75 * ('\n') characters. |
75 * ('\n') characters. |
76 */ |
76 */ |
77 static PyObject *parse_manifest(PyObject *self, PyObject *args) |
77 static PyObject *parse_manifest(PyObject *self, PyObject *args) |
78 { |
78 { |
79 PyObject *mfdict, *fdict; |
79 PyObject *mfdict, *fdict; |
80 char *str, *cur, *start, *zero; |
80 char *str, *start, *end; |
81 int len; |
81 int len; |
82 |
82 |
83 if (!PyArg_ParseTuple(args, "O!O!s#:parse_manifest", |
83 if (!PyArg_ParseTuple(args, "O!O!s#:parse_manifest", |
84 &PyDict_Type, &mfdict, |
84 &PyDict_Type, &mfdict, |
85 &PyDict_Type, &fdict, |
85 &PyDict_Type, &fdict, |
86 &str, &len)) |
86 &str, &len)) |
87 goto quit; |
87 goto quit; |
88 |
88 |
89 for (start = cur = str, zero = NULL; cur < str + len; cur++) { |
89 start = str; |
|
90 end = str + len; |
|
91 while (start < end) { |
90 PyObject *file = NULL, *node = NULL; |
92 PyObject *file = NULL, *node = NULL; |
91 PyObject *flags = NULL; |
93 PyObject *flags = NULL; |
|
94 char *zero = NULL, *newline = NULL; |
92 ptrdiff_t nlen; |
95 ptrdiff_t nlen; |
93 |
96 |
94 if (!*cur) { |
97 zero = memchr(start, '\0', end - start); |
95 zero = cur; |
|
96 continue; |
|
97 } |
|
98 else if (*cur != '\n') |
|
99 continue; |
|
100 |
|
101 if (!zero) { |
98 if (!zero) { |
102 PyErr_SetString(PyExc_ValueError, |
99 PyErr_SetString(PyExc_ValueError, |
103 "manifest entry has no separator"); |
100 "manifest entry has no separator"); |
104 goto quit; |
101 goto quit; |
105 } |
102 } |
106 |
103 |
|
104 newline = memchr(zero + 1, '\n', end - (zero + 1)); |
|
105 if (!newline) { |
|
106 PyErr_SetString(PyExc_ValueError, |
|
107 "manifest contains trailing garbage"); |
|
108 goto quit; |
|
109 } |
|
110 |
107 file = PyBytes_FromStringAndSize(start, zero - start); |
111 file = PyBytes_FromStringAndSize(start, zero - start); |
108 |
112 |
109 if (!file) |
113 if (!file) |
110 goto bail; |
114 goto bail; |
111 |
115 |
112 nlen = cur - zero - 1; |
116 nlen = newline - zero - 1; |
113 |
117 |
114 node = unhexlify(zero + 1, nlen > 40 ? 40 : (int)nlen); |
118 node = unhexlify(zero + 1, nlen > 40 ? 40 : (int)nlen); |
115 if (!node) |
119 if (!node) |
116 goto bail; |
120 goto bail; |
117 |
121 |