Half implemented decompression. Need to figure out how to handle group size adjustment on decompressed data.
This commit is contained in:
@@ -277,6 +277,12 @@ extern "C" {
|
||||
*/
|
||||
size_t espr_formid_count(char *data, size_t size);
|
||||
|
||||
/* Copies the data from `data` to `buf` decompressing compressed fields as
|
||||
* it does so. buf_size should be the value returned from `espr_decompressed_size`,
|
||||
* and `buf` should be at least of that size.
|
||||
*/
|
||||
void espr_decompress(char *data, size_t size, char *buf, size_t buf_size);
|
||||
|
||||
// End C++ guard
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <intrin.h>
|
||||
|
||||
#include "zlib.h"
|
||||
@@ -45,6 +46,7 @@ Timestamp convert_ts(uint16_t ts);
|
||||
void print_callback(Node n, void *_);
|
||||
void dc_size_cb(Node n, void *dc_size_ptr);
|
||||
void formid_count_cb(Node n, void *count_ptr);
|
||||
void decompress_cb(Node n, void *decom_ptr);
|
||||
|
||||
//
|
||||
// === FUNCTIONS ===
|
||||
@@ -135,6 +137,63 @@ void formid_count_cb(Node n, void *count_ptr) {
|
||||
}
|
||||
}
|
||||
|
||||
struct decom {
|
||||
char *buf;
|
||||
char *start;
|
||||
size_t remaining;
|
||||
};
|
||||
|
||||
void espr_decompress(char *data, size_t size, char *buf, size_t buf_size) {
|
||||
struct decom s = { .buf = buf, .start = data, .remaining = buf_size };
|
||||
espr_walk(data, size, decompress_cb, &s);
|
||||
|
||||
// handle final segment
|
||||
size_t remaining = buf_size - (s.buf - buf);
|
||||
assert(remaining == s.remaining);
|
||||
memcpy(s.buf, s.start, remaining);
|
||||
}
|
||||
|
||||
void decompress_cb(Node n, void *decom_ptr) {
|
||||
struct decom *d = decom_ptr;
|
||||
|
||||
// only need to do anything when we find a compressed flag
|
||||
if (n.type == NT_RECORD && n.header.record->flags & COMPRESSED_FLAG) {
|
||||
// uncompressed segment copy
|
||||
size_t size = n.data - d->start;
|
||||
assert(size < d->remaining);
|
||||
memcpy(d->buf, d->start, size);
|
||||
|
||||
// update decom struct
|
||||
d->remaining -= size;
|
||||
d->buf += size;
|
||||
|
||||
// copied header
|
||||
Record *header = (Record *)(d->buf) - 1;
|
||||
|
||||
// decompress directly into buffer
|
||||
const size_t dc_size = *((uint32_t *)n.data);
|
||||
size_t to_copy = dc_size;
|
||||
size_t cur_size = n.header.record->size - sizeof(uint32_t);
|
||||
char *data_start = n.data + sizeof(uint32_t);
|
||||
int ret = uncompress(d->buf, &to_copy, data_start, cur_size);
|
||||
assert(ret == Z_OK);
|
||||
assert(to_copy == dc_size);
|
||||
|
||||
// update decom struct
|
||||
d->remaining -= dc_size;
|
||||
d->buf += dc_size;
|
||||
|
||||
// update start to start of next record/group
|
||||
d->start = n.data + n.header.record->size;
|
||||
|
||||
// update header data size
|
||||
header->size = dc_size;
|
||||
|
||||
// unset compressed flag
|
||||
header->flags &= ~COMPRESSED_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unknown data will be some concatenation of groups and records.
|
||||
*
|
||||
* `walk_concat` will call the appropriate walking function
|
||||
|
||||
Reference in New Issue
Block a user