github.com/patricebensoussan/go/codec@v1.2.99/binc.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 // Symbol management: 13 // - symbols are stored in a symbol map during encoding and decoding. 14 // - the symbols persist until the (En|De)coder ResetXXX method is called. 15 16 const bincDoPrune = true 17 18 // vd as low 4 bits (there are 16 slots) 19 const ( 20 bincVdSpecial byte = iota 21 bincVdPosInt 22 bincVdNegInt 23 bincVdFloat 24 25 bincVdString 26 bincVdByteArray 27 bincVdArray 28 bincVdMap 29 30 bincVdTimestamp 31 bincVdSmallInt 32 _ // bincVdUnicodeOther 33 bincVdSymbol 34 35 _ // bincVdDecimal 36 _ // open slot 37 _ // open slot 38 bincVdCustomExt = 0x0f 39 ) 40 41 const ( 42 bincSpNil byte = iota 43 bincSpFalse 44 bincSpTrue 45 bincSpNan 46 bincSpPosInf 47 bincSpNegInf 48 bincSpZeroFloat 49 bincSpZero 50 bincSpNegOne 51 ) 52 53 const ( 54 _ byte = iota // bincFlBin16 55 bincFlBin32 56 _ // bincFlBin32e 57 bincFlBin64 58 _ // bincFlBin64e 59 // others not currently supported 60 ) 61 62 const bincBdNil = 0 // bincVdSpecial<<4 | bincSpNil // staticcheck barfs on this (SA4016) 63 64 var ( 65 bincdescSpecialVsNames = map[byte]string{ 66 bincSpNil: "nil", 67 bincSpFalse: "false", 68 bincSpTrue: "true", 69 bincSpNan: "float", 70 bincSpPosInf: "float", 71 bincSpNegInf: "float", 72 bincSpZeroFloat: "float", 73 bincSpZero: "uint", 74 bincSpNegOne: "int", 75 } 76 bincdescVdNames = map[byte]string{ 77 bincVdSpecial: "special", 78 bincVdSmallInt: "uint", 79 bincVdPosInt: "uint", 80 bincVdFloat: "float", 81 bincVdSymbol: "string", 82 bincVdString: "string", 83 bincVdByteArray: "bytes", 84 bincVdTimestamp: "time", 85 bincVdCustomExt: "ext", 86 bincVdArray: "array", 87 bincVdMap: "map", 88 } 89 ) 90 91 func bincdescbd(bd byte) (s string) { 92 return bincdesc(bd>>4, bd&0x0f) 93 } 94 95 func bincdesc(vd, vs byte) (s string) { 96 if vd == bincVdSpecial { 97 s = bincdescSpecialVsNames[vs] 98 } else { 99 s = bincdescVdNames[vd] 100 } 101 if s == "" { 102 s = "unknown" 103 } 104 return 105 } 106 107 type bincEncState struct { 108 m map[string]uint16 // symbols 109 } 110 111 func (e bincEncState) captureState() interface{} { return e.m } 112 func (e *bincEncState) resetState() { e.m = nil } 113 func (e *bincEncState) reset() { e.resetState() } 114 func (e *bincEncState) restoreState(v interface{}) { e.m = v.(map[string]uint16) } 115 116 type bincEncDriver struct { 117 noBuiltInTypes 118 encDriverNoopContainerWriter 119 h *BincHandle 120 bincEncState 121 122 e Encoder 123 } 124 125 func (e *bincEncDriver) encoder() *Encoder { 126 return &e.e 127 } 128 129 func (e *bincEncDriver) EncodeNil() { 130 e.e.encWr.writen1(bincBdNil) 131 } 132 133 func (e *bincEncDriver) EncodeTime(t time.Time) { 134 if t.IsZero() { 135 e.EncodeNil() 136 } else { 137 bs := bincEncodeTime(t) 138 e.e.encWr.writen1(bincVdTimestamp<<4 | uint8(len(bs))) 139 e.e.encWr.writeb(bs) 140 } 141 } 142 143 func (e *bincEncDriver) EncodeBool(b bool) { 144 if b { 145 e.e.encWr.writen1(bincVdSpecial<<4 | bincSpTrue) 146 } else { 147 e.e.encWr.writen1(bincVdSpecial<<4 | bincSpFalse) 148 } 149 } 150 151 func (e *bincEncDriver) encSpFloat(f float64) (done bool) { 152 if f == 0 { 153 e.e.encWr.writen1(bincVdSpecial<<4 | bincSpZeroFloat) 154 } else if math.IsNaN(float64(f)) { 155 e.e.encWr.writen1(bincVdSpecial<<4 | bincSpNan) 156 } else if math.IsInf(float64(f), +1) { 157 e.e.encWr.writen1(bincVdSpecial<<4 | bincSpPosInf) 158 } else if math.IsInf(float64(f), -1) { 159 e.e.encWr.writen1(bincVdSpecial<<4 | bincSpNegInf) 160 } else { 161 return 162 } 163 return true 164 } 165 166 func (e *bincEncDriver) EncodeFloat32(f float32) { 167 if !e.encSpFloat(float64(f)) { 168 e.e.encWr.writen1(bincVdFloat<<4 | bincFlBin32) 169 bigen.writeUint32(e.e.w(), math.Float32bits(f)) 170 } 171 } 172 173 func (e *bincEncDriver) EncodeFloat64(f float64) { 174 if e.encSpFloat(f) { 175 return 176 } 177 b := bigen.PutUint64(math.Float64bits(f)) 178 if bincDoPrune { 179 i := 7 180 for ; i >= 0 && (b[i] == 0); i-- { 181 } 182 i++ 183 if i <= 6 { 184 e.e.encWr.writen1(bincVdFloat<<4 | 0x8 | bincFlBin64) 185 e.e.encWr.writen1(byte(i)) 186 e.e.encWr.writeb(b[:i]) 187 return 188 } 189 } 190 e.e.encWr.writen1(bincVdFloat<<4 | bincFlBin64) 191 e.e.encWr.writen8(b) 192 } 193 194 func (e *bincEncDriver) encIntegerPrune32(bd byte, pos bool, v uint64) { 195 b := bigen.PutUint32(uint32(v)) 196 if bincDoPrune { 197 i := byte(pruneSignExt(b[:], pos)) 198 e.e.encWr.writen1(bd | 3 - i) 199 e.e.encWr.writeb(b[i:]) 200 } else { 201 e.e.encWr.writen1(bd | 3) 202 e.e.encWr.writen4(b) 203 } 204 } 205 206 func (e *bincEncDriver) encIntegerPrune64(bd byte, pos bool, v uint64) { 207 b := bigen.PutUint64(v) 208 if bincDoPrune { 209 i := byte(pruneSignExt(b[:], pos)) 210 e.e.encWr.writen1(bd | 7 - i) 211 e.e.encWr.writeb(b[i:]) 212 } else { 213 e.e.encWr.writen1(bd | 7) 214 e.e.encWr.writen8(b) 215 } 216 } 217 218 func (e *bincEncDriver) EncodeInt(v int64) { 219 if v >= 0 { 220 e.encUint(bincVdPosInt<<4, true, uint64(v)) 221 } else if v == -1 { 222 e.e.encWr.writen1(bincVdSpecial<<4 | bincSpNegOne) 223 } else { 224 e.encUint(bincVdNegInt<<4, false, uint64(-v)) 225 } 226 } 227 228 func (e *bincEncDriver) EncodeUint(v uint64) { 229 e.encUint(bincVdPosInt<<4, true, v) 230 } 231 232 func (e *bincEncDriver) encUint(bd byte, pos bool, v uint64) { 233 if v == 0 { 234 e.e.encWr.writen1(bincVdSpecial<<4 | bincSpZero) 235 } else if pos && v >= 1 && v <= 16 { 236 e.e.encWr.writen1(bincVdSmallInt<<4 | byte(v-1)) 237 } else if v <= math.MaxUint8 { 238 e.e.encWr.writen2(bd|0x0, byte(v)) 239 } else if v <= math.MaxUint16 { 240 e.e.encWr.writen1(bd | 0x01) 241 bigen.writeUint16(e.e.w(), uint16(v)) 242 } else if v <= math.MaxUint32 { 243 e.encIntegerPrune32(bd, pos, v) 244 } else { 245 e.encIntegerPrune64(bd, pos, v) 246 } 247 } 248 249 func (e *bincEncDriver) EncodeExt(v interface{}, basetype reflect.Type, xtag uint64, ext Ext) { 250 var bs0, bs []byte 251 if ext == SelfExt { 252 bs0 = e.e.blist.get(1024) 253 bs = bs0 254 e.e.sideEncode(v, basetype, &bs) 255 } else { 256 bs = ext.WriteExt(v) 257 } 258 if bs == nil { 259 e.EncodeNil() 260 goto END 261 } 262 e.encodeExtPreamble(uint8(xtag), len(bs)) 263 e.e.encWr.writeb(bs) 264 END: 265 if ext == SelfExt { 266 e.e.blist.put(bs) 267 if !byteSliceSameData(bs0, bs) { 268 e.e.blist.put(bs0) 269 } 270 } 271 } 272 273 func (e *bincEncDriver) EncodeRawExt(re *RawExt) { 274 e.encodeExtPreamble(uint8(re.Tag), len(re.Data)) 275 e.e.encWr.writeb(re.Data) 276 } 277 278 func (e *bincEncDriver) encodeExtPreamble(xtag byte, length int) { 279 e.encLen(bincVdCustomExt<<4, uint64(length)) 280 e.e.encWr.writen1(xtag) 281 } 282 283 func (e *bincEncDriver) WriteArrayStart(length int) { 284 e.encLen(bincVdArray<<4, uint64(length)) 285 } 286 287 func (e *bincEncDriver) WriteMapStart(length int) { 288 e.encLen(bincVdMap<<4, uint64(length)) 289 } 290 291 func (e *bincEncDriver) EncodeSymbol(v string) { 292 //symbols only offer benefit when string length > 1. 293 //This is because strings with length 1 take only 2 bytes to store 294 //(bd with embedded length, and single byte for string val). 295 296 l := len(v) 297 if l == 0 { 298 e.encBytesLen(cUTF8, 0) 299 return 300 } else if l == 1 { 301 e.encBytesLen(cUTF8, 1) 302 e.e.encWr.writen1(v[0]) 303 return 304 } 305 if e.m == nil { 306 e.m = make(map[string]uint16, 16) 307 } 308 ui, ok := e.m[v] 309 if ok { 310 if ui <= math.MaxUint8 { 311 e.e.encWr.writen2(bincVdSymbol<<4, byte(ui)) 312 } else { 313 e.e.encWr.writen1(bincVdSymbol<<4 | 0x8) 314 bigen.writeUint16(e.e.w(), ui) 315 } 316 } else { 317 e.e.seq++ 318 ui = e.e.seq 319 e.m[v] = ui 320 var lenprec uint8 321 if l <= math.MaxUint8 { 322 // lenprec = 0 323 } else if l <= math.MaxUint16 { 324 lenprec = 1 325 } else if int64(l) <= math.MaxUint32 { 326 lenprec = 2 327 } else { 328 lenprec = 3 329 } 330 if ui <= math.MaxUint8 { 331 e.e.encWr.writen2(bincVdSymbol<<4|0x0|0x4|lenprec, byte(ui)) 332 } else { 333 e.e.encWr.writen1(bincVdSymbol<<4 | 0x8 | 0x4 | lenprec) 334 bigen.writeUint16(e.e.w(), ui) 335 } 336 if lenprec == 0 { 337 e.e.encWr.writen1(byte(l)) 338 } else if lenprec == 1 { 339 bigen.writeUint16(e.e.w(), uint16(l)) 340 } else if lenprec == 2 { 341 bigen.writeUint32(e.e.w(), uint32(l)) 342 } else { 343 bigen.writeUint64(e.e.w(), uint64(l)) 344 } 345 e.e.encWr.writestr(v) 346 } 347 } 348 349 func (e *bincEncDriver) EncodeString(v string) { 350 if e.h.StringToRaw { 351 e.encLen(bincVdByteArray<<4, uint64(len(v))) 352 if len(v) > 0 { 353 e.e.encWr.writestr(v) 354 } 355 return 356 } 357 e.EncodeStringEnc(cUTF8, v) 358 } 359 360 func (e *bincEncDriver) EncodeStringEnc(c charEncoding, v string) { 361 if e.e.c == containerMapKey && c == cUTF8 && (e.h.AsSymbols == 1) { 362 e.EncodeSymbol(v) 363 return 364 } 365 e.encLen(bincVdString<<4, uint64(len(v))) 366 if len(v) > 0 { 367 e.e.encWr.writestr(v) 368 } 369 } 370 371 func (e *bincEncDriver) EncodeStringBytesRaw(v []byte) { 372 if v == nil { 373 e.EncodeNil() 374 return 375 } 376 e.encLen(bincVdByteArray<<4, uint64(len(v))) 377 if len(v) > 0 { 378 e.e.encWr.writeb(v) 379 } 380 } 381 382 func (e *bincEncDriver) encBytesLen(c charEncoding, length uint64) { 383 // MARKER: we currently only support UTF-8 (string) and RAW (bytearray). 384 // We should consider supporting bincUnicodeOther. 385 386 if c == cRAW { 387 e.encLen(bincVdByteArray<<4, length) 388 } else { 389 e.encLen(bincVdString<<4, length) 390 } 391 } 392 393 func (e *bincEncDriver) encLen(bd byte, l uint64) { 394 if l < 12 { 395 e.e.encWr.writen1(bd | uint8(l+4)) 396 } else { 397 e.encLenNumber(bd, l) 398 } 399 } 400 401 func (e *bincEncDriver) encLenNumber(bd byte, v uint64) { 402 if v <= math.MaxUint8 { 403 e.e.encWr.writen2(bd, byte(v)) 404 } else if v <= math.MaxUint16 { 405 e.e.encWr.writen1(bd | 0x01) 406 bigen.writeUint16(e.e.w(), uint16(v)) 407 } else if v <= math.MaxUint32 { 408 e.e.encWr.writen1(bd | 0x02) 409 bigen.writeUint32(e.e.w(), uint32(v)) 410 } else { 411 e.e.encWr.writen1(bd | 0x03) 412 bigen.writeUint64(e.e.w(), uint64(v)) 413 } 414 } 415 416 //------------------------------------ 417 418 type bincDecState struct { 419 bdRead bool 420 bd byte 421 vd byte 422 vs byte 423 424 _ bool 425 // MARKER: consider using binary search here instead of a map (ie bincDecSymbol) 426 s map[uint16][]byte 427 } 428 429 func (x bincDecState) captureState() interface{} { return x } 430 func (x *bincDecState) resetState() { *x = bincDecState{} } 431 func (x *bincDecState) reset() { x.resetState() } 432 func (x *bincDecState) restoreState(v interface{}) { *x = v.(bincDecState) } 433 434 type bincDecDriver struct { 435 decDriverNoopContainerReader 436 decDriverNoopNumberHelper 437 noBuiltInTypes 438 439 h *BincHandle 440 441 bincDecState 442 d Decoder 443 } 444 445 func (d *bincDecDriver) decoder() *Decoder { 446 return &d.d 447 } 448 449 func (d *bincDecDriver) descBd() string { 450 return sprintf("%v (%s)", d.bd, bincdescbd(d.bd)) 451 } 452 453 func (d *bincDecDriver) readNextBd() { 454 d.bd = d.d.decRd.readn1() 455 d.vd = d.bd >> 4 456 d.vs = d.bd & 0x0f 457 d.bdRead = true 458 } 459 460 func (d *bincDecDriver) advanceNil() (null bool) { 461 if !d.bdRead { 462 d.readNextBd() 463 } 464 if d.bd == bincBdNil { 465 d.bdRead = false 466 return true // null = true 467 } 468 return 469 } 470 471 func (d *bincDecDriver) TryNil() bool { 472 return d.advanceNil() 473 } 474 475 func (d *bincDecDriver) ContainerType() (vt valueType) { 476 if !d.bdRead { 477 d.readNextBd() 478 } 479 if d.bd == bincBdNil { 480 d.bdRead = false 481 return valueTypeNil 482 } else if d.vd == bincVdByteArray { 483 return valueTypeBytes 484 } else if d.vd == bincVdString { 485 return valueTypeString 486 } else if d.vd == bincVdArray { 487 return valueTypeArray 488 } else if d.vd == bincVdMap { 489 return valueTypeMap 490 } 491 return valueTypeUnset 492 } 493 494 func (d *bincDecDriver) DecodeTime() (t time.Time) { 495 if d.advanceNil() { 496 return 497 } 498 if d.vd != bincVdTimestamp { 499 d.d.errorf("cannot decode time - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs)) 500 } 501 t, err := bincDecodeTime(d.d.decRd.readx(uint(d.vs))) 502 halt.onerror(err) 503 d.bdRead = false 504 return 505 } 506 507 func (d *bincDecDriver) decFloatPruned(maxlen uint8) { 508 l := d.d.decRd.readn1() 509 if l > maxlen { 510 d.d.errorf("cannot read float - at most %v bytes used to represent float - received %v bytes", maxlen, l) 511 } 512 for i := l; i < maxlen; i++ { 513 d.d.b[i] = 0 514 } 515 d.d.decRd.readb(d.d.b[0:l]) 516 } 517 518 func (d *bincDecDriver) decFloatPre32() (b [4]byte) { 519 if d.vs&0x8 == 0 { 520 b = d.d.decRd.readn4() 521 } else { 522 d.decFloatPruned(4) 523 copy(b[:], d.d.b[:]) 524 } 525 return 526 } 527 528 func (d *bincDecDriver) decFloatPre64() (b [8]byte) { 529 if d.vs&0x8 == 0 { 530 b = d.d.decRd.readn8() 531 } else { 532 d.decFloatPruned(8) 533 copy(b[:], d.d.b[:]) 534 } 535 return 536 } 537 538 func (d *bincDecDriver) decFloatVal() (f float64) { 539 switch d.vs & 0x7 { 540 case bincFlBin32: 541 f = float64(math.Float32frombits(bigen.Uint32(d.decFloatPre32()))) 542 case bincFlBin64: 543 f = math.Float64frombits(bigen.Uint64(d.decFloatPre64())) 544 default: 545 // ok = false 546 d.d.errorf("read float supports only float32/64 - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs)) 547 } 548 return 549 } 550 551 func (d *bincDecDriver) decUint() (v uint64) { 552 switch d.vs { 553 case 0: 554 v = uint64(d.d.decRd.readn1()) 555 case 1: 556 v = uint64(bigen.Uint16(d.d.decRd.readn2())) 557 case 2: 558 v = uint64(bigen.Uint32(d.d.decRd.readn3())) 559 case 3: 560 v = uint64(bigen.Uint32(d.d.decRd.readn4())) 561 case 4, 5, 6: 562 var b [8]byte 563 lim := 7 - d.vs 564 bs := d.d.b[lim:8] 565 d.d.decRd.readb(bs) 566 copy(b[lim:], bs) 567 v = bigen.Uint64(b) 568 case 7: 569 v = bigen.Uint64(d.d.decRd.readn8()) 570 default: 571 d.d.errorf("unsigned integers with greater than 64 bits of precision not supported: d.vs: %v %x", d.vs, d.vs) 572 } 573 return 574 } 575 576 func (d *bincDecDriver) uintBytes() (bs []byte) { 577 switch d.vs { 578 case 0: 579 bs = d.d.b[:1] 580 bs[0] = d.d.decRd.readn1() 581 case 1: 582 bs = d.d.b[:2] 583 d.d.decRd.readb(bs) 584 case 2: 585 bs = d.d.b[:3] 586 d.d.decRd.readb(bs) 587 case 3: 588 bs = d.d.b[:4] 589 d.d.decRd.readb(bs) 590 case 4, 5, 6: 591 lim := 7 - d.vs 592 bs = d.d.b[lim:8] 593 d.d.decRd.readb(bs) 594 case 7: 595 bs = d.d.b[:8] 596 d.d.decRd.readb(bs) 597 default: 598 d.d.errorf("unsigned integers with greater than 64 bits of precision not supported: d.vs: %v %x", d.vs, d.vs) 599 } 600 return 601 } 602 603 func (d *bincDecDriver) decInteger() (ui uint64, neg, ok bool) { 604 ok = true 605 vd, vs := d.vd, d.vs 606 if vd == bincVdPosInt { 607 ui = d.decUint() 608 } else if vd == bincVdNegInt { 609 ui = d.decUint() 610 neg = true 611 } else if vd == bincVdSmallInt { 612 ui = uint64(d.vs) + 1 613 } else if vd == bincVdSpecial { 614 if vs == bincSpZero { 615 // i = 0 616 } else if vs == bincSpNegOne { 617 neg = true 618 ui = 1 619 } else { 620 ok = false 621 // d.d.errorf("integer decode has invalid special value %x-%x/%s", d.vd, d.vs, bincdesc(d.vd, d.vs)) 622 } 623 } else { 624 ok = false 625 // d.d.errorf("integer can only be decoded from int/uint. d.bd: 0x%x, d.vd: 0x%x", d.bd, d.vd) 626 } 627 return 628 } 629 630 func (d *bincDecDriver) decFloat() (f float64, ok bool) { 631 ok = true 632 vd, vs := d.vd, d.vs 633 if vd == bincVdSpecial { 634 if vs == bincSpNan { 635 f = math.NaN() 636 } else if vs == bincSpPosInf { 637 f = math.Inf(1) 638 } else if vs == bincSpZeroFloat || vs == bincSpZero { 639 640 } else if vs == bincSpNegInf { 641 f = math.Inf(-1) 642 } else { 643 ok = false 644 // d.d.errorf("float - invalid special value %x-%x/%s", d.vd, d.vs, bincdesc(d.vd, d.vs)) 645 } 646 } else if vd == bincVdFloat { 647 f = d.decFloatVal() 648 } else { 649 ok = false 650 } 651 return 652 } 653 654 func (d *bincDecDriver) DecodeInt64() (i int64) { 655 if d.advanceNil() { 656 return 657 } 658 i = decNegintPosintFloatNumberHelper{&d.d}.int64(d.decInteger()) 659 d.bdRead = false 660 return 661 } 662 663 func (d *bincDecDriver) DecodeUint64() (ui uint64) { 664 if d.advanceNil() { 665 return 666 } 667 ui = decNegintPosintFloatNumberHelper{&d.d}.uint64(d.decInteger()) 668 d.bdRead = false 669 return 670 } 671 672 func (d *bincDecDriver) DecodeFloat64() (f float64) { 673 if d.advanceNil() { 674 return 675 } 676 f = decNegintPosintFloatNumberHelper{&d.d}.float64(d.decFloat()) 677 d.bdRead = false 678 return 679 } 680 681 func (d *bincDecDriver) DecodeBool() (b bool) { 682 if d.advanceNil() { 683 return 684 } 685 if d.bd == (bincVdSpecial | bincSpFalse) { 686 // b = false 687 } else if d.bd == (bincVdSpecial | bincSpTrue) { 688 b = true 689 } else { 690 d.d.errorf("bool - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs)) 691 } 692 d.bdRead = false 693 return 694 } 695 696 func (d *bincDecDriver) ReadMapStart() (length int) { 697 if d.advanceNil() { 698 return containerLenNil 699 } 700 if d.vd != bincVdMap { 701 d.d.errorf("map - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs)) 702 } 703 length = d.decLen() 704 d.bdRead = false 705 return 706 } 707 708 func (d *bincDecDriver) ReadArrayStart() (length int) { 709 if d.advanceNil() { 710 return containerLenNil 711 } 712 if d.vd != bincVdArray { 713 d.d.errorf("array - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs)) 714 } 715 length = d.decLen() 716 d.bdRead = false 717 return 718 } 719 720 func (d *bincDecDriver) decLen() int { 721 if d.vs > 3 { 722 return int(d.vs - 4) 723 } 724 return int(d.decLenNumber()) 725 } 726 727 func (d *bincDecDriver) decLenNumber() (v uint64) { 728 if x := d.vs; x == 0 { 729 v = uint64(d.d.decRd.readn1()) 730 } else if x == 1 { 731 v = uint64(bigen.Uint16(d.d.decRd.readn2())) 732 } else if x == 2 { 733 v = uint64(bigen.Uint32(d.d.decRd.readn4())) 734 } else { 735 v = bigen.Uint64(d.d.decRd.readn8()) 736 } 737 return 738 } 739 740 // func (d *bincDecDriver) decStringBytes(bs []byte, zerocopy bool) (bs2 []byte) { 741 func (d *bincDecDriver) DecodeStringAsBytes() (bs2 []byte) { 742 d.d.decByteState = decByteStateNone 743 if d.advanceNil() { 744 return 745 } 746 var slen = -1 747 switch d.vd { 748 case bincVdString, bincVdByteArray: 749 slen = d.decLen() 750 if d.d.bytes { 751 d.d.decByteState = decByteStateZerocopy 752 bs2 = d.d.decRd.rb.readx(uint(slen)) 753 } else { 754 d.d.decByteState = decByteStateReuseBuf 755 bs2 = decByteSlice(d.d.r(), slen, d.d.h.MaxInitLen, d.d.b[:]) 756 } 757 case bincVdSymbol: 758 // zerocopy doesn't apply for symbols, 759 // as the values must be stored in a table for later use. 760 var symbol uint16 761 vs := d.vs 762 if vs&0x8 == 0 { 763 symbol = uint16(d.d.decRd.readn1()) 764 } else { 765 symbol = uint16(bigen.Uint16(d.d.decRd.readn2())) 766 } 767 if d.s == nil { 768 d.s = make(map[uint16][]byte, 16) 769 } 770 771 if vs&0x4 == 0 { 772 bs2 = d.s[symbol] 773 } else { 774 switch vs & 0x3 { 775 case 0: 776 slen = int(d.d.decRd.readn1()) 777 case 1: 778 slen = int(bigen.Uint16(d.d.decRd.readn2())) 779 case 2: 780 slen = int(bigen.Uint32(d.d.decRd.readn4())) 781 case 3: 782 slen = int(bigen.Uint64(d.d.decRd.readn8())) 783 } 784 // As we are using symbols, do not store any part of 785 // the parameter bs in the map, as it might be a shared buffer. 786 bs2 = decByteSlice(d.d.r(), slen, d.d.h.MaxInitLen, nil) 787 d.s[symbol] = bs2 788 } 789 default: 790 d.d.errorf("string/bytes - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs)) 791 } 792 d.bdRead = false 793 return 794 } 795 796 func (d *bincDecDriver) DecodeBytes(bs []byte) (bsOut []byte) { 797 d.d.decByteState = decByteStateNone 798 if d.advanceNil() { 799 return 800 } 801 if d.vd == bincVdArray { 802 if bs == nil { 803 bs = d.d.b[:] 804 d.d.decByteState = decByteStateReuseBuf 805 } 806 slen := d.ReadArrayStart() 807 var changed bool 808 if bs, changed = usableByteSlice(bs, slen); changed { 809 d.d.decByteState = decByteStateNone 810 } 811 for i := 0; i < slen; i++ { 812 bs[i] = uint8(chkOvf.UintV(d.DecodeUint64(), 8)) 813 } 814 return bs 815 } 816 var clen int 817 if d.vd == bincVdString || d.vd == bincVdByteArray { 818 clen = d.decLen() 819 } else { 820 d.d.errorf("bytes - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs)) 821 } 822 d.bdRead = false 823 if d.d.zerocopy() { 824 d.d.decByteState = decByteStateZerocopy 825 return d.d.decRd.rb.readx(uint(clen)) 826 } 827 if bs == nil { 828 bs = d.d.b[:] 829 d.d.decByteState = decByteStateReuseBuf 830 } 831 return decByteSlice(d.d.r(), clen, d.d.h.MaxInitLen, bs) 832 } 833 834 func (d *bincDecDriver) DecodeExt(rv interface{}, basetype reflect.Type, xtag uint64, ext Ext) { 835 if xtag > 0xff { 836 d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag) 837 } 838 if d.advanceNil() { 839 return 840 } 841 xbs, realxtag1, zerocopy := d.decodeExtV(ext != nil, uint8(xtag)) 842 realxtag := uint64(realxtag1) 843 if ext == nil { 844 re := rv.(*RawExt) 845 re.Tag = realxtag 846 re.setData(xbs, zerocopy) 847 } else if ext == SelfExt { 848 d.d.sideDecode(rv, basetype, xbs) 849 } else { 850 ext.ReadExt(rv, xbs) 851 } 852 } 853 854 func (d *bincDecDriver) decodeExtV(verifyTag bool, tag byte) (xbs []byte, xtag byte, zerocopy bool) { 855 if d.vd == bincVdCustomExt { 856 l := d.decLen() 857 xtag = d.d.decRd.readn1() 858 if verifyTag && xtag != tag { 859 d.d.errorf("wrong extension tag - got %b, expecting: %v", xtag, tag) 860 } 861 if d.d.bytes { 862 xbs = d.d.decRd.rb.readx(uint(l)) 863 zerocopy = true 864 } else { 865 xbs = decByteSlice(d.d.r(), l, d.d.h.MaxInitLen, d.d.b[:]) 866 } 867 } else if d.vd == bincVdByteArray { 868 xbs = d.DecodeBytes(nil) 869 } else { 870 d.d.errorf("ext expects extensions or byte array - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs)) 871 } 872 d.bdRead = false 873 return 874 } 875 876 func (d *bincDecDriver) DecodeNaked() { 877 if !d.bdRead { 878 d.readNextBd() 879 } 880 881 n := d.d.naked() 882 var decodeFurther bool 883 884 switch d.vd { 885 case bincVdSpecial: 886 switch d.vs { 887 case bincSpNil: 888 n.v = valueTypeNil 889 case bincSpFalse: 890 n.v = valueTypeBool 891 n.b = false 892 case bincSpTrue: 893 n.v = valueTypeBool 894 n.b = true 895 case bincSpNan: 896 n.v = valueTypeFloat 897 n.f = math.NaN() 898 case bincSpPosInf: 899 n.v = valueTypeFloat 900 n.f = math.Inf(1) 901 case bincSpNegInf: 902 n.v = valueTypeFloat 903 n.f = math.Inf(-1) 904 case bincSpZeroFloat: 905 n.v = valueTypeFloat 906 n.f = float64(0) 907 case bincSpZero: 908 n.v = valueTypeUint 909 n.u = uint64(0) // int8(0) 910 case bincSpNegOne: 911 n.v = valueTypeInt 912 n.i = int64(-1) // int8(-1) 913 default: 914 d.d.errorf("cannot infer value - unrecognized special value %x-%x/%s", d.vd, d.vs, bincdesc(d.vd, d.vs)) 915 } 916 case bincVdSmallInt: 917 n.v = valueTypeUint 918 n.u = uint64(int8(d.vs)) + 1 // int8(d.vs) + 1 919 case bincVdPosInt: 920 n.v = valueTypeUint 921 n.u = d.decUint() 922 case bincVdNegInt: 923 n.v = valueTypeInt 924 n.i = -(int64(d.decUint())) 925 case bincVdFloat: 926 n.v = valueTypeFloat 927 n.f = d.decFloatVal() 928 case bincVdString: 929 n.v = valueTypeString 930 n.s = d.d.stringZC(d.DecodeStringAsBytes()) 931 case bincVdByteArray: 932 d.d.fauxUnionReadRawBytes(false) 933 case bincVdSymbol: 934 n.v = valueTypeSymbol 935 n.s = d.d.stringZC(d.DecodeStringAsBytes()) 936 case bincVdTimestamp: 937 n.v = valueTypeTime 938 tt, err := bincDecodeTime(d.d.decRd.readx(uint(d.vs))) 939 halt.onerror(err) 940 n.t = tt 941 case bincVdCustomExt: 942 n.v = valueTypeExt 943 l := d.decLen() 944 n.u = uint64(d.d.decRd.readn1()) 945 if d.d.bytes { 946 n.l = d.d.decRd.rb.readx(uint(l)) 947 } else { 948 n.l = decByteSlice(d.d.r(), l, d.d.h.MaxInitLen, d.d.b[:]) 949 } 950 case bincVdArray: 951 n.v = valueTypeArray 952 decodeFurther = true 953 case bincVdMap: 954 n.v = valueTypeMap 955 decodeFurther = true 956 default: 957 d.d.errorf("cannot infer value - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs)) 958 } 959 960 if !decodeFurther { 961 d.bdRead = false 962 } 963 if n.v == valueTypeUint && d.h.SignedInteger { 964 n.v = valueTypeInt 965 n.i = int64(n.u) 966 } 967 } 968 969 func (d *bincDecDriver) nextValueBytes(v0 []byte) (v []byte) { 970 if !d.bdRead { 971 d.readNextBd() 972 } 973 v = v0 974 var h = decNextValueBytesHelper{d: &d.d} 975 var cursor = d.d.rb.c - 1 976 h.append1(&v, d.bd) 977 v = d.nextValueBytesBdReadR(v) 978 d.bdRead = false 979 h.bytesRdV(&v, cursor) 980 return 981 } 982 983 func (d *bincDecDriver) nextValueBytesR(v0 []byte) (v []byte) { 984 d.readNextBd() 985 v = v0 986 var h = decNextValueBytesHelper{d: &d.d} 987 h.append1(&v, d.bd) 988 return d.nextValueBytesBdReadR(v) 989 } 990 991 func (d *bincDecDriver) nextValueBytesBdReadR(v0 []byte) (v []byte) { 992 v = v0 993 var h = decNextValueBytesHelper{d: &d.d} 994 995 fnLen := func(vs byte) uint { 996 switch vs { 997 case 0: 998 x := d.d.decRd.readn1() 999 h.append1(&v, x) 1000 return uint(x) 1001 case 1: 1002 x := d.d.decRd.readn2() 1003 h.appendN(&v, x[:]...) 1004 return uint(bigen.Uint16(x)) 1005 case 2: 1006 x := d.d.decRd.readn4() 1007 h.appendN(&v, x[:]...) 1008 return uint(bigen.Uint32(x)) 1009 case 3: 1010 x := d.d.decRd.readn8() 1011 h.appendN(&v, x[:]...) 1012 return uint(bigen.Uint64(x)) 1013 default: 1014 return uint(vs - 4) 1015 } 1016 } 1017 1018 var clen uint 1019 1020 switch d.vd { 1021 case bincVdSpecial: 1022 switch d.vs { 1023 case bincSpNil, bincSpFalse, bincSpTrue, bincSpNan, bincSpPosInf: // pass 1024 case bincSpNegInf, bincSpZeroFloat, bincSpZero, bincSpNegOne: // pass 1025 default: 1026 d.d.errorf("cannot infer value - unrecognized special value %x-%x/%s", d.vd, d.vs, bincdesc(d.vd, d.vs)) 1027 } 1028 case bincVdSmallInt: // pass 1029 case bincVdPosInt, bincVdNegInt: 1030 bs := d.uintBytes() 1031 h.appendN(&v, bs...) 1032 case bincVdFloat: 1033 fn := func(xlen byte) { 1034 if d.vs&0x8 != 0 { 1035 xlen = d.d.decRd.readn1() 1036 h.append1(&v, xlen) 1037 if xlen > 8 { 1038 d.d.errorf("cannot read float - at most 8 bytes used to represent float - received %v bytes", xlen) 1039 } 1040 } 1041 d.d.decRd.readb(d.d.b[:xlen]) 1042 h.appendN(&v, d.d.b[:xlen]...) 1043 } 1044 switch d.vs & 0x7 { 1045 case bincFlBin32: 1046 fn(4) 1047 case bincFlBin64: 1048 fn(8) 1049 default: 1050 d.d.errorf("read float supports only float32/64 - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs)) 1051 } 1052 case bincVdString, bincVdByteArray: 1053 clen = fnLen(d.vs) 1054 h.appendN(&v, d.d.decRd.readx(clen)...) 1055 case bincVdSymbol: 1056 if d.vs&0x8 == 0 { 1057 h.append1(&v, d.d.decRd.readn1()) 1058 } else { 1059 h.appendN(&v, d.d.decRd.rb.readx(2)...) 1060 } 1061 if d.vs&0x4 != 0 { 1062 clen = fnLen(d.vs & 0x3) 1063 h.appendN(&v, d.d.decRd.readx(clen)...) 1064 } 1065 case bincVdTimestamp: 1066 h.appendN(&v, d.d.decRd.readx(uint(d.vs))...) 1067 case bincVdCustomExt: 1068 clen = fnLen(d.vs) 1069 h.append1(&v, d.d.decRd.readn1()) // tag 1070 h.appendN(&v, d.d.decRd.readx(clen)...) 1071 case bincVdArray: 1072 clen = fnLen(d.vs) 1073 for i := uint(0); i < clen; i++ { 1074 v = d.nextValueBytesR(v) 1075 } 1076 case bincVdMap: 1077 clen = fnLen(d.vs) 1078 for i := uint(0); i < clen; i++ { 1079 v = d.nextValueBytesR(v) 1080 v = d.nextValueBytesR(v) 1081 } 1082 default: 1083 d.d.errorf("cannot infer value - %s %x-%x/%s", msgBadDesc, d.vd, d.vs, bincdesc(d.vd, d.vs)) 1084 } 1085 return 1086 } 1087 1088 //------------------------------------ 1089 1090 //BincHandle is a Handle for the Binc Schema-Free Encoding Format 1091 //defined at https://github.com/ugorji/binc . 1092 // 1093 //BincHandle currently supports all Binc features with the following EXCEPTIONS: 1094 // - only integers up to 64 bits of precision are supported. 1095 // big integers are unsupported. 1096 // - Only IEEE 754 binary32 and binary64 floats are supported (ie Go float32 and float64 types). 1097 // extended precision and decimal IEEE 754 floats are unsupported. 1098 // - Only UTF-8 strings supported. 1099 // Unicode_Other Binc types (UTF16, UTF32) are currently unsupported. 1100 // 1101 //Note that these EXCEPTIONS are temporary and full support is possible and may happen soon. 1102 type BincHandle struct { 1103 BasicHandle 1104 binaryEncodingType 1105 // noElemSeparators 1106 1107 // AsSymbols defines what should be encoded as symbols. 1108 // 1109 // Encoding as symbols can reduce the encoded size significantly. 1110 // 1111 // However, during decoding, each string to be encoded as a symbol must 1112 // be checked to see if it has been seen before. Consequently, encoding time 1113 // will increase if using symbols, because string comparisons has a clear cost. 1114 // 1115 // Values: 1116 // - 0: default: library uses best judgement 1117 // - 1: use symbols 1118 // - 2: do not use symbols 1119 AsSymbols uint8 1120 1121 // AsSymbols: may later on introduce more options ... 1122 // - m: map keys 1123 // - s: struct fields 1124 // - n: none 1125 // - a: all: same as m, s, ... 1126 1127 // _ [7]uint64 // padding (cache-aligned) 1128 } 1129 1130 // Name returns the name of the handle: binc 1131 func (h *BincHandle) Name() string { return "binc" } 1132 1133 func (h *BincHandle) desc(bd byte) string { return bincdesc(bd>>4, bd&0x0f) } 1134 1135 func (h *BincHandle) newEncDriver() encDriver { 1136 var e = &bincEncDriver{h: h} 1137 e.e.e = e 1138 e.e.init(h) 1139 e.reset() 1140 return e 1141 } 1142 1143 func (h *BincHandle) newDecDriver() decDriver { 1144 d := &bincDecDriver{h: h} 1145 d.d.d = d 1146 d.d.init(h) 1147 d.reset() 1148 return d 1149 } 1150 1151 // var timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'} 1152 1153 // EncodeTime encodes a time.Time as a []byte, including 1154 // information on the instant in time and UTC offset. 1155 // 1156 // Format Description 1157 // 1158 // A timestamp is composed of 3 components: 1159 // 1160 // - secs: signed integer representing seconds since unix epoch 1161 // - nsces: unsigned integer representing fractional seconds as a 1162 // nanosecond offset within secs, in the range 0 <= nsecs < 1e9 1163 // - tz: signed integer representing timezone offset in minutes east of UTC, 1164 // and a dst (daylight savings time) flag 1165 // 1166 // When encoding a timestamp, the first byte is the descriptor, which 1167 // defines which components are encoded and how many bytes are used to 1168 // encode secs and nsecs components. *If secs/nsecs is 0 or tz is UTC, it 1169 // is not encoded in the byte array explicitly*. 1170 // 1171 // Descriptor 8 bits are of the form `A B C DDD EE`: 1172 // A: Is secs component encoded? 1 = true 1173 // B: Is nsecs component encoded? 1 = true 1174 // C: Is tz component encoded? 1 = true 1175 // DDD: Number of extra bytes for secs (range 0-7). 1176 // If A = 1, secs encoded in DDD+1 bytes. 1177 // If A = 0, secs is not encoded, and is assumed to be 0. 1178 // If A = 1, then we need at least 1 byte to encode secs. 1179 // DDD says the number of extra bytes beyond that 1. 1180 // E.g. if DDD=0, then secs is represented in 1 byte. 1181 // if DDD=2, then secs is represented in 3 bytes. 1182 // EE: Number of extra bytes for nsecs (range 0-3). 1183 // If B = 1, nsecs encoded in EE+1 bytes (similar to secs/DDD above) 1184 // 1185 // Following the descriptor bytes, subsequent bytes are: 1186 // 1187 // secs component encoded in `DDD + 1` bytes (if A == 1) 1188 // nsecs component encoded in `EE + 1` bytes (if B == 1) 1189 // tz component encoded in 2 bytes (if C == 1) 1190 // 1191 // secs and nsecs components are integers encoded in a BigEndian 1192 // 2-complement encoding format. 1193 // 1194 // tz component is encoded as 2 bytes (16 bits). Most significant bit 15 to 1195 // Least significant bit 0 are described below: 1196 // 1197 // Timezone offset has a range of -12:00 to +14:00 (ie -720 to +840 minutes). 1198 // Bit 15 = have\_dst: set to 1 if we set the dst flag. 1199 // Bit 14 = dst\_on: set to 1 if dst is in effect at the time, or 0 if not. 1200 // Bits 13..0 = timezone offset in minutes. It is a signed integer in Big Endian format. 1201 // 1202 func bincEncodeTime(t time.Time) []byte { 1203 // t := rv2i(rv).(time.Time) 1204 tsecs, tnsecs := t.Unix(), t.Nanosecond() 1205 var ( 1206 bd byte 1207 bs [16]byte 1208 i int = 1 1209 ) 1210 l := t.Location() 1211 if l == time.UTC { 1212 l = nil 1213 } 1214 if tsecs != 0 { 1215 bd = bd | 0x80 1216 btmp := bigen.PutUint64(uint64(tsecs)) 1217 f := pruneSignExt(btmp[:], tsecs >= 0) 1218 bd = bd | (byte(7-f) << 2) 1219 copy(bs[i:], btmp[f:]) 1220 i = i + (8 - f) 1221 } 1222 if tnsecs != 0 { 1223 bd = bd | 0x40 1224 btmp := bigen.PutUint32(uint32(tnsecs)) 1225 f := pruneSignExt(btmp[:4], true) 1226 bd = bd | byte(3-f) 1227 copy(bs[i:], btmp[f:4]) 1228 i = i + (4 - f) 1229 } 1230 if l != nil { 1231 bd = bd | 0x20 1232 // Note that Go Libs do not give access to dst flag. 1233 _, zoneOffset := t.Zone() 1234 // zoneName, zoneOffset := t.Zone() 1235 zoneOffset /= 60 1236 z := uint16(zoneOffset) 1237 btmp := bigen.PutUint16(z) 1238 // clear dst flags 1239 bs[i] = btmp[0] & 0x3f 1240 bs[i+1] = btmp[1] 1241 i = i + 2 1242 } 1243 bs[0] = bd 1244 return bs[0:i] 1245 } 1246 1247 // bincDecodeTime decodes a []byte into a time.Time. 1248 func bincDecodeTime(bs []byte) (tt time.Time, err error) { 1249 bd := bs[0] 1250 var ( 1251 tsec int64 1252 tnsec uint32 1253 tz uint16 1254 i byte = 1 1255 i2 byte 1256 n byte 1257 ) 1258 if bd&(1<<7) != 0 { 1259 var btmp [8]byte 1260 n = ((bd >> 2) & 0x7) + 1 1261 i2 = i + n 1262 copy(btmp[8-n:], bs[i:i2]) 1263 // if first bit of bs[i] is set, then fill btmp[0..8-n] with 0xff (ie sign extend it) 1264 if bs[i]&(1<<7) != 0 { 1265 copy(btmp[0:8-n], bsAll0xff) 1266 } 1267 i = i2 1268 tsec = int64(bigen.Uint64(btmp)) 1269 } 1270 if bd&(1<<6) != 0 { 1271 var btmp [4]byte 1272 n = (bd & 0x3) + 1 1273 i2 = i + n 1274 copy(btmp[4-n:], bs[i:i2]) 1275 i = i2 1276 tnsec = bigen.Uint32(btmp) 1277 } 1278 if bd&(1<<5) == 0 { 1279 tt = time.Unix(tsec, int64(tnsec)).UTC() 1280 return 1281 } 1282 // In stdlib time.Parse, when a date is parsed without a zone name, it uses "" as zone name. 1283 // However, we need name here, so it can be shown when time is printf.d. 1284 // Zone name is in form: UTC-08:00. 1285 // Note that Go Libs do not give access to dst flag, so we ignore dst bits 1286 1287 tz = bigen.Uint16([2]byte{bs[i], bs[i+1]}) 1288 // sign extend sign bit into top 2 MSB (which were dst bits): 1289 if tz&(1<<13) == 0 { // positive 1290 tz = tz & 0x3fff //clear 2 MSBs: dst bits 1291 } else { // negative 1292 tz = tz | 0xc000 //set 2 MSBs: dst bits 1293 } 1294 tzint := int16(tz) 1295 if tzint == 0 { 1296 tt = time.Unix(tsec, int64(tnsec)).UTC() 1297 } else { 1298 // For Go Time, do not use a descriptive timezone. 1299 // It's unnecessary, and makes it harder to do a reflect.DeepEqual. 1300 // The Offset already tells what the offset should be, if not on UTC and unknown zone name. 1301 // var zoneName = timeLocUTCName(tzint) 1302 tt = time.Unix(tsec, int64(tnsec)).In(time.FixedZone("", int(tzint)*60)) 1303 } 1304 return 1305 } 1306 1307 var _ decDriver = (*bincDecDriver)(nil) 1308 var _ encDriver = (*bincEncDriver)(nil)