60 lines
1.2 KiB
Go
60 lines
1.2 KiB
Go
// Copyright (C) 2018 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package filestore
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
"os"
|
|
)
|
|
|
|
// blobBodyReader implements reader that is offset by blob header size
|
|
type blobBodyReader struct {
|
|
file *os.File
|
|
}
|
|
|
|
func newBlobBodyReader(file *os.File) (blobBodyReader, error) {
|
|
_, err := file.Seek(headerSize, io.SeekStart)
|
|
return blobBodyReader{file}, err
|
|
}
|
|
|
|
func (r blobBodyReader) Read(p []byte) (n int, err error) {
|
|
return r.file.Read(p)
|
|
}
|
|
|
|
func (r blobBodyReader) Close() error {
|
|
return r.file.Close()
|
|
}
|
|
|
|
func (r blobBodyReader) ReadAt(p []byte, off int64) (n int, err error) {
|
|
if off < 0 {
|
|
return 0, errors.New("invalid offset")
|
|
}
|
|
|
|
return r.file.ReadAt(p, off+headerSize)
|
|
}
|
|
|
|
func (r blobBodyReader) Seek(offset int64, whence int) (int64, error) {
|
|
var pos int64
|
|
var err error
|
|
if whence == io.SeekStart {
|
|
pos, err = r.file.Seek(offset+headerSize, io.SeekStart)
|
|
} else {
|
|
pos, err = r.file.Seek(offset, whence)
|
|
}
|
|
pos -= headerSize
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
if pos < 0 {
|
|
return -1, errors.New("invalid offset")
|
|
}
|
|
return pos, err
|
|
}
|
|
|
|
func (r blobBodyReader) Size() (n int64) {
|
|
stat, _ := r.file.Stat()
|
|
return stat.Size() - headerSize
|
|
}
|