| 152 | } |
| 153 | |
| 154 | func (r *objectReader) Seek(offset int64, whence int) (int64, error) { |
| 155 | if whence == io.SeekCurrent { |
| 156 | return r.Seek(r.currentPosition+offset, 0) |
| 157 | } |
| 158 | |
| 159 | if whence == io.SeekEnd { |
| 160 | return r.Seek(r.totalLength+offset, 0) |
| 161 | } |
| 162 | |
| 163 | if offset >= r.totalLength { |
| 164 | r.currentChunkIndex = len(r.seekTable) |
| 165 | r.currentChunkData = nil |
| 166 | r.currentPosition = offset |
| 167 | |
| 168 | return offset, nil |
| 169 | } |
| 170 | |
| 171 | index, err := r.findChunkIndexForOffset(offset) |
| 172 | if err != nil { |
| 173 | return -1, errors.Wrapf(err, "invalid seek %v %v", offset, whence) |
| 174 | } |
| 175 | |
| 176 | chunkStartOffset := r.seekTable[index].Start |
| 177 | |
| 178 | if index != r.currentChunkIndex { |
| 179 | r.closeCurrentChunk() |
| 180 | r.currentChunkIndex = index |
| 181 | } |
| 182 | |
| 183 | if r.currentChunkData == nil { |
| 184 | if err := r.openCurrentChunk(); err != nil { |
| 185 | return 0, err |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | r.currentChunkPosition = int(offset - chunkStartOffset) |
| 190 | r.currentPosition = offset |
| 191 | |
| 192 | return r.currentPosition, nil |
| 193 | } |
| 194 | |
| 195 | func (r *objectReader) Close() error { |
| 196 | return nil |