diff --git a/include/boost/capy/brotli.hpp b/include/boost/capy/brotli.hpp index 6e449d8c..cb7c3794 100644 --- a/include/boost/capy/brotli.hpp +++ b/include/boost/capy/brotli.hpp @@ -7,6 +7,30 @@ // Official repository: https://github.com/cppalliance/capy // +/** @file + Brotli compression and decompression library. + + This header includes all Brotli-related functionality including + encoding, decoding, error handling, and shared dictionary support. + + Brotli is a generic-purpose lossless compression algorithm that compresses + data using a combination of a modern variant of the LZ77 algorithm, Huffman + coding and 2nd order context modeling, with a compression ratio comparable + to the best currently available general-purpose compression methods. + + @code + #include + #include + + // Create a datastore for services + boost::capy::datastore ctx; + + // Install compression and decompression services + auto& encoder = boost::capy::brotli::install_encode_service(ctx); + auto& decoder = boost::capy::brotli::install_decode_service(ctx); + @endcode +*/ + #ifndef BOOST_CAPY_BROTLI_HPP #define BOOST_CAPY_BROTLI_HPP diff --git a/include/boost/capy/brotli/decode.hpp b/include/boost/capy/brotli/decode.hpp index eaa886e4..6158224a 100644 --- a/include/boost/capy/brotli/decode.hpp +++ b/include/boost/capy/brotli/decode.hpp @@ -22,19 +22,36 @@ namespace brotli { /** Opaque structure that holds decoder state. */ struct decoder_state; -/** Result type for decompress and decompress_stream functions. */ +/** Decoder result codes. + + These values indicate the result of decompression operations. +*/ enum class decoder_result { + /** Decompression error occurred. */ error = 0, + + /** Decompression completed successfully. */ success = 1, + + /** More input data is needed. */ needs_more_input = 2, + + /** More output space is needed. */ needs_more_output = 3 }; -/** Options to be used with set_parameter. */ +/** Decoder parameter identifiers. + + These values identify parameters that can be set + on a decoder instance. +*/ enum class decoder_param { + /** Disable automatic ring buffer reallocation. */ disable_ring_buffer_reallocation = 0, + + /** Enable large window mode. */ large_window = 1 }; @@ -44,25 +61,96 @@ using metadata_start_func = void (*)(void* opaque, std::size_t size); /** Callback to fire on metadata block chunk becomes available. */ using metadata_chunk_func = void (*)(void* opaque, const std::uint8_t* data, std::size_t size); -/** Provides the Brotli decompression API */ +/** Provides the Brotli decompression API. + + This service interface exposes Brotli decoder functionality + through a set of virtual functions. The decoder can operate + in one-shot mode for simple decompression or streaming mode + for processing data in chunks. + + @code + // Example: Simple one-shot decompression + boost::capy::datastore ctx; + auto& decoder = boost::capy::brotli::install_decode_service(ctx); + + std::vector compressed_data = get_compressed_data(); + std::vector output(1024 * 1024); // 1MB buffer + std::size_t decoded_size = output.size(); + + auto result = decoder.decompress( + compressed_data.size(), + compressed_data.data(), + &decoded_size, + output.data()); + + if (result == boost::capy::brotli::decoder_result::success) + { + output.resize(decoded_size); + // Use decompressed data + } + @endcode + + @code + // Example: Streaming decompression + auto* state = decoder.create_instance(nullptr, nullptr, nullptr); + + std::size_t available_in = compressed_data.size(); + const std::uint8_t* next_in = compressed_data.data(); + std::size_t available_out = output.size(); + std::uint8_t* next_out = output.data(); + std::size_t total_out = 0; + + auto result = decoder.decompress_stream( + state, + &available_in, + &next_in, + &available_out, + &next_out, + &total_out); + + decoder.destroy_instance(state); + @endcode +*/ struct BOOST_SYMBOL_VISIBLE decode_service { + /** Set a decoder parameter. + @param state The decoder state. + @param param The parameter identifier. + @param value The parameter value. + @return True on success, false on error. + */ virtual bool set_parameter( decoder_state* state, decoder_param param, std::uint32_t value) const noexcept = 0; + /** Create a new decoder instance. + @param alloc_func Allocation function. + @param free_func Deallocation function. + @param opaque Opaque pointer passed to allocation functions. + @return Pointer to decoder state, or nullptr on error. + */ virtual decoder_state* create_instance( alloc_func alloc_func, free_func free_func, void* opaque) const noexcept = 0; + /** Destroy a decoder instance. + @param state The decoder state to destroy. + */ virtual void destroy_instance(decoder_state* state) const noexcept = 0; + /** Decompress data in one call. + @param encoded_size Input data size. + @param encoded_buffer Input data buffer. + @param decoded_size Pointer to variable receiving output size. + @param decoded_buffer Output buffer. + @return Result code indicating success or failure. + */ virtual decoder_result decompress( std::size_t encoded_size, @@ -70,6 +158,15 @@ struct BOOST_SYMBOL_VISIBLE std::size_t* decoded_size, std::uint8_t decoded_buffer[]) const noexcept = 0; + /** Decompress data in streaming mode. + @param state The decoder state. + @param available_in Pointer to input bytes available. + @param next_in Pointer to pointer to input data. + @param available_out Pointer to output space available. + @param next_out Pointer to pointer to output buffer. + @param total_out Pointer to variable receiving total bytes written. + @return Result code indicating decoder state. + */ virtual decoder_result decompress_stream( decoder_state* state, @@ -79,24 +176,52 @@ struct BOOST_SYMBOL_VISIBLE std::uint8_t** next_out, std::size_t* total_out) const noexcept = 0; + /** Check if more output is available. + @param state The decoder state. + @return True if output is available, false otherwise. + */ virtual bool has_more_output(const decoder_state* state) const noexcept = 0; + /** Return buffered output data. + @param state The decoder state. + @param size Pointer to variable receiving output size. + @return Pointer to output buffer. + */ virtual const std::uint8_t* take_output(decoder_state* state, std::size_t* size) const noexcept = 0; + /** Check if decoder has been used. + @param state The decoder state. + @return True if decoder has processed data, false otherwise. + */ virtual bool is_used(const decoder_state* state) const noexcept = 0; + /** Check if decompression is finished. + @param state The decoder state. + @return True if decompression is complete, false otherwise. + */ virtual bool is_finished(const decoder_state* state) const noexcept = 0; + /** Return the error code from the decoder. + @param state The decoder state. + @return The error code. + */ virtual error get_error_code(const decoder_state* state) const noexcept = 0; + /** Return a string description of an error code. + @param c The error code. + @return Pointer to error description string. + */ virtual const char* error_string(error c) const noexcept = 0; + /** Return the Brotli library version. + @return Version number. + */ virtual std::uint32_t version() const noexcept = 0; @@ -117,6 +242,10 @@ struct BOOST_SYMBOL_VISIBLE #endif }; +/** Install the decode service into a polystore. + @param ctx The polystore to install the service into. + @return A reference to the installed decode service. +*/ BOOST_CAPY_DECL decode_service& install_decode_service(polystore& ctx); diff --git a/include/boost/capy/brotli/encode.hpp b/include/boost/capy/brotli/encode.hpp index d490d693..e36e278f 100644 --- a/include/boost/capy/brotli/encode.hpp +++ b/include/boost/capy/brotli/encode.hpp @@ -26,79 +26,234 @@ struct encoder_state; */ struct encoder_prepared_dictionary; -/** Options for ::BROTLI_PARAM_MODE parameter. */ +/** Encoder mode options. + + These values specify the type of input data for + optimization purposes. +*/ enum class encoder_mode { + /** Generic mode for mixed or unknown data. */ generic = 0, + + /** Mode optimized for UTF-8 text. */ text = 1, + + /** Mode optimized for WOFF 2.0 fonts. */ font = 2 }; -/** Operations that can be performed by streaming encoder. */ +/** Encoder stream operations. + + These operations control the streaming encoder behavior. +*/ enum class encoder_operation { + /** Process input data. */ process = 0, + + /** Flush pending output. */ flush = 1, + + /** Finish encoding and emit trailer. */ finish = 2, + + /** Emit metadata block. */ emit_metadata = 3 }; -/** Options to be used with ::SetParameter. */ +/** Encoder parameter identifiers. + + These values identify parameters that can be set + on an encoder instance. +*/ enum class encoder_parameter { + /** Encoder mode (generic, text, or font). */ mode = 0, + + /** Compression quality (0-11). */ quality = 1, + + /** Base-2 logarithm of window size. */ lgwin = 2, + + /** Base-2 logarithm of input block size. */ lgblock = 3, + + /** Disable literal context modeling flag. */ disable_literal_context_modeling = 4, + + /** Expected input size hint. */ size_hint = 5, + + /** Enable large window mode flag. */ large_window = 6, + + /** Number of postfix bits for distance codes. */ npostfix = 7, + + /** Number of direct distance codes. */ ndirect = 8, + + /** Current stream offset. */ stream_offset = 9 }; -/** Different constants in Brotli API */ +/** Brotli encoder constants. + + These constants define valid ranges and default values + for encoder parameters. +*/ enum constants { + /** Minimum window size (2^10 bytes). */ min_window_bits = 10, + + /** Maximum standard window size (2^24 bytes). */ max_window_bits = 24, + /** Maximum large window size (2^30 bytes). */ large_max_window_bits = 30, + /** Minimum input block size (2^16 bytes). */ min_input_block_bits = 16, + + /** Maximum input block size (2^24 bytes). */ max_input_block_bits = 24, + /** Minimum quality level. */ min_quality = 0, + + /** Maximum quality level. */ max_quality = 11, + /** Default quality level. */ default_quality = 11, + + /** Default window size. */ default_window = 22, + + /** Default encoder mode. */ default_mode = 0 }; -/** Provides the Brotli compression API */ +/** Provides the Brotli compression API. + + This service interface exposes Brotli encoder functionality + through a set of virtual functions. The encoder can operate + in one-shot mode for simple compression or streaming mode + for processing data in chunks. + + The quality parameter ranges from 0 to 11 (see min_quality + and max_quality constants). Quality 0 offers fastest compression + with lower ratio, while quality 11 offers best compression with + slower speed. The default quality is 11. + + @code + // Example: Simple one-shot compression + boost::capy::datastore ctx; + auto& encoder = boost::capy::brotli::install_encode_service(ctx); + + std::vector input_data = get_input_data(); + std::size_t max_size = encoder.max_compressed_size(input_data.size()); + std::vector output(max_size); + std::size_t encoded_size = max_size; + + bool success = encoder.compress( + 11, // quality (0-11) + 22, // lgwin (window size = 2^22) + boost::capy::brotli::encoder_mode::generic, + input_data.size(), + input_data.data(), + &encoded_size, + output.data()); + + if (success) + { + output.resize(encoded_size); + // Use compressed data + } + @endcode + + @code + // Example: Streaming compression + auto* state = encoder.create_instance(nullptr, nullptr, nullptr); + + // Set parameters + encoder.set_parameter(state, + boost::capy::brotli::encoder_parameter::quality, 6); + encoder.set_parameter(state, + boost::capy::brotli::encoder_parameter::lgwin, 22); + + std::size_t available_in = input_data.size(); + const std::uint8_t* next_in = input_data.data(); + std::size_t available_out = output.size(); + std::uint8_t* next_out = output.data(); + std::size_t total_out = 0; + + bool success = encoder.compress_stream( + state, + boost::capy::brotli::encoder_operation::finish, + &available_in, + &next_in, + &available_out, + &next_out, + &total_out); + + encoder.destroy_instance(state); + @endcode +*/ struct BOOST_SYMBOL_VISIBLE encode_service { + /** Set an encoder parameter. + @param state The encoder state. + @param param The parameter identifier. + @param value The parameter value. + @return True on success, false on error. + */ virtual bool set_parameter( encoder_state* state, encoder_parameter param, std::uint32_t value) const noexcept = 0; + /** Create a new encoder instance. + @param alloc_func Allocation function. + @param free_func Deallocation function. + @param opaque Opaque pointer passed to allocation functions. + @return Pointer to encoder state, or nullptr on error. + */ virtual encoder_state* create_instance( alloc_func alloc_func, free_func free_func, void* opaque) const noexcept = 0; + /** Destroy an encoder instance. + @param state The encoder state to destroy. + */ virtual void destroy_instance(encoder_state* state) const noexcept = 0; + /** Return maximum possible compressed size. + @param input_size The input data size. + @return Maximum compressed size in bytes. + */ virtual std::size_t max_compressed_size(std::size_t input_size) const noexcept = 0; + /** Compress data in one call. + @param quality Compression quality (0-11). + @param lgwin Base-2 logarithm of window size. + @param mode Encoder mode. + @param input_size Input data size. + @param input_buffer Input data buffer. + @param encoded_size Pointer to variable receiving output size. + @param encoded_buffer Output buffer. + @return True on success, false on error. + */ virtual bool compress( int quality, @@ -109,6 +264,16 @@ struct BOOST_SYMBOL_VISIBLE std::size_t* encoded_size, std::uint8_t encoded_buffer[]) const noexcept = 0; + /** Compress data in streaming mode. + @param state The encoder state. + @param op The encoder operation. + @param available_in Pointer to input bytes available. + @param next_in Pointer to pointer to input data. + @param available_out Pointer to output space available. + @param next_out Pointer to pointer to output buffer. + @param total_out Pointer to variable receiving total bytes written. + @return True on success, false on error. + */ virtual bool compress_stream( encoder_state* state, @@ -119,17 +284,33 @@ struct BOOST_SYMBOL_VISIBLE std::uint8_t** next_out, std::size_t* total_out) const noexcept = 0; + /** Check if encoding is finished. + @param state The encoder state. + @return True if encoding is complete, false otherwise. + */ virtual bool is_finished(encoder_state* state) const noexcept = 0; + /** Check if more output is available. + @param state The encoder state. + @return True if output is available, false otherwise. + */ virtual bool has_more_output(encoder_state* state) const noexcept = 0; + /** Return buffered output data. + @param state The encoder state. + @param size Pointer to variable receiving output size. + @return Pointer to output buffer. + */ virtual const std::uint8_t* take_output( encoder_state* state, std::size_t* size) const noexcept = 0; + /** Return the Brotli library version. + @return Version number. + */ virtual std::uint32_t version() const noexcept = 0; @@ -165,6 +346,10 @@ struct BOOST_SYMBOL_VISIBLE #endif }; +/** Install the encode service into a polystore. + @param ctx The polystore to install the service into. + @return A reference to the installed encode service. +*/ BOOST_CAPY_DECL encode_service& install_encode_service(polystore& ctx); diff --git a/include/boost/capy/brotli/shared_dictionary.hpp b/include/boost/capy/brotli/shared_dictionary.hpp index db638266..a006e798 100644 --- a/include/boost/capy/brotli/shared_dictionary.hpp +++ b/include/boost/capy/brotli/shared_dictionary.hpp @@ -21,14 +21,25 @@ namespace brotli { /** Opaque structure that holds shared dictionary data. */ struct shared_dictionary; -/** Input data type for attach. */ +/** Shared dictionary data format. + + These values specify the format of dictionary data + being attached to an encoder or decoder. +*/ enum class shared_dictionary_type { + /** Raw dictionary data. */ raw = 0, + + /** Serialized dictionary format. */ serialized = 1 }; -/** Provides the Brotli shared_dictionary API */ +/** Provides the Brotli shared dictionary API. + + This service interface exposes Brotli shared dictionary + functionality through a set of virtual functions. +*/ struct BOOST_SYMBOL_VISIBLE shared_dictionary_service { @@ -52,6 +63,10 @@ struct BOOST_SYMBOL_VISIBLE #endif }; +/** Install the shared dictionary service into a polystore. + @param ctx The polystore to install the service into. + @return A reference to the installed shared dictionary service. +*/ BOOST_CAPY_DECL shared_dictionary_service& install_shared_dictionary_service(polystore& ctx); diff --git a/include/boost/capy/datastore.hpp b/include/boost/capy/datastore.hpp index 088fb66f..832c6309 100644 --- a/include/boost/capy/datastore.hpp +++ b/include/boost/capy/datastore.hpp @@ -16,12 +16,43 @@ namespace boost { namespace capy { +/** A polymorphic data container with clear functionality. + + This class extends @ref polystore to provide a container + for type-erased objects with an explicit clear operation. + It is commonly used as a service container for compression + and decompression services. + + @code + // Example: Using datastore with compression services + boost::capy::datastore ctx; + + // Install services + auto& deflate_svc = boost::capy::zlib::install_deflate_service(ctx); + auto& inflate_svc = boost::capy::zlib::install_inflate_service(ctx); + auto& brotli_enc = boost::capy::brotli::install_encode_service(ctx); + + // Use services... + + // Clean up all services when done + ctx.clear(); + @endcode +*/ class datastore : public polystore { public: + /** Constructor + + Constructs an empty datastore. + */ datastore() = default; - void clear() noexcept + /** Remove and destroy all stored objects. + + All stored objects are destroyed in the reverse order + of construction. The container is left empty. + */ + void clear() noexcept { polystore::clear(); } diff --git a/include/boost/capy/polystore_fwd.hpp b/include/boost/capy/polystore_fwd.hpp index 2309d292..35ac506f 100644 --- a/include/boost/capy/polystore_fwd.hpp +++ b/include/boost/capy/polystore_fwd.hpp @@ -13,6 +13,10 @@ namespace boost { namespace capy { +/** Forward declaration of polystore class. + + @see polystore +*/ class polystore; } // capy diff --git a/include/boost/capy/zlib.hpp b/include/boost/capy/zlib.hpp index 5e5494d7..ca8da00e 100644 --- a/include/boost/capy/zlib.hpp +++ b/include/boost/capy/zlib.hpp @@ -7,6 +7,31 @@ // Official repository: https://github.com/cppalliance/capy // +/** @file + ZLib compression and decompression library. + + This header includes all ZLib-related functionality including + deflate, inflate, error handling, and stream management. + + ZLib is a widely-used lossless data compression library that + implements the DEFLATE compression algorithm. It provides both + compression (deflate) and decompression (inflate) functionality + with support for raw, zlib, and gzip formats through the + windowBits parameter. + + @code + #include + #include + + // Create a datastore for services + boost::capy::datastore ctx; + + // Install compression and decompression services + auto& deflate_svc = boost::capy::zlib::install_deflate_service(ctx); + auto& inflate_svc = boost::capy::zlib::install_inflate_service(ctx); + @endcode +*/ + #ifndef BOOST_CAPY_ZLIB_HPP #define BOOST_CAPY_ZLIB_HPP diff --git a/include/boost/capy/zlib/compression_level.hpp b/include/boost/capy/zlib/compression_level.hpp index 79b37ba2..53e7cf3a 100644 --- a/include/boost/capy/zlib/compression_level.hpp +++ b/include/boost/capy/zlib/compression_level.hpp @@ -14,12 +14,41 @@ namespace boost { namespace capy { namespace zlib { -/// Compression levels +/** Compression level constants. + + These values control the trade-off between compression + speed and compression ratio. Higher values produce better + compression but take more time. Level 0 disables compression + entirely, storing data uncompressed. Levels 1-9 provide + increasing compression, with 6 being the default compromise + between speed and ratio. + + @code + boost::capy::zlib::stream st = {}; + auto& deflate_svc = boost::capy::zlib::install_deflate_service(ctx); + + // Use best speed for time-critical operations + deflate_svc.init(st, boost::capy::zlib::best_speed); + + // Use best compression for archival storage + deflate_svc.init(st, boost::capy::zlib::best_compression); + + // Use default compression for balanced performance + deflate_svc.init(st, boost::capy::zlib::default_compression); + @endcode +*/ enum compression_level { + /** Use the default compression level. */ default_compression = -1, + + /** No compression is performed. */ no_compression = 0, + + /** Fastest compression speed with minimal compression. */ best_speed = 1, + + /** Best compression ratio with slower speed. */ best_compression = 9 }; diff --git a/include/boost/capy/zlib/compression_method.hpp b/include/boost/capy/zlib/compression_method.hpp index e9446df0..ba97a72c 100644 --- a/include/boost/capy/zlib/compression_method.hpp +++ b/include/boost/capy/zlib/compression_method.hpp @@ -14,9 +14,13 @@ namespace boost { namespace capy { namespace zlib { -/// Compression method +/** Compression method constants. + + Specifies the compression algorithm to use. +*/ enum compression_method { + /** The deflate compression method. */ deflated = 8 }; diff --git a/include/boost/capy/zlib/compression_strategy.hpp b/include/boost/capy/zlib/compression_strategy.hpp index ddc432b3..ffe3b3dd 100644 --- a/include/boost/capy/zlib/compression_strategy.hpp +++ b/include/boost/capy/zlib/compression_strategy.hpp @@ -14,13 +14,47 @@ namespace boost { namespace capy { namespace zlib { -/// Compression strategy +/** Compression strategy constants. + + These values tune the compression algorithm for specific + types of input data. The default strategy works well for + most data. Other strategies optimize for specific patterns: + filtered for data with small value differences, huffman_only + for pre-compressed data, rle for image data with many + repeated bytes, and fixed for fastest compression. + + @code + // Example: Using different strategies for different data types + boost::capy::zlib::stream st = {}; + + // For PNG image data (many repeated bytes) + deflate_svc.init2(st, 6, boost::capy::zlib::deflated, + 15, 8, boost::capy::zlib::rle); + + // For small numeric differences (filtered data) + deflate_svc.init2(st, 6, boost::capy::zlib::deflated, + 15, 8, boost::capy::zlib::filtered); + + // For fastest speed with pre-compressed data + deflate_svc.init2(st, 1, boost::capy::zlib::deflated, + 15, 8, boost::capy::zlib::huffman_only); + @endcode +*/ enum compression_strategy { + /** Use the default compression strategy. */ default_strategy = 0, + + /** Strategy optimized for data with small values. */ filtered = 1, + + /** Force Huffman encoding only (no string match). */ huffman_only = 2, + + /** Limit match distances to one (run-length encoding). */ rle = 3, + + /** Prevent use of dynamic Huffman codes. */ fixed = 4 }; diff --git a/include/boost/capy/zlib/data_type.hpp b/include/boost/capy/zlib/data_type.hpp index 51a9870f..abadd308 100644 --- a/include/boost/capy/zlib/data_type.hpp +++ b/include/boost/capy/zlib/data_type.hpp @@ -14,12 +14,23 @@ namespace boost { namespace capy { namespace zlib { -/// Possible values of the data_type field for deflate +/** Data type constants for the stream data_type field. + + These values represent the best guess about the type + of data being compressed or decompressed. +*/ enum data_type { + /** Binary data. */ binary = 0, + + /** Text data. */ text = 1, + + /** ASCII text data (same as text). */ ascii = 1, + + /** Data type is unknown. */ unknown = 2 }; diff --git a/include/boost/capy/zlib/deflate.hpp b/include/boost/capy/zlib/deflate.hpp index 1f9b5bb7..e694a34d 100644 --- a/include/boost/capy/zlib/deflate.hpp +++ b/include/boost/capy/zlib/deflate.hpp @@ -19,28 +19,173 @@ namespace boost { namespace capy { namespace zlib { -/** Provides the ZLib compression API +/** Provides the ZLib compression API. + + This service interface exposes the ZLib deflate (compression) + functionality through a set of virtual functions. The deflate + algorithm compresses data by finding repeated byte sequences + and encoding them efficiently using a combination of LZ77 and + Huffman coding. + + The windowBits parameter in init2() controls the format: + - 8..15: zlib format with specified window size + - -8..-15: raw deflate format (no header/trailer) + - 16+windowBits: gzip format + + @code + // Example: Basic compression + boost::capy::datastore ctx; + auto& deflate_svc = boost::capy::zlib::install_deflate_service(ctx); + + boost::capy::zlib::stream st = {}; + std::vector input_data = get_data(); + std::vector output(input_data.size() * 2); + + st.zalloc = nullptr; + st.zfree = nullptr; + st.opaque = nullptr; + + deflate_svc.init(st, boost::capy::zlib::default_compression); + + st.avail_in = input_data.size(); + st.next_in = input_data.data(); + st.avail_out = output.size(); + st.next_out = output.data(); + + deflate_svc.deflate(st, boost::capy::zlib::finish); + output.resize(st.total_out); + + deflate_svc.deflate_end(st); + @endcode + + @code + // Example: Gzip compression with custom window size + boost::capy::zlib::stream st = {}; + st.zalloc = nullptr; + st.zfree = nullptr; + + // Use gzip format (16 + 15 for max window) + deflate_svc.init2(st, + 6, // level + boost::capy::zlib::deflated, // method + 16 + 15, // gzip format + 8, // memLevel + boost::capy::zlib::default_strategy); // strategy + + // Compress data... + deflate_svc.deflate_end(st); + @endcode */ struct BOOST_SYMBOL_VISIBLE deflate_service { + /** Return the ZLib version string. */ virtual char const* version() const noexcept = 0; + + /** Initialize deflate compression. + @param st The stream to initialize. + @param level The compression level. + @return Zero on success, or an error code. + */ virtual int init(stream& st, int level) const = 0; + + /** Initialize deflate compression with extended parameters. + @param st The stream to initialize. + @param level The compression level. + @param method The compression method. + @param windowBits The base-2 logarithm of the window size. + @param memLevel Memory usage level (1-9). + @param strategy The compression strategy. + @return Zero on success, or an error code. + */ virtual int init2(stream& st, int level, int method, int windowBits, int memLevel, int strategy) const = 0; + + /** Set the compression dictionary. + @param st The stream. + @param dict Pointer to the dictionary data. + @param len Length of the dictionary. + @return Zero on success, or an error code. + */ virtual int set_dict(stream& st, unsigned char const* dict, unsigned len) const = 0; + + /** Return the current compression dictionary. + @param st The stream. + @param dest Destination buffer for the dictionary. + @param len Pointer to variable receiving dictionary length. + @return Zero on success, or an error code. + */ virtual int get_dict(stream& st, unsigned char* dest, unsigned* len) const = 0; + + /** Duplicate a deflate stream. + @param dest The destination stream. + @param src The source stream to duplicate. + @return Zero on success, or an error code. + */ virtual int dup(stream& dest, stream& src) const = 0; + + /** Compress data in the stream. + @param st The stream containing data to compress. + @param flush The flush mode. + @return Status code indicating compression state. + */ virtual int deflate(stream& st, int flush) const = 0; + + /** Release all resources held by the deflate stream. + @param st The stream to finalize. + @return Zero on success, or an error code. + */ virtual int deflate_end(stream& st) const = 0; + + /** Reset the deflate stream state. + @param st The stream to reset. + @return Zero on success, or an error code. + */ virtual int reset(stream& st) const = 0; + + /** Dynamically update compression parameters. + @param st The stream. + @param level The new compression level. + @param strategy The new compression strategy. + @return Zero on success, or an error code. + */ virtual int params(stream& st, int level, int strategy) const = 0; + + /** Return an upper bound on compressed size. + @param st The stream. + @param sourceLen The length of source data. + @return Maximum possible compressed size. + */ virtual std::size_t bound(stream& st, unsigned long sourceLen) const = 0; + + /** Return the number of pending output bytes. + @param st The stream. + @param pending Pointer to variable receiving pending byte count. + @param bits Pointer to variable receiving pending bit count. + @return Zero on success, or an error code. + */ virtual int pending(stream& st, unsigned* pending, int* bits) const = 0; + + /** Insert bits into the compressed stream. + @param st The stream. + @param bits Number of bits to insert. + @param value The bit pattern to insert. + @return Zero on success, or an error code. + */ virtual int prime(stream& st, int bits, int value) const = 0; + + /** Set the gzip header information. + @param st The stream. + @param header Pointer to gzip header structure. + @return Zero on success, or an error code. + */ virtual int set_header(stream& st, void* header) const = 0; }; +/** Install the deflate service into a polystore. + @param ctx The polystore to install the service into. + @return A reference to the installed deflate service. +*/ BOOST_CAPY_DECL deflate_service& install_deflate_service(polystore& ctx); diff --git a/include/boost/capy/zlib/flush.hpp b/include/boost/capy/zlib/flush.hpp index 426001fb..3b43f68b 100644 --- a/include/boost/capy/zlib/flush.hpp +++ b/include/boost/capy/zlib/flush.hpp @@ -14,15 +14,57 @@ namespace boost { namespace capy { namespace zlib { -/// Flush methods +/** Flush method constants. + + These values control how and when compressed data is + flushed from internal buffers during compression operations. + + Use no_flush for maximum compression efficiency when more + input is available. Use sync_flush to force output to a + byte boundary, allowing partial decompression. Use finish + when no more input is available to complete compression + and write the trailer. + + @code + // Example: Streaming compression with periodic flushing + boost::capy::zlib::stream st = {}; + // ... initialize stream ... + + while (has_more_data) + { + st.next_in = get_next_chunk(); + st.avail_in = chunk_size; + + // Flush at chunk boundaries for progressive decoding + int flush_mode = has_more_data ? + boost::capy::zlib::sync_flush : + boost::capy::zlib::finish; + + deflate_svc.deflate(st, flush_mode); + } + @endcode +*/ enum flush { + /** No flushing, allow optimal compression. */ no_flush = 0, + + /** Flush to byte boundary (deprecated). */ partial_flush = 1, + + /** Flush to byte boundary for synchronization. */ sync_flush = 2, + + /** Full flush, reset compression state. */ full_flush = 3, + + /** Finish compression, emit trailer. */ finish = 4, + + /** Flush current block to output. */ block = 5, + + /** Flush up to end of previous block. */ trees = 6 }; diff --git a/include/boost/capy/zlib/inflate.hpp b/include/boost/capy/zlib/inflate.hpp index bd6512e3..00959154 100644 --- a/include/boost/capy/zlib/inflate.hpp +++ b/include/boost/capy/zlib/inflate.hpp @@ -19,30 +19,184 @@ namespace boost { namespace capy { namespace zlib { -/** Provides the ZLib decompression API +/** Provides the ZLib decompression API. + + This service interface exposes the ZLib inflate (decompression) + functionality through a set of virtual functions. The inflate + algorithm reverses the deflate compression, restoring the + original uncompressed data. + + The windowBits parameter in init2() controls format detection: + - 8..15: zlib format with specified window size + - -8..-15: raw deflate format (no header/trailer) + - 16+windowBits: gzip format only + - 32+windowBits: auto-detect zlib or gzip format + + @code + // Example: Basic decompression + boost::capy::datastore ctx; + auto& inflate_svc = boost::capy::zlib::install_inflate_service(ctx); + + boost::capy::zlib::stream st = {}; + std::vector compressed_data = get_compressed(); + std::vector output(1024 * 1024); // 1MB buffer + + st.zalloc = nullptr; + st.zfree = nullptr; + st.opaque = nullptr; + + inflate_svc.init(st); + + st.avail_in = compressed_data.size(); + st.next_in = compressed_data.data(); + st.avail_out = output.size(); + st.next_out = output.data(); + + inflate_svc.inflate(st, boost::capy::zlib::finish); + output.resize(st.total_out); + + inflate_svc.inflate_end(st); + @endcode + + @code + // Example: Auto-detect gzip or zlib format + boost::capy::zlib::stream st = {}; + st.zalloc = nullptr; + st.zfree = nullptr; + + // Auto-detect format (32 + 15 for max window) + inflate_svc.init2(st, 32 + 15); + + st.avail_in = compressed_data.size(); + st.next_in = compressed_data.data(); + st.avail_out = output.size(); + st.next_out = output.data(); + + int result = inflate_svc.inflate(st, boost::capy::zlib::no_flush); + // Handle result... + + inflate_svc.inflate_end(st); + @endcode */ struct BOOST_SYMBOL_VISIBLE inflate_service { + /** Return the ZLib version string. */ virtual char const* version() const noexcept = 0; + + /** Initialize inflate decompression. + @param st The stream to initialize. + @return Zero on success, or an error code. + */ virtual int init(stream& st) const = 0; + + /** Initialize inflate decompression with extended parameters. + @param st The stream to initialize. + @param windowBits The base-2 logarithm of the window size. + @return Zero on success, or an error code. + */ virtual int init2(stream& st, int windowBits) const = 0; + + /** Decompress data in the stream. + @param st The stream containing data to decompress. + @param flush The flush mode. + @return Status code indicating decompression state. + */ virtual int inflate(stream& st, int flush) const = 0; + + /** Release all resources held by the inflate stream. + @param st The stream to finalize. + @return Zero on success, or an error code. + */ virtual int inflate_end(stream& st) const = 0; + + /** Set the decompression dictionary. + @param st The stream. + @param dict Pointer to the dictionary data. + @param len Length of the dictionary. + @return Zero on success, or an error code. + */ virtual int set_dict(stream& st, unsigned char const* dict, unsigned len) const = 0; + + /** Return the current decompression dictionary. + @param st The stream. + @param dest Destination buffer for the dictionary. + @param len Pointer to variable receiving dictionary length. + @return Zero on success, or an error code. + */ virtual int get_dict(stream& st, unsigned char* dest, unsigned* len) const = 0; + + /** Synchronize the decompression state. + @param st The stream to synchronize. + @return Zero on success, or an error code. + */ virtual int sync(stream& st) const = 0; + + /** Duplicate an inflate stream. + @param dest The destination stream. + @param src The source stream to duplicate. + @return Zero on success, or an error code. + */ virtual int dup(stream& dest, stream& src) const = 0; + + /** Reset the inflate stream state. + @param st The stream to reset. + @return Zero on success, or an error code. + */ virtual int reset(stream& st) const = 0; + + /** Reset the inflate stream state with new window size. + @param st The stream to reset. + @param windowBits The base-2 logarithm of the window size. + @return Zero on success, or an error code. + */ virtual int reset2(stream& st, int windowBits) const = 0; + + /** Insert bits into the input stream. + @param st The stream. + @param bits Number of bits to insert. + @param value The bit pattern to insert. + @return Zero on success, or an error code. + */ virtual int prime(stream& st, int bits, int value) const = 0; + + /** Return the current inflate mark. + @param st The stream. + @return The mark value, or -1 on error. + */ virtual long mark(stream& st) const = 0; + + /** Return the gzip header information. + @param st The stream. + @param header Pointer to gzip header structure. + @return Zero on success, or an error code. + */ virtual int get_header(stream& st, void* header) const = 0; + + /** Initialize backward inflate decompression. + @param st The stream to initialize. + @param windowBits The base-2 logarithm of the window size. + @param window Pointer to the window buffer. + @return Zero on success, or an error code. + */ virtual int back_init(stream& st, int windowBits, unsigned char* window) const = 0; + + /** Release resources held by backward inflate stream. + @param st The stream to finalize. + @return Zero on success, or an error code. + */ virtual int back_end(stream& st) const = 0; + + /** Return ZLib compile-time flags. + @return Bit flags indicating compile-time options. + */ virtual unsigned long compile_flags() const = 0; }; +/** Install the inflate service into a polystore. + @param ctx The polystore to install the service into. + @return A reference to the installed inflate service. +*/ BOOST_CAPY_DECL inflate_service& install_inflate_service(polystore& ctx); diff --git a/include/boost/capy/zlib/stream.hpp b/include/boost/capy/zlib/stream.hpp index 7fc023a2..a5610791 100644 --- a/include/boost/capy/zlib/stream.hpp +++ b/include/boost/capy/zlib/stream.hpp @@ -15,30 +15,87 @@ namespace boost { namespace capy { namespace zlib { +/** ZLib stream state structure. + + This structure maintains the state for compression and + decompression operations, including input/output buffers, + statistics, and internal state. Applications provide input + data through next_in/avail_in and receive output through + next_out/avail_out. The service updates these fields as + data is processed. + + Before use, initialize zalloc, zfree, and opaque. Set them + to nullptr to use the default allocator. The state field + is managed internally and should not be modified. + + @code + // Example: Initialize a stream for compression + boost::capy::zlib::stream st = {}; + st.zalloc = nullptr; // Use default allocator + st.zfree = nullptr; + st.opaque = nullptr; + + // Set up input and output buffers + st.next_in = input_buffer; + st.avail_in = input_size; + st.next_out = output_buffer; + st.avail_out = output_size; + + // After deflate/inflate operations: + // - next_in and next_out are updated to point past processed data + // - avail_in and avail_out are decreased by bytes processed + // - total_in and total_out track cumulative totals + @endcode +*/ struct stream { + /** Allocating function pointer type. */ using alloc_func = void*(*)(void*, unsigned int, unsigned int); + + /** Deallocating function pointer type. */ using free_func = void(*)(void*, void*); - unsigned char* next_in; // next input byte - unsigned int avail_in; // number of bytes available at next_in - unsigned long total_in; // total number of input bytes read so far + /** Pointer to next input byte. */ + unsigned char* next_in; + + /** Number of bytes available at next_in. */ + unsigned int avail_in; + + /** Total number of input bytes read so far. */ + unsigned long total_in; + + /** Pointer where next output byte will be placed. */ + unsigned char* next_out; + + /** Remaining free space at next_out. */ + unsigned int avail_out; + + /** Total number of bytes output so far. */ + unsigned long total_out; + + /** Last error message, NULL if no error. */ + char* msg; + + /** Internal state, not visible to applications. */ + void* state; + + /** Function used to allocate internal state. */ + alloc_func zalloc; + + /** Function used to deallocate internal state. */ + free_func zfree; - unsigned char* next_out; // next output byte will go here - unsigned int avail_out; // remaining free space at next_out - unsigned long total_out; // total number of bytes output so far + /** Private data object passed to zalloc and zfree. */ + void* opaque; - char* msg; // last error message, NULL if no error - void* state; // not visible by applications + /** Best guess about data type (binary or text for deflate, decoding state for inflate). */ + int data_type; - alloc_func zalloc; // used to allocate internal state - free_func zfree; // used to deallocate internal state - void* opaque; // private data object passed to zalloc and zfree + /** Adler-32 or CRC-32 value of the uncompressed data. */ + unsigned long adler; - int data_type; // best guess about the data type: binary or text - // for deflate, or the decoding state for inflate - unsigned long adler; // Adler-32 or CRC-32 value of the uncompressed data - unsigned long reserved; // reserved for future use + /** Reserved for future use. */ + unsigned long reserved; }; } // zlib