| 3074 | inline bool gzip_decompressor::is_valid() const { return is_valid_; } |
| 3075 | |
| 3076 | inline bool gzip_decompressor::decompress(const char *data, size_t data_length, |
| 3077 | Callback callback) { |
| 3078 | assert(is_valid_); |
| 3079 | |
| 3080 | int ret = Z_OK; |
| 3081 | |
| 3082 | do { |
| 3083 | constexpr size_t max_avail_in = |
| 3084 | (std::numeric_limits<decltype(strm_.avail_in)>::max)(); |
| 3085 | |
| 3086 | strm_.avail_in = static_cast<decltype(strm_.avail_in)>( |
| 3087 | (std::min)(data_length, max_avail_in)); |
| 3088 | strm_.next_in = const_cast<Bytef *>(reinterpret_cast<const Bytef *>(data)); |
| 3089 | |
| 3090 | data_length -= strm_.avail_in; |
| 3091 | data += strm_.avail_in; |
| 3092 | |
| 3093 | std::array<char, CPPHTTPLIB_COMPRESSION_BUFSIZ> buff{}; |
| 3094 | while (strm_.avail_in > 0) { |
| 3095 | strm_.avail_out = static_cast<uInt>(buff.size()); |
| 3096 | strm_.next_out = reinterpret_cast<Bytef *>(buff.data()); |
| 3097 | |
| 3098 | auto prev_avail_in = strm_.avail_in; |
| 3099 | |
| 3100 | ret = inflate(&strm_, Z_NO_FLUSH); |
| 3101 | |
| 3102 | if (prev_avail_in - strm_.avail_in == 0) { return false; } |
| 3103 | |
| 3104 | assert(ret != Z_STREAM_ERROR); |
| 3105 | switch (ret) { |
| 3106 | case Z_NEED_DICT: |
| 3107 | case Z_DATA_ERROR: |
| 3108 | case Z_MEM_ERROR: inflateEnd(&strm_); return false; |
| 3109 | } |
| 3110 | |
| 3111 | if (!callback(buff.data(), buff.size() - strm_.avail_out)) { |
| 3112 | return false; |
| 3113 | } |
| 3114 | } |
| 3115 | |
| 3116 | if (ret != Z_OK && ret != Z_STREAM_END) return false; |
| 3117 | |
| 3118 | } while (data_length > 0); |
| 3119 | |
| 3120 | return true; |
| 3121 | } |
| 3122 | #endif |
| 3123 | |
| 3124 | #ifdef CPPHTTPLIB_BROTLI_SUPPORT |
no test coverage detected