Mercurial > public > mercurial-scm > hg
comparison mercurial/parsers.c @ 7093:16bafcebd3d1
dirstate: C parsing extension
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Sun, 12 Oct 2008 15:21:08 -0500 |
parents | fb3fc27617a2 |
children | 1ca878d7b849 |
comparison
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 { |