change: decompress the 'contents' with zstd_seekable

laumann
Aug 18, 2022, 8:12 AM
RIWSVVASWLJQQTSVRHIIUPENOZWOMHQLZMTQVGJUS2ZUGDPSWWIQC

Dependencies

  • [2] QEFCNNVC change: display offsets for given change file
  • [3] Q7TKZCJP Add initial support for reading the offsets from a (fixed) change

Change contents

  • edit in change.c at line 7
    [3.1191]
    [3.1191]
    #include <stdlib.h>
    #include <zstd.h>
  • edit in change.c at line 10
    [3.1192]
    [3.1192]
    #include "zstd_seekable.h"
  • edit in change.c at line 43
    [3.2195]
    [3.2195]
    }
    void
    dump_buf(const char *name, uint8_t *buf, size_t len)
    {
    int i;
    if (len == 0) {
    printf("%s = []\n", name);
    return;
    }
    printf("%s = [%u", name, buf[0]);
    for (i = 1; i < len; i++)
    printf(", %u", buf[i]);
    printf("]\n");
  • edit in change.c at line 62
    [2.4]
    [2.4]
    * Read the contents section of the open change file, decompress it and return
    * the raw bytes.
    *
    * Returns a malloc()'ed byte buffer that the caller is responsible for
    * deallocating. Returns NULL if the full contents could not be read, or the
    * decompression failed, or some other error occurred.
    */
    uint8_t *
    read_contents(int fd, struct offsets *off)
    {
    /**
    * Allocate two buffers: one for compressed data, and one for
    * decompressed data. The decompressed data buffer is the return value.
    */
    uint8_t *compressed;
    uint8_t *buf;
    size_t compressed_to_read;
    ssize_t compressed_read;
    ZSTD_seekable *zs;
    size_t result;
    compressed_to_read = off->total - off->contents_off;
    printf("expecting to read %lu bytes (compressed)\n", compressed_to_read);
    compressed = calloc(sizeof(uint8_t), compressed_to_read);
    if (compressed == NULL) {
    perror("malloc compressed");
    exit(1);
    }
    buf = calloc(sizeof(uint8_t), off->contents_len);
    if (buf == NULL) {
    perror("malloc buf");
    exit(1);
    }
    /* Read data into compressed */
    compressed_read = read(fd, compressed, compressed_to_read);
    if (compressed_read != compressed_to_read) {
    fprintf(stderr, "error: Expected to read %lu bytes, got %lu\n",
    compressed_to_read, compressed_read);
    goto errout;
    }
    dump_buf("compressed", compressed, compressed_read);
    zs = ZSTD_seekable_create();
    if (zs == NULL) {
    fprintf(stderr, "ZSTD_seekable_create() failed");
    goto errout;
    }
    result = ZSTD_seekable_initBuff(zs, compressed, compressed_to_read);
    if (ZSTD_isError(result)) {
    fprintf(stderr, "ZSTD_seekable_init() error: %s\n",
    ZSTD_getErrorName(result));
    goto outfreezs;
    }
    result = ZSTD_seekable_decompress(zs, buf, off->contents_len, 0);
    printf("decompress result: %lu\n", result);
    if (ZSTD_isError(result)) {
    fprintf(stderr, "ZSTD_seekable_decompress() error: %s\n",
    ZSTD_getErrorName(result));
    goto outfreezs;
    }
    if (result != off->contents_len) {
    fprintf(stderr, "decoded %lu bytes, wanted %lu\n", result, off->contents_len);
    goto outfreezs;
    }
    /** Success! decompressed all that we wanted */
    dump_buf("contents", buf, off->contents_len);
    ZSTD_seekable_free(zs);
    goto out;
    outfreezs:
    ZSTD_seekable_free(zs);
    errout:
    free(buf);
    buf = NULL;
    out:
    free(compressed);
    return buf;
    }
    /**
  • edit in change.c at line 156
    [3.2254]
    [2.122]
    uint8_t *contents;
  • edit in change.c at line 182
    [3.2587]
    [3.2587]
    /**
    * Seek to the point in the file where contents begin. Keep in mind,
    * we've already read 56 bytes.
    *
    * seek to off.contents_off - OFFSETS_SIZE
    */
    if (lseek(fd, off.contents_off, SEEK_SET) == -1) {
    perror("lseek");
    goto out;
    }
    contents = read_contents(fd, &off);
  • replacement in change.c at line 212
    [2.405][2.405:416]()
    size_t l;
    [2.405]
    [2.416]
    size_t hash_len;
  • replacement in change.c at line 224
    [2.607][2.607:725]()
    if ((l = strnlen(hash, 54)) != 53) {
    fprintf(stderr, "error: hash must be exactly 53 characters (got: %lu)\n", l);
    [2.607]
    [2.725]
    if ((hash_len = strnlen(hash, 54)) != 53) {
    fprintf(stderr, "error: hash must be exactly 53 characters (got: %lu)\n", hash_len);