read returns the data [from, to). Requires: to > from and [to, from) is contained in the file.
(e sqlExecutor, inodeID, from, to uint64)
| 191 | // read returns the data [from, to). |
| 192 | // Requires: to > from and [to, from) is contained in the file. |
| 193 | func read(e sqlExecutor, inodeID, from, to uint64) ([]byte, error) { |
| 194 | readRange := newBlockRange(from, to-from) |
| 195 | end := readRange.last |
| 196 | if readRange.lastLength == 0 { |
| 197 | end-- |
| 198 | } |
| 199 | |
| 200 | blockInfos, err := getBlocksBetween(e, inodeID, readRange.start, end) |
| 201 | if err != nil { |
| 202 | return nil, err |
| 203 | } |
| 204 | if len(blockInfos) != end-readRange.start+1 { |
| 205 | return nil, fmt.Errorf("wrong number of blocks, asked for [%d-%d], got %d back", |
| 206 | readRange.start, end, len(blockInfos)) |
| 207 | } |
| 208 | |
| 209 | if readRange.lastLength != 0 { |
| 210 | // We have a last partial block, truncate it. |
| 211 | last := len(blockInfos) - 1 |
| 212 | blockInfos[last].data = blockInfos[last].data[:readRange.lastLength] |
| 213 | } |
| 214 | blockInfos[0].data = blockInfos[0].data[readRange.startOffset:] |
| 215 | |
| 216 | var data []byte |
| 217 | for _, b := range blockInfos { |
| 218 | data = append(data, b.data...) |
| 219 | } |
| 220 | |
| 221 | return data, nil |
| 222 | } |
| 223 | |
| 224 | // write commits data to the blocks starting at 'offset' |
| 225 | // Amount of data to write must be non-zero. |