github.com/patricebensoussan/go/codec@v1.2.99/cbor.go (about) 1 // Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved. 2 // Use of this source code is governed by a MIT license found in the LICENSE file. 3 4 package codec 5 6 import ( 7 "math" 8 "reflect" 9 "time" 10 ) 11 12 // major 13 const ( 14 cborMajorUint byte = iota 15 cborMajorNegInt 16 cborMajorBytes 17 cborMajorString 18 cborMajorArray 19 cborMajorMap 20 cborMajorTag 21 cborMajorSimpleOrFloat 22 ) 23 24 // simple 25 const ( 26 cborBdFalse byte = 0xf4 + iota 27 cborBdTrue 28 cborBdNil 29 cborBdUndefined 30 cborBdExt 31 cborBdFloat16 32 cborBdFloat32 33 cborBdFloat64 34 ) 35 36 // indefinite 37 const ( 38 cborBdIndefiniteBytes byte = 0x5f 39 cborBdIndefiniteString byte = 0x7f 40 cborBdIndefiniteArray byte = 0x9f 41 cborBdIndefiniteMap byte = 0xbf 42 cborBdBreak byte = 0xff 43 ) 44 45 // These define some in-stream descriptors for 46 // manual encoding e.g. when doing explicit indefinite-length 47 const ( 48 CborStreamBytes byte = 0x5f 49 CborStreamString byte = 0x7f 50 CborStreamArray byte = 0x9f 51 CborStreamMap byte = 0xbf 52 CborStreamBreak byte = 0xff 53 ) 54 55 // base values 56 const ( 57 cborBaseUint byte = 0x00 58 cborBaseNegInt byte = 0x20 59 cborBaseBytes byte = 0x40 60 cborBaseString byte = 0x60 61 cborBaseArray byte = 0x80 62 cborBaseMap byte = 0xa0 63 cborBaseTag byte = 0xc0 64 cborBaseSimple byte = 0xe0 65 ) 66 67 // const ( 68 // cborSelfDesrTag byte = 0xd9 69 // cborSelfDesrTag2 byte = 0xd9 70 // cborSelfDesrTag3 byte = 0xf7 71 // ) 72 73 var ( 74 cbordescSimpleNames = map[byte]string{ 75 cborBdNil: "nil", 76 cborBdFalse: "false", 77 cborBdTrue: "true", 78 cborBdFloat16: "float", 79 cborBdFloat32: "float", 80 cborBdFloat64: "float", 81 cborBdBreak: "break", 82 } 83 cbordescIndefNames = map[byte]string{ 84 cborBdIndefiniteBytes: "bytes*", 85 cborBdIndefiniteString: "string*", 86 cborBdIndefiniteArray: "array*", 87 cborBdIndefiniteMap: "map*", 88 } 89 cbordescMajorNames = map[byte]string{ 90 cborMajorUint: "(u)int", 91 cborMajorNegInt: "int", 92 cborMajorBytes: "bytes", 93 cborMajorString: "string", 94 cborMajorArray: "array", 95 cborMajorMap: "map", 96 cborMajorTag: "tag", 97 cborMajorSimpleOrFloat: "simple", 98 } 99 ) 100 101 func cbordesc(bd byte) (s string) { 102 bm := bd >> 5 103 if bm == cborMajorSimpleOrFloat { 104 s = cbordescSimpleNames[bd] 105 } else { 106 s = cbordescMajorNames[bm] 107 if s == "" { 108 s = cbordescIndefNames[bd] 109 } 110 } 111 if s == "" { 112 s = "unknown" 113 } 114 return 115 } 116 117 // ------------------- 118 119 type cborEncDriver struct { 120 noBuiltInTypes 121 encDriverNoState 122 encDriverNoopContainerWriter 123 h *CborHandle 124 125 e Encoder 126 } 127 128 func (e *cborEncDriver) encoder() *Encoder { 129 return &e.e 130 } 131 132 func (e *cborEncDriver) EncodeNil() { 133 e.e.encWr.writen1(cborBdNil) 134 } 135 136 func (e *cborEncDriver) EncodeBool(b bool) { 137 if b { 138 e.e.encWr.writen1(cborBdTrue) 139 } else { 140 e.e.encWr.writen1(cborBdFalse) 141 } 142 } 143 144 func (e *cborEncDriver) EncodeFloat32(f float32) { 145 b := math.Float32bits(f) 146 if e.h.OptimumSize { 147 if h := floatToHalfFloatBits(b); halfFloatToFloatBits(h) == b { 148 e.e.encWr.writen1(cborBdFloat16) 149 bigen.writeUint16(e.e.w(), h) 150 return 151 } 152 } 153 e.e.encWr.writen1(cborBdFloat32) 154 bigen.writeUint32(e.e.w(), b) 155 } 156 157 func (e *cborEncDriver) EncodeFloat64(f float64) { 158 if e.h.OptimumSize { 159 if f32 := float32(f); float64(f32) == f { 160 e.EncodeFloat32(f32) 161 return 162 } 163 } 164 e.e.encWr.writen1(cborBdFloat64) 165 bigen.writeUint64(e.e.w(), math.Float64bits(f)) 166 } 167 168 func (e *cborEncDriver) encUint(v uint64, bd byte) { 169 if v <= 0x17 { 170 e.e.encWr.writen1(byte(v) + bd) 171 } else if v <= math.MaxUint8 { 172 e.e.encWr.writen2(bd+0x18, uint8(v)) 173 } else if v <= math.MaxUint16 { 174 e.e.encWr.writen1(bd + 0x19) 175 bigen.writeUint16(e.e.w(), uint16(v)) 176 } else if v <= math.MaxUint32 { 177 e.e.encWr.writen1(bd + 0x1a) 178 bigen.writeUint32(e.e.w(), uint32(v)) 179 } else { // if v <= math.MaxUint64 { 180 e.e.encWr.writen1(bd + 0x1b) 181 bigen.writeUint64(e.e.w(), v) 182 } 183 } 184 185 func (e *cborEncDriver) EncodeInt(v int64) { 186 if v < 0 { 187 e.encUint(uint64(-1-v), cborBaseNegInt) 188 } else { 189 e.encUint(uint64(v), cborBaseUint) 190 } 191 } 192 193 func (e *cborEncDriver) EncodeUint(v uint64) { 194 e.encUint(v, cborBaseUint) 195 } 196 197 func (e *cborEncDriver) encLen(bd byte, length int) { 198 e.encUint(uint64(length), bd) 199 } 200 201 func (e *cborEncDriver) EncodeTime(t time.Time) { 202 if t.IsZero() { 203 e.EncodeNil() 204 } else if e.h.TimeRFC3339 { 205 e.encUint(0, cborBaseTag) 206 e.encStringBytesS(cborBaseString, t.Format(time.RFC3339Nano)) 207 } else { 208 e.encUint(1, cborBaseTag) 209 t = t.UTC().Round(time.Microsecond) 210 sec, nsec := t.Unix(), uint64(t.Nanosecond()) 211 if nsec == 0 { 212 e.EncodeInt(sec) 213 } else { 214 e.EncodeFloat64(float64(sec) + float64(nsec)/1e9) 215 } 216 } 217 } 218 219 func (e *cborEncDriver) EncodeExt(rv interface{}, basetype reflect.Type, xtag uint64, ext Ext) { 220 e.encUint(uint64(xtag), cborBaseTag) 221 if ext == SelfExt { 222 e.e.encodeValue(baseRV(rv), e.h.fnNoExt(basetype)) 223 } else if v := ext.ConvertExt(rv); v == nil { 224 e.EncodeNil() 225 } else { 226 e.e.encode(v) 227 } 228 } 229 230 func (e *cborEncDriver) EncodeRawExt(re *RawExt) { 231 e.encUint(uint64(re.Tag), cborBaseTag) 232 // only encodes re.Value (never re.Data) 233 if re.Value != nil { 234 e.e.encode(re.Value) 235 } else { 236 e.EncodeNil() 237 } 238 } 239 240 func (e *cborEncDriver) WriteArrayStart(length int) { 241 if e.h.IndefiniteLength { 242 e.e.encWr.writen1(cborBdIndefiniteArray) 243 } else { 244 e.encLen(cborBaseArray, length) 245 } 246 } 247 248 func (e *cborEncDriver) WriteMapStart(length int) { 249 if e.h.IndefiniteLength { 250 e.e.encWr.writen1(cborBdIndefiniteMap) 251 } else { 252 e.encLen(cborBaseMap, length) 253 } 254 } 255 256 func (e *cborEncDriver) WriteMapEnd() { 257 if e.h.IndefiniteLength { 258 e.e.encWr.writen1(cborBdBreak) 259 } 260 } 261 262 func (e *cborEncDriver) WriteArrayEnd() { 263 if e.h.IndefiniteLength { 264 e.e.encWr.writen1(cborBdBreak) 265 } 266 } 267 268 func (e *cborEncDriver) EncodeString(v string) { 269 bb := cborBaseString 270 if e.h.StringToRaw { 271 bb = cborBaseBytes 272 } 273 e.encStringBytesS(bb, v) 274 } 275 276 func (e *cborEncDriver) EncodeStringBytesRaw(v []byte) { 277 if v == nil { 278 e.EncodeNil() 279 } else { 280 e.encStringBytesS(cborBaseBytes, stringView(v)) 281 } 282 } 283 284 func (e *cborEncDriver) encStringBytesS(bb byte, v string) { 285 if e.h.IndefiniteLength { 286 if bb == cborBaseBytes { 287 e.e.encWr.writen1(cborBdIndefiniteBytes) 288 } else { 289 e.e.encWr.writen1(cborBdIndefiniteString) 290 } 291 var vlen uint = uint(len(v)) 292 blen := vlen / 4 293 if blen == 0 { 294 blen = 64 295 } else if blen > 1024 { 296 blen = 1024 297 } 298 for i := uint(0); i < vlen; { 299 var v2 string 300 i2 := i + blen 301 if i2 >= i && i2 < vlen { 302 v2 = v[i:i2] 303 } else { 304 v2 = v[i:] 305 } 306 e.encLen(bb, len(v2)) 307 e.e.encWr.writestr(v2) 308 i = i2 309 } 310 e.e.encWr.writen1(cborBdBreak) 311 } else { 312 e.encLen(bb, len(v)) 313 e.e.encWr.writestr(v) 314 } 315 } 316 317 // ---------------------- 318 319 type cborDecDriver struct { 320 decDriverNoopContainerReader 321 decDriverNoopNumberHelper 322 h *CborHandle 323 bdAndBdread 324 st bool // skip tags 325 _ bool // found nil 326 noBuiltInTypes 327 d Decoder 328 } 329 330 func (d *cborDecDriver) decoder() *Decoder { 331 return &d.d 332 } 333 334 func (d *cborDecDriver) descBd() string { 335 return sprintf("%v (%s)", d.bd, cbordesc(d.bd)) 336 } 337 338 func (d *cborDecDriver) readNextBd() { 339 d.bd = d.d.decRd.readn1() 340 d.bdRead = true 341 } 342 343 func (d *cborDecDriver) advanceNil() (null bool) { 344 if !d.bdRead { 345 d.readNextBd() 346 } 347 if d.bd == cborBdNil || d.bd == cborBdUndefined { 348 d.bdRead = false 349 return true // null = true 350 } 351 return 352 } 353 354 func (d *cborDecDriver) TryNil() bool { 355 return d.advanceNil() 356 } 357 358 // skipTags is called to skip any tags in the stream. 359 // 360 // Since any value can be tagged, then we should call skipTags 361 // before any value is decoded. 362 // 363 // By definition, skipTags should not be called before 364 // checking for break, or nil or undefined. 365 func (d *cborDecDriver) skipTags() { 366 for d.bd>>5 == cborMajorTag { 367 d.decUint() 368 d.bd = d.d.decRd.readn1() 369 } 370 } 371 372 func (d *cborDecDriver) ContainerType() (vt valueType) { 373 if !d.bdRead { 374 d.readNextBd() 375 } 376 if d.st { 377 d.skipTags() 378 } 379 if d.bd == cborBdNil { 380 d.bdRead = false // always consume nil after seeing it in container type 381 return valueTypeNil 382 } 383 major := d.bd >> 5 384 if major == cborMajorBytes { 385 return valueTypeBytes 386 } else if major == cborMajorString { 387 return valueTypeString 388 } else if major == cborMajorArray { 389 return valueTypeArray 390 } else if major == cborMajorMap { 391 return valueTypeMap 392 } 393 return valueTypeUnset 394 } 395 396 func (d *cborDecDriver) CheckBreak() (v bool) { 397 if !d.bdRead { 398 d.readNextBd() 399 } 400 if d.bd == cborBdBreak { 401 d.bdRead = false 402 v = true 403 } 404 return 405 } 406 407 func (d *cborDecDriver) decUint() (ui uint64) { 408 v := d.bd & 0x1f 409 if v <= 0x17 { 410 ui = uint64(v) 411 } else if v == 0x18 { 412 ui = uint64(d.d.decRd.readn1()) 413 } else if v == 0x19 { 414 ui = uint64(bigen.Uint16(d.d.decRd.readn2())) 415 } else if v == 0x1a { 416 ui = uint64(bigen.Uint32(d.d.decRd.readn4())) 417 } else if v == 0x1b { 418 ui = uint64(bigen.Uint64(d.d.decRd.readn8())) 419 } else { 420 d.d.errorf("invalid descriptor decoding uint: %x/%s", d.bd, cbordesc(d.bd)) 421 } 422 return 423 } 424 425 func (d *cborDecDriver) decLen() int { 426 return int(d.decUint()) 427 } 428 429 func (d *cborDecDriver) decAppendIndefiniteBytes(bs []byte) []byte { 430 d.bdRead = false 431 for !d.CheckBreak() { 432 if major := d.bd >> 5; major != cborMajorBytes && major != cborMajorString { 433 d.d.errorf("invalid indefinite string/bytes %x (%s); got major %v, expected %v or %v", 434 d.bd, cbordesc(d.bd), major, cborMajorBytes, cborMajorString) 435 } 436 n := uint(d.decLen()) 437 oldLen := uint(len(bs)) 438 newLen := oldLen + n 439 if newLen > uint(cap(bs)) { 440 bs2 := make([]byte, newLen, 2*uint(cap(bs))+n) 441 copy(bs2, bs) 442 bs = bs2 443 } else { 444 bs = bs[:newLen] 445 } 446 d.d.decRd.readb(bs[oldLen:newLen]) 447 d.bdRead = false 448 } 449 d.bdRead = false 450 return bs 451 } 452 453 func (d *cborDecDriver) decFloat() (f float64, ok bool) { 454 ok = true 455 switch d.bd { 456 case cborBdFloat16: 457 f = float64(math.Float32frombits(halfFloatToFloatBits(bigen.Uint16(d.d.decRd.readn2())))) 458 case cborBdFloat32: 459 f = float64(math.Float32frombits(bigen.Uint32(d.d.decRd.readn4()))) 460 case cborBdFloat64: 461 f = math.Float64frombits(bigen.Uint64(d.d.decRd.readn8())) 462 default: 463 ok = false 464 } 465 return 466 } 467 468 func (d *cborDecDriver) decInteger() (ui uint64, neg, ok bool) { 469 ok = true 470 switch d.bd >> 5 { 471 case cborMajorUint: 472 ui = d.decUint() 473 case cborMajorNegInt: 474 ui = d.decUint() 475 neg = true 476 default: 477 ok = false 478 } 479 return 480 } 481 482 func (d *cborDecDriver) DecodeInt64() (i int64) { 483 if d.advanceNil() { 484 return 485 } 486 if d.st { 487 d.skipTags() 488 } 489 i = decNegintPosintFloatNumberHelper{&d.d}.int64(d.decInteger()) 490 d.bdRead = false 491 return 492 } 493 494 func (d *cborDecDriver) DecodeUint64() (ui uint64) { 495 if d.advanceNil() { 496 return 497 } 498 if d.st { 499 d.skipTags() 500 } 501 ui = decNegintPosintFloatNumberHelper{&d.d}.uint64(d.decInteger()) 502 d.bdRead = false 503 return 504 } 505 506 func (d *cborDecDriver) DecodeFloat64() (f float64) { 507 if d.advanceNil() { 508 return 509 } 510 if d.st { 511 d.skipTags() 512 } 513 f = decNegintPosintFloatNumberHelper{&d.d}.float64(d.decFloat()) 514 d.bdRead = false 515 return 516 } 517 518 // bool can be decoded from bool only (single byte). 519 func (d *cborDecDriver) DecodeBool() (b bool) { 520 if d.advanceNil() { 521 return 522 } 523 if d.st { 524 d.skipTags() 525 } 526 if d.bd == cborBdTrue { 527 b = true 528 } else if d.bd == cborBdFalse { 529 } else { 530 d.d.errorf("not bool - %s %x/%s", msgBadDesc, d.bd, cbordesc(d.bd)) 531 } 532 d.bdRead = false 533 return 534 } 535 536 func (d *cborDecDriver) ReadMapStart() (length int) { 537 if d.advanceNil() { 538 return containerLenNil 539 } 540 if d.st { 541 d.skipTags() 542 } 543 d.bdRead = false 544 if d.bd == cborBdIndefiniteMap { 545 return containerLenUnknown 546 } 547 if d.bd>>5 != cborMajorMap { 548 d.d.errorf("error reading map; got major type: %x, expected %x/%s", d.bd>>5, cborMajorMap, cbordesc(d.bd)) 549 } 550 return d.decLen() 551 } 552 553 func (d *cborDecDriver) ReadArrayStart() (length int) { 554 if d.advanceNil() { 555 return containerLenNil 556 } 557 if d.st { 558 d.skipTags() 559 } 560 d.bdRead = false 561 if d.bd == cborBdIndefiniteArray { 562 return containerLenUnknown 563 } 564 if d.bd>>5 != cborMajorArray { 565 d.d.errorf("invalid array; got major type: %x, expect: %x/%s", d.bd>>5, cborMajorArray, cbordesc(d.bd)) 566 } 567 return d.decLen() 568 } 569 570 func (d *cborDecDriver) DecodeBytes(bs []byte) (bsOut []byte) { 571 d.d.decByteState = decByteStateNone 572 if d.advanceNil() { 573 return 574 } 575 if d.st { 576 d.skipTags() 577 } 578 if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString { 579 d.bdRead = false 580 if bs == nil { 581 d.d.decByteState = decByteStateReuseBuf 582 return d.decAppendIndefiniteBytes(d.d.b[:0]) 583 } 584 return d.decAppendIndefiniteBytes(bs[:0]) 585 } 586 if d.bd == cborBdIndefiniteArray { 587 d.bdRead = false 588 if bs == nil { 589 d.d.decByteState = decByteStateReuseBuf 590 bs = d.d.b[:0] 591 } else { 592 bs = bs[:0] 593 } 594 for !d.CheckBreak() { 595 bs = append(bs, uint8(chkOvf.UintV(d.DecodeUint64(), 8))) 596 } 597 return bs 598 } 599 if d.bd>>5 == cborMajorArray { 600 d.bdRead = false 601 if bs == nil { 602 d.d.decByteState = decByteStateReuseBuf 603 bs = d.d.b[:] 604 } 605 slen := d.decLen() 606 var changed bool 607 if bs, changed = usableByteSlice(bs, slen); changed { 608 d.d.decByteState = decByteStateNone 609 } 610 for i := 0; i < len(bs); i++ { 611 bs[i] = uint8(chkOvf.UintV(d.DecodeUint64(), 8)) 612 } 613 return bs 614 } 615 clen := d.decLen() 616 d.bdRead = false 617 if d.d.zerocopy() { 618 d.d.decByteState = decByteStateZerocopy 619 return d.d.decRd.rb.readx(uint(clen)) 620 } 621 if bs == nil { 622 d.d.decByteState = decByteStateReuseBuf 623 bs = d.d.b[:] 624 } 625 return decByteSlice(d.d.r(), clen, d.h.MaxInitLen, bs) 626 } 627 628 func (d *cborDecDriver) DecodeStringAsBytes() (s []byte) { 629 return d.DecodeBytes(nil) 630 } 631 632 func (d *cborDecDriver) DecodeTime() (t time.Time) { 633 if d.advanceNil() { 634 return 635 } 636 if d.bd>>5 != cborMajorTag { 637 d.d.errorf("error reading tag; expected major type: %x, got: %x", cborMajorTag, d.bd>>5) 638 } 639 xtag := d.decUint() 640 d.bdRead = false 641 return d.decodeTime(xtag) 642 } 643 644 func (d *cborDecDriver) decodeTime(xtag uint64) (t time.Time) { 645 switch xtag { 646 case 0: 647 var err error 648 t, err = time.Parse(time.RFC3339, stringView(d.DecodeStringAsBytes())) 649 d.d.onerror(err) 650 case 1: 651 f1, f2 := math.Modf(d.DecodeFloat64()) 652 t = time.Unix(int64(f1), int64(f2*1e9)) 653 default: 654 d.d.errorf("invalid tag for time.Time - expecting 0 or 1, got 0x%x", xtag) 655 } 656 t = t.UTC().Round(time.Microsecond) 657 return 658 } 659 660 func (d *cborDecDriver) DecodeExt(rv interface{}, basetype reflect.Type, xtag uint64, ext Ext) { 661 if d.advanceNil() { 662 return 663 } 664 if d.bd>>5 != cborMajorTag { 665 d.d.errorf("error reading tag; expected major type: %x, got: %x", cborMajorTag, d.bd>>5) 666 } 667 realxtag := d.decUint() 668 d.bdRead = false 669 if ext == nil { 670 re := rv.(*RawExt) 671 re.Tag = realxtag 672 d.d.decode(&re.Value) 673 } else if xtag != realxtag { 674 d.d.errorf("Wrong extension tag. Got %b. Expecting: %v", realxtag, xtag) 675 } else if ext == SelfExt { 676 d.d.decodeValue(baseRV(rv), d.h.fnNoExt(basetype)) 677 } else { 678 d.d.interfaceExtConvertAndDecode(rv, ext) 679 } 680 d.bdRead = false 681 } 682 683 func (d *cborDecDriver) DecodeNaked() { 684 if !d.bdRead { 685 d.readNextBd() 686 } 687 688 n := d.d.naked() 689 var decodeFurther bool 690 691 switch d.bd >> 5 { 692 case cborMajorUint: 693 if d.h.SignedInteger { 694 n.v = valueTypeInt 695 n.i = d.DecodeInt64() 696 } else { 697 n.v = valueTypeUint 698 n.u = d.DecodeUint64() 699 } 700 case cborMajorNegInt: 701 n.v = valueTypeInt 702 n.i = d.DecodeInt64() 703 case cborMajorBytes: 704 d.d.fauxUnionReadRawBytes(false) 705 case cborMajorString: 706 n.v = valueTypeString 707 n.s = d.d.stringZC(d.DecodeStringAsBytes()) 708 case cborMajorArray: 709 n.v = valueTypeArray 710 decodeFurther = true 711 case cborMajorMap: 712 n.v = valueTypeMap 713 decodeFurther = true 714 case cborMajorTag: 715 n.v = valueTypeExt 716 n.u = d.decUint() 717 n.l = nil 718 if n.u == 0 || n.u == 1 { 719 d.bdRead = false 720 n.v = valueTypeTime 721 n.t = d.decodeTime(n.u) 722 } else if d.st && d.h.getExtForTag(n.u) == nil { 723 // d.skipTags() // no need to call this - tags already skipped 724 d.bdRead = false 725 d.DecodeNaked() 726 return // return when done (as true recursive function) 727 } 728 case cborMajorSimpleOrFloat: 729 switch d.bd { 730 case cborBdNil, cborBdUndefined: 731 n.v = valueTypeNil 732 case cborBdFalse: 733 n.v = valueTypeBool 734 n.b = false 735 case cborBdTrue: 736 n.v = valueTypeBool 737 n.b = true 738 case cborBdFloat16, cborBdFloat32, cborBdFloat64: 739 n.v = valueTypeFloat 740 n.f = d.DecodeFloat64() 741 default: 742 d.d.errorf("decodeNaked: Unrecognized d.bd: 0x%x", d.bd) 743 } 744 default: // should never happen 745 d.d.errorf("decodeNaked: Unrecognized d.bd: 0x%x", d.bd) 746 } 747 if !decodeFurther { 748 d.bdRead = false 749 } 750 } 751 752 func (d *cborDecDriver) uintBytes() (v []byte, ui uint64) { 753 // this is only used by nextValueBytes, so it's ok to 754 // use readx and bigenstd here. 755 switch vv := d.bd & 0x1f; vv { 756 case 0x18: 757 v = d.d.decRd.readx(1) 758 ui = uint64(v[0]) 759 case 0x19: 760 v = d.d.decRd.readx(2) 761 ui = uint64(bigenstd.Uint16(v)) 762 case 0x1a: 763 v = d.d.decRd.readx(4) 764 ui = uint64(bigenstd.Uint32(v)) 765 case 0x1b: 766 v = d.d.decRd.readx(8) 767 ui = uint64(bigenstd.Uint64(v)) 768 default: 769 if vv > 0x1b { 770 d.d.errorf("invalid descriptor decoding uint: %x/%s", d.bd, cbordesc(d.bd)) 771 } 772 ui = uint64(vv) 773 } 774 return 775 } 776 777 func (d *cborDecDriver) nextValueBytes(v0 []byte) (v []byte) { 778 if !d.bdRead { 779 d.readNextBd() 780 } 781 v = v0 782 var h = decNextValueBytesHelper{d: &d.d} 783 var cursor = d.d.rb.c - 1 784 h.append1(&v, d.bd) 785 v = d.nextValueBytesBdReadR(v) 786 d.bdRead = false 787 h.bytesRdV(&v, cursor) 788 return 789 } 790 791 func (d *cborDecDriver) nextValueBytesR(v0 []byte) (v []byte) { 792 d.readNextBd() 793 v = v0 794 var h = decNextValueBytesHelper{d: &d.d} 795 h.append1(&v, d.bd) 796 return d.nextValueBytesBdReadR(v) 797 } 798 799 func (d *cborDecDriver) nextValueBytesBdReadR(v0 []byte) (v []byte) { 800 v = v0 801 var h = decNextValueBytesHelper{d: &d.d} 802 803 var bs []byte 804 var ui uint64 805 806 switch d.bd >> 5 { 807 case cborMajorUint, cborMajorNegInt: 808 bs, _ = d.uintBytes() 809 h.appendN(&v, bs...) 810 case cborMajorString, cborMajorBytes: 811 if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString { 812 for { 813 d.readNextBd() 814 h.append1(&v, d.bd) 815 if d.bd == cborBdBreak { 816 break 817 } 818 bs, ui = d.uintBytes() 819 h.appendN(&v, bs...) 820 h.appendN(&v, d.d.decRd.readx(uint(ui))...) 821 } 822 } else { 823 bs, ui = d.uintBytes() 824 h.appendN(&v, bs...) 825 h.appendN(&v, d.d.decRd.readx(uint(ui))...) 826 } 827 case cborMajorArray: 828 if d.bd == cborBdIndefiniteArray { 829 for { 830 d.readNextBd() 831 h.append1(&v, d.bd) 832 if d.bd == cborBdBreak { 833 break 834 } 835 v = d.nextValueBytesBdReadR(v) 836 } 837 } else { 838 bs, ui = d.uintBytes() 839 h.appendN(&v, bs...) 840 for i := uint64(0); i < ui; i++ { 841 v = d.nextValueBytesR(v) 842 } 843 } 844 case cborMajorMap: 845 if d.bd == cborBdIndefiniteMap { 846 for { 847 d.readNextBd() 848 h.append1(&v, d.bd) 849 if d.bd == cborBdBreak { 850 break 851 } 852 v = d.nextValueBytesBdReadR(v) 853 v = d.nextValueBytesR(v) 854 } 855 } else { 856 bs, ui = d.uintBytes() 857 h.appendN(&v, bs...) 858 for i := uint64(0); i < ui; i++ { 859 v = d.nextValueBytesR(v) 860 v = d.nextValueBytesR(v) 861 } 862 } 863 case cborMajorTag: 864 bs, _ = d.uintBytes() 865 h.appendN(&v, bs...) 866 v = d.nextValueBytesR(v) 867 case cborMajorSimpleOrFloat: 868 switch d.bd { 869 case cborBdNil, cborBdUndefined, cborBdFalse, cborBdTrue: // pass 870 case cborBdFloat16: 871 h.appendN(&v, d.d.decRd.readx(2)...) 872 case cborBdFloat32: 873 h.appendN(&v, d.d.decRd.readx(4)...) 874 case cborBdFloat64: 875 h.appendN(&v, d.d.decRd.readx(8)...) 876 default: 877 d.d.errorf("nextValueBytes: Unrecognized d.bd: 0x%x", d.bd) 878 } 879 default: // should never happen 880 d.d.errorf("nextValueBytes: Unrecognized d.bd: 0x%x", d.bd) 881 } 882 return 883 } 884 885 // ------------------------- 886 887 // CborHandle is a Handle for the CBOR encoding format, 888 // defined at http://tools.ietf.org/html/rfc7049 and documented further at http://cbor.io . 889 // 890 // CBOR is comprehensively supported, including support for: 891 // - indefinite-length arrays/maps/bytes/strings 892 // - (extension) tags in range 0..0xffff (0 .. 65535) 893 // - half, single and double-precision floats 894 // - all numbers (1, 2, 4 and 8-byte signed and unsigned integers) 895 // - nil, true, false, ... 896 // - arrays and maps, bytes and text strings 897 // 898 // None of the optional extensions (with tags) defined in the spec are supported out-of-the-box. 899 // Users can implement them as needed (using SetExt), including spec-documented ones: 900 // - timestamp, BigNum, BigFloat, Decimals, 901 // - Encoded Text (e.g. URL, regexp, base64, MIME Message), etc. 902 type CborHandle struct { 903 binaryEncodingType 904 // noElemSeparators 905 BasicHandle 906 907 // IndefiniteLength=true, means that we encode using indefinitelength 908 IndefiniteLength bool 909 910 // TimeRFC3339 says to encode time.Time using RFC3339 format. 911 // If unset, we encode time.Time using seconds past epoch. 912 TimeRFC3339 bool 913 914 // SkipUnexpectedTags says to skip over any tags for which extensions are 915 // not defined. This is in keeping with the cbor spec on "Optional Tagging of Items". 916 // 917 // Furthermore, this allows the skipping over of the Self Describing Tag 0xd9d9f7. 918 SkipUnexpectedTags bool 919 } 920 921 // Name returns the name of the handle: cbor 922 func (h *CborHandle) Name() string { return "cbor" } 923 924 func (h *CborHandle) desc(bd byte) string { return cbordesc(bd) } 925 926 func (h *CborHandle) newEncDriver() encDriver { 927 var e = &cborEncDriver{h: h} 928 e.e.e = e 929 e.e.init(h) 930 e.reset() 931 return e 932 } 933 934 func (h *CborHandle) newDecDriver() decDriver { 935 d := &cborDecDriver{h: h, st: h.SkipUnexpectedTags} 936 d.d.d = d 937 d.d.cbor = true 938 d.d.init(h) 939 d.reset() 940 return d 941 } 942 943 func (d *cborDecDriver) reset() { 944 d.bdAndBdread.reset() 945 d.st = d.h.SkipUnexpectedTags 946 } 947 948 var _ decDriver = (*cborDecDriver)(nil) 949 var _ encDriver = (*cborEncDriver)(nil)