* 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;
}
/**