mercurial/parsers.c
changeset 7093 16bafcebd3d1
parent 7092 fb3fc27617a2
child 7108 1ca878d7b849
equal deleted inserted replaced
7092:fb3fc27617a2 7093:16bafcebd3d1
   126 		goto quit;
   126 		goto quit;
   127 	}
   127 	}
   128 
   128 
   129 	Py_INCREF(Py_None);
   129 	Py_INCREF(Py_None);
   130 	return Py_None;
   130 	return Py_None;
   131 
       
   132 quit:
   131 quit:
   133 	return NULL;
   132 	return NULL;
   134 }
   133 }
   135 
   134 
       
   135 #ifdef _WIN32
       
   136 # ifdef _MSC_VER
       
   137 /* msvc 6.0 has problems */
       
   138 #  define inline __inline
       
   139 typedef unsigned long uint32_t;
       
   140 # else
       
   141 #  include <stdint.h>
       
   142 # endif
       
   143 static uint32_t ntohl(uint32_t x)
       
   144 {
       
   145 	return ((x & 0x000000ffUL) << 24) |
       
   146 		((x & 0x0000ff00UL) <<  8) |
       
   147 		((x & 0x00ff0000UL) >>  8) |
       
   148 		((x & 0xff000000UL) >> 24);
       
   149 }
       
   150 #else
       
   151 /* not windows */
       
   152 # include <sys/types.h>
       
   153 # if defined __BEOS__ && !defined __HAIKU__
       
   154 #  include <ByteOrder.h>
       
   155 # else
       
   156 #  include <arpa/inet.h>
       
   157 # endif
       
   158 # include <inttypes.h>
       
   159 #endif
       
   160 
       
   161 static PyObject *parse_dirstate(PyObject *self, PyObject *args)
       
   162 {
       
   163 	PyObject *dmap, *cmap, *parents = NULL, *ret = NULL;
       
   164 	PyObject *fname = NULL, *cname = NULL, *entry = NULL;
       
   165 	char *str, *cur, *end, *cpos;
       
   166 	int state, mode, size, mtime, flen;
       
   167 	int len;
       
   168 	char decode[16]; /* for alignment */
       
   169 
       
   170 	if (!PyArg_ParseTuple(args, "O!O!s#:parse_dirstate",
       
   171 			      &PyDict_Type, &dmap,
       
   172 			      &PyDict_Type, &cmap,
       
   173 			      &str, &len))
       
   174 		goto quit;
       
   175 
       
   176 	/* read parents */
       
   177 	if (len < 40)
       
   178 		goto quit;
       
   179 
       
   180 	parents = Py_BuildValue("s#s#", str, 20, str + 20, 20);
       
   181 	if (!parents)
       
   182 		goto quit;
       
   183 
       
   184 	/* read filenames */
       
   185 	cur = str + 40;
       
   186 	end = str + len;
       
   187 
       
   188 	while (cur < end - 17) {
       
   189 		/* unpack header */
       
   190 		state = *cur;
       
   191 		memcpy(decode, cur + 1, 16);
       
   192 		mode = ntohl(*(uint32_t *)(decode));
       
   193 		size = ntohl(*(uint32_t *)(decode + 4));
       
   194 		mtime = ntohl(*(uint32_t *)(decode + 8));
       
   195 		flen = ntohl(*(uint32_t *)(decode + 12));
       
   196 		cur += 17;
       
   197 		if (cur + flen > end)
       
   198 			goto quit;
       
   199 
       
   200 		entry = Py_BuildValue("ciii", state, mode, size, mtime);
       
   201 		PyObject_GC_UnTrack(entry); /* don't waste time with this */
       
   202 		if (!entry)
       
   203 			goto quit;
       
   204 
       
   205 		cpos = memchr(cur, 0, flen);
       
   206 		if (cpos) {
       
   207 			fname = PyString_FromStringAndSize(cur, cpos - cur);
       
   208 			cname = PyString_FromStringAndSize(cpos + 1,
       
   209 							   flen - (cpos - cur) - 1);
       
   210 			if (!fname || !cname ||
       
   211 			    PyDict_SetItem(cmap, fname, cname) == -1 ||
       
   212 			    PyDict_SetItem(dmap, fname, entry) == -1)
       
   213 				goto quit;
       
   214 			Py_DECREF(cname);
       
   215 		} else {
       
   216 			fname = PyString_FromStringAndSize(cur, flen);
       
   217 			if (!fname ||
       
   218 			    PyDict_SetItem(dmap, fname, entry) == -1)
       
   219 				goto quit;
       
   220 		}
       
   221 		cur += flen;
       
   222 		Py_DECREF(fname);
       
   223 		Py_DECREF(entry);
       
   224 		fname = cname = entry = NULL;
       
   225 	}
       
   226 
       
   227 	ret = parents;
       
   228 	Py_INCREF(ret);
       
   229 quit:
       
   230 	Py_XDECREF(fname);
       
   231 	Py_XDECREF(cname);
       
   232 	Py_XDECREF(entry);
       
   233 	Py_XDECREF(parents);
       
   234 	return ret;
       
   235 }
       
   236 
   136 static char parsers_doc[] = "Efficient content parsing.";
   237 static char parsers_doc[] = "Efficient content parsing.";
   137 
   238 
   138 static PyMethodDef methods[] = {
   239 static PyMethodDef methods[] = {
   139 	{"parse_manifest", parse_manifest, METH_VARARGS, "parse a manifest\n"},
   240 	{"parse_manifest", parse_manifest, METH_VARARGS, "parse a manifest\n"},
       
   241 	{"parse_dirstate", parse_dirstate, METH_VARARGS, "parse a dirstate\n"},
   140 	{NULL, NULL}
   242 	{NULL, NULL}
   141 };
   243 };
   142 
   244 
   143 PyMODINIT_FUNC initparsers(void)
   245 PyMODINIT_FUNC initparsers(void)
   144 {
   246 {