introduce got_object_blob_dump_to_file()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
diff --git a/include/got_object.h b/include/got_object.h
index 6687d7a..60c0249 100644
--- a/include/got_object.h
+++ b/include/got_object.h
@@ -179,6 +179,14 @@ const uint8_t *got_object_blob_get_read_buf(struct got_blob_object *);
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 *);
diff --git a/lib/diff.c b/lib/diff.c
index 94feecd..2fb482f 100644
--- a/lib/diff.c
+++ b/lib/diff.c
@@ -44,7 +44,6 @@ got_diff_blob(struct got_blob_object *blob1, struct got_blob_object *blob2,
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 got_blob_object *blob2,
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;
diff --git a/lib/object.c b/lib/object.c
index 7e037bb..559dc54 100644
--- a/lib/object.c
+++ b/lib/object.c
@@ -1358,6 +1358,34 @@ got_object_blob_read_block(size_t *outlenp, struct got_blob_object *blob)
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;
+}
+
static struct got_tree_entry *
find_entry_by_name(struct got_tree_object *tree, const char *name)
{