From: Joel Rosdahl Date: Wed, 3 Jul 2019 21:19:59 +0000 (+0200) Subject: Refactor result_get code into functions per marker type X-Git-Tag: v4.0~906 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=3c87f41dbcb20ff2cba8f4a33f17df2901a3cda8;p=thirdparty%2Fccache.git Refactor result_get code into functions per marker type In preparation for reimplementing the hard link mode. --- diff --git a/src/result.c b/src/result.c index 5fb8eea1b..e2db4edb4 100644 --- a/src/result.c +++ b/src/result.c @@ -25,51 +25,53 @@ // // Integers are big-endian. // -// ::=
-//
::= -// ::= 4 bytes ("cCrS") -// ::= uint8_t -// ::= | -// ::= 0 (uint8_t) -// ::= 1 (uint8_t) -// ::= int8_t -// ::= uint64_t ; size of file if stored uncompressed -// ::= * ; body is potentially compressed -// ::= uint8_t -// ::= | -// ::= -// ::= 0 (uint8_t) -// ::= uint8_t -// ::= suffix_len bytes -// ::= uint64_t -// ::= data_len bytes -// ::= -// ::= 1 (uint8_t) -// ::= uint8_t -// ::= key_len bytes -// ::= -// ::= uint64_t ; XXH64 of content bytes +// ::=
+//
::= +// +// ::= 4 bytes ("cCrS") +// ::= uint8_t +// ::= | +// ::= 0 (uint8_t) +// ::= 1 (uint8_t) +// ::= int8_t +// ::= uint64_t ; size of file if stored uncompressed +// ::= * ; potentially compressed +// ::= uint8_t +// ::= | +// ::= +// +// ::= 0 (uint8_t) +// ::= uint8_t +// ::= suffix_len bytes +// ::= uint64_t +// ::= data_len bytes +// ::= +// ::= 1 (uint8_t) +// ::= uint8_t +// ::= key_len bytes +// ::= +// ::= uint64_t ; XXH64 of content bytes // // Sketch of concrete layout: // -// 4 bytes -// 1 byte -// 1 byte -// 1 byte -// 8 bytes +// 4 bytes +// 1 byte +// 1 byte +// 1 byte +// 8 bytes // --- [potentially compressed from here] ------------------------------------- -// 1 byte -// 1 byte -// 1 byte -// suffix_len bytes -// 8 bytes -// data_len bytes +// 1 byte +// 1 byte +// 1 byte +// suffix_len bytes +// 8 bytes +// data_len bytes // ... -// 1 byte -// 1 byte -// key_len bytes +// 1 byte +// 1 byte +// key_len bytes // ... -// checksum 8 bytes +// checksum 8 bytes // // // Version history @@ -80,8 +82,11 @@ const char RESULT_MAGIC[4] = "cCrS"; enum { - FILE_MARKER = 0, - REF_MARKER = 1 + // File data stored inside the result file. + EMBEDDED_FILE_MARKER = 0, + + // File stored as-is in the file system. + RAW_FILE_MARKER = 1 }; struct result_file { @@ -157,6 +162,88 @@ result_files_free(struct result_files *list) (var) = UINT64_FROM_BYTES(buf_); \ } while (false) +static bool +read_embedded_file_entry( + struct decompressor *decompressor, + struct decompr_state *decompr_state, + uint32_t entry_number, + struct result_files *list, + FILE *dump_stream) +{ + bool success = false; + FILE *subfile = NULL; + + uint8_t suffix_len; + READ_BYTE(suffix_len); + + char suffix[256 + 1]; + READ_BYTES(suffix, suffix_len); + suffix[suffix_len] = '\0'; + + uint64_t filelen; + READ_UINT64(filelen); + + cc_log("Reading embedded file #%u: %s (%llu)", + entry_number, + str_eq(suffix, "stderr") ? "" : suffix, + (unsigned long long)filelen); + + bool found = false; + if (dump_stream) { + fprintf(dump_stream, + "Entry: %s (size: %" PRIu64 " bytes)\n", + str_eq(suffix, "stderr") ? "" : suffix, + filelen); + } else { + for (uint32_t i = 0; i < list->n_files; i++) { + if (str_eq(suffix, list->files[i].suffix)) { + found = true; + + cc_log("Copying to %s", list->files[i].path); + + subfile = fopen(list->files[i].path, "wb"); + if (!subfile) { + cc_log("Failed to open %s for writing", list->files[i].path); + goto out; + } + char buf[READ_BUFFER_SIZE]; + size_t remain = filelen; + while (remain > 0) { + size_t n = MIN(remain, sizeof(buf)); + READ_BYTES(buf, n); + if (fwrite(buf, 1, n, subfile) != n) { + goto out; + } + remain -= n; + } + fclose(subfile); + subfile = NULL; + + break; + } + } + } + if (!found) { + // Discard the file data. + char buf[READ_BUFFER_SIZE]; + size_t remain = filelen; + while (remain > 0) { + size_t n = MIN(remain, sizeof(buf)); + READ_BYTES(buf, n); + remain -= n; + } + } + + success = true; + +out: + if (subfile) { + fclose(subfile); + } + + return success; +} + static bool read_result( const char *path, @@ -168,7 +255,6 @@ read_result( bool success = false; struct decompressor *decompressor = NULL; struct decompr_state *decompr_state = NULL; - FILE *subfile = NULL; XXH64_state_t *checksum = XXH64_createState(); FILE *f = fopen(path, "rb"); @@ -202,11 +288,16 @@ read_result( for (i = 0; i < n_entries; i++) { uint8_t marker; READ_BYTE(marker); + switch (marker) { - case FILE_MARKER: + case EMBEDDED_FILE_MARKER: + if (!read_embedded_file_entry( + decompressor, decompr_state, i, list, dump_stream)) { + goto out; + } break; - case REF_MARKER: + case RAW_FILE_MARKER: // TODO: Implement. // Fall through. @@ -214,65 +305,6 @@ read_result( *errmsg = format("Unknown entry type: %u", marker); goto out; } - - uint8_t suffix_len; - READ_BYTE(suffix_len); - - char suffix[256 + 1]; - READ_BYTES(suffix, suffix_len); - suffix[suffix_len] = '\0'; - - uint64_t filelen; - READ_UINT64(filelen); - - cc_log("Reading entry #%u: %s (%llu)", - i, - str_eq(suffix, "stderr") ? "" : suffix, - (unsigned long long)filelen); - - bool found = false; - if (dump_stream) { - fprintf(dump_stream, - "Entry: %s (size: %" PRIu64 " bytes)\n", - str_eq(suffix, "stderr") ? "" : suffix, - filelen); - } else { - for (uint32_t j = 0; j < list->n_files; j++) { - if (str_eq(suffix, list->files[j].suffix)) { - found = true; - - cc_log("Copying to %s", list->files[j].path); - - subfile = fopen(list->files[j].path, "wb"); - if (!subfile) { - cc_log("Failed to open %s for writing", list->files[j].path); - goto out; - } - char buf[READ_BUFFER_SIZE]; - size_t remain = filelen; - while (remain > 0) { - size_t n = MIN(remain, sizeof(buf)); - READ_BYTES(buf, n); - if (fwrite(buf, 1, n, subfile) != n) { - goto out; - } - remain -= n; - } - fclose(subfile); - subfile = NULL; - } - } - } - if (!found) { - // Discard the file data. - char buf[READ_BUFFER_SIZE]; - size_t remain = filelen; - while (remain > 0) { - size_t n = MIN(remain, sizeof(buf)); - READ_BYTES(buf, n); - remain -= n; - } - } } if (i != n_entries) { @@ -294,9 +326,6 @@ read_result( } out: - if (subfile) { - fclose(subfile); - } if (decompressor && !decompressor->free(decompr_state)) { success = false; } @@ -347,7 +376,7 @@ write_result( (unsigned long long)list->files[i].size, list->files[i].path); - WRITE_BYTE(FILE_MARKER); + WRITE_BYTE(EMBEDDED_FILE_MARKER); size_t suffix_len = strlen(list->files[i].suffix); WRITE_BYTE(suffix_len); WRITE_BYTES(list->files[i].suffix, suffix_len); @@ -413,7 +442,7 @@ bool result_put(const char *path, struct result_files *list) uint64_t content_size = COMMON_HEADER_SIZE; content_size += 1; // n_entries for (uint32_t i = 0; i < list->n_files; i++) { - content_size += 1; // file_marker + content_size += 1; // embedded_file_marker content_size += 1; // suffix_len content_size += strlen(list->files[i].suffix); // suffix content_size += 8; // data_len