##// END OF EJS Templates
index parser: fix refcounting in case of errors, refactor...
Benoit Boissinot -
r7154:7fdf7a0a default
parent child Browse files
Show More
@@ -238,6 +238,40 b' quit:'
238 const char nullid[20];
238 const char nullid[20];
239 const int nullrev = -1;
239 const int nullrev = -1;
240
240
241 /* create an index tuple, insert into the nodemap */
242 static PyObject * _build_idx_entry(PyObject *nodemap, int n, uint64_t offset_flags,
243 int comp_len, int uncomp_len, int base_rev,
244 int link_rev, int parent_1, int parent_2,
245 const char *c_node_id)
246 {
247 int err;
248 PyObject *entry, *node_id, *n_obj;
249
250 node_id = PyString_FromStringAndSize(c_node_id, 20);
251 n_obj = PyInt_FromLong(n);
252 if (!node_id || !n_obj)
253 err = -1;
254 else
255 err = PyDict_SetItem(nodemap, node_id, n_obj);
256
257 Py_XDECREF(n_obj);
258 if (err)
259 goto error_dealloc;
260
261 entry = Py_BuildValue("LiiiiiiN", offset_flags, comp_len,
262 uncomp_len, base_rev, link_rev,
263 parent_1, parent_2, node_id);
264 if (!entry)
265 goto error_dealloc;
266 PyObject_GC_UnTrack(entry); /* don't waste time with this */
267
268 return entry;
269
270 error_dealloc:
271 Py_XDECREF(node_id);
272 return NULL;
273 }
274
241 /* RevlogNG format (all in big endian, data may be inlined):
275 /* RevlogNG format (all in big endian, data may be inlined):
242 * 6 bytes: offset
276 * 6 bytes: offset
243 * 2 bytes: flags
277 * 2 bytes: flags
@@ -252,11 +286,11 b' const int nullrev = -1;'
252 static int _parse_index_ng (const char *data, int size, int inlined,
286 static int _parse_index_ng (const char *data, int size, int inlined,
253 PyObject *index, PyObject *nodemap)
287 PyObject *index, PyObject *nodemap)
254 {
288 {
255 PyObject *entry = NULL, *node_id = NULL, *n_obj = NULL;
289 PyObject *entry;
256 PyObject *nullrev_obj = NULL, *nullid_obj = NULL;
290 int n = 0, err;
291 uint64_t offset_flags;
257 int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2;
292 int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2;
258 uint64_t offset_flags;
293 const char *c_node_id;
259 int n = 0;
260 const char *end = data + size;
294 const char *end = data + size;
261
295
262 while (data < end) {
296 while (data < end) {
@@ -268,35 +302,28 b' static int _parse_index_ng (const char *'
268 offset_flags |= ((uint64_t) offset_high) << 32;
302 offset_flags |= ((uint64_t) offset_high) << 32;
269 }
303 }
270
304
271
272 comp_len = ntohl(*((uint32_t *) (data + 8)));
305 comp_len = ntohl(*((uint32_t *) (data + 8)));
273 uncomp_len = ntohl(*((uint32_t *) (data + 12)));
306 uncomp_len = ntohl(*((uint32_t *) (data + 12)));
274 base_rev = ntohl(*((uint32_t *) (data + 16)));
307 base_rev = ntohl(*((uint32_t *) (data + 16)));
275 link_rev = ntohl(*((uint32_t *) (data + 20)));
308 link_rev = ntohl(*((uint32_t *) (data + 20)));
276 parent_1 = ntohl(*((uint32_t *) (data + 24)));
309 parent_1 = ntohl(*((uint32_t *) (data + 24)));
277 parent_2 = ntohl(*((uint32_t *) (data + 28)));
310 parent_2 = ntohl(*((uint32_t *) (data + 28)));
278 node_id = PyString_FromStringAndSize(data + 32, 20);
311 c_node_id = data + 32;
279 n_obj = PyInt_FromLong(n);
312
280 if (!node_id || !n_obj ||
313 entry = _build_idx_entry(nodemap, n, offset_flags,
281 PyDict_SetItem(nodemap, node_id, n_obj) != 0)
314 comp_len, uncomp_len, base_rev,
282 goto quit;
315 link_rev, parent_1, parent_2,
283 Py_DECREF(n_obj);
316 c_node_id);
284
285 entry = Py_BuildValue("LiiiiiiN", offset_flags, comp_len,
286 uncomp_len, base_rev, link_rev,
287 parent_1, parent_2, node_id);
288 PyObject_GC_UnTrack(entry); /* don't waste time with this */
289 if (!entry)
317 if (!entry)
290 goto quit;
318 return 0;
291
319
292 /* append to or set value in the index list */
293 if (inlined) {
320 if (inlined) {
294 if (PyList_Append(index, entry) != 0)
321 err = PyList_Append(index, entry);
295 goto quit;
296 Py_DECREF(entry);
322 Py_DECREF(entry);
297 } else {
323 if (err)
324 return 0;
325 } else
298 PyList_SET_ITEM(index, n, entry); /* steals reference */
326 PyList_SET_ITEM(index, n, entry); /* steals reference */
299 }
300
327
301 data += 64 + (inlined ? comp_len : 0);
328 data += 64 + (inlined ? comp_len : 0);
302 n++;
329 n++;
@@ -304,43 +331,26 b' static int _parse_index_ng (const char *'
304 if (data > end) {
331 if (data > end) {
305 if (!PyErr_Occurred())
332 if (!PyErr_Occurred())
306 PyErr_SetString(PyExc_ValueError, "corrupt index file");
333 PyErr_SetString(PyExc_ValueError, "corrupt index file");
307 goto quit;
334 return 0;
308 }
335 }
309
336
310 /* create the nullid/nullrev entry in the nodemap and the
337 /* create the nullid/nullrev entry in the nodemap and the
311 * magic nullid entry in the index at [-1] */
338 * magic nullid entry in the index at [-1] */
312 nullid_obj = PyString_FromStringAndSize(nullid, 20);
339 entry = _build_idx_entry(nodemap,
313 nullrev_obj = PyInt_FromLong(nullrev);
340 nullrev, 0, 0, 0, -1, -1, -1, -1, nullid);
314 if (!nodemap || !nullid_obj || !nullrev_obj ||
315 PyDict_SetItem(nodemap, nullid_obj, nullrev_obj) != 0)
316 goto quit;
317 Py_DECREF(nullrev_obj);
318
319 entry = Py_BuildValue("iiiiiiiN", 0, 0, 0, -1, -1, -1, -1, nullid_obj);
320 PyObject_GC_UnTrack(entry); /* don't waste time with this */
321 if (!entry)
341 if (!entry)
322 goto quit;
342 return 0;
323 if (inlined) {
343 if (inlined) {
324 if (PyList_Append(index, entry) != 0)
344 err = PyList_Append(index, entry);
325 goto quit;
326 Py_DECREF(entry);
345 Py_DECREF(entry);
327 } else {
346 if (err)
347 return 0;
348 } else
328 PyList_SET_ITEM(index, n, entry); /* steals reference */
349 PyList_SET_ITEM(index, n, entry); /* steals reference */
329 }
330
350
331 return 1;
351 return 1;
332
333 quit:
334 Py_XDECREF(n_obj);
335 Py_XDECREF(node_id);
336 Py_XDECREF(entry);
337 Py_XDECREF(nullrev_obj);
338 Py_XDECREF(nullid_obj);
339 return 0;
340 }
352 }
341
353
342
343
344 /* This function parses a index file and returns a Python tuple of the
354 /* This function parses a index file and returns a Python tuple of the
345 * following format: (index, nodemap, cache)
355 * following format: (index, nodemap, cache)
346 *
356 *
@@ -367,6 +377,8 b' static PyObject *parse_index(PyObject *s'
367 goto quit;
377 goto quit;
368
378
369 nodemap = PyDict_New();
379 nodemap = PyDict_New();
380 if (!nodemap)
381 goto quit;
370
382
371 /* set up the cache return value */
383 /* set up the cache return value */
372 if (inlined) {
384 if (inlined) {
General Comments 0
You need to be logged in to leave comments. Login now