-
Notifications
You must be signed in to change notification settings - Fork 0
/
block_notifying_reader.go
60 lines (47 loc) · 1.5 KB
/
block_notifying_reader.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
package eyego
import "io"
type BlockNotifyingReader struct {
delegate io.Reader
state *blockState
blockSize int
notifier func([]byte)
}
type blockState struct {
buf []byte
ptr int
}
func NewBlockNotifyingReader(_delegate io.Reader, _blockSize int, _notifier func([]byte)) BlockNotifyingReader {
return BlockNotifyingReader{
delegate: _delegate,
blockSize: _blockSize,
notifier: _notifier,
state: &blockState{
buf: make([]byte, _blockSize),
ptr: 0}}
}
func (r BlockNotifyingReader) Read(p []byte) (n int, err error){
n, err = r.delegate.Read(p)
if err == nil && n > 0 {
r.appendBytes(p, n)
}
return n, err
}
func (r BlockNotifyingReader) appendBytes(b []byte, len int) {
Trace("Appending %d bytes", len)
srcPtr := 0
for ;r.state.ptr + (len - srcPtr) >= r.blockSize; {
Trace("Adding block")
Trace("Filling from source[%d:%d] to buf[%d:%d]", srcPtr, r.blockSize-r.state.ptr + srcPtr, r.state.ptr, r.blockSize)
toAdd := copy(r.state.buf[r.state.ptr:r.blockSize], b[srcPtr:r.blockSize-r.state.ptr + srcPtr]) //copy bytes to fill temp buffer
// Trace("Notifying %v", r.state.buf)
r.notifier(r.state.buf)
// r.state.buf = r.state.buf[:0]
r.state.ptr = 0
srcPtr += toAdd
}
Trace("srcPtr: %d", srcPtr)
//copy remaining
Trace("Adding %d bytes to (%d byte) buffer", len-srcPtr, r.state.ptr)
Trace("Copying from source[%d:%d] to buf[%d:%d]", srcPtr, len-srcPtr, r.state.ptr, r.state.ptr+len-srcPtr)
r.state.ptr += copy(r.state.buf[r.state.ptr:r.state.ptr+len-srcPtr], b[srcPtr:len])
}