-
Notifications
You must be signed in to change notification settings - Fork 30
/
io.go
129 lines (114 loc) · 2.17 KB
/
io.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
119
120
121
122
123
124
125
126
127
128
129
package main
import (
"fmt"
"io"
"unsafe"
)
type BytesWriter struct {
buf []byte
pos int
}
func NewBytesWriter() *BytesWriter {
return &BytesWriter{
buf: []byte{},
}
}
func castInt64ToInt(n int64) (int, error) {
if unsafe.Sizeof(n) == unsafe.Sizeof(int(0)) {
return int(n), nil
} else {
_n := int(n)
if int64(_n) < n {
return -1, fmt.Errorf("integer overflow detected when converting %#v to int", n)
}
return _n, nil
}
}
func (bw *BytesWriter) Close() error {
return nil
}
// Resize the buffer capacity so the new size is at least the value of newCap.
func (bw *BytesWriter) grow(newCap int) {
if cap(bw.buf) >= newCap {
return
}
i := cap(bw.buf)
if i < 2 {
i = 2
}
for i < newCap {
i = i + i/2
if i < cap(bw.buf) {
panic("allocation failure")
}
}
newBuf := make([]byte, len(bw.buf), i)
copy(newBuf, bw.buf)
bw.buf = newBuf
}
func (bw *BytesWriter) Truncate(n int64) error {
_n, err := castInt64ToInt(n)
if err != nil {
return err
}
bw.buf = bw.buf[0:_n]
if bw.pos > _n {
bw.pos = _n
}
return nil
}
func (bw *BytesWriter) Seek(offset int64, whence int) (int64, error) {
_o, err := castInt64ToInt(offset)
if err != nil {
return -1, err
}
var newPos int
switch whence {
case 0:
newPos = _o
case 1:
newPos = bw.pos + _o
case 2:
newPos = len(bw.buf) + _o
}
if newPos < len(bw.buf) {
bw.grow(newPos)
bw.buf = bw.buf[0:newPos]
}
bw.pos = newPos
return int64(newPos), nil
}
func (bw *BytesWriter) Write(p []byte) (n int, err error) {
bw.grow(bw.pos + len(p))
copy(bw.buf[bw.pos:bw.pos+len(p)], p)
return len(p), nil
}
func (bw *BytesWriter) WriteAt(p []byte, offset int64) (n int, err error) {
_o, err := castInt64ToInt(offset)
if err != nil {
return -1, err
}
req := _o + len(p)
if req > len(bw.buf) {
bw.grow(req)
bw.buf = bw.buf[0:req]
}
copy(bw.buf[_o:req], p)
return len(p), nil
}
func (bw *BytesWriter) Size() int64 {
return int64(len(bw.buf))
}
func (bw *BytesWriter) Bytes() []byte {
return bw.buf
}
func IsEOF(e error) bool {
return e == io.EOF || e == io.ErrUnexpectedEOF
}
func IsTimeout(e error) bool {
t, ok := e.(interface{ Timeout() bool })
if ok {
return t.Timeout()
}
return false
}