| 3259 | inline bool gzip_decompressor::is_valid() const { return is_valid_; } |
| 3260 | |
| 3261 | inline bool gzip_decompressor::decompress(const char *data, size_t data_length, |
| 3262 | Callback callback) { |
| 3263 | assert(is_valid_); |
| 3264 | |
| 3265 | int ret = Z_OK; |
| 3266 | |
| 3267 | do { |
| 3268 | constexpr size_t max_avail_in = |
| 3269 | (std::numeric_limits<decltype(strm_.avail_in)>::max)(); |
| 3270 | |
| 3271 | strm_.avail_in = static_cast<decltype(strm_.avail_in)>( |
| 3272 | (std::min)(data_length, max_avail_in)); |
| 3273 | strm_.next_in = const_cast<Bytef *>(reinterpret_cast<const Bytef *>(data)); |
| 3274 | |
| 3275 | data_length -= strm_.avail_in; |
| 3276 | data += strm_.avail_in; |
| 3277 | |
| 3278 | std::array<char, CPPHTTPLIB_COMPRESSION_BUFSIZ> buff{}; |
| 3279 | while (strm_.avail_in > 0) { |
| 3280 | strm_.avail_out = static_cast<uInt>(buff.size()); |
| 3281 | strm_.next_out = reinterpret_cast<Bytef *>(buff.data()); |
| 3282 | |
| 3283 | auto prev_avail_in = strm_.avail_in; |
| 3284 | |
| 3285 | ret = inflate(&strm_, Z_NO_FLUSH); |
| 3286 | |
| 3287 | if (prev_avail_in - strm_.avail_in == 0) { return false; } |
| 3288 | |
| 3289 | assert(ret != Z_STREAM_ERROR); |
| 3290 | switch (ret) { |
| 3291 | case Z_NEED_DICT: |
| 3292 | case Z_DATA_ERROR: |
| 3293 | case Z_MEM_ERROR: inflateEnd(&strm_); return false; |
| 3294 | } |
| 3295 | |
| 3296 | if (!callback(buff.data(), buff.size() - strm_.avail_out)) { |
| 3297 | return false; |
| 3298 | } |
| 3299 | } |
| 3300 | |
| 3301 | if (ret != Z_OK && ret != Z_STREAM_END) return false; |
| 3302 | |
| 3303 | } while (data_length > 0); |
| 3304 | |
| 3305 | return true; |
| 3306 | } |
| 3307 | #endif |
| 3308 | |
| 3309 | #ifdef CPPHTTPLIB_BROTLI_SUPPORT |
no test coverage detected