Skip to content

Instantly share code, notes, and snippets.

@AeroStun
Last active March 7, 2020 19:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AeroStun/687ec9ca69404e26f8e02e5084926036 to your computer and use it in GitHub Desktop.
Save AeroStun/687ec9ca69404e26f8e02e5084926036 to your computer and use it in GitHub Desktop.
enum class stream_wrapper {
none,
zlib, // RFC1950
gzip, // RFC1952
dynamic // all three types are allowed and can be chosen at compile-time
};
template <stream_wrapper wrap = stream_wrapper::none>
class basic_deflate_stream;
using raw_deflate_stream = basic_deflate_stream<>;
using zlib_stream = basic_deflate_stream<stream_wrapper::zlib>
using gzip_stream = basic_deflate_stream<stream_wrapper::gzip>;
using deflate_stream = basic_deflate_stream<stream_wrapper::dynamic>
template <>
class basic_deflate_stream<stream_wrapper::none> {
// initializes the stream with some default values
basic_deflate_stream();
// resets the stream
void reset();
// resets the stream, and reinitializes it with user-provided values
void reset(int level, int windowBits, int memLevel, Strategy strategy);
// estimates how many bytes does one need to store `sourceLen` bytes after compression with the current stream parameters
std::size_t upper_bound(std::size_t sourceLen) const;
// fine-tunes internal compression parameters
void tune(int good_length, int max_lazy, int nice_length, int max_chain);
// compresses bytes from the input in `zs` to the output also specified in `zs`, with `flush` indicating when to flush pending compressed input, and errors put in `ec`
void write(z_params& zs, Flush flush, error_code& ec);
// dynamically updates the `level` and `strategy`, reporting errors via `ec`
void params(z_params& zs, int level, Strategy strategy, error_code& ec);
// gives how many bytes and extra bits are waiting to be flushed to the output
void pending(unsigned *bytes, int *bits); /// Should this maybe return a struct like std::div does?
// primes the stream buffers with `bits` bits from `value` (at most 16); errors are reported through `ec`
void prime(int bits, int value, error_code& ec);
};
template <>
class basic_deflate_stream<stream_wrapper::zlib> {
/* Same as above, except the output is in the zlib format */
};
template <>
class basic_deflate_stream<stream_wrapper::gzip> {
/* Same as above, except the output is in the gzip format */
// Gives the stream a location to put the gzip header, or clears it with nullptr
void set_headerp(gz_header* gzhead);
};
template <>
class basic_deflate_stream<stream_wrapper::dynamic> {
/* Same as the combination of the above, except `reset` takes the wrapper type as a fourth parameter */
};
optional<std::string> easy_compress(string_view in, stream_wrapper wrapping = stream_wrapper::none);
optional<std::string> easy_uncompress(string_view in, stream_wrapper wrapping = stream_wrapper::none);
// Note 1: A given stream type will make sure not to run any code that it does not need for its wrapper.
// Note 2: all stream types currently share the same `z_params`. As a user would you prefer having one params type per stream type in order to reduce sizeof(params) when possible, or is intercompatibility between streams more important?
// Note 3: in the same way, the inflate_stream family would be declared, albeit with only `write` and `reset`, as well as an additional `clear` method
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment