File size: 1,667 Bytes
619f93d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | package buffer
import (
"errors"
"io"
"os"
)
type PeekFile struct {
peek *Reader
file *os.File
offset int64
size int64
}
func (p *PeekFile) Read(b []byte) (n int, err error) {
n, err = p.ReadAt(b, p.offset)
if n > 0 {
p.offset += int64(n)
}
return n, err
}
func (p *PeekFile) ReadAt(b []byte, off int64) (n int, err error) {
if off < p.peek.Size() {
n, err = p.peek.ReadAt(b, off)
if err == nil || n == len(b) {
return n, nil
}
// EOF
}
var nn int
nn, err = p.file.ReadAt(b[n:], off+int64(n)-p.peek.Size())
return n + nn, err
}
func (p *PeekFile) Seek(offset int64, whence int) (int64, error) {
switch whence {
case io.SeekStart:
case io.SeekCurrent:
if offset == 0 {
return p.offset, nil
}
offset = p.offset + offset
case io.SeekEnd:
offset = p.size + offset
default:
return 0, errors.New("Seek: invalid whence")
}
if offset < 0 || offset > p.size {
return 0, errors.New("Seek: invalid offset")
}
if offset <= p.peek.Size() {
_, err := p.peek.Seek(offset, io.SeekStart)
if err != nil {
return 0, err
}
_, err = p.file.Seek(0, io.SeekStart)
if err != nil {
return 0, err
}
} else {
_, err := p.peek.Seek(p.peek.Size(), io.SeekStart)
if err != nil {
return 0, err
}
_, err = p.file.Seek(offset-p.peek.Size(), io.SeekStart)
if err != nil {
return 0, err
}
}
p.offset = offset
return offset, nil
}
func (p *PeekFile) Size() int64 {
return p.size
}
func NewPeekFile(peek *Reader, file *os.File) (*PeekFile, error) {
stat, err := file.Stat()
if err == nil {
return &PeekFile{peek: peek, file: file, size: stat.Size() + peek.Size()}, nil
}
return nil, err
}
|