-
Notifications
You must be signed in to change notification settings - Fork 0
/
multi_buffer.go
138 lines (120 loc) · 2.59 KB
/
multi_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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package buf
import "net"
type MultiBufferWriter interface {
WriteMultiBuffer(MultiBuffer) error
}
type MultiBufferReader interface {
ReadMultiBuffer() (MultiBuffer, error)
}
// MultiBuffer is a list of Buffers. The order of Buffer matters.
type MultiBuffer []*Buffer
// NewMultiBuffer creates a new MultiBuffer instance.
func NewMultiBuffer() MultiBuffer {
return MultiBuffer(make([]*Buffer, 0, 128))
}
// NewMultiBufferValue wraps a list of Buffers into MultiBuffer.
func NewMultiBufferValue(b ...*Buffer) MultiBuffer {
return MultiBuffer(b)
}
func (mb *MultiBuffer) Append(buf *Buffer) {
*mb = append(*mb, buf)
}
func (mb *MultiBuffer) AppendMulti(buf MultiBuffer) {
*mb = append(*mb, buf...)
}
func (mb MultiBuffer) Copy(b []byte) int {
total := 0
for _, bb := range mb {
nBytes := copy(b[total:], bb.Bytes())
total += nBytes
if nBytes < bb.Len() {
break
}
}
return total
}
func (mb *MultiBuffer) Read(b []byte) (int, error) {
endIndex := len(*mb)
totalBytes := 0
for i, bb := range *mb {
nBytes, _ := bb.Read(b)
totalBytes += nBytes
b = b[nBytes:]
if bb.IsEmpty() {
bb.Release()
} else {
endIndex = i
break
}
}
*mb = (*mb)[endIndex:]
return totalBytes, nil
}
func (mb *MultiBuffer) Write(b []byte) {
n := len(*mb)
if n > 0 && !(*mb)[n-1].IsFull() {
nBytes, _ := (*mb)[n-1].Write(b)
b = b[nBytes:]
}
for len(b) > 0 {
bb := New()
nBytes, _ := bb.Write(b)
b = b[nBytes:]
mb.Append(bb)
}
}
// Len returns the total number of bytes in the MultiBuffer.
func (mb MultiBuffer) Len() int {
size := 0
for _, b := range mb {
size += b.Len()
}
return size
}
// IsEmpty return true if the MultiBuffer has no content.
func (mb MultiBuffer) IsEmpty() bool {
for _, b := range mb {
if !b.IsEmpty() {
return false
}
}
return true
}
// Release releases all Buffers in the MultiBuffer.
func (mb MultiBuffer) Release() {
for i, b := range mb {
b.Release()
mb[i] = nil
}
}
// ToNetBuffers converts this MultiBuffer to net.Buffers. The return net.Buffers points to the same content of the MultiBuffer.
func (mb MultiBuffer) ToNetBuffers() net.Buffers {
bs := make([][]byte, len(mb))
for i, b := range mb {
bs[i] = b.Bytes()
}
return bs
}
func (mb *MultiBuffer) SliceBySize(size int) MultiBuffer {
slice := NewMultiBuffer()
sliceSize := 0
endIndex := len(*mb)
for i, b := range *mb {
if b.Len()+sliceSize > size {
endIndex = i
break
}
sliceSize += b.Len()
slice.Append(b)
}
*mb = (*mb)[endIndex:]
return slice
}
func (mb *MultiBuffer) SplitFirst() *Buffer {
if len(*mb) == 0 {
return nil
}
b := (*mb)[0]
*mb = (*mb)[1:]
return b
}