A fork of https://github.com/crosspoint-reader/crosspoint-reader
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at records-reader 78 lines 2.3 kB view raw
1#include "InflateReader.h" 2 3#include <cstring> 4#include <type_traits> 5 6namespace { 7constexpr size_t INFLATE_DICT_SIZE = 32768; 8} 9 10// Guarantee the cast pattern in the header comment is valid. 11static_assert(std::is_standard_layout<InflateReader>::value, 12 "InflateReader must be standard-layout for the uzlib callback cast to work"); 13 14InflateReader::~InflateReader() { deinit(); } 15 16bool InflateReader::init(const bool streaming) { 17 deinit(); // free any previously allocated ring buffer and reset state 18 19 if (streaming) { 20 ringBuffer = static_cast<uint8_t*>(malloc(INFLATE_DICT_SIZE)); 21 if (!ringBuffer) return false; 22 memset(ringBuffer, 0, INFLATE_DICT_SIZE); 23 } 24 25 uzlib_uncompress_init(&decomp, ringBuffer, ringBuffer ? INFLATE_DICT_SIZE : 0); 26 return true; 27} 28 29void InflateReader::deinit() { 30 if (ringBuffer) { 31 free(ringBuffer); 32 ringBuffer = nullptr; 33 } 34 memset(&decomp, 0, sizeof(decomp)); 35} 36 37void InflateReader::setSource(const uint8_t* src, size_t len) { 38 decomp.source = src; 39 decomp.source_limit = src + len; 40} 41 42void InflateReader::setReadCallback(int (*cb)(struct uzlib_uncomp*)) { decomp.source_read_cb = cb; } 43 44void InflateReader::skipZlibHeader() { 45 uzlib_get_byte(&decomp); 46 uzlib_get_byte(&decomp); 47} 48 49bool InflateReader::read(uint8_t* dest, size_t len) { 50 if (!ringBuffer) { 51 // One-shot mode: back-references use absolute offset from dest_start. 52 // Valid only when read() is called once with the full output buffer. 53 decomp.dest_start = dest; 54 } 55 decomp.dest = dest; 56 decomp.dest_limit = dest + len; 57 58 const int res = uzlib_uncompress(&decomp); 59 if (res < 0) return false; 60 return decomp.dest == decomp.dest_limit; 61} 62 63InflateStatus InflateReader::readAtMost(uint8_t* dest, size_t maxLen, size_t* produced) { 64 if (!ringBuffer) { 65 // One-shot mode: back-references use absolute offset from dest_start. 66 // Valid only when readAtMost() is called once with the full output buffer. 67 decomp.dest_start = dest; 68 } 69 decomp.dest = dest; 70 decomp.dest_limit = dest + maxLen; 71 72 const int res = uzlib_uncompress(&decomp); 73 *produced = static_cast<size_t>(decomp.dest - dest); 74 75 if (res == TINF_DONE) return InflateStatus::Done; 76 if (res < 0) return InflateStatus::Error; 77 return InflateStatus::Ok; 78}