9
9
10
10
package mysql
11
11
12
- import (
13
- "io"
14
- )
12
+ import "io"
15
13
16
- const (
17
- defaultBufSize = 4096
18
- )
14
+ const defaultBufSize = 4096
19
15
20
16
type buffer struct {
21
17
buf []byte
@@ -38,6 +34,11 @@ func (b *buffer) fill(need int) (err error) {
38
34
copy (b .buf [0 :b .length ], b .buf [b .idx :])
39
35
}
40
36
37
+ // grow buffer if necessary
38
+ if need > len (b .buf ) {
39
+ b .grow (need )
40
+ }
41
+
41
42
b .idx = 0
42
43
43
44
var n int
@@ -54,48 +55,32 @@ func (b *buffer) fill(need int) (err error) {
54
55
return
55
56
}
56
57
57
- // returns next N bytes from buffer.
58
- // The returned slice is only guaranteed to be valid until the next read
59
- func (b * buffer ) readNext (need int ) (p []byte , err error ) {
60
- // return slice from buffer if possible
61
- if b .length >= need {
62
- p = b .buf [b .idx : b .idx + need ]
63
- b .idx += need
64
- b .length -= need
58
+ // credit for this code snippet goes to Maxim Khitrov
59
+ // https://groups.google.com/forum/#!topic/golang-nuts/ETbw1ECDgRs
60
+ func (b * buffer ) grow (size int ) {
61
+ if size > 2 * cap (b .buf ) {
62
+ newBuf := make ([]byte , size )
63
+ copy (newBuf , b .buf )
64
+ b .buf = newBuf
65
65
return
66
-
67
66
} else {
68
-
69
- // does the data fit into the buffer?
70
- if need < len (b .buf ) {
71
- // refill
72
- err = b .fill (need ) // err deferred
73
- p = b .buf [:need ]
74
- b .idx += need
75
- b .length -= need
76
- return
77
-
78
- } else {
79
- p = make ([]byte , need )
80
- has := 0
81
-
82
- // copy data that is already in the buffer
83
- if b .length > 0 {
84
- copy (p [0 :b .length ], b .buf [b .idx :])
85
- has = b .length
86
- need -= has
87
- b .idx = 0
88
- b .length = 0
89
- }
90
-
91
- // read rest directly into the new slice
92
- var n int
93
- for err == nil && need > 0 {
94
- n , err = b .rd .Read (p [has :])
95
- has += n
96
- need -= n
97
- }
67
+ for cap (b .buf ) < size {
68
+ b .buf = append (b .buf [:cap (b .buf )], 0 )
98
69
}
70
+ b .buf = b .buf [:cap (b .buf )]
71
+ }
72
+ }
73
+
74
+ // returns next N bytes from buffer.
75
+ // The returned slice is only guaranteed to be valid until the next read
76
+ func (b * buffer ) readNext (need int ) (p []byte , err error ) {
77
+ if b .length < need {
78
+ // refill
79
+ err = b .fill (need ) // err deferred
99
80
}
81
+
82
+ p = b .buf [b .idx : b .idx + need ]
83
+ b .idx += need
84
+ b .length -= need
100
85
return
101
86
}
0 commit comments