1 // Copyright (c) 2012, 2013 Ugorji Nwoke. All rights reserved.
2 // Use of this source code is governed by a BSD-style license found in the LICENSE file.
14 const bincDoPrune = true // No longer needed. Needed before as C lib did not support pruning.
18 // vd as low 4 bits (there are 16 slots)
20 bincVdSpecial byte = iota
38 bincVdCustomExt = 0x0f
54 bincFlBin16 byte = iota
59 // others not currently supported
62 type bincEncDriver struct {
64 m map[string]uint16 // symbols
65 s uint32 // symbols sequencer
69 func (e *bincEncDriver) isBuiltinType(rt uintptr) bool {
70 return rt == timeTypId
73 func (e *bincEncDriver) encodeBuiltin(rt uintptr, v interface{}) {
76 bs := encodeTime(v.(time.Time))
77 e.w.writen1(bincVdTimestamp<<4 | uint8(len(bs)))
82 func (e *bincEncDriver) encodeNil() {
83 e.w.writen1(bincVdSpecial<<4 | bincSpNil)
86 func (e *bincEncDriver) encodeBool(b bool) {
88 e.w.writen1(bincVdSpecial<<4 | bincSpTrue)
90 e.w.writen1(bincVdSpecial<<4 | bincSpFalse)
94 func (e *bincEncDriver) encodeFloat32(f float32) {
96 e.w.writen1(bincVdSpecial<<4 | bincSpZeroFloat)
99 e.w.writen1(bincVdFloat<<4 | bincFlBin32)
100 e.w.writeUint32(math.Float32bits(f))
103 func (e *bincEncDriver) encodeFloat64(f float64) {
105 e.w.writen1(bincVdSpecial<<4 | bincSpZeroFloat)
108 bigen.PutUint64(e.b[:], math.Float64bits(f))
111 for ; i >= 0 && (e.b[i] == 0); i-- {
115 e.w.writen1(bincVdFloat<<4 | 0x8 | bincFlBin64)
121 e.w.writen1(bincVdFloat<<4 | bincFlBin64)
125 func (e *bincEncDriver) encIntegerPrune(bd byte, pos bool, v uint64, lim uint8) {
127 bigen.PutUint32(e.b[:lim], uint32(v))
129 bigen.PutUint64(e.b[:lim], v)
132 i := pruneSignExt(e.b[:lim], pos)
133 e.w.writen1(bd | lim - 1 - byte(i))
134 e.w.writeb(e.b[i:lim])
136 e.w.writen1(bd | lim - 1)
137 e.w.writeb(e.b[:lim])
141 func (e *bincEncDriver) encodeInt(v int64) {
142 const nbd byte = bincVdNegInt << 4
145 e.encUint(bincVdPosInt<<4, true, uint64(v))
147 e.w.writen1(bincVdSpecial<<4 | bincSpNegOne)
149 e.encUint(bincVdNegInt<<4, false, uint64(-v))
153 func (e *bincEncDriver) encodeUint(v uint64) {
154 e.encUint(bincVdPosInt<<4, true, v)
157 func (e *bincEncDriver) encUint(bd byte, pos bool, v uint64) {
160 e.w.writen1(bincVdSpecial<<4 | bincSpZero)
161 case pos && v >= 1 && v <= 16:
162 e.w.writen1(bincVdSmallInt<<4 | byte(v-1))
163 case v <= math.MaxUint8:
164 e.w.writen2(bd|0x0, byte(v))
165 case v <= math.MaxUint16:
166 e.w.writen1(bd | 0x01)
167 e.w.writeUint16(uint16(v))
168 case v <= math.MaxUint32:
169 e.encIntegerPrune(bd, pos, v, 4)
171 e.encIntegerPrune(bd, pos, v, 8)
175 func (e *bincEncDriver) encodeExtPreamble(xtag byte, length int) {
176 e.encLen(bincVdCustomExt<<4, uint64(length))
180 func (e *bincEncDriver) encodeArrayPreamble(length int) {
181 e.encLen(bincVdArray<<4, uint64(length))
184 func (e *bincEncDriver) encodeMapPreamble(length int) {
185 e.encLen(bincVdMap<<4, uint64(length))
188 func (e *bincEncDriver) encodeString(c charEncoding, v string) {
196 func (e *bincEncDriver) encodeSymbol(v string) {
197 // if WriteSymbolsNoRefs {
198 // e.encodeString(c_UTF8, v)
202 //symbols only offer benefit when string length > 1.
203 //This is because strings with length 1 take only 2 bytes to store
204 //(bd with embedded length, and single byte for string val).
209 e.encBytesLen(c_UTF8, 0)
212 e.encBytesLen(c_UTF8, 1)
217 e.m = make(map[string]uint16, 16)
221 if ui <= math.MaxUint8 {
222 e.w.writen2(bincVdSymbol<<4, byte(ui))
224 e.w.writen1(bincVdSymbol<<4 | 0x8)
230 //ui = uint16(atomic.AddUint32(&e.s, 1))
234 case l <= math.MaxUint8:
236 case l <= math.MaxUint16:
238 case int64(l) <= math.MaxUint32:
243 if ui <= math.MaxUint8 {
244 e.w.writen2(bincVdSymbol<<4|0x0|0x4|lenprec, byte(ui))
246 e.w.writen1(bincVdSymbol<<4 | 0x8 | 0x4 | lenprec)
253 e.w.writeUint16(uint16(l))
255 e.w.writeUint32(uint32(l))
257 e.w.writeUint64(uint64(l))
263 func (e *bincEncDriver) encodeStringBytes(c charEncoding, v []byte) {
271 func (e *bincEncDriver) encBytesLen(c charEncoding, length uint64) {
272 //TODO: support bincUnicodeOther (for now, just use string or bytearray)
274 e.encLen(bincVdByteArray<<4, length)
276 e.encLen(bincVdString<<4, length)
280 func (e *bincEncDriver) encLen(bd byte, l uint64) {
282 e.w.writen1(bd | uint8(l+4))
284 e.encLenNumber(bd, l)
288 func (e *bincEncDriver) encLenNumber(bd byte, v uint64) {
290 case v <= math.MaxUint8:
291 e.w.writen2(bd, byte(v))
292 case v <= math.MaxUint16:
293 e.w.writen1(bd | 0x01)
294 e.w.writeUint16(uint16(v))
295 case v <= math.MaxUint32:
296 e.w.writen1(bd | 0x02)
297 e.w.writeUint32(uint32(v))
299 e.w.writen1(bd | 0x03)
300 e.w.writeUint64(uint64(v))
304 //------------------------------------
306 type bincDecDriver struct {
314 m map[uint32]string // symbols (use uint32 as key, as map optimizes for it)
317 func (d *bincDecDriver) initReadNext() {
325 d.bdType = valueTypeUnset
328 func (d *bincDecDriver) currentEncodedType() valueType {
329 if d.bdType == valueTypeUnset {
334 d.bdType = valueTypeNil
335 case bincSpFalse, bincSpTrue:
336 d.bdType = valueTypeBool
337 case bincSpNan, bincSpNegInf, bincSpPosInf, bincSpZeroFloat:
338 d.bdType = valueTypeFloat
340 d.bdType = valueTypeUint
342 d.bdType = valueTypeInt
344 decErr("currentEncodedType: Unrecognized special value 0x%x", d.vs)
347 d.bdType = valueTypeUint
349 d.bdType = valueTypeUint
351 d.bdType = valueTypeInt
353 d.bdType = valueTypeFloat
355 d.bdType = valueTypeString
357 d.bdType = valueTypeSymbol
358 case bincVdByteArray:
359 d.bdType = valueTypeBytes
360 case bincVdTimestamp:
361 d.bdType = valueTypeTimestamp
362 case bincVdCustomExt:
363 d.bdType = valueTypeExt
365 d.bdType = valueTypeArray
367 d.bdType = valueTypeMap
369 decErr("currentEncodedType: Unrecognized d.vd: 0x%x", d.vd)
375 func (d *bincDecDriver) tryDecodeAsNil() bool {
376 if d.bd == bincVdSpecial<<4|bincSpNil {
383 func (d *bincDecDriver) isBuiltinType(rt uintptr) bool {
384 return rt == timeTypId
387 func (d *bincDecDriver) decodeBuiltin(rt uintptr, v interface{}) {
390 if d.vd != bincVdTimestamp {
391 decErr("Invalid d.vd. Expecting 0x%x. Received: 0x%x", bincVdTimestamp, d.vd)
393 tt, err := decodeTime(d.r.readn(int(d.vs)))
397 var vt *time.Time = v.(*time.Time)
403 func (d *bincDecDriver) decFloatPre(vs, defaultLen byte) {
405 d.r.readb(d.b[0:defaultLen])
409 decErr("At most 8 bytes used to represent float. Received: %v bytes", l)
411 for i := l; i < 8; i++ {
418 func (d *bincDecDriver) decFloat() (f float64) {
419 //if true { f = math.Float64frombits(d.r.readUint64()); break; }
420 switch vs := d.vs; vs & 0x7 {
423 f = float64(math.Float32frombits(bigen.Uint32(d.b[0:4])))
426 f = math.Float64frombits(bigen.Uint64(d.b[0:8]))
428 decErr("only float32 and float64 are supported. d.vd: 0x%x, d.vs: 0x%x", d.vd, d.vs)
433 func (d *bincDecDriver) decUint() (v uint64) {
434 // need to inline the code (interface conversion and type assertion expensive)
437 v = uint64(d.r.readn1())
440 v = uint64(bigen.Uint16(d.b[6:]))
444 v = uint64(bigen.Uint32(d.b[4:]))
447 v = uint64(bigen.Uint32(d.b[4:]))
451 for i := 0; i < lim; i++ {
454 v = uint64(bigen.Uint64(d.b[:]))
457 v = uint64(bigen.Uint64(d.b[:]))
459 decErr("unsigned integers with greater than 64 bits of precision not supported")
464 func (d *bincDecDriver) decIntAny() (ui uint64, i int64, neg bool) {
475 ui = uint64(d.vs) + 1
485 decErr("numeric decode fails for special value: d.vs: 0x%x", d.vs)
488 decErr("number can only be decoded from uint or int values. d.bd: 0x%x, d.vd: 0x%x", d.bd, d.vd)
493 func (d *bincDecDriver) decodeInt(bitsize uint8) (i int64) {
494 _, i, _ = d.decIntAny()
495 checkOverflow(0, i, bitsize)
500 func (d *bincDecDriver) decodeUint(bitsize uint8) (ui uint64) {
501 ui, i, neg := d.decIntAny()
503 decErr("Assigning negative signed value: %v, to unsigned type", i)
505 checkOverflow(ui, 0, bitsize)
510 func (d *bincDecDriver) decodeFloat(chkOverflow32 bool) (f float64) {
519 case bincSpZeroFloat, bincSpZero:
524 decErr("Invalid d.vs decoding float where d.vd=bincVdSpecial: %v", d.vs)
529 _, i, _ := d.decIntAny()
532 checkOverflowFloat32(f, chkOverflow32)
537 // bool can be decoded from bool only (single byte).
538 func (d *bincDecDriver) decodeBool() (b bool) {
540 case (bincVdSpecial | bincSpFalse):
542 case (bincVdSpecial | bincSpTrue):
545 decErr("Invalid single-byte value for bool: %s: %x", msgBadDesc, d.bd)
551 func (d *bincDecDriver) readMapLen() (length int) {
552 if d.vd != bincVdMap {
553 decErr("Invalid d.vd for map. Expecting 0x%x. Got: 0x%x", bincVdMap, d.vd)
560 func (d *bincDecDriver) readArrayLen() (length int) {
561 if d.vd != bincVdArray {
562 decErr("Invalid d.vd for array. Expecting 0x%x. Got: 0x%x", bincVdArray, d.vd)
569 func (d *bincDecDriver) decLen() int {
571 return int(d.decUint())
576 func (d *bincDecDriver) decodeString() (s string) {
578 case bincVdString, bincVdByteArray:
579 if length := d.decLen(); length > 0 {
580 s = string(d.r.readn(length))
583 //from vs: extract numSymbolBytes, containsStringVal, strLenPrecision,
585 //if containsStringVal, read it and put in map
586 //else look in map for string value
589 //fmt.Printf(">>>> d.vs: 0b%b, & 0x8: %v, & 0x4: %v\n", d.vs, vs & 0x8, vs & 0x4)
591 symbol = uint32(d.r.readn1())
593 symbol = uint32(d.r.readUint16())
596 d.m = make(map[uint32]string, 16)
605 slen = int(d.r.readn1())
607 slen = int(d.r.readUint16())
609 slen = int(d.r.readUint32())
611 slen = int(d.r.readUint64())
613 s = string(d.r.readn(slen))
617 decErr("Invalid d.vd for string. Expecting string:0x%x, bytearray:0x%x or symbol: 0x%x. Got: 0x%x",
618 bincVdString, bincVdByteArray, bincVdSymbol, d.vd)
624 func (d *bincDecDriver) decodeBytes(bs []byte) (bsOut []byte, changed bool) {
627 case bincVdString, bincVdByteArray:
630 decErr("Invalid d.vd for bytes. Expecting string:0x%x or bytearray:0x%x. Got: 0x%x",
631 bincVdString, bincVdByteArray, d.vd)
634 // if no contents in stream, don't update the passed byteslice
639 bs = make([]byte, clen)
650 func (d *bincDecDriver) decodeExt(verifyTag bool, tag byte) (xtag byte, xbs []byte) {
652 case bincVdCustomExt:
655 if verifyTag && xtag != tag {
656 decErr("Wrong extension tag. Got %b. Expecting: %v", xtag, tag)
659 case bincVdByteArray:
660 xbs, _ = d.decodeBytes(nil)
662 decErr("Invalid d.vd for extensions (Expecting extensions or byte array). Got: 0x%x", d.vd)
668 func (d *bincDecDriver) decodeNaked() (v interface{}, vt valueType, decodeFurther bool) {
691 case bincSpZeroFloat:
696 v = int64(0) // int8(0)
699 v = int64(-1) // int8(-1)
701 decErr("decodeNaked: Unrecognized special value 0x%x", d.vs)
705 v = uint64(int8(d.vs)) + 1 // int8(d.vs) + 1
711 v = -(int64(d.decUint()))
721 case bincVdByteArray:
723 v, _ = d.decodeBytes(nil)
724 case bincVdTimestamp:
725 vt = valueTypeTimestamp
726 tt, err := decodeTime(d.r.readn(int(d.vs)))
731 case bincVdCustomExt:
735 re.Tag = d.r.readn1()
736 re.Data = d.r.readn(l)
746 decErr("decodeNaked: Unrecognized d.vd: 0x%x", d.vd)
755 //------------------------------------
757 //BincHandle is a Handle for the Binc Schema-Free Encoding Format
758 //defined at https://github.com/ugorji/binc .
760 //BincHandle currently supports all Binc features with the following EXCEPTIONS:
761 // - only integers up to 64 bits of precision are supported.
762 // big integers are unsupported.
763 // - Only IEEE 754 binary32 and binary64 floats are supported (ie Go float32 and float64 types).
764 // extended precision and decimal IEEE 754 floats are unsupported.
765 // - Only UTF-8 strings supported.
766 // Unicode_Other Binc types (UTF16, UTF32) are currently unsupported.
767 //Note that these EXCEPTIONS are temporary and full support is possible and may happen soon.
768 type BincHandle struct {
772 func (h *BincHandle) newEncDriver(w encWriter) encDriver {
773 return &bincEncDriver{w: w}
776 func (h *BincHandle) newDecDriver(r decReader) decDriver {
777 return &bincDecDriver{r: r}
780 func (_ *BincHandle) writeExt() bool {
784 func (h *BincHandle) getBasicHandle() *BasicHandle {
785 return &h.BasicHandle