commit 35e9ba5d1cb044ee42c15d31ff663c7d16b25daf from: Stefan Sperling date: Thu Jun 21 17:41:20 2018 UTC introduce got_object_blob_dump_to_file() 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; }