Browse Source

Accept chunked contents for apply_delta base texts.

Jelmer Vernooij 15 years ago
parent
commit
997e077366
3 changed files with 33 additions and 5 deletions
  1. 29 2
      dulwich/_pack.c
  2. 1 1
      dulwich/objects.py
  3. 3 2
      dulwich/pack.py

+ 29 - 2
dulwich/_pack.c

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

+ 1 - 1
dulwich/objects.py

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

+ 3 - 2
dulwich/pack.py

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