forked from OneOfOne/otk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
buffer.go
96 lines (79 loc) · 1.64 KB
/
buffer.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
87
88
89
90
91
92
93
94
95
96
package otk
import (
"bytes"
"io"
"sync"
"golang.org/x/xerrors"
)
var (
_ io.ReaderAt = (*Buffer)(nil)
ErrOffsetOOB = xerrors.New("offset out of bounds")
)
type BufferPool struct {
o sync.Once
p sync.Pool
}
func (bp *BufferPool) Get() *Buffer {
bp.o.Do(func() {
bp.p.New = func() interface{} {
return new(Buffer)
}
})
return bp.p.Get().(*Buffer)
}
func (bp *BufferPool) Put(b *Buffer) {
b.Reset()
bp.p.Put(b)
}
func NewBuffer(buf []byte) *Buffer {
var b Buffer
b.Write(buf)
return &b
}
func NewBufferString(s string) *Buffer {
var b Buffer
b.WriteString(s)
return &b
}
// Buffer is a drop-in replacement for bytes.Buffer that implements the io.ReaderAt interface.
type Buffer struct {
bytes.Buffer
ref []byte
}
func (b *Buffer) WriteByte(c byte) (err error) {
err = b.Buffer.WriteByte(c)
b.ref = b.Buffer.Bytes()
return
}
func (b *Buffer) WriteRune(r rune) (n int, err error) {
n, err = b.Buffer.WriteRune(r)
b.ref = b.Buffer.Bytes()
return
}
func (b *Buffer) Write(p []byte) (n int, err error) {
n, err = b.Buffer.Write(p)
b.ref = b.Buffer.Bytes()
return
}
func (b *Buffer) WriteString(s string) (n int, err error) {
n, err = b.Buffer.WriteString(s)
b.ref = b.Buffer.Bytes()
return
}
func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {
n, err = b.Buffer.ReadFrom(r)
b.ref = b.Buffer.Bytes()
return
}
func (b *Buffer) ReadAt(p []byte, off int64) (n int, err error) {
if int(off) > len(b.ref) {
err = ErrOffsetOOB
return
}
n = copy(p, b.ref[off:])
return
}
// UnsafeString returns the accumulated string, unsafely without a copy.
func (b *Buffer) UnsafeString() string {
return UnsafeString(b.Bytes())
}