| 52 | } |
| 53 | |
| 54 | func (r *objectReader) Read(buffer []byte) (int, error) { |
| 55 | readBytes := 0 |
| 56 | remaining := len(buffer) |
| 57 | |
| 58 | if r.currentPosition >= r.totalLength { |
| 59 | return 0, io.EOF |
| 60 | } |
| 61 | |
| 62 | for remaining > 0 { |
| 63 | if r.currentChunkData != nil { |
| 64 | toCopy := len(r.currentChunkData) - r.currentChunkPosition |
| 65 | if toCopy == 0 { |
| 66 | // EOF on current chunk |
| 67 | r.closeCurrentChunk() |
| 68 | |
| 69 | r.currentChunkIndex++ |
| 70 | |
| 71 | continue |
| 72 | } |
| 73 | |
| 74 | if toCopy > remaining { |
| 75 | toCopy = remaining |
| 76 | } |
| 77 | |
| 78 | copy(buffer[readBytes:], |
| 79 | r.currentChunkData[r.currentChunkPosition:r.currentChunkPosition+toCopy]) |
| 80 | |
| 81 | r.currentChunkPosition += toCopy |
| 82 | r.currentPosition += int64(toCopy) |
| 83 | readBytes += toCopy |
| 84 | remaining -= toCopy |
| 85 | |
| 86 | continue |
| 87 | } |
| 88 | |
| 89 | if r.currentChunkIndex < len(r.seekTable) { |
| 90 | err := r.openCurrentChunk() |
| 91 | if err != nil { |
| 92 | return 0, err |
| 93 | } |
| 94 | } else { |
| 95 | break |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | if readBytes == 0 { |
| 100 | return readBytes, io.EOF |
| 101 | } |
| 102 | |
| 103 | return readBytes, nil |
| 104 | } |
| 105 | |
| 106 | func (r *objectReader) openCurrentChunk() error { |
| 107 | st := r.seekTable[r.currentChunkIndex] |