-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbuffer.go
More file actions
95 lines (82 loc) · 1.83 KB
/
buffer.go
File metadata and controls
95 lines (82 loc) · 1.83 KB
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
package bpool
import (
"errors"
"sync/atomic"
)
type (
buffer struct {
buf []byte
size int64
}
)
func (b *buffer) append(data []byte) (int64, error) {
off := b.Size()
if _, err := b.writeAt(data, off); err != nil {
return 0, err
}
return off, nil
}
func (b *buffer) allocate(size uint32) (int64, error) {
if size == 0 {
panic("unable to allocate zero bytes")
}
off := b.Size()
return off, b.truncate(off + int64(size))
}
func (b *buffer) bytes() ([]byte, error) {
return b.slice(0, b.Size())
}
func (b *buffer) reset() (ok bool) {
atomic.StoreInt64(&b.size, 0)
b.buf = b.buf[:0]
return true
}
func (b *buffer) read(p []byte) (int, error) {
n := len(p)
if int64(n) > b.Size() {
return 0, errors.New("eof")
}
copy(p, b.buf[:int64(n)])
return n, nil
}
func (b *buffer) readAt(p []byte, off int64) (int, error) {
n := len(p)
if int64(n) > b.Size()-off {
return 0, errors.New("eof")
}
copy(p, b.buf[off:off+int64(n)])
return n, nil
}
func (b *buffer) writeAt(p []byte, off int64) (int, error) {
n := len(p)
if off == b.Size() {
b.buf = append(b.buf, p...)
atomic.AddInt64(&b.size, int64(n))
} else if off+int64(n) > b.Size() {
panic("trying to write past EOF - undefined behavior")
} else {
copy(b.buf[off:off+int64(n)], p)
}
return n, nil
}
func (b *buffer) truncate(size int64) error {
if size > b.Size() {
diff := int(size - b.Size())
b.buf = append(b.buf, make([]byte, diff)...)
} else {
b.buf = b.buf[:b.Size()]
}
atomic.StoreInt64(&b.size, size)
return nil
}
func (b *buffer) slice(start int64, end int64) ([]byte, error) {
return b.buf[start:end], nil
}
// Size returns buffer size
func (b *buffer) Size() int64 {
return atomic.LoadInt64(&b.size)
}
// incSize increases buffer size to allocate more buffer
func (b *buffer) grow(size int64) int64 {
return atomic.AddInt64(&b.size, size)
}