1 // 2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 // 7 #include "td/utils/GzipByteFlow.h" 8 9 char disable_linker_warning_about_empty_file_gzipbyteflow_cpp TD_UNUSED; 10 11 #if TD_HAVE_ZLIB 12 #include "td/utils/common.h" 13 #include "td/utils/Status.h" 14 15 namespace td { 16 loop()17bool GzipByteFlow::loop() { 18 if (gzip_.need_input()) { 19 auto slice = input_->prepare_read(); 20 if (slice.empty()) { 21 if (!is_input_active_) { 22 gzip_.close_input(); 23 } else { 24 return false; 25 } 26 } else { 27 gzip_.set_input(input_->prepare_read()); 28 } 29 } 30 if (gzip_.need_output()) { 31 auto slice = output_.prepare_append(); 32 CHECK(!slice.empty()); 33 gzip_.set_output(slice); 34 } 35 auto r_state = gzip_.run(); 36 auto output_size = gzip_.flush_output(); 37 if (output_size) { 38 uncommited_size_ += output_size; 39 total_output_size_ += output_size; 40 if (total_output_size_ > max_output_size_) { 41 finish(Status::Error("Max output size limit exceeded")); 42 return false; 43 } 44 output_.confirm_append(output_size); 45 } 46 47 auto input_size = gzip_.flush_input(); 48 if (input_size) { 49 input_->confirm_read(input_size); 50 } 51 if (r_state.is_error()) { 52 finish(r_state.move_as_error()); 53 return false; 54 } 55 auto state = r_state.ok(); 56 if (state == Gzip::State::Done) { 57 consume_input(); 58 return false; 59 } 60 return true; 61 } 62 63 } // namespace td 64 65 #endif 66