| 114 | } |
| 115 | |
| 116 | Status ZlibInputStream::ReadFromStream() { |
| 117 | int bytes_to_read = input_buffer_capacity_; |
| 118 | char* read_location = reinterpret_cast<char*>(z_stream_def_->input.get()); |
| 119 | |
| 120 | // If there are unread bytes in the input stream we move them to the head |
| 121 | // of the stream to maximize the space available to read new data into. |
| 122 | if (z_stream_def_->stream->avail_in > 0) { |
| 123 | uLong read_bytes = |
| 124 | z_stream_def_->stream->next_in - z_stream_def_->input.get(); |
| 125 | // Remove `read_bytes` from the head of the input stream. |
| 126 | // Move unread bytes to the head of the input stream. |
| 127 | if (read_bytes > 0) { |
| 128 | memmove(z_stream_def_->input.get(), z_stream_def_->stream->next_in, |
| 129 | z_stream_def_->stream->avail_in); |
| 130 | } |
| 131 | |
| 132 | bytes_to_read -= z_stream_def_->stream->avail_in; |
| 133 | read_location += z_stream_def_->stream->avail_in; |
| 134 | } |
| 135 | string data; |
| 136 | // Try to read enough data to fill up z_stream_def_->input. |
| 137 | // TODO(rohanj): Add a char* version of ReadNBytes to InputStreamInterface |
| 138 | // and use that instead to make this more efficient. |
| 139 | Status s = input_stream_->ReadNBytes(bytes_to_read, &data); |
| 140 | memcpy(read_location, data.data(), data.size()); |
| 141 | |
| 142 | // Since we moved unread data to the head of the input stream we can point |
| 143 | // next_in to the head of the input stream. |
| 144 | z_stream_def_->stream->next_in = z_stream_def_->input.get(); |
| 145 | |
| 146 | // Note: data.size() could be different from bytes_to_read. |
| 147 | z_stream_def_->stream->avail_in += data.size(); |
| 148 | |
| 149 | if (!s.ok() && !errors::IsOutOfRange(s)) { |
| 150 | return s; |
| 151 | } |
| 152 | |
| 153 | // We throw OutOfRange error iff no new data has been read from stream. |
| 154 | // Since we never check how much data is remaining in the stream, it is |
| 155 | // possible that on the last read there isn't enough data in the stream to |
| 156 | // fill up the buffer in which case input_stream_->ReadNBytes would return an |
| 157 | // OutOfRange error. |
| 158 | if (data.empty()) { |
| 159 | return errors::OutOfRange("EOF reached"); |
| 160 | } |
| 161 | if (errors::IsOutOfRange(s)) { |
| 162 | return Status::OK(); |
| 163 | } |
| 164 | |
| 165 | return s; |
| 166 | } |
| 167 | |
| 168 | size_t ZlibInputStream::ReadBytesFromCache(size_t bytes_to_read, |
| 169 | string* result) { |