OnlineLibrary
64 строки · 1.2 Кб
1package buffer
2
3import (
4"bytes"
5"fmt"
6"io"
7)
8
9const default_buffer_size = 1024 * 16
10
11type Reader struct {
12source io.ReadSeeker
13nReadsFromSource int64
14buffer []byte
15br *bytes.Reader
16lastErr error
17}
18
19func NewReader(src io.ReadSeeker) *Reader {
20return NewReaderSize(src, default_buffer_size)
21}
22
23func NewReaderSize(src io.ReadSeeker, bufSize int) *Reader {
24r := new(Reader)
25r.source = src
26r.buffer = make([]byte, bufSize)
27r.br = bytes.NewReader(nil)
28return r
29}
30
31func (r *Reader) Read(p []byte) (int, error) {
32if len(p) == 0 {
33return 0, io.ErrShortBuffer
34}
35if r.br.Len() == 0 {
36if r.lastErr != nil {
37return 0, r.lastErr
38}
39var n int
40n, r.lastErr = r.source.Read(r.buffer)
41if n == 0 {
42return 0, r.lastErr
43}
44r.nReadsFromSource += int64(n)
45r.br.Reset(r.buffer[:n])
46}
47return r.br.Read(p)
48}
49
50func (r *Reader) Seek(offset int64, whence int) (int64, error) {
51if offset < 0 {
52return 0, fmt.Errorf("negative offset not supported")
53}
54if whence != io.SeekStart {
55return 0, fmt.Errorf("whence %v not supported", whence)
56}
57r.br.Reset(nil)
58sourceOffset, err := r.source.Seek(offset, io.SeekStart)
59if err != nil {
60r.lastErr = err
61}
62r.nReadsFromSource = sourceOffset
63return sourceOffset, err
64}
65