Half implemented decompression. Need to figure out how to handle group size adjustment on decompressed data.
This commit is contained in:
@@ -23,8 +23,17 @@ int main(void) {
|
|||||||
size_t read = fread(buffer, sizeof(char), size, fp);
|
size_t read = fread(buffer, sizeof(char), size, fp);
|
||||||
assert(read == size);
|
assert(read == size);
|
||||||
|
|
||||||
size_t formids = espr_formid_count(buffer, size);
|
size_t dc_size = espr_decompressed_size(buffer, size);
|
||||||
printf("FormID Count: %zu\n", formids);
|
|
||||||
|
char *decompressed = malloc(dc_size);
|
||||||
|
if (!decompressed)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
espr_decompress(buffer, size, decompressed, dc_size);
|
||||||
|
|
||||||
|
size_t formid_count = espr_formid_count(decompressed, dc_size);
|
||||||
|
|
||||||
|
printf("FormID Count: %zu\n", formid_count);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -277,6 +277,12 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
size_t espr_formid_count(char *data, size_t size);
|
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
|
// End C++ guard
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
|
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
@@ -45,6 +46,7 @@ Timestamp convert_ts(uint16_t ts);
|
|||||||
void print_callback(Node n, void *_);
|
void print_callback(Node n, void *_);
|
||||||
void dc_size_cb(Node n, void *dc_size_ptr);
|
void dc_size_cb(Node n, void *dc_size_ptr);
|
||||||
void formid_count_cb(Node n, void *count_ptr);
|
void formid_count_cb(Node n, void *count_ptr);
|
||||||
|
void decompress_cb(Node n, void *decom_ptr);
|
||||||
|
|
||||||
//
|
//
|
||||||
// === FUNCTIONS ===
|
// === 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.
|
/* Unknown data will be some concatenation of groups and records.
|
||||||
*
|
*
|
||||||
* `walk_concat` will call the appropriate walking function
|
* `walk_concat` will call the appropriate walking function
|
||||||
|
|||||||
Reference in New Issue
Block a user