@@ -182,8 +182,15 @@ func (d *Decoder) readUint64() uint64 {
182
182
//
183
183
// Most of the values of that initial byte can be devoted to small unsigned
184
184
// integers. For example, the number 17 is represented by the single byte 17.
185
- // Only five byte values have special meaning.
185
+ // Only a few byte values have special meaning.
186
186
//
187
+ // The nil code indicates that the value is nil. We don't absolutely need this:
188
+ // we could always represent the nil value for a type as something that couldn't
189
+ // be mistaken for an encoded value of that type. For instance, we could use 0
190
+ // for nil in the case of slices (which always begin with the nValues code), and
191
+ // for pointers to numbers like *int, we could use something like "nBytes 0".
192
+ // But it is simpler to have a reserved value for nil.
193
+
187
194
// The nBytes code indicates that an unsigned integer N is encoded next,
188
195
// followed by N bytes of data. This is used to represent strings and byte
189
196
// slices, as well numbers bigger than can fit into the initial byte. For
@@ -207,11 +214,20 @@ func (d *Decoder) readUint64() uint64 {
207
214
// The start and end codes delimit a value whose length is unknown beforehand.
208
215
// It is used for structs.
209
216
const (
210
- nBytesCode = 255 - iota // uint n follows, then n bytes
211
- nValuesCode // uint n follows, then n values
212
- refCode // uint n follows, referring to a previous value
213
- startCode // start of a value of indeterminate length
214
- endCode // end of a value that began with with start
217
+ nilCode = 255 - iota // a nil value
218
+ // reserve a few values for future use
219
+ reserved1
220
+ reserved2
221
+ reserved3
222
+ reserved4
223
+ reserved5
224
+ reserved6
225
+ reserved7
226
+ nBytesCode // uint n follows, then n bytes
227
+ nValuesCode // uint n follows, then n values
228
+ refCode // uint n follows, referring to a previous value
229
+ startCode // start of a value of indeterminate length
230
+ endCode // end of a value that began with start
215
231
// Bytes less than endCode represent themselves.
216
232
)
217
233
@@ -349,6 +365,10 @@ func (d *Decoder) DecodeFloat() float64 {
349
365
return math .Float64frombits (d .DecodeUint ())
350
366
}
351
367
368
+ func (e * Encoder ) EncodeNil () {
369
+ e .writeByte (nilCode )
370
+ }
371
+
352
372
// StartList should be called before encoding any sequence of variable-length
353
373
// values.
354
374
func (e * Encoder ) StartList (len int ) {
@@ -360,15 +380,15 @@ func (e *Encoder) StartList(len int) {
360
380
// values. It returns -1 if the encoded list was nil. Otherwise, it returns the
361
381
// length of the sequence.
362
382
func (d * Decoder ) StartList () int {
363
- b := d .readByte ()
364
- if b == 0 { // used for nil
383
+ switch b := d .readByte (); b {
384
+ case nilCode :
365
385
return - 1
366
- }
367
- if b != nValuesCode {
386
+ case nValuesCode :
387
+ return int (d .DecodeUint ())
388
+ default :
368
389
d .badcode (b )
369
390
return 0
370
391
}
371
- return int (d .DecodeUint ())
372
392
}
373
393
374
394
//////////////// Struct Support
@@ -378,7 +398,7 @@ func (d *Decoder) StartList() int {
378
398
// pointer. If StartStruct returns false, encoding should not proceed.
379
399
func (e * Encoder ) StartStruct (isNil bool , p interface {}) bool {
380
400
if isNil {
381
- e .EncodeUint ( 0 )
401
+ e .EncodeNil ( )
382
402
return false
383
403
}
384
404
if u , ok := e .seen [p ]; ok {
@@ -402,7 +422,7 @@ func (e *Encoder) StartStruct(isNil bool, p interface{}) bool {
402
422
func (d * Decoder ) StartStruct () (bool , interface {}) {
403
423
b := d .readByte ()
404
424
switch b {
405
- case 0 : // nil; do not set the pointer
425
+ case nilCode : // do not set the pointer
406
426
return false , nil
407
427
case refCode :
408
428
u := d .DecodeUint ()
@@ -451,6 +471,8 @@ func (d *Decoder) skip() {
451
471
return
452
472
}
453
473
switch b {
474
+ case nilCode :
475
+ // Nothing follows.
454
476
case nBytesCode :
455
477
// A uint n and n bytes follow. It is efficient to call readBytes here
456
478
// because it does no allocation.
0 commit comments