Commit Diff


commit - 730c718b4e7767bb2d4da775f58804d8cacbc530
commit + 35e9ba5d1cb044ee42c15d31ff663c7d16b25daf
blob - 6687d7a01fd4ec3044033b802990e13135f72b4b
blob + 60c024909bd661ac5ba3c006a17501e2ad3e1ed4
--- include/got_object.h
+++ include/got_object.h
@@ -179,6 +179,14 @@ const uint8_t *got_object_blob_get_read_buf(struct got
 const struct got_error *got_object_blob_read_block(size_t *,
     struct got_blob_object *);
 
+/*
+ * Read the entire content of a blob and write it to the specified file.
+ * Flush and rewind the file as well, and indicate the amount of bytes
+ * written in the size_t output argument.
+ */
+const struct got_error *got_object_blob_dump_to_file(size_t *, FILE *,
+    struct got_blob_object *);
+
 const struct got_error *
 got_object_open_as_commit(struct got_commit_object **,
     struct got_repository *, struct got_object_id *);
blob - 94feecd2d6cb9b1250f7594b6f9f27977135dfa6
blob + 2fb482f6e9a84df16124b0c3c805b68224bea7b4
--- lib/diff.c
+++ lib/diff.c
@@ -44,7 +44,6 @@ got_diff_blob(struct got_blob_object *blob1, struct go
 	char hex1[SHA1_DIGEST_STRING_LENGTH];
 	char hex2[SHA1_DIGEST_STRING_LENGTH];
 	char *idstr1 = NULL, *idstr2 = NULL;
-	size_t len, hdrlen;
 	size_t size1, size2;
 	int res, flags = 0;
 
@@ -67,50 +66,21 @@ got_diff_blob(struct got_blob_object *blob1, struct go
 	size1 = 0;
 	if (blob1) {
 		idstr1 = got_object_blob_id_str(blob1, hex1, sizeof(hex1));
-		hdrlen = got_object_blob_get_hdrlen(blob1);
-		do {
-			err = got_object_blob_read_block(&len, blob1);
-			if (err)
-				goto done;
-			if (len == 0)
-				break;
-			size1 += len;
-			/* Skip blob object header first time around. */
-			fwrite(got_object_blob_get_read_buf(blob1) + hdrlen,
-			    len - hdrlen, 1, f1);
-			hdrlen = 0;
-		} while (len != 0);
+		err = got_object_blob_dump_to_file(&size1, f1, blob1);
+		if (err)
+			goto done;
 	} else
 		idstr1 = "/dev/null";
 
 	size2 = 0;
 	if (blob2) {
 		idstr2 = got_object_blob_id_str(blob2, hex2, sizeof(hex2));
-		hdrlen = got_object_blob_get_hdrlen(blob2);
-		do {
-			err = got_object_blob_read_block(&len, blob2);
-			if (err)
-				goto done;
-			if (len == 0)
-				break;
-			size2 += len;
-			/* Skip blob object header first time around. */
-			fwrite(got_object_blob_get_read_buf(blob2) + hdrlen,
-			    len - hdrlen, 1, f2);
-			hdrlen = 0;
-		} while (len != 0);
+		err = got_object_blob_dump_to_file(&size2, f2, blob2);
+		if (err)
+			goto done;
 	} else
 		idstr2 = "/dev/null";
 
-	if (f1) {
-		fflush(f1);
-		rewind(f1);
-	}
-	if (f2) {
-		fflush(f2);
-		rewind(f2);
-	}
-
 	memset(&ds, 0, sizeof(ds));
 	/* XXX should stat buffers be passed in args instead of ds? */
 	ds.stb1.st_mode = S_IFREG;
blob - 7e037bbba1c2f2cf32211f9bc9ad9dd6a060568e
blob + 559dc5485e4ac33b36cdae46f20eedd575d06bb9
--- lib/object.c
+++ lib/object.c
@@ -1355,6 +1355,34 @@ got_object_blob_read_block(size_t *outlenp, struct got
 	if (n == 0 && ferror(blob->f))
 		return got_ferror(blob->f, GOT_ERR_IO);
 	*outlenp = n;
+	return NULL;
+}
+
+const struct got_error *
+got_object_blob_dump_to_file(size_t *total_len, FILE *outfile,
+    struct got_blob_object *blob)
+{
+	const struct got_error *err = NULL;
+	size_t len, hdrlen;
+
+	*total_len = 0;
+	hdrlen = got_object_blob_get_hdrlen(blob);
+	do {
+		err = got_object_blob_read_block(&len, blob);
+		if (err)
+			return err;
+		if (len == 0)
+			break;
+		*total_len += len;
+		/* Skip blob object header first time around. */
+		fwrite(got_object_blob_get_read_buf(blob) + hdrlen,
+		    len - hdrlen, 1, outfile);
+		hdrlen = 0;
+	} while (len != 0);
+
+	fflush(outfile);
+	rewind(outfile);
+
 	return NULL;
 }