-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbuffer.go
118 lines (104 loc) · 1.7 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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package smux
type Buffer struct {
r, w int
buf []byte
cap int
empty bool
}
func NewBuffer(size int) *Buffer {
return &Buffer{
buf: make([]byte, size),
cap: size,
empty: true,
}
}
func (b *Buffer) Empty() bool {
return b.empty
}
func (b *Buffer) Full() bool {
if b.r == b.w && !b.empty {
return true
}
return false
}
func (b *Buffer) Clear() {
b.r = 0
b.w = 0
b.empty = true
}
func (b *Buffer) Len() int {
if b.w > b.r {
return b.w - b.r
} else if b.w < b.r {
return b.cap - b.r + b.w
} else {
if b.empty {
return 0
} else {
return b.cap
}
}
}
func (b *Buffer) Cap() int {
return b.cap
}
func (b *Buffer) Grow(n int) {
buf := make([]byte, b.cap+n)
var num int
if !b.empty {
if b.w > b.r {
num = copy(buf, b.buf[b.r:b.w])
} else {
num = copy(buf, b.buf[b.r:])
if b.w > 0 {
num += copy(buf[num:], b.buf[:b.w])
}
}
}
b.cap = b.cap + n
b.buf = buf
b.r = 0
b.w = num % b.cap
}
func (b *Buffer) Read(buf []byte) (n int, err error) {
plen := len(buf)
if plen == 0 || b.empty {
return
}
if b.w > b.r {
n = copy(buf, b.buf[b.r:b.w])
b.r = (b.r + n) % b.cap
} else {
n = copy(buf, b.buf[b.r:])
b.r = (b.r + n) % b.cap
if plen > n && b.w > 0 {
b.r = copy(buf[n:], b.buf[:b.w])
n += b.r
}
}
if b.r == b.w {
b.empty = true
}
return
}
func (b *Buffer) Write(buf []byte) (n int, err error) {
plen := len(buf)
if plen == 0 || (b.r == b.w && !b.empty) {
return
}
if b.w < b.r {
n = copy(b.buf[b.w:b.r], buf)
b.w = (b.w + n) % b.cap
} else {
n = copy(b.buf[b.w:], buf)
b.w = (b.w + n) % b.cap
if plen > n && b.r > 0 {
b.w = copy(b.buf[:b.r], buf[n:])
n += b.w
}
}
if n > 0 {
b.empty = false
}
return
}