-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathxbuffer.go
86 lines (75 loc) · 1.5 KB
/
xbuffer.go
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
package fastimage
import (
"io"
)
type xbuffer struct {
r io.Reader
buf []byte
}
func (b *xbuffer) fill(end int) error {
m := len(b.buf)
if end > m {
if end > cap(b.buf) {
newcap := 1024
for newcap < end {
newcap *= 2
}
newbuf := make([]byte, end, newcap)
copy(newbuf, b.buf)
b.buf = newbuf
} else {
b.buf = b.buf[:end]
}
if n, err := io.ReadFull(b.r, b.buf[m:end]); err != nil {
end = m + n
b.buf = b.buf[:end]
return err
}
}
return nil
}
func (b *xbuffer) ReadAt(p []byte, off int64) (int, error) {
o := int(off)
end := o + len(p)
if int64(end) != off+int64(len(p)) {
return 0, io.ErrUnexpectedEOF
}
err := b.fill(end)
return copy(p, b.buf[o:end]), err
}
func (b *xbuffer) Slice(off, n int) ([]byte, error) {
end := off + n
if err := b.fill(end); err != nil {
return nil, err
}
return b.buf[off:end], nil
}
func (b *xbuffer) ReadByte() (byte, error) {
current := len(b.buf)
if err := b.fill(current + 1); err != nil {
return 0, err
}
return b.buf[current], nil
}
func (b *xbuffer) ReadBytes(n int) ([]byte, error) {
current := len(b.buf)
if err := b.fill(current + n); err != nil {
return nil, err
}
return b.buf[current : current+n], nil
}
func (b *xbuffer) ReadFull(p []byte) (int, error) {
o := len(b.buf)
end := o + len(p)
err := b.fill(end)
return copy(p, b.buf[o:end]), err
}
func newReaderAt(r io.Reader) io.ReaderAt {
if ra, ok := r.(io.ReaderAt); ok {
return ra
}
return &xbuffer{
r: r,
buf: make([]byte, 0, 2),
}
}