| 142 | } |
| 143 | |
| 144 | Status SnappyInputBuffer::ReadFromFile() { |
| 145 | int bytes_to_read = input_buffer_capacity_; |
| 146 | char* read_location = reinterpret_cast<char*>(input_buffer_.get()); |
| 147 | |
| 148 | // If there are unread bytes in the input stream we move them to the head |
| 149 | // of the stream to maximize the space available to read new data into. |
| 150 | // TODO(srbs): A circular buffer would be useful here. |
| 151 | if (avail_in_ > 0) { |
| 152 | size_t read_bytes = next_in_ - input_buffer_.get(); |
| 153 | // Remove `read_bytes` from the head of the input stream. |
| 154 | // Move unread bytes to the head of the input stream. |
| 155 | if (read_bytes > 0) { |
| 156 | memmove(input_buffer_.get(), next_in_, avail_in_); |
| 157 | } |
| 158 | |
| 159 | bytes_to_read -= avail_in_; |
| 160 | read_location += avail_in_; |
| 161 | } |
| 162 | StringPiece data; |
| 163 | // Try to read enough data to fill up input_buffer_. |
| 164 | Status s = file_->Read(file_pos_, bytes_to_read, &data, read_location); |
| 165 | if (data.data() != read_location) { |
| 166 | memmove(read_location, data.data(), data.size()); |
| 167 | } |
| 168 | |
| 169 | // Since we moved unread data to the head of the input stream we can point |
| 170 | // next_in to the head of the input stream. |
| 171 | next_in_ = input_buffer_.get(); |
| 172 | |
| 173 | // Note: data.size() could be different from bytes_to_read. |
| 174 | avail_in_ += data.size(); |
| 175 | file_pos_ += data.size(); |
| 176 | |
| 177 | if (!s.ok() && !errors::IsOutOfRange(s)) { |
| 178 | return s; |
| 179 | } |
| 180 | |
| 181 | // We throw OutOfRange error iff no new data has been read from file. |
| 182 | // Since we never check how much data is remaining in the file, it is |
| 183 | // possible that on the last read there isn't enough data in the file to |
| 184 | // fill up the buffer in which case file_->ReadNBytes would return an |
| 185 | // OutOfRange error. |
| 186 | if (data.empty()) { |
| 187 | return errors::OutOfRange("EOF reached"); |
| 188 | } |
| 189 | if (errors::IsOutOfRange(s)) { |
| 190 | return Status::OK(); |
| 191 | } |
| 192 | |
| 193 | return s; |
| 194 | } |
| 195 | |
| 196 | } // namespace io |
| 197 | } // namespace tensorflow |