| 143 | } |
| 144 | |
| 145 | Status ZlibOutputBuffer::Append(StringPiece data) { |
| 146 | // If there is sufficient free space in z_stream_input_ to fit data we |
| 147 | // add it there and return. |
| 148 | // If there isn't enough space we deflate the existing contents of |
| 149 | // z_input_stream_. If data now fits in z_input_stream_ we add it there |
| 150 | // else we directly deflate it. |
| 151 | // |
| 152 | // The deflated output is accumulated in z_stream_output_ and gets written to |
| 153 | // file as and when needed. |
| 154 | |
| 155 | size_t bytes_to_write = data.size(); |
| 156 | |
| 157 | if (bytes_to_write <= AvailableInputSpace()) { |
| 158 | AddToInputBuffer(data); |
| 159 | return Status::OK(); |
| 160 | } |
| 161 | |
| 162 | TF_RETURN_IF_ERROR(DeflateBuffered(zlib_options_.flush_mode)); |
| 163 | |
| 164 | // At this point input stream should be empty. |
| 165 | if (bytes_to_write <= AvailableInputSpace()) { |
| 166 | AddToInputBuffer(data); |
| 167 | return Status::OK(); |
| 168 | } |
| 169 | |
| 170 | // `data` is too large to fit in input buffer so we deflate it directly. |
| 171 | // Note that at this point we have already deflated all existing input so |
| 172 | // we do not need to backup next_in and avail_in. |
| 173 | z_stream_->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data.data())); |
| 174 | z_stream_->avail_in = bytes_to_write; |
| 175 | |
| 176 | do { |
| 177 | if (z_stream_->avail_out == 0) { |
| 178 | // No available output space. |
| 179 | // Write output buffer to file. |
| 180 | TF_RETURN_IF_ERROR(FlushOutputBufferToFile()); |
| 181 | } |
| 182 | TF_RETURN_IF_ERROR(Deflate(zlib_options_.flush_mode)); |
| 183 | } while (z_stream_->avail_out == 0); |
| 184 | |
| 185 | DCHECK(z_stream_->avail_in == 0); // All input will be used up. |
| 186 | |
| 187 | // Restore z_stream input pointers. |
| 188 | z_stream_->next_in = z_stream_input_.get(); |
| 189 | |
| 190 | return Status::OK(); |
| 191 | } |
| 192 | |
| 193 | #if defined(PLATFORM_GOOGLE) |
| 194 | Status ZlibOutputBuffer::Append(const absl::Cord& cord) { |