forked from alberliu/gn
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuffer.go
91 lines (78 loc) · 1.86 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
package gn
import (
"errors"
"io"
"syscall"
)
var ErrNotEnough = errors.New("not enough")
// Buffer 读缓冲区,每个tcp长连接对应一个读缓冲区
type Buffer struct {
buf []byte // 应用内缓存区
start int // 有效字节开始位置
end int // 有效字节结束位置
}
// NewBuffer 创建一个缓存区
func NewBuffer(bytes []byte) *Buffer {
return &Buffer{buf: bytes, start: 0, end: 0}
}
// Len 返回有效字节数组长度
func (b *Buffer) Len() int {
return b.end - b.start
}
// Cap 返回总容量
func (b *Buffer) Cap() int {
return len(b.buf)
}
func (b *Buffer) GetBuf() []byte {
return b.buf
}
// ReadFromFD 从文件描述符里面读取数据
func (b *Buffer) ReadFromFD(fd int) error {
b.reset()
n, err := syscall.Read(fd, b.buf[b.end:])
if err != nil {
return err
}
if n == 0 {
return syscall.EAGAIN
}
b.end += n
return nil
}
// ReadFromReader 从reader里面读取数据,如果reader阻塞,会发生阻塞
func (b *Buffer) ReadFromReader(reader io.Reader) (int, error) {
b.reset()
n, err := reader.Read(b.buf[b.end:])
if err != nil {
return n, err
}
b.end += n
return n, nil
}
// Seek 返回n个字节,而不产生移位,如果没有足够字节,返回错误
func (b *Buffer) Seek(len int) ([]byte, error) {
if b.end-b.start >= len {
buf := b.buf[b.start : b.start+len]
return buf, nil
}
return nil, ErrNotEnough
}
// Read 舍弃offset个字段,读取n个字段,如果没有足够的字节,返回错误
func (b *Buffer) Read(offset, limit int) ([]byte, error) {
if b.Len() < offset+limit {
return nil, ErrNotEnough
}
b.start += offset
buf := b.buf[b.start : b.start+limit]
b.start += limit
return buf, nil
}
// reset 重新设置缓存区(将有用字节前移)
func (b *Buffer) reset() {
if b.start == 0 {
return
}
copy(b.buf, b.buf[b.start:b.end])
b.end -= b.start
b.start = 0
}