Allow delta's to be chunked as well.
authorJelmer Vernooij <jelmer@samba.org>
Wed, 31 Mar 2010 21:05:52 +0000 (23:05 +0200)
committerJelmer Vernooij <jelmer@samba.org>
Wed, 31 Mar 2010 21:05:52 +0000 (23:05 +0200)
dulwich/_pack.c
dulwich/pack.py

index dc8101818107aad3452c5fb6a4e35935d7675408..ee79b40e17eea2f42244b741bea1061af44f0748 100644 (file)
@@ -47,50 +47,66 @@ static size_t get_delta_header_size(uint8_t *delta, int *index, int length)
        return size;
 }
 
-
-static PyObject *py_apply_delta(PyObject *self, PyObject *args)
+static PyObject *py_chunked_as_string(PyObject *py_buf)
 {
-       uint8_t *src_buf, *delta;
-       int src_buf_len, delta_len;
-       size_t src_size, dest_size;
-       size_t outindex = 0;
-       int index;
-       uint8_t *out;
-       PyObject *ret, *py_src_buf;
-
-       if (!PyArg_ParseTuple(args, "Os#", &py_src_buf,
-                                                 (uint8_t *)&delta, &delta_len))
-               return NULL;
-
-       if (PyList_Check(py_src_buf)) {
+       if (PyList_Check(py_buf)) {
                PyObject *sep = PyString_FromString("");
                if (sep == NULL) {
                        PyErr_NoMemory();
                        return NULL;
                }
-               py_src_buf = _PyString_Join(sep, py_src_buf);
+               py_buf = _PyString_Join(sep, py_buf);
                Py_DECREF(sep);
-               if (py_src_buf == NULL) {
+               if (py_buf == NULL) {
                        PyErr_NoMemory();
                        return NULL;
                }
-       } else if (PyString_Check(py_src_buf)) {
-               Py_INCREF(py_src_buf);
+       } else if (PyString_Check(py_buf)) {
+               Py_INCREF(py_buf);
        } else {
                PyErr_SetString(PyExc_TypeError,
                        "src_buf is not a string or a list of chunks");
                return NULL;
        }
+    return py_buf;
+}
+
+static PyObject *py_apply_delta(PyObject *self, PyObject *args)
+{
+       uint8_t *src_buf, *delta;
+       int src_buf_len, delta_len;
+       size_t src_size, dest_size;
+       size_t outindex = 0;
+       int index;
+       uint8_t *out;
+       PyObject *ret, *py_src_buf, *py_delta;
+
+       if (!PyArg_ParseTuple(args, "OO", &py_src_buf, &py_delta))
+               return NULL;
+
+    py_src_buf = py_chunked_as_string(py_src_buf);
+    if (py_src_buf == NULL)
+        return NULL;
+
+    py_delta = py_chunked_as_string(py_delta);
+    if (py_delta == NULL) {
+        Py_DECREF(py_src_buf);
+        return NULL;
+    }
 
        src_buf = (uint8_t *)PyString_AS_STRING(py_src_buf);
        src_buf_len = PyString_GET_SIZE(py_src_buf);
 
+    delta = (uint8_t *)PyString_AS_STRING(py_delta);
+    delta_len = PyString_GET_SIZE(py_delta);
+
     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);
+               Py_DECREF(py_delta);
                return NULL;
        }
     dest_size = get_delta_header_size(delta, &index, delta_len);
@@ -98,6 +114,7 @@ static PyObject *py_apply_delta(PyObject *self, PyObject *args)
        if (ret == NULL) {
                PyErr_NoMemory();
                Py_DECREF(py_src_buf);
+               Py_DECREF(py_delta);
                return NULL;
        }
        out = (uint8_t *)PyString_AsString(ret);
@@ -136,11 +153,13 @@ static PyObject *py_apply_delta(PyObject *self, PyObject *args)
                } else {
                        PyErr_SetString(PyExc_ValueError, "Invalid opcode 0");
                        Py_DECREF(ret);
+            Py_DECREF(py_delta);
                        Py_DECREF(py_src_buf);
                        return NULL;
                }
        }
        Py_DECREF(py_src_buf);
+    Py_DECREF(py_delta);
     
     if (index != delta_len) {
                PyErr_SetString(PyExc_ValueError, "delta not empty");
index 7bf61a390b3750948c76ec3817aaae2255c83315..18a96ac4dc6047a547c1a15f3f9485b87456e8f0 100644 (file)
@@ -446,9 +446,8 @@ def _compute_object_size((num, obj)):
     """Compute the size of a unresolved object for use with LRUSizeCache.
     """
     if num in (6, 7):
-        return len(obj[1])
-    assert isinstance(obj, str)
-    return len(obj)
+        return chunks_length(obj[1])
+    return chunks_length(obj)
 
 
 class PackData(object):
@@ -548,14 +547,12 @@ class PackData(object):
         if type == 6: # offset delta
             (delta_offset, delta) = obj
             assert isinstance(delta_offset, int)
-            assert isinstance(delta, str)
             base_offset = offset-delta_offset
             type, base_obj = get_offset(base_offset)
             assert isinstance(type, int)
         elif type == 7: # ref delta
             (basename, delta) = obj
             assert isinstance(basename, str) and len(basename) == 20
-            assert isinstance(delta, str)
             type, base_obj = get_ref(basename)
             assert isinstance(type, int)
             # Can't be a ofs delta, as we wouldn't know the base offset
@@ -962,7 +959,8 @@ def apply_delta(src_buf, delta):
     """
     if type(src_buf) != str:
         src_buf = "".join(src_buf)
-    assert isinstance(delta, str)
+    if type(delta) != str:
+        delta = "".join(delta)
     out = []
     index = 0
     delta_length = len(delta)