Accept chunked contents for apply_delta base texts.
authorJelmer Vernooij <jelmer@samba.org>
Wed, 31 Mar 2010 19:45:10 +0000 (21:45 +0200)
committerJelmer Vernooij <jelmer@samba.org>
Wed, 31 Mar 2010 19:45:10 +0000 (21:45 +0200)
dulwich/_pack.c
dulwich/objects.py
dulwich/pack.py

index 7cdfe304a4ca8737f4706150b8cf81dbc88fc7d7..dc8101818107aad3452c5fb6a4e35935d7675408 100644 (file)
@@ -56,23 +56,48 @@ static PyObject *py_apply_delta(PyObject *self, PyObject *args)
        size_t outindex = 0;
        int index;
        uint8_t *out;
-       PyObject *ret;
+       PyObject *ret, *py_src_buf;
 
-       if (!PyArg_ParseTuple(args, "s#s#", (uint8_t *)&src_buf, &src_buf_len, 
+       if (!PyArg_ParseTuple(args, "Os#", &py_src_buf,
                                                  (uint8_t *)&delta, &delta_len))
                return NULL;
 
+       if (PyList_Check(py_src_buf)) {
+               PyObject *sep = PyString_FromString("");
+               if (sep == NULL) {
+                       PyErr_NoMemory();
+                       return NULL;
+               }
+               py_src_buf = _PyString_Join(sep, py_src_buf);
+               Py_DECREF(sep);
+               if (py_src_buf == NULL) {
+                       PyErr_NoMemory();
+                       return NULL;
+               }
+       } else if (PyString_Check(py_src_buf)) {
+               Py_INCREF(py_src_buf);
+       } else {
+               PyErr_SetString(PyExc_TypeError,
+                       "src_buf is not a string or a list of chunks");
+               return NULL;
+       }
+
+       src_buf = (uint8_t *)PyString_AS_STRING(py_src_buf);
+       src_buf_len = PyString_GET_SIZE(py_src_buf);
+
     index = 0;
     src_size = get_delta_header_size(delta, &index, delta_len);
     if (src_size != src_buf_len) {
                PyErr_Format(PyExc_ValueError, 
                        "Unexpected source buffer size: %lu vs %d", src_size, src_buf_len);
+               Py_DECREF(py_src_buf);
                return NULL;
        }
     dest_size = get_delta_header_size(delta, &index, delta_len);
        ret = PyString_FromStringAndSize(NULL, dest_size);
        if (ret == NULL) {
                PyErr_NoMemory();
+               Py_DECREF(py_src_buf);
                return NULL;
        }
        out = (uint8_t *)PyString_AsString(ret);
@@ -111,9 +136,11 @@ static PyObject *py_apply_delta(PyObject *self, PyObject *args)
                } else {
                        PyErr_SetString(PyExc_ValueError, "Invalid opcode 0");
                        Py_DECREF(ret);
+                       Py_DECREF(py_src_buf);
                        return NULL;
                }
        }
+       Py_DECREF(py_src_buf);
     
     if (index != delta_len) {
                PyErr_SetString(PyExc_ValueError, "delta not empty");
index a3efd3a55a00d0b102c660128ae4b20e8b49b58d..6864e56f3e9c4967edd4b17338e7d3c1fe557082 100644 (file)
@@ -280,7 +280,7 @@ class ShaFile(object):
         return self.id != other.id
 
     def __eq__(self, other):
-        """Return true id the sha of the two objects match.
+        """Return true if the sha of the two objects match.
 
         The __le__ etc methods aren't overriden as they make no sense,
         certainly at this level.
index 4aaac6d106cf47c74544ba326f4773a8d96476e2..7bf61a390b3750948c76ec3817aaae2255c83315 100644 (file)
@@ -565,7 +565,7 @@ class PackData(object):
             get_ref)
         if base_offset is not None:
             self._offset_cache[base_offset] = type, base_chunks
-        return (type, apply_delta("".join(base_chunks), delta))
+        return (type, apply_delta(base_chunks, delta))
   
     def iterobjects(self, progress=None):
 
@@ -960,7 +960,8 @@ def apply_delta(src_buf, delta):
     :param src_buf: Source buffer
     :param delta: Delta instructions
     """
-    assert isinstance(src_buf, str), "was %r" % (src_buf,)
+    if type(src_buf) != str:
+        src_buf = "".join(src_buf)
     assert isinstance(delta, str)
     out = []
     index = 0