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 4/* 5MSGPACK 6 7Msgpack-c implementation powers the c, c++, python, ruby, etc libraries. 8We need to maintain compatibility with it and how it encodes integer values 9without caring about the type. 10 11For compatibility with behaviour of msgpack-c reference implementation: 12 - Go intX (>0) and uintX 13 IS ENCODED AS 14 msgpack +ve fixnum, unsigned 15 - Go intX (<0) 16 IS ENCODED AS 17 msgpack -ve fixnum, signed 18*/ 19 20package codec 21 22import ( 23 "fmt" 24 "io" 25 "math" 26 "net/rpc" 27 "reflect" 28 "time" 29) 30 31const ( 32 mpPosFixNumMin byte = 0x00 33 mpPosFixNumMax byte = 0x7f 34 mpFixMapMin byte = 0x80 35 mpFixMapMax byte = 0x8f 36 mpFixArrayMin byte = 0x90 37 mpFixArrayMax byte = 0x9f 38 mpFixStrMin byte = 0xa0 39 mpFixStrMax byte = 0xbf 40 mpNil byte = 0xc0 41 _ byte = 0xc1 42 mpFalse byte = 0xc2 43 mpTrue byte = 0xc3 44 mpFloat byte = 0xca 45 mpDouble byte = 0xcb 46 mpUint8 byte = 0xcc 47 mpUint16 byte = 0xcd 48 mpUint32 byte = 0xce 49 mpUint64 byte = 0xcf 50 mpInt8 byte = 0xd0 51 mpInt16 byte = 0xd1 52 mpInt32 byte = 0xd2 53 mpInt64 byte = 0xd3 54 55 // extensions below 56 mpBin8 byte = 0xc4 57 mpBin16 byte = 0xc5 58 mpBin32 byte = 0xc6 59 mpExt8 byte = 0xc7 60 mpExt16 byte = 0xc8 61 mpExt32 byte = 0xc9 62 mpFixExt1 byte = 0xd4 63 mpFixExt2 byte = 0xd5 64 mpFixExt4 byte = 0xd6 65 mpFixExt8 byte = 0xd7 66 mpFixExt16 byte = 0xd8 67 68 mpStr8 byte = 0xd9 // new 69 mpStr16 byte = 0xda 70 mpStr32 byte = 0xdb 71 72 mpArray16 byte = 0xdc 73 mpArray32 byte = 0xdd 74 75 mpMap16 byte = 0xde 76 mpMap32 byte = 0xdf 77 78 mpNegFixNumMin byte = 0xe0 79 mpNegFixNumMax byte = 0xff 80) 81 82var mpTimeExtTag int8 = -1 83var mpTimeExtTagU = uint8(mpTimeExtTag) 84 85// var mpdesc = map[byte]string{ 86// mpPosFixNumMin: "PosFixNumMin", 87// mpPosFixNumMax: "PosFixNumMax", 88// mpFixMapMin: "FixMapMin", 89// mpFixMapMax: "FixMapMax", 90// mpFixArrayMin: "FixArrayMin", 91// mpFixArrayMax: "FixArrayMax", 92// mpFixStrMin: "FixStrMin", 93// mpFixStrMax: "FixStrMax", 94// mpNil: "Nil", 95// mpFalse: "False", 96// mpTrue: "True", 97// mpFloat: "Float", 98// mpDouble: "Double", 99// mpUint8: "Uint8", 100// mpUint16: "Uint16", 101// mpUint32: "Uint32", 102// mpUint64: "Uint64", 103// mpInt8: "Int8", 104// mpInt16: "Int16", 105// mpInt32: "Int32", 106// mpInt64: "Int64", 107// mpBin8: "Bin8", 108// mpBin16: "Bin16", 109// mpBin32: "Bin32", 110// mpExt8: "Ext8", 111// mpExt16: "Ext16", 112// mpExt32: "Ext32", 113// mpFixExt1: "FixExt1", 114// mpFixExt2: "FixExt2", 115// mpFixExt4: "FixExt4", 116// mpFixExt8: "FixExt8", 117// mpFixExt16: "FixExt16", 118// mpStr8: "Str8", 119// mpStr16: "Str16", 120// mpStr32: "Str32", 121// mpArray16: "Array16", 122// mpArray32: "Array32", 123// mpMap16: "Map16", 124// mpMap32: "Map32", 125// mpNegFixNumMin: "NegFixNumMin", 126// mpNegFixNumMax: "NegFixNumMax", 127// } 128 129func mpdesc(bd byte) string { 130 switch bd { 131 case mpNil: 132 return "nil" 133 case mpFalse: 134 return "false" 135 case mpTrue: 136 return "true" 137 case mpFloat, mpDouble: 138 return "float" 139 case mpUint8, mpUint16, mpUint32, mpUint64: 140 return "uint" 141 case mpInt8, mpInt16, mpInt32, mpInt64: 142 return "int" 143 default: 144 switch { 145 case bd >= mpPosFixNumMin && bd <= mpPosFixNumMax: 146 return "int" 147 case bd >= mpNegFixNumMin && bd <= mpNegFixNumMax: 148 return "int" 149 case bd == mpStr8, bd == mpStr16, bd == mpStr32, bd >= mpFixStrMin && bd <= mpFixStrMax: 150 return "string|bytes" 151 case bd == mpBin8, bd == mpBin16, bd == mpBin32: 152 return "bytes" 153 case bd == mpArray16, bd == mpArray32, bd >= mpFixArrayMin && bd <= mpFixArrayMax: 154 return "array" 155 case bd == mpMap16, bd == mpMap32, bd >= mpFixMapMin && bd <= mpFixMapMax: 156 return "map" 157 case bd >= mpFixExt1 && bd <= mpFixExt16, bd >= mpExt8 && bd <= mpExt32: 158 return "ext" 159 default: 160 return "unknown" 161 } 162 } 163} 164 165// MsgpackSpecRpcMultiArgs is a special type which signifies to the MsgpackSpecRpcCodec 166// that the backend RPC service takes multiple arguments, which have been arranged 167// in sequence in the slice. 168// 169// The Codec then passes it AS-IS to the rpc service (without wrapping it in an 170// array of 1 element). 171type MsgpackSpecRpcMultiArgs []interface{} 172 173// A MsgpackContainer type specifies the different types of msgpackContainers. 174type msgpackContainerType struct { 175 fixCutoff int 176 bFixMin, b8, b16, b32 byte 177 hasFixMin, has8, has8Always bool 178} 179 180var ( 181 msgpackContainerStr = msgpackContainerType{ 182 32, mpFixStrMin, mpStr8, mpStr16, mpStr32, true, true, false, 183 } 184 msgpackContainerBin = msgpackContainerType{ 185 0, 0, mpBin8, mpBin16, mpBin32, false, true, true, 186 } 187 msgpackContainerList = msgpackContainerType{ 188 16, mpFixArrayMin, 0, mpArray16, mpArray32, true, false, false, 189 } 190 msgpackContainerMap = msgpackContainerType{ 191 16, mpFixMapMin, 0, mpMap16, mpMap32, true, false, false, 192 } 193) 194 195//--------------------------------------------- 196 197type msgpackEncDriver struct { 198 noBuiltInTypes 199 encDriverNoopContainerWriter 200 // encNoSeparator 201 e *Encoder 202 w *encWriterSwitch 203 h *MsgpackHandle 204 x [8]byte 205 // _ [3]uint64 // padding 206} 207 208func (e *msgpackEncDriver) EncodeNil() { 209 e.w.writen1(mpNil) 210} 211 212func (e *msgpackEncDriver) EncodeInt(i int64) { 213 if e.h.PositiveIntUnsigned && i >= 0 { 214 e.EncodeUint(uint64(i)) 215 } else if i > math.MaxInt8 { 216 if i <= math.MaxInt16 { 217 e.w.writen1(mpInt16) 218 bigenHelper{e.x[:2], e.w}.writeUint16(uint16(i)) 219 } else if i <= math.MaxInt32 { 220 e.w.writen1(mpInt32) 221 bigenHelper{e.x[:4], e.w}.writeUint32(uint32(i)) 222 } else { 223 e.w.writen1(mpInt64) 224 bigenHelper{e.x[:8], e.w}.writeUint64(uint64(i)) 225 } 226 } else if i >= -32 { 227 if e.h.NoFixedNum { 228 e.w.writen2(mpInt8, byte(i)) 229 } else { 230 e.w.writen1(byte(i)) 231 } 232 } else if i >= math.MinInt8 { 233 e.w.writen2(mpInt8, byte(i)) 234 } else if i >= math.MinInt16 { 235 e.w.writen1(mpInt16) 236 bigenHelper{e.x[:2], e.w}.writeUint16(uint16(i)) 237 } else if i >= math.MinInt32 { 238 e.w.writen1(mpInt32) 239 bigenHelper{e.x[:4], e.w}.writeUint32(uint32(i)) 240 } else { 241 e.w.writen1(mpInt64) 242 bigenHelper{e.x[:8], e.w}.writeUint64(uint64(i)) 243 } 244} 245 246func (e *msgpackEncDriver) EncodeUint(i uint64) { 247 if i <= math.MaxInt8 { 248 if e.h.NoFixedNum { 249 e.w.writen2(mpUint8, byte(i)) 250 } else { 251 e.w.writen1(byte(i)) 252 } 253 } else if i <= math.MaxUint8 { 254 e.w.writen2(mpUint8, byte(i)) 255 } else if i <= math.MaxUint16 { 256 e.w.writen1(mpUint16) 257 bigenHelper{e.x[:2], e.w}.writeUint16(uint16(i)) 258 } else if i <= math.MaxUint32 { 259 e.w.writen1(mpUint32) 260 bigenHelper{e.x[:4], e.w}.writeUint32(uint32(i)) 261 } else { 262 e.w.writen1(mpUint64) 263 bigenHelper{e.x[:8], e.w}.writeUint64(uint64(i)) 264 } 265} 266 267func (e *msgpackEncDriver) EncodeBool(b bool) { 268 if b { 269 e.w.writen1(mpTrue) 270 } else { 271 e.w.writen1(mpFalse) 272 } 273} 274 275func (e *msgpackEncDriver) EncodeFloat32(f float32) { 276 e.w.writen1(mpFloat) 277 bigenHelper{e.x[:4], e.w}.writeUint32(math.Float32bits(f)) 278} 279 280func (e *msgpackEncDriver) EncodeFloat64(f float64) { 281 e.w.writen1(mpDouble) 282 bigenHelper{e.x[:8], e.w}.writeUint64(math.Float64bits(f)) 283} 284 285func (e *msgpackEncDriver) EncodeTime(t time.Time) { 286 if t.IsZero() { 287 e.EncodeNil() 288 return 289 } 290 t = t.UTC() 291 sec, nsec := t.Unix(), uint64(t.Nanosecond()) 292 var data64 uint64 293 var l = 4 294 if sec >= 0 && sec>>34 == 0 { 295 data64 = (nsec << 34) | uint64(sec) 296 if data64&0xffffffff00000000 != 0 { 297 l = 8 298 } 299 } else { 300 l = 12 301 } 302 if e.h.WriteExt { 303 e.encodeExtPreamble(mpTimeExtTagU, l) 304 } else { 305 e.writeContainerLen(msgpackContainerStr, l) 306 } 307 switch l { 308 case 4: 309 bigenHelper{e.x[:4], e.w}.writeUint32(uint32(data64)) 310 case 8: 311 bigenHelper{e.x[:8], e.w}.writeUint64(data64) 312 case 12: 313 bigenHelper{e.x[:4], e.w}.writeUint32(uint32(nsec)) 314 bigenHelper{e.x[:8], e.w}.writeUint64(uint64(sec)) 315 } 316} 317 318func (e *msgpackEncDriver) EncodeExt(v interface{}, xtag uint64, ext Ext, _ *Encoder) { 319 bs := ext.WriteExt(v) 320 if bs == nil { 321 e.EncodeNil() 322 return 323 } 324 if e.h.WriteExt { 325 e.encodeExtPreamble(uint8(xtag), len(bs)) 326 e.w.writeb(bs) 327 } else { 328 e.EncodeStringBytesRaw(bs) 329 } 330} 331 332func (e *msgpackEncDriver) EncodeRawExt(re *RawExt, _ *Encoder) { 333 e.encodeExtPreamble(uint8(re.Tag), len(re.Data)) 334 e.w.writeb(re.Data) 335} 336 337func (e *msgpackEncDriver) encodeExtPreamble(xtag byte, l int) { 338 if l == 1 { 339 e.w.writen2(mpFixExt1, xtag) 340 } else if l == 2 { 341 e.w.writen2(mpFixExt2, xtag) 342 } else if l == 4 { 343 e.w.writen2(mpFixExt4, xtag) 344 } else if l == 8 { 345 e.w.writen2(mpFixExt8, xtag) 346 } else if l == 16 { 347 e.w.writen2(mpFixExt16, xtag) 348 } else if l < 256 { 349 e.w.writen2(mpExt8, byte(l)) 350 e.w.writen1(xtag) 351 } else if l < 65536 { 352 e.w.writen1(mpExt16) 353 bigenHelper{e.x[:2], e.w}.writeUint16(uint16(l)) 354 e.w.writen1(xtag) 355 } else { 356 e.w.writen1(mpExt32) 357 bigenHelper{e.x[:4], e.w}.writeUint32(uint32(l)) 358 e.w.writen1(xtag) 359 } 360} 361 362func (e *msgpackEncDriver) WriteArrayStart(length int) { 363 e.writeContainerLen(msgpackContainerList, length) 364} 365 366func (e *msgpackEncDriver) WriteMapStart(length int) { 367 e.writeContainerLen(msgpackContainerMap, length) 368} 369 370func (e *msgpackEncDriver) EncodeString(c charEncoding, s string) { 371 slen := len(s) 372 if c == cRAW && e.h.WriteExt { 373 e.writeContainerLen(msgpackContainerBin, slen) 374 } else { 375 e.writeContainerLen(msgpackContainerStr, slen) 376 } 377 if slen > 0 { 378 e.w.writestr(s) 379 } 380} 381 382func (e *msgpackEncDriver) EncodeStringEnc(c charEncoding, s string) { 383 slen := len(s) 384 e.writeContainerLen(msgpackContainerStr, slen) 385 if slen > 0 { 386 e.w.writestr(s) 387 } 388} 389 390func (e *msgpackEncDriver) EncodeStringBytes(c charEncoding, bs []byte) { 391 if bs == nil { 392 e.EncodeNil() 393 return 394 } 395 slen := len(bs) 396 if c == cRAW && e.h.WriteExt { 397 e.writeContainerLen(msgpackContainerBin, slen) 398 } else { 399 e.writeContainerLen(msgpackContainerStr, slen) 400 } 401 if slen > 0 { 402 e.w.writeb(bs) 403 } 404} 405 406func (e *msgpackEncDriver) EncodeStringBytesRaw(bs []byte) { 407 if bs == nil { 408 e.EncodeNil() 409 return 410 } 411 slen := len(bs) 412 if e.h.WriteExt { 413 e.writeContainerLen(msgpackContainerBin, slen) 414 } else { 415 e.writeContainerLen(msgpackContainerStr, slen) 416 } 417 if slen > 0 { 418 e.w.writeb(bs) 419 } 420} 421 422func (e *msgpackEncDriver) writeContainerLen(ct msgpackContainerType, l int) { 423 if ct.hasFixMin && l < ct.fixCutoff { 424 e.w.writen1(ct.bFixMin | byte(l)) 425 } else if ct.has8 && l < 256 && (ct.has8Always || e.h.WriteExt) { 426 e.w.writen2(ct.b8, uint8(l)) 427 } else if l < 65536 { 428 e.w.writen1(ct.b16) 429 bigenHelper{e.x[:2], e.w}.writeUint16(uint16(l)) 430 } else { 431 e.w.writen1(ct.b32) 432 bigenHelper{e.x[:4], e.w}.writeUint32(uint32(l)) 433 } 434} 435 436//--------------------------------------------- 437 438type msgpackDecDriver struct { 439 d *Decoder 440 r *decReaderSwitch 441 h *MsgpackHandle 442 // b [scratchByteArrayLen]byte 443 bd byte 444 bdRead bool 445 br bool // bytes reader 446 noBuiltInTypes 447 // noStreamingCodec 448 // decNoSeparator 449 decDriverNoopContainerReader 450 // _ [3]uint64 // padding 451} 452 453// Note: This returns either a primitive (int, bool, etc) for non-containers, 454// or a containerType, or a specific type denoting nil or extension. 455// It is called when a nil interface{} is passed, leaving it up to the DecDriver 456// to introspect the stream and decide how best to decode. 457// It deciphers the value by looking at the stream first. 458func (d *msgpackDecDriver) DecodeNaked() { 459 if !d.bdRead { 460 d.readNextBd() 461 } 462 bd := d.bd 463 n := d.d.naked() 464 var decodeFurther bool 465 466 switch bd { 467 case mpNil: 468 n.v = valueTypeNil 469 d.bdRead = false 470 case mpFalse: 471 n.v = valueTypeBool 472 n.b = false 473 case mpTrue: 474 n.v = valueTypeBool 475 n.b = true 476 477 case mpFloat: 478 n.v = valueTypeFloat 479 n.f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4)))) 480 case mpDouble: 481 n.v = valueTypeFloat 482 n.f = math.Float64frombits(bigen.Uint64(d.r.readx(8))) 483 484 case mpUint8: 485 n.v = valueTypeUint 486 n.u = uint64(d.r.readn1()) 487 case mpUint16: 488 n.v = valueTypeUint 489 n.u = uint64(bigen.Uint16(d.r.readx(2))) 490 case mpUint32: 491 n.v = valueTypeUint 492 n.u = uint64(bigen.Uint32(d.r.readx(4))) 493 case mpUint64: 494 n.v = valueTypeUint 495 n.u = uint64(bigen.Uint64(d.r.readx(8))) 496 497 case mpInt8: 498 n.v = valueTypeInt 499 n.i = int64(int8(d.r.readn1())) 500 case mpInt16: 501 n.v = valueTypeInt 502 n.i = int64(int16(bigen.Uint16(d.r.readx(2)))) 503 case mpInt32: 504 n.v = valueTypeInt 505 n.i = int64(int32(bigen.Uint32(d.r.readx(4)))) 506 case mpInt64: 507 n.v = valueTypeInt 508 n.i = int64(int64(bigen.Uint64(d.r.readx(8)))) 509 510 default: 511 switch { 512 case bd >= mpPosFixNumMin && bd <= mpPosFixNumMax: 513 // positive fixnum (always signed) 514 n.v = valueTypeInt 515 n.i = int64(int8(bd)) 516 case bd >= mpNegFixNumMin && bd <= mpNegFixNumMax: 517 // negative fixnum 518 n.v = valueTypeInt 519 n.i = int64(int8(bd)) 520 case bd == mpStr8, bd == mpStr16, bd == mpStr32, bd >= mpFixStrMin && bd <= mpFixStrMax: 521 if d.h.RawToString { 522 n.v = valueTypeString 523 n.s = d.DecodeString() 524 } else { 525 n.v = valueTypeBytes 526 n.l = d.DecodeBytes(nil, false) 527 } 528 case bd == mpBin8, bd == mpBin16, bd == mpBin32: 529 n.v = valueTypeBytes 530 n.l = d.DecodeBytes(nil, false) 531 case bd == mpArray16, bd == mpArray32, bd >= mpFixArrayMin && bd <= mpFixArrayMax: 532 n.v = valueTypeArray 533 decodeFurther = true 534 case bd == mpMap16, bd == mpMap32, bd >= mpFixMapMin && bd <= mpFixMapMax: 535 n.v = valueTypeMap 536 decodeFurther = true 537 case bd >= mpFixExt1 && bd <= mpFixExt16, bd >= mpExt8 && bd <= mpExt32: 538 n.v = valueTypeExt 539 clen := d.readExtLen() 540 n.u = uint64(d.r.readn1()) 541 if n.u == uint64(mpTimeExtTagU) { 542 n.v = valueTypeTime 543 n.t = d.decodeTime(clen) 544 } else if d.br { 545 n.l = d.r.readx(uint(clen)) 546 } else { 547 n.l = decByteSlice(d.r, clen, d.d.h.MaxInitLen, d.d.b[:]) 548 } 549 default: 550 d.d.errorf("cannot infer value: %s: Ox%x/%d/%s", msgBadDesc, bd, bd, mpdesc(bd)) 551 } 552 } 553 if !decodeFurther { 554 d.bdRead = false 555 } 556 if n.v == valueTypeUint && d.h.SignedInteger { 557 n.v = valueTypeInt 558 n.i = int64(n.u) 559 } 560} 561 562// int can be decoded from msgpack type: intXXX or uintXXX 563func (d *msgpackDecDriver) DecodeInt64() (i int64) { 564 if !d.bdRead { 565 d.readNextBd() 566 } 567 switch d.bd { 568 case mpUint8: 569 i = int64(uint64(d.r.readn1())) 570 case mpUint16: 571 i = int64(uint64(bigen.Uint16(d.r.readx(2)))) 572 case mpUint32: 573 i = int64(uint64(bigen.Uint32(d.r.readx(4)))) 574 case mpUint64: 575 i = int64(bigen.Uint64(d.r.readx(8))) 576 case mpInt8: 577 i = int64(int8(d.r.readn1())) 578 case mpInt16: 579 i = int64(int16(bigen.Uint16(d.r.readx(2)))) 580 case mpInt32: 581 i = int64(int32(bigen.Uint32(d.r.readx(4)))) 582 case mpInt64: 583 i = int64(bigen.Uint64(d.r.readx(8))) 584 default: 585 switch { 586 case d.bd >= mpPosFixNumMin && d.bd <= mpPosFixNumMax: 587 i = int64(int8(d.bd)) 588 case d.bd >= mpNegFixNumMin && d.bd <= mpNegFixNumMax: 589 i = int64(int8(d.bd)) 590 default: 591 d.d.errorf("cannot decode signed integer: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd)) 592 return 593 } 594 } 595 d.bdRead = false 596 return 597} 598 599// uint can be decoded from msgpack type: intXXX or uintXXX 600func (d *msgpackDecDriver) DecodeUint64() (ui uint64) { 601 if !d.bdRead { 602 d.readNextBd() 603 } 604 switch d.bd { 605 case mpUint8: 606 ui = uint64(d.r.readn1()) 607 case mpUint16: 608 ui = uint64(bigen.Uint16(d.r.readx(2))) 609 case mpUint32: 610 ui = uint64(bigen.Uint32(d.r.readx(4))) 611 case mpUint64: 612 ui = bigen.Uint64(d.r.readx(8)) 613 case mpInt8: 614 if i := int64(int8(d.r.readn1())); i >= 0 { 615 ui = uint64(i) 616 } else { 617 d.d.errorf("assigning negative signed value: %v, to unsigned type", i) 618 return 619 } 620 case mpInt16: 621 if i := int64(int16(bigen.Uint16(d.r.readx(2)))); i >= 0 { 622 ui = uint64(i) 623 } else { 624 d.d.errorf("assigning negative signed value: %v, to unsigned type", i) 625 return 626 } 627 case mpInt32: 628 if i := int64(int32(bigen.Uint32(d.r.readx(4)))); i >= 0 { 629 ui = uint64(i) 630 } else { 631 d.d.errorf("assigning negative signed value: %v, to unsigned type", i) 632 return 633 } 634 case mpInt64: 635 if i := int64(bigen.Uint64(d.r.readx(8))); i >= 0 { 636 ui = uint64(i) 637 } else { 638 d.d.errorf("assigning negative signed value: %v, to unsigned type", i) 639 return 640 } 641 default: 642 switch { 643 case d.bd >= mpPosFixNumMin && d.bd <= mpPosFixNumMax: 644 ui = uint64(d.bd) 645 case d.bd >= mpNegFixNumMin && d.bd <= mpNegFixNumMax: 646 d.d.errorf("assigning negative signed value: %v, to unsigned type", int(d.bd)) 647 return 648 default: 649 d.d.errorf("cannot decode unsigned integer: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd)) 650 return 651 } 652 } 653 d.bdRead = false 654 return 655} 656 657// float can either be decoded from msgpack type: float, double or intX 658func (d *msgpackDecDriver) DecodeFloat64() (f float64) { 659 if !d.bdRead { 660 d.readNextBd() 661 } 662 if d.bd == mpFloat { 663 f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4)))) 664 } else if d.bd == mpDouble { 665 f = math.Float64frombits(bigen.Uint64(d.r.readx(8))) 666 } else { 667 f = float64(d.DecodeInt64()) 668 } 669 d.bdRead = false 670 return 671} 672 673// bool can be decoded from bool, fixnum 0 or 1. 674func (d *msgpackDecDriver) DecodeBool() (b bool) { 675 if !d.bdRead { 676 d.readNextBd() 677 } 678 if d.bd == mpFalse || d.bd == 0 { 679 // b = false 680 } else if d.bd == mpTrue || d.bd == 1 { 681 b = true 682 } else { 683 d.d.errorf("cannot decode bool: %s: %x/%s", msgBadDesc, d.bd, mpdesc(d.bd)) 684 return 685 } 686 d.bdRead = false 687 return 688} 689 690func (d *msgpackDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) { 691 if !d.bdRead { 692 d.readNextBd() 693 } 694 695 // check if an "array" of uint8's (see ContainerType for how to infer if an array) 696 bd := d.bd 697 // DecodeBytes could be from: bin str fixstr fixarray array ... 698 var clen int 699 vt := d.ContainerType() 700 switch vt { 701 case valueTypeBytes: 702 // valueTypeBytes may be a mpBin or an mpStr container 703 if bd == mpBin8 || bd == mpBin16 || bd == mpBin32 { 704 clen = d.readContainerLen(msgpackContainerBin) 705 } else { 706 clen = d.readContainerLen(msgpackContainerStr) 707 } 708 case valueTypeString: 709 clen = d.readContainerLen(msgpackContainerStr) 710 case valueTypeArray: 711 if zerocopy && len(bs) == 0 { 712 bs = d.d.b[:] 713 } 714 bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d) 715 return 716 default: 717 d.d.errorf("invalid container type: expecting bin|str|array, got: 0x%x", uint8(vt)) 718 return 719 } 720 721 // these are (bin|str)(8|16|32) 722 d.bdRead = false 723 // bytes may be nil, so handle it. if nil, clen=-1. 724 if clen < 0 { 725 return nil 726 } 727 if zerocopy { 728 if d.br { 729 return d.r.readx(uint(clen)) 730 } else if len(bs) == 0 { 731 bs = d.d.b[:] 732 } 733 } 734 return decByteSlice(d.r, clen, d.h.MaxInitLen, bs) 735} 736 737func (d *msgpackDecDriver) DecodeString() (s string) { 738 return string(d.DecodeBytes(d.d.b[:], true)) 739} 740 741func (d *msgpackDecDriver) DecodeStringAsBytes() (s []byte) { 742 return d.DecodeBytes(d.d.b[:], true) 743} 744 745func (d *msgpackDecDriver) readNextBd() { 746 d.bd = d.r.readn1() 747 d.bdRead = true 748} 749 750func (d *msgpackDecDriver) uncacheRead() { 751 if d.bdRead { 752 d.r.unreadn1() 753 d.bdRead = false 754 } 755} 756 757func (d *msgpackDecDriver) ContainerType() (vt valueType) { 758 if !d.bdRead { 759 d.readNextBd() 760 } 761 bd := d.bd 762 if bd == mpNil { 763 return valueTypeNil 764 } else if bd == mpBin8 || bd == mpBin16 || bd == mpBin32 || 765 (!d.h.RawToString && 766 (bd == mpStr8 || bd == mpStr16 || bd == mpStr32 || (bd >= mpFixStrMin && bd <= mpFixStrMax))) { 767 return valueTypeBytes 768 } else if d.h.RawToString && 769 (bd == mpStr8 || bd == mpStr16 || bd == mpStr32 || (bd >= mpFixStrMin && bd <= mpFixStrMax)) { 770 return valueTypeString 771 } else if bd == mpArray16 || bd == mpArray32 || (bd >= mpFixArrayMin && bd <= mpFixArrayMax) { 772 return valueTypeArray 773 } else if bd == mpMap16 || bd == mpMap32 || (bd >= mpFixMapMin && bd <= mpFixMapMax) { 774 return valueTypeMap 775 } 776 // else { 777 // d.d.errorf("isContainerType: unsupported parameter: %v", vt) 778 // } 779 return valueTypeUnset 780} 781 782func (d *msgpackDecDriver) TryDecodeAsNil() (v bool) { 783 if !d.bdRead { 784 d.readNextBd() 785 } 786 if d.bd == mpNil { 787 d.bdRead = false 788 return true 789 } 790 return 791} 792 793func (d *msgpackDecDriver) readContainerLen(ct msgpackContainerType) (clen int) { 794 bd := d.bd 795 if bd == mpNil { 796 clen = -1 // to represent nil 797 } else if bd == ct.b8 { 798 clen = int(d.r.readn1()) 799 } else if bd == ct.b16 { 800 clen = int(bigen.Uint16(d.r.readx(2))) 801 } else if bd == ct.b32 { 802 clen = int(bigen.Uint32(d.r.readx(4))) 803 } else if (ct.bFixMin & bd) == ct.bFixMin { 804 clen = int(ct.bFixMin ^ bd) 805 } else { 806 d.d.errorf("cannot read container length: %s: hex: %x, decimal: %d", msgBadDesc, bd, bd) 807 return 808 } 809 d.bdRead = false 810 return 811} 812 813func (d *msgpackDecDriver) ReadMapStart() int { 814 if !d.bdRead { 815 d.readNextBd() 816 } 817 return d.readContainerLen(msgpackContainerMap) 818} 819 820func (d *msgpackDecDriver) ReadArrayStart() int { 821 if !d.bdRead { 822 d.readNextBd() 823 } 824 return d.readContainerLen(msgpackContainerList) 825} 826 827func (d *msgpackDecDriver) readExtLen() (clen int) { 828 switch d.bd { 829 case mpNil: 830 clen = -1 // to represent nil 831 case mpFixExt1: 832 clen = 1 833 case mpFixExt2: 834 clen = 2 835 case mpFixExt4: 836 clen = 4 837 case mpFixExt8: 838 clen = 8 839 case mpFixExt16: 840 clen = 16 841 case mpExt8: 842 clen = int(d.r.readn1()) 843 case mpExt16: 844 clen = int(bigen.Uint16(d.r.readx(2))) 845 case mpExt32: 846 clen = int(bigen.Uint32(d.r.readx(4))) 847 default: 848 d.d.errorf("decoding ext bytes: found unexpected byte: %x", d.bd) 849 return 850 } 851 return 852} 853 854func (d *msgpackDecDriver) DecodeTime() (t time.Time) { 855 // decode time from string bytes or ext 856 if !d.bdRead { 857 d.readNextBd() 858 } 859 if d.bd == mpNil { 860 d.bdRead = false 861 return 862 } 863 var clen int 864 switch d.ContainerType() { 865 case valueTypeBytes, valueTypeString: 866 clen = d.readContainerLen(msgpackContainerStr) 867 default: 868 // expect to see mpFixExt4,-1 OR mpFixExt8,-1 OR mpExt8,12,-1 869 d.bdRead = false 870 b2 := d.r.readn1() 871 if d.bd == mpFixExt4 && b2 == mpTimeExtTagU { 872 clen = 4 873 } else if d.bd == mpFixExt8 && b2 == mpTimeExtTagU { 874 clen = 8 875 } else if d.bd == mpExt8 && b2 == 12 && d.r.readn1() == mpTimeExtTagU { 876 clen = 12 877 } else { 878 d.d.errorf("invalid bytes for decoding time as extension: got 0x%x, 0x%x", d.bd, b2) 879 return 880 } 881 } 882 return d.decodeTime(clen) 883} 884 885func (d *msgpackDecDriver) decodeTime(clen int) (t time.Time) { 886 // bs = d.r.readx(clen) 887 d.bdRead = false 888 switch clen { 889 case 4: 890 t = time.Unix(int64(bigen.Uint32(d.r.readx(4))), 0).UTC() 891 case 8: 892 tv := bigen.Uint64(d.r.readx(8)) 893 t = time.Unix(int64(tv&0x00000003ffffffff), int64(tv>>34)).UTC() 894 case 12: 895 nsec := bigen.Uint32(d.r.readx(4)) 896 sec := bigen.Uint64(d.r.readx(8)) 897 t = time.Unix(int64(sec), int64(nsec)).UTC() 898 default: 899 d.d.errorf("invalid length of bytes for decoding time - expecting 4 or 8 or 12, got %d", clen) 900 return 901 } 902 return 903} 904 905func (d *msgpackDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) { 906 if xtag > 0xff { 907 d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag) 908 return 909 } 910 realxtag1, xbs := d.decodeExtV(ext != nil, uint8(xtag)) 911 realxtag = uint64(realxtag1) 912 if ext == nil { 913 re := rv.(*RawExt) 914 re.Tag = realxtag 915 re.Data = detachZeroCopyBytes(d.br, re.Data, xbs) 916 } else { 917 ext.ReadExt(rv, xbs) 918 } 919 return 920} 921 922func (d *msgpackDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs []byte) { 923 if !d.bdRead { 924 d.readNextBd() 925 } 926 xbd := d.bd 927 if xbd == mpBin8 || xbd == mpBin16 || xbd == mpBin32 { 928 xbs = d.DecodeBytes(nil, true) 929 } else if xbd == mpStr8 || xbd == mpStr16 || xbd == mpStr32 || 930 (xbd >= mpFixStrMin && xbd <= mpFixStrMax) { 931 xbs = d.DecodeStringAsBytes() 932 } else { 933 clen := d.readExtLen() 934 xtag = d.r.readn1() 935 if verifyTag && xtag != tag { 936 d.d.errorf("wrong extension tag - got %b, expecting %v", xtag, tag) 937 return 938 } 939 if d.br { 940 xbs = d.r.readx(uint(clen)) 941 } else { 942 xbs = decByteSlice(d.r, clen, d.d.h.MaxInitLen, d.d.b[:]) 943 } 944 } 945 d.bdRead = false 946 return 947} 948 949//-------------------------------------------------- 950 951//MsgpackHandle is a Handle for the Msgpack Schema-Free Encoding Format. 952type MsgpackHandle struct { 953 BasicHandle 954 955 // RawToString controls how raw bytes are decoded into a nil interface{}. 956 RawToString bool 957 958 // NoFixedNum says to output all signed integers as 2-bytes, never as 1-byte fixednum. 959 NoFixedNum bool 960 961 // WriteExt flag supports encoding configured extensions with extension tags. 962 // It also controls whether other elements of the new spec are encoded (ie Str8). 963 // 964 // With WriteExt=false, configured extensions are serialized as raw bytes 965 // and Str8 is not encoded. 966 // 967 // A stream can still be decoded into a typed value, provided an appropriate value 968 // is provided, but the type cannot be inferred from the stream. If no appropriate 969 // type is provided (e.g. decoding into a nil interface{}), you get back 970 // a []byte or string based on the setting of RawToString. 971 WriteExt bool 972 973 // PositiveIntUnsigned says to encode positive integers as unsigned. 974 PositiveIntUnsigned bool 975 976 binaryEncodingType 977 noElemSeparators 978 979 // _ [1]uint64 // padding 980} 981 982// Name returns the name of the handle: msgpack 983func (h *MsgpackHandle) Name() string { return "msgpack" } 984 985// SetBytesExt sets an extension 986func (h *MsgpackHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) { 987 return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}}) 988} 989 990func (h *MsgpackHandle) newEncDriver(e *Encoder) encDriver { 991 return &msgpackEncDriver{e: e, w: e.w, h: h} 992} 993 994func (h *MsgpackHandle) newDecDriver(d *Decoder) decDriver { 995 return &msgpackDecDriver{d: d, h: h, r: d.r, br: d.bytes} 996} 997 998func (e *msgpackEncDriver) reset() { 999 e.w = e.e.w 1000} 1001 1002func (d *msgpackDecDriver) reset() { 1003 d.r, d.br = d.d.r, d.d.bytes 1004 d.bd, d.bdRead = 0, false 1005} 1006 1007//-------------------------------------------------- 1008 1009type msgpackSpecRpcCodec struct { 1010 rpcCodec 1011} 1012 1013// /////////////// Spec RPC Codec /////////////////// 1014func (c *msgpackSpecRpcCodec) WriteRequest(r *rpc.Request, body interface{}) error { 1015 // WriteRequest can write to both a Go service, and other services that do 1016 // not abide by the 1 argument rule of a Go service. 1017 // We discriminate based on if the body is a MsgpackSpecRpcMultiArgs 1018 var bodyArr []interface{} 1019 if m, ok := body.(MsgpackSpecRpcMultiArgs); ok { 1020 bodyArr = ([]interface{})(m) 1021 } else { 1022 bodyArr = []interface{}{body} 1023 } 1024 r2 := []interface{}{0, uint32(r.Seq), r.ServiceMethod, bodyArr} 1025 return c.write(r2, nil, false) 1026} 1027 1028func (c *msgpackSpecRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error { 1029 var moe interface{} 1030 if r.Error != "" { 1031 moe = r.Error 1032 } 1033 if moe != nil && body != nil { 1034 body = nil 1035 } 1036 r2 := []interface{}{1, uint32(r.Seq), moe, body} 1037 return c.write(r2, nil, false) 1038} 1039 1040func (c *msgpackSpecRpcCodec) ReadResponseHeader(r *rpc.Response) error { 1041 return c.parseCustomHeader(1, &r.Seq, &r.Error) 1042} 1043 1044func (c *msgpackSpecRpcCodec) ReadRequestHeader(r *rpc.Request) error { 1045 return c.parseCustomHeader(0, &r.Seq, &r.ServiceMethod) 1046} 1047 1048func (c *msgpackSpecRpcCodec) ReadRequestBody(body interface{}) error { 1049 if body == nil { // read and discard 1050 return c.read(nil) 1051 } 1052 bodyArr := []interface{}{body} 1053 return c.read(&bodyArr) 1054} 1055 1056func (c *msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint64, methodOrError *string) (err error) { 1057 if cls := c.cls.load(); cls.closed { 1058 return io.EOF 1059 } 1060 1061 // We read the response header by hand 1062 // so that the body can be decoded on its own from the stream at a later time. 1063 1064 const fia byte = 0x94 //four item array descriptor value 1065 // Not sure why the panic of EOF is swallowed above. 1066 // if bs1 := c.dec.r.readn1(); bs1 != fia { 1067 // err = fmt.Errorf("Unexpected value for array descriptor: Expecting %v. Received %v", fia, bs1) 1068 // return 1069 // } 1070 var ba [1]byte 1071 var n int 1072 for { 1073 n, err = c.r.Read(ba[:]) 1074 if err != nil { 1075 return 1076 } 1077 if n == 1 { 1078 break 1079 } 1080 } 1081 1082 var b = ba[0] 1083 if b != fia { 1084 err = fmt.Errorf("not array - %s %x/%s", msgBadDesc, b, mpdesc(b)) 1085 } else { 1086 err = c.read(&b) 1087 if err == nil { 1088 if b != expectTypeByte { 1089 err = fmt.Errorf("%s - expecting %v but got %x/%s", 1090 msgBadDesc, expectTypeByte, b, mpdesc(b)) 1091 } else { 1092 err = c.read(msgid) 1093 if err == nil { 1094 err = c.read(methodOrError) 1095 } 1096 } 1097 } 1098 } 1099 return 1100} 1101 1102//-------------------------------------------------- 1103 1104// msgpackSpecRpc is the implementation of Rpc that uses custom communication protocol 1105// as defined in the msgpack spec at https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md 1106type msgpackSpecRpc struct{} 1107 1108// MsgpackSpecRpc implements Rpc using the communication protocol defined in 1109// the msgpack spec at https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md . 1110// 1111// See GoRpc documentation, for information on buffering for better performance. 1112var MsgpackSpecRpc msgpackSpecRpc 1113 1114func (x msgpackSpecRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec { 1115 return &msgpackSpecRpcCodec{newRPCCodec(conn, h)} 1116} 1117 1118func (x msgpackSpecRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec { 1119 return &msgpackSpecRpcCodec{newRPCCodec(conn, h)} 1120} 1121 1122var _ decDriver = (*msgpackDecDriver)(nil) 1123var _ encDriver = (*msgpackEncDriver)(nil) 1124