1// 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 _ uint8 = iota 14 simpleVdNil = 1 15 simpleVdFalse = 2 16 simpleVdTrue = 3 17 simpleVdFloat32 = 4 18 simpleVdFloat64 = 5 19 20 // each lasts for 4 (ie n, n+1, n+2, n+3) 21 simpleVdPosInt = 8 22 simpleVdNegInt = 12 23 24 simpleVdTime = 24 25 26 // containers: each lasts for 4 (ie n, n+1, n+2, ... n+7) 27 simpleVdString = 216 28 simpleVdByteArray = 224 29 simpleVdArray = 232 30 simpleVdMap = 240 31 simpleVdExt = 248 32) 33 34type simpleEncDriver struct { 35 noBuiltInTypes 36 // encNoSeparator 37 e *Encoder 38 h *SimpleHandle 39 w *encWriterSwitch 40 b [8]byte 41 // c containerState 42 encDriverTrackContainerWriter 43 // encDriverNoopContainerWriter 44 _ [3]uint64 // padding 45} 46 47func (e *simpleEncDriver) EncodeNil() { 48 e.w.writen1(simpleVdNil) 49} 50 51func (e *simpleEncDriver) EncodeBool(b bool) { 52 if e.h.EncZeroValuesAsNil && e.c != containerMapKey && !b { 53 e.EncodeNil() 54 return 55 } 56 if b { 57 e.w.writen1(simpleVdTrue) 58 } else { 59 e.w.writen1(simpleVdFalse) 60 } 61} 62 63func (e *simpleEncDriver) EncodeFloat32(f float32) { 64 if e.h.EncZeroValuesAsNil && e.c != containerMapKey && f == 0.0 { 65 e.EncodeNil() 66 return 67 } 68 e.w.writen1(simpleVdFloat32) 69 bigenHelper{e.b[:4], e.w}.writeUint32(math.Float32bits(f)) 70} 71 72func (e *simpleEncDriver) EncodeFloat64(f float64) { 73 if e.h.EncZeroValuesAsNil && e.c != containerMapKey && f == 0.0 { 74 e.EncodeNil() 75 return 76 } 77 e.w.writen1(simpleVdFloat64) 78 bigenHelper{e.b[:8], e.w}.writeUint64(math.Float64bits(f)) 79} 80 81func (e *simpleEncDriver) EncodeInt(v int64) { 82 if v < 0 { 83 e.encUint(uint64(-v), simpleVdNegInt) 84 } else { 85 e.encUint(uint64(v), simpleVdPosInt) 86 } 87} 88 89func (e *simpleEncDriver) EncodeUint(v uint64) { 90 e.encUint(v, simpleVdPosInt) 91} 92 93func (e *simpleEncDriver) encUint(v uint64, bd uint8) { 94 if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == 0 { 95 e.EncodeNil() 96 return 97 } 98 if v <= math.MaxUint8 { 99 e.w.writen2(bd, uint8(v)) 100 } else if v <= math.MaxUint16 { 101 e.w.writen1(bd + 1) 102 bigenHelper{e.b[:2], e.w}.writeUint16(uint16(v)) 103 } else if v <= math.MaxUint32 { 104 e.w.writen1(bd + 2) 105 bigenHelper{e.b[:4], e.w}.writeUint32(uint32(v)) 106 } else { // if v <= math.MaxUint64 { 107 e.w.writen1(bd + 3) 108 bigenHelper{e.b[:8], e.w}.writeUint64(v) 109 } 110} 111 112func (e *simpleEncDriver) encLen(bd byte, length int) { 113 if length == 0 { 114 e.w.writen1(bd) 115 } else if length <= math.MaxUint8 { 116 e.w.writen1(bd + 1) 117 e.w.writen1(uint8(length)) 118 } else if length <= math.MaxUint16 { 119 e.w.writen1(bd + 2) 120 bigenHelper{e.b[:2], e.w}.writeUint16(uint16(length)) 121 } else if int64(length) <= math.MaxUint32 { 122 e.w.writen1(bd + 3) 123 bigenHelper{e.b[:4], e.w}.writeUint32(uint32(length)) 124 } else { 125 e.w.writen1(bd + 4) 126 bigenHelper{e.b[:8], e.w}.writeUint64(uint64(length)) 127 } 128} 129 130func (e *simpleEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, _ *Encoder) { 131 bs := ext.WriteExt(rv) 132 if bs == nil { 133 e.EncodeNil() 134 return 135 } 136 e.encodeExtPreamble(uint8(xtag), len(bs)) 137 e.w.writeb(bs) 138} 139 140func (e *simpleEncDriver) EncodeRawExt(re *RawExt, _ *Encoder) { 141 e.encodeExtPreamble(uint8(re.Tag), len(re.Data)) 142 e.w.writeb(re.Data) 143} 144 145func (e *simpleEncDriver) encodeExtPreamble(xtag byte, length int) { 146 e.encLen(simpleVdExt, length) 147 e.w.writen1(xtag) 148} 149 150func (e *simpleEncDriver) WriteArrayStart(length int) { 151 e.c = containerArrayStart 152 e.encLen(simpleVdArray, length) 153} 154 155func (e *simpleEncDriver) WriteMapStart(length int) { 156 e.c = containerMapStart 157 e.encLen(simpleVdMap, length) 158} 159 160// func (e *simpleEncDriver) EncodeSymbol(v string) { 161// e.EncodeStringEnc(cUTF8, v) 162// } 163 164func (e *simpleEncDriver) EncodeStringEnc(c charEncoding, v string) { 165 if false && e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == "" { 166 e.EncodeNil() 167 return 168 } 169 e.encLen(simpleVdString, len(v)) 170 e.w.writestr(v) 171} 172 173func (e *simpleEncDriver) EncodeString(c charEncoding, v string) { 174 e.EncodeStringEnc(c, v) 175} 176 177func (e *simpleEncDriver) EncodeStringBytes(c charEncoding, v []byte) { 178 e.EncodeStringBytesRaw(v) 179} 180 181func (e *simpleEncDriver) EncodeStringBytesRaw(v []byte) { 182 // if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == nil { 183 if v == nil { 184 e.EncodeNil() 185 return 186 } 187 e.encLen(simpleVdByteArray, len(v)) 188 e.w.writeb(v) 189} 190 191func (e *simpleEncDriver) EncodeTime(t time.Time) { 192 // if e.h.EncZeroValuesAsNil && e.c != containerMapKey && t.IsZero() { 193 if t.IsZero() { 194 e.EncodeNil() 195 return 196 } 197 v, err := t.MarshalBinary() 198 if err != nil { 199 e.e.errorv(err) 200 return 201 } 202 // time.Time marshalbinary takes about 14 bytes. 203 e.w.writen2(simpleVdTime, uint8(len(v))) 204 e.w.writeb(v) 205} 206 207//------------------------------------ 208 209type simpleDecDriver struct { 210 d *Decoder 211 h *SimpleHandle 212 r *decReaderSwitch 213 bdRead bool 214 bd byte 215 br bool // a bytes reader? 216 c containerState 217 // b [scratchByteArrayLen]byte 218 noBuiltInTypes 219 // noStreamingCodec 220 decDriverNoopContainerReader 221 // _ [3]uint64 // padding 222} 223 224func (d *simpleDecDriver) readNextBd() { 225 d.bd = d.r.readn1() 226 d.bdRead = true 227} 228 229func (d *simpleDecDriver) uncacheRead() { 230 if d.bdRead { 231 d.r.unreadn1() 232 d.bdRead = false 233 } 234} 235 236func (d *simpleDecDriver) ContainerType() (vt valueType) { 237 if !d.bdRead { 238 d.readNextBd() 239 } 240 switch d.bd { 241 case simpleVdNil: 242 return valueTypeNil 243 case simpleVdByteArray, simpleVdByteArray + 1, 244 simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4: 245 return valueTypeBytes 246 case simpleVdString, simpleVdString + 1, 247 simpleVdString + 2, simpleVdString + 3, simpleVdString + 4: 248 return valueTypeString 249 case simpleVdArray, simpleVdArray + 1, 250 simpleVdArray + 2, simpleVdArray + 3, simpleVdArray + 4: 251 return valueTypeArray 252 case simpleVdMap, simpleVdMap + 1, 253 simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4: 254 return valueTypeMap 255 // case simpleVdTime: 256 // return valueTypeTime 257 } 258 // else { 259 // d.d.errorf("isContainerType: unsupported parameter: %v", vt) 260 // } 261 return valueTypeUnset 262} 263 264func (d *simpleDecDriver) TryDecodeAsNil() bool { 265 if !d.bdRead { 266 d.readNextBd() 267 } 268 if d.bd == simpleVdNil { 269 d.bdRead = false 270 return true 271 } 272 return false 273} 274 275func (d *simpleDecDriver) decCheckInteger() (ui uint64, neg bool) { 276 if !d.bdRead { 277 d.readNextBd() 278 } 279 switch d.bd { 280 case simpleVdPosInt: 281 ui = uint64(d.r.readn1()) 282 case simpleVdPosInt + 1: 283 ui = uint64(bigen.Uint16(d.r.readx(2))) 284 case simpleVdPosInt + 2: 285 ui = uint64(bigen.Uint32(d.r.readx(4))) 286 case simpleVdPosInt + 3: 287 ui = uint64(bigen.Uint64(d.r.readx(8))) 288 case simpleVdNegInt: 289 ui = uint64(d.r.readn1()) 290 neg = true 291 case simpleVdNegInt + 1: 292 ui = uint64(bigen.Uint16(d.r.readx(2))) 293 neg = true 294 case simpleVdNegInt + 2: 295 ui = uint64(bigen.Uint32(d.r.readx(4))) 296 neg = true 297 case simpleVdNegInt + 3: 298 ui = uint64(bigen.Uint64(d.r.readx(8))) 299 neg = true 300 default: 301 d.d.errorf("integer only valid from pos/neg integer1..8. Invalid descriptor: %v", d.bd) 302 return 303 } 304 // don't do this check, because callers may only want the unsigned value. 305 // if ui > math.MaxInt64 { 306 // d.d.errorf("decIntAny: Integer out of range for signed int64: %v", ui) 307 // return 308 // } 309 return 310} 311 312func (d *simpleDecDriver) DecodeInt64() (i int64) { 313 ui, neg := d.decCheckInteger() 314 i = chkOvf.SignedIntV(ui) 315 if neg { 316 i = -i 317 } 318 d.bdRead = false 319 return 320} 321 322func (d *simpleDecDriver) DecodeUint64() (ui uint64) { 323 ui, neg := d.decCheckInteger() 324 if neg { 325 d.d.errorf("assigning negative signed value to unsigned type") 326 return 327 } 328 d.bdRead = false 329 return 330} 331 332func (d *simpleDecDriver) DecodeFloat64() (f float64) { 333 if !d.bdRead { 334 d.readNextBd() 335 } 336 if d.bd == simpleVdFloat32 { 337 f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4)))) 338 } else if d.bd == simpleVdFloat64 { 339 f = math.Float64frombits(bigen.Uint64(d.r.readx(8))) 340 } else { 341 if d.bd >= simpleVdPosInt && d.bd <= simpleVdNegInt+3 { 342 f = float64(d.DecodeInt64()) 343 } else { 344 d.d.errorf("float only valid from float32/64: Invalid descriptor: %v", d.bd) 345 return 346 } 347 } 348 d.bdRead = false 349 return 350} 351 352// bool can be decoded from bool only (single byte). 353func (d *simpleDecDriver) DecodeBool() (b bool) { 354 if !d.bdRead { 355 d.readNextBd() 356 } 357 if d.bd == simpleVdTrue { 358 b = true 359 } else if d.bd == simpleVdFalse { 360 } else { 361 d.d.errorf("cannot decode bool - %s: %x", msgBadDesc, d.bd) 362 return 363 } 364 d.bdRead = false 365 return 366} 367 368func (d *simpleDecDriver) ReadMapStart() (length int) { 369 if !d.bdRead { 370 d.readNextBd() 371 } 372 d.bdRead = false 373 d.c = containerMapStart 374 return d.decLen() 375} 376 377func (d *simpleDecDriver) ReadArrayStart() (length int) { 378 if !d.bdRead { 379 d.readNextBd() 380 } 381 d.bdRead = false 382 d.c = containerArrayStart 383 return d.decLen() 384} 385 386func (d *simpleDecDriver) ReadArrayElem() { 387 d.c = containerArrayElem 388} 389 390func (d *simpleDecDriver) ReadArrayEnd() { 391 d.c = containerArrayEnd 392} 393 394func (d *simpleDecDriver) ReadMapElemKey() { 395 d.c = containerMapKey 396} 397 398func (d *simpleDecDriver) ReadMapElemValue() { 399 d.c = containerMapValue 400} 401 402func (d *simpleDecDriver) ReadMapEnd() { 403 d.c = containerMapEnd 404} 405 406func (d *simpleDecDriver) decLen() int { 407 switch d.bd % 8 { 408 case 0: 409 return 0 410 case 1: 411 return int(d.r.readn1()) 412 case 2: 413 return int(bigen.Uint16(d.r.readx(2))) 414 case 3: 415 ui := uint64(bigen.Uint32(d.r.readx(4))) 416 if chkOvf.Uint(ui, intBitsize) { 417 d.d.errorf("overflow integer: %v", ui) 418 return 0 419 } 420 return int(ui) 421 case 4: 422 ui := bigen.Uint64(d.r.readx(8)) 423 if chkOvf.Uint(ui, intBitsize) { 424 d.d.errorf("overflow integer: %v", ui) 425 return 0 426 } 427 return int(ui) 428 } 429 d.d.errorf("cannot read length: bd%%8 must be in range 0..4. Got: %d", d.bd%8) 430 return -1 431} 432 433func (d *simpleDecDriver) DecodeString() (s string) { 434 return string(d.DecodeBytes(d.d.b[:], true)) 435} 436 437func (d *simpleDecDriver) DecodeStringAsBytes() (s []byte) { 438 return d.DecodeBytes(d.d.b[:], true) 439} 440 441func (d *simpleDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) { 442 if !d.bdRead { 443 d.readNextBd() 444 } 445 if d.bd == simpleVdNil { 446 d.bdRead = false 447 return 448 } 449 // check if an "array" of uint8's (see ContainerType for how to infer if an array) 450 if d.bd >= simpleVdArray && d.bd <= simpleVdMap+4 { 451 if len(bs) == 0 && zerocopy { 452 bs = d.d.b[:] 453 } 454 bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d) 455 return 456 } 457 458 clen := d.decLen() 459 d.bdRead = false 460 if zerocopy { 461 if d.br { 462 return d.r.readx(uint(clen)) 463 } else if len(bs) == 0 { 464 bs = d.d.b[:] 465 } 466 } 467 return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs) 468} 469 470func (d *simpleDecDriver) DecodeTime() (t time.Time) { 471 if !d.bdRead { 472 d.readNextBd() 473 } 474 if d.bd == simpleVdNil { 475 d.bdRead = false 476 return 477 } 478 if d.bd != simpleVdTime { 479 d.d.errorf("invalid descriptor for time.Time - expect 0x%x, received 0x%x", simpleVdTime, d.bd) 480 return 481 } 482 d.bdRead = false 483 clen := int(d.r.readn1()) 484 b := d.r.readx(uint(clen)) 485 if err := (&t).UnmarshalBinary(b); err != nil { 486 d.d.errorv(err) 487 } 488 return 489} 490 491func (d *simpleDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) { 492 if xtag > 0xff { 493 d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag) 494 return 495 } 496 realxtag1, xbs := d.decodeExtV(ext != nil, uint8(xtag)) 497 realxtag = uint64(realxtag1) 498 if ext == nil { 499 re := rv.(*RawExt) 500 re.Tag = realxtag 501 re.Data = detachZeroCopyBytes(d.br, re.Data, xbs) 502 } else { 503 ext.ReadExt(rv, xbs) 504 } 505 return 506} 507 508func (d *simpleDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs []byte) { 509 if !d.bdRead { 510 d.readNextBd() 511 } 512 switch d.bd { 513 case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4: 514 l := d.decLen() 515 xtag = d.r.readn1() 516 if verifyTag && xtag != tag { 517 d.d.errorf("wrong extension tag. Got %b. Expecting: %v", xtag, tag) 518 return 519 } 520 if d.br { 521 xbs = d.r.readx(uint(l)) 522 } else { 523 xbs = decByteSlice(d.r, l, d.d.h.MaxInitLen, d.d.b[:]) 524 } 525 case simpleVdByteArray, simpleVdByteArray + 1, 526 simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4: 527 xbs = d.DecodeBytes(nil, true) 528 default: 529 d.d.errorf("ext - %s - expecting extensions/bytearray, got: 0x%x", msgBadDesc, d.bd) 530 return 531 } 532 d.bdRead = false 533 return 534} 535 536func (d *simpleDecDriver) DecodeNaked() { 537 if !d.bdRead { 538 d.readNextBd() 539 } 540 541 n := d.d.naked() 542 var decodeFurther bool 543 544 switch d.bd { 545 case simpleVdNil: 546 n.v = valueTypeNil 547 case simpleVdFalse: 548 n.v = valueTypeBool 549 n.b = false 550 case simpleVdTrue: 551 n.v = valueTypeBool 552 n.b = true 553 case simpleVdPosInt, simpleVdPosInt + 1, simpleVdPosInt + 2, simpleVdPosInt + 3: 554 if d.h.SignedInteger { 555 n.v = valueTypeInt 556 n.i = d.DecodeInt64() 557 } else { 558 n.v = valueTypeUint 559 n.u = d.DecodeUint64() 560 } 561 case simpleVdNegInt, simpleVdNegInt + 1, simpleVdNegInt + 2, simpleVdNegInt + 3: 562 n.v = valueTypeInt 563 n.i = d.DecodeInt64() 564 case simpleVdFloat32: 565 n.v = valueTypeFloat 566 n.f = d.DecodeFloat64() 567 case simpleVdFloat64: 568 n.v = valueTypeFloat 569 n.f = d.DecodeFloat64() 570 case simpleVdTime: 571 n.v = valueTypeTime 572 n.t = d.DecodeTime() 573 case simpleVdString, simpleVdString + 1, 574 simpleVdString + 2, simpleVdString + 3, simpleVdString + 4: 575 n.v = valueTypeString 576 n.s = d.DecodeString() 577 case simpleVdByteArray, simpleVdByteArray + 1, 578 simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4: 579 decNakedReadRawBytes(d, d.d, n, d.h.RawToString) 580 case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4: 581 n.v = valueTypeExt 582 l := d.decLen() 583 n.u = uint64(d.r.readn1()) 584 if d.br { 585 n.l = d.r.readx(uint(l)) 586 } else { 587 n.l = decByteSlice(d.r, l, d.d.h.MaxInitLen, d.d.b[:]) 588 } 589 case simpleVdArray, simpleVdArray + 1, simpleVdArray + 2, 590 simpleVdArray + 3, simpleVdArray + 4: 591 n.v = valueTypeArray 592 decodeFurther = true 593 case simpleVdMap, simpleVdMap + 1, simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4: 594 n.v = valueTypeMap 595 decodeFurther = true 596 default: 597 d.d.errorf("cannot infer value - %s 0x%x", msgBadDesc, d.bd) 598 } 599 600 if !decodeFurther { 601 d.bdRead = false 602 } 603} 604 605//------------------------------------ 606 607// SimpleHandle is a Handle for a very simple encoding format. 608// 609// simple is a simplistic codec similar to binc, but not as compact. 610// - Encoding of a value is always preceded by the descriptor byte (bd) 611// - True, false, nil are encoded fully in 1 byte (the descriptor) 612// - Integers (intXXX, uintXXX) are encoded in 1, 2, 4 or 8 bytes (plus a descriptor byte). 613// There are positive (uintXXX and intXXX >= 0) and negative (intXXX < 0) integers. 614// - Floats are encoded in 4 or 8 bytes (plus a descriptor byte) 615// - Length of containers (strings, bytes, array, map, extensions) 616// are encoded in 0, 1, 2, 4 or 8 bytes. 617// Zero-length containers have no length encoded. 618// For others, the number of bytes is given by pow(2, bd%3) 619// - maps are encoded as [bd] [length] [[key][value]]... 620// - arrays are encoded as [bd] [length] [value]... 621// - extensions are encoded as [bd] [length] [tag] [byte]... 622// - strings/bytearrays are encoded as [bd] [length] [byte]... 623// - time.Time are encoded as [bd] [length] [byte]... 624// 625// The full spec will be published soon. 626type SimpleHandle struct { 627 BasicHandle 628 binaryEncodingType 629 noElemSeparators 630 // EncZeroValuesAsNil says to encode zero values for numbers, bool, string, etc as nil 631 EncZeroValuesAsNil bool 632 633 // _ [1]uint64 // padding 634} 635 636// Name returns the name of the handle: simple 637func (h *SimpleHandle) Name() string { return "simple" } 638 639// SetBytesExt sets an extension 640func (h *SimpleHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) { 641 return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}}) 642} 643 644func (h *SimpleHandle) hasElemSeparators() bool { return true } // as it implements Write(Map|Array)XXX 645 646func (h *SimpleHandle) newEncDriver(e *Encoder) encDriver { 647 return &simpleEncDriver{e: e, w: e.w, h: h} 648} 649 650func (h *SimpleHandle) newDecDriver(d *Decoder) decDriver { 651 return &simpleDecDriver{d: d, h: h, r: d.r, br: d.bytes} 652} 653 654func (e *simpleEncDriver) reset() { 655 e.c = 0 656 e.w = e.e.w 657} 658 659func (d *simpleDecDriver) reset() { 660 d.c = 0 661 d.r, d.br = d.d.r, d.d.bytes 662 d.bd, d.bdRead = 0, false 663} 664 665var _ decDriver = (*simpleDecDriver)(nil) 666var _ encDriver = (*simpleEncDriver)(nil) 667