ReadAt is the magic sauce. Heavily commented to include all logic.
(p []byte, off int64)
| 119 | |
| 120 | // ReadAt is the magic sauce. Heavily commented to include all logic. |
| 121 | func (mr *multiReaderAt) ReadAt(p []byte, off int64) (n int, err error) { |
| 122 | startF, endF := 0, 0 |
| 123 | startPos, endPos, length := int64(0), int64(0), int64(len(p)) |
| 124 | |
| 125 | if off > mr.size { |
| 126 | return 0, io.EOF |
| 127 | } |
| 128 | |
| 129 | // find start |
| 130 | for i, fd := range mr.boundaries { |
| 131 | if off >= fd.start && off <= fd.end { |
| 132 | startF = i |
| 133 | startPos = off - fd.start |
| 134 | break |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | // find end |
| 139 | if off+length > mr.size { |
| 140 | endF = len(mr.readers) - 1 |
| 141 | endPos = mr.size - mr.boundaries[endF].start |
| 142 | } else { |
| 143 | for i, fd := range mr.boundaries { |
| 144 | if off+length >= fd.start && off+length <= fd.end { |
| 145 | endF = i |
| 146 | endPos = off + length - fd.start |
| 147 | break |
| 148 | } |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | if startF == endF { |
| 153 | // read startpos till endpos |
| 154 | // println("--> readat: startpos till endpos") |
| 155 | // fmt.Printf("file: %d, offset: %d, length: %d\n", startF, startPos, endPos-startPos) |
| 156 | return mr.readers[startF].ReadAt(p[0:length], startPos) |
| 157 | } else { |
| 158 | buffPos := 0 |
| 159 | for i := startF; i <= endF; i++ { |
| 160 | if i == startF { |
| 161 | // read startpos till end of file |
| 162 | // println("--> readat: startpos till end of file") |
| 163 | // fmt.Printf("file: %d, offset: %d, length: %d, buffPos: %d\n", i, startPos, mr.boundaries[i].size-startPos, buffPos) |
| 164 | if rn, err := mr.readers[i].ReadAt(p[buffPos:buffPos+int(mr.boundaries[i].size-startPos)], startPos); err != nil && err != io.EOF { |
| 165 | return 0, err |
| 166 | } else { |
| 167 | buffPos = buffPos + int(mr.boundaries[i].size-startPos) |
| 168 | n = n + rn |
| 169 | } |
| 170 | } else if i == endF { |
| 171 | // read start of file till endpos |
| 172 | // println("--> readat: start of file till endpos") |
| 173 | // fmt.Printf("file: %d, offset: %d, length: %d, buffPos: %d\n", i, 0, endPos, buffPos) |
| 174 | if rn, err := mr.readers[i].ReadAt(p[buffPos:buffPos+int(endPos)], 0); err != nil && err != io.EOF { |
| 175 | println("--> error here: ", err.Error()) |
| 176 | return 0, err |
| 177 | } else { |
| 178 | buffPos = buffPos + int(endPos) |
no test coverage detected