Browse Source

Updated README to refer to binc/msgpack, gofmt'ed sources, and updated to v0.3.0 of binc spec
with support for compact time representation.

Ugorji Nwoke 12 years ago
parent
commit
9966a02b69
14 changed files with 851 additions and 855 deletions
  1. 1 1
      README.md
  2. 24 24
      codec/0doc.go
  3. 24 25
      codec/bench_test.go
  4. 137 150
      codec/binc.go
  5. 156 158
      codec/codecs_test.go
  6. 84 157
      codec/decode.go
  7. 78 133
      codec/encode.go
  8. 3 3
      codec/ext_dep_test.go
  9. 57 54
      codec/helper.go
  10. 26 3
      codec/helper_internal.go
  11. 115 121
      codec/msgpack.go
  12. 15 16
      codec/rpc.go
  13. 122 0
      codec/time.go
  14. 9 10
      codec/z_helper_test.go

+ 1 - 1
README.md

@@ -4,7 +4,7 @@ Collection of Open-Source Go libraries and tools.
 
 
 ## Codec
 ## Codec
 
 
-[Codec](https://github.com/ugorji/go/tree/master/codec#readme) is a High Performance and Feature-Rich Idiomatic encode/decode and rpc library.
+[Codec](https://github.com/ugorji/go/tree/master/codec#readme) is a High Performance and Feature-Rich Idiomatic encode/decode and rpc library for [msgpack](http://msgpack.org) and [Binc](https://github.com/ugorji/binc).
 
 
 Online documentation is at [http://godoc.org/github.com/ugorji/go/codec].
 Online documentation is at [http://godoc.org/github.com/ugorji/go/codec].
 
 

+ 24 - 24
codec/0doc.go

@@ -19,41 +19,41 @@ the standard library (ie json, xml, gob, etc).
 Rich Feature Set includes:
 Rich Feature Set includes:
 
 
   - Simple but extremely powerful and feature-rich API
   - Simple but extremely powerful and feature-rich API
-  - Very High Performance.   
+  - Very High Performance.
     Our extensive benchmarks show us outperforming Gob, Json and Bson by 2-4X.
     Our extensive benchmarks show us outperforming Gob, Json and Bson by 2-4X.
     This was achieved by taking extreme care on:
     This was achieved by taking extreme care on:
       - managing allocation
       - managing allocation
-      - stack frame size (important due to Go's use of split stacks), 
+      - stack frame size (important due to Go's use of split stacks),
       - reflection use
       - reflection use
       - recursion implications
       - recursion implications
       - zero-copy mode (encoding/decoding to byte slice without using temp buffers)
       - zero-copy mode (encoding/decoding to byte slice without using temp buffers)
-  - Correct.  
-    Care was taken to precisely handle corner cases like: 
+  - Correct.
+    Care was taken to precisely handle corner cases like:
       overflows, nil maps and slices, nil value in stream, etc.
       overflows, nil maps and slices, nil value in stream, etc.
-  - Efficient zero-copying into temporary byte buffers  
+  - Efficient zero-copying into temporary byte buffers
     when encoding into or decoding from a byte slice.
     when encoding into or decoding from a byte slice.
   - Standard field renaming via tags
   - Standard field renaming via tags
-  - Encoding from any value  
+  - Encoding from any value
     (struct, slice, map, primitives, pointers, interface{}, etc)
     (struct, slice, map, primitives, pointers, interface{}, etc)
-  - Decoding into pointer to any non-nil typed value  
+  - Decoding into pointer to any non-nil typed value
     (struct, slice, map, int, float32, bool, string, reflect.Value, etc)
     (struct, slice, map, int, float32, bool, string, reflect.Value, etc)
   - Supports extension functions to handle the encode/decode of custom types
   - Supports extension functions to handle the encode/decode of custom types
-  - Schema-less decoding  
-    (decode into a pointer to a nil interface{} as opposed to a typed non-nil value).  
-    Includes Options to configure what specific map or slice type to use 
+  - Schema-less decoding
+    (decode into a pointer to a nil interface{} as opposed to a typed non-nil value).
+    Includes Options to configure what specific map or slice type to use
     when decoding an encoded list or map into a nil interface{}
     when decoding an encoded list or map into a nil interface{}
   - Provides a RPC Server and Client Codec for net/rpc communication protocol.
   - Provides a RPC Server and Client Codec for net/rpc communication protocol.
   - Msgpack Specific:
   - Msgpack Specific:
       - Provides extension functions to handle spec-defined extensions (binary, timestamp)
       - Provides extension functions to handle spec-defined extensions (binary, timestamp)
-      - Options to resolve ambiguities in handling raw bytes (as string or []byte)  
+      - Options to resolve ambiguities in handling raw bytes (as string or []byte)
         during schema-less decoding (decoding into a nil interface{})
         during schema-less decoding (decoding into a nil interface{})
-      - RPC Server/Client Codec for msgpack-rpc protocol defined at: 
+      - RPC Server/Client Codec for msgpack-rpc protocol defined at:
         http://wiki.msgpack.org/display/MSGPACK/RPC+specification
         http://wiki.msgpack.org/display/MSGPACK/RPC+specification
 
 
 Extension Support
 Extension Support
 
 
 Users can register a function to handle the encoding or decoding of
 Users can register a function to handle the encoding or decoding of
-their custom types. 
+their custom types.
 
 
 There are no restrictions on what the custom type can be. Extensions can
 There are no restrictions on what the custom type can be. Extensions can
 be any type: pointers, structs, custom types off arrays/slices, strings,
 be any type: pointers, structs, custom types off arrays/slices, strings,
@@ -84,7 +84,7 @@ Typical usage model:
       sliceByteTyp = reflect.TypeOf([]byte(nil))
       sliceByteTyp = reflect.TypeOf([]byte(nil))
       timeTyp = reflect.TypeOf(time.Time{})
       timeTyp = reflect.TypeOf(time.Time{})
     )
     )
-    
+
     // create and configure Handle
     // create and configure Handle
     var (
     var (
       bh codec.BincHandle
       bh codec.BincHandle
@@ -92,7 +92,7 @@ Typical usage model:
     )
     )
 
 
     mh.MapType = mapStrIntfTyp
     mh.MapType = mapStrIntfTyp
-    
+
     // configure extensions for msgpack, to enable Binary and Time support for tags 0 and 1
     // configure extensions for msgpack, to enable Binary and Time support for tags 0 and 1
     mh.AddExt(sliceByteTyp, 0, mh.BinaryEncodeExt, mh.BinaryDecodeExt)
     mh.AddExt(sliceByteTyp, 0, mh.BinaryEncodeExt, mh.BinaryDecodeExt)
     mh.AddExt(timeTyp, 1, mh.TimeEncodeExt, mh.TimeDecodeExt)
     mh.AddExt(timeTyp, 1, mh.TimeEncodeExt, mh.TimeDecodeExt)
@@ -104,15 +104,15 @@ Typical usage model:
       b []byte
       b []byte
       h = &bh // or mh to use msgpack
       h = &bh // or mh to use msgpack
     )
     )
-    
+
     dec = codec.NewDecoder(r, h)
     dec = codec.NewDecoder(r, h)
     dec = codec.NewDecoderBytes(b, h)
     dec = codec.NewDecoderBytes(b, h)
-    err = dec.Decode(&v) 
-    
+    err = dec.Decode(&v)
+
     enc = codec.NewEncoder(w, h)
     enc = codec.NewEncoder(w, h)
     enc = codec.NewEncoderBytes(&b, h)
     enc = codec.NewEncoderBytes(&b, h)
     err = enc.Encode(v)
     err = enc.Encode(v)
-    
+
     //RPC Server
     //RPC Server
     go func() {
     go func() {
         for {
         for {
@@ -122,10 +122,10 @@ Typical usage model:
             rpc.ServeCodec(rpcCodec)
             rpc.ServeCodec(rpcCodec)
         }
         }
     }()
     }()
-    
+
     //RPC Communication (client side)
     //RPC Communication (client side)
-    conn, err = net.Dial("tcp", "localhost:5555")  
-    rpcCodec := rpcH.ClientCodec(conn, h)  
+    conn, err = net.Dial("tcp", "localhost:5555")
+    rpcCodec := rpcH.ClientCodec(conn, h)
     client := rpc.NewClientWithCodec(rpcCodec)
     client := rpc.NewClientWithCodec(rpcCodec)
 
 
 Representative Benchmark Results
 Representative Benchmark Results
@@ -133,7 +133,7 @@ Representative Benchmark Results
 A sample run of benchmark using "go test -bi -bench=.":
 A sample run of benchmark using "go test -bi -bench=.":
 
 
     ..............................................
     ..............................................
-    Benchmark: 
+    Benchmark:
     	Struct recursive Depth:             1
     	Struct recursive Depth:             1
     	ApproxDeepSize Of benchmark Struct: 4786
     	ApproxDeepSize Of benchmark Struct: 4786
     Benchmark One-Pass Run:
     Benchmark One-Pass Run:
@@ -158,7 +158,7 @@ A sample run of benchmark using "go test -bi -bench=.":
     Benchmark__VMsgpack_Encode	   20000	     81752 ns/op
     Benchmark__VMsgpack_Encode	   20000	     81752 ns/op
     Benchmark__VMsgpack_Decode	   10000	    160050 ns/op
     Benchmark__VMsgpack_Decode	   10000	    160050 ns/op
 
 
-To run full benchmark suite (including against vmsgpack and bson), 
+To run full benchmark suite (including against vmsgpack and bson),
 see notes in ext_dep_test.go
 see notes in ext_dep_test.go
 
 
 */
 */

+ 24 - 25
codec/bench_test.go

@@ -4,41 +4,41 @@
 package codec
 package codec
 
 
 import (
 import (
-	"encoding/json"
-	"encoding/gob"
-	"testing"
 	"bytes"
 	"bytes"
-	"reflect"
-	"time"
-	"runtime"
+	"encoding/gob"
+	"encoding/json"
 	"flag"
 	"flag"
 	"fmt"
 	"fmt"
+	"reflect"
+	"runtime"
+	"testing"
+	"time"
 )
 )
 
 
 // Sample way to run:
 // Sample way to run:
 // go test -bi -bv -bd=1 -benchmem -bench Msgpack__Encode
 // go test -bi -bv -bd=1 -benchmem -bench Msgpack__Encode
 
 
 var (
 var (
-	_ = fmt.Printf
+	_       = fmt.Printf
 	benchTs *TestStruc
 	benchTs *TestStruc
 
 
 	approxSize int
 	approxSize int
 
 
-	benchDoInitBench bool
-	benchVerify bool
+	benchDoInitBench     bool
+	benchVerify          bool
 	benchUnscientificRes bool = false
 	benchUnscientificRes bool = false
 	//depth of 0 maps to ~400bytes json-encoded string, 1 maps to ~1400 bytes, etc
 	//depth of 0 maps to ~400bytes json-encoded string, 1 maps to ~1400 bytes, etc
 	//For depth>1, we likely trigger stack growth for encoders, making benchmarking unreliable.
 	//For depth>1, we likely trigger stack growth for encoders, making benchmarking unreliable.
-	benchDepth int
+	benchDepth     int
 	benchInitDebug bool
 	benchInitDebug bool
-	benchInitChan = make(chan bool, 1)
-	benchCheckers []benchChecker
+	benchInitChan  = make(chan bool, 1)
+	benchCheckers  []benchChecker
 )
 )
 
 
 type benchEncFn func(*TestStruc) ([]byte, error)
 type benchEncFn func(*TestStruc) ([]byte, error)
 type benchDecFn func([]byte, *TestStruc) error
 type benchDecFn func([]byte, *TestStruc) error
 type benchChecker struct {
 type benchChecker struct {
-	name string
+	name     string
 	encodefn benchEncFn
 	encodefn benchEncFn
 	decodefn benchDecFn
 	decodefn benchDecFn
 }
 }
@@ -58,7 +58,7 @@ func init() {
 		bytesLen = approxSize
 		bytesLen = approxSize
 	}
 	}
 
 
-	benchCheckers = append(benchCheckers, 
+	benchCheckers = append(benchCheckers,
 		benchChecker{"msgpack", fnMsgpackEncodeFn, fnMsgpackDecodeFn},
 		benchChecker{"msgpack", fnMsgpackEncodeFn, fnMsgpackDecodeFn},
 		benchChecker{"binc", fnBincEncodeFn, fnBincDecodeFn},
 		benchChecker{"binc", fnBincEncodeFn, fnBincDecodeFn},
 		benchChecker{"gob", fnGobEncodeFn, fnGobDecodeFn},
 		benchChecker{"gob", fnGobEncodeFn, fnGobDecodeFn},
@@ -66,7 +66,7 @@ func init() {
 	)
 	)
 	if benchDoInitBench {
 	if benchDoInitBench {
 		go func() {
 		go func() {
-			<- benchInitChan
+			<-benchInitChan
 			runBenchInit()
 			runBenchInit()
 		}()
 		}()
 	}
 	}
@@ -75,12 +75,12 @@ func init() {
 func runBenchInit() {
 func runBenchInit() {
 	logT(nil, "..............................................")
 	logT(nil, "..............................................")
 	logT(nil, "BENCHMARK INIT: %v", time.Now())
 	logT(nil, "BENCHMARK INIT: %v", time.Now())
-	logT(nil, "To run full benchmark comparing encodings (MsgPack, Binc, JSON, GOB, etc), " + 
+	logT(nil, "To run full benchmark comparing encodings (MsgPack, Binc, JSON, GOB, etc), "+
 		"use: \"go test -bench=.\"")
 		"use: \"go test -bench=.\"")
 	logT(nil, "Benchmark: ")
 	logT(nil, "Benchmark: ")
 	logT(nil, "\tStruct recursive Depth:             %d", benchDepth)
 	logT(nil, "\tStruct recursive Depth:             %d", benchDepth)
 	if approxSize > 0 {
 	if approxSize > 0 {
-		logT(nil, "\tApproxDeepSize Of benchmark Struct: %d", approxSize)
+		logT(nil, "\tApproxDeepSize Of benchmark Struct: %d bytes", approxSize)
 	}
 	}
 	if benchUnscientificRes {
 	if benchUnscientificRes {
 		logT(nil, "Benchmark One-Pass Run (with Unscientific Encode/Decode times): ")
 		logT(nil, "Benchmark One-Pass Run (with Unscientific Encode/Decode times): ")
@@ -102,12 +102,12 @@ func doBenchCheck(name string, encfn benchEncFn, decfn benchDecFn) {
 	buf, err := encfn(benchTs)
 	buf, err := encfn(benchTs)
 	if err != nil {
 	if err != nil {
 		logT(nil, "\t%10s: **** Error encoding benchTs: %v", name, err)
 		logT(nil, "\t%10s: **** Error encoding benchTs: %v", name, err)
-	} 
+	}
 	encDur := time.Now().Sub(tnow)
 	encDur := time.Now().Sub(tnow)
 	encLen := len(buf)
 	encLen := len(buf)
 	runtime.GC()
 	runtime.GC()
 	if !benchUnscientificRes {
 	if !benchUnscientificRes {
-		logT(nil, "\t%10s: len: %v\n", name, encLen)
+		logT(nil, "\t%10s: len: %d bytes\n", name, encLen)
 		return
 		return
 	}
 	}
 	tnow = time.Now()
 	tnow = time.Now()
@@ -115,7 +115,7 @@ func doBenchCheck(name string, encfn benchEncFn, decfn benchDecFn) {
 		logT(nil, "\t%10s: **** Error decoding into new TestStruc: %v", name, err)
 		logT(nil, "\t%10s: **** Error decoding into new TestStruc: %v", name, err)
 	}
 	}
 	decDur := time.Now().Sub(tnow)
 	decDur := time.Now().Sub(tnow)
-	logT(nil, "\t%10s: len: %v, encode: %v, decode: %v\n", name, encLen, encDur, decDur)
+	logT(nil, "\t%10s: len: %d bytes, encode: %v, decode: %v\n", name, encLen, encDur, decDur)
 }
 }
 
 
 func fnBenchmarkEncode(b *testing.B, encName string, encfn benchEncFn) {
 func fnBenchmarkEncode(b *testing.B, encName string, encfn benchEncFn) {
@@ -139,7 +139,7 @@ func fnBenchmarkDecode(b *testing.B, encName string, encfn benchEncFn, decfn ben
 	runtime.GC()
 	runtime.GC()
 	b.ResetTimer()
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 	for i := 0; i < b.N; i++ {
-		ts := new(TestStruc)		
+		ts := new(TestStruc)
 		if err = decfn(buf, ts); err != nil {
 		if err = decfn(buf, ts); err != nil {
 			logT(b, "Error decoding into new TestStruc: %s: %v", encName, err)
 			logT(b, "Error decoding into new TestStruc: %s: %v", encName, err)
 			b.FailNow()
 			b.FailNow()
@@ -172,17 +172,17 @@ func verifyCheckAndGet(b *testing.B, ts0 *TestStruc) (ts1m *TestStruc, ts1s *Tes
 	// if len(ts1m.Ms) <= 2 {
 	// if len(ts1m.Ms) <= 2 {
 	// 	logT(b, "Error: ts1m.Ms len should be > 2. Got: %v", len(ts1m.Ms))
 	// 	logT(b, "Error: ts1m.Ms len should be > 2. Got: %v", len(ts1m.Ms))
 	// 	b.FailNow()
 	// 	b.FailNow()
-	// } 
+	// }
 	if len(ts0.Its) == 0 {
 	if len(ts0.Its) == 0 {
 		logT(b, "Error: ts0.Islice len should be > 0. Got: %v", len(ts0.Its))
 		logT(b, "Error: ts0.Islice len should be > 0. Got: %v", len(ts0.Its))
 		b.FailNow()
 		b.FailNow()
 	}
 	}
 	ts1m = ts0.Mtsptr["0"]
 	ts1m = ts0.Mtsptr["0"]
 	ts1s = ts0.Its[0]
 	ts1s = ts0.Its[0]
-	if (ts1m == nil || ts1s == nil) {
+	if ts1m == nil || ts1s == nil {
 		logT(b, "Error: At benchDepth 1, No *TestStruc found")
 		logT(b, "Error: At benchDepth 1, No *TestStruc found")
 		b.FailNow()
 		b.FailNow()
-	}		
+	}
 	return
 	return
 }
 }
 
 
@@ -260,4 +260,3 @@ func Benchmark__Json_____Encode(b *testing.B) {
 func Benchmark__Json_____Decode(b *testing.B) {
 func Benchmark__Json_____Decode(b *testing.B) {
 	fnBenchmarkDecode(b, "json", fnJsonEncodeFn, fnJsonDecodeFn)
 	fnBenchmarkDecode(b, "json", fnJsonEncodeFn, fnJsonDecodeFn)
 }
 }
-

+ 137 - 150
codec/binc.go

@@ -6,8 +6,8 @@ package codec
 import (
 import (
 	"math"
 	"math"
 	"reflect"
 	"reflect"
-	"time"
 	"sync/atomic"
 	"sync/atomic"
+	"time"
 	//"fmt"
 	//"fmt"
 )
 )
 
 
@@ -21,7 +21,7 @@ import (
 //    big integers are unsupported.
 //    big integers are unsupported.
 //  - Only IEEE 754 binary32 and binary64 floats are supported (ie Go float32 and float64 types).
 //  - Only IEEE 754 binary32 and binary64 floats are supported (ie Go float32 and float64 types).
 //    extended precision and decimal IEEE 754 floats are unsupported.
 //    extended precision and decimal IEEE 754 floats are unsupported.
-//  - Only UTF-8 strings supported. 
+//  - Only UTF-8 strings supported.
 //    Unicode_Other Binc types (UTF16, UTF32) are currently unsupported.
 //    Unicode_Other Binc types (UTF16, UTF32) are currently unsupported.
 //Note that these EXCEPTIONS are temporary and full support is possible and may happen soon.
 //Note that these EXCEPTIONS are temporary and full support is possible and may happen soon.
 type BincHandle struct {
 type BincHandle struct {
@@ -35,20 +35,20 @@ const (
 	bincVdUint
 	bincVdUint
 	bincVdInt
 	bincVdInt
 	bincVdFloat
 	bincVdFloat
-	
+
 	bincVdString
 	bincVdString
 	bincVdByteArray
 	bincVdByteArray
 	bincVdArray
 	bincVdArray
 	bincVdMap
 	bincVdMap
-	
+
 	bincVdTimestamp
 	bincVdTimestamp
 	bincVdSmallInt
 	bincVdSmallInt
 	bincVdUnicodeOther
 	bincVdUnicodeOther
 	bincVdSymbol
 	bincVdSymbol
-	
+
 	bincVdDecimal
 	bincVdDecimal
-	_ // open slot
-	_ // open slot
+	_               // open slot
+	_               // open slot
 	bincVdCustomExt = 0x0f
 	bincVdCustomExt = 0x0f
 )
 )
 
 
@@ -61,7 +61,7 @@ const (
 	bincSpNegInf
 	bincSpNegInf
 	bincSpZeroFloat
 	bincSpZeroFloat
 	bincSpZero
 	bincSpZero
-    bincSpNegOne
+	bincSpNegOne
 )
 )
 
 
 const (
 const (
@@ -73,179 +73,170 @@ const (
 	// others not currently supported
 	// others not currently supported
 )
 )
 
 
-type bincEncoder struct { 
+type bincEncDriver struct {
 	w encWriter
 	w encWriter
 	m map[string]uint16 // symbols
 	m map[string]uint16 // symbols
-	s uint32 // symbols sequencer
+	s uint32            // symbols sequencer
 	b [8]byte
 	b [8]byte
 }
 }
 
 
-type bincDecoder struct {
-	r decReader
+type bincDecDriver struct {
+	r      decReader
 	bdRead bool
 	bdRead bool
-	bd byte 
-	vd byte
-	vs byte 
-	b [8]byte
-	m map[uint16]string // symbols (TODO: maybe use uint32 as key, as map optimizes for it)
+	bd     byte
+	vd     byte
+	vs     byte
+	b      [8]byte
+	m      map[uint16]string // symbols (TODO: maybe use uint32 as key, as map optimizes for it)
 }
 }
 
 
-func (_ *BincHandle) newEncoder(w encWriter) encoder {
-	return &bincEncoder{w: w}
+func (_ *BincHandle) newEncDriver(w encWriter) encDriver {
+	return &bincEncDriver{w: w}
 }
 }
 
 
-func (_ *BincHandle) newDecoder(r decReader) decoder {
-	return &bincDecoder{r: r}
+func (_ *BincHandle) newDecDriver(r decReader) decDriver {
+	return &bincDecDriver{r: r}
 }
 }
 
 
 func (_ *BincHandle) writeExt() bool {
 func (_ *BincHandle) writeExt() bool {
 	return true
 	return true
 }
 }
 
 
-func (e *bincEncoder) encodeBuiltinType(rt reflect.Type, rv reflect.Value) bool {
+func (e *bincEncDriver) encodeBuiltinType(rt reflect.Type, rv reflect.Value) bool {
 	switch rt {
 	switch rt {
 	case timeTyp:
 	case timeTyp:
 		bs := encodeTime(rv.Interface().(time.Time))
 		bs := encodeTime(rv.Interface().(time.Time))
-		e.w.writen1(bincVdTimestamp << 4 | uint8(len(bs)))
+		e.w.writen1(bincVdTimestamp<<4 | uint8(len(bs)))
 		e.w.writeb(bs)
 		e.w.writeb(bs)
 		return true
 		return true
 	}
 	}
 	return false
 	return false
 }
 }
 
 
-func (e *bincEncoder) encodeNil() { 
-	e.w.writen1(bincVdSpecial << 4 | bincSpNil)
+func (e *bincEncDriver) encodeNil() {
+	e.w.writen1(bincVdSpecial<<4 | bincSpNil)
 }
 }
 
 
-func (e *bincEncoder) encodeBool(b bool) { 
+func (e *bincEncDriver) encodeBool(b bool) {
 	if b {
 	if b {
-		e.w.writen1(bincVdSpecial << 4 | bincSpTrue)
+		e.w.writen1(bincVdSpecial<<4 | bincSpTrue)
 	} else {
 	} else {
-		e.w.writen1(bincVdSpecial << 4 | bincSpFalse)
-	}		
+		e.w.writen1(bincVdSpecial<<4 | bincSpFalse)
+	}
 }
 }
 
 
-func (e *bincEncoder) encodeFloat32(f float32) { 
+func (e *bincEncDriver) encodeFloat32(f float32) {
 	if f == 0 {
 	if f == 0 {
-		e.w.writen1(bincVdSpecial << 4 | bincSpZeroFloat)
+		e.w.writen1(bincVdSpecial<<4 | bincSpZeroFloat)
 		return
 		return
 	}
 	}
-	e.w.writen1(bincVdFloat << 4 | bincFlBin32)
+	e.w.writen1(bincVdFloat<<4 | bincFlBin32)
 	e.w.writeUint32(math.Float32bits(f))
 	e.w.writeUint32(math.Float32bits(f))
 }
 }
 
 
-func (e *bincEncoder) encodeFloat64(f float64) { 
+func (e *bincEncDriver) encodeFloat64(f float64) {
 	//if true { e.w.writen1(bincVdFloat << 4 | bincFlBin64); e.w.writeUint64(math.Float64bits(f)); return; }
 	//if true { e.w.writen1(bincVdFloat << 4 | bincFlBin64); e.w.writeUint64(math.Float64bits(f)); return; }
 	if f == 0 {
 	if f == 0 {
-		e.w.writen1(bincVdSpecial << 4 | bincSpZeroFloat)
+		e.w.writen1(bincVdSpecial<<4 | bincSpZeroFloat)
 		return
 		return
 	}
 	}
 	bigen.PutUint64(e.b[:], math.Float64bits(f))
 	bigen.PutUint64(e.b[:], math.Float64bits(f))
 	var i int = 7
 	var i int = 7
-	for ; i >= 0 && (e.b[i] == 0); i-- { }
+	for ; i >= 0 && (e.b[i] == 0); i-- {
+	}
 	i++
 	i++
 	if i > 6 { // 7 or 8 ie < 2 trailing zeros
 	if i > 6 { // 7 or 8 ie < 2 trailing zeros
-		e.w.writen1(bincVdFloat << 4 | bincFlBin64)
+		e.w.writen1(bincVdFloat<<4 | bincFlBin64)
 		e.w.writeb(e.b[:])
 		e.w.writeb(e.b[:])
 	} else {
 	} else {
-		e.w.writen1(bincVdFloat << 4 | 0x8 | bincFlBin64)
+		e.w.writen1(bincVdFloat<<4 | 0x8 | bincFlBin64)
 		e.w.writen1(byte(i))
 		e.w.writen1(byte(i))
 		e.w.writeb(e.b[:i])
 		e.w.writeb(e.b[:i])
 	}
 	}
 }
 }
 
 
-func (e *bincEncoder) encInteger4(bd byte, trim byte, v uint32) {
+func (e *bincEncDriver) encInteger4(bd byte, v uint32) {
 	const lim int = 4
 	const lim int = 4
-	bigen.PutUint32(e.b[:lim], v)
-	var i int 
-	for ; i < (lim-1) && (e.b[i] == trim); i++ { }
-	e.w.writen1(bd | byte(lim-i-1))
+	eb := e.b[:lim]
+	bigen.PutUint32(eb, v)
+	i := pruneSignExt(eb)
+	e.w.writen1(bd | byte(lim-1-i))
 	e.w.writeb(e.b[i:lim])
 	e.w.writeb(e.b[i:lim])
 }
 }
 
 
-func (e *bincEncoder) encInteger8(bd byte, trim byte, v uint64) {
+func (e *bincEncDriver) encInteger8(bd byte, v uint64) {
 	const lim int = 8
 	const lim int = 8
-	bigen.PutUint64(e.b[:lim], v)
-	var i int 
-	for ; i < (lim-1) && (e.b[i] == trim); i++ { }
-	e.w.writen1(bd | byte(lim-i-1))
+	eb := e.b[:lim]
+	bigen.PutUint64(eb, v)
+	i := pruneSignExt(eb)
+	e.w.writen1(bd | byte(lim-1-i))
 	e.w.writeb(e.b[i:lim])
 	e.w.writeb(e.b[i:lim])
-	// e.w.writen1(bincVdInt << 4 | 0x03)
-	// e.w.writeUint64(uint64(v))
 }
 }
 
 
-func (e *bincEncoder) encodeInt(v int64) { 
+func (e *bincEncDriver) encodeInt(v int64) {
 	const bd byte = bincVdInt << 4
 	const bd byte = bincVdInt << 4
 	switch {
 	switch {
 	case v == 0:
 	case v == 0:
-		e.w.writen1(bincVdSpecial << 4 | bincSpZero)
+		e.w.writen1(bincVdSpecial<<4 | bincSpZero)
 	case v == -1:
 	case v == -1:
-		e.w.writen1(bincVdSpecial << 4 | bincSpNegOne)
+		e.w.writen1(bincVdSpecial<<4 | bincSpNegOne)
 	case v >= 1 && v <= 16:
 	case v >= 1 && v <= 16:
-		e.w.writen1(bincVdSmallInt << 4 | byte(v-1))
+		e.w.writen1(bincVdSmallInt<<4 | byte(v-1))
 	case v >= math.MinInt8 && v <= math.MaxInt8:
 	case v >= math.MinInt8 && v <= math.MaxInt8:
-		e.w.writen2(bd | 0x0, byte(v))
+		e.w.writen2(bd|0x0, byte(v))
 	case v >= math.MinInt16 && v <= math.MaxInt16:
 	case v >= math.MinInt16 && v <= math.MaxInt16:
 		e.w.writen1(bd | 0x1)
 		e.w.writen1(bd | 0x1)
 		e.w.writeUint16(uint16(v))
 		e.w.writeUint16(uint16(v))
 	case v >= math.MinInt32 && v <= math.MaxInt32:
 	case v >= math.MinInt32 && v <= math.MaxInt32:
-		if v < 0 {
-			e.encInteger4(bd, 0xff, uint32(v))
-		} else {
-			e.encInteger4(bd, 0, uint32(v))
-		} 	
+		e.encInteger4(bd, uint32(v))
 	default:
 	default:
-		if v < 0 {
-			e.encInteger8(bd, 0xff, uint64(v))
-		} else {
-			e.encInteger8(bd, 0, uint64(v))
-		}
+		e.encInteger8(bd, uint64(v))
 	}
 	}
 }
 }
 
 
-func (e *bincEncoder) encodeUint(v uint64) { 
+func (e *bincEncDriver) encodeUint(v uint64) {
 	const bd byte = bincVdUint << 4
 	const bd byte = bincVdUint << 4
 	switch {
 	switch {
 	case v <= math.MaxUint8:
 	case v <= math.MaxUint8:
-		e.w.writen2(bd | 0x0, byte(v))
+		e.w.writen2(bd|0x0, byte(v))
 	case v <= math.MaxUint16:
 	case v <= math.MaxUint16:
 		e.w.writen1(bd | 0x01)
 		e.w.writen1(bd | 0x01)
 		e.w.writeUint16(uint16(v))
 		e.w.writeUint16(uint16(v))
 	case v <= math.MaxUint32:
 	case v <= math.MaxUint32:
-		e.encInteger4(bd, 0, uint32(v))
+		e.encInteger4(bd, uint32(v))
 	default:
 	default:
-		e.encInteger8(bd, 0, v)
+		e.encInteger8(bd, v)
 	}
 	}
 }
 }
 
 
-func (e *bincEncoder) encodeExtPreamble(xtag byte, length int)  {
-	e.encLen(bincVdCustomExt << 4, uint64(length))
+func (e *bincEncDriver) encodeExtPreamble(xtag byte, length int) {
+	e.encLen(bincVdCustomExt<<4, uint64(length))
 	e.w.writen1(xtag)
 	e.w.writen1(xtag)
 }
 }
 
 
-func (e *bincEncoder) encodeArrayPreamble(length int) {
-	e.encLen(bincVdArray << 4, uint64(length))
+func (e *bincEncDriver) encodeArrayPreamble(length int) {
+	e.encLen(bincVdArray<<4, uint64(length))
 }
 }
 
 
-func (e *bincEncoder) encodeMapPreamble(length int) { 
-	e.encLen(bincVdMap << 4, uint64(length))
+func (e *bincEncDriver) encodeMapPreamble(length int) {
+	e.encLen(bincVdMap<<4, uint64(length))
 }
 }
 
 
-func (e *bincEncoder) encodeString(c charEncoding, v string) { 
+func (e *bincEncDriver) encodeString(c charEncoding, v string) {
 	l := uint64(len(v))
 	l := uint64(len(v))
 	e.encBytesLen(c, l)
 	e.encBytesLen(c, l)
 	if l > 0 {
 	if l > 0 {
 		e.w.writestr(v)
 		e.w.writestr(v)
-	}	
+	}
 }
 }
 
 
-func (e *bincEncoder) encodeSymbol(v string) { 
+func (e *bincEncDriver) encodeSymbol(v string) {
 	//if true { e.encodeString(c_UTF8, v); return; }
 	//if true { e.encodeString(c_UTF8, v); return; }
-	
+
 	//symbols only offer benefit when string length > 1.
 	//symbols only offer benefit when string length > 1.
-	//This is because strings with length 1 take only 2 bytes to store 
+	//This is because strings with length 1 take only 2 bytes to store
 	//(bd with embedded length, and single byte for string val).
 	//(bd with embedded length, and single byte for string val).
-	
+
 	l := len(v)
 	l := len(v)
 	switch l {
 	switch l {
 	case 0:
 	case 0:
@@ -262,9 +253,9 @@ func (e *bincEncoder) encodeSymbol(v string) {
 	ui, ok := e.m[v]
 	ui, ok := e.m[v]
 	if ok {
 	if ok {
 		if ui <= math.MaxUint8 {
 		if ui <= math.MaxUint8 {
-			e.w.writen2(bincVdSymbol << 4, byte(ui))
+			e.w.writen2(bincVdSymbol<<4, byte(ui))
 		} else {
 		} else {
-			e.w.writen1(bincVdSymbol << 4 | 0x8)
+			e.w.writen1(bincVdSymbol<<4 | 0x8)
 			e.w.writeUint16(ui)
 			e.w.writeUint16(ui)
 		}
 		}
 	} else {
 	} else {
@@ -282,9 +273,9 @@ func (e *bincEncoder) encodeSymbol(v string) {
 			lenprec = 3
 			lenprec = 3
 		}
 		}
 		if ui <= math.MaxUint8 {
 		if ui <= math.MaxUint8 {
-			e.w.writen2(bincVdSymbol << 4 | 0x0 | 0x4 | lenprec, byte(ui))
+			e.w.writen2(bincVdSymbol<<4|0x0|0x4|lenprec, byte(ui))
 		} else {
 		} else {
-			e.w.writen1(bincVdSymbol << 4 | 0x8 | 0x4 | lenprec)
+			e.w.writen1(bincVdSymbol<<4 | 0x8 | 0x4 | lenprec)
 			e.w.writeUint16(ui)
 			e.w.writeUint16(ui)
 		}
 		}
 		switch lenprec {
 		switch lenprec {
@@ -298,35 +289,35 @@ func (e *bincEncoder) encodeSymbol(v string) {
 			e.w.writeUint64(uint64(l))
 			e.w.writeUint64(uint64(l))
 		}
 		}
 		e.w.writestr(v)
 		e.w.writestr(v)
-	}	
+	}
 }
 }
 
 
-func (e *bincEncoder) encodeStringBytes(c charEncoding, v []byte) { 
+func (e *bincEncDriver) encodeStringBytes(c charEncoding, v []byte) {
 	l := uint64(len(v))
 	l := uint64(len(v))
 	e.encBytesLen(c, l)
 	e.encBytesLen(c, l)
 	if l > 0 {
 	if l > 0 {
 		e.w.writeb(v)
 		e.w.writeb(v)
-	}	
+	}
 }
 }
 
 
-func (e *bincEncoder) encBytesLen(c charEncoding, length uint64) {
+func (e *bincEncDriver) encBytesLen(c charEncoding, length uint64) {
 	//TODO: support bincUnicodeOther (for now, just use string or bytearray)
 	//TODO: support bincUnicodeOther (for now, just use string or bytearray)
 	if c == c_RAW {
 	if c == c_RAW {
-		e.encLen(bincVdByteArray << 4, length)
+		e.encLen(bincVdByteArray<<4, length)
 	} else {
 	} else {
-		e.encLen(bincVdString << 4, length)
+		e.encLen(bincVdString<<4, length)
 	}
 	}
 }
 }
 
 
-func (e *bincEncoder) encLen(bd byte, l uint64) {
+func (e *bincEncDriver) encLen(bd byte, l uint64) {
 	if l < 12 {
 	if l < 12 {
-		e.w.writen1(bd | uint8(l + 4))
+		e.w.writen1(bd | uint8(l+4))
 	} else {
 	} else {
 		e.encLenNumber(bd, l)
 		e.encLenNumber(bd, l)
 	}
 	}
 }
 }
-	
-func (e *bincEncoder) encLenNumber(bd byte, v uint64) {
+
+func (e *bincEncDriver) encLenNumber(bd byte, v uint64) {
 	switch {
 	switch {
 	case v <= math.MaxUint8:
 	case v <= math.MaxUint8:
 		e.w.writen2(bd, byte(v))
 		e.w.writen2(bd, byte(v))
@@ -342,11 +333,9 @@ func (e *bincEncoder) encLenNumber(bd byte, v uint64) {
 	}
 	}
 }
 }
 
 
-
 //------------------------------------
 //------------------------------------
 
 
-
-func (d *bincDecoder) initReadNext() {
+func (d *bincDecDriver) initReadNext() {
 	if d.bdRead {
 	if d.bdRead {
 		return
 		return
 	}
 	}
@@ -356,15 +345,15 @@ func (d *bincDecoder) initReadNext() {
 	d.bdRead = true
 	d.bdRead = true
 }
 }
 
 
-func (d *bincDecoder) currentIsNil() bool {
-	if d.bd == bincVdSpecial << 4 | bincSpNil {
+func (d *bincDecDriver) currentIsNil() bool {
+	if d.bd == bincVdSpecial<<4|bincSpNil {
 		d.bdRead = false
 		d.bdRead = false
 		return true
 		return true
-	} 
+	}
 	return false
 	return false
 }
 }
 
 
-func (d *bincDecoder) decodeBuiltinType(rt reflect.Type, rv reflect.Value) bool {
+func (d *bincDecDriver) decodeBuiltinType(rt reflect.Type, rv reflect.Value) bool {
 	switch rt {
 	switch rt {
 	case timeTyp:
 	case timeTyp:
 		if d.vd != bincVdTimestamp {
 		if d.vd != bincVdTimestamp {
@@ -381,8 +370,8 @@ func (d *bincDecoder) decodeBuiltinType(rt reflect.Type, rv reflect.Value) bool
 	return false
 	return false
 }
 }
 
 
-func (d *bincDecoder) decFloatPre(vs, defaultLen byte) {
-	if vs & 0x8 == 0 {
+func (d *bincDecDriver) decFloatPre(vs, defaultLen byte) {
+	if vs&0x8 == 0 {
 		d.r.readb(d.b[0:defaultLen])
 		d.r.readb(d.b[0:defaultLen])
 	} else {
 	} else {
 		l := d.r.readn1()
 		l := d.r.readn1()
@@ -396,9 +385,9 @@ func (d *bincDecoder) decFloatPre(vs, defaultLen byte) {
 	}
 	}
 }
 }
 
 
-func (d *bincDecoder) decFloat() (f float64) {
+func (d *bincDecDriver) decFloat() (f float64) {
 	//if true { f = math.Float64frombits(d.r.readUint64()); break; }
 	//if true { f = math.Float64frombits(d.r.readUint64()); break; }
-	switch vs := d.vs; (vs & 0x7) {
+	switch vs := d.vs; vs & 0x7 {
 	case bincFlBin32:
 	case bincFlBin32:
 		d.decFloatPre(vs, 4)
 		d.decFloatPre(vs, 4)
 		f = float64(math.Float32frombits(bigen.Uint32(d.b[0:4])))
 		f = float64(math.Float32frombits(bigen.Uint32(d.b[0:4])))
@@ -411,7 +400,7 @@ func (d *bincDecoder) decFloat() (f float64) {
 	return
 	return
 }
 }
 
 
-func (d *bincDecoder) decInt() (v int64) {
+func (d *bincDecDriver) decInt() (v int64) {
 	// need to inline the code (interface conversion and type assertion expensive)
 	// need to inline the code (interface conversion and type assertion expensive)
 	switch d.vs {
 	switch d.vs {
 	case 0:
 	case 0:
@@ -421,7 +410,7 @@ func (d *bincDecoder) decInt() (v int64) {
 		v = int64(int16(bigen.Uint16(d.b[6:])))
 		v = int64(int16(bigen.Uint16(d.b[6:])))
 	case 2:
 	case 2:
 		d.r.readb(d.b[5:])
 		d.r.readb(d.b[5:])
-		if d.b[5] & 0x80 == 0 {
+		if d.b[5]&0x80 == 0 {
 			d.b[4] = 0
 			d.b[4] = 0
 		} else {
 		} else {
 			d.b[4] = 0xff
 			d.b[4] = 0xff
@@ -430,11 +419,11 @@ func (d *bincDecoder) decInt() (v int64) {
 	case 3:
 	case 3:
 		d.r.readb(d.b[4:])
 		d.r.readb(d.b[4:])
 		v = int64(int32(bigen.Uint32(d.b[4:])))
 		v = int64(int32(bigen.Uint32(d.b[4:])))
-	case 4,5,6:
-		lim := int(7-d.vs)
+	case 4, 5, 6:
+		lim := int(7 - d.vs)
 		d.r.readb(d.b[lim:])
 		d.r.readb(d.b[lim:])
 		var fillval byte = 0
 		var fillval byte = 0
-		if d.b[lim] & 0x80 != 0 {
+		if d.b[lim]&0x80 != 0 {
 			fillval = 0xff
 			fillval = 0xff
 		}
 		}
 		for i := 0; i < lim; i++ {
 		for i := 0; i < lim; i++ {
@@ -447,10 +436,10 @@ func (d *bincDecoder) decInt() (v int64) {
 	default:
 	default:
 		decErr("integers with greater than 64 bits of precision not supported")
 		decErr("integers with greater than 64 bits of precision not supported")
 	}
 	}
-	return 
+	return
 }
 }
 
 
-func (d *bincDecoder) decUint() (v uint64) {
+func (d *bincDecDriver) decUint() (v uint64) {
 	// need to inline the code (interface conversion and type assertion expensive)
 	// need to inline the code (interface conversion and type assertion expensive)
 	switch d.vs {
 	switch d.vs {
 	case 0:
 	case 0:
@@ -465,8 +454,8 @@ func (d *bincDecoder) decUint() (v uint64) {
 	case 3:
 	case 3:
 		d.r.readb(d.b[4:])
 		d.r.readb(d.b[4:])
 		v = uint64(bigen.Uint32(d.b[4:]))
 		v = uint64(bigen.Uint32(d.b[4:]))
-	case 4,5,6:
-		lim := int(7-d.vs)
+	case 4, 5, 6:
+		lim := int(7 - d.vs)
 		d.r.readb(d.b[lim:])
 		d.r.readb(d.b[lim:])
 		for i := 0; i < lim; i++ {
 		for i := 0; i < lim; i++ {
 			d.b[i] = 0
 			d.b[i] = 0
@@ -478,12 +467,12 @@ func (d *bincDecoder) decUint() (v uint64) {
 	default:
 	default:
 		decErr("unsigned integers with greater than 64 bits of precision not supported")
 		decErr("unsigned integers with greater than 64 bits of precision not supported")
 	}
 	}
-	return 
+	return
 }
 }
 
 
-func (d *bincDecoder) decIntAny() (i int64) {
+func (d *bincDecDriver) decIntAny() (i int64) {
 	switch d.vd {
 	switch d.vd {
-	case bincVdInt: 
+	case bincVdInt:
 		i = d.decInt()
 		i = d.decInt()
 	case bincVdSmallInt:
 	case bincVdSmallInt:
 		i = int64(d.vs) + 1
 		i = int64(d.vs) + 1
@@ -501,10 +490,10 @@ func (d *bincDecoder) decIntAny() (i int64) {
 	}
 	}
 	return
 	return
 }
 }
-		
-func (d *bincDecoder) decodeInt(bitsize uint8) (i int64) {
+
+func (d *bincDecDriver) decodeInt(bitsize uint8) (i int64) {
 	switch d.vd {
 	switch d.vd {
-	case bincVdUint: 
+	case bincVdUint:
 		i = int64(d.decUint())
 		i = int64(d.decUint())
 	default:
 	default:
 		i = d.decIntAny()
 		i = d.decIntAny()
@@ -519,9 +508,9 @@ func (d *bincDecoder) decodeInt(bitsize uint8) (i int64) {
 	return
 	return
 }
 }
 
 
-func (d *bincDecoder) decodeUint(bitsize uint8) (ui uint64)  {
+func (d *bincDecDriver) decodeUint(bitsize uint8) (ui uint64) {
 	switch d.vd {
 	switch d.vd {
-	case bincVdUint: 
+	case bincVdUint:
 		ui = d.decUint()
 		ui = d.decUint()
 	default:
 	default:
 		if i := d.decIntAny(); i >= 0 {
 		if i := d.decIntAny(); i >= 0 {
@@ -529,18 +518,18 @@ func (d *bincDecoder) decodeUint(bitsize uint8) (ui uint64)  {
 		} else {
 		} else {
 			decErr("Assigning negative signed value: %v, to unsigned type", i)
 			decErr("Assigning negative signed value: %v, to unsigned type", i)
 		}
 		}
-	}	
+	}
 	// check overflow (logic adapted from std pkg reflect/value.go OverflowUint()
 	// check overflow (logic adapted from std pkg reflect/value.go OverflowUint()
 	if bitsize > 0 {
 	if bitsize > 0 {
 		if trunc := (ui << (64 - bitsize)) >> (64 - bitsize); ui != trunc {
 		if trunc := (ui << (64 - bitsize)) >> (64 - bitsize); ui != trunc {
-			decErr("Overflow uint value: %v", ui) 
+			decErr("Overflow uint value: %v", ui)
 		}
 		}
 	}
 	}
 	d.bdRead = false
 	d.bdRead = false
 	return
 	return
 }
 }
 
 
-func (d *bincDecoder) decodeFloat(chkOverflow32 bool) (f float64) {
+func (d *bincDecDriver) decodeFloat(chkOverflow32 bool) (f float64) {
 	if d.vd == bincVdSpecial {
 	if d.vd == bincVdSpecial {
 		switch d.vs {
 		switch d.vs {
 		case bincSpNan:
 		case bincSpNan:
@@ -548,20 +537,20 @@ func (d *bincDecoder) decodeFloat(chkOverflow32 bool) (f float64) {
 		case bincSpPosInf:
 		case bincSpPosInf:
 			return math.Inf(1)
 			return math.Inf(1)
 		case bincSpZeroFloat:
 		case bincSpZeroFloat:
-			return 
+			return
 		case bincSpNegInf:
 		case bincSpNegInf:
 			return math.Inf(-1)
 			return math.Inf(-1)
 		}
 		}
 	}
 	}
 	switch d.vd {
 	switch d.vd {
-	case bincVdFloat: 
+	case bincVdFloat:
 		f = d.decFloat()
 		f = d.decFloat()
-	case bincVdUint: 
+	case bincVdUint:
 		f = float64(d.decUint())
 		f = float64(d.decUint())
 	default:
 	default:
 		f = float64(d.decIntAny())
 		f = float64(d.decIntAny())
 	}
 	}
-	
+
 	// check overflow (logic adapted from std pkg reflect/value.go OverflowFloat()
 	// check overflow (logic adapted from std pkg reflect/value.go OverflowFloat()
 	if chkOverflow32 {
 	if chkOverflow32 {
 		f2 := f
 		f2 := f
@@ -576,9 +565,8 @@ func (d *bincDecoder) decodeFloat(chkOverflow32 bool) (f float64) {
 	return
 	return
 }
 }
 
 
-
 // bool can be decoded from bool only (single byte).
 // bool can be decoded from bool only (single byte).
-func (d *bincDecoder) decodeBool() (b bool)  {
+func (d *bincDecDriver) decodeBool() (b bool) {
 	switch d.bd {
 	switch d.bd {
 	case (bincVdSpecial | bincSpFalse):
 	case (bincVdSpecial | bincSpFalse):
 		// b = false
 		// b = false
@@ -591,7 +579,7 @@ func (d *bincDecoder) decodeBool() (b bool)  {
 	return
 	return
 }
 }
 
 
-func (d *bincDecoder) readMapLen() (length int) {
+func (d *bincDecDriver) readMapLen() (length int) {
 	if d.vd != bincVdMap {
 	if d.vd != bincVdMap {
 		decErr("Invalid d.vd for map. Expecting 0x%x. Got: 0x%x", bincVdMap, d.vd)
 		decErr("Invalid d.vd for map. Expecting 0x%x. Got: 0x%x", bincVdMap, d.vd)
 	}
 	}
@@ -600,7 +588,7 @@ func (d *bincDecoder) readMapLen() (length int) {
 	return
 	return
 }
 }
 
 
-func (d *bincDecoder) readArrayLen() (length int) {
+func (d *bincDecDriver) readArrayLen() (length int) {
 	if d.vd != bincVdArray {
 	if d.vd != bincVdArray {
 		decErr("Invalid d.vd for array. Expecting 0x%x. Got: 0x%x", bincVdArray, d.vd)
 		decErr("Invalid d.vd for array. Expecting 0x%x. Got: 0x%x", bincVdArray, d.vd)
 	}
 	}
@@ -609,28 +597,28 @@ func (d *bincDecoder) readArrayLen() (length int) {
 	return
 	return
 }
 }
 
 
-func (d *bincDecoder) decLen() int {
+func (d *bincDecDriver) decLen() int {
 	if d.vs <= 3 {
 	if d.vs <= 3 {
 		return int(d.decUint())
 		return int(d.decUint())
-	} 
+	}
 	return int(d.vs - 4)
 	return int(d.vs - 4)
 }
 }
 
 
-func (d *bincDecoder) decodeString() (s string) {
+func (d *bincDecDriver) decodeString() (s string) {
 	switch d.vd {
 	switch d.vd {
 	case bincVdString, bincVdByteArray:
 	case bincVdString, bincVdByteArray:
 		if length := d.decLen(); length > 0 {
 		if length := d.decLen(); length > 0 {
 			s = string(d.r.readn(length))
 			s = string(d.r.readn(length))
 		}
 		}
 	case bincVdSymbol:
 	case bincVdSymbol:
-		//from vs: extract numSymbolBytes, containsStringVal, strLenPrecision, 
+		//from vs: extract numSymbolBytes, containsStringVal, strLenPrecision,
 		//extract symbol
 		//extract symbol
 		//if containsStringVal, read it and put in map
 		//if containsStringVal, read it and put in map
 		//else look in map for string value
 		//else look in map for string value
 		var symbol uint16
 		var symbol uint16
 		vs := d.vs
 		vs := d.vs
 		//fmt.Printf(">>>> d.vs: 0b%b, & 0x8: %v, & 0x4: %v\n", d.vs, vs & 0x8, vs & 0x4)
 		//fmt.Printf(">>>> d.vs: 0b%b, & 0x8: %v, & 0x4: %v\n", d.vs, vs & 0x8, vs & 0x4)
-		if vs & 0x8 == 0 {
+		if vs&0x8 == 0 {
 			symbol = uint16(d.r.readn1())
 			symbol = uint16(d.r.readn1())
 		} else {
 		} else {
 			symbol = d.r.readUint16()
 			symbol = d.r.readUint16()
@@ -639,8 +627,8 @@ func (d *bincDecoder) decodeString() (s string) {
 		if d.m == nil {
 		if d.m == nil {
 			d.m = make(map[uint16]string, 16)
 			d.m = make(map[uint16]string, 16)
 		}
 		}
-		
-		if vs & 0x4 == 0 {
+
+		if vs&0x4 == 0 {
 			s = d.m[symbol]
 			s = d.m[symbol]
 		} else {
 		} else {
 			//println(">>>> will store symbol")
 			//println(">>>> will store symbol")
@@ -661,24 +649,24 @@ func (d *bincDecoder) decodeString() (s string) {
 			d.m[symbol] = s
 			d.m[symbol] = s
 		}
 		}
 	default:
 	default:
-		decErr("Invalid d.vd for string. Expecting string:0x%x, bytearray:0x%x or symbol: 0x%x. Got: 0x%x", 
+		decErr("Invalid d.vd for string. Expecting string:0x%x, bytearray:0x%x or symbol: 0x%x. Got: 0x%x",
 			bincVdString, bincVdByteArray, bincVdSymbol, d.vd)
 			bincVdString, bincVdByteArray, bincVdSymbol, d.vd)
 	}
 	}
 	d.bdRead = false
 	d.bdRead = false
 	return
 	return
 }
 }
 
 
-func (d *bincDecoder) decodeBytes(bs []byte) (bsOut []byte, changed bool) {
-	var clen int 
+func (d *bincDecDriver) decodeBytes(bs []byte) (bsOut []byte, changed bool) {
+	var clen int
 	switch d.vd {
 	switch d.vd {
 	case bincVdString, bincVdByteArray:
 	case bincVdString, bincVdByteArray:
 		clen = d.decLen()
 		clen = d.decLen()
 	default:
 	default:
-		decErr("Invalid d.vd for bytes. Expecting string:0x%x or bytearray:0x%x. Got: 0x%x", 
+		decErr("Invalid d.vd for bytes. Expecting string:0x%x or bytearray:0x%x. Got: 0x%x",
 			bincVdString, bincVdByteArray, d.vd)
 			bincVdString, bincVdByteArray, d.vd)
 	}
 	}
 	if clen > 0 {
 	if clen > 0 {
-		// if no contents in stream, don't update the passed byteslice	
+		// if no contents in stream, don't update the passed byteslice
 		if len(bs) != clen {
 		if len(bs) != clen {
 			if len(bs) > clen {
 			if len(bs) > clen {
 				bs = bs[:clen]
 				bs = bs[:clen]
@@ -694,7 +682,7 @@ func (d *bincDecoder) decodeBytes(bs []byte) (bsOut []byte, changed bool) {
 	return
 	return
 }
 }
 
 
-func (d *bincDecoder) decodeExt(tag byte) (xbs []byte) {
+func (d *bincDecDriver) decodeExt(tag byte) (xbs []byte) {
 	switch d.vd {
 	switch d.vd {
 	case bincVdCustomExt:
 	case bincVdCustomExt:
 		l := d.decLen()
 		l := d.decLen()
@@ -708,10 +696,10 @@ func (d *bincDecoder) decodeExt(tag byte) (xbs []byte) {
 		decErr("Invalid d.vd for extensions (Expecting extensions or byte array). Got: 0x%x", d.vd)
 		decErr("Invalid d.vd for extensions (Expecting extensions or byte array). Got: 0x%x", d.vd)
 	}
 	}
 	d.bdRead = false
 	d.bdRead = false
-	return	
+	return
 }
 }
 
 
-func (d *bincDecoder) decodeNaked(h decodeHandleI) (rv reflect.Value, ctx decodeNakedContext) {
+func (d *bincDecDriver) decodeNaked(h decodeHandleI) (rv reflect.Value, ctx decodeNakedContext) {
 	d.initReadNext()
 	d.initReadNext()
 	var v interface{}
 	var v interface{}
 
 
@@ -776,7 +764,7 @@ func (d *bincDecoder) decodeNaked(h decodeHandleI) (rv reflect.Value, ctx decode
 		}
 		}
 		if fnerr := bfn(rv, d.r.readn(l)); fnerr != nil {
 		if fnerr := bfn(rv, d.r.readn(l)); fnerr != nil {
 			panic(fnerr)
 			panic(fnerr)
-		} 
+		}
 	case bincVdArray:
 	case bincVdArray:
 		ctx = dncContainer
 		ctx = dncContainer
 		opts := h.(*BincHandle)
 		opts := h.(*BincHandle)
@@ -805,4 +793,3 @@ func (d *bincDecoder) decodeNaked(h decodeHandleI) (rv reflect.Value, ctx decode
 	}
 	}
 	return
 	return
 }
 }
-

+ 156 - 158
codec/codecs_test.go

@@ -11,7 +11,7 @@ package codec
 // First test internally encodes and decodes things and verifies that
 // First test internally encodes and decodes things and verifies that
 // the artifact was as expected.
 // the artifact was as expected.
 // Second test will use python msgpack to create a bunch of golden files,
 // Second test will use python msgpack to create a bunch of golden files,
-// read those files, and compare them to what it should be. It then 
+// read those files, and compare them to what it should be. It then
 // writes those files back out and compares the byte streams.
 // writes those files back out and compares the byte streams.
 //
 //
 // Taken together, the tests are pretty extensive.
 // Taken together, the tests are pretty extensive.
@@ -21,24 +21,25 @@ package codec
 //   for positive numbers.
 //   for positive numbers.
 
 
 import (
 import (
-	"reflect"
-	"testing"
-	"net/rpc"
 	"bytes"
 	"bytes"
-	"time"
+	"encoding/gob"
+	"flag"
+	"fmt"
+	"io/ioutil"
+	"math"
+	"net"
+	"net/rpc"
 	"os"
 	"os"
 	"os/exec"
 	"os/exec"
-	"io/ioutil"
 	"path/filepath"
 	"path/filepath"
+	"reflect"
 	"strconv"
 	"strconv"
-	"net"
-	"fmt"
-	"flag"
-	"math"
-	"encoding/gob"
+	"testing"
+	"time"
 )
 )
 
 
-type testVerifyArg int 
+type testVerifyArg int
+
 const (
 const (
 	testVerifyMapTypeSame testVerifyArg = iota
 	testVerifyMapTypeSame testVerifyArg = iota
 	testVerifyMapTypeStrIntf
 	testVerifyMapTypeStrIntf
@@ -46,22 +47,22 @@ const (
 )
 )
 
 
 var (
 var (
-	testInitDebug bool
+	testInitDebug   bool
 	testUseIoEncDec bool
 	testUseIoEncDec bool
-	_ = fmt.Printf
-	skipVerifyVal interface{} = &(struct{}{})
-	timeLoc = time.FixedZone("UTC-08:00", -8*60*60) //time.UTC
-	timeToCompare = time.Date(2012, 2, 2, 2, 2, 2, 2000, timeLoc) //time.Time{} 
+	_                           = fmt.Printf
+	skipVerifyVal   interface{} = &(struct{}{})
+	timeLoc                     = time.FixedZone("UTC-08:00", -8*60*60)         //time.UTC
+	timeToCompare               = time.Date(2012, 2, 2, 2, 2, 2, 2000, timeLoc) //time.Time{}
 	//"2012-02-02T02:02:02.000002000Z" //1328148122000002
 	//"2012-02-02T02:02:02.000002000Z" //1328148122000002
-	timeToCompareAs interface{} = timeToCompare.UnixNano() 
-	table []interface{}               // main items we encode
-	tableVerify []interface{}         // we verify encoded things against this after decode
-	tableTestNilVerify []interface{}  // for nil interface, use this to verify (rules are different)
-	tablePythonVerify []interface{}   // for verifying for python, since Python sometimes
-                                      // will encode a float32 as float64, or large int as uint
-	testRpcInt = new(TestRpcInt)
+	timeToCompareAs    interface{}   = timeToCompare.UnixNano()
+	table              []interface{} // main items we encode
+	tableVerify        []interface{} // we verify encoded things against this after decode
+	tableTestNilVerify []interface{} // for nil interface, use this to verify (rules are different)
+	tablePythonVerify  []interface{} // for verifying for python, since Python sometimes
+	// will encode a float32 as float64, or large int as uint
+	testRpcInt   = new(TestRpcInt)
 	testMsgpackH = &MsgpackHandle{}
 	testMsgpackH = &MsgpackHandle{}
-	testBincH = &BincHandle{}
+	testBincH    = &BincHandle{}
 )
 )
 
 
 func init() {
 func init() {
@@ -74,54 +75,54 @@ func init() {
 		ts0 := newTestStruc(2, false)
 		ts0 := newTestStruc(2, false)
 		fmt.Printf("====> depth: %v, ts: %#v\n", 2, ts0)
 		fmt.Printf("====> depth: %v, ts: %#v\n", 2, ts0)
 	}
 	}
-	
+
 	testMsgpackH.AddExt(byteSliceTyp, 0, testMsgpackH.BinaryEncodeExt, testMsgpackH.BinaryDecodeExt)
 	testMsgpackH.AddExt(byteSliceTyp, 0, testMsgpackH.BinaryEncodeExt, testMsgpackH.BinaryDecodeExt)
 	testMsgpackH.AddExt(timeTyp, 1, testMsgpackH.TimeEncodeExt, testMsgpackH.TimeDecodeExt)
 	testMsgpackH.AddExt(timeTyp, 1, testMsgpackH.TimeEncodeExt, testMsgpackH.TimeDecodeExt)
 }
 }
 
 
 type AnonInTestStruc struct {
 type AnonInTestStruc struct {
-	AS string
-	AI64 int64
-	AI16 int16
-	AUi64 uint64
-	ASslice []string
+	AS        string
+	AI64      int64
+	AI16      int16
+	AUi64     uint64
+	ASslice   []string
 	AI64slice []int64
 	AI64slice []int64
 }
 }
 
 
 type TestStruc struct {
 type TestStruc struct {
-	S string
-	I64 int64
-	I16 int16
+	S    string
+	I64  int64
+	I16  int16
 	Ui64 uint64
 	Ui64 uint64
-	Ui8 uint8
-	B bool
-	By byte
-	
-	Sslice []string
-	I64slice []int64
-	I16slice []int16
+	Ui8  uint8
+	B    bool
+	By   byte
+
+	Sslice    []string
+	I64slice  []int64
+	I16slice  []int16
 	Ui64slice []uint64
 	Ui64slice []uint64
-	Ui8slice []uint8
-	Bslice []bool
-	Byslice []byte
-	
-	Islice []interface{}
+	Ui8slice  []uint8
+	Bslice    []bool
+	Byslice   []byte
+
+	Islice    []interface{}
 	Iptrslice []*int64
 	Iptrslice []*int64
-	
+
 	AnonInTestStruc
 	AnonInTestStruc
-	
+
 	//M map[interface{}]interface{}  `json:"-",bson:"-"`
 	//M map[interface{}]interface{}  `json:"-",bson:"-"`
-	Ms map[string]interface{}
+	Ms    map[string]interface{}
 	Msi64 map[string]int64
 	Msi64 map[string]int64
-	
-	Nintf interface{}    //don't set this, so we can test for nil
-	T time.Time          
-	Nmap map[string]bool //don't set this, so we can test for nil
-	Nslice []byte        //don't set this, so we can test for nil
-	Nint64 *int64        //don't set this, so we can test for nil
-	Mtsptr map[string]*TestStruc
-	Mts map[string]TestStruc
-	Its []*TestStruc
+
+	Nintf      interface{} //don't set this, so we can test for nil
+	T          time.Time
+	Nmap       map[string]bool //don't set this, so we can test for nil
+	Nslice     []byte          //don't set this, so we can test for nil
+	Nint64     *int64          //don't set this, so we can test for nil
+	Mtsptr     map[string]*TestStruc
+	Mts        map[string]TestStruc
+	Its        []*TestStruc
 	Nteststruc *TestStruc
 	Nteststruc *TestStruc
 }
 }
 
 
@@ -129,9 +130,9 @@ type TestRpcInt struct {
 	i int
 	i int
 }
 }
 
 
-func (r *TestRpcInt) Update(n int, res *int) error { r.i = n; *res = r.i; return nil }
+func (r *TestRpcInt) Update(n int, res *int) error      { r.i = n; *res = r.i; return nil }
 func (r *TestRpcInt) Square(ignore int, res *int) error { *res = r.i * r.i; return nil }
 func (r *TestRpcInt) Square(ignore int, res *int) error { *res = r.i * r.i; return nil }
-func (r *TestRpcInt) Mult(n int, res *int) error { *res = r.i * n; return nil }
+func (r *TestRpcInt) Mult(n int, res *int) error        { *res = r.i * n; return nil }
 
 
 func testVerifyVal(v interface{}, arg testVerifyArg) (v2 interface{}) {
 func testVerifyVal(v interface{}, arg testVerifyArg) (v2 interface{}) {
 	switch iv := v.(type) {
 	switch iv := v.(type) {
@@ -161,13 +162,13 @@ func testVerifyVal(v interface{}, arg testVerifyArg) (v2 interface{}) {
 			m2[j] = testVerifyVal(vj, arg)
 			m2[j] = testVerifyVal(vj, arg)
 		}
 		}
 		v2 = m2
 		v2 = m2
-	case map[string]bool: 
+	case map[string]bool:
 		switch arg {
 		switch arg {
 		case testVerifyMapTypeSame:
 		case testVerifyMapTypeSame:
 			m2 := make(map[string]bool)
 			m2 := make(map[string]bool)
 			for kj, kv := range iv {
 			for kj, kv := range iv {
 				m2[kj] = kv
 				m2[kj] = kv
-			}			
+			}
 			v2 = m2
 			v2 = m2
 		case testVerifyMapTypeStrIntf:
 		case testVerifyMapTypeStrIntf:
 			m2 := make(map[string]interface{})
 			m2 := make(map[string]interface{})
@@ -182,7 +183,7 @@ func testVerifyVal(v interface{}, arg testVerifyArg) (v2 interface{}) {
 			}
 			}
 			v2 = m2
 			v2 = m2
 		}
 		}
-	case map[string]interface{}: 
+	case map[string]interface{}:
 		switch arg {
 		switch arg {
 		case testVerifyMapTypeSame:
 		case testVerifyMapTypeSame:
 			m2 := make(map[string]interface{})
 			m2 := make(map[string]interface{})
@@ -203,7 +204,7 @@ func testVerifyVal(v interface{}, arg testVerifyArg) (v2 interface{}) {
 			}
 			}
 			v2 = m2
 			v2 = m2
 		}
 		}
-	case map[interface{}]interface{}: 
+	case map[interface{}]interface{}:
 		m2 := make(map[interface{}]interface{})
 		m2 := make(map[interface{}]interface{})
 		for kj, kv := range iv {
 		for kj, kv := range iv {
 			m2[testVerifyVal(kj, arg)] = testVerifyVal(kv, arg)
 			m2[testVerifyVal(kj, arg)] = testVerifyVal(kv, arg)
@@ -216,7 +217,7 @@ func testVerifyVal(v interface{}, arg testVerifyArg) (v2 interface{}) {
 }
 }
 
 
 func init() {
 func init() {
-	primitives := []interface{} {
+	primitives := []interface{}{
 		int8(-8),
 		int8(-8),
 		int16(-1616),
 		int16(-1616),
 		int32(-32323232),
 		int32(-32323232),
@@ -240,12 +241,12 @@ func init() {
 	}
 	}
 	mapsAndStrucs := []interface{}{
 	mapsAndStrucs := []interface{}{
 		map[string]bool{
 		map[string]bool{
-			"true":true,
-			"false":false,
+			"true":  true,
+			"false": false,
 		},
 		},
 		map[string]interface{}{
 		map[string]interface{}{
-			"true": "True",
-			"false": false,
+			"true":         "True",
+			"false":        false,
 			"uint16(1616)": uint16(1616),
 			"uint16(1616)": uint16(1616),
 		},
 		},
 		//add a complex combo map in here. (map has list which has map)
 		//add a complex combo map in here. (map has list which has map)
@@ -256,25 +257,25 @@ func init() {
 				int32(32323232),
 				int32(32323232),
 				true,
 				true,
 				float32(-3232.0),
 				float32(-3232.0),
-				map[string]interface{} {
-					"TRUE":true,
-					"FALSE":false,
+				map[string]interface{}{
+					"TRUE":  true,
+					"FALSE": false,
 				},
 				},
 				[]interface{}{true, false},
 				[]interface{}{true, false},
 			},
 			},
-			"int32": int32(32323232),
-			"bool": true,
-			"LONG STRING": "123456789012345678901234567890123456789012345678901234567890",
+			"int32":        int32(32323232),
+			"bool":         true,
+			"LONG STRING":  "123456789012345678901234567890123456789012345678901234567890",
 			"SHORT STRING": "1234567890",
 			"SHORT STRING": "1234567890",
 		},
 		},
 		map[interface{}]interface{}{
 		map[interface{}]interface{}{
-			true: "true",
+			true:     "true",
 			uint8(8): false,
 			uint8(8): false,
-			"false": uint8(0),
+			"false":  uint8(0),
 		},
 		},
 		newTestStruc(0, false),
 		newTestStruc(0, false),
 	}
 	}
-	
+
 	table = []interface{}{}
 	table = []interface{}{}
 	table = append(table, primitives...)    //0-19 are primitives
 	table = append(table, primitives...)    //0-19 are primitives
 	table = append(table, primitives)       //20 is a list of primitives
 	table = append(table, primitives)       //20 is a list of primitives
@@ -283,14 +284,14 @@ func init() {
 	tableVerify = make([]interface{}, len(table))
 	tableVerify = make([]interface{}, len(table))
 	tableTestNilVerify = make([]interface{}, len(table))
 	tableTestNilVerify = make([]interface{}, len(table))
 	tablePythonVerify = make([]interface{}, len(table))
 	tablePythonVerify = make([]interface{}, len(table))
-	
+
 	lp := len(primitives)
 	lp := len(primitives)
 	av := tableVerify
 	av := tableVerify
 	for i, v := range table {
 	for i, v := range table {
 		if i == lp+3 {
 		if i == lp+3 {
 			av[i] = skipVerifyVal
 			av[i] = skipVerifyVal
 			continue
 			continue
-		} 
+		}
 		switch v.(type) {
 		switch v.(type) {
 		case []interface{}:
 		case []interface{}:
 			av[i] = testVerifyVal(v, testVerifyMapTypeSame)
 			av[i] = testVerifyVal(v, testVerifyMapTypeSame)
@@ -300,21 +301,21 @@ func init() {
 			av[i] = testVerifyVal(v, testVerifyMapTypeSame)
 			av[i] = testVerifyVal(v, testVerifyMapTypeSame)
 		default:
 		default:
 			av[i] = v
 			av[i] = v
-		}				
+		}
 	}
 	}
 
 
 	av = tableTestNilVerify
 	av = tableTestNilVerify
 	for i, v := range table {
 	for i, v := range table {
-		if i > lp+3 { 
+		if i > lp+3 {
 			av[i] = skipVerifyVal
 			av[i] = skipVerifyVal
 			continue
 			continue
 		}
 		}
 		av[i] = testVerifyVal(v, testVerifyMapTypeStrIntf)
 		av[i] = testVerifyVal(v, testVerifyMapTypeStrIntf)
 	}
 	}
-	
+
 	av = tablePythonVerify
 	av = tablePythonVerify
 	for i, v := range table {
 	for i, v := range table {
-		if i > lp+3 { 
+		if i > lp+3 {
 			av[i] = skipVerifyVal
 			av[i] = skipVerifyVal
 			continue
 			continue
 		}
 		}
@@ -332,7 +333,7 @@ func init() {
 			av[i] = m3
 			av[i] = m3
 		case 23:
 		case 23:
 			m2 := make(map[string]interface{})
 			m2 := make(map[string]interface{})
-			for k2, v2 := range av[i].(map[string]interface{}) { 
+			for k2, v2 := range av[i].(map[string]interface{}) {
 				m2[k2] = v2
 				m2[k2] = v2
 			}
 			}
 			m2["int32"] = uint64(32323232)
 			m2["int32"] = uint64(32323232)
@@ -341,7 +342,7 @@ func init() {
 			av[i] = m2
 			av[i] = m2
 		}
 		}
 	}
 	}
-	
+
 	tablePythonVerify = tablePythonVerify[:24]
 	tablePythonVerify = tablePythonVerify[:24]
 }
 }
 
 
@@ -365,28 +366,28 @@ func testMarshal(v interface{}, h Handle) (bs []byte, err error) {
 
 
 func newTestStruc(depth int, bench bool) (ts *TestStruc) {
 func newTestStruc(depth int, bench bool) (ts *TestStruc) {
 	var i64a, i64b, i64c, i64d int64 = 64, 6464, 646464, 64646464
 	var i64a, i64b, i64c, i64d int64 = 64, 6464, 646464, 64646464
-	
-	ts = &TestStruc {
-		S: "some string",
-		I64: math.MaxInt64 * 2 / 3, // 64,
-		I16: 16,
+
+	ts = &TestStruc{
+		S:    "some string",
+		I64:  math.MaxInt64 * 2 / 3, // 64,
+		I16:  16,
 		Ui64: uint64(int64(math.MaxInt64 * 2 / 3)), // 64, //don't use MaxUint64, as bson can't write it
 		Ui64: uint64(int64(math.MaxInt64 * 2 / 3)), // 64, //don't use MaxUint64, as bson can't write it
-		Ui8: 160,
-		B: true,
-		By: 5,
-		
-		Sslice: []string{"one", "two", "three"},
-		I64slice: []int64{1, 2, 3},
-		I16slice: []int16{4, 5, 6},
+		Ui8:  160,
+		B:    true,
+		By:   5,
+
+		Sslice:    []string{"one", "two", "three"},
+		I64slice:  []int64{1, 2, 3},
+		I16slice:  []int16{4, 5, 6},
 		Ui64slice: []uint64{7, 8, 9},
 		Ui64slice: []uint64{7, 8, 9},
-		Ui8slice: []uint8{10, 11, 12},
-		Bslice: []bool{true, false, true, false},
-		Byslice: []byte{13, 14, 15},
-		
+		Ui8slice:  []uint8{10, 11, 12},
+		Bslice:    []bool{true, false, true, false},
+		Byslice:   []byte{13, 14, 15},
+
 		Islice: []interface{}{"true", true, "no", false, uint64(88), float64(0.4)},
 		Islice: []interface{}{"true", true, "no", false, uint64(88), float64(0.4)},
-		
+
 		Ms: map[string]interface{}{
 		Ms: map[string]interface{}{
-			"true": "true",
+			"true":     "true",
 			"int64(9)": false,
 			"int64(9)": false,
 		},
 		},
 		Msi64: map[string]int64{
 		Msi64: map[string]int64{
@@ -395,11 +396,11 @@ func newTestStruc(depth int, bench bool) (ts *TestStruc) {
 		},
 		},
 		T: timeToCompare,
 		T: timeToCompare,
 		AnonInTestStruc: AnonInTestStruc{
 		AnonInTestStruc: AnonInTestStruc{
-			AS: "A-String",
-			AI64: 64,
-			AI16: 16,
-			AUi64: 64,
-			ASslice: []string{"Aone", "Atwo", "Athree"},
+			AS:        "A-String",
+			AI64:      64,
+			AI16:      16,
+			AUi64:     64,
+			ASslice:   []string{"Aone", "Atwo", "Athree"},
 			AI64slice: []int64{1, 2, 3},
 			AI64slice: []int64{1, 2, 3},
 		},
 		},
 	}
 	}
@@ -430,7 +431,7 @@ func newTestStruc(depth int, bench bool) (ts *TestStruc) {
 }
 }
 
 
 // doTestCodecTableOne allows us test for different variations based on arguments passed.
 // doTestCodecTableOne allows us test for different variations based on arguments passed.
-func doTestCodecTableOne(t *testing.T, testNil bool, h Handle, 
+func doTestCodecTableOne(t *testing.T, testNil bool, h Handle,
 	vs []interface{}, vsVerify []interface{}) {
 	vs []interface{}, vsVerify []interface{}) {
 	//if testNil, then just test for when a pointer to a nil interface{} is passed. It should work.
 	//if testNil, then just test for when a pointer to a nil interface{} is passed. It should work.
 	//Current setup allows us test (at least manually) the nil interface or typed interface.
 	//Current setup allows us test (at least manually) the nil interface or typed interface.
@@ -445,9 +446,9 @@ func doTestCodecTableOne(t *testing.T, testNil bool, h Handle,
 			continue
 			continue
 		}
 		}
 		logT(t, "         Encoded bytes: len: %v, %v\n", len(b0), b0)
 		logT(t, "         Encoded bytes: len: %v, %v\n", len(b0), b0)
-		
+
 		var v1 interface{}
 		var v1 interface{}
-		
+
 		if testNil {
 		if testNil {
 			err = testUnmarshal(&v1, b0, h)
 			err = testUnmarshal(&v1, b0, h)
 		} else {
 		} else {
@@ -459,7 +460,7 @@ func doTestCodecTableOne(t *testing.T, testNil bool, h Handle,
 				// v1 = reflect.Indirect(reflect.ValueOf(v1)).Interface()
 				// v1 = reflect.Indirect(reflect.ValueOf(v1)).Interface()
 			}
 			}
 		}
 		}
-		
+
 		logT(t, "         v1 returned: %T, %#v", v1, v1)
 		logT(t, "         v1 returned: %T, %#v", v1, v1)
 		// if v1 != nil {
 		// if v1 != nil {
 		//	logT(t, "         v1 returned: %T, %#v", v1, v1)
 		//	logT(t, "         v1 returned: %T, %#v", v1, v1)
@@ -472,32 +473,31 @@ func doTestCodecTableOne(t *testing.T, testNil bool, h Handle,
 			continue
 			continue
 		}
 		}
 		v0check := vsVerify[i]
 		v0check := vsVerify[i]
-		if v0check == skipVerifyVal { 
+		if v0check == skipVerifyVal {
 			logT(t, "        Nil Check skipped: Decoded: %T, %#v\n", v1, v1)
 			logT(t, "        Nil Check skipped: Decoded: %T, %#v\n", v1, v1)
-			continue 
+			continue
 		}
 		}
-		
-		if err = deepEqual(v0check, v1); err == nil { 
+
+		if err = deepEqual(v0check, v1); err == nil {
 			logT(t, "++++++++ Before and After marshal matched\n")
 			logT(t, "++++++++ Before and After marshal matched\n")
 		} else {
 		} else {
-			logT(t, "-------- Before and After marshal do not match: Error: %v" + 
+			logT(t, "-------- Before and After marshal do not match: Error: %v"+
 				" ====> AGAINST: (%T) %#v, DECODED: (%T) %#v\n", err, v0check, v0check, v1, v1)
 				" ====> AGAINST: (%T) %#v, DECODED: (%T) %#v\n", err, v0check, v0check, v1, v1)
 			failT(t)
 			failT(t)
 		}
 		}
 	}
 	}
 }
 }
 
 
-
 func testCodecTableOne(t *testing.T, h Handle) {
 func testCodecTableOne(t *testing.T, h Handle) {
 	// func TestMsgpackAllExperimental(t *testing.T) {
 	// func TestMsgpackAllExperimental(t *testing.T) {
-	// dopts := testDecOpts(nil, nil, false, true, true), 
+	// dopts := testDecOpts(nil, nil, false, true, true),
 	var oldWriteExt bool
 	var oldWriteExt bool
 	switch v := h.(type) {
 	switch v := h.(type) {
 	case *MsgpackHandle:
 	case *MsgpackHandle:
 		oldWriteExt = v.WriteExt
 		oldWriteExt = v.WriteExt
 		v.WriteExt = true
 		v.WriteExt = true
 	}
 	}
-	doTestCodecTableOne(t, false, h, table, tableVerify) 
+	doTestCodecTableOne(t, false, h, table, tableVerify)
 	//if true { panic("") }
 	//if true { panic("") }
 	switch v := h.(type) {
 	switch v := h.(type) {
 	case *MsgpackHandle:
 	case *MsgpackHandle:
@@ -505,8 +505,8 @@ func testCodecTableOne(t *testing.T, h Handle) {
 	}
 	}
 	// func TestMsgpackAll(t *testing.T) {
 	// func TestMsgpackAll(t *testing.T) {
 
 
-	doTestCodecTableOne(t, false, h, table[:20], tableVerify[:20]) 
-	doTestCodecTableOne(t, false, h, table[21:], tableVerify[21:]) 
+	doTestCodecTableOne(t, false, h, table[:20], tableVerify[:20])
+	doTestCodecTableOne(t, false, h, table[21:], tableVerify[21:])
 
 
 	// func TestMsgpackNilStringMap(t *testing.T) {
 	// func TestMsgpackNilStringMap(t *testing.T) {
 	var oldMapType reflect.Type
 	var oldMapType reflect.Type
@@ -519,10 +519,10 @@ func testCodecTableOne(t *testing.T, h Handle) {
 		v.MapType = mapStringIntfTyp
 		v.MapType = mapStringIntfTyp
 	}
 	}
 	//skip #16 (time.Time), and #20 ([]interface{} containing time.Time)
 	//skip #16 (time.Time), and #20 ([]interface{} containing time.Time)
-	doTestCodecTableOne(t, true, h, table[:16], tableTestNilVerify[:16]) 
+	doTestCodecTableOne(t, true, h, table[:16], tableTestNilVerify[:16])
 	doTestCodecTableOne(t, true, h, table[17:20], tableTestNilVerify[17:20])
 	doTestCodecTableOne(t, true, h, table[17:20], tableTestNilVerify[17:20])
-	doTestCodecTableOne(t, true, h, table[21:24], tableTestNilVerify[21:24]) 
-	
+	doTestCodecTableOne(t, true, h, table[21:24], tableTestNilVerify[21:24])
+
 	switch v := h.(type) {
 	switch v := h.(type) {
 	case *MsgpackHandle:
 	case *MsgpackHandle:
 		v.MapType = oldMapType
 		v.MapType = oldMapType
@@ -530,13 +530,12 @@ func testCodecTableOne(t *testing.T, h Handle) {
 		v.MapType = oldMapType
 		v.MapType = oldMapType
 	}
 	}
 
 
-	// func TestMsgpackNilIntf(t *testing.T) {	
-	doTestCodecTableOne(t, true, h, table[24:], tableTestNilVerify[24:]) 
+	// func TestMsgpackNilIntf(t *testing.T) {
+	doTestCodecTableOne(t, true, h, table[24:], tableTestNilVerify[24:])
 
 
-	doTestCodecTableOne(t, true, h, table[17:18], tableTestNilVerify[17:18]) 
+	doTestCodecTableOne(t, true, h, table[17:18], tableTestNilVerify[17:18])
 }
 }
 
 
-
 func testCodecMiscOne(t *testing.T, h Handle) {
 func testCodecMiscOne(t *testing.T, h Handle) {
 	b, err := testMarshal(32, h)
 	b, err := testMarshal(32, h)
 	// Cannot do this nil one, because faster type assertion decoding will panic
 	// Cannot do this nil one, because faster type assertion decoding will panic
@@ -571,13 +570,13 @@ func testCodecMiscOne(t *testing.T, h Handle) {
 	if err != nil {
 	if err != nil {
 		logT(t, "------- Cannot Unmarshal pointer to struct. Error: %v", err)
 		logT(t, "------- Cannot Unmarshal pointer to struct. Error: %v", err)
 		t.FailNow()
 		t.FailNow()
-	} else if ts2.I64 != math.MaxInt64 * 2 / 3 {
+	} else if ts2.I64 != math.MaxInt64*2/3 {
 		logT(t, "------- Unmarshal wrong. Expect I64 = 64. Got: %v", ts2.I64)
 		logT(t, "------- Unmarshal wrong. Expect I64 = 64. Got: %v", ts2.I64)
 		t.FailNow()
 		t.FailNow()
 	}
 	}
 
 
 	// func TestMsgpackIntfDecode(t *testing.T) {
 	// func TestMsgpackIntfDecode(t *testing.T) {
-	m := map[string]int{"A":2, "B":3, }
+	m := map[string]int{"A": 2, "B": 3}
 	p := []interface{}{m}
 	p := []interface{}{m}
 	bs, err := testMarshal(p, h)
 	bs, err := testMarshal(p, h)
 	if err != nil {
 	if err != nil {
@@ -586,12 +585,12 @@ func testCodecMiscOne(t *testing.T, h Handle) {
 	}
 	}
 	m2 := map[string]int{}
 	m2 := map[string]int{}
 	p2 := []interface{}{m2}
 	p2 := []interface{}{m2}
-    err = testUnmarshal(&p2, bs, h)
+	err = testUnmarshal(&p2, bs, h)
 	if err != nil {
 	if err != nil {
 		logT(t, "Error unmarshalling into &p2: %v, Err: %v", p2, err)
 		logT(t, "Error unmarshalling into &p2: %v, Err: %v", p2, err)
 		t.FailNow()
 		t.FailNow()
 	}
 	}
-	
+
 	if m2["A"] != 2 || m2["B"] != 3 {
 	if m2["A"] != 2 || m2["B"] != 3 {
 		logT(t, "m2 not as expected: expecting: %v, got: %v", m, m2)
 		logT(t, "m2 not as expected: expecting: %v, got: %v", m, m2)
 		t.FailNow()
 		t.FailNow()
@@ -612,7 +611,7 @@ func testCodecMiscOne(t *testing.T, h Handle) {
 
 
 	// func TestMsgpackDecodeStructSubset(t *testing.T) {
 	// func TestMsgpackDecodeStructSubset(t *testing.T) {
 	// test that we can decode a subset of the stream
 	// test that we can decode a subset of the stream
-	mm := map[string]interface{}{"A": 5, "B": 99, "C": 333, }
+	mm := map[string]interface{}{"A": 5, "B": 99, "C": 333}
 	bs, err = testMarshal(mm, h)
 	bs, err = testMarshal(mm, h)
 	if err != nil {
 	if err != nil {
 		logT(t, "Error marshalling m: %v, Err: %v", mm, err)
 		logT(t, "Error marshalling m: %v, Err: %v", mm, err)
@@ -642,14 +641,14 @@ func doTestRpcOne(t *testing.T, rr Rpc, h Handle, callClose, doRequest, doExit b
 	// log("listener: %v", ln.Addr())
 	// log("listener: %v", ln.Addr())
 	checkErrT(t, err)
 	checkErrT(t, err)
 	defer ln.Close()
 	defer ln.Close()
-	
+
 	// var opts *DecoderOptions
 	// var opts *DecoderOptions
 	// opts := testDecOpts
 	// opts := testDecOpts
 	// opts.MapType = mapStringIntfTyp
 	// opts.MapType = mapStringIntfTyp
 	// opts.RawToString = false
 	// opts.RawToString = false
 	serverExitChan := make(chan bool, 1)
 	serverExitChan := make(chan bool, 1)
 	serverFn := func() {
 	serverFn := func() {
-		for { 
+		for {
 			conn1, err1 := ln.Accept()
 			conn1, err1 := ln.Accept()
 			if err1 != nil {
 			if err1 != nil {
 				continue
 				continue
@@ -666,7 +665,7 @@ func doTestRpcOne(t *testing.T, rr Rpc, h Handle, callClose, doRequest, doExit b
 				sc = rr.ServerCodec(conn1, h)
 				sc = rr.ServerCodec(conn1, h)
 			case 'X':
 			case 'X':
 				serverExitChan <- true
 				serverExitChan <- true
-				// <- serverExitChan				
+				// <- serverExitChan
 				conn1.Close()
 				conn1.Close()
 				return // exit serverFn goroutine
 				return // exit serverFn goroutine
 			}
 			}
@@ -681,16 +680,16 @@ func doTestRpcOne(t *testing.T, rr Rpc, h Handle, callClose, doRequest, doExit b
 			// 	}
 			// 	}
 			// }
 			// }
 			// if callClose {
 			// if callClose {
-			// 	sc.Close() 
+			// 	sc.Close()
 			// }
 			// }
 		}
 		}
 	}
 	}
-	
+
 	clientFn := func(cc rpc.ClientCodec) {
 	clientFn := func(cc rpc.ClientCodec) {
 		cl := rpc.NewClientWithCodec(cc)
 		cl := rpc.NewClientWithCodec(cc)
 		if callClose {
 		if callClose {
-			defer cl.Close() 
-		} 
+			defer cl.Close()
+		}
 		var up, sq, mult int
 		var up, sq, mult int
 		// log("Calling client")
 		// log("Calling client")
 		checkErrT(t, cl.Call("TestRpcInt.Update", 5, &up))
 		checkErrT(t, cl.Call("TestRpcInt.Update", 5, &up))
@@ -700,9 +699,9 @@ func doTestRpcOne(t *testing.T, rr Rpc, h Handle, callClose, doRequest, doExit b
 		checkErrT(t, cl.Call("TestRpcInt.Square", 1, &sq))
 		checkErrT(t, cl.Call("TestRpcInt.Square", 1, &sq))
 		checkEqualT(t, sq, 25)
 		checkEqualT(t, sq, 25)
 		checkErrT(t, cl.Call("TestRpcInt.Mult", 20, &mult))
 		checkErrT(t, cl.Call("TestRpcInt.Mult", 20, &mult))
-		checkEqualT(t, mult, 100)		
+		checkEqualT(t, mult, 100)
 	}
 	}
-	
+
 	connFn := func(req byte) (bs net.Conn) {
 	connFn := func(req byte) (bs net.Conn) {
 		// log("calling f1")
 		// log("calling f1")
 		bs, err2 := net.Dial(ln.Addr().Network(), ln.Addr().String())
 		bs, err2 := net.Dial(ln.Addr().Network(), ln.Addr().String())
@@ -713,7 +712,7 @@ func doTestRpcOne(t *testing.T, rr Rpc, h Handle, callClose, doRequest, doExit b
 		checkEqualT(t, n1, 1)
 		checkEqualT(t, n1, 1)
 		return
 		return
 	}
 	}
-	
+
 	go serverFn()
 	go serverFn()
 	if doRequest {
 	if doRequest {
 		bs := connFn('R')
 		bs := connFn('R')
@@ -722,19 +721,19 @@ func doTestRpcOne(t *testing.T, rr Rpc, h Handle, callClose, doRequest, doExit b
 	}
 	}
 	if doExit {
 	if doExit {
 		bs := connFn('X')
 		bs := connFn('X')
-		<- serverExitChan
+		<-serverExitChan
 		bs.Close()
 		bs.Close()
 		// serverExitChan <- true
 		// serverExitChan <- true
 	}
 	}
 }
 }
 
 
-// Comprehensive testing that generates data encoded from python msgpack, 
+// Comprehensive testing that generates data encoded from python msgpack,
 // and validates that our code can read and write it out accordingly.
 // and validates that our code can read and write it out accordingly.
 // We keep this unexported here, and put actual test in ext_dep_test.go.
 // We keep this unexported here, and put actual test in ext_dep_test.go.
 // This way, it can be excluded by excluding file completely.
 // This way, it can be excluded by excluding file completely.
 func doTestMsgpackPythonGenStreams(t *testing.T) {
 func doTestMsgpackPythonGenStreams(t *testing.T) {
 	logT(t, "TestPythonGenStreams")
 	logT(t, "TestPythonGenStreams")
-	tmpdir, err := ioutil.TempDir("", "golang-msgpack-test") 
+	tmpdir, err := ioutil.TempDir("", "golang-msgpack-test")
 	if err != nil {
 	if err != nil {
 		logT(t, "-------- Unable to create temp directory\n")
 		logT(t, "-------- Unable to create temp directory\n")
 		t.FailNow()
 		t.FailNow()
@@ -750,7 +749,7 @@ func doTestMsgpackPythonGenStreams(t *testing.T) {
 		logT(t, "         %v", string(cmdout))
 		logT(t, "         %v", string(cmdout))
 		t.FailNow()
 		t.FailNow()
 	}
 	}
-	
+
 	oldMapType := testMsgpackH.MapType
 	oldMapType := testMsgpackH.MapType
 	for i, v := range tablePythonVerify {
 	for i, v := range tablePythonVerify {
 		testMsgpackH.MapType = oldMapType
 		testMsgpackH.MapType = oldMapType
@@ -760,16 +759,16 @@ func doTestMsgpackPythonGenStreams(t *testing.T) {
 		//encode it again
 		//encode it again
 		//compare to output stream
 		//compare to output stream
 		logT(t, "..............................................")
 		logT(t, "..............................................")
-		logT(t, "         Testing: #%d: %T, %#v\n", i, v, v) 
+		logT(t, "         Testing: #%d: %T, %#v\n", i, v, v)
 		var bss []byte
 		var bss []byte
-		bss, err = ioutil.ReadFile(filepath.Join(tmpdir, strconv.Itoa(i) + ".golden"))
+		bss, err = ioutil.ReadFile(filepath.Join(tmpdir, strconv.Itoa(i)+".golden"))
 		if err != nil {
 		if err != nil {
 			logT(t, "-------- Error reading golden file: %d. Err: %v", i, err)
 			logT(t, "-------- Error reading golden file: %d. Err: %v", i, err)
 			failT(t)
 			failT(t)
 			continue
 			continue
 		}
 		}
 		testMsgpackH.MapType = mapStringIntfTyp
 		testMsgpackH.MapType = mapStringIntfTyp
-		
+
 		var v1 interface{}
 		var v1 interface{}
 		if err = testUnmarshal(&v1, bss, testMsgpackH); err != nil {
 		if err = testUnmarshal(&v1, bss, testMsgpackH); err != nil {
 			logT(t, "-------- Error decoding stream: %d: Err: %v", i, err)
 			logT(t, "-------- Error decoding stream: %d: Err: %v", i, err)
@@ -779,9 +778,9 @@ func doTestMsgpackPythonGenStreams(t *testing.T) {
 		if v == skipVerifyVal {
 		if v == skipVerifyVal {
 			continue
 			continue
 		}
 		}
-		//no need to indirect, because we pass a nil ptr, so we already have the value 
+		//no need to indirect, because we pass a nil ptr, so we already have the value
 		//if v1 != nil { v1 = reflect.Indirect(reflect.ValueOf(v1)).Interface() }
 		//if v1 != nil { v1 = reflect.Indirect(reflect.ValueOf(v1)).Interface() }
-		if err = deepEqual(v, v1); err == nil { 
+		if err = deepEqual(v, v1); err == nil {
 			logT(t, "++++++++ Objects match")
 			logT(t, "++++++++ Objects match")
 		} else {
 		} else {
 			logT(t, "-------- Objects do not match: %v. Source: %T. Decoded: %T", err, v, v1)
 			logT(t, "-------- Objects do not match: %v. Source: %T. Decoded: %T", err, v, v1)
@@ -795,7 +794,7 @@ func doTestMsgpackPythonGenStreams(t *testing.T) {
 			failT(t)
 			failT(t)
 			continue
 			continue
 		}
 		}
-		if err = deepEqual(bsb, bss); err == nil { 
+		if err = deepEqual(bsb, bss); err == nil {
 			logT(t, "++++++++ Bytes match")
 			logT(t, "++++++++ Bytes match")
 		} else {
 		} else {
 			logT(t, "???????? Bytes do not match. %v.", err)
 			logT(t, "???????? Bytes do not match. %v.", err)
@@ -812,7 +811,7 @@ func doTestMsgpackPythonGenStreams(t *testing.T) {
 		}
 		}
 	}
 	}
 	testMsgpackH.MapType = oldMapType
 	testMsgpackH.MapType = oldMapType
-	
+
 }
 }
 
 
 func TestMsgpackCodecsTable(t *testing.T) {
 func TestMsgpackCodecsTable(t *testing.T) {
@@ -828,7 +827,7 @@ func TestBincCodecsTable(t *testing.T) {
 }
 }
 
 
 func TestBincCodecsMisc(t *testing.T) {
 func TestBincCodecsMisc(t *testing.T) {
-	testCodecMiscOne(t, testBincH)	
+	testCodecMiscOne(t, testBincH)
 }
 }
 
 
 func TestMsgpackRpcGo(t *testing.T) {
 func TestMsgpackRpcGo(t *testing.T) {
@@ -841,4 +840,3 @@ func TestMsgpackRpcSpec(t *testing.T) {
 func TestBincRpcGo(t *testing.T) {
 func TestBincRpcGo(t *testing.T) {
 	doTestRpcOne(t, GoRpc, testBincH, true, true, true)
 	doTestRpcOne(t, GoRpc, testBincH, true, true, true)
 }
 }
-

+ 84 - 157
codec/decode.go

@@ -7,18 +7,18 @@ import (
 	"io"
 	"io"
 	"reflect"
 	"reflect"
 	//"math"
 	//"math"
-	"fmt"
-	"time"
+	//"fmt"
 )
 )
 
 
 // Some tagging information for error messages.
 // Some tagging information for error messages.
 var (
 var (
-	msgTagDec = "codec.decoder"
+	msgTagDec  = "codec.decoder"
 	msgBadDesc = "Unrecognized descriptor byte"
 	msgBadDesc = "Unrecognized descriptor byte"
-	digits = [...]byte {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
+	digits     = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
 )
 )
 
 
-type decodeNakedContext uint8 
+type decodeNakedContext uint8
+
 const (
 const (
 	dncHandled decodeNakedContext = iota
 	dncHandled decodeNakedContext = iota
 	dncNil
 	dncNil
@@ -26,7 +26,7 @@ const (
 	dncContainer
 	dncContainer
 )
 )
 
 
-// decReader abstracts the reading source, allowing implementations that can 
+// decReader abstracts the reading source, allowing implementations that can
 // read from an io.Reader or directly off a byte slice with zero-copying.
 // read from an io.Reader or directly off a byte slice with zero-copying.
 type decReader interface {
 type decReader interface {
 	readn(n int) []byte
 	readn(n int) []byte
@@ -37,50 +37,47 @@ type decReader interface {
 	readUint64() uint64
 	readUint64() uint64
 }
 }
 
 
-type decoder interface {
-	initReadNext() 
+type decDriver interface {
+	initReadNext()
 	currentIsNil() bool
 	currentIsNil() bool
 	decodeBuiltinType(rt reflect.Type, rv reflect.Value) bool
 	decodeBuiltinType(rt reflect.Type, rv reflect.Value) bool
 	//decodeNaked should completely handle extensions, builtins, primitives, etc.
 	//decodeNaked should completely handle extensions, builtins, primitives, etc.
 	//Numbers are decoded as int64, uint64, float64 only (no smaller sized number types).
 	//Numbers are decoded as int64, uint64, float64 only (no smaller sized number types).
 	decodeNaked(h decodeHandleI) (rv reflect.Value, ctx decodeNakedContext)
 	decodeNaked(h decodeHandleI) (rv reflect.Value, ctx decodeNakedContext)
 	decodeInt(bitsize uint8) (i int64)
 	decodeInt(bitsize uint8) (i int64)
-	decodeUint(bitsize uint8) (ui uint64) 
+	decodeUint(bitsize uint8) (ui uint64)
 	decodeFloat(chkOverflow32 bool) (f float64)
 	decodeFloat(chkOverflow32 bool) (f float64)
-	decodeBool() (b bool) 
+	decodeBool() (b bool)
 	// decodeString can also decode symbols
 	// decodeString can also decode symbols
-	decodeString() (s string) 
+	decodeString() (s string)
 	decodeBytes(bs []byte) (bsOut []byte, changed bool)
 	decodeBytes(bs []byte) (bsOut []byte, changed bool)
 	decodeExt(tag byte) []byte
 	decodeExt(tag byte) []byte
 	readMapLen() int
 	readMapLen() int
-	readArrayLen() int 
+	readArrayLen() int
 }
 }
 
 
-type newDecoderFunc func(r decReader) decoder 
-
 // A Decoder reads and decodes an object from an input stream in the codec format.
 // A Decoder reads and decodes an object from an input stream in the codec format.
 type Decoder struct {
 type Decoder struct {
 	r decReader
 	r decReader
-	d decoder 
+	d decDriver
 	h decodeHandleI
 	h decodeHandleI
 }
 }
 
 
 // ioDecReader is a decReader that reads off an io.Reader
 // ioDecReader is a decReader that reads off an io.Reader
 type ioDecReader struct {
 type ioDecReader struct {
 	r io.Reader
 	r io.Reader
-	x [8]byte        //temp byte array re-used internally for efficiency
+	x [8]byte //temp byte array re-used internally for efficiency
 }
 }
 
 
-
 // bytesDecReader is a decReader that reads off a byte slice with zero copying
 // bytesDecReader is a decReader that reads off a byte slice with zero copying
 type bytesDecReader struct {
 type bytesDecReader struct {
 	b []byte // data
 	b []byte // data
 	c int    // cursor
 	c int    // cursor
-	a int // available
+	a int    // available
 }
 }
 
 
 type decExtTagFn struct {
 type decExtTagFn struct {
-	fn func(reflect.Value, []byte)(error)
+	fn  func(reflect.Value, []byte) error
 	tag byte
 	tag byte
 }
 }
 
 
@@ -91,14 +88,13 @@ type decExtTypeTagFn struct {
 
 
 type decodeHandleI interface {
 type decodeHandleI interface {
 	getDecodeExt(rt reflect.Type) (tag byte, fn func(reflect.Value, []byte) error)
 	getDecodeExt(rt reflect.Type) (tag byte, fn func(reflect.Value, []byte) error)
-	newDecoder(r decReader) decoder
 	errorIfNoField() bool
 	errorIfNoField() bool
 }
 }
 
 
 type decHandle struct {
 type decHandle struct {
 	// put word-aligned fields first (before bools, etc)
 	// put word-aligned fields first (before bools, etc)
-	exts []decExtTypeTagFn
-	extFuncs map[reflect.Type] decExtTagFn
+	exts     []decExtTypeTagFn
+	extFuncs map[reflect.Type]decExtTagFn
 	// if an extension for byte slice is defined, then always decode Raw as strings
 	// if an extension for byte slice is defined, then always decode Raw as strings
 	rawToStringOverride bool
 	rawToStringOverride bool
 }
 }
@@ -110,7 +106,7 @@ type DecodeOptions struct {
 	// An instance of SliceType is used during schema-less decoding of an array in the stream.
 	// An instance of SliceType is used during schema-less decoding of an array in the stream.
 	// If nil, we use []interface{}
 	// If nil, we use []interface{}
 	SliceType reflect.Type
 	SliceType reflect.Type
-	// ErrorIfNoField controls whether an error is returned when decoding a map 
+	// ErrorIfNoField controls whether an error is returned when decoding a map
 	// from a codec stream into a struct, and no matching struct field is found.
 	// from a codec stream into a struct, and no matching struct field is found.
 	ErrorIfNoField bool
 	ErrorIfNoField bool
 }
 }
@@ -119,10 +115,10 @@ func (o *DecodeOptions) errorIfNoField() bool {
 	return o.ErrorIfNoField
 	return o.ErrorIfNoField
 }
 }
 
 
-// addDecodeExt registers a function to handle decoding into a given type when an 
-// extension type and specific tag byte is detected in the codec stream. 
+// addDecodeExt registers a function to handle decoding into a given type when an
+// extension type and specific tag byte is detected in the codec stream.
 // To remove an extension, pass fn=nil.
 // To remove an extension, pass fn=nil.
-func (o *decHandle) addDecodeExt(rt reflect.Type, tag byte, fn func(reflect.Value, []byte) (error)) {
+func (o *decHandle) addDecodeExt(rt reflect.Type, tag byte, fn func(reflect.Value, []byte) error) {
 	if o.exts == nil {
 	if o.exts == nil {
 		o.exts = make([]decExtTypeTagFn, 0, 2)
 		o.exts = make([]decExtTypeTagFn, 0, 2)
 		o.extFuncs = make(map[reflect.Type]decExtTagFn, 2)
 		o.extFuncs = make(map[reflect.Type]decExtTagFn, 2)
@@ -139,7 +135,7 @@ func (o *decHandle) addDecodeExt(rt reflect.Type, tag byte, fn func(reflect.Valu
 			o.rawToStringOverride = true
 			o.rawToStringOverride = true
 		}
 		}
 	}
 	}
-	
+
 	if leno := len(o.extFuncs); leno > cap(o.exts) {
 	if leno := len(o.extFuncs); leno > cap(o.exts) {
 		o.exts = make([]decExtTypeTagFn, leno, (leno * 3 / 2))
 		o.exts = make([]decExtTypeTagFn, leno, (leno * 3 / 2))
 	} else {
 	} else {
@@ -147,7 +143,7 @@ func (o *decHandle) addDecodeExt(rt reflect.Type, tag byte, fn func(reflect.Valu
 	}
 	}
 	var i int
 	var i int
 	for k, v := range o.extFuncs {
 	for k, v := range o.extFuncs {
-		o.exts[i] = decExtTypeTagFn {k, v}
+		o.exts[i] = decExtTypeTagFn{k, v}
 		i++
 		i++
 	}
 	}
 }
 }
@@ -158,7 +154,7 @@ func (o *decHandle) getDecodeExtForTag(tag byte) (rt reflect.Type, fn func(refle
 			return o.exts[i].rt, o.exts[i].fn
 			return o.exts[i].rt, o.exts[i].fn
 		}
 		}
 	}
 	}
-	return 
+	return
 }
 }
 
 
 func (o *decHandle) getDecodeExt(rt reflect.Type) (tag byte, fn func(reflect.Value, []byte) error) {
 func (o *decHandle) getDecodeExt(rt reflect.Type) (tag byte, fn func(reflect.Value, []byte) error) {
@@ -179,31 +175,31 @@ func (o *decHandle) getDecodeExt(rt reflect.Type) (tag byte, fn func(reflect.Val
 }
 }
 
 
 // NewDecoder returns a Decoder for decoding a stream of bytes from an io.Reader.
 // NewDecoder returns a Decoder for decoding a stream of bytes from an io.Reader.
-func NewDecoder(r io.Reader, h Handle) (*Decoder) {
-	z := ioDecReader {
+func NewDecoder(r io.Reader, h Handle) *Decoder {
+	z := ioDecReader{
 		r: r,
 		r: r,
 	}
 	}
-	return &Decoder{ r: &z, d: h.newDecoder(&z), h: h }
+	return &Decoder{r: &z, d: h.newDecDriver(&z), h: h}
 }
 }
 
 
-// NewDecoderBytes returns a Decoder which efficiently decodes directly 
+// NewDecoderBytes returns a Decoder which efficiently decodes directly
 // from a byte slice with zero copying.
 // from a byte slice with zero copying.
-func NewDecoderBytes(in []byte, h Handle) (*Decoder) {
-	z := bytesDecReader {
+func NewDecoderBytes(in []byte, h Handle) *Decoder {
+	z := bytesDecReader{
 		b: in,
 		b: in,
 		a: len(in),
 		a: len(in),
 	}
 	}
-	return &Decoder{ r: &z, d: h.newDecoder(&z), h: h }
+	return &Decoder{r: &z, d: h.newDecDriver(&z), h: h}
 }
 }
 
 
-// Decode decodes the stream from reader and stores the result in the 
-// value pointed to by v. v cannot be a nil pointer. v can also be 
+// Decode decodes the stream from reader and stores the result in the
+// value pointed to by v. v cannot be a nil pointer. v can also be
 // a reflect.Value of a pointer.
 // a reflect.Value of a pointer.
-// 
+//
 // Note that a pointer to a nil interface is not a nil pointer.
 // Note that a pointer to a nil interface is not a nil pointer.
 // If you do not know what type of stream it is, pass in a pointer to a nil interface.
 // If you do not know what type of stream it is, pass in a pointer to a nil interface.
-// We will decode and store a value in that nil interface. 
-// 
+// We will decode and store a value in that nil interface.
+//
 // Sample usages:
 // Sample usages:
 //   // Decoding into a non-nil typed value
 //   // Decoding into a non-nil typed value
 //   var f float32
 //   var f float32
@@ -213,7 +209,7 @@ func NewDecoderBytes(in []byte, h Handle) (*Decoder) {
 //   var v interface{}
 //   var v interface{}
 //   dec := codec.NewDecoder(r, handle)
 //   dec := codec.NewDecoder(r, handle)
 //   err = dec.Decode(&v)
 //   err = dec.Decode(&v)
-//   
+//
 func (d *Decoder) Decode(v interface{}) (err error) {
 func (d *Decoder) Decode(v interface{}) (err error) {
 	defer panicToErr(&err)
 	defer panicToErr(&err)
 	d.decode(v)
 	d.decode(v)
@@ -222,7 +218,7 @@ func (d *Decoder) Decode(v interface{}) (err error) {
 
 
 func (d *Decoder) decode(iv interface{}) {
 func (d *Decoder) decode(iv interface{}) {
 	d.d.initReadNext()
 	d.d.initReadNext()
-	
+
 	// Fast path included for various pointer types which cannot be registered as extensions
 	// Fast path included for various pointer types which cannot be registered as extensions
 	switch v := iv.(type) {
 	switch v := iv.(type) {
 	case nil:
 	case nil:
@@ -257,20 +253,19 @@ func (d *Decoder) decode(iv interface{}) {
 	case *float32:
 	case *float32:
 		*v = float32(d.d.decodeFloat(true))
 		*v = float32(d.d.decodeFloat(true))
 	case *float64:
 	case *float64:
-		*v = d.d.decodeFloat(false) 
+		*v = d.d.decodeFloat(false)
 	case *interface{}:
 	case *interface{}:
-	 	d.decodeValue(reflect.ValueOf(iv).Elem())
+		d.decodeValue(reflect.ValueOf(iv).Elem())
 	default:
 	default:
 		rv := reflect.ValueOf(iv)
 		rv := reflect.ValueOf(iv)
 		d.chkPtrValue(rv)
 		d.chkPtrValue(rv)
 		d.decodeValue(rv)
 		d.decodeValue(rv)
-	}	
+	}
 }
 }
 
 
-
 func (d *Decoder) decodeValue(rv reflect.Value) {
 func (d *Decoder) decodeValue(rv reflect.Value) {
 	// Note: if stream is set to nil, we set the corresponding value to its "zero" value
 	// Note: if stream is set to nil, we set the corresponding value to its "zero" value
-	
+
 	// var ctr int (define this above the  function if trying to do this run)
 	// var ctr int (define this above the  function if trying to do this run)
 	// ctr++
 	// ctr++
 	// log(".. [%v] enter decode: rv: %v <==> %T <==> %v", ctr, rv, rv.Interface(), rv.Interface())
 	// log(".. [%v] enter decode: rv: %v <==> %T <==> %v", ctr, rv, rv.Interface(), rv.Interface())
@@ -279,13 +274,13 @@ func (d *Decoder) decodeValue(rv reflect.Value) {
 	// }(ctr)
 	// }(ctr)
 	dd := d.d //so we don't dereference constantly
 	dd := d.d //so we don't dereference constantly
 	dd.initReadNext()
 	dd.initReadNext()
-	
+
 	rvOrig := rv
 	rvOrig := rv
 	wasNilIntf := rv.Kind() == reflect.Interface && rv.IsNil()
 	wasNilIntf := rv.Kind() == reflect.Interface && rv.IsNil()
 	rt := rv.Type()
 	rt := rv.Type()
-	
+
 	var ndesc decodeNakedContext
 	var ndesc decodeNakedContext
-	//if nil interface, use some hieristics to set the nil interface to an 
+	//if nil interface, use some hieristics to set the nil interface to an
 	//appropriate value based on the first byte read (byte descriptor bd)
 	//appropriate value based on the first byte read (byte descriptor bd)
 	if wasNilIntf {
 	if wasNilIntf {
 		if dd.currentIsNil() {
 		if dd.currentIsNil() {
@@ -313,15 +308,15 @@ func (d *Decoder) decodeValue(rv reflect.Value) {
 		}
 		}
 		return
 		return
 	}
 	}
-	
-	// An extension can be registered for any type, regardless of the Kind 
+
+	// An extension can be registered for any type, regardless of the Kind
 	// (e.g. type BitSet int64, type MyStruct { / * unexported fields * / }, type X []int, etc.
 	// (e.g. type BitSet int64, type MyStruct { / * unexported fields * / }, type X []int, etc.
-	// 
-	// We can't check if it's an extension byte here first, because the user may have 
-	// registered a pointer or non-pointer type, meaning we may have to recurse first 
+	//
+	// We can't check if it's an extension byte here first, because the user may have
+	// registered a pointer or non-pointer type, meaning we may have to recurse first
 	// before matching a mapped type, even though the extension byte is already detected.
 	// before matching a mapped type, even though the extension byte is already detected.
-	// 
-	// If we are checking for builtin or ext type here, it means we didn't go through decodeNaked, 
+	//
+	// If we are checking for builtin or ext type here, it means we didn't go through decodeNaked,
 	// Because decodeNaked would have handled it. It also means wasNilIntf = false.
 	// Because decodeNaked would have handled it. It also means wasNilIntf = false.
 	if dd.decodeBuiltinType(rt, rv) {
 	if dd.decodeBuiltinType(rt, rv) {
 		return
 		return
@@ -333,22 +328,22 @@ func (d *Decoder) decodeValue(rv reflect.Value) {
 		}
 		}
 		return
 		return
 	}
 	}
-	
+
 	// Note: In decoding into containers, we just use the stream to UPDATE the container.
 	// Note: In decoding into containers, we just use the stream to UPDATE the container.
 	// This means that for a struct or map, we just update matching fields or keys.
 	// This means that for a struct or map, we just update matching fields or keys.
-	// For a slice/array, we just update the first n elements, where n is the length of the 
+	// For a slice/array, we just update the first n elements, where n is the length of the
 	// stream.
 	// stream.
-	// However, if the encoded value is Nil in the stream, then we try to set 
+	// However, if the encoded value is Nil in the stream, then we try to set
 	// to nil, or a "zero" value.
 	// to nil, or a "zero" value.
 	//
 	//
 	// Also, we must ensure that, if decoding into a nil interface{}, we return a non-nil
 	// Also, we must ensure that, if decoding into a nil interface{}, we return a non-nil
 	// value except even if the container registers a length of 0.
 	// value except even if the container registers a length of 0.
-	// 
-	// NOTE: Do not make blocks for struct, slice, map, etc individual methods. 
+	//
+	// NOTE: Do not make blocks for struct, slice, map, etc individual methods.
 	// It ends up being more expensive, because they recursively calls decodeValue
 	// It ends up being more expensive, because they recursively calls decodeValue
-	// 
+	//
 	// (Mar 7, 2013. DON'T REARRANGE ... code clarity)
 	// (Mar 7, 2013. DON'T REARRANGE ... code clarity)
-	// tried arranging in sequence of most probable ones. 
+	// tried arranging in sequence of most probable ones.
 	// string, bool, integer, float, struct, ptr, slice, array, map, interface, uint.
 	// string, bool, integer, float, struct, ptr, slice, array, map, interface, uint.
 	switch rk := rv.Kind(); rk {
 	switch rk := rv.Kind(); rk {
 	case reflect.String:
 	case reflect.String:
@@ -371,7 +366,7 @@ func (d *Decoder) decodeValue(rv reflect.Value) {
 		rv.SetFloat(dd.decodeFloat(false))
 		rv.SetFloat(dd.decodeFloat(false))
 	case reflect.Uint8:
 	case reflect.Uint8:
 		rv.SetUint(dd.decodeUint(8))
 		rv.SetUint(dd.decodeUint(8))
-	case reflect.Uint64: 
+	case reflect.Uint64:
 		rv.SetUint(dd.decodeUint(64))
 		rv.SetUint(dd.decodeUint(64))
 	case reflect.Uint:
 	case reflect.Uint:
 		rv.SetUint(dd.decodeUint(uintBitsize))
 		rv.SetUint(dd.decodeUint(uintBitsize))
@@ -392,11 +387,11 @@ func (d *Decoder) decodeValue(rv reflect.Value) {
 		d.decodeValue(rv.Elem())
 		d.decodeValue(rv.Elem())
 	case reflect.Struct:
 	case reflect.Struct:
 		containerLen := dd.readMapLen()
 		containerLen := dd.readMapLen()
-		
+
 		if containerLen == 0 {
 		if containerLen == 0 {
 			break
 			break
 		}
 		}
-		
+
 		sfi := getStructFieldInfos(rt)
 		sfi := getStructFieldInfos(rt)
 		for j := 0; j < containerLen; j++ {
 		for j := 0; j < containerLen; j++ {
 			// var rvkencname string
 			// var rvkencname string
@@ -412,7 +407,7 @@ func (d *Decoder) decodeValue(rv reflect.Value) {
 					d.decodeValue(rv.FieldByIndex(sfik.is))
 					d.decodeValue(rv.FieldByIndex(sfik.is))
 				}
 				}
 				// d.decodeValue(sfi.field(k, rv))
 				// d.decodeValue(sfi.field(k, rv))
-			} else { 
+			} else {
 				if d.h.errorIfNoField() {
 				if d.h.errorIfNoField() {
 					decErr("No matching struct field found when decoding stream map with key: %v", rvkencname)
 					decErr("No matching struct field found when decoding stream map with key: %v", rvkencname)
 				} else {
 				} else {
@@ -423,10 +418,10 @@ func (d *Decoder) decodeValue(rv reflect.Value) {
 		}
 		}
 	case reflect.Slice:
 	case reflect.Slice:
 		// Be more careful calling Set() here, because a reflect.Value from an array
 		// Be more careful calling Set() here, because a reflect.Value from an array
-		// may have come in here (which may not be settable). 
+		// may have come in here (which may not be settable).
 		// In places where the slice got from an array could be, we should guard with CanSet() calls.
 		// In places where the slice got from an array could be, we should guard with CanSet() calls.
-		
-		if rt == byteSliceTyp { // rawbytes 
+
+		if rt == byteSliceTyp { // rawbytes
 			if bs2, changed2 := dd.decodeBytes(rv.Bytes()); changed2 {
 			if bs2, changed2 := dd.decodeBytes(rv.Bytes()); changed2 {
 				rv.SetBytes(bs2)
 				rv.SetBytes(bs2)
 			}
 			}
@@ -435,16 +430,16 @@ func (d *Decoder) decodeValue(rv reflect.Value) {
 			}
 			}
 			break
 			break
 		}
 		}
-		
+
 		containerLen := dd.readArrayLen()
 		containerLen := dd.readArrayLen()
 
 
 		if wasNilIntf {
 		if wasNilIntf {
 			rv = reflect.MakeSlice(rt, containerLen, containerLen)
 			rv = reflect.MakeSlice(rt, containerLen, containerLen)
-		} 
+		}
 		if containerLen == 0 {
 		if containerLen == 0 {
 			break
 			break
 		}
 		}
-		
+
 		if rv.IsNil() {
 		if rv.IsNil() {
 			// wasNilIntf only applies if rv is nil (since that's what we did earlier)
 			// wasNilIntf only applies if rv is nil (since that's what we did earlier)
 			if containerLen > 0 {
 			if containerLen > 0 {
@@ -474,7 +469,7 @@ func (d *Decoder) decodeValue(rv reflect.Value) {
 		d.decodeValue(rv.Slice(0, rv.Len()))
 		d.decodeValue(rv.Slice(0, rv.Len()))
 	case reflect.Map:
 	case reflect.Map:
 		containerLen := dd.readMapLen()
 		containerLen := dd.readMapLen()
-		
+
 		if containerLen == 0 {
 		if containerLen == 0 {
 			break
 			break
 		}
 		}
@@ -482,11 +477,11 @@ func (d *Decoder) decodeValue(rv reflect.Value) {
 		if rv.IsNil() {
 		if rv.IsNil() {
 			rv.Set(reflect.MakeMap(rt))
 			rv.Set(reflect.MakeMap(rt))
 		}
 		}
-		ktype, vtype := rt.Key(), rt.Elem()			
+		ktype, vtype := rt.Key(), rt.Elem()
 		for j := 0; j < containerLen; j++ {
 		for j := 0; j < containerLen; j++ {
 			rvk := reflect.New(ktype).Elem()
 			rvk := reflect.New(ktype).Elem()
 			d.decodeValue(rvk)
 			d.decodeValue(rvk)
-			
+
 			if ktype == intfTyp {
 			if ktype == intfTyp {
 				rvk = rvk.Elem()
 				rvk = rvk.Elem()
 				if rvk.Type() == byteSliceTyp {
 				if rvk.Type() == byteSliceTyp {
@@ -497,29 +492,29 @@ func (d *Decoder) decodeValue(rv reflect.Value) {
 			if !rvv.IsValid() {
 			if !rvv.IsValid() {
 				rvv = reflect.New(vtype).Elem()
 				rvv = reflect.New(vtype).Elem()
 			}
 			}
-			
+
 			d.decodeValue(rvv)
 			d.decodeValue(rvv)
 			rv.SetMapIndex(rvk, rvv)
 			rv.SetMapIndex(rvk, rvv)
 		}
 		}
 	default:
 	default:
 		decErr("Unhandled value for kind: %v: %s", rk, msgBadDesc)
 		decErr("Unhandled value for kind: %v: %s", rk, msgBadDesc)
 	}
 	}
-	
+
 	if wasNilIntf {
 	if wasNilIntf {
 		rvOrig.Set(rv)
 		rvOrig.Set(rv)
-	} 
+	}
 	return
 	return
 }
 }
 
 
 func (d *Decoder) chkPtrValue(rv reflect.Value) {
 func (d *Decoder) chkPtrValue(rv reflect.Value) {
-	// We cannot marshal into a non-pointer or a nil pointer 
+	// We cannot marshal into a non-pointer or a nil pointer
 	// (at least pass a nil interface so we can marshal into it)
 	// (at least pass a nil interface so we can marshal into it)
 	if rv.Kind() != reflect.Ptr || rv.IsNil() {
 	if rv.Kind() != reflect.Ptr || rv.IsNil() {
 		var rvi interface{} = rv
 		var rvi interface{} = rv
 		if rv.IsValid() && rv.CanInterface() {
 		if rv.IsValid() && rv.CanInterface() {
 			rvi = rv.Interface()
 			rvi = rv.Interface()
 		}
 		}
-		decErr("Decode: Expecting valid pointer to decode into. Got: %v, %T, %v", 
+		decErr("Decode: Expecting valid pointer to decode into. Got: %v, %T, %v",
 			rv.Kind(), rvi, rvi)
 			rv.Kind(), rvi, rvi)
 	}
 	}
 }
 }
@@ -573,12 +568,12 @@ func (z *bytesDecReader) consume(n int) (oldcursor int) {
 	oldcursor = z.c
 	oldcursor = z.c
 	z.c = oldcursor + n
 	z.c = oldcursor + n
 	z.a = z.a - n
 	z.a = z.a - n
-	return 
+	return
 }
 }
 
 
 func (z *bytesDecReader) readn(n int) (bs []byte) {
 func (z *bytesDecReader) readn(n int) (bs []byte) {
 	c0 := z.consume(n)
 	c0 := z.consume(n)
-	bs = z.b[c0 : z.c]
+	bs = z.b[c0:z.c]
 	return
 	return
 }
 }
 
 
@@ -593,21 +588,21 @@ func (z *bytesDecReader) readn1() uint8 {
 
 
 // Use binaryEncoding helper for 4 and 8 bits, but inline it for 2 bits
 // Use binaryEncoding helper for 4 and 8 bits, but inline it for 2 bits
 // creating temp slice variable and copying it to helper function is expensive
 // creating temp slice variable and copying it to helper function is expensive
-// for just 2 bits. 
+// for just 2 bits.
 
 
 func (z *bytesDecReader) readUint16() uint16 {
 func (z *bytesDecReader) readUint16() uint16 {
 	c0 := z.consume(2)
 	c0 := z.consume(2)
-	return uint16(z.b[c0+1]) | uint16(z.b[c0])<<8 
+	return uint16(z.b[c0+1]) | uint16(z.b[c0])<<8
 }
 }
 
 
 func (z *bytesDecReader) readUint32() uint32 {
 func (z *bytesDecReader) readUint32() uint32 {
 	c0 := z.consume(4)
 	c0 := z.consume(4)
-	return bigen.Uint32(z.b[c0 : z.c])
+	return bigen.Uint32(z.b[c0:z.c])
 }
 }
 
 
 func (z *bytesDecReader) readUint64() uint64 {
 func (z *bytesDecReader) readUint64() uint64 {
 	c0 := z.consume(8)
 	c0 := z.consume(8)
-	return bigen.Uint64(z.b[c0 : z.c])
+	return bigen.Uint64(z.b[c0:z.c])
 }
 }
 
 
 // ----------------------------------------
 // ----------------------------------------
@@ -615,71 +610,3 @@ func (z *bytesDecReader) readUint64() uint64 {
 func decErr(format string, params ...interface{}) {
 func decErr(format string, params ...interface{}) {
 	doPanic(msgTagDec, format, params...)
 	doPanic(msgTagDec, format, params...)
 }
 }
-
-// DecodeTimeExt decodes a []byte into a time.Time, 
-// and sets into passed reflectValue.
-func decodeTime(bs []byte) (tt time.Time, err error) {
-	var (
-		tsec int64
-		tnsec int32
-		tz uint16
-	)
-	switch len(bs) {
-	case 4:		
-		tsec = int64(int32(bigen.Uint32(bs)))
-	case 6:
-		tsec = int64(int32(bigen.Uint32(bs)))
-		tz = (bigen.Uint16(bs[4:]))
-	case 8:
-		tsec = int64(int32(bigen.Uint32(bs)))
-		tnsec = int32(bigen.Uint32(bs[4:]))
-	case 10:
-		tsec = int64(int32(bigen.Uint32(bs)))
-		tnsec = int32(bigen.Uint32(bs[4:]))
-		tz = (bigen.Uint16(bs[8:]))
-
-	case 9:
-		tsec = int64(bigen.Uint64(bs))
-	case 11:
-		tsec = int64(bigen.Uint64(bs))
-		tz = (bigen.Uint16(bs[8:]))
-	case 12:
-		tsec = int64(bigen.Uint64(bs))
-		tnsec = int32(bigen.Uint32(bs[8:]))
-	case 14:
-		tsec = int64(bigen.Uint64(bs))
-		tnsec = int32(bigen.Uint32(bs[8:]))
-		tz = (bigen.Uint16(bs[12:]))
-	default:
-		err = fmt.Errorf("Error decoding bytes: %v as time.Time. Invalid length: %v", bs, len(bs))
-		return 
-	}
-	if tz == 0 {
-		tt = time.Unix(tsec, int64(tnsec)).UTC()
-	} else {
-		// In stdlib time.Parse, when a date is parsed without a zone name, it uses "" as zone name.
-		// However, we need name here, so it can be shown when time is printed.
-		// Zone name is in form: UTC-08:00.
-		// Note that Go Libs do not give access to dst flag, so we only check for sign bit
-		tzneg := tz & (1 << 15) != 0 //check if negative sign
-		tz = tz & 0x1fff             //clear 3 MSBs: sign and dst bits 
-		tzoff := int(tz) * 60
-		var tzname = []byte("UTC+00:00")
-		if tzneg {
-			tzoff = -tzoff
-			tzname[3] = '-'
-		}
-		//tzname := fmt.Sprintf("UTC%s%02d:%02d", tzsign, tz/60, tz%60) //perf issue using Sprintf. inline below.
-		//tzhr, tzmin := tz/60, tz%60 //faster if u convert to int first
-		tzhr, tzmin := int(tz/60), int(tz%60)
-		tzname[4] = digits[tzhr/10]
-		tzname[5] = digits[tzhr%10]
-		tzname[7] = digits[tzmin/10]
-		tzname[8] = digits[tzmin%10]
-			
-		//fmt.Printf(">>>>> DEC: tzname: %s, tzoff: %v\n", tzname, tzoff)
-		tt = time.Unix(tsec, int64(tnsec)).In(time.FixedZone(string(tzname), tzoff))
-	}
-	return 
-}
-

+ 78 - 133
codec/encode.go

@@ -4,23 +4,21 @@
 package codec
 package codec
 
 
 import (
 import (
-	"io"
 	"bufio"
 	"bufio"
+	"io"
 	"reflect"
 	"reflect"
-	"math"
-	"time"
 	//"fmt"
 	//"fmt"
 )
 )
 
 
 //var _ = fmt.Printf
 //var _ = fmt.Printf
 const (
 const (
 	// Some tagging information for error messages.
 	// Some tagging information for error messages.
-	msgTagEnc = "codec.encoder"
+	msgTagEnc         = "codec.encoder"
 	defEncByteBufSize = 1 << 6 // 4:16, 6:64, 8:256, 10:1024
 	defEncByteBufSize = 1 << 6 // 4:16, 6:64, 8:256, 10:1024
 	// maxTimeSecs32 = math.MaxInt32 / 60 / 24 / 366
 	// maxTimeSecs32 = math.MaxInt32 / 60 / 24 / 366
 )
 )
 
 
-// encWriter abstracting writing to a byte array or to an io.Writer. 
+// encWriter abstracting writing to a byte array or to an io.Writer.
 type encWriter interface {
 type encWriter interface {
 	writeUint16(uint16)
 	writeUint16(uint16)
 	writeUint32(uint32)
 	writeUint32(uint32)
@@ -34,37 +32,34 @@ type encWriter interface {
 	flush()
 	flush()
 }
 }
 
 
-type encoder interface {
+type encDriver interface {
 	encodeBuiltinType(rt reflect.Type, rv reflect.Value) bool
 	encodeBuiltinType(rt reflect.Type, rv reflect.Value) bool
 	encodeNil()
 	encodeNil()
 	encodeInt(i int64)
 	encodeInt(i int64)
 	encodeUint(i uint64)
 	encodeUint(i uint64)
-	encodeBool(b bool) 
+	encodeBool(b bool)
 	encodeFloat32(f float32)
 	encodeFloat32(f float32)
 	encodeFloat64(f float64)
 	encodeFloat64(f float64)
-	encodeExtPreamble(xtag byte, length int) 
+	encodeExtPreamble(xtag byte, length int)
 	encodeArrayPreamble(length int)
 	encodeArrayPreamble(length int)
 	encodeMapPreamble(length int)
 	encodeMapPreamble(length int)
 	encodeString(c charEncoding, v string)
 	encodeString(c charEncoding, v string)
 	encodeSymbol(v string)
 	encodeSymbol(v string)
 	encodeStringBytes(c charEncoding, v []byte)
 	encodeStringBytes(c charEncoding, v []byte)
 	//TODO
 	//TODO
-	//encBignum(f *big.Int) 
+	//encBignum(f *big.Int)
 	//encStringRunes(c charEncoding, v []rune)
 	//encStringRunes(c charEncoding, v []rune)
 }
 }
 
 
-type newEncoderFunc func(w encWriter) encoder
-
 type encodeHandleI interface {
 type encodeHandleI interface {
-	getEncodeExt(rt reflect.Type) (tag byte, fn func(reflect.Value) ([]byte, error)) 
-	newEncoder(w encWriter) encoder
+	getEncodeExt(rt reflect.Type) (tag byte, fn func(reflect.Value) ([]byte, error))
 	writeExt() bool
 	writeExt() bool
 }
 }
 
 
 // An Encoder writes an object to an output stream in the codec format.
 // An Encoder writes an object to an output stream in the codec format.
 type Encoder struct {
 type Encoder struct {
 	w encWriter
 	w encWriter
-	e encoder
+	e encDriver
 	h encodeHandleI
 	h encodeHandleI
 }
 }
 
 
@@ -75,9 +70,9 @@ type ioEncWriterWriter interface {
 }
 }
 
 
 type ioEncWriterFlusher interface {
 type ioEncWriterFlusher interface {
-	 Flush() error
+	Flush() error
 }
 }
-	
+
 // ioEncWriter implements encWriter and can write to an io.Writer implementation
 // ioEncWriter implements encWriter and can write to an io.Writer implementation
 type ioEncWriter struct {
 type ioEncWriter struct {
 	w ioEncWriterWriter
 	w ioEncWriterWriter
@@ -87,16 +82,16 @@ type ioEncWriter struct {
 // bytesEncWriter implements encWriter and can write to an byte slice.
 // bytesEncWriter implements encWriter and can write to an byte slice.
 // It is used by Marshal function.
 // It is used by Marshal function.
 type bytesEncWriter struct {
 type bytesEncWriter struct {
-	b []byte
-	c int // cursor
+	b   []byte
+	c   int     // cursor
 	out *[]byte // write out on flush
 	out *[]byte // write out on flush
 }
 }
-	
+
 type encExtTagFn struct {
 type encExtTagFn struct {
-	fn func(reflect.Value) ([]byte, error)
+	fn  func(reflect.Value) ([]byte, error)
 	tag byte
 	tag byte
 }
 }
- 
+
 type encExtTypeTagFn struct {
 type encExtTypeTagFn struct {
 	rt reflect.Type
 	rt reflect.Type
 	encExtTagFn
 	encExtTagFn
@@ -104,20 +99,20 @@ type encExtTypeTagFn struct {
 
 
 // EncoderOptions contain options for the encoder, e.g. registered extension functions.
 // EncoderOptions contain options for the encoder, e.g. registered extension functions.
 type encHandle struct {
 type encHandle struct {
-	extFuncs map[reflect.Type] encExtTagFn
-	exts []encExtTypeTagFn
+	extFuncs map[reflect.Type]encExtTagFn
+	exts     []encExtTypeTagFn
 }
 }
 
 
-// addEncodeExt registers a function to handle encoding a given type as an extension  
-// with a specific specific tag byte. 
+// addEncodeExt registers a function to handle encoding a given type as an extension
+// with a specific specific tag byte.
 // To remove an extension, pass fn=nil.
 // To remove an extension, pass fn=nil.
 func (o *encHandle) addEncodeExt(rt reflect.Type, tag byte, fn func(reflect.Value) ([]byte, error)) {
 func (o *encHandle) addEncodeExt(rt reflect.Type, tag byte, fn func(reflect.Value) ([]byte, error)) {
 	if o.exts == nil {
 	if o.exts == nil {
 		o.exts = make([]encExtTypeTagFn, 0, 8)
 		o.exts = make([]encExtTypeTagFn, 0, 8)
-		o.extFuncs = make(map[reflect.Type] encExtTagFn, 8)
+		o.extFuncs = make(map[reflect.Type]encExtTagFn, 8)
 	}
 	}
 	delete(o.extFuncs, rt)
 	delete(o.extFuncs, rt)
-	
+
 	if fn != nil {
 	if fn != nil {
 		o.extFuncs[rt] = encExtTagFn{fn, tag}
 		o.extFuncs[rt] = encExtTagFn{fn, tag}
 	}
 	}
@@ -128,12 +123,12 @@ func (o *encHandle) addEncodeExt(rt reflect.Type, tag byte, fn func(reflect.Valu
 	}
 	}
 	var i int
 	var i int
 	for k, v := range o.extFuncs {
 	for k, v := range o.extFuncs {
-		o.exts[i] = encExtTypeTagFn {k, v}
+		o.exts[i] = encExtTypeTagFn{k, v}
 		i++
 		i++
 	}
 	}
 }
 }
 
 
-func (o *encHandle) getEncodeExt(rt reflect.Type) (tag byte, fn func(reflect.Value) ([]byte, error)) {	
+func (o *encHandle) getEncodeExt(rt reflect.Type) (tag byte, fn func(reflect.Value) ([]byte, error)) {
 	// For >= 5 elements, map constant cost less than iteration cost.
 	// For >= 5 elements, map constant cost less than iteration cost.
 	// This is because reflect.Type equality cost is pretty high
 	// This is because reflect.Type equality cost is pretty high
 	if l := len(o.exts); l == 0 {
 	if l := len(o.exts); l == 0 {
@@ -155,56 +150,56 @@ func (o *encHandle) getEncodeExt(rt reflect.Type) (tag byte, fn func(reflect.Val
 // NewEncoder returns an Encoder for encoding into an io.Writer.
 // NewEncoder returns an Encoder for encoding into an io.Writer.
 // For efficiency, Users are encouraged to pass in a memory buffered writer
 // For efficiency, Users are encouraged to pass in a memory buffered writer
 // (eg bufio.Writer, bytes.Buffer). This implementation *may* use one internally.
 // (eg bufio.Writer, bytes.Buffer). This implementation *may* use one internally.
-func NewEncoder(w io.Writer, h Handle) (*Encoder) {
+func NewEncoder(w io.Writer, h Handle) *Encoder {
 	ww, ok := w.(ioEncWriterWriter)
 	ww, ok := w.(ioEncWriterWriter)
 	if !ok {
 	if !ok {
 		ww = bufio.NewWriterSize(w, defEncByteBufSize)
 		ww = bufio.NewWriterSize(w, defEncByteBufSize)
 	}
 	}
-	z := ioEncWriter {
+	z := ioEncWriter{
 		w: ww,
 		w: ww,
 	}
 	}
-	return &Encoder { w: &z, h: h, e: h.newEncoder(&z) }
+	return &Encoder{w: &z, h: h, e: h.newEncDriver(&z)}
 }
 }
 
 
-// NewEncoderBytes returns an encoder for encoding directly and efficiently 
+// NewEncoderBytes returns an encoder for encoding directly and efficiently
 // into a byte slice, using zero-copying to temporary slices.
 // into a byte slice, using zero-copying to temporary slices.
-// 
+//
 // It will potentially replace the output byte slice pointed to.
 // It will potentially replace the output byte slice pointed to.
 // After encoding, the out parameter contains the encoded contents.
 // After encoding, the out parameter contains the encoded contents.
-func NewEncoderBytes(out *[]byte, h Handle) (*Encoder) {
+func NewEncoderBytes(out *[]byte, h Handle) *Encoder {
 	in := *out
 	in := *out
 	if in == nil {
 	if in == nil {
 		in = make([]byte, defEncByteBufSize)
 		in = make([]byte, defEncByteBufSize)
 	}
 	}
-	z := bytesEncWriter {
-		b: in,
+	z := bytesEncWriter{
+		b:   in,
 		out: out,
 		out: out,
 	}
 	}
-	return &Encoder { w: &z, h: h, e: h.newEncoder(&z) }
+	return &Encoder{w: &z, h: h, e: h.newEncDriver(&z)}
 }
 }
 
 
 // Encode writes an object into a stream in the codec format.
 // Encode writes an object into a stream in the codec format.
-// 
+//
 // Struct values encode as maps. Each exported struct field is encoded unless:
 // Struct values encode as maps. Each exported struct field is encoded unless:
 //    - the field's tag is "-", or
 //    - the field's tag is "-", or
 //    - the field is empty and its tag specifies the "omitempty" option.
 //    - the field is empty and its tag specifies the "omitempty" option.
 //
 //
-// The empty values are false, 0, any nil pointer or interface value, 
-// and any array, slice, map, or string of length zero. 
-// 
+// The empty values are false, 0, any nil pointer or interface value,
+// and any array, slice, map, or string of length zero.
+//
 // Anonymous fields are encoded inline if no struct tag is present.
 // Anonymous fields are encoded inline if no struct tag is present.
 // Else they are encoded as regular fields.
 // Else they are encoded as regular fields.
-// 
-// The object's default key string is the struct field name but can be 
-// specified in the struct field's tag value. 
-// The "codec" key in struct field's tag value is the key name, 
-// followed by an optional comma and options. 
-// 
-// To set an option on all fields (e.g. omitempty on all fields), you 
+//
+// The object's default key string is the struct field name but can be
+// specified in the struct field's tag value.
+// The "codec" key in struct field's tag value is the key name,
+// followed by an optional comma and options.
+//
+// To set an option on all fields (e.g. omitempty on all fields), you
 // can create a field called _struct, and set flags on it.
 // can create a field called _struct, and set flags on it.
-// 
+//
 // Examples:
 // Examples:
-//    
+//
 //      type MyStruct struct {
 //      type MyStruct struct {
 //          _struct bool    `codec:",omitempty"`   //set omitempty for every field
 //          _struct bool    `codec:",omitempty"`   //set omitempty for every field
 //          Field1 string   `codec:"-"`            //skip this field
 //          Field1 string   `codec:"-"`            //skip this field
@@ -213,23 +208,23 @@ func NewEncoderBytes(out *[]byte, h Handle) (*Encoder) {
 //          Field4 bool     `codec:"f4,omitempty"` //use key "f4". Omit if empty.
 //          Field4 bool     `codec:"f4,omitempty"` //use key "f4". Omit if empty.
 //          ...
 //          ...
 //      }
 //      }
-// 
-// Note: 
+//
+// Note:
 //   - Encode will treat struct field names and keys in map[string]XXX as symbols.
 //   - Encode will treat struct field names and keys in map[string]XXX as symbols.
 //     Some formats support symbols (e.g. binc) and will properly encode the string
 //     Some formats support symbols (e.g. binc) and will properly encode the string
 //     only once in the stream, and use a tag to refer to it thereafter.
 //     only once in the stream, and use a tag to refer to it thereafter.
 func (e *Encoder) Encode(v interface{}) (err error) {
 func (e *Encoder) Encode(v interface{}) (err error) {
-	defer panicToErr(&err) 
+	defer panicToErr(&err)
 	e.encode(v)
 	e.encode(v)
 	e.w.flush()
 	e.w.flush()
-	return 
+	return
 }
 }
 
 
 func (e *Encoder) encode(iv interface{}) {
 func (e *Encoder) encode(iv interface{}) {
 	switch v := iv.(type) {
 	switch v := iv.(type) {
 	case nil:
 	case nil:
 		e.e.encodeNil()
 		e.e.encodeNil()
-		
+
 	case reflect.Value:
 	case reflect.Value:
 		e.encodeValue(v)
 		e.encodeValue(v)
 
 
@@ -294,7 +289,7 @@ func (e *Encoder) encode(iv interface{}) {
 	default:
 	default:
 		e.encodeValue(reflect.ValueOf(iv))
 		e.encodeValue(reflect.ValueOf(iv))
 	}
 	}
-	
+
 }
 }
 
 
 func (e *Encoder) encodeValue(rv reflect.Value) {
 func (e *Encoder) encodeValue(rv reflect.Value) {
@@ -304,7 +299,7 @@ func (e *Encoder) encodeValue(rv reflect.Value) {
 	if ee.encodeBuiltinType(rt, rv) {
 	if ee.encodeBuiltinType(rt, rv) {
 		return
 		return
 	}
 	}
-	
+
 	//Note: tagFn must handle returning nil if value should be encoded as a nil.
 	//Note: tagFn must handle returning nil if value should be encoded as a nil.
 	if xfTag, xfFn := e.h.getEncodeExt(rt); xfFn != nil {
 	if xfTag, xfFn := e.h.getEncodeExt(rt); xfFn != nil {
 		bs, fnerr := xfFn(rv)
 		bs, fnerr := xfFn(rv)
@@ -323,7 +318,7 @@ func (e *Encoder) encodeValue(rv reflect.Value) {
 		}
 		}
 		return
 		return
 	}
 	}
-	
+
 	// ensure more common cases appear early in switch.
 	// ensure more common cases appear early in switch.
 	rk := rv.Kind()
 	rk := rv.Kind()
 	switch rk {
 	switch rk {
@@ -339,7 +334,7 @@ func (e *Encoder) encodeValue(rv reflect.Value) {
 		if rv.IsNil() {
 		if rv.IsNil() {
 			ee.encodeNil()
 			ee.encodeNil()
 			break
 			break
-		} 
+		}
 		if rt == byteSliceTyp {
 		if rt == byteSliceTyp {
 			ee.encodeStringBytes(c_RAW, rv.Bytes())
 			ee.encodeStringBytes(c_RAW, rv.Bytes())
 			break
 			break
@@ -364,7 +359,7 @@ func (e *Encoder) encodeValue(rv reflect.Value) {
 		if l == 0 {
 		if l == 0 {
 			break
 			break
 		}
 		}
-		keyTypeIsString := rt.Key().Kind() == reflect.String 
+		keyTypeIsString := rt.Key().Kind() == reflect.String
 		mks := rv.MapKeys()
 		mks := rv.MapKeys()
 		// for j, lmks := 0, len(mks); j < lmks; j++ {
 		// for j, lmks := 0, len(mks); j < lmks; j++ {
 		for j := range mks {
 		for j := range mks {
@@ -373,7 +368,7 @@ func (e *Encoder) encodeValue(rv reflect.Value) {
 			} else {
 			} else {
 				e.encodeValue(mks[j])
 				e.encodeValue(mks[j])
 			}
 			}
-		 	e.encodeValue(rv.MapIndex(mks[j]))
+			e.encodeValue(rv.MapIndex(mks[j]))
 		}
 		}
 	case reflect.Struct:
 	case reflect.Struct:
 		e.encStruct(rt, rv)
 		e.encStruct(rt, rv)
@@ -456,7 +451,7 @@ func (z *ioEncWriter) writeb(bs []byte) {
 	}
 	}
 	if n != len(bs) {
 	if n != len(bs) {
 		doPanic(msgTagEnc, "write: Incorrect num bytes written. Expecting: %v, Wrote: %v", len(bs), n)
 		doPanic(msgTagEnc, "write: Incorrect num bytes written. Expecting: %v, Wrote: %v", len(bs), n)
-	}	
+	}
 }
 }
 
 
 func (z *ioEncWriter) writestr(s string) {
 func (z *ioEncWriter) writestr(s string) {
@@ -466,7 +461,7 @@ func (z *ioEncWriter) writestr(s string) {
 	}
 	}
 	if n != len(s) {
 	if n != len(s) {
 		doPanic(msgTagEnc, "write: Incorrect num bytes written. Expecting: %v, Wrote: %v", len(s), n)
 		doPanic(msgTagEnc, "write: Incorrect num bytes written. Expecting: %v, Wrote: %v", len(s), n)
-	}	
+	}
 }
 }
 
 
 func (z *ioEncWriter) writen1(b byte) {
 func (z *ioEncWriter) writen1(b byte) {
@@ -506,27 +501,27 @@ func (z *ioEncWriter) flush() {
 func (z *bytesEncWriter) writeUint16(v uint16) {
 func (z *bytesEncWriter) writeUint16(v uint16) {
 	c := z.grow(2)
 	c := z.grow(2)
 	z.b[c] = byte(v >> 8)
 	z.b[c] = byte(v >> 8)
-	z.b[c + 1] = byte(v)
+	z.b[c+1] = byte(v)
 }
 }
 
 
 func (z *bytesEncWriter) writeUint32(v uint32) {
 func (z *bytesEncWriter) writeUint32(v uint32) {
 	c := z.grow(4)
 	c := z.grow(4)
 	z.b[c] = byte(v >> 24)
 	z.b[c] = byte(v >> 24)
-	z.b[c + 1] = byte(v >> 16)
-	z.b[c + 2] = byte(v >> 8)
-	z.b[c + 3] = byte(v)
+	z.b[c+1] = byte(v >> 16)
+	z.b[c+2] = byte(v >> 8)
+	z.b[c+3] = byte(v)
 }
 }
 
 
 func (z *bytesEncWriter) writeUint64(v uint64) {
 func (z *bytesEncWriter) writeUint64(v uint64) {
 	c := z.grow(8)
 	c := z.grow(8)
 	z.b[c] = byte(v >> 56)
 	z.b[c] = byte(v >> 56)
-	z.b[c + 1] = byte(v >> 48)
-	z.b[c + 2] = byte(v >> 40)
-	z.b[c + 3] = byte(v >> 32)
-	z.b[c + 4] = byte(v >> 24)
-	z.b[c + 5] = byte(v >> 16)
-	z.b[c + 6] = byte(v >> 8)
-	z.b[c + 7] = byte(v)
+	z.b[c+1] = byte(v >> 48)
+	z.b[c+2] = byte(v >> 40)
+	z.b[c+3] = byte(v >> 32)
+	z.b[c+4] = byte(v >> 24)
+	z.b[c+5] = byte(v >> 16)
+	z.b[c+6] = byte(v >> 8)
+	z.b[c+7] = byte(v)
 }
 }
 
 
 func (z *bytesEncWriter) writeb(s []byte) {
 func (z *bytesEncWriter) writeb(s []byte) {
@@ -547,25 +542,25 @@ func (z *bytesEncWriter) writen1(b1 byte) {
 func (z *bytesEncWriter) writen2(b1 byte, b2 byte) {
 func (z *bytesEncWriter) writen2(b1 byte, b2 byte) {
 	c := z.grow(2)
 	c := z.grow(2)
 	z.b[c] = b1
 	z.b[c] = b1
-	z.b[c + 1] = b2
+	z.b[c+1] = b2
 }
 }
 
 
 func (z *bytesEncWriter) writen3(b1 byte, b2 byte, b3 byte) {
 func (z *bytesEncWriter) writen3(b1 byte, b2 byte, b3 byte) {
 	c := z.grow(3)
 	c := z.grow(3)
 	z.b[c] = b1
 	z.b[c] = b1
-	z.b[c + 1] = b2
-	z.b[c + 2] = b3
+	z.b[c+1] = b2
+	z.b[c+2] = b3
 }
 }
 
 
 func (z *bytesEncWriter) writen4(b1 byte, b2 byte, b3 byte, b4 byte) {
 func (z *bytesEncWriter) writen4(b1 byte, b2 byte, b3 byte, b4 byte) {
 	c := z.grow(4)
 	c := z.grow(4)
 	z.b[c] = b1
 	z.b[c] = b1
-	z.b[c + 1] = b2
-	z.b[c + 2] = b3
-	z.b[c + 3] = b4
+	z.b[c+1] = b2
+	z.b[c+2] = b3
+	z.b[c+3] = b4
 }
 }
 
 
-func (z *bytesEncWriter) flush() { 
+func (z *bytesEncWriter) flush() {
 	*(z.out) = z.b[:z.c]
 	*(z.out) = z.b[:z.c]
 }
 }
 
 
@@ -574,7 +569,7 @@ func (z *bytesEncWriter) grow(n int) (oldcursor int) {
 	z.c = oldcursor + n
 	z.c = oldcursor + n
 	if z.c > cap(z.b) {
 	if z.c > cap(z.b) {
 		// It tried using appendslice logic: (if cap < 1024, *2, else *1.25).
 		// It tried using appendslice logic: (if cap < 1024, *2, else *1.25).
-		// However, it was too expensive, causing too many iterations of copy. 
+		// However, it was too expensive, causing too many iterations of copy.
 		// Using bytes.Buffer model was much better (2*cap + n)
 		// Using bytes.Buffer model was much better (2*cap + n)
 		bs := make([]byte, 2*cap(z.b)+n)
 		bs := make([]byte, 2*cap(z.b)+n)
 		copy(bs, z.b[:oldcursor])
 		copy(bs, z.b[:oldcursor])
@@ -590,53 +585,3 @@ func (z *bytesEncWriter) grow(n int) (oldcursor int) {
 func encErr(format string, params ...interface{}) {
 func encErr(format string, params ...interface{}) {
 	doPanic(msgTagEnc, format, params...)
 	doPanic(msgTagEnc, format, params...)
 }
 }
-
-// EncodeTimeExt encodes a time.Time as a []byte, including 
-// information on the instant in time and UTC offset.
-func encodeTime(t time.Time) ([]byte) {
-	//t := rv.Interface().(time.Time)
-	tsecs, tnsecs := t.Unix(), t.Nanosecond()
-	var padzero bool
-	var bs [14]byte
-	var i int
-	l := t.Location()
-	if l == time.UTC {
-		l = nil
-	}
-	if tsecs > math.MinInt32 && tsecs < math.MaxInt32 {
-		bigen.PutUint32(bs[i:], uint32(int32(tsecs)))
-		i = i + 4
-	} else {
-		bigen.PutUint64(bs[i:], uint64(tsecs))
-		i = i + 8
-		padzero = (tnsecs == 0)
-	}
-	if tnsecs != 0 {
-		bigen.PutUint32(bs[i:], uint32(tnsecs))
-		i = i + 4
-	}
-	if l != nil {
-		// Note that Go Libs do not give access to dst flag.
-		_, zoneOffset := t.Zone()
-		//zoneName, zoneOffset := t.Zone()
-		//fmt.Printf(">>>>>> ENC: zone: %s, %v\n", zoneName, zoneOffset)
-		zoneOffset /= 60
-		isNeg := zoneOffset < 0
-		if isNeg {
-			zoneOffset = -zoneOffset
-		}
-		var z uint16 = uint16(zoneOffset)
-		if isNeg {
-			z |= 1 << 15 //set sign bit
-		}
-		//fmt.Printf(">>>>>> ENC: z: %b\n", z)
-		bigen.PutUint16(bs[i:], z)
-		i = i + 2
-	}
-	if padzero {
-		i = i + 1
-	}
-	//fmt.Printf(">>>> EncodeTimeExt: t: %v, len: %v, v: %v\n", t, i, bs[0:i])
-	return bs[0:i]
-}
-

+ 3 - 3
codec/ext_dep_test.go

@@ -5,9 +5,9 @@
 
 
 package codec
 package codec
 
 
-// This file includes benchmarks which have dependencies on 3rdparty  
+// This file includes benchmarks which have dependencies on 3rdparty
 // packages (bson and vmihailenco/msgpack) which must be installed locally.
 // packages (bson and vmihailenco/msgpack) which must be installed locally.
-// 
+//
 // To run the benchmarks including these 3rdparty packages, first
 // To run the benchmarks including these 3rdparty packages, first
 //   - Uncomment first line in this file (put // // in front of it)
 //   - Uncomment first line in this file (put // // in front of it)
 //   - Get those packages:
 //   - Get those packages:
@@ -23,7 +23,7 @@ import (
 )
 )
 
 
 func init() {
 func init() {
-	benchCheckers = append(benchCheckers, 
+	benchCheckers = append(benchCheckers,
 		benchChecker{"v-msgpack", fnVMsgpackEncodeFn, fnVMsgpackDecodeFn},
 		benchChecker{"v-msgpack", fnVMsgpackEncodeFn, fnVMsgpackDecodeFn},
 		benchChecker{"bson", fnBsonEncodeFn, fnBsonDecodeFn},
 		benchChecker{"bson", fnBsonEncodeFn, fnBsonDecodeFn},
 	)
 	)

+ 57 - 54
codec/helper.go

@@ -6,22 +6,22 @@ package codec
 // Contains code shared by both encode and decode.
 // Contains code shared by both encode and decode.
 
 
 import (
 import (
-	"unicode"
-	"unicode/utf8"
-	"reflect"
-	"sync"
-	"strings"
+	"encoding/binary"
 	"fmt"
 	"fmt"
+	"reflect"
 	"sort"
 	"sort"
+	"strings"
+	"sync"
 	"time"
 	"time"
-	"encoding/binary"
+	"unicode"
+	"unicode/utf8"
 )
 )
 
 
 const (
 const (
 	// For >= 4 elements, map outways cost of linear search (especially for reflect.Type)
 	// For >= 4 elements, map outways cost of linear search (especially for reflect.Type)
-	mapAccessThreshold = 4 
-	binarySearchThreshold = 16 
-	structTagName = "codec"
+	mapAccessThreshold    = 4
+	binarySearchThreshold = 16
+	structTagName         = "codec"
 )
 )
 
 
 type charEncoding uint8
 type charEncoding uint8
@@ -36,24 +36,24 @@ const (
 )
 )
 
 
 var (
 var (
-	bigen = binary.BigEndian
+	bigen               = binary.BigEndian
 	structInfoFieldName = "_struct"
 	structInfoFieldName = "_struct"
-	
-	cachedStructFieldInfos = make(map[reflect.Type]structFieldInfos, 4)
+
+	cachedStructFieldInfos      = make(map[reflect.Type]structFieldInfos, 4)
 	cachedStructFieldInfosMutex sync.RWMutex
 	cachedStructFieldInfosMutex sync.RWMutex
 
 
-	nilIntfSlice = []interface{}(nil)
-	intfSliceTyp = reflect.TypeOf(nilIntfSlice)
-	intfTyp = intfSliceTyp.Elem()
-	byteSliceTyp = reflect.TypeOf([]byte(nil))
-	ptrByteSliceTyp = reflect.TypeOf((*[]byte)(nil))
+	nilIntfSlice     = []interface{}(nil)
+	intfSliceTyp     = reflect.TypeOf(nilIntfSlice)
+	intfTyp          = intfSliceTyp.Elem()
+	byteSliceTyp     = reflect.TypeOf([]byte(nil))
+	ptrByteSliceTyp  = reflect.TypeOf((*[]byte)(nil))
 	mapStringIntfTyp = reflect.TypeOf(map[string]interface{}(nil))
 	mapStringIntfTyp = reflect.TypeOf(map[string]interface{}(nil))
-	mapIntfIntfTyp = reflect.TypeOf(map[interface{}]interface{}(nil))
-	timeTyp = reflect.TypeOf(time.Time{})
-	ptrTimeTyp = reflect.TypeOf((*time.Time)(nil))
-	int64SliceTyp = reflect.TypeOf([]int64(nil))
-	
-	intBitsize uint8 = uint8(reflect.TypeOf(int(0)).Bits())
+	mapIntfIntfTyp   = reflect.TypeOf(map[interface{}]interface{}(nil))
+	timeTyp          = reflect.TypeOf(time.Time{})
+	ptrTimeTyp       = reflect.TypeOf((*time.Time)(nil))
+	int64SliceTyp    = reflect.TypeOf([]int64(nil))
+
+	intBitsize  uint8 = uint8(reflect.TypeOf(int(0)).Bits())
 	uintBitsize uint8 = uint8(reflect.TypeOf(uint(0)).Bits())
 	uintBitsize uint8 = uint8(reflect.TypeOf(uint(0)).Bits())
 )
 )
 
 
@@ -63,24 +63,31 @@ type encdecHandle struct {
 }
 }
 
 
 func (o *encdecHandle) AddExt(
 func (o *encdecHandle) AddExt(
-	rt reflect.Type, 
-	tag byte, 
+	rt reflect.Type,
+	tag byte,
 	encfn func(reflect.Value) ([]byte, error),
 	encfn func(reflect.Value) ([]byte, error),
-	decfn func(reflect.Value, []byte) (error),
+	decfn func(reflect.Value, []byte) error,
 ) {
 ) {
 	o.addEncodeExt(rt, tag, encfn)
 	o.addEncodeExt(rt, tag, encfn)
 	o.addDecodeExt(rt, tag, decfn)
 	o.addDecodeExt(rt, tag, decfn)
 }
 }
 
 
+// Handle is the interface for a specific encoding format.
+//
+// Typically, a Handle is pre-configured before first time use,
+// and not modified while in use. Such a pre-configured Handle
+// is safe for concurrent access.
 type Handle interface {
 type Handle interface {
 	encodeHandleI
 	encodeHandleI
 	decodeHandleI
 	decodeHandleI
+	newEncDriver(w encWriter) encDriver
+	newDecDriver(r decReader) decDriver
 }
 }
-	
+
 type structFieldInfo struct {
 type structFieldInfo struct {
-	encName   string      // encode name
+	encName   string // encode name
 	is        []int
 	is        []int
-	i         int16       // field index in struct
+	i         int16 // field index in struct
 	omitEmpty bool
 	omitEmpty bool
 	// tag       string   // tag
 	// tag       string   // tag
 	// name      string   // field name
 	// name      string   // field name
@@ -92,16 +99,16 @@ type structFieldInfos []structFieldInfo
 
 
 type sfiSortedByEncName []*structFieldInfo
 type sfiSortedByEncName []*structFieldInfo
 
 
-func (p sfiSortedByEncName) Len() int { 
-	return len(p) 
+func (p sfiSortedByEncName) Len() int {
+	return len(p)
 }
 }
 
 
-func (p sfiSortedByEncName) Less(i, j int) bool { 
-	return p[i].encName < p[j].encName 
+func (p sfiSortedByEncName) Less(i, j int) bool {
+	return p[i].encName < p[j].encName
 }
 }
 
 
-func (p sfiSortedByEncName) Swap(i, j int) { 
-	p[i], p[j] = p[j], p[i] 
+func (p sfiSortedByEncName) Swap(i, j int) {
+	p[i], p[j] = p[j], p[i]
 }
 }
 
 
 func (sis structFieldInfos) indexForEncName(name string) int {
 func (sis structFieldInfos) indexForEncName(name string) int {
@@ -117,7 +124,7 @@ func (sis structFieldInfos) indexForEncName(name string) int {
 		// binary search. adapted from sort/search.go.
 		// binary search. adapted from sort/search.go.
 		h, i, j := 0, 0, sislen
 		h, i, j := 0, 0, sislen
 		for i < j {
 		for i < j {
-			h = i + (j-i)/2 
+			h = i + (j-i)/2
 			// i ≤ h < j
 			// i ≤ h < j
 			if sis[h].encName < name {
 			if sis[h].encName < name {
 				i = h + 1 // preserves f(i-1) == false
 				i = h + 1 // preserves f(i-1) == false
@@ -137,12 +144,12 @@ func getStructFieldInfos(rt reflect.Type) (sis structFieldInfos) {
 	sis, ok := cachedStructFieldInfos[rt]
 	sis, ok := cachedStructFieldInfos[rt]
 	cachedStructFieldInfosMutex.RUnlock()
 	cachedStructFieldInfosMutex.RUnlock()
 	if ok {
 	if ok {
-		return 
+		return
 	}
 	}
-	
+
 	cachedStructFieldInfosMutex.Lock()
 	cachedStructFieldInfosMutex.Lock()
 	defer cachedStructFieldInfosMutex.Unlock()
 	defer cachedStructFieldInfosMutex.Unlock()
-	
+
 	var siInfo *structFieldInfo
 	var siInfo *structFieldInfo
 	if f, ok := rt.FieldByName(structInfoFieldName); ok {
 	if f, ok := rt.FieldByName(structInfoFieldName); ok {
 		siInfo = parseStructFieldInfo(structInfoFieldName, f.Tag.Get(structTagName))
 		siInfo = parseStructFieldInfo(structInfoFieldName, f.Tag.Get(structTagName))
@@ -161,7 +168,7 @@ func getStructFieldInfos(rt reflect.Type) (sis structFieldInfos) {
 	return
 	return
 }
 }
 
 
-func rgetStructFieldInfos(rt reflect.Type, indexstack []int, fnameToHastag map[string]bool, 
+func rgetStructFieldInfos(rt reflect.Type, indexstack []int, fnameToHastag map[string]bool,
 	sis *[]*structFieldInfo, siInfo *structFieldInfo,
 	sis *[]*structFieldInfo, siInfo *structFieldInfo,
 ) {
 ) {
 	for j := 0; j < rt.NumField(); j++ {
 	for j := 0; j < rt.NumField(); j++ {
@@ -172,7 +179,7 @@ func rgetStructFieldInfos(rt reflect.Type, indexstack []int, fnameToHastag map[s
 		}
 		}
 		if r1, _ := utf8.DecodeRuneInString(f.Name); r1 == utf8.RuneError || !unicode.IsUpper(r1) {
 		if r1, _ := utf8.DecodeRuneInString(f.Name); r1 == utf8.RuneError || !unicode.IsUpper(r1) {
 			continue
 			continue
-		} 
+		}
 		if f.Anonymous {
 		if f.Anonymous {
 			//if anonymous, inline it if there is no struct tag, else treat as regular field
 			//if anonymous, inline it if there is no struct tag, else treat as regular field
 			if stag == "" {
 			if stag == "" {
@@ -180,7 +187,7 @@ func rgetStructFieldInfos(rt reflect.Type, indexstack []int, fnameToHastag map[s
 				rgetStructFieldInfos(f.Type, indexstack2, fnameToHastag, sis, siInfo)
 				rgetStructFieldInfos(f.Type, indexstack2, fnameToHastag, sis, siInfo)
 				continue
 				continue
 			}
 			}
-		} 
+		}
 		//do not let fields with same name in embedded structs override field at higher level.
 		//do not let fields with same name in embedded structs override field at higher level.
 		//this must be done after anonymous check, to allow anonymous field still include their child fields
 		//this must be done after anonymous check, to allow anonymous field still include their child fields
 		if _, ok := fnameToHastag[f.Name]; ok {
 		if _, ok := fnameToHastag[f.Name]; ok {
@@ -205,16 +212,16 @@ func rgetStructFieldInfos(rt reflect.Type, indexstack []int, fnameToHastag map[s
 	}
 	}
 }
 }
 
 
-func parseStructFieldInfo(fname string, stag string) (*structFieldInfo) {
+func parseStructFieldInfo(fname string, stag string) *structFieldInfo {
 	if fname == "" {
 	if fname == "" {
 		panic("parseStructFieldInfo: No Field Name")
 		panic("parseStructFieldInfo: No Field Name")
 	}
 	}
-	si := structFieldInfo {
+	si := structFieldInfo{
 		// name: fname,
 		// name: fname,
 		encName: fname,
 		encName: fname,
 		// tag: stag,
 		// tag: stag,
-	}	
-	
+	}
+
 	if stag != "" {
 	if stag != "" {
 		for i, s := range strings.Split(stag, ",") {
 		for i, s := range strings.Split(stag, ",") {
 			if i == 0 {
 			if i == 0 {
@@ -233,22 +240,19 @@ func parseStructFieldInfo(fname string, stag string) (*structFieldInfo) {
 }
 }
 
 
 func panicToErr(err *error) {
 func panicToErr(err *error) {
-	if x := recover(); x != nil { 
-		//debug.PrintStack() 
+	if x := recover(); x != nil {
+		//debug.PrintStack()
 		panicValToErr(x, err)
 		panicValToErr(x, err)
 	}
 	}
 }
 }
 
 
 func doPanic(tag string, format string, params ...interface{}) {
 func doPanic(tag string, format string, params ...interface{}) {
-	params2 := make([]interface{}, len(params) + 1)
+	params2 := make([]interface{}, len(params)+1)
 	params2[0] = tag
 	params2[0] = tag
 	copy(params2[1:], params)
 	copy(params2[1:], params)
-	panic(fmt.Errorf("%s: " + format, params2...))
+	panic(fmt.Errorf("%s: "+format, params2...))
 }
 }
 
 
-
-
-
 //--------------------------------------------------
 //--------------------------------------------------
 
 
 // // This implements the util.Codec interface
 // // This implements the util.Codec interface
@@ -271,4 +275,3 @@ func doPanic(tag string, format string, params ...interface{}) {
 // func (x Codec) DecodeBytes(in []byte, v interface{}) error {
 // func (x Codec) DecodeBytes(in []byte, v interface{}) error {
 // 	return NewDecoderBytes(in, x.H).Decode(v)
 // 	return NewDecoderBytes(in, x.H).Decode(v)
 // }
 // }
-

+ 26 - 3
codec/helper_internal.go

@@ -7,14 +7,14 @@ package codec
 // so porting to different environment is easy (just update functions).
 // so porting to different environment is easy (just update functions).
 
 
 import (
 import (
-	"reflect"
-	"fmt"
 	"errors"
 	"errors"
+	"fmt"
+	"reflect"
 )
 )
 
 
 var (
 var (
 	raisePanicAfterRecover = false
 	raisePanicAfterRecover = false
-	debugging = true
+	debugging              = true
 )
 )
 
 
 func panicValToErr(panicVal interface{}, err *error) {
 func panicValToErr(panicVal interface{}, err *error) {
@@ -59,3 +59,26 @@ func debugf(format string, args ...interface{}) {
 	}
 	}
 }
 }
 
 
+func pruneSignExt(v []byte) (n int) {
+	l := len(v)
+	if l < 2 {
+		return
+	}
+	if v[0] == 0 {
+		n2 := n + 1
+		for v[n] == 0 && n2 < l && (v[n2]&(1<<7) == 0) {
+			n++
+			n2++
+		}
+		return
+	}
+	if v[0] == 0xff {
+		n2 := n + 1
+		for v[n] == 0xff && n2 < l && (v[n2]&(1<<7) != 0) {
+			n++
+			n2++
+		}
+		return
+	}
+	return
+}

+ 115 - 121
codec/msgpack.go

@@ -4,44 +4,44 @@
 package codec
 package codec
 
 
 import (
 import (
-	"reflect"
-	"math"
-	"time"
 	"fmt"
 	"fmt"
-	"net/rpc"
 	"io"
 	"io"
+	"math"
+	"net/rpc"
+	"reflect"
+	"time"
 )
 )
 
 
 const (
 const (
 	mpPosFixNumMin byte = 0x00
 	mpPosFixNumMin byte = 0x00
-	mpPosFixNumMax = 0x7f
-	mpFixMapMin = 0x80
-	mpFixMapMax = 0x8f
-	mpFixArrayMin =  0x90
-	mpFixArrayMax =  0x9f
-	mpFixRawMin  = 0xa0
-	mpFixRawMax  = 0xbf
-	mpNil = 0xc0
-	mpFalse = 0xc2
-	mpTrue = 0xc3
-	mpFloat = 0xca
-	mpDouble = 0xcb
-	mpUint8 = 0xcc
-	mpUint16 = 0xcd
-	mpUint32 = 0xce
-	mpUint64 = 0xcf
-	mpInt8 = 0xd0
-	mpInt16 = 0xd1
-	mpInt32 = 0xd2
-	mpInt64 = 0xd3
-	mpRaw16 = 0xda
-	mpRaw32 = 0xdb
-	mpArray16 = 0xdc
-	mpArray32 = 0xdd
-	mpMap16 = 0xde
-	mpMap32 = 0xdf
-	mpNegFixNumMin = 0xe0
-	mpNegFixNumMax = 0xff
+	mpPosFixNumMax      = 0x7f
+	mpFixMapMin         = 0x80
+	mpFixMapMax         = 0x8f
+	mpFixArrayMin       = 0x90
+	mpFixArrayMax       = 0x9f
+	mpFixRawMin         = 0xa0
+	mpFixRawMax         = 0xbf
+	mpNil               = 0xc0
+	mpFalse             = 0xc2
+	mpTrue              = 0xc3
+	mpFloat             = 0xca
+	mpDouble            = 0xcb
+	mpUint8             = 0xcc
+	mpUint16            = 0xcd
+	mpUint32            = 0xce
+	mpUint64            = 0xcf
+	mpInt8              = 0xd0
+	mpInt16             = 0xd1
+	mpInt32             = 0xd2
+	mpInt64             = 0xd3
+	mpRaw16             = 0xda
+	mpRaw32             = 0xdb
+	mpArray16           = 0xdc
+	mpArray32           = 0xdd
+	mpMap16             = 0xde
+	mpMap32             = 0xdf
+	mpNegFixNumMin      = 0xe0
+	mpNegFixNumMax      = 0xff
 
 
 	// extensions below
 	// extensions below
 	// mpBin8 = 0xc4
 	// mpBin8 = 0xc4
@@ -64,31 +64,31 @@ const (
 	mpXv4Fixext4 = 0xc8
 	mpXv4Fixext4 = 0xc8
 	mpXv4Fixext5 = 0xc9
 	mpXv4Fixext5 = 0xc9
 
 
-	mpXv4Ext8m = 0xd4
+	mpXv4Ext8m  = 0xd4
 	mpXv4Ext16m = 0xd5
 	mpXv4Ext16m = 0xd5
 	mpXv4Ext32m = 0xd6
 	mpXv4Ext32m = 0xd6
-	mpXv4Ext8 = 0xd7
-	mpXv4Ext16 = 0xd8
-	mpXv4Ext32 = 0xd9
-)	
+	mpXv4Ext8   = 0xd7
+	mpXv4Ext16  = 0xd8
+	mpXv4Ext32  = 0xd9
+)
 
 
-// MsgpackSpecRpc implements Rpc using the communication protocol defined in 
+// MsgpackSpecRpc implements Rpc using the communication protocol defined in
 // the msgpack spec at http://wiki.msgpack.org/display/MSGPACK/RPC+specification
 // the msgpack spec at http://wiki.msgpack.org/display/MSGPACK/RPC+specification
 var MsgpackSpecRpc msgpackSpecRpc
 var MsgpackSpecRpc msgpackSpecRpc
 
 
 // A MsgpackContainer type specifies the different types of msgpackContainers.
 // A MsgpackContainer type specifies the different types of msgpackContainers.
 type msgpackContainerType struct {
 type msgpackContainerType struct {
-	cutoff int8
+	cutoff     int8
 	b0, b1, b2 byte
 	b0, b1, b2 byte
 }
 }
 
 
 var (
 var (
 	msgpackContainerRawBytes = msgpackContainerType{32, mpFixRawMin, mpRaw16, mpRaw32}
 	msgpackContainerRawBytes = msgpackContainerType{32, mpFixRawMin, mpRaw16, mpRaw32}
-	msgpackContainerList = msgpackContainerType{16, mpFixArrayMin, mpArray16, mpArray32}
-	msgpackContainerMap = msgpackContainerType{16, mpFixMapMin, mpMap16, mpMap32}
+	msgpackContainerList     = msgpackContainerType{16, mpFixArrayMin, mpArray16, mpArray32}
+	msgpackContainerMap      = msgpackContainerType{16, mpFixMapMin, mpMap16, mpMap32}
 )
 )
 
 
-// msgpackSpecRpc is the implementation of Rpc that uses custom communication protocol 
+// msgpackSpecRpc is the implementation of Rpc that uses custom communication protocol
 // as defined in the msgpack spec at http://wiki.msgpack.org/display/MSGPACK/RPC+specification
 // as defined in the msgpack spec at http://wiki.msgpack.org/display/MSGPACK/RPC+specification
 type msgpackSpecRpc struct{}
 type msgpackSpecRpc struct{}
 
 
@@ -99,44 +99,44 @@ type msgpackSpecRpcCodec struct {
 //MsgpackHandle is a Handle for the Msgpack Schema-Free Encoding Format.
 //MsgpackHandle is a Handle for the Msgpack Schema-Free Encoding Format.
 type MsgpackHandle struct {
 type MsgpackHandle struct {
 	// RawToString controls how raw bytes are decoded into a nil interface{}.
 	// RawToString controls how raw bytes are decoded into a nil interface{}.
-	// Note that setting an extension func for []byte ensures that raw bytes 
-	// are decoded as strings, regardless of this setting. 
+	// Note that setting an extension func for []byte ensures that raw bytes
+	// are decoded as strings, regardless of this setting.
 	// This setting is used only if an extension func isn't defined for []byte.
 	// This setting is used only if an extension func isn't defined for []byte.
 	RawToString bool
 	RawToString bool
 	// WriteExt flag supports encoding configured extensions with extension tags.
 	// WriteExt flag supports encoding configured extensions with extension tags.
-	// 
+	//
 	// With WriteExt=false, configured extensions are serialized as raw bytes.
 	// With WriteExt=false, configured extensions are serialized as raw bytes.
-	// 
-	// They can still be decoded into a typed object, provided an appropriate one is 
+	//
+	// They can still be decoded into a typed object, provided an appropriate one is
 	// provided, but the type cannot be inferred from the stream. If no appropriate
 	// provided, but the type cannot be inferred from the stream. If no appropriate
 	// type is provided (e.g. decoding into a nil interface{}), you get back
 	// type is provided (e.g. decoding into a nil interface{}), you get back
 	// a []byte or string based on the setting of RawToString.
 	// a []byte or string based on the setting of RawToString.
-	WriteExt bool	
+	WriteExt bool
 
 
 	encdecHandle
 	encdecHandle
 	DecodeOptions
 	DecodeOptions
 }
 }
 
 
-type msgpackEncoder struct { 
+type msgpackEncDriver struct {
 	w encWriter
 	w encWriter
 }
 }
 
 
-type msgpackDecoder struct {
-	r decReader
-	bd byte
+type msgpackDecDriver struct {
+	r      decReader
+	bd     byte
 	bdRead bool
 	bdRead bool
 }
 }
 
 
-func (e *msgpackEncoder) encodeBuiltinType(rt reflect.Type, rv reflect.Value) bool {
+func (e *msgpackEncDriver) encodeBuiltinType(rt reflect.Type, rv reflect.Value) bool {
 	//no builtin types. All encodings are based on kinds. Types supported as extensions.
 	//no builtin types. All encodings are based on kinds. Types supported as extensions.
 	return false
 	return false
 }
 }
 
 
-func (e *msgpackEncoder) encodeNil() {
+func (e *msgpackEncDriver) encodeNil() {
 	e.w.writen1(mpNil)
 	e.w.writen1(mpNil)
 }
 }
 
 
-func (e *msgpackEncoder) encodeInt(i int64) {
+func (e *msgpackEncDriver) encodeInt(i int64) {
 	switch {
 	switch {
 	case i >= -32 && i <= math.MaxInt8:
 	case i >= -32 && i <= math.MaxInt8:
 		e.w.writen1(byte(i))
 		e.w.writen1(byte(i))
@@ -156,7 +156,7 @@ func (e *msgpackEncoder) encodeInt(i int64) {
 	}
 	}
 }
 }
 
 
-func (e *msgpackEncoder) encodeUint(i uint64) {
+func (e *msgpackEncDriver) encodeUint(i uint64) {
 	// uints are not fixnums. fixnums are always signed.
 	// uints are not fixnums. fixnums are always signed.
 	// case i <= math.MaxInt8:
 	// case i <= math.MaxInt8:
 	// 	e.w.writen1(byte(i))
 	// 	e.w.writen1(byte(i))
@@ -175,7 +175,7 @@ func (e *msgpackEncoder) encodeUint(i uint64) {
 	}
 	}
 }
 }
 
 
-func (e *msgpackEncoder) encodeBool(b bool) {
+func (e *msgpackEncDriver) encodeBool(b bool) {
 	if b {
 	if b {
 		e.w.writen1(mpTrue)
 		e.w.writen1(mpTrue)
 	} else {
 	} else {
@@ -183,22 +183,22 @@ func (e *msgpackEncoder) encodeBool(b bool) {
 	}
 	}
 }
 }
 
 
-func (e *msgpackEncoder) encodeFloat32(f float32) {
+func (e *msgpackEncDriver) encodeFloat32(f float32) {
 	e.w.writen1(mpFloat)
 	e.w.writen1(mpFloat)
 	e.w.writeUint32(math.Float32bits(f))
 	e.w.writeUint32(math.Float32bits(f))
 }
 }
 
 
-func (e *msgpackEncoder) encodeFloat64(f float64) {
+func (e *msgpackEncDriver) encodeFloat64(f float64) {
 	e.w.writen1(mpDouble)
 	e.w.writen1(mpDouble)
 	e.w.writeUint64(math.Float64bits(f))
 	e.w.writeUint64(math.Float64bits(f))
 }
 }
 
 
-func (e *msgpackEncoder) encodeExtPreamble(xtag byte, l int) {
+func (e *msgpackEncDriver) encodeExtPreamble(xtag byte, l int) {
 	switch {
 	switch {
 	case l <= 4:
 	case l <= 4:
-		e.w.writen2(0xd4 | byte(l), xtag)
+		e.w.writen2(0xd4|byte(l), xtag)
 	case l <= 8:
 	case l <= 8:
-		e.w.writen2(0xc0 | byte(l), xtag)
+		e.w.writen2(0xc0|byte(l), xtag)
 	case l < 256:
 	case l < 256:
 		e.w.writen3(mpXv4Fixext5, xtag, byte(l))
 		e.w.writen3(mpXv4Fixext5, xtag, byte(l))
 	case l < 65536:
 	case l < 65536:
@@ -210,36 +210,35 @@ func (e *msgpackEncoder) encodeExtPreamble(xtag byte, l int) {
 	}
 	}
 }
 }
 
 
-func (e *msgpackEncoder) encodeArrayPreamble(length int) {
+func (e *msgpackEncDriver) encodeArrayPreamble(length int) {
 	e.writeContainerLen(msgpackContainerList, length)
 	e.writeContainerLen(msgpackContainerList, length)
 }
 }
 
 
-
-func (e *msgpackEncoder) encodeMapPreamble(length int) {
-	e.writeContainerLen(msgpackContainerMap, length)	
+func (e *msgpackEncDriver) encodeMapPreamble(length int) {
+	e.writeContainerLen(msgpackContainerMap, length)
 }
 }
 
 
-func (e *msgpackEncoder) encodeString(c charEncoding, s string) {
-	//ignore charEncoding. 
+func (e *msgpackEncDriver) encodeString(c charEncoding, s string) {
+	//ignore charEncoding.
 	e.writeContainerLen(msgpackContainerRawBytes, len(s))
 	e.writeContainerLen(msgpackContainerRawBytes, len(s))
 	if len(s) > 0 {
 	if len(s) > 0 {
 		e.w.writestr(s)
 		e.w.writestr(s)
 	}
 	}
 }
 }
 
 
-func (e *msgpackEncoder) encodeSymbol(v string) { 
+func (e *msgpackEncDriver) encodeSymbol(v string) {
 	e.encodeString(c_UTF8, v)
 	e.encodeString(c_UTF8, v)
 }
 }
 
 
-func (e *msgpackEncoder) encodeStringBytes(c charEncoding, bs []byte) {
-	//ignore charEncoding. 
+func (e *msgpackEncDriver) encodeStringBytes(c charEncoding, bs []byte) {
+	//ignore charEncoding.
 	e.writeContainerLen(msgpackContainerRawBytes, len(bs))
 	e.writeContainerLen(msgpackContainerRawBytes, len(bs))
 	if len(bs) > 0 {
 	if len(bs) > 0 {
 		e.w.writeb(bs)
 		e.w.writeb(bs)
 	}
 	}
 }
 }
 
 
-func (e *msgpackEncoder) writeContainerLen(ct msgpackContainerType, l int) {
+func (e *msgpackEncDriver) writeContainerLen(ct msgpackContainerType, l int) {
 	switch {
 	switch {
 	case l < int(ct.cutoff):
 	case l < int(ct.cutoff):
 		e.w.writen1(ct.b0 | byte(l))
 		e.w.writen1(ct.b0 | byte(l))
@@ -254,19 +253,19 @@ func (e *msgpackEncoder) writeContainerLen(ct msgpackContainerType, l int) {
 
 
 //---------------------------------------------
 //---------------------------------------------
 
 
-func (d *msgpackDecoder) decodeBuiltinType(rt reflect.Type, rv reflect.Value) bool { 
+func (d *msgpackDecDriver) decodeBuiltinType(rt reflect.Type, rv reflect.Value) bool {
 	return false
 	return false
 }
 }
 
 
 // Note: This returns either a primitive (int, bool, etc) for non-containers,
 // Note: This returns either a primitive (int, bool, etc) for non-containers,
-// or a containerType, or a specific type denoting nil or extension. 
-// It is called when a nil interface{} is passed, leaving it up to the Decoder
+// or a containerType, or a specific type denoting nil or extension.
+// It is called when a nil interface{} is passed, leaving it up to the DecDriver
 // to introspect the stream and decide how best to decode.
 // to introspect the stream and decide how best to decode.
 // It deciphers the value by looking at the stream first.
 // It deciphers the value by looking at the stream first.
-func (d *msgpackDecoder) decodeNaked(h decodeHandleI) (rv reflect.Value, ctx decodeNakedContext) {
+func (d *msgpackDecDriver) decodeNaked(h decodeHandleI) (rv reflect.Value, ctx decodeNakedContext) {
 	d.initReadNext()
 	d.initReadNext()
 	bd := d.bd
 	bd := d.bd
-	
+
 	var v interface{}
 	var v interface{}
 
 
 	switch bd {
 	switch bd {
@@ -282,7 +281,7 @@ func (d *msgpackDecoder) decodeNaked(h decodeHandleI) (rv reflect.Value, ctx dec
 		v = float64(math.Float32frombits(d.r.readUint32()))
 		v = float64(math.Float32frombits(d.r.readUint32()))
 	case mpDouble:
 	case mpDouble:
 		v = math.Float64frombits(d.r.readUint64())
 		v = math.Float64frombits(d.r.readUint64())
-		
+
 	case mpUint8:
 	case mpUint8:
 		v = uint64(d.r.readn1())
 		v = uint64(d.r.readn1())
 	case mpUint16:
 	case mpUint16:
@@ -291,7 +290,7 @@ func (d *msgpackDecoder) decodeNaked(h decodeHandleI) (rv reflect.Value, ctx dec
 		v = uint64(d.r.readUint32())
 		v = uint64(d.r.readUint32())
 	case mpUint64:
 	case mpUint64:
 		v = uint64(d.r.readUint64())
 		v = uint64(d.r.readUint64())
-		
+
 	case mpInt8:
 	case mpInt8:
 		v = int64(int8(d.r.readn1()))
 		v = int64(int8(d.r.readn1()))
 	case mpInt16:
 	case mpInt16:
@@ -300,7 +299,7 @@ func (d *msgpackDecoder) decodeNaked(h decodeHandleI) (rv reflect.Value, ctx dec
 		v = int64(int32(d.r.readUint32()))
 		v = int64(int32(d.r.readUint32()))
 	case mpInt64:
 	case mpInt64:
 		v = int64(int64(d.r.readUint64()))
 		v = int64(int64(d.r.readUint64()))
-		
+
 	default:
 	default:
 		switch {
 		switch {
 		case bd >= mpPosFixNumMin && bd <= mpPosFixNumMax:
 		case bd >= mpPosFixNumMin && bd <= mpPosFixNumMax:
@@ -308,7 +307,7 @@ func (d *msgpackDecoder) decodeNaked(h decodeHandleI) (rv reflect.Value, ctx dec
 			v = int64(int8(bd))
 			v = int64(int8(bd))
 		case bd >= mpNegFixNumMin && bd <= mpNegFixNumMax:
 		case bd >= mpNegFixNumMin && bd <= mpNegFixNumMax:
 			// negative fixnum
 			// negative fixnum
-			v = int64(int8(bd))		
+			v = int64(int8(bd))
 		case bd == mpRaw16, bd == mpRaw32, bd >= mpFixRawMin && bd <= mpFixRawMax:
 		case bd == mpRaw16, bd == mpRaw32, bd >= mpFixRawMin && bd <= mpFixRawMax:
 			ctx = dncContainer
 			ctx = dncContainer
 			// v = containerRawBytes
 			// v = containerRawBytes
@@ -352,7 +351,7 @@ func (d *msgpackDecoder) decodeNaked(h decodeHandleI) (rv reflect.Value, ctx dec
 			}
 			}
 			if fnerr := bfn(rv, d.r.readn(d.readExtLen())); fnerr != nil {
 			if fnerr := bfn(rv, d.r.readn(d.readExtLen())); fnerr != nil {
 				panic(fnerr)
 				panic(fnerr)
-			} 
+			}
 		default:
 		default:
 			decErr("Nil-Deciphered DecodeValue: %s: hex: %x, dec: %d", msgBadDesc, bd, bd)
 			decErr("Nil-Deciphered DecodeValue: %s: hex: %x, dec: %d", msgBadDesc, bd, bd)
 		}
 		}
@@ -366,8 +365,8 @@ func (d *msgpackDecoder) decodeNaked(h decodeHandleI) (rv reflect.Value, ctx dec
 	return
 	return
 }
 }
 
 
-// int can be decoded from msgpack type: intXXX or uintXXX 
-func (d *msgpackDecoder) decodeInt(bitsize uint8) (i int64) {
+// int can be decoded from msgpack type: intXXX or uintXXX
+func (d *msgpackDecDriver) decodeInt(bitsize uint8) (i int64) {
 	switch d.bd {
 	switch d.bd {
 	case mpUint8:
 	case mpUint8:
 		i = int64(uint64(d.r.readn1()))
 		i = int64(uint64(d.r.readn1()))
@@ -405,9 +404,8 @@ func (d *msgpackDecoder) decodeInt(bitsize uint8) (i int64) {
 	return
 	return
 }
 }
 
 
-
-// uint can be decoded from msgpack type: intXXX or uintXXX 
-func (d *msgpackDecoder) decodeUint(bitsize uint8) (ui uint64) {
+// uint can be decoded from msgpack type: intXXX or uintXXX
+func (d *msgpackDecDriver) decodeUint(bitsize uint8) (ui uint64) {
 	switch d.bd {
 	switch d.bd {
 	case mpUint8:
 	case mpUint8:
 		ui = uint64(d.r.readn1())
 		ui = uint64(d.r.readn1())
@@ -454,7 +452,7 @@ func (d *msgpackDecoder) decodeUint(bitsize uint8) (ui uint64) {
 	// check overflow (logic adapted from std pkg reflect/value.go OverflowUint()
 	// check overflow (logic adapted from std pkg reflect/value.go OverflowUint()
 	if bitsize > 0 {
 	if bitsize > 0 {
 		if trunc := (ui << (64 - bitsize)) >> (64 - bitsize); ui != trunc {
 		if trunc := (ui << (64 - bitsize)) >> (64 - bitsize); ui != trunc {
-			decErr("Overflow uint value: %v", ui) 
+			decErr("Overflow uint value: %v", ui)
 		}
 		}
 	}
 	}
 	d.bdRead = false
 	d.bdRead = false
@@ -462,7 +460,7 @@ func (d *msgpackDecoder) decodeUint(bitsize uint8) (ui uint64) {
 }
 }
 
 
 // float can either be decoded from msgpack type: float, double or intX
 // float can either be decoded from msgpack type: float, double or intX
-func (d *msgpackDecoder) decodeFloat(chkOverflow32 bool) (f float64) {
+func (d *msgpackDecDriver) decodeFloat(chkOverflow32 bool) (f float64) {
 	switch d.bd {
 	switch d.bd {
 	case mpFloat:
 	case mpFloat:
 		f = float64(math.Float32frombits(d.r.readUint32()))
 		f = float64(math.Float32frombits(d.r.readUint32()))
@@ -486,7 +484,7 @@ func (d *msgpackDecoder) decodeFloat(chkOverflow32 bool) (f float64) {
 }
 }
 
 
 // bool can be decoded from bool, fixnum 0 or 1.
 // bool can be decoded from bool, fixnum 0 or 1.
-func (d *msgpackDecoder) decodeBool() (b bool) {
+func (d *msgpackDecDriver) decodeBool() (b bool) {
 	switch d.bd {
 	switch d.bd {
 	case mpFalse, 0:
 	case mpFalse, 0:
 		// b = false
 		// b = false
@@ -498,8 +496,8 @@ func (d *msgpackDecoder) decodeBool() (b bool) {
 	d.bdRead = false
 	d.bdRead = false
 	return
 	return
 }
 }
-	
-func (d *msgpackDecoder) decodeString() (s string) {
+
+func (d *msgpackDecDriver) decodeString() (s string) {
 	clen := d.readContainerLen(msgpackContainerRawBytes)
 	clen := d.readContainerLen(msgpackContainerRawBytes)
 	if clen > 0 {
 	if clen > 0 {
 		s = string(d.r.readn(clen))
 		s = string(d.r.readn(clen))
@@ -509,14 +507,14 @@ func (d *msgpackDecoder) decodeString() (s string) {
 }
 }
 
 
 // Callers must check if changed=true (to decide whether to replace the one they have)
 // Callers must check if changed=true (to decide whether to replace the one they have)
-func (d *msgpackDecoder) decodeBytes(bs []byte) (bsOut []byte, changed bool) {
+func (d *msgpackDecDriver) decodeBytes(bs []byte) (bsOut []byte, changed bool) {
 	clen := d.readContainerLen(msgpackContainerRawBytes)
 	clen := d.readContainerLen(msgpackContainerRawBytes)
 	// if clen < 0 {
 	// if clen < 0 {
 	// 	changed = true
 	// 	changed = true
 	// 	panic("length cannot be zero. this cannot be nil.")
 	// 	panic("length cannot be zero. this cannot be nil.")
-	// } 
+	// }
 	if clen > 0 {
 	if clen > 0 {
-		// if no contents in stream, don't update the passed byteslice	
+		// if no contents in stream, don't update the passed byteslice
 		if len(bs) != clen {
 		if len(bs) != clen {
 			// Return changed=true if length of passed slice is different from length of bytes in the stream.
 			// Return changed=true if length of passed slice is different from length of bytes in the stream.
 			if len(bs) > clen {
 			if len(bs) > clen {
@@ -534,7 +532,7 @@ func (d *msgpackDecoder) decodeBytes(bs []byte) (bsOut []byte, changed bool) {
 }
 }
 
 
 // Every top-level decode funcs (i.e. decodeValue, decode) must call this first.
 // Every top-level decode funcs (i.e. decodeValue, decode) must call this first.
-func (d *msgpackDecoder) initReadNext() {
+func (d *msgpackDecDriver) initReadNext() {
 	if d.bdRead {
 	if d.bdRead {
 		return
 		return
 	}
 	}
@@ -542,15 +540,15 @@ func (d *msgpackDecoder) initReadNext() {
 	d.bdRead = true
 	d.bdRead = true
 }
 }
 
 
-func (d *msgpackDecoder) currentIsNil() bool {
+func (d *msgpackDecDriver) currentIsNil() bool {
 	if d.bd == mpNil {
 	if d.bd == mpNil {
 		d.bdRead = false
 		d.bdRead = false
 		return true
 		return true
-	} 
+	}
 	return false
 	return false
 }
 }
 
 
-func (d *msgpackDecoder) readContainerLen(ct msgpackContainerType) (clen int) {
+func (d *msgpackDecDriver) readContainerLen(ct msgpackContainerType) (clen int) {
 	switch {
 	switch {
 	case d.bd == mpNil:
 	case d.bd == mpNil:
 		clen = -1 // to represent nil
 		clen = -1 // to represent nil
@@ -564,19 +562,18 @@ func (d *msgpackDecoder) readContainerLen(ct msgpackContainerType) (clen int) {
 		decErr("readContainerLen: %s: hex: %x, dec: %d", msgBadDesc, d.bd, d.bd)
 		decErr("readContainerLen: %s: hex: %x, dec: %d", msgBadDesc, d.bd, d.bd)
 	}
 	}
 	d.bdRead = false
 	d.bdRead = false
-	return	
+	return
 }
 }
 
 
-func (d *msgpackDecoder) readMapLen() int {
+func (d *msgpackDecDriver) readMapLen() int {
 	return d.readContainerLen(msgpackContainerMap)
 	return d.readContainerLen(msgpackContainerMap)
 }
 }
 
 
-func (d *msgpackDecoder) readArrayLen() int {
+func (d *msgpackDecDriver) readArrayLen() int {
 	return d.readContainerLen(msgpackContainerList)
 	return d.readContainerLen(msgpackContainerList)
 }
 }
 
 
-
-func (d *msgpackDecoder) readExtLen() (clen int) {
+func (d *msgpackDecDriver) readExtLen() (clen int) {
 	switch d.bd {
 	switch d.bd {
 	case mpNil:
 	case mpNil:
 		clen = -1 // to represent nil
 		clen = -1 // to represent nil
@@ -586,7 +583,7 @@ func (d *msgpackDecoder) readExtLen() (clen int) {
 		clen = int(d.r.readUint16())
 		clen = int(d.r.readUint16())
 	case mpXv4Ext32:
 	case mpXv4Ext32:
 		clen = int(d.r.readUint32())
 		clen = int(d.r.readUint32())
-	default: 
+	default:
 		switch {
 		switch {
 		case d.bd >= mpXv4Fixext0 && d.bd <= mpXv4Fixext4:
 		case d.bd >= mpXv4Fixext0 && d.bd <= mpXv4Fixext4:
 			clen = int(d.bd & 0x0f)
 			clen = int(d.bd & 0x0f)
@@ -599,7 +596,7 @@ func (d *msgpackDecoder) readExtLen() (clen int) {
 	return
 	return
 }
 }
 
 
-func (d *msgpackDecoder) decodeExt(tag byte) (xbs []byte) {
+func (d *msgpackDecDriver) decodeExt(tag byte) (xbs []byte) {
 	// if (d.bd >= mpXv4Fixext0 && d.bd <= mpXv4Fixext5) || (d.bd >= mpXv4Ext8m && d.bd <= mpXv4Ext32) {
 	// if (d.bd >= mpXv4Fixext0 && d.bd <= mpXv4Fixext5) || (d.bd >= mpXv4Ext8m && d.bd <= mpXv4Ext32) {
 	xbd := d.bd
 	xbd := d.bd
 	switch {
 	switch {
@@ -612,19 +609,19 @@ func (d *msgpackDecoder) decodeExt(tag byte) (xbs []byte) {
 		xbs, _ = d.decodeBytes(nil)
 		xbs, _ = d.decodeBytes(nil)
 	default:
 	default:
 		decErr("Wrong byte descriptor (Expecting extensions or raw bytes). Got: 0x%x", xbd)
 		decErr("Wrong byte descriptor (Expecting extensions or raw bytes). Got: 0x%x", xbd)
-	}		
+	}
 	d.bdRead = false
 	d.bdRead = false
 	return
 	return
 }
 }
 
 
 //--------------------------------------------------
 //--------------------------------------------------
 
 
-func (msgpackSpecRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) (rpc.ServerCodec) {
-	return &msgpackSpecRpcCodec{ newRPCCodec(conn, h) }
+func (msgpackSpecRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
+	return &msgpackSpecRpcCodec{newRPCCodec(conn, h)}
 }
 }
 
 
-func (msgpackSpecRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) (rpc.ClientCodec) {
-	return &msgpackSpecRpcCodec{ newRPCCodec(conn, h) }
+func (msgpackSpecRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec {
+	return &msgpackSpecRpcCodec{newRPCCodec(conn, h)}
 }
 }
 
 
 // /////////////// Spec RPC Codec ///////////////////
 // /////////////// Spec RPC Codec ///////////////////
@@ -646,13 +643,13 @@ func (c msgpackSpecRpcCodec) ReadRequestHeader(r *rpc.Request) error {
 
 
 func (c msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint64, methodOrError *string) (err error) {
 func (c msgpackSpecRpcCodec) parseCustomHeader(expectTypeByte byte, msgid *uint64, methodOrError *string) (err error) {
 
 
-	// We read the response header by hand 
+	// We read the response header by hand
 	// so that the body can be decoded on its own from the stream at a later time.
 	// so that the body can be decoded on its own from the stream at a later time.
 
 
 	bs := make([]byte, 1)
 	bs := make([]byte, 1)
 	n, err := c.rwc.Read(bs)
 	n, err := c.rwc.Read(bs)
 	if err != nil {
 	if err != nil {
-		return 
+		return
 	}
 	}
 	if n != 1 {
 	if n != 1 {
 		err = fmt.Errorf("Couldn't read array descriptor: No bytes read")
 		err = fmt.Errorf("Couldn't read array descriptor: No bytes read")
@@ -685,12 +682,10 @@ func (c msgpackSpecRpcCodec) writeCustomBody(typeByte byte, msgid uint64, method
 			body = nil
 			body = nil
 		}
 		}
 	}
 	}
-	r2 := []interface{}{ typeByte, uint32(msgid), moe, body }
+	r2 := []interface{}{typeByte, uint32(msgid), moe, body}
 	return c.enc.Encode(r2)
 	return c.enc.Encode(r2)
 }
 }
 
 
-
-
 //--------------------------------------------------
 //--------------------------------------------------
 
 
 // EncodeBinaryExt returns the underlying bytes of this value AS-IS.
 // EncodeBinaryExt returns the underlying bytes of this value AS-IS.
@@ -724,15 +719,14 @@ func (_ *MsgpackHandle) TimeDecodeExt(rv reflect.Value, bs []byte) (err error) {
 	return
 	return
 }
 }
 
 
-func (_ *MsgpackHandle) newEncoder(w encWriter) encoder {
-	return &msgpackEncoder{w: w}
+func (_ *MsgpackHandle) newEncDriver(w encWriter) encDriver {
+	return &msgpackEncDriver{w: w}
 }
 }
 
 
-func (_ *MsgpackHandle) newDecoder(r decReader) decoder {
-	return &msgpackDecoder{r: r}
+func (_ *MsgpackHandle) newDecDriver(r decReader) decDriver {
+	return &msgpackDecDriver{r: r}
 }
 }
 
 
 func (o *MsgpackHandle) writeExt() bool {
 func (o *MsgpackHandle) writeExt() bool {
 	return o.WriteExt
 	return o.WriteExt
 }
 }
-

+ 15 - 16
codec/rpc.go

@@ -5,13 +5,13 @@
 RPC
 RPC
 
 
 RPC Client and Server Codecs are implemented, so the codecs can be used
 RPC Client and Server Codecs are implemented, so the codecs can be used
-with the standard net/rpc package. 
+with the standard net/rpc package.
 */
 */
 package codec
 package codec
 
 
 import (
 import (
-	"net/rpc"
 	"io"
 	"io"
+	"net/rpc"
 )
 )
 
 
 // GoRpc implements Rpc using the communication protocol defined in net/rpc package.
 // GoRpc implements Rpc using the communication protocol defined in net/rpc package.
@@ -19,33 +19,33 @@ var GoRpc goRpc
 
 
 // Rpc interface provides a rpc Server or Client Codec for rpc communication.
 // Rpc interface provides a rpc Server or Client Codec for rpc communication.
 type Rpc interface {
 type Rpc interface {
-	ServerCodec(conn io.ReadWriteCloser, h Handle) (rpc.ServerCodec) 
-	ClientCodec(conn io.ReadWriteCloser, h Handle) (rpc.ClientCodec)
+	ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec
+	ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec
 }
 }
 
 
 type rpcCodec struct {
 type rpcCodec struct {
-	rwc       io.ReadWriteCloser
-	dec       *Decoder
-	enc       *Encoder
+	rwc io.ReadWriteCloser
+	dec *Decoder
+	enc *Encoder
 }
 }
 
 
 type goRpcCodec struct {
 type goRpcCodec struct {
 	rpcCodec
 	rpcCodec
 }
 }
 
 
-// goRpc is the implementation of Rpc that uses the communication protocol 
+// goRpc is the implementation of Rpc that uses the communication protocol
 // as defined in net/rpc package.
 // as defined in net/rpc package.
-type goRpc struct {}
+type goRpc struct{}
 
 
-func (x goRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) (rpc.ServerCodec) {
-	return goRpcCodec { newRPCCodec(conn, h) }
+func (x goRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
+	return goRpcCodec{newRPCCodec(conn, h)}
 }
 }
 
 
-func (x goRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) (rpc.ClientCodec) {
-	return goRpcCodec { newRPCCodec(conn, h) }
+func (x goRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec {
+	return goRpcCodec{newRPCCodec(conn, h)}
 }
 }
 
 
-func newRPCCodec(conn io.ReadWriteCloser, h Handle) (rpcCodec) {
+func newRPCCodec(conn io.ReadWriteCloser, h Handle) rpcCodec {
 	return rpcCodec{
 	return rpcCodec{
 		rwc: conn,
 		rwc: conn,
 		dec: NewDecoder(conn, h),
 		dec: NewDecoder(conn, h),
@@ -79,7 +79,7 @@ func (c rpcCodec) read(objs ...interface{}) (err error) {
 }
 }
 
 
 func (c rpcCodec) Close() error {
 func (c rpcCodec) Close() error {
-	return c.rwc.Close()	
+	return c.rwc.Close()
 }
 }
 
 
 func (c rpcCodec) ReadResponseBody(body interface{}) (err error) {
 func (c rpcCodec) ReadResponseBody(body interface{}) (err error) {
@@ -108,4 +108,3 @@ func (c goRpcCodec) ReadResponseHeader(r *rpc.Response) (err error) {
 func (c goRpcCodec) ReadRequestHeader(r *rpc.Request) error {
 func (c goRpcCodec) ReadRequestHeader(r *rpc.Request) error {
 	return c.read(r)
 	return c.read(r)
 }
 }
-

+ 122 - 0
codec/time.go

@@ -0,0 +1,122 @@
+// Copyright (c) 2012, 2013 Ugorji Nwoke. All rights reserved.
+// Use of this source code is governed by a BSD-style license found in the LICENSE file.
+
+package codec
+
+import (
+	"time"
+)
+
+// encodeTime encodes a time.Time as a []byte, including
+// information on the instant in time and UTC offset.
+func encodeTime(t time.Time) []byte {
+	//t := rv.Interface().(time.Time)
+	tsecs, tnsecs := t.Unix(), t.Nanosecond()
+	var (
+		bd   byte
+		btmp [8]byte
+		bs   [16]byte
+		i    int = 1
+	)
+	l := t.Location()
+	if l == time.UTC {
+		l = nil
+	}
+	if tsecs != 0 {
+		bd = bd | 0x80
+		bigen.PutUint64(btmp[:], uint64(tsecs))
+		f := pruneSignExt(btmp[:])
+		bd = bd | (byte(7-f) << 2)
+		copy(bs[i:], btmp[f:])
+		i = i + (8 - f)
+	}
+	if tnsecs != 0 {
+		bd = bd | 0x40
+		bigen.PutUint32(btmp[:4], uint32(tnsecs))
+		f := pruneSignExt(btmp[:4])
+		bd = bd | byte(3-f)
+		copy(bs[i:], btmp[f:4])
+		i = i + (4 - f)
+	}
+	if l != nil {
+		bd = bd | 0x20
+		// Note that Go Libs do not give access to dst flag.
+		_, zoneOffset := t.Zone()
+		//zoneName, zoneOffset := t.Zone()
+		zoneOffset /= 60
+		z := uint16(zoneOffset)
+		bigen.PutUint16(btmp[:2], z)
+		// clear dst flags
+		bs[i] = btmp[0] & 0x3f
+		bs[i+1] = btmp[1]
+		i = i + 2
+	}
+	bs[0] = bd
+	return bs[0:i]
+}
+
+// decodeTime decodes a []byte into a time.Time,
+// and sets into passed reflectValue.
+func decodeTime(bs []byte) (tt time.Time, err error) {
+	bd := bs[0]
+	var (
+		tsec  int64
+		tnsec uint32
+		tz    uint16
+		i     byte = 1
+		i2    byte
+		n     byte
+	)
+	if bd&(1<<7) != 0 {
+		var btmp [8]byte
+		n = ((bd >> 2) & 0x7) + 1
+		i2 = i + n
+		copy(btmp[8-n:], bs[i:i2])
+		i = i2
+		tsec = int64(bigen.Uint64(btmp[:]))
+	}
+	if bd&(1<<6) != 0 {
+		var btmp [4]byte
+		n = (bd & 0x3) + 1
+		i2 = i + n
+		copy(btmp[4-n:], bs[i:i2])
+		i = i2
+		tnsec = bigen.Uint32(btmp[:])
+	}
+	if bd&(1<<5) == 0 {
+		tt = time.Unix(tsec, int64(tnsec)).UTC()
+		return
+	}
+	// In stdlib time.Parse, when a date is parsed without a zone name, it uses "" as zone name.
+	// However, we need name here, so it can be shown when time is printed.
+	// Zone name is in form: UTC-08:00.
+	// Note that Go Libs do not give access to dst flag, so we ignore dst bits
+
+	i2 = i + 2
+	tz = bigen.Uint16(bs[i:i2])
+	i = i2
+	var tzname = []byte("UTC+00:00")
+	// sign extend sign bit into top 2 MSB (which were dst bits):
+	if tz&(1<<13) == 0 { // positive
+		tz = tz & 0x3fff //clear 2 MSBs: dst bits
+	} else { // negative
+		tz = tz | 0xc000 //set 2 MSBs: dst bits
+		tzname[3] = '-'
+	}
+	tzint := (int16(tz))
+	//tzname := fmt.Sprintf("UTC%s%02d:%02d", tzsign, tz/60, tz%60) //perf issue using Sprintf. inline below.
+	//tzhr, tzmin := tz/60, tz%60 //faster if u convert to int first
+	var tzhr, tzmin int16
+	if tzint < 0 {
+		tzhr, tzmin = -tzint/60, (-tzint)%60
+	} else {
+		tzhr, tzmin = tzint/60, tzint%60
+	}
+	tzname[4] = digits[tzhr/10]
+	tzname[5] = digits[tzhr%10]
+	tzname[7] = digits[tzmin/10]
+	tzname[8] = digits[tzmin%10]
+
+	tt = time.Unix(tsec, int64(tnsec)).In(time.FixedZone(string(tzname), int(tzint)*60))
+	return
+}

+ 9 - 10
codec/z_helper_test.go

@@ -5,18 +5,18 @@ package codec
 
 
 // All non-std package dependencies related to testing live in this file,
 // All non-std package dependencies related to testing live in this file,
 // so porting to different environment is easy (just update functions).
 // so porting to different environment is easy (just update functions).
-// 
+//
 // Also, this file is called z_helper_test, to give a "hint" to compiler
 // Also, this file is called z_helper_test, to give a "hint" to compiler
 // that its init() function should be called last. (not guaranteed by spec)
 // that its init() function should be called last. (not guaranteed by spec)
 
 
 import (
 import (
-	"testing"
-	"reflect"
 	"errors"
 	"errors"
+	"reflect"
+	"testing"
 )
 )
 
 
 var (
 var (
-	testLogToT = true
+	testLogToT    = true
 	failNowOnFail = true
 	failNowOnFail = true
 )
 )
 
 
@@ -33,7 +33,7 @@ func checkErrT(t *testing.T, err error) {
 }
 }
 
 
 func checkEqualT(t *testing.T, v1 interface{}, v2 interface{}) {
 func checkEqualT(t *testing.T, v1 interface{}, v2 interface{}) {
-	if err := deepEqual(v1, v2); err != nil { 
+	if err := deepEqual(v1, v2); err != nil {
 		logT(t, "Do not match: %v. v1: %v, v2: %v", err, v1, v2)
 		logT(t, "Do not match: %v. v1: %v, v2: %v", err, v1, v2)
 		failT(t)
 		failT(t)
 	}
 	}
@@ -41,7 +41,7 @@ func checkEqualT(t *testing.T, v1 interface{}, v2 interface{}) {
 
 
 func logT(x interface{}, format string, args ...interface{}) {
 func logT(x interface{}, format string, args ...interface{}) {
 	if t, ok := x.(*testing.T); ok && t != nil && testLogToT {
 	if t, ok := x.(*testing.T); ok && t != nil && testLogToT {
-		t.Logf(format, args...)	
+		t.Logf(format, args...)
 	} else if b, ok := x.(*testing.B); ok && b != nil && testLogToT {
 	} else if b, ok := x.(*testing.B); ok && b != nil && testLogToT {
 		b.Logf(format, args...)
 		b.Logf(format, args...)
 	} else {
 	} else {
@@ -76,10 +76,10 @@ func approxDataSize(rv reflect.Value) (sum int) {
 			sum += approxDataSize(rv.Index(j))
 			sum += approxDataSize(rv.Index(j))
 		}
 		}
 	case reflect.String:
 	case reflect.String:
-		sum += int(rv.Type().Size()) 
+		sum += int(rv.Type().Size())
 		sum += rv.Len()
 		sum += rv.Len()
 	case reflect.Map:
 	case reflect.Map:
-		sum += int(rv.Type().Size()) 
+		sum += int(rv.Type().Size())
 		for _, mk := range rv.MapKeys() {
 		for _, mk := range rv.MapKeys() {
 			sum += approxDataSize(mk)
 			sum += approxDataSize(mk)
 			sum += approxDataSize(rv.MapIndex(mk))
 			sum += approxDataSize(rv.MapIndex(mk))
@@ -89,11 +89,10 @@ func approxDataSize(rv reflect.Value) (sum int) {
 		//sum += int(rv.Type().Size())
 		//sum += int(rv.Type().Size())
 		for j := 0; j < rv.NumField(); j++ {
 		for j := 0; j < rv.NumField(); j++ {
 			sum += approxDataSize(rv.Field(j))
 			sum += approxDataSize(rv.Field(j))
-		}	
+		}
 	default:
 	default:
 		//pure value types
 		//pure value types
 		sum += int(rv.Type().Size())
 		sum += int(rv.Type().Size())
 	}
 	}
 	return
 	return
 }
 }
-