-
Notifications
You must be signed in to change notification settings - Fork 33
/
chunkbuf.go
90 lines (75 loc) · 1.86 KB
/
chunkbuf.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
package chunkbuf
import (
"io"
"github.com/sahib/brig/util"
)
// ChunkBuffer represents a custom buffer struct with Read/Write and Seek support.
type ChunkBuffer struct {
buf []byte
readOff int64
writeOff int64
size int64
}
const (
maxChunkSize = 64 * 1024
)
func (c *ChunkBuffer) Write(p []byte) (int, error) {
n := copy(c.buf[c.writeOff:c.size], p)
c.writeOff += int64(n)
c.size = util.Max64(c.size, c.writeOff)
return n, nil
}
// Reset resets the buffer like bytes.Buffer
func (c *ChunkBuffer) Reset() {
c.readOff = 0
c.writeOff = 0
c.size = 0
}
// Len tells you the current size of the buffer contents
func (c *ChunkBuffer) Len() int {
return int(c.size - c.readOff)
}
func (c *ChunkBuffer) Read(p []byte) (int, error) {
n := copy(p, c.buf[c.readOff:c.size])
c.readOff += int64(n)
if n < len(p) {
return n, io.EOF
}
return n, nil
}
// Seek implements io.Seeker
func (c *ChunkBuffer) Seek(offset int64, whence int) (int64, error) {
switch whence {
case io.SeekCurrent:
c.readOff += offset
case io.SeekEnd:
c.readOff = c.size + offset
case io.SeekStart:
c.readOff = offset
}
c.readOff = util.Min64(c.readOff, c.size)
c.writeOff = c.readOff
return c.readOff, nil
}
// Close is a no-op only existing to fulfill io.Closer
func (c *ChunkBuffer) Close() error {
return nil
}
// WriteTo implements the io.WriterTo interface
func (c *ChunkBuffer) WriteTo(w io.Writer) (int64, error) {
n, err := w.Write(c.buf[c.readOff:])
if err != nil {
return 0, err
}
c.readOff += int64(n)
return int64(n), nil
}
// NewChunkBuffer returns a ChunkBuffer with the given data. if data is nil a
// ChunkBuffer with 64k is returned.
// Note that chunkbuf will take over ownership over the buf.
func NewChunkBuffer(data []byte) *ChunkBuffer {
if data == nil {
data = make([]byte, maxChunkSize)
}
return &ChunkBuffer{buf: data, size: int64(len(data))}
}