@@ -49,7 +49,7 @@ type MarshalSizer interface {
4949type 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.
6767func 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.
11190func (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.
133116func (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.
146130func (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.
158141func (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
169152func (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
181164func (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
193176func (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
205188func (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.
218201func (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.
233216func (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.
249238func (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.
357348func (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.
363354func (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.
366360func (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.
432426func (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
445439func (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.
501495func (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
0 commit comments