Browse Source

Allow delta's to be chunked as well.

Jelmer Vernooij 15 years ago
parent
commit
8ed151e147
2 changed files with 42 additions and 25 deletions
  1. 38 19
      dulwich/_pack.c
  2. 4 6
      dulwich/pack.py

+ 38 - 19
dulwich/_pack.c

@@ -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");

+ 4 - 6
dulwich/pack.py

@@ -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)