/
ringbuffer.go
77 lines (63 loc) · 1.38 KB
/
ringbuffer.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
package flac
import (
"errors"
)
type RingBuffer struct {
buf []byte
capacity int
readPos int
writePos int
size int
}
func NewRingBuffer(capacity int) RingBuffer {
rb := RingBuffer{
capacity: capacity,
buf: make([]byte, capacity),
}
return rb
}
func (rb *RingBuffer) Capacity() int {
return rb.capacity
}
func (rb *RingBuffer) Size() int {
return rb.size
}
func (rb *RingBuffer) Reset() {
rb.size = 0
rb.readPos = 0
rb.writePos = 0
}
func (rb *RingBuffer) Read(n int, dst []byte) (int, error) {
if rb.size < n {
return 0, errors.New("invalid n")
}
if rb.readPos+n <= rb.capacity {
copy(dst, rb.buf[rb.readPos:rb.readPos+n])
rb.readPos += n
rb.size -= n
return n, nil
}
copy(dst, rb.buf[rb.readPos:rb.capacity])
copy(dst[rb.capacity-rb.readPos:], rb.buf[0:n-(rb.capacity-rb.readPos)])
rb.readPos = n - (rb.capacity - rb.readPos)
rb.size -= n
return n, nil
}
func (rb *RingBuffer) Write(data []byte) (int, error) {
szData := len(data)
if szData > rb.Capacity()-rb.Size() {
return 0, errors.New("data len exceed capacity")
}
szToEnd := rb.writePos + szData
if szToEnd <= rb.Capacity() {
copy(rb.buf[rb.writePos:], data)
rb.writePos += len(data)
} else {
sz1 := rb.Capacity() - rb.writePos
copy(rb.buf[rb.writePos:], data[:sz1])
copy(rb.buf[0:], data[sz1:])
rb.writePos = szData - sz1
}
rb.size += szData
return szData, nil
}