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