Skip to content
This repository was archived by the owner on May 8, 2019. It is now read-only.

Commit eb97c00

Browse files
committed
improved func WriteUint8 and renamed Writer.Buffered to Writer.OpenSpace
1 parent fb136ed commit eb97c00

File tree

4 files changed

+145
-93
lines changed

4 files changed

+145
-93
lines changed

msgp/extension.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ func (mw *Writer) WriteExtension(e Extension) error {
183183
}
184184
// We can only write directly to the buffer if we're sure that it
185185
// fits the object.
186-
if l <= mw.bufsize() {
186+
if l <= len(mw.buf) {
187187
o, err := mw.require(l)
188188
if err != nil {
189189
return err
@@ -202,7 +202,7 @@ func (mw *Writer) WriteExtension(e Extension) error {
202202
return err
203203
}
204204
mw.buf = buf
205-
mw.wloc = l
205+
mw.wLoc = l
206206
return nil
207207
}
208208

msgp/write.go

Lines changed: 77 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ type MarshalSizer interface {
4949
type Writer struct {
5050
w io.Writer
5151
buf []byte
52-
wloc int
52+
wLoc int // The index at which to write.
5353
}
5454

5555
// NewWriter creates a new Writer.
@@ -66,7 +66,7 @@ func NewWriter(w io.Writer) *Writer {
6666
// NewWriterSize creates a Writer with a custom buffer size.
6767
func NewWriterSize(w io.Writer, sz int) *Writer {
6868
// We must be able to require() 18 contiguous bytes for WriteComplex128,
69-
// so that is the practical minimum buffer size.
69+
// so that is the practical minimal buffer size.
7070
if sz < 18 {
7171
sz = 18
7272
}
@@ -86,170 +86,159 @@ func Encode(w io.Writer, e Encoder) error {
8686
return err
8787
}
8888

89-
// Require ensures that cap(old)-len(old) >= extra.
90-
func Require(old []byte, extra int) []byte {
91-
l := len(old)
92-
c := cap(old)
93-
r := l + extra
94-
if c >= r {
95-
return old
96-
} else if l == 0 {
97-
return make([]byte, 0, extra)
98-
}
99-
// The new size is the greater of double the old capacity and
100-
// the sum of the old length and the number of new bytes needed.
101-
c <<= 1
102-
if c < r {
103-
c = r
104-
}
105-
n := make([]byte, l, c)
106-
copy(n, old)
107-
return n
108-
}
109-
11089
// Flush flushes all of the buffered data to the underlying writer.
11190
func (mw *Writer) Flush() error {
112-
if mw.wloc == 0 {
91+
if mw.wLoc == 0 {
11392
return nil
11493
}
115-
n, err := mw.w.Write(mw.buf[:mw.wloc])
94+
n, err := mw.w.Write(mw.buf[:mw.wLoc])
11695
if err != nil {
11796
if n > 0 {
118-
mw.wloc = copy(mw.buf, mw.buf[n:mw.wloc])
97+
mw.wLoc = copy(mw.buf, mw.buf[n:mw.wLoc])
11998
}
12099
return err
121100
}
122-
mw.wloc = 0
101+
if n < mw.wLoc {
102+
return io.ErrShortWrite
103+
}
104+
mw.wLoc = 0
123105
return nil
124106
}
125107

126-
// Buffered returns the number bytes in the write buffer.
127-
func (mw *Writer) Buffered() int { return len(mw.buf) - mw.wloc }
128-
129-
func (mw *Writer) bufsize() int { return len(mw.buf) }
108+
// OpenSpace returns the number of bytes currently free for writing to the write buffer.
109+
func (mw *Writer) OpenSpace() int { return len(mw.buf) - mw.wLoc }
130110

131-
// NOTE: require should only be called with a number that is guaranteed to be
132-
// less than len(mw.buf). Typically, it is called with a constant.
111+
// require ensures that, starting at the index returned as an int here, you can
112+
// immediately write n bytes to the buffer.
113+
//
114+
// Important: This function must only be called with a number that is guaranteed
115+
// to be less than len(mw.buf). Typically, it is called with a constant.
133116
func (mw *Writer) require(n int) (int, error) {
134-
wl := mw.wloc
135-
if len(mw.buf)-wl < n {
117+
wl := mw.wLoc
118+
if mw.OpenSpace() < n {
136119
if err := mw.Flush(); err != nil {
137120
return 0, err
138121
}
139-
wl = mw.wloc
122+
wl = mw.wLoc
140123
}
141-
mw.wloc += n
124+
mw.wLoc += n
142125
return wl, nil
143126
}
144127

145-
// Append appends to the buffer any number of single bytes.
128+
// Append can be used to append a few (no more than the total buffer length) single
129+
// bytes to the buffer.
146130
func (mw *Writer) Append(bts ...byte) error {
147-
if mw.Buffered() < len(bts) {
148-
err := mw.Flush()
149-
if err != nil {
131+
if mw.OpenSpace() < len(bts) {
132+
if err := mw.Flush(); err != nil {
150133
return err
151134
}
152135
}
153-
mw.wloc += copy(mw.buf[mw.wloc:], bts)
136+
mw.wLoc += copy(mw.buf[mw.wLoc:], bts)
154137
return nil
155138
}
156139

157140
// push pushes one byte onto the buffer.
158141
func (mw *Writer) push(b byte) error {
159-
if mw.wloc == len(mw.buf) {
142+
if mw.wLoc == len(mw.buf) {
160143
if err := mw.Flush(); err != nil {
161144
return err
162145
}
163146
}
164-
mw.buf[mw.wloc] = b
165-
mw.wloc++
147+
mw.buf[mw.wLoc] = b
148+
mw.wLoc++
166149
return nil
167150
}
168151

169152
func (mw *Writer) prefix8(b byte, u uint8) error {
170153
const need = 2
171-
if len(mw.buf)-mw.wloc < need {
154+
if mw.OpenSpace() < need {
172155
if err := mw.Flush(); err != nil {
173156
return err
174157
}
175158
}
176-
prefixu8(mw.buf[mw.wloc:], b, u)
177-
mw.wloc += need
159+
prefixu8(mw.buf[mw.wLoc:], b, u)
160+
mw.wLoc += need
178161
return nil
179162
}
180163

181164
func (mw *Writer) prefix16(b byte, u uint16) error {
182165
const need = 3
183-
if len(mw.buf)-mw.wloc < need {
166+
if mw.OpenSpace() < need {
184167
if err := mw.Flush(); err != nil {
185168
return err
186169
}
187170
}
188-
prefixu16(mw.buf[mw.wloc:], b, u)
189-
mw.wloc += need
171+
prefixu16(mw.buf[mw.wLoc:], b, u)
172+
mw.wLoc += need
190173
return nil
191174
}
192175

193176
func (mw *Writer) prefix32(b byte, u uint32) error {
194177
const need = 5
195-
if len(mw.buf)-mw.wloc < need {
178+
if mw.OpenSpace() < need {
196179
if err := mw.Flush(); err != nil {
197180
return err
198181
}
199182
}
200-
prefixu32(mw.buf[mw.wloc:], b, u)
201-
mw.wloc += need
183+
prefixu32(mw.buf[mw.wLoc:], b, u)
184+
mw.wLoc += need
202185
return nil
203186
}
204187

205188
func (mw *Writer) prefix64(b byte, u uint64) error {
206189
const need = 9
207-
if len(mw.buf)-mw.wloc < need {
190+
if mw.OpenSpace() < need {
208191
if err := mw.Flush(); err != nil {
209192
return err
210193
}
211194
}
212-
prefixu64(mw.buf[mw.wloc:], b, u)
213-
mw.wloc += need
195+
prefixu64(mw.buf[mw.wLoc:], b, u)
196+
mw.wLoc += need
214197
return nil
215198
}
216199

217200
// Write implements io.Writer to write directly to the buffer.
218201
func (mw *Writer) Write(p []byte) (int, error) {
219202
l := len(p)
220-
if mw.Buffered() < l {
203+
if mw.OpenSpace() < l {
221204
if err := mw.Flush(); err != nil {
222205
return 0, err
223206
}
224207
if l > len(mw.buf) {
225208
return mw.w.Write(p)
226209
}
227210
}
228-
mw.wloc += copy(mw.buf[mw.wloc:], p)
211+
mw.wLoc += copy(mw.buf[mw.wLoc:], p)
229212
return l, nil
230213
}
231214

232215
// writeString writes s to the buffer.
233216
func (mw *Writer) writeString(s string) error {
234217
l := len(s)
235-
if mw.Buffered() < l {
218+
if mw.OpenSpace() < l {
236219
if err := mw.Flush(); err != nil {
237220
return err
238221
}
239222
if l > len(mw.buf) {
240-
_, err := io.WriteString(mw.w, s)
241-
return err
223+
n, err := io.WriteString(mw.w, s)
224+
if err != nil {
225+
return err
226+
}
227+
if n < l {
228+
return io.ErrShortWrite
229+
}
230+
return nil
242231
}
243232
}
244-
mw.wloc += copy(mw.buf[mw.wloc:], s)
233+
mw.wLoc += copy(mw.buf[mw.wLoc:], s)
245234
return nil
246235
}
247236

248237
// Reset resets the underlying buffer used by the Writer.
249238
func (mw *Writer) Reset(w io.Writer) {
250239
mw.buf = mw.buf[:cap(mw.buf)]
251240
mw.w = w
252-
mw.wloc = 0
241+
mw.wLoc = 0
253242
}
254243

255244
// WriteMapHeader writes a map header of the given size to the buffer.
@@ -347,11 +336,13 @@ func (mw *Writer) WriteUint64(u uint64) error {
347336
}
348337
}
349338

350-
// WriteByte is analogous to WriteUint8.
351-
func (mw *Writer) WriteByte(u byte) error { return mw.WriteUint8(uint8(u)) }
352-
353339
// WriteUint8 writes a uint8 to the writer.
354-
func (mw *Writer) WriteUint8(u uint8) error { return mw.WriteUint64(uint64(u)) }
340+
func (mw *Writer) WriteUint8(u uint8) error {
341+
if u <= math.MaxInt8 {
342+
return mw.push(wfixint(u))
343+
}
344+
return mw.prefix8(muint8, u)
345+
}
355346

356347
// WriteUint16 writes a uint16 to the writer.
357348
func (mw *Writer) WriteUint16(u uint16) error { return mw.WriteUint64(uint64(u)) }
@@ -362,6 +353,9 @@ func (mw *Writer) WriteUint32(u uint32) error { return mw.WriteUint64(uint64(u))
362353
// WriteUint writes a uint to the writer.
363354
func (mw *Writer) WriteUint(u uint) error { return mw.WriteUint64(uint64(u)) }
364355

356+
// WriteByte does the same thing as WriteUint8.
357+
func (mw *Writer) WriteByte(u byte) error { return mw.WriteUint8(u) }
358+
365359
// WriteBool writes a bool to the writer.
366360
func (mw *Writer) WriteBool(b bool) error {
367361
if b {
@@ -430,27 +424,27 @@ func (mw *Writer) WriteStringFromBytes(str []byte) error {
430424

431425
// WriteComplex64 writes a complex64 to the writer.
432426
func (mw *Writer) WriteComplex64(f complex64) error {
433-
o, err := mw.require(10)
427+
i, err := mw.require(10)
434428
if err != nil {
435429
return err
436430
}
437-
mw.buf[o] = mfixext8
438-
mw.buf[o+1] = Complex64Extension
439-
big.PutUint32(mw.buf[o+2:], math.Float32bits(real(f)))
440-
big.PutUint32(mw.buf[o+6:], math.Float32bits(imag(f)))
431+
mw.buf[i] = mfixext8
432+
mw.buf[i+1] = Complex64Extension
433+
big.PutUint32(mw.buf[i+2:], math.Float32bits(real(f)))
434+
big.PutUint32(mw.buf[i+6:], math.Float32bits(imag(f)))
441435
return nil
442436
}
443437

444438
// WriteComplex128 writes a complex128 to the writer
445439
func (mw *Writer) WriteComplex128(f complex128) error {
446-
o, err := mw.require(18)
440+
i, err := mw.require(18)
447441
if err != nil {
448442
return err
449443
}
450-
mw.buf[o] = mfixext16
451-
mw.buf[o+1] = Complex128Extension
452-
big.PutUint64(mw.buf[o+2:], math.Float64bits(real(f)))
453-
big.PutUint64(mw.buf[o+10:], math.Float64bits(imag(f)))
444+
mw.buf[i] = mfixext16
445+
mw.buf[i+1] = Complex128Extension
446+
big.PutUint64(mw.buf[i+2:], math.Float64bits(real(f)))
447+
big.PutUint64(mw.buf[i+10:], math.Float64bits(imag(f)))
454448
return nil
455449
}
456450

@@ -500,14 +494,14 @@ func (mw *Writer) WriteMapStrIntf(mp map[string]interface{}) (err error) {
500494
// the nanosecond offset of the time. This encoding is intended to ease portability across languages.
501495
func (mw *Writer) WriteTime(t time.Time) error {
502496
t = t.UTC()
503-
o, err := mw.require(15)
497+
i, err := mw.require(15)
504498
if err != nil {
505499
return err
506500
}
507-
mw.buf[o] = mext8
508-
mw.buf[o+1] = 12
509-
mw.buf[o+2] = TimeExtension
510-
putUnix(mw.buf[o+3:], t.Unix(), int32(t.Nanosecond()))
501+
mw.buf[i] = mext8
502+
mw.buf[i+1] = 12
503+
mw.buf[i+2] = TimeExtension
504+
putUnix(mw.buf[i+3:], t.Unix(), int32(t.Nanosecond()))
511505
return nil
512506
}
513507

msgp/write_bytes.go

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,32 @@ import (
66
"time"
77
)
88

9-
// ensure returns a slice with the contents of b with the returned slice having
10-
// at lease sz extra bytes between its length and capacity.
9+
// Require returns a slice (with the contents of old) having a capacity to fit at
10+
// least extra number of bytes after the current length. The length of the returned
11+
// slice is the same as the length of the old slice.
12+
func Require(old []byte, extra int) []byte {
13+
l := len(old)
14+
c := cap(old)
15+
r := l + extra
16+
if c >= r {
17+
return old
18+
}
19+
// The new size is the greater of double the old capacity and
20+
// the sum of the old length and the number of new bytes needed.
21+
c <<= 1
22+
if c < r {
23+
c = r
24+
}
25+
n := make([]byte, l, c)
26+
copy(n, old)
27+
return n
28+
}
29+
30+
// ensure returns a slice (with the contents of b) having at least sz extra bytes between
31+
// its length and capacity. The int returned indicates the index at which to write.
1132
func ensure(b []byte, sz int) ([]byte, int) {
33+
b = Require(b, sz)
1234
l := len(b)
13-
c := cap(b)
14-
if c-l < sz {
15-
o := make([]byte, (2*c)+sz)
16-
n := copy(o, b)
17-
return o[:n+sz], n
18-
}
1935
return b[:l+sz], l
2036
}
2137

0 commit comments

Comments
 (0)