| 73 | } |
| 74 | |
| 75 | void ZlibOutputBuffer::AddToInputBuffer(StringPiece data) { |
| 76 | size_t bytes_to_write = data.size(); |
| 77 | CHECK_LE(bytes_to_write, AvailableInputSpace()); |
| 78 | |
| 79 | // Input stream -> |
| 80 | // [....................input_buffer_capacity_...............] |
| 81 | // [<...read_bytes...><...avail_in...>......empty space......] |
| 82 | // ^ ^ |
| 83 | // | | |
| 84 | // z_stream_input_ next_in |
| 85 | // |
| 86 | // Data in the input stream is sharded as show above. z_stream_->next_in could |
| 87 | // be pointing to some byte in the buffer with avail_in number of bytes |
| 88 | // available to be read. |
| 89 | // |
| 90 | // In order to avoid shifting the avail_in bytes at next_in to the head of |
| 91 | // the buffer we try to fit `data` in the empty space at the tail of the |
| 92 | // input stream. |
| 93 | // TODO(srbs): This could be avoided if we had a circular buffer. |
| 94 | // If it doesn't fit we free the space at the head of the stream and then |
| 95 | // append `data` at the end of existing data. |
| 96 | |
| 97 | int32 read_bytes = z_stream_->next_in - z_stream_input_.get(); |
| 98 | int32 unread_bytes = z_stream_->avail_in; |
| 99 | int32 free_tail_bytes = input_buffer_capacity_ - (read_bytes + unread_bytes); |
| 100 | |
| 101 | if (bytes_to_write > free_tail_bytes) { |
| 102 | memmove(z_stream_input_.get(), z_stream_->next_in, z_stream_->avail_in); |
| 103 | z_stream_->next_in = z_stream_input_.get(); |
| 104 | } |
| 105 | memcpy(z_stream_->next_in + z_stream_->avail_in, data.data(), bytes_to_write); |
| 106 | z_stream_->avail_in += bytes_to_write; |
| 107 | } |
| 108 | |
| 109 | Status ZlibOutputBuffer::DeflateBuffered(int flush_mode) { |
| 110 | do { |