mercurial/parsers.c
changeset 30577 6146d5acee69
parent 30171 7a3b59f0329a
child 31278 1c97a91a18dc
equal deleted inserted replaced
30576:541949a10a68 30577:6146d5acee69
   751  */
   751  */
   752 typedef struct {
   752 typedef struct {
   753 	PyObject_HEAD
   753 	PyObject_HEAD
   754 	/* Type-specific fields go here. */
   754 	/* Type-specific fields go here. */
   755 	PyObject *data;        /* raw bytes of index */
   755 	PyObject *data;        /* raw bytes of index */
       
   756 	Py_buffer buf;         /* buffer of data */
   756 	PyObject **cache;      /* cached tuples */
   757 	PyObject **cache;      /* cached tuples */
   757 	const char **offsets;  /* populated on demand */
   758 	const char **offsets;  /* populated on demand */
   758 	Py_ssize_t raw_length; /* original number of elements */
   759 	Py_ssize_t raw_length; /* original number of elements */
   759 	Py_ssize_t length;     /* current number of elements */
   760 	Py_ssize_t length;     /* current number of elements */
   760 	PyObject *added;       /* populated on demand */
   761 	PyObject *added;       /* populated on demand */
   806 			inline_scan(self, self->offsets);
   807 			inline_scan(self, self->offsets);
   807 		}
   808 		}
   808 		return self->offsets[pos];
   809 		return self->offsets[pos];
   809 	}
   810 	}
   810 
   811 
   811 	return PyBytes_AS_STRING(self->data) + pos * v1_hdrsize;
   812 	return (const char *)(self->buf.buf) + pos * v1_hdrsize;
   812 }
   813 }
   813 
   814 
   814 static inline int index_get_parents(indexObject *self, Py_ssize_t rev,
   815 static inline int index_get_parents(indexObject *self, Py_ssize_t rev,
   815 				    int *ps, int maxrev)
   816 				    int *ps, int maxrev)
   816 {
   817 {
  2387  * Find all RevlogNG entries in an index that has inline data. Update
  2388  * Find all RevlogNG entries in an index that has inline data. Update
  2388  * the optional "offsets" table with those entries.
  2389  * the optional "offsets" table with those entries.
  2389  */
  2390  */
  2390 static Py_ssize_t inline_scan(indexObject *self, const char **offsets)
  2391 static Py_ssize_t inline_scan(indexObject *self, const char **offsets)
  2391 {
  2392 {
  2392 	const char *data = PyBytes_AS_STRING(self->data);
  2393 	const char *data = (const char *)self->buf.buf;
  2393 	Py_ssize_t pos = 0;
  2394 	Py_ssize_t pos = 0;
  2394 	Py_ssize_t end = PyBytes_GET_SIZE(self->data);
  2395 	Py_ssize_t end = self->buf.len;
  2395 	long incr = v1_hdrsize;
  2396 	long incr = v1_hdrsize;
  2396 	Py_ssize_t len = 0;
  2397 	Py_ssize_t len = 0;
  2397 
  2398 
  2398 	while (pos + v1_hdrsize <= end && pos >= 0) {
  2399 	while (pos + v1_hdrsize <= end && pos >= 0) {
  2399 		uint32_t comp_len;
  2400 		uint32_t comp_len;
  2423 	/* Initialize before argument-checking to avoid index_dealloc() crash. */
  2424 	/* Initialize before argument-checking to avoid index_dealloc() crash. */
  2424 	self->raw_length = 0;
  2425 	self->raw_length = 0;
  2425 	self->added = NULL;
  2426 	self->added = NULL;
  2426 	self->cache = NULL;
  2427 	self->cache = NULL;
  2427 	self->data = NULL;
  2428 	self->data = NULL;
       
  2429 	memset(&self->buf, 0, sizeof(self->buf));
  2428 	self->headrevs = NULL;
  2430 	self->headrevs = NULL;
  2429 	self->filteredrevs = Py_None;
  2431 	self->filteredrevs = Py_None;
  2430 	Py_INCREF(Py_None);
  2432 	Py_INCREF(Py_None);
  2431 	self->nt = NULL;
  2433 	self->nt = NULL;
  2432 	self->offsets = NULL;
  2434 	self->offsets = NULL;
  2433 
  2435 
  2434 	if (!PyArg_ParseTuple(args, "OO", &data_obj, &inlined_obj))
  2436 	if (!PyArg_ParseTuple(args, "OO", &data_obj, &inlined_obj))
  2435 		return -1;
  2437 		return -1;
  2436 	if (!PyBytes_Check(data_obj)) {
  2438 	if (!PyObject_CheckBuffer(data_obj)) {
  2437 		PyErr_SetString(PyExc_TypeError, "data is not a string");
  2439 		PyErr_SetString(PyExc_TypeError,
       
  2440 				"data does not support buffer interface");
  2438 		return -1;
  2441 		return -1;
  2439 	}
  2442 	}
  2440 	size = PyBytes_GET_SIZE(data_obj);
  2443 
       
  2444 	if (PyObject_GetBuffer(data_obj, &self->buf, PyBUF_SIMPLE) == -1)
       
  2445 		return -1;
       
  2446 	size = self->buf.len;
  2441 
  2447 
  2442 	self->inlined = inlined_obj && PyObject_IsTrue(inlined_obj);
  2448 	self->inlined = inlined_obj && PyObject_IsTrue(inlined_obj);
  2443 	self->data = data_obj;
  2449 	self->data = data_obj;
  2444 
  2450 
  2445 	self->ntlength = self->ntcapacity = 0;
  2451 	self->ntlength = self->ntcapacity = 0;
  2476 
  2482 
  2477 static void index_dealloc(indexObject *self)
  2483 static void index_dealloc(indexObject *self)
  2478 {
  2484 {
  2479 	_index_clearcaches(self);
  2485 	_index_clearcaches(self);
  2480 	Py_XDECREF(self->filteredrevs);
  2486 	Py_XDECREF(self->filteredrevs);
       
  2487 	if (self->buf.buf) {
       
  2488 		PyBuffer_Release(&self->buf);
       
  2489 		memset(&self->buf, 0, sizeof(self->buf));
       
  2490 	}
  2481 	Py_XDECREF(self->data);
  2491 	Py_XDECREF(self->data);
  2482 	Py_XDECREF(self->added);
  2492 	Py_XDECREF(self->added);
  2483 	PyObject_Del(self);
  2493 	PyObject_Del(self);
  2484 }
  2494 }
  2485 
  2495 
  2575 /*
  2585 /*
  2576  * returns a tuple of the form (index, index, cache) with elements as
  2586  * returns a tuple of the form (index, index, cache) with elements as
  2577  * follows:
  2587  * follows:
  2578  *
  2588  *
  2579  * index: an index object that lazily parses RevlogNG records
  2589  * index: an index object that lazily parses RevlogNG records
  2580  * cache: if data is inlined, a tuple (index_file_content, 0), else None
  2590  * cache: if data is inlined, a tuple (0, index_file_content), else None
       
  2591  *        index_file_content could be a string, or a buffer
  2581  *
  2592  *
  2582  * added complications are for backwards compatibility
  2593  * added complications are for backwards compatibility
  2583  */
  2594  */
  2584 static PyObject *parse_index2(PyObject *self, PyObject *args)
  2595 static PyObject *parse_index2(PyObject *self, PyObject *args)
  2585 {
  2596 {