blob: 7633c04ac3ece57ed4faad7218b19056084977a1 [file] [log] [blame]
khenaidooffe076b2019-01-15 16:08:08 -05001// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
2// Use of this source code is governed by a MIT license found in the LICENSE file.
3
4package codec
5
6import (
7 "math"
8 "reflect"
9 "time"
10)
11
12const (
13 cborMajorUint byte = iota
14 cborMajorNegInt
15 cborMajorBytes
16 cborMajorText
17 cborMajorArray
18 cborMajorMap
19 cborMajorTag
20 cborMajorOther
21)
22
23const (
24 cborBdFalse byte = 0xf4 + iota
25 cborBdTrue
26 cborBdNil
27 cborBdUndefined
28 cborBdExt
29 cborBdFloat16
30 cborBdFloat32
31 cborBdFloat64
32)
33
34const (
35 cborBdIndefiniteBytes byte = 0x5f
36 cborBdIndefiniteString = 0x7f
37 cborBdIndefiniteArray = 0x9f
38 cborBdIndefiniteMap = 0xbf
39 cborBdBreak = 0xff
40)
41
42// These define some in-stream descriptors for
43// manual encoding e.g. when doing explicit indefinite-length
44const (
45 CborStreamBytes byte = 0x5f
46 CborStreamString = 0x7f
47 CborStreamArray = 0x9f
48 CborStreamMap = 0xbf
49 CborStreamBreak = 0xff
50)
51
52const (
53 cborBaseUint byte = 0x00
54 cborBaseNegInt = 0x20
55 cborBaseBytes = 0x40
56 cborBaseString = 0x60
57 cborBaseArray = 0x80
58 cborBaseMap = 0xa0
59 cborBaseTag = 0xc0
60 cborBaseSimple = 0xe0
61)
62
63func cbordesc(bd byte) string {
64 switch bd {
65 case cborBdNil:
66 return "nil"
67 case cborBdFalse:
68 return "false"
69 case cborBdTrue:
70 return "true"
71 case cborBdFloat16, cborBdFloat32, cborBdFloat64:
72 return "float"
73 case cborBdIndefiniteBytes:
74 return "bytes*"
75 case cborBdIndefiniteString:
76 return "string*"
77 case cborBdIndefiniteArray:
78 return "array*"
79 case cborBdIndefiniteMap:
80 return "map*"
81 default:
82 switch {
83 case bd >= cborBaseUint && bd < cborBaseNegInt:
84 return "(u)int"
85 case bd >= cborBaseNegInt && bd < cborBaseBytes:
86 return "int"
87 case bd >= cborBaseBytes && bd < cborBaseString:
88 return "bytes"
89 case bd >= cborBaseString && bd < cborBaseArray:
90 return "string"
91 case bd >= cborBaseArray && bd < cborBaseMap:
92 return "array"
93 case bd >= cborBaseMap && bd < cborBaseTag:
94 return "map"
95 case bd >= cborBaseTag && bd < cborBaseSimple:
96 return "ext"
97 default:
98 return "unknown"
99 }
100 }
101}
102
103// -------------------
104
105type cborEncDriver struct {
106 noBuiltInTypes
107 encDriverNoopContainerWriter
108 // encNoSeparator
109 e *Encoder
110 w encWriter
111 h *CborHandle
112 x [8]byte
113 _ [3]uint64 // padding
114}
115
116func (e *cborEncDriver) EncodeNil() {
117 e.w.writen1(cborBdNil)
118}
119
120func (e *cborEncDriver) EncodeBool(b bool) {
121 if b {
122 e.w.writen1(cborBdTrue)
123 } else {
124 e.w.writen1(cborBdFalse)
125 }
126}
127
128func (e *cborEncDriver) EncodeFloat32(f float32) {
129 e.w.writen1(cborBdFloat32)
130 bigenHelper{e.x[:4], e.w}.writeUint32(math.Float32bits(f))
131}
132
133func (e *cborEncDriver) EncodeFloat64(f float64) {
134 e.w.writen1(cborBdFloat64)
135 bigenHelper{e.x[:8], e.w}.writeUint64(math.Float64bits(f))
136}
137
138func (e *cborEncDriver) encUint(v uint64, bd byte) {
139 if v <= 0x17 {
140 e.w.writen1(byte(v) + bd)
141 } else if v <= math.MaxUint8 {
142 e.w.writen2(bd+0x18, uint8(v))
143 } else if v <= math.MaxUint16 {
144 e.w.writen1(bd + 0x19)
145 bigenHelper{e.x[:2], e.w}.writeUint16(uint16(v))
146 } else if v <= math.MaxUint32 {
147 e.w.writen1(bd + 0x1a)
148 bigenHelper{e.x[:4], e.w}.writeUint32(uint32(v))
149 } else { // if v <= math.MaxUint64 {
150 e.w.writen1(bd + 0x1b)
151 bigenHelper{e.x[:8], e.w}.writeUint64(v)
152 }
153}
154
155func (e *cborEncDriver) EncodeInt(v int64) {
156 if v < 0 {
157 e.encUint(uint64(-1-v), cborBaseNegInt)
158 } else {
159 e.encUint(uint64(v), cborBaseUint)
160 }
161}
162
163func (e *cborEncDriver) EncodeUint(v uint64) {
164 e.encUint(v, cborBaseUint)
165}
166
167func (e *cborEncDriver) encLen(bd byte, length int) {
168 e.encUint(uint64(length), bd)
169}
170
171func (e *cborEncDriver) EncodeTime(t time.Time) {
172 if t.IsZero() {
173 e.EncodeNil()
174 } else if e.h.TimeRFC3339 {
175 e.encUint(0, cborBaseTag)
176 e.EncodeString(cUTF8, t.Format(time.RFC3339Nano))
177 } else {
178 e.encUint(1, cborBaseTag)
179 t = t.UTC().Round(time.Microsecond)
180 sec, nsec := t.Unix(), uint64(t.Nanosecond())
181 if nsec == 0 {
182 e.EncodeInt(sec)
183 } else {
184 e.EncodeFloat64(float64(sec) + float64(nsec)/1e9)
185 }
186 }
187}
188
189func (e *cborEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Encoder) {
190 e.encUint(uint64(xtag), cborBaseTag)
191 if v := ext.ConvertExt(rv); v == nil {
192 e.EncodeNil()
193 } else {
194 en.encode(v)
195 }
196}
197
198func (e *cborEncDriver) EncodeRawExt(re *RawExt, en *Encoder) {
199 e.encUint(uint64(re.Tag), cborBaseTag)
200 if false && re.Data != nil {
201 en.encode(re.Data)
202 } else if re.Value != nil {
203 en.encode(re.Value)
204 } else {
205 e.EncodeNil()
206 }
207}
208
209func (e *cborEncDriver) WriteArrayStart(length int) {
210 if e.h.IndefiniteLength {
211 e.w.writen1(cborBdIndefiniteArray)
212 } else {
213 e.encLen(cborBaseArray, length)
214 }
215}
216
217func (e *cborEncDriver) WriteMapStart(length int) {
218 if e.h.IndefiniteLength {
219 e.w.writen1(cborBdIndefiniteMap)
220 } else {
221 e.encLen(cborBaseMap, length)
222 }
223}
224
225func (e *cborEncDriver) WriteMapEnd() {
226 if e.h.IndefiniteLength {
227 e.w.writen1(cborBdBreak)
228 }
229}
230
231func (e *cborEncDriver) WriteArrayEnd() {
232 if e.h.IndefiniteLength {
233 e.w.writen1(cborBdBreak)
234 }
235}
236
237func (e *cborEncDriver) EncodeString(c charEncoding, v string) {
238 e.encStringBytesS(cborBaseString, v)
239}
240
241func (e *cborEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
242 if v == nil {
243 e.EncodeNil()
244 } else if c == cRAW {
245 e.encStringBytesS(cborBaseBytes, stringView(v))
246 } else {
247 e.encStringBytesS(cborBaseString, stringView(v))
248 }
249}
250
251func (e *cborEncDriver) encStringBytesS(bb byte, v string) {
252 if e.h.IndefiniteLength {
253 if bb == cborBaseBytes {
254 e.w.writen1(cborBdIndefiniteBytes)
255 } else {
256 e.w.writen1(cborBdIndefiniteString)
257 }
258 blen := len(v) / 4
259 if blen == 0 {
260 blen = 64
261 } else if blen > 1024 {
262 blen = 1024
263 }
264 for i := 0; i < len(v); {
265 var v2 string
266 i2 := i + blen
267 if i2 < len(v) {
268 v2 = v[i:i2]
269 } else {
270 v2 = v[i:]
271 }
272 e.encLen(bb, len(v2))
273 e.w.writestr(v2)
274 i = i2
275 }
276 e.w.writen1(cborBdBreak)
277 } else {
278 e.encLen(bb, len(v))
279 e.w.writestr(v)
280 }
281}
282
283// ----------------------
284
285type cborDecDriver struct {
286 d *Decoder
287 h *CborHandle
288 r decReader
289 // b [scratchByteArrayLen]byte
290 br bool // bytes reader
291 bdRead bool
292 bd byte
293 noBuiltInTypes
294 // decNoSeparator
295 decDriverNoopContainerReader
296 _ [3]uint64 // padding
297}
298
299func (d *cborDecDriver) readNextBd() {
300 d.bd = d.r.readn1()
301 d.bdRead = true
302}
303
304func (d *cborDecDriver) uncacheRead() {
305 if d.bdRead {
306 d.r.unreadn1()
307 d.bdRead = false
308 }
309}
310
311func (d *cborDecDriver) ContainerType() (vt valueType) {
312 if !d.bdRead {
313 d.readNextBd()
314 }
315 if d.bd == cborBdNil {
316 return valueTypeNil
317 } else if d.bd == cborBdIndefiniteBytes || (d.bd >= cborBaseBytes && d.bd < cborBaseString) {
318 return valueTypeBytes
319 } else if d.bd == cborBdIndefiniteString || (d.bd >= cborBaseString && d.bd < cborBaseArray) {
320 return valueTypeString
321 } else if d.bd == cborBdIndefiniteArray || (d.bd >= cborBaseArray && d.bd < cborBaseMap) {
322 return valueTypeArray
323 } else if d.bd == cborBdIndefiniteMap || (d.bd >= cborBaseMap && d.bd < cborBaseTag) {
324 return valueTypeMap
325 }
326 // else {
327 // d.d.errorf("isContainerType: unsupported parameter: %v", vt)
328 // }
329 return valueTypeUnset
330}
331
332func (d *cborDecDriver) TryDecodeAsNil() bool {
333 if !d.bdRead {
334 d.readNextBd()
335 }
336 // treat Nil and Undefined as nil values
337 if d.bd == cborBdNil || d.bd == cborBdUndefined {
338 d.bdRead = false
339 return true
340 }
341 return false
342}
343
344func (d *cborDecDriver) CheckBreak() bool {
345 if !d.bdRead {
346 d.readNextBd()
347 }
348 if d.bd == cborBdBreak {
349 d.bdRead = false
350 return true
351 }
352 return false
353}
354
355func (d *cborDecDriver) decUint() (ui uint64) {
356 v := d.bd & 0x1f
357 if v <= 0x17 {
358 ui = uint64(v)
359 } else {
360 if v == 0x18 {
361 ui = uint64(d.r.readn1())
362 } else if v == 0x19 {
363 ui = uint64(bigen.Uint16(d.r.readx(2)))
364 } else if v == 0x1a {
365 ui = uint64(bigen.Uint32(d.r.readx(4)))
366 } else if v == 0x1b {
367 ui = uint64(bigen.Uint64(d.r.readx(8)))
368 } else {
369 d.d.errorf("invalid descriptor decoding uint: %x/%s", d.bd, cbordesc(d.bd))
370 return
371 }
372 }
373 return
374}
375
376func (d *cborDecDriver) decCheckInteger() (neg bool) {
377 if !d.bdRead {
378 d.readNextBd()
379 }
380 major := d.bd >> 5
381 if major == cborMajorUint {
382 } else if major == cborMajorNegInt {
383 neg = true
384 } else {
385 d.d.errorf("not an integer - invalid major %v from descriptor %x/%s", major, d.bd, cbordesc(d.bd))
386 return
387 }
388 return
389}
390
391func (d *cborDecDriver) DecodeInt64() (i int64) {
392 neg := d.decCheckInteger()
393 ui := d.decUint()
394 // check if this number can be converted to an int without overflow
395 if neg {
396 i = -(chkOvf.SignedIntV(ui + 1))
397 } else {
398 i = chkOvf.SignedIntV(ui)
399 }
400 d.bdRead = false
401 return
402}
403
404func (d *cborDecDriver) DecodeUint64() (ui uint64) {
405 if d.decCheckInteger() {
406 d.d.errorf("assigning negative signed value to unsigned type")
407 return
408 }
409 ui = d.decUint()
410 d.bdRead = false
411 return
412}
413
414func (d *cborDecDriver) DecodeFloat64() (f float64) {
415 if !d.bdRead {
416 d.readNextBd()
417 }
418 if bd := d.bd; bd == cborBdFloat16 {
419 f = float64(math.Float32frombits(halfFloatToFloatBits(bigen.Uint16(d.r.readx(2)))))
420 } else if bd == cborBdFloat32 {
421 f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4))))
422 } else if bd == cborBdFloat64 {
423 f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
424 } else if bd >= cborBaseUint && bd < cborBaseBytes {
425 f = float64(d.DecodeInt64())
426 } else {
427 d.d.errorf("float only valid from float16/32/64 - invalid descriptor %x/%s", bd, cbordesc(bd))
428 return
429 }
430 d.bdRead = false
431 return
432}
433
434// bool can be decoded from bool only (single byte).
435func (d *cborDecDriver) DecodeBool() (b bool) {
436 if !d.bdRead {
437 d.readNextBd()
438 }
439 if bd := d.bd; bd == cborBdTrue {
440 b = true
441 } else if bd == cborBdFalse {
442 } else {
443 d.d.errorf("not bool - %s %x/%s", msgBadDesc, d.bd, cbordesc(d.bd))
444 return
445 }
446 d.bdRead = false
447 return
448}
449
450func (d *cborDecDriver) ReadMapStart() (length int) {
451 if !d.bdRead {
452 d.readNextBd()
453 }
454 d.bdRead = false
455 if d.bd == cborBdIndefiniteMap {
456 return -1
457 }
458 return d.decLen()
459}
460
461func (d *cborDecDriver) ReadArrayStart() (length int) {
462 if !d.bdRead {
463 d.readNextBd()
464 }
465 d.bdRead = false
466 if d.bd == cborBdIndefiniteArray {
467 return -1
468 }
469 return d.decLen()
470}
471
472func (d *cborDecDriver) decLen() int {
473 return int(d.decUint())
474}
475
476func (d *cborDecDriver) decAppendIndefiniteBytes(bs []byte) []byte {
477 d.bdRead = false
478 for {
479 if d.CheckBreak() {
480 break
481 }
482 if major := d.bd >> 5; major != cborMajorBytes && major != cborMajorText {
483 d.d.errorf("expect bytes/string major type in indefinite string/bytes;"+
484 " got major %v from descriptor %x/%x", major, d.bd, cbordesc(d.bd))
485 return nil
486 }
487 n := d.decLen()
488 oldLen := len(bs)
489 newLen := oldLen + n
490 if newLen > cap(bs) {
491 bs2 := make([]byte, newLen, 2*cap(bs)+n)
492 copy(bs2, bs)
493 bs = bs2
494 } else {
495 bs = bs[:newLen]
496 }
497 d.r.readb(bs[oldLen:newLen])
498 // bs = append(bs, d.r.readn()...)
499 d.bdRead = false
500 }
501 d.bdRead = false
502 return bs
503}
504
505func (d *cborDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
506 if !d.bdRead {
507 d.readNextBd()
508 }
509 if d.bd == cborBdNil || d.bd == cborBdUndefined {
510 d.bdRead = false
511 return nil
512 }
513 if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString {
514 d.bdRead = false
515 if bs == nil {
516 if zerocopy {
517 return d.decAppendIndefiniteBytes(d.d.b[:0])
518 }
519 return d.decAppendIndefiniteBytes(zeroByteSlice)
520 }
521 return d.decAppendIndefiniteBytes(bs[:0])
522 }
523 // check if an "array" of uint8's (see ContainerType for how to infer if an array)
524 if d.bd == cborBdIndefiniteArray || (d.bd >= cborBaseArray && d.bd < cborBaseMap) {
525 bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
526 return
527 }
528 clen := d.decLen()
529 d.bdRead = false
530 if zerocopy {
531 if d.br {
532 return d.r.readx(clen)
533 } else if len(bs) == 0 {
534 bs = d.d.b[:]
535 }
536 }
537 return decByteSlice(d.r, clen, d.h.MaxInitLen, bs)
538}
539
540func (d *cborDecDriver) DecodeString() (s string) {
541 return string(d.DecodeBytes(d.d.b[:], true))
542}
543
544func (d *cborDecDriver) DecodeStringAsBytes() (s []byte) {
545 return d.DecodeBytes(d.d.b[:], true)
546}
547
548func (d *cborDecDriver) DecodeTime() (t time.Time) {
549 if !d.bdRead {
550 d.readNextBd()
551 }
552 if d.bd == cborBdNil || d.bd == cborBdUndefined {
553 d.bdRead = false
554 return
555 }
556 xtag := d.decUint()
557 d.bdRead = false
558 return d.decodeTime(xtag)
559}
560
561func (d *cborDecDriver) decodeTime(xtag uint64) (t time.Time) {
562 if !d.bdRead {
563 d.readNextBd()
564 }
565 switch xtag {
566 case 0:
567 var err error
568 if t, err = time.Parse(time.RFC3339, stringView(d.DecodeStringAsBytes())); err != nil {
569 d.d.errorv(err)
570 }
571 case 1:
572 // decode an int64 or a float, and infer time.Time from there.
573 // for floats, round to microseconds, as that is what is guaranteed to fit well.
574 switch {
575 case d.bd == cborBdFloat16, d.bd == cborBdFloat32:
576 f1, f2 := math.Modf(d.DecodeFloat64())
577 t = time.Unix(int64(f1), int64(f2*1e9))
578 case d.bd == cborBdFloat64:
579 f1, f2 := math.Modf(d.DecodeFloat64())
580 t = time.Unix(int64(f1), int64(f2*1e9))
581 case d.bd >= cborBaseUint && d.bd < cborBaseNegInt,
582 d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
583 t = time.Unix(d.DecodeInt64(), 0)
584 default:
585 d.d.errorf("time.Time can only be decoded from a number (or RFC3339 string)")
586 }
587 default:
588 d.d.errorf("invalid tag for time.Time - expecting 0 or 1, got 0x%x", xtag)
589 }
590 t = t.UTC().Round(time.Microsecond)
591 return
592}
593
594func (d *cborDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
595 if !d.bdRead {
596 d.readNextBd()
597 }
598 u := d.decUint()
599 d.bdRead = false
600 realxtag = u
601 if ext == nil {
602 re := rv.(*RawExt)
603 re.Tag = realxtag
604 d.d.decode(&re.Value)
605 } else if xtag != realxtag {
606 d.d.errorf("Wrong extension tag. Got %b. Expecting: %v", realxtag, xtag)
607 return
608 } else {
609 var v interface{}
610 d.d.decode(&v)
611 ext.UpdateExt(rv, v)
612 }
613 d.bdRead = false
614 return
615}
616
617func (d *cborDecDriver) DecodeNaked() {
618 if !d.bdRead {
619 d.readNextBd()
620 }
621
622 n := d.d.n
623 var decodeFurther bool
624
625 switch d.bd {
626 case cborBdNil:
627 n.v = valueTypeNil
628 case cborBdFalse:
629 n.v = valueTypeBool
630 n.b = false
631 case cborBdTrue:
632 n.v = valueTypeBool
633 n.b = true
634 case cborBdFloat16, cborBdFloat32, cborBdFloat64:
635 n.v = valueTypeFloat
636 n.f = d.DecodeFloat64()
637 case cborBdIndefiniteBytes:
638 n.v = valueTypeBytes
639 n.l = d.DecodeBytes(nil, false)
640 case cborBdIndefiniteString:
641 n.v = valueTypeString
642 n.s = d.DecodeString()
643 case cborBdIndefiniteArray:
644 n.v = valueTypeArray
645 decodeFurther = true
646 case cborBdIndefiniteMap:
647 n.v = valueTypeMap
648 decodeFurther = true
649 default:
650 switch {
651 case d.bd >= cborBaseUint && d.bd < cborBaseNegInt:
652 if d.h.SignedInteger {
653 n.v = valueTypeInt
654 n.i = d.DecodeInt64()
655 } else {
656 n.v = valueTypeUint
657 n.u = d.DecodeUint64()
658 }
659 case d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
660 n.v = valueTypeInt
661 n.i = d.DecodeInt64()
662 case d.bd >= cborBaseBytes && d.bd < cborBaseString:
663 n.v = valueTypeBytes
664 n.l = d.DecodeBytes(nil, false)
665 case d.bd >= cborBaseString && d.bd < cborBaseArray:
666 n.v = valueTypeString
667 n.s = d.DecodeString()
668 case d.bd >= cborBaseArray && d.bd < cborBaseMap:
669 n.v = valueTypeArray
670 decodeFurther = true
671 case d.bd >= cborBaseMap && d.bd < cborBaseTag:
672 n.v = valueTypeMap
673 decodeFurther = true
674 case d.bd >= cborBaseTag && d.bd < cborBaseSimple:
675 n.v = valueTypeExt
676 n.u = d.decUint()
677 n.l = nil
678 if n.u == 0 || n.u == 1 {
679 d.bdRead = false
680 n.v = valueTypeTime
681 n.t = d.decodeTime(n.u)
682 }
683 // d.bdRead = false
684 // d.d.decode(&re.Value) // handled by decode itself.
685 // decodeFurther = true
686 default:
687 d.d.errorf("decodeNaked: Unrecognized d.bd: 0x%x", d.bd)
688 return
689 }
690 }
691
692 if !decodeFurther {
693 d.bdRead = false
694 }
695 return
696}
697
698// -------------------------
699
700// CborHandle is a Handle for the CBOR encoding format,
701// defined at http://tools.ietf.org/html/rfc7049 and documented further at http://cbor.io .
702//
703// CBOR is comprehensively supported, including support for:
704// - indefinite-length arrays/maps/bytes/strings
705// - (extension) tags in range 0..0xffff (0 .. 65535)
706// - half, single and double-precision floats
707// - all numbers (1, 2, 4 and 8-byte signed and unsigned integers)
708// - nil, true, false, ...
709// - arrays and maps, bytes and text strings
710//
711// None of the optional extensions (with tags) defined in the spec are supported out-of-the-box.
712// Users can implement them as needed (using SetExt), including spec-documented ones:
713// - timestamp, BigNum, BigFloat, Decimals,
714// - Encoded Text (e.g. URL, regexp, base64, MIME Message), etc.
715type CborHandle struct {
716 binaryEncodingType
717 noElemSeparators
718 BasicHandle
719
720 // IndefiniteLength=true, means that we encode using indefinitelength
721 IndefiniteLength bool
722
723 // TimeRFC3339 says to encode time.Time using RFC3339 format.
724 // If unset, we encode time.Time using seconds past epoch.
725 TimeRFC3339 bool
726
727 // _ [1]uint64 // padding
728}
729
730// Name returns the name of the handle: cbor
731func (h *CborHandle) Name() string { return "cbor" }
732
733// SetInterfaceExt sets an extension
734func (h *CborHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
735 return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
736}
737
738func (h *CborHandle) newEncDriver(e *Encoder) encDriver {
739 return &cborEncDriver{e: e, w: e.w, h: h}
740}
741
742func (h *CborHandle) newDecDriver(d *Decoder) decDriver {
743 return &cborDecDriver{d: d, h: h, r: d.r, br: d.bytes}
744}
745
746func (e *cborEncDriver) reset() {
747 e.w = e.e.w
748}
749
750func (d *cborDecDriver) reset() {
751 d.r, d.br = d.d.r, d.d.bytes
752 d.bd, d.bdRead = 0, false
753}
754
755var _ decDriver = (*cborDecDriver)(nil)
756var _ encDriver = (*cborEncDriver)(nil)