pax_global_header00006660000000000000000000000064131763051310014512gustar00rootroot0000000000000052 comment=6e8df1b1fb9d591dfc8249e230e0a762524873f3 golang-github-alecthomas-binary-0.0~git20171101.6e8df1b/000077500000000000000000000000001317630513100223555ustar00rootroot00000000000000golang-github-alecthomas-binary-0.0~git20171101.6e8df1b/LICENSE000066400000000000000000000020371317630513100233640ustar00rootroot00000000000000Copyright (C) 2015 Alec Thomas Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. golang-github-alecthomas-binary-0.0~git20171101.6e8df1b/README.md000066400000000000000000000007121317630513100236340ustar00rootroot00000000000000# Compact binary encoding for Go The Go standard library package [encoding/binary](http://golang.org/pkg/encoding/binary/) provides encoding/decoding of *fixed-size* Go values or slices of same. This package extends support to arbitrary, variable-sized values by prefixing these values with their varint-encoded size, recursively. It expects the encoded type and decoded type to match exactly and makes no attempt to reconcile or check for any differences. golang-github-alecthomas-binary-0.0~git20171101.6e8df1b/binary.go000066400000000000000000000144461317630513100242010ustar00rootroot00000000000000package binary import ( "bytes" "encoding" "encoding/binary" "errors" "fmt" "io" "reflect" ) var ( LittleEndian = binary.LittleEndian BigEndian = binary.BigEndian DefaultEndian = LittleEndian ) func Marshal(v interface{}) ([]byte, error) { b := &bytes.Buffer{} if err := NewEncoder(b).Encode(v); err != nil { return nil, err } return b.Bytes(), nil } func Unmarshal(b []byte, v interface{}) error { return NewDecoder(bytes.NewReader(b)).Decode(v) } type Encoder struct { Order binary.ByteOrder w io.Writer buf []byte strict bool } func NewEncoder(w io.Writer) *Encoder { return &Encoder{ Order: DefaultEndian, w: w, buf: make([]byte, 8), } } // NewStrictEncoder creates an encoder similar to NewEncoder, however // if this encoder attempts to encode a struct and the struct has no encodable // fields an error is returned whereas the encoder returned from NewEncoder // will simply not write anything to `w`. func NewStrictEncoder(w io.Writer) *Encoder { e := NewEncoder(w) e.strict = true return e } func (e *Encoder) writeVarint(v int) error { l := binary.PutUvarint(e.buf, uint64(v)) _, err := e.w.Write(e.buf[:l]) return err } func (b *Encoder) Encode(v interface{}) (err error) { switch cv := v.(type) { case encoding.BinaryMarshaler: buf, err := cv.MarshalBinary() if err != nil { return err } if err = b.writeVarint(len(buf)); err != nil { return err } _, err = b.w.Write(buf) case []byte: // fast-path byte arrays if err = b.writeVarint(len(cv)); err != nil { return } _, err = b.w.Write(cv) default: rv := reflect.Indirect(reflect.ValueOf(v)) t := rv.Type() switch t.Kind() { case reflect.Array: l := t.Len() for i := 0; i < l; i++ { if err = b.Encode(rv.Index(i).Addr().Interface()); err != nil { return } } case reflect.Slice: l := rv.Len() if err = b.writeVarint(l); err != nil { return } for i := 0; i < l; i++ { if err = b.Encode(rv.Index(i).Addr().Interface()); err != nil { return } } case reflect.Struct: l := rv.NumField() n := 0 for i := 0; i < l; i++ { if v := rv.Field(i); t.Field(i).Name != "_" { if err = b.Encode(v.Interface()); err != nil { return } n++ } } if b.strict && n == 0 { return fmt.Errorf("binary: struct had no encodable fields") } case reflect.Map: l := rv.Len() if err = b.writeVarint(l); err != nil { return } for _, key := range rv.MapKeys() { value := rv.MapIndex(key) if err = b.Encode(key.Interface()); err != nil { return err } if err = b.Encode(value.Interface()); err != nil { return err } } case reflect.String: if err = b.writeVarint(rv.Len()); err != nil { return } _, err = b.w.Write([]byte(rv.String())) case reflect.Bool: var out byte if rv.Bool() { out = 1 } err = binary.Write(b.w, b.Order, out) case reflect.Int: err = binary.Write(b.w, b.Order, int64(rv.Int())) case reflect.Uint: err = binary.Write(b.w, b.Order, int64(rv.Uint())) case reflect.Int8, reflect.Uint8, reflect.Int16, reflect.Uint16, reflect.Int32, reflect.Uint32, reflect.Int64, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: err = binary.Write(b.w, b.Order, v) default: return errors.New("binary: unsupported type " + t.String()) } } return } type byteReader struct { io.Reader } func (b *byteReader) ReadByte() (byte, error) { var buf [1]byte if _, err := io.ReadFull(b, buf[:]); err != nil { return 0, err } return buf[0], nil } type Decoder struct { Order binary.ByteOrder r *byteReader } func NewDecoder(r io.Reader) *Decoder { return &Decoder{ Order: DefaultEndian, r: &byteReader{r}, } } func (d *Decoder) Decode(v interface{}) (err error) { // Check if the type implements the encoding.BinaryUnmarshaler interface, and use it if so. if i, ok := v.(encoding.BinaryUnmarshaler); ok { var l uint64 if l, err = binary.ReadUvarint(d.r); err != nil { return } buf := make([]byte, l) _, err = d.r.Read(buf) return i.UnmarshalBinary(buf) } // Otherwise, use reflection. rv := reflect.Indirect(reflect.ValueOf(v)) if !rv.CanAddr() { return errors.New("binary: can only Decode to pointer type") } t := rv.Type() switch t.Kind() { case reflect.Array: len := t.Len() for i := 0; i < int(len); i++ { if err = d.Decode(rv.Index(i).Addr().Interface()); err != nil { return } } case reflect.Slice: var l uint64 if l, err = binary.ReadUvarint(d.r); err != nil { return } if t.Kind() == reflect.Slice { rv.Set(reflect.MakeSlice(t, int(l), int(l))) } else if int(l) != t.Len() { return fmt.Errorf("binary: encoded size %d != real size %d", l, t.Len()) } for i := 0; i < int(l); i++ { if err = d.Decode(rv.Index(i).Addr().Interface()); err != nil { return } } case reflect.Struct: l := rv.NumField() for i := 0; i < l; i++ { if v := rv.Field(i); v.CanSet() && t.Field(i).Name != "_" { if err = d.Decode(v.Addr().Interface()); err != nil { return } } } case reflect.Map: var l uint64 if l, err = binary.ReadUvarint(d.r); err != nil { return } kt := t.Key() vt := t.Elem() rv.Set(reflect.MakeMap(t)) for i := 0; i < int(l); i++ { kv := reflect.Indirect(reflect.New(kt)) if err = d.Decode(kv.Addr().Interface()); err != nil { return } vv := reflect.Indirect(reflect.New(vt)) if err = d.Decode(vv.Addr().Interface()); err != nil { return } rv.SetMapIndex(kv, vv) } case reflect.String: var l uint64 if l, err = binary.ReadUvarint(d.r); err != nil { return } buf := make([]byte, l) _, err = d.r.Read(buf) rv.SetString(string(buf)) case reflect.Bool: var out byte err = binary.Read(d.r, d.Order, &out) rv.SetBool(out != 0) case reflect.Int: var out int64 err = binary.Read(d.r, d.Order, &out) rv.SetInt(out) case reflect.Uint: var out uint64 err = binary.Read(d.r, d.Order, &out) rv.SetUint(out) case reflect.Int8, reflect.Uint8, reflect.Int16, reflect.Uint16, reflect.Int32, reflect.Uint32, reflect.Int64, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: err = binary.Read(d.r, d.Order, v) default: return errors.New("binary: unsupported type " + t.String()) } return } golang-github-alecthomas-binary-0.0~git20171101.6e8df1b/binary_test.go000066400000000000000000000154521317630513100252360ustar00rootroot00000000000000package binary import ( "bytes" "errors" "fmt" "io" "reflect" "testing" "time" "github.com/stretchrcom/testify/assert" ) type s0 struct { A string B string C int16 } var ( s0v = &s0{"A", "B", 1} s0b = []byte{0x1, 0x41, 0x1, 0x42, 0x1, 0x0} ) func TestBinaryEncodeStruct(t *testing.T) { b, err := Marshal(s0v) assert.NoError(t, err) assert.Equal(t, s0b, b) } func TestBinaryDecodeStruct(t *testing.T) { s := &s0{} err := Unmarshal(s0b, s) assert.NoError(t, err) assert.Equal(t, s0v, s) } func TestBinaryDecodeToValueErrors(t *testing.T) { b := []byte{1, 0, 0, 0} var v uint32 err := Unmarshal(b, v) assert.Error(t, err) err = Unmarshal(b, &v) assert.NoError(t, err) assert.Equal(t, uint32(1), v) } type s1 struct { Name string BirthDay time.Time Phone string Siblings int Spouse bool Money float64 Tags map[string]string Aliases []string } var ( s1v = &s1{ Name: "Bob Smith", BirthDay: time.Date(2013, 1, 2, 3, 4, 5, 6, time.UTC), Phone: "5551234567", Siblings: 2, Spouse: false, Money: 100.0, Tags: map[string]string{"key": "value"}, Aliases: []string{"Bobby", "Robert"}, } svb = []byte{0x9, 0x42, 0x6f, 0x62, 0x20, 0x53, 0x6d, 0x69, 0x74, 0x68, 0xf, 0x1, 0x0, 0x0, 0x0, 0xe, 0xc8, 0x75, 0x9a, 0xa5, 0x0, 0x0, 0x0, 0x6, 0xff, 0xff, 0xa, 0x35, 0x35, 0x35, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x59, 0x40, 0x1, 0x3, 0x6b, 0x65, 0x79, 0x5, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2, 0x5, 0x42, 0x6f, 0x62, 0x62, 0x79, 0x6, 0x52, 0x6f, 0x62, 0x65, 0x72, 0x74} ) func TestBinaryEncodeComplex(t *testing.T) { b, err := Marshal(s1v) assert.NoError(t, err) assert.Equal(t, svb, b) s := &s1{} err = Unmarshal(svb, s) assert.NoError(t, err) assert.Equal(t, s1v, s) } type s2 struct { b []byte } func (s *s2) UnmarshalBinary(data []byte) error { if len(data) != 1 { return errors.New("expected data to be length 1") } s.b = data return nil } func (s *s2) MarshalBinary() (data []byte, err error) { return s.b, nil } func TestBinaryMarshalUnMarshaler(t *testing.T) { s2v := &s2{[]byte{0x13}} b, err := Marshal(s2v) assert.NoError(t, err) assert.Equal(t, []byte{0x1, 0x13}, b) } func TestMarshalUnMarshalTypeAliases(t *testing.T) { type Foo int64 f := Foo(32) b, err := Marshal(f) assert.NoError(t, err) assert.Equal(t, []byte{0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, b) } func TestStructWithStruct(t *testing.T) { type T1 struct { ID uint64 Name string Slice []int } type T2 uint64 type Struct struct { V1 T1 V2 T2 V3 T1 } s := Struct{V1: T1{1, "1", []int{1}}, V2: 2, V3: T1{3, "3", []int{3}}} buf := new(bytes.Buffer) enc := NewEncoder(buf) err := enc.Encode(&s) if err != nil { t.Fatalf("error: %v\n", err) } v := Struct{} dec := NewDecoder(buf) err = dec.Decode(&v) if err != nil { t.Fatalf("error: %v\n", err) } if !reflect.DeepEqual(s, v) { t.Fatalf("got= %#v\nwant=%#v\n", v, s) } } func TestStructWithEmbeddedStruct(t *testing.T) { type T1 struct { ID uint64 Name string Slice []int } type T2 uint64 type Struct struct { T1 V2 T2 V3 T1 } s := Struct{T1: T1{1, "1", []int{1}}, V2: 2, V3: T1{3, "3", []int{3}}} buf := new(bytes.Buffer) enc := NewEncoder(buf) err := enc.Encode(&s) if err != nil { t.Fatalf("error: %v\n", err) } v := Struct{} dec := NewDecoder(buf) err = dec.Decode(&v) if err != nil { t.Fatalf("error: %v\n", err) } if !reflect.DeepEqual(s, v) { t.Fatalf("got= %#v\nwant=%#v\n", v, s) } } func TestArrayOfStructWithStruct(t *testing.T) { type T1 struct { ID uint64 Name string Slice []int } type T2 uint64 type Struct struct { V1 T1 V2 T2 V3 T1 } s := [1]Struct{ {V1: T1{1, "1", []int{1}}, V2: 2, V3: T1{3, "3", []int{3}}}, } buf := new(bytes.Buffer) enc := NewEncoder(buf) err := enc.Encode(&s) if err != nil { t.Fatalf("error: %v\n", err) } v := [1]Struct{} dec := NewDecoder(buf) err = dec.Decode(&v) if err != nil { t.Fatalf("error: %v\n", err) } if !reflect.DeepEqual(s, v) { t.Fatalf("got= %#v\nwant=%#v\n", v, s) } } func TestSliceOfStructWithStruct(t *testing.T) { type T1 struct { ID uint64 Name string Slice []int } type T2 uint64 type Struct struct { V1 T1 V2 T2 V3 T1 } s := []Struct{ {V1: T1{1, "1", []int{1}}, V2: 2, V3: T1{3, "3", []int{3}}}, } buf := new(bytes.Buffer) enc := NewEncoder(buf) err := enc.Encode(&s) if err != nil { t.Fatalf("error: %v\n", err) } v := []Struct{} dec := NewDecoder(buf) err = dec.Decode(&v) if err != nil { t.Fatalf("error: %v\n", err) } if !reflect.DeepEqual(s, v) { t.Fatalf("got= %#v\nwant=%#v\n", v, s) } } func TestMarshalNonPointer(t *testing.T) { type S struct { A int } s := S{A: 1} data, err := Marshal(s) if err != nil { t.Fatal(err) } var res S if err := Unmarshal(data, &res); err != nil { t.Fatal(err) } if !reflect.DeepEqual(res, s) { t.Fatalf("expect %v got %v", s, res) } } func BenchmarkEncodeStructI1(b *testing.B) { type Struct struct { S struct { I int64 } } var s Struct s.S.I = 1024 buf := new(bytes.Buffer) b.ResetTimer() for i := 0; i < b.N; i++ { enc := NewEncoder(buf) _ = enc.Encode(&s) } } func BenchmarkEncodeStructI2(b *testing.B) { type Struct struct { S struct { I int64 } } var s Struct s.S.I = 1024 buf := new(bytes.Buffer) enc := NewEncoder(buf) b.ResetTimer() for i := 0; i < b.N; i++ { _ = enc.Encode(&s) } } func BenchmarkEncodeStructI3(b *testing.B) { type Struct struct { S struct { I int64 } } var s Struct s.S.I = 1024 buf := new(bytes.Buffer) enc := NewEncoder(buf) b.ResetTimer() for i := 0; i < b.N; i++ { err := enc.Encode(&s) if err != nil { b.Fatalf("error: %v\n", err) } } } type bufferT struct { buf []byte } func (buf *bufferT) Read(data []byte) (int, error) { n := copy(data, buf.buf) if n != len(data) { panic(fmt.Errorf("read too few bytes. got=%d want=%d", n, len(data))) } return n, nil } func getTestBuffer(b *testing.B) io.Reader { return &bufferT{ buf: []byte{0, 4, 0, 0, 0, 0, 0, 0}, } } func BenchmarkDecodeStructI1(b *testing.B) { type Struct struct { I int64 } var s Struct buf := getTestBuffer(b) b.ResetTimer() for i := 0; i < b.N; i++ { dec := NewDecoder(buf) _ = dec.Decode(&s) } } func BenchmarkDecodeStructI2(b *testing.B) { type Struct struct { S struct { I int64 } } var s Struct buf := getTestBuffer(b) dec := NewDecoder(buf) b.ResetTimer() for i := 0; i < b.N; i++ { _ = dec.Decode(&s) } } func BenchmarkDecodeStructI3(b *testing.B) { type Struct struct { S struct { I int64 } } var s Struct buf := getTestBuffer(b) dec := NewDecoder(buf) b.ResetTimer() for i := 0; i < b.N; i++ { err := dec.Decode(&s) if err != nil { b.Fatalf("error: %v\n", err) } } }