54 if (!hash) { |
54 if (!hash) { |
55 return NULL; |
55 return NULL; |
56 } |
56 } |
57 if (l->hash_suffix != '\0') { |
57 if (l->hash_suffix != '\0') { |
58 char newhash[21]; |
58 char newhash[21]; |
59 memcpy(newhash, PyString_AsString(hash), 20); |
59 memcpy(newhash, PyBytes_AsString(hash), 20); |
60 Py_DECREF(hash); |
60 Py_DECREF(hash); |
61 newhash[20] = l->hash_suffix; |
61 newhash[20] = l->hash_suffix; |
62 hash = PyString_FromStringAndSize(newhash, 21); |
62 hash = PyBytes_FromStringAndSize(newhash, 21); |
63 } |
63 } |
64 return hash; |
64 return hash; |
65 } |
65 } |
66 |
66 |
67 /* get the node hash and flags of a line as a tuple */ |
67 /* get the node hash and flags of a line as a tuple */ |
236 l = lmiter_nextline((lmIter *)o); |
236 l = lmiter_nextline((lmIter *)o); |
237 if (!l) { |
237 if (!l) { |
238 goto done; |
238 goto done; |
239 } |
239 } |
240 pl = pathlen(l); |
240 pl = pathlen(l); |
241 path = PyString_FromStringAndSize(l->start, pl); |
241 path = PyBytes_FromStringAndSize(l->start, pl); |
242 hash = nodeof(l); |
242 hash = nodeof(l); |
243 consumed = pl + 41; |
243 consumed = pl + 41; |
244 flags = PyString_FromStringAndSize(l->start + consumed, |
244 flags = PyBytes_FromStringAndSize(l->start + consumed, |
245 l->len - consumed - 1); |
245 l->len - consumed - 1); |
246 if (!path || !hash || !flags) { |
246 if (!path || !hash || !flags) { |
247 goto done; |
247 goto done; |
248 } |
248 } |
249 ret = PyTuple_Pack(3, path, hash, flags); |
249 ret = PyTuple_Pack(3, path, hash, flags); |
396 |
396 |
397 static PyObject *lazymanifest_getitem(lazymanifest *self, PyObject *key) |
397 static PyObject *lazymanifest_getitem(lazymanifest *self, PyObject *key) |
398 { |
398 { |
399 line needle; |
399 line needle; |
400 line *hit; |
400 line *hit; |
401 if (!PyString_Check(key)) { |
401 if (!PyBytes_Check(key)) { |
402 PyErr_Format(PyExc_TypeError, |
402 PyErr_Format(PyExc_TypeError, |
403 "getitem: manifest keys must be a string."); |
403 "getitem: manifest keys must be a string."); |
404 return NULL; |
404 return NULL; |
405 } |
405 } |
406 needle.start = PyString_AsString(key); |
406 needle.start = PyBytes_AsString(key); |
407 hit = bsearch(&needle, self->lines, self->numlines, sizeof(line), |
407 hit = bsearch(&needle, self->lines, self->numlines, sizeof(line), |
408 &linecmp); |
408 &linecmp); |
409 if (!hit || hit->deleted) { |
409 if (!hit || hit->deleted) { |
410 PyErr_Format(PyExc_KeyError, "No such manifest entry."); |
410 PyErr_Format(PyExc_KeyError, "No such manifest entry."); |
411 return NULL; |
411 return NULL; |
415 |
415 |
416 static int lazymanifest_delitem(lazymanifest *self, PyObject *key) |
416 static int lazymanifest_delitem(lazymanifest *self, PyObject *key) |
417 { |
417 { |
418 line needle; |
418 line needle; |
419 line *hit; |
419 line *hit; |
420 if (!PyString_Check(key)) { |
420 if (!PyBytes_Check(key)) { |
421 PyErr_Format(PyExc_TypeError, |
421 PyErr_Format(PyExc_TypeError, |
422 "delitem: manifest keys must be a string."); |
422 "delitem: manifest keys must be a string."); |
423 return -1; |
423 return -1; |
424 } |
424 } |
425 needle.start = PyString_AsString(key); |
425 needle.start = PyBytes_AsString(key); |
426 hit = bsearch(&needle, self->lines, self->numlines, sizeof(line), |
426 hit = bsearch(&needle, self->lines, self->numlines, sizeof(line), |
427 &linecmp); |
427 &linecmp); |
428 if (!hit || hit->deleted) { |
428 if (!hit || hit->deleted) { |
429 PyErr_Format(PyExc_KeyError, |
429 PyErr_Format(PyExc_KeyError, |
430 "Tried to delete nonexistent manifest entry."); |
430 "Tried to delete nonexistent manifest entry."); |
497 if (!PyTuple_Check(value) || PyTuple_Size(value) != 2) { |
497 if (!PyTuple_Check(value) || PyTuple_Size(value) != 2) { |
498 PyErr_Format(PyExc_TypeError, |
498 PyErr_Format(PyExc_TypeError, |
499 "Manifest values must be a tuple of (node, flags)."); |
499 "Manifest values must be a tuple of (node, flags)."); |
500 return -1; |
500 return -1; |
501 } |
501 } |
502 if (PyString_AsStringAndSize(key, &path, &plen) == -1) { |
502 if (PyBytes_AsStringAndSize(key, &path, &plen) == -1) { |
503 return -1; |
503 return -1; |
504 } |
504 } |
505 |
505 |
506 pyhash = PyTuple_GetItem(value, 0); |
506 pyhash = PyTuple_GetItem(value, 0); |
507 if (!PyString_Check(pyhash)) { |
507 if (!PyBytes_Check(pyhash)) { |
508 PyErr_Format(PyExc_TypeError, |
508 PyErr_Format(PyExc_TypeError, |
509 "node must be a 20-byte string"); |
509 "node must be a 20-byte string"); |
510 return -1; |
510 return -1; |
511 } |
511 } |
512 hlen = PyString_Size(pyhash); |
512 hlen = PyBytes_Size(pyhash); |
513 /* Some parts of the codebase try and set 21 or 22 |
513 /* Some parts of the codebase try and set 21 or 22 |
514 * byte "hash" values in order to perturb things for |
514 * byte "hash" values in order to perturb things for |
515 * status. We have to preserve at least the 21st |
515 * status. We have to preserve at least the 21st |
516 * byte. Sigh. If there's a 22nd byte, we drop it on |
516 * byte. Sigh. If there's a 22nd byte, we drop it on |
517 * the floor, which works fine. |
517 * the floor, which works fine. |
519 if (hlen != 20 && hlen != 21 && hlen != 22) { |
519 if (hlen != 20 && hlen != 21 && hlen != 22) { |
520 PyErr_Format(PyExc_TypeError, |
520 PyErr_Format(PyExc_TypeError, |
521 "node must be a 20-byte string"); |
521 "node must be a 20-byte string"); |
522 return -1; |
522 return -1; |
523 } |
523 } |
524 hash = PyString_AsString(pyhash); |
524 hash = PyBytes_AsString(pyhash); |
525 |
525 |
526 pyflags = PyTuple_GetItem(value, 1); |
526 pyflags = PyTuple_GetItem(value, 1); |
527 if (!PyString_Check(pyflags) || PyString_Size(pyflags) > 1) { |
527 if (!PyBytes_Check(pyflags) || PyBytes_Size(pyflags) > 1) { |
528 PyErr_Format(PyExc_TypeError, |
528 PyErr_Format(PyExc_TypeError, |
529 "flags must a 0 or 1 byte string"); |
529 "flags must a 0 or 1 byte string"); |
530 return -1; |
530 return -1; |
531 } |
531 } |
532 if (PyString_AsStringAndSize(pyflags, &flags, &flen) == -1) { |
532 if (PyBytes_AsStringAndSize(pyflags, &flags, &flen) == -1) { |
533 return -1; |
533 return -1; |
534 } |
534 } |
535 /* one null byte and one newline */ |
535 /* one null byte and one newline */ |
536 dlen = plen + 41 + flen + 1; |
536 dlen = plen + 41 + flen + 1; |
537 dest = malloc(dlen); |
537 dest = malloc(dlen); |
572 |
572 |
573 static int lazymanifest_contains(lazymanifest *self, PyObject *key) |
573 static int lazymanifest_contains(lazymanifest *self, PyObject *key) |
574 { |
574 { |
575 line needle; |
575 line needle; |
576 line *hit; |
576 line *hit; |
577 if (!PyString_Check(key)) { |
577 if (!PyBytes_Check(key)) { |
578 /* Our keys are always strings, so if the contains |
578 /* Our keys are always strings, so if the contains |
579 * check is for a non-string, just return false. */ |
579 * check is for a non-string, just return false. */ |
580 return 0; |
580 return 0; |
581 } |
581 } |
582 needle.start = PyString_AsString(key); |
582 needle.start = PyBytes_AsString(key); |
583 hit = bsearch(&needle, self->lines, self->numlines, sizeof(line), |
583 hit = bsearch(&needle, self->lines, self->numlines, sizeof(line), |
584 &linecmp); |
584 &linecmp); |
585 if (!hit || hit->deleted) { |
585 if (!hit || hit->deleted) { |
586 return 0; |
586 return 0; |
587 } |
587 } |
617 for (i = 0; i < self->numlines; i++) { |
617 for (i = 0; i < self->numlines; i++) { |
618 if (!self->lines[i].deleted) { |
618 if (!self->lines[i].deleted) { |
619 need += self->lines[i].len; |
619 need += self->lines[i].len; |
620 } |
620 } |
621 } |
621 } |
622 pydata = PyString_FromStringAndSize(NULL, need); |
622 pydata = PyBytes_FromStringAndSize(NULL, need); |
623 if (!pydata) |
623 if (!pydata) |
624 return -1; |
624 return -1; |
625 data = PyString_AsString(pydata); |
625 data = PyBytes_AsString(pydata); |
626 if (!data) { |
626 if (!data) { |
627 return -1; |
627 return -1; |
628 } |
628 } |
629 src = self->lines; |
629 src = self->lines; |
630 dst = self->lines; |
630 dst = self->lines; |
755 int sneedle = 0, oneedle = 0; |
755 int sneedle = 0, oneedle = 0; |
756 if (!PyArg_ParseTuple(args, "O!|O", &lazymanifestType, &other, &pyclean)) { |
756 if (!PyArg_ParseTuple(args, "O!|O", &lazymanifestType, &other, &pyclean)) { |
757 return NULL; |
757 return NULL; |
758 } |
758 } |
759 listclean = (!pyclean) ? false : PyObject_IsTrue(pyclean); |
759 listclean = (!pyclean) ? false : PyObject_IsTrue(pyclean); |
760 es = PyString_FromString(""); |
760 es = PyBytes_FromString(""); |
761 if (!es) { |
761 if (!es) { |
762 goto nomem; |
762 goto nomem; |
763 } |
763 } |
764 emptyTup = PyTuple_Pack(2, Py_None, es); |
764 emptyTup = PyTuple_Pack(2, Py_None, es); |
765 Py_DECREF(es); |
765 Py_DECREF(es); |