package binary import ( "fmt" "io" "reflect" "testing" "unsafe" ) type TDoNotSupport struct { DeepPointer **uint32 Uintptr uintptr UnsafePointer unsafe.Pointer Ch chan bool Map map[uintptr]uintptr Map2 map[int]uintptr Map3 map[uintptr]int Slice []uintptr Array [2]uintptr Array2 [2][2]uintptr Array3 [2]struct{ A uintptr } Func func() Struct struct { Uintptr uintptr } Struct2 struct { PStruct *struct { PPUintptr **uintptr } } Struct3 struct { PStruct *struct { PUintptr *uintptr PPUintptr **uintptr } } PStruct *struct { PUintptr *uintptr PPUintptr **uintptr } } var doNotSupportTypes = TDoNotSupport{ Map2: map[int]uintptr{1: 1}, Map3: map[uintptr]int{2: 2}, } type fastValues struct { Int int Uint uint Bool bool Int8 int8 Int16 int16 Int32 int32 Int64 int64 Uint8 uint8 Uint16 uint16 Uint32 uint32 Uint64 uint64 Float32 float32 Float64 float64 Complex64 complex64 Complex128 complex128 String string IntSlice []int UintSlice []uint BoolSlice []bool Int8Slice []int8 Int16Slice []int16 Int32Slice []int32 Int64Slice []int64 Uint8Slice []uint8 Uint16Slice []uint16 Uint32Slice []uint32 Uint64Slice []uint64 Float32Slice []float32 Float64Slice []float64 Complex64Slice []complex64 Complex128Slice []complex128 StringSlice []string } var _fastValues = fastValues{ Int: -2, Uint: 2, Bool: true, Int8: -3, Int16: -4, Int32: -5, Int64: -6, Uint8: 3, Uint16: 4, Uint32: 5, Uint64: 6, Float32: -7, Float64: 7, Complex64: 8, Complex128: 9, String: "hello", IntSlice: []int{-1, 2}, UintSlice: []uint{1, 3}, BoolSlice: []bool{false, true}, Int8Slice: []int8{-1, 2}, Int16Slice: []int16{-1, 3}, Int32Slice: []int32{-1, 4}, Int64Slice: []int64{-1, 5}, Uint8Slice: []uint8{1, 6}, Uint16Slice: []uint16{1, 7}, Uint32Slice: []uint32{1, 8}, Uint64Slice: []uint64{1, 9}, Float32Slice: []float32{1, 10.1}, Float64Slice: []float64{1, 11.2}, Complex64Slice: []complex64{1, 2.2}, Complex128Slice: []complex128{1, 12.9}, StringSlice: []string{"abc", "bcd"}, } type baseStruct struct { Int8 int8 Int16 int16 Int32 int32 Int64 int64 Uint8 uint8 Uint16 uint16 Uint32 uint32 Uint64 uint64 Float32 float32 Float64 float64 Complex64 complex64 Complex128 complex128 Array [4]uint8 Bool bool BoolArray [9]bool } type littleStruct struct { String string Int16 int16 } type fullStruct struct { BaseStruct baseStruct LittleStruct littleStruct PLittleStruct *littleStruct String string PString *string PInt32 *int32 Slice []*littleStruct PSlice *[]*string Float64Slice []float64 BoolSlice []bool Uint32Slice []uint32 Map map[string]*littleStruct Map2 map[string]uint16 IntSlice []int UintSlice []uint } var full = fullStruct{ BaseStruct: baseStruct{ Int8: 0x12, Int16: 0x1234, Int32: 0x12345678, Int64: 0x123456789abcdef0, Uint8: 0x12, Uint16: 0x1234, Uint32: 0x71234568, Uint64: 0xa123456789bcdef0, Float32: 1234.5678, Float64: 2345.6789012, Complex64: complex(1.12456453, 2.344565), Complex128: complex(333.4569789789123, 567.34577890012), Array: [4]uint8{0x1, 0x2, 0x3, 0x4}, Bool: false, BoolArray: [9]bool{true, false, false, false, false, true, true, false, true}, }, LittleStruct: littleStruct{ String: "abc", Int16: 0x1234, }, PLittleStruct: &littleStruct{ String: "bcd", Int16: 0x2345, }, String: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", PString: newString("hello"), PInt32: newInt32(0x11223344), Slice: []*littleStruct{ &littleStruct{ String: "abc", Int16: 0x1122, }, &littleStruct{ String: "bcd", Int16: 0x2233, }, &littleStruct{ String: "cdef", Int16: 0x3344, }, }, PSlice: &[]*string{newString("abc"), newString("def"), newString("ghijkl")}, Float64Slice: []float64{3.141592654, 1.137856998, 6.789012345}, BoolSlice: []bool{false, true, false, false, true, true, false}, Uint32Slice: []uint32{0x12345678, 0x23456789, 0x34567890, 0x4567890a, 0x567890ab}, Map: map[string]*littleStruct{"a": &littleStruct{String: "a", Int16: 0x1122}, "b": &littleStruct{String: "b", Int16: 0x1122}}, Map2: map[string]uint16{"aaa": 0x5566, "bbb": 0x7788}, IntSlice: []int{0, -1, 1, -2, 2, -63, 63, -64, 64, -65, 65, -125, 125, -126, 126, -127, 127, -128, 128, -32765, 32765, -32766, 32766, -32767, 32767, -32768, 32768, -2147483645, 2147483645, -2147483646, 2147483646, -2147483647, 2147483647, -2147483648, 2147483648, -9223372036854775807, 9223372036854775806, -9223372036854775808, 9223372036854775807}, UintSlice: []uint{0, 1, 2, 127, 128, 32765, 32766, 32767, 32768, 65533, 65534, 65535, 65536, 0xFFFFFD, 0xFFFFFE, 0xFFFFFF, 0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF}, } func newString(s string) *string { p := new(string) *p = s return p } func newInt32(i int32) *int32 { p := new(int32) *p = i return p } var bigFull = []byte{ //field#1|BaseStruct|binary.baseStruct{Int8:18, Int16:4660, Int32:305419896, Int64:1311768467463790320, Uint8:0x12, Uint16:0x1234, Uint32:0x71234568, Uint64:0xa123456789bcdef0, Float32:1234.5677, Float64:2345.6789012, Complex64:(1.1245645+2.344565i), Complex128:(333.4569789789123+567.34577890012i), Array:[4]uint8{0x1, 0x2, 0x3, 0x4}, Bool:false, BoolArray:[9]bool{true, false, false, false, false, true, true, false, true}} 0x12, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x12, 0x34, 0x71, 0x23, 0x45, 0x68, 0xa1, 0x23, 0x45, 0x67, 0x89, 0xbc, 0xde, 0xf0, 0x44, 0x9a, 0x52, 0x2b, 0x40, 0xa2, 0x53, 0x5b, 0x98, 0xf0, 0x26, 0x6e, 0x3f, 0x8f, 0xf1, 0xbb, 0x40, 0x16, 0x0d, 0x5a, 0x40, 0x74, 0xd7, 0x4f, 0xc9, 0x30, 0x96, 0x34, 0x40, 0x81, 0xba, 0xc4, 0x27, 0xba, 0x5d, 0x4c, 0x04, 0x01, 0x02, 0x03, 0x04, 0x00, 0x09, 0x61, 0x01, //field#2|LittleStruct|binary.littleStruct{String:"abc", Int16:4660} 0x03, 0x61, 0x62, 0x63, 0x12, 0x34, //field#3|PLittleStruct|&binary.littleStruct{String:"bcd", Int16:9029} 0x03, 0x62, 0x63, 0x64, 0x23, 0x45, //field#4|String|"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" 0x40, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, //field#5|PString|(*string)(0xc042033170) 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, //field#6|PInt32|(*int32)(0xc04200e268) 0x11, 0x22, 0x33, 0x44, //field#7|Slice|[]*binary.littleStruct{(*binary.littleStruct)(0x68f620), (*binary.littleStruct)(0x68f640), (*binary.littleStruct)(0x68f660)} 0x03, 0x07, 0x03, 0x61, 0x62, 0x63, 0x11, 0x22, 0x03, 0x62, 0x63, 0x64, 0x22, 0x33, 0x04, 0x63, 0x64, 0x65, 0x66, 0x33, 0x44, //field#8|PSlice|&[]*string{(*string)(0xc042033180), (*string)(0xc042033190), (*string)(0xc0420331a0)} 0x03, 0x07, 0x03, 0x61, 0x62, 0x63, 0x03, 0x64, 0x65, 0x66, 0x06, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, //field#9|Float64Slice|[]float64{3.141592654, 1.137856998, 6.789012345} 0x03, 0x40, 0x09, 0x21, 0xfb, 0x54, 0x52, 0x45, 0x50, 0x3f, 0xf2, 0x34, 0xa9, 0x8a, 0x1e, 0xf4, 0xaf, 0x40, 0x1b, 0x27, 0xf2, 0xda, 0x27, 0xa9, 0x3c, //field#10|BoolSlice|[]bool{false, true, false, false, true, true, false} 0x07, 0x32, //field#11|Uint32Slice|[]uint32{0x12345678, 0x23456789, 0x34567890, 0x4567890a, 0x567890ab} 0x05, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x90, 0x45, 0x67, 0x89, 0x0a, 0x56, 0x78, 0x90, 0xab, //field#12|Map|map[string]*binary.littleStruct{"a":(*binary.littleStruct)(0xc0420029c0), "b":(*binary.littleStruct)(0xc0420029e0)} 0x02, 0x01, 0x61, 0x03, 0x01, 0x61, 0x11, 0x22, 0x01, 0x62, 0x01, 0x62, 0x11, 0x22, //field#13|Map2|map[string]uint16{"aaa":0x5566, "bbb":0x7788} 0x02, 0x03, 0x61, 0x61, 0x61, 0x55, 0x66, 0x03, 0x62, 0x62, 0x62, 0x77, 0x88, //field#14|IntSlice|[]int{0, -1, 1, -2, 2, -63, 63, -64, 64, -65, 65, -125, 125, -126, 126, -127, 127, -128, 128, -32765, 32765, -32766, 32766, -32767, 32767, -32768, 32768, -2147483645, 2147483645, -2147483646, 2147483646, -2147483647, 2147483647, -2147483648, 2147483648, -9223372036854775807, 9223372036854775806, -9223372036854775808, 9223372036854775807} 0x27, 0x00, 0x01, 0x02, 0x03, 0x04, 0x7d, 0x7e, 0x7f, 0x80, 0x01, 0x81, 0x01, 0x82, 0x01, 0xf9, 0x01, 0xfa, 0x01, 0xfb, 0x01, 0xfc, 0x01, 0xfd, 0x01, 0xfe, 0x01, 0xff, 0x01, 0x80, 0x02, 0xf9, 0xff, 0x03, 0xfa, 0xff, 0x03, 0xfb, 0xff, 0x03, 0xfc, 0xff, 0x03, 0xfd, 0xff, 0x03, 0xfe, 0xff, 0x03, 0xff, 0xff, 0x03, 0x80, 0x80, 0x04, 0xf9, 0xff, 0xff, 0xff, 0x0f, 0xfa, 0xff, 0xff, 0xff, 0x0f, 0xfb, 0xff, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0xff, 0x0f, 0xfd, 0xff, 0xff, 0xff, 0x0f, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x80, 0x80, 0x80, 0x10, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, //field#15|UintSlice|[]uint{0x0, 0x1, 0x2, 0x7f, 0x80, 0x7ffd, 0x7ffe, 0x7fff, 0x8000, 0xfffd, 0xfffe, 0xffff, 0x10000, 0xfffffd, 0xfffffe, 0xffffff, 0xfffffffffffffffd, 0xfffffffffffffffe, 0xffffffffffffffff} 0x13, 0x00, 0x01, 0x02, 0x7f, 0x80, 0x01, 0xfd, 0xff, 0x01, 0xfe, 0xff, 0x01, 0xff, 0xff, 0x01, 0x80, 0x80, 0x02, 0xfd, 0xff, 0x03, 0xfe, 0xff, 0x03, 0xff, 0xff, 0x03, 0x80, 0x80, 0x04, 0xfd, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0x07, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, } var littleFull = []byte{ //field#1|BaseStruct|binary.baseStruct{Int8:18, Int16:4660, Int32:305419896, Int64:1311768467463790320, Uint8:0x12, Uint16:0x1234, Uint32:0x71234568, Uint64:0xa123456789bcdef0, Float32:1234.5677, Float64:2345.6789012, Complex64:(1.1245645+2.344565i), Complex128:(333.4569789789123+567.34577890012i), Array:[4]uint8{0x1, 0x2, 0x3, 0x4}, Bool:false, BoolArray:[9]bool{true, false, false, false, false, true, true, false, true}} 0x12, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x12, 0x34, 0x12, 0x68, 0x45, 0x23, 0x71, 0xf0, 0xde, 0xbc, 0x89, 0x67, 0x45, 0x23, 0xa1, 0x2b, 0x52, 0x9a, 0x44, 0x6e, 0x26, 0xf0, 0x98, 0x5b, 0x53, 0xa2, 0x40, 0xbb, 0xf1, 0x8f, 0x3f, 0x5a, 0x0d, 0x16, 0x40, 0x34, 0x96, 0x30, 0xc9, 0x4f, 0xd7, 0x74, 0x40, 0x4c, 0x5d, 0xba, 0x27, 0xc4, 0xba, 0x81, 0x40, 0x04, 0x01, 0x02, 0x03, 0x04, 0x00, 0x09, 0x61, 0x01, //field#2|LittleStruct|binary.littleStruct{String:"abc", Int16:4660} 0x03, 0x61, 0x62, 0x63, 0x34, 0x12, //field#3|PLittleStruct|&binary.littleStruct{String:"bcd", Int16:9029} 0x03, 0x62, 0x63, 0x64, 0x45, 0x23, //field#4|String|"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" 0x40, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, //field#5|PString|(*string)(0xc042033170) 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, //field#6|PInt32|(*int32)(0xc04200e268) 0x44, 0x33, 0x22, 0x11, //field#7|Slice|[]*binary.littleStruct{(*binary.littleStruct)(0x68f400), (*binary.littleStruct)(0x68f420), (*binary.littleStruct)(0x68f440)} 0x03, 0x07, 0x03, 0x61, 0x62, 0x63, 0x22, 0x11, 0x03, 0x62, 0x63, 0x64, 0x33, 0x22, 0x04, 0x63, 0x64, 0x65, 0x66, 0x44, 0x33, //field#8|PSlice|&[]*string{(*string)(0xc042033180), (*string)(0xc042033190), (*string)(0xc0420331a0)} 0x03, 0x07, 0x03, 0x61, 0x62, 0x63, 0x03, 0x64, 0x65, 0x66, 0x06, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, //field#9|Float64Slice|[]float64{3.141592654, 1.137856998, 6.789012345} 0x03, 0x50, 0x45, 0x52, 0x54, 0xfb, 0x21, 0x09, 0x40, 0xaf, 0xf4, 0x1e, 0x8a, 0xa9, 0x34, 0xf2, 0x3f, 0x3c, 0xa9, 0x27, 0xda, 0xf2, 0x27, 0x1b, 0x40, //field#10|BoolSlice|[]bool{false, true, false, false, true, true, false} 0x07, 0x32, //field#11|Uint32Slice|[]uint32{0x12345678, 0x23456789, 0x34567890, 0x4567890a, 0x567890ab} 0x05, 0x78, 0x56, 0x34, 0x12, 0x89, 0x67, 0x45, 0x23, 0x90, 0x78, 0x56, 0x34, 0x0a, 0x89, 0x67, 0x45, 0xab, 0x90, 0x78, 0x56, //field#12|Map|map[string]*binary.littleStruct{"b":(*binary.littleStruct)(0xc0420029e0), "a":(*binary.littleStruct)(0xc0420029c0)} 0x02, 0x01, 0x61, 0x03, 0x01, 0x61, 0x22, 0x11, 0x01, 0x62, 0x01, 0x62, 0x22, 0x11, //field#13|Map2|map[string]uint16{"aaa":0x5566, "bbb":0x7788} 0x02, 0x03, 0x61, 0x61, 0x61, 0x66, 0x55, 0x03, 0x62, 0x62, 0x62, 0x88, 0x77, //field#14|IntSlice|[]int{0, -1, 1, -2, 2, -63, 63, -64, 64, -65, 65, -125, 125, -126, 126, -127, 127, -128, 128, -32765, 32765, -32766, 32766, -32767, 32767, -32768, 32768, -2147483645, 2147483645, -2147483646, 2147483646, -2147483647, 2147483647, -2147483648, 2147483648, -9223372036854775807, 9223372036854775806, -9223372036854775808, 9223372036854775807} 0x27, 0x00, 0x01, 0x02, 0x03, 0x04, 0x7d, 0x7e, 0x7f, 0x80, 0x01, 0x81, 0x01, 0x82, 0x01, 0xf9, 0x01, 0xfa, 0x01, 0xfb, 0x01, 0xfc, 0x01, 0xfd, 0x01, 0xfe, 0x01, 0xff, 0x01, 0x80, 0x02, 0xf9, 0xff, 0x03, 0xfa, 0xff, 0x03, 0xfb, 0xff, 0x03, 0xfc, 0xff, 0x03, 0xfd, 0xff, 0x03, 0xfe, 0xff, 0x03, 0xff, 0xff, 0x03, 0x80, 0x80, 0x04, 0xf9, 0xff, 0xff, 0xff, 0x0f, 0xfa, 0xff, 0xff, 0xff, 0x0f, 0xfb, 0xff, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0xff, 0x0f, 0xfd, 0xff, 0xff, 0xff, 0x0f, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x80, 0x80, 0x80, 0x10, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, //field#15|UintSlice|[]uint{0x0, 0x1, 0x2, 0x7f, 0x80, 0x7ffd, 0x7ffe, 0x7fff, 0x8000, 0xfffd, 0xfffe, 0xffff, 0x10000, 0xfffffd, 0xfffffe, 0xffffff, 0xfffffffffffffffd, 0xfffffffffffffffe, 0xffffffffffffffff} 0x13, 0x00, 0x01, 0x02, 0x7f, 0x80, 0x01, 0xfd, 0xff, 0x01, 0xfe, 0xff, 0x01, 0xff, 0xff, 0x01, 0x80, 0x80, 0x02, 0xfd, 0xff, 0x03, 0xfe, 0xff, 0x03, 0xff, 0xff, 0x03, 0x80, 0x80, 0x04, 0xfd, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0x07, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, } var littleFullAll = []byte{ 0x12, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x12, 0x34, 0x12, 0x68, 0x45, 0x23, 0x71, 0xf0, 0xde, 0xbc, 0x89, 0x67, 0x45, 0x23, 0xa1, 0x2b, 0x52, 0x9a, 0x44, 0x6e, 0x26, 0xf0, 0x98, 0x5b, 0x53, 0xa2, 0x40, 0xbb, 0xf1, 0x8f, 0x3f, 0x5a, 0x0d, 0x16, 0x40, 0x34, 0x96, 0x30, 0xc9, 0x4f, 0xd7, 0x74, 0x40, 0x4c, 0x5d, 0xba, 0x27, 0xc4, 0xba, 0x81, 0x40, 0x04, 0x01, 0x02, 0x03, 0x04, 0xfe, 0x09, 0x61, 0x01, 0x03, 0x61, 0x62, 0x63, 0x34, 0x12, 0x03, 0x62, 0x63, 0x64, 0x45, 0x23, 0x40, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x44, 0x33, 0x22, 0x11, 0x03, 0x03, 0x61, 0x62, 0x63, 0x22, 0x11, 0x03, 0x62, 0x63, 0x64, 0x33, 0x22, 0x04, 0x63, 0x64, 0x65, 0x66, 0x44, 0x33, 0x03, 0x1f, 0x03, 0x61, 0x62, 0x63, 0x03, 0x64, 0x65, 0x66, 0x06, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x03, 0x50, 0x45, 0x52, 0x54, 0xfb, 0x21, 0x09, 0x40, 0xaf, 0xf4, 0x1e, 0x8a, 0xa9, 0x34, 0xf2, 0x3f, 0x3c, 0xa9, 0x27, 0xda, 0xf2, 0x27, 0x1b, 0x40, 0x07, 0x32, 0x05, 0x78, 0x56, 0x34, 0x12, 0x89, 0x67, 0x45, 0x23, 0x90, 0x78, 0x56, 0x34, 0x0a, 0x89, 0x67, 0x45, 0xab, 0x90, 0x78, 0x56, 0x02, 0x01, 0x61, 0x01, 0x61, 0x22, 0x11, 0x01, 0x62, 0x01, 0x62, 0x22, 0x11, 0x02, 0x03, 0x61, 0x61, 0x61, 0x66, 0x55, 0x03, 0x62, 0x62, 0x62, 0x88, 0x77, 0x27, 0x00, 0x01, 0x02, 0x03, 0x04, 0x7d, 0x7e, 0x7f, 0x80, 0x01, 0x81, 0x01, 0x82, 0x01, 0xf9, 0x01, 0xfa, 0x01, 0xfb, 0x01, 0xfc, 0x01, 0xfd, 0x01, 0xfe, 0x01, 0xff, 0x01, 0x80, 0x02, 0xf9, 0xff, 0x03, 0xfa, 0xff, 0x03, 0xfb, 0xff, 0x03, 0xfc, 0xff, 0x03, 0xfd, 0xff, 0x03, 0xfe, 0xff, 0x03, 0xff, 0xff, 0x03, 0x80, 0x80, 0x04, 0xf9, 0xff, 0xff, 0xff, 0x0f, 0xfa, 0xff, 0xff, 0xff, 0x0f, 0xfb, 0xff, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0xff, 0x0f, 0xfd, 0xff, 0xff, 0xff, 0x0f, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x80, 0x80, 0x80, 0x10, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x13, 0x00, 0x01, 0x02, 0x7f, 0x80, 0x01, 0xfd, 0xff, 0x01, 0xfe, 0xff, 0x01, 0xff, 0xff, 0x01, 0x80, 0x80, 0x02, 0xfd, 0xff, 0x03, 0xfe, 0xff, 0x03, 0xff, 0xff, 0x03, 0x80, 0x80, 0x04, 0xfd, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0x07, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, } func TestEncode(t *testing.T) { v := reflect.ValueOf(full) vt := v.Type() n := v.NumField() check := littleFull for i := 0; i < n; i++ { if !validField(vt.Field(i)) { continue } b, err := Encode(v.Field(i).Interface(), nil) c := check[:len(b)] check = check[len(b):] if err != nil { t.Error(err) } //fmt.Printf("//field#%d|%s|%#v\n$% x,\n", i+1, vt.Field(i).Name, v.Field(i).Interface(), b) if vt.Field(i).Type.Kind() != reflect.Map && //map keys will be got as unspecified order, byte order may change but it doesn't matter !reflect.DeepEqual(b, c) { //fmt.Printf("%d %s\ngot%#v\n%need#v\n", i, vt.Field(i).Type.String(), b, c) t.Errorf("field %d %s got %+v\nneed %+v\n", i, vt.Field(i).Name, b, c) } } ////map fields will case uncertain bytes order but it does't matter //b2, err := Encode(full, nil) //if err != nil { // t.Error(err) //} //fmt.Printf("//% x,\n", b2) //if !reflect.DeepEqual(b2, littleFull) { // t.Errorf("got %+v\nneed %+v\n", b2, littleFull) //} } func TestEncodeBig(t *testing.T) { v := reflect.ValueOf(full) vt := v.Type() n := v.NumField() check := bigFull for i := 0; i < n; i++ { if !validField(vt.Field(i)) { continue } size := Sizeof(v.Field(i).Interface()) encoder := NewEncoderEndian(size, BigEndian) err := encoder.Value(v.Field(i).Interface()) b := encoder.Buffer() c := check[:len(b)] check = check[len(b):] if err != nil { t.Error(err) } //fmt.Printf("//field#%d|%s|%#v\n$% x,\n", i+1, vt.Field(i).Name, v.Field(i).Interface(), b) if vt.Field(i).Type.Kind() != reflect.Map && //map keys will be got as unspecified order, byte order may change but it doesn't matter !reflect.DeepEqual(b, c) { //fmt.Printf("%d %s\ngot%#v\n%need#v\n", i, vt.Field(i).Type.String(), b, c) t.Errorf("field %d %s got %+v\nneed %+v\n", i, vt.Field(i).Name, b, c) } } } func TestDecode(t *testing.T) { var v fullStruct err := Decode(littleFullAll, &v) if err != nil { t.Error(err) } if !reflect.DeepEqual(v, full) { t.Errorf("got %#v\nneed %#v\n", v, full) } } func TestReset(t *testing.T) { encoder := NewEncoder(100) encoder.Uint64(0x1122334455667788, false) encoder.String("0123456789abcdef") oldCheck := []byte{0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x10, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66} old := encoder.Buffer() l := encoder.Len() if len(old) != l { t.Errorf("encode len error: got %#v\nneed %#v\n", old, l) } if !reflect.DeepEqual(old, oldCheck) { t.Errorf("got %#v\nneed %#v\n", old, oldCheck) } encoder.Reset() var s struct { PString *string PSlice *[]int PArray *[2]bool PArray2 *[2]struct{ X *string } PInt *int32 PStruct *struct{ A int } PStruct2 *struct{ B *[]string } } err := encoder.Value(&s) if err != nil { t.Error(err) } _new := encoder.Buffer() l2 := encoder.Len() newCheck := []byte{0x0} if len(_new) != l2 { t.Errorf("encode len error: got %#v\nneed %#v\n", _new, l2) } if !reflect.DeepEqual(_new, newCheck) { t.Errorf("got %#v\nneed %#v\n", _new, newCheck) } if s := encoder.Skip(1); s < 0 { t.Errorf("got %#v\nneed %#v\n", s, 1) } if s := encoder.Skip(encoder.Cap()); s >= 0 { t.Errorf("got %#v\nneed %#v\n", s, -1) } r := encoder.reserve(0) if r != nil { t.Errorf("got %#v\nneed %#v\n", r, nil) } defer func() { if e := recover(); e == nil { t.Error("need panic but not") } }() if !encoder.ResizeBuffer(101) { t.Errorf("Decoder: have %v, want %v", false, true) } large := [100]complex128{} err2 := encoder.Value(&large) if err2 == nil { t.Errorf("got err=nil, need err=none-nil") } else { //println("info******", err2.Error()) } r2 := encoder.reserve(100) if r2 != nil { t.Errorf("got %#v\nneed %#v\n", r2, nil) } } func TestEncodeEmptyPointer(t *testing.T) { var s struct { PString *string PSlice *[]int PArray *[2]bool PArray2 *[2]struct{ X *string } PInt *int32 PStruct *struct{ A int } PStruct2 *struct{ B *[]string } } b, err := Encode(&s, nil) if err != nil { t.Error(err) } ss := s err = Decode(b, &ss) if err != nil { t.Error(err) } b2, err2 := Encode(&ss, nil) if err2 != nil { t.Error(err) } if !reflect.DeepEqual(b, b2) { t.Errorf("%+v->%+v got %+v\nneed %+v\n", s, ss, b2, b) } check := []byte{0x0} if !reflect.DeepEqual(b2, check) { t.Errorf("got %+v\nneed %+v\n", b2, check) } } func TestHideStructField(t *testing.T) { type T struct { A uint32 b uint32 _ uint32 C uint32 `binary:"ignore"` } var s T s.A = 0x11223344 s.b = 0x22334455 s.C = 0x33445566 check := []byte{0x44, 0x33, 0x22, 0x11} b, err := Encode(s, nil) if err != nil { t.Error(err) } if !reflect.DeepEqual(b, check) { t.Errorf("%T: got %x; want %x", s, b, check) } var ss, ssCheck T ssCheck.A = s.A err = Decode(b, &ss) if err != nil { t.Error(err) } if !reflect.DeepEqual(ss, ssCheck) { t.Errorf("%T: got %q; want %q", s, ss, ssCheck) } } func TestEndian(t *testing.T) { if LittleEndian.String() != "LittleEndian" || LittleEndian.GoString() != "binary.LittleEndian" { t.Error("LittleEndian") } if BigEndian.String() != "BigEndian" || BigEndian.GoString() != "binary.BigEndian" { t.Error("BigEndian") } } func TestByteReaderWriter(t *testing.T) { buff := [10]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} reader := BytesReader(buff[:]) r := make([]byte, len(buff)-1) n, err := reader.Read(r) if err != nil { t.Error(err) } if n != len(r) { t.Errorf("got %+v\nneed %+v\n", n, len(r)) } if check := buff[:len(r)]; !reflect.DeepEqual(r, check) { t.Errorf("got %+v\nneed %+v\n", r, check) } n2, err2 := reader.Read(r) if n2 != 1 || err2 == nil { t.Errorf("got %d %+v\nneed %d %+v\n", n2, err2, 1, io.EOF) } wBuff := make([]byte, len(buff)+1) writer := BytesWriter(wBuff) w := buff[:] n3, err3 := writer.Write(w) if err3 != nil { t.Error(err3) } if n3 != len(w) { t.Errorf("got %+v\nneed %+v\n", n3, len(w)) } n4, err4 := writer.Write(w) if n4 != 1 || err4 == nil { t.Errorf("got %d %+v\nneed %d %+v\n", n4, err4, 1, ErrNotEnoughSpace) } wCheck := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0} if c := wBuff; !reflect.DeepEqual(c, wCheck) { t.Errorf("got %+v\nneed %+v\n", c, wCheck) } } func TestDecoderSkip(t *testing.T) { type skipedStruct struct { S string I int U uint Map map[uint32]uint32 BoolArray [5]bool U16Array [5]uint16 StrArray [5]string Struct struct{ A uint8 } Bool1 bool Pointer *uint32 Bool2 bool Packed1 uint32 `binary:"packed"` Packed2 int64 `binary:"packed"` } RegStruct((*skipedStruct)(nil)) var w [5]skipedStruct for i := len(w) - 1; i >= 0; i-- { w[i].S = fmt.Sprintf("%d", i) w[i].I = i w[i].U = uint(i) w[i].Map = map[uint32]uint32{uint32(i): uint32(i), uint32(i + 1): uint32(i + 1)} w[i].Struct.A = uint8(i) w[i].U16Array[i] = uint16(i) w[i].BoolArray[i] = true w[i].Bool2 = true w[i].Packed1 = uint32(i) w[i].Packed2 = int64(i * 2) if i%2 == 0 { w[i].Pointer = new(uint32) } } var r [3]skipedStruct b, err := Encode(&w, nil) if err != nil { t.Error(err) } err2 := Decode(b, &r) if err2 != nil { t.Error(err2) } for i := len(r) - 1; i >= 0; i-- { if !reflect.DeepEqual(w[i], r[i]) { t.Errorf("%d got %+v\nneed %+v\n", i, w[i], r[i]) } } } //func TestDecoderSkipError(t *testing.T) { // // defer func() { // // if msg := recover(); msg == nil { // // t.Fatal("did not panic") // // } else { // // fmt.Println(msg) // // } // // }() // bytes := []byte{2, 0, 0, 0, 0} // var dataDecode [0]uintptr // decoder := NewDecoder(bytes) // n := decoder.skipByType(reflect.TypeOf(dataDecode), false) // if n >= 0 { // t.Errorf("DecoderSkipError: have %d, want %d", n, -1) // } else { // //println(n) // } //} func TestFastValue(t *testing.T) { s := _fastValues v := reflect.ValueOf(s) encoder := NewEncoder(Size(s)) for i := v.NumField() - 1; i >= 0; i-- { f := v.Field(i) if err := encoder.Value(f.Interface()); err != nil { t.Error(err) } } buffer := encoder.Buffer() var r fastValues vr := reflect.ValueOf(&r) vr = reflect.Indirect(vr) decoder := NewDecoder(buffer) for i := vr.NumField() - 1; i >= 0; i-- { f := vr.Field(i).Addr() oldSize := decoder.Len() if err := decoder.Value(f.Interface()); err != nil { t.Error(err) } size := decoder.Len() - oldSize assert(size == Sizeof(f.Interface()), "") } if !reflect.DeepEqual(r, s) { t.Errorf("got %+v\nneed %+v\n", r, s) } } func TestEncodeDonotSupportedType(t *testing.T) { ts := doNotSupportTypes if _, err := Encode(ts, nil); err == nil { t.Errorf("EncodeDonotSupportedType: have err == nil, want non-nil") } buff := make([]byte, 0) ecoder := NewEncoder(100) decoder := NewDecoder(buff) tv := reflect.Indirect(reflect.ValueOf(&ts)) for i, n := 0, tv.NumField(); i < n; i++ { if _, err := Encode(tv.Field(i).Interface(), nil); err == nil { t.Errorf("EncodeDonotSupportedType.%v: have err == nil, want non-nil", tv.Field(i).Type()) } else { //fmt.Println(err) } if err := ecoder.Value(tv.Field(i).Interface()); err == nil { t.Errorf("EncodeDonotSupportedType.%v: have err == nil, want non-nil", tv.Field(i).Type()) } else { //fmt.Println(err) } if err := Decode(buff, tv.Field(i).Addr().Interface()); err == nil { t.Errorf("Decode DonotSupportedType.%v: have err == nil, want non-nil", tv.Field(i).Type()) } else { //fmt.Printf("Decode error: %#v\n%s\n", tv.Field(i).Addr().Type().String(), err.Error()) } if err := decoder.value(tv.Field(i), true, false); err == nil { t.Errorf("EncodeDonotSupportedType.%v: have err == nil, want non-nil", tv.Field(i).Type()) } else { //fmt.Println(err) } } if queryStruct(tv.Type()).decode(decoder, tv) == nil { t.Errorf("decode DonotSupportedType.%v: have err == nil, want non-nil", tv.Type()) } } func TestDecoder(t *testing.T) { buffer := []byte{} decoder := NewDecoder(buffer) got := decoder.Skip(0) if got != -1 { t.Errorf("Decoder: have %d, want %d", got, -1) } n := decoder.skipByType(reflect.TypeOf(uintptr(0)), false) if n != -1 { t.Errorf("Decoder: have %d, want %d", n, -1) } } func TestAssert(t *testing.T) { defer func() { if msg := recover(); msg == nil { t.Fatal("did not panic") } }() message := "it will panic" assert(false, message) } func TestRegStruct(t *testing.T) { type StructForReg struct { A int B uint `binary:"ignore"` C int `binary:"int32"` d string _ int32 F float32 S struct { A int B string } S2 struct { A int B string } PS *struct { A int32 B string } } RegStruct((*StructForReg)(nil)) if err := RegStruct((*StructForReg)(nil)); err == nil { //duplicate regist t.Errorf("RegStruct: have err == nil, want non-nil") } var a = StructForReg{ A: -5, B: 6, C: 7, d: "hello", F: 3.14, } a.S.A = 9 a.S.B = "abc" b, err := Encode(&a, nil) if err != nil { t.Error(err) } var r StructForReg //fmt.Printf("%#v\n%#v\n", a, b) err = Decode(b, &r) if err != nil { t.Error(err) } c := a c.B = 0 c.d = "" //r.PS = nil //BUG: how to encode nil pointer? if !reflect.DeepEqual(r, c) { t.Errorf("RegStruct got %+v\nneed %+v\n", r, c) } } func TestRegistStructUnsupported(t *testing.T) { err := RegStruct(int(0)) if err == nil { t.Errorf("RegistStructUnsupported: have err == nil, want non-nil") } info := queryStruct(reflect.TypeOf(doNotSupportTypes)) if info != nil { t.Errorf("RegistStructUnsupported: have info == %v, want nil", info) } numField := info.numField() if numField != 0 { t.Errorf("RegistStructUnsupported: have numField == %v, want 0", numField) } field := info.field(0) if field != nil { t.Errorf("RegistStructUnsupported: have info == %v, want nil", field) } } func TestDecodeUvarintOverflow(t *testing.T) { data := [][]byte{ []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x2}, []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x1, 0, 0}, } var d uint for _, v := range data { decoder := NewDecoder(v) err := decoder.Value(&d) if err == nil { t.Errorf("DecodeUvarintOverflow: have err == nil, want none-nil") } else { //println(err.Error()) } } } type sizerOnly struct{ A uint8 } func (obj sizerOnly) Size() int { return 1 } type encoderOnly struct{ B uint8 } func (obj encoderOnly) Encode(buffer []byte) ([]byte, error) { return nil, nil } type decoderOnly struct { C uint8 } func (obj *decoderOnly) Decode(buffer []byte) error { return nil } type sizeencoderOnly struct { sizerOnly encoderOnly } type sizedecoderOnly struct { sizerOnly decoderOnly } type encodedecoderOnly struct { encoderOnly decoderOnly } type fullSerializer struct { sizerOnly encoderOnly decoderOnly } type fullSerializerError struct { fullSerializer } func (obj *fullSerializerError) Decode(buffer []byte) error { return fmt.Errorf("expected error") } func TestBinarySerializer(t *testing.T) { var a sizerOnly var b encoderOnly var c decoderOnly var d sizeencoderOnly var e sizedecoderOnly var f encodedecoderOnly var g fullSerializerError var h fullSerializer testCase := func(data interface{}, testcase int) (info interface{}) { defer func() { _info := recover() if _info != nil && info == nil { info = _info //fmt.Println(info) } }() switch testcase { case 1: Sizeof(data) case 2: if _, err := Encode(data, nil); err != nil { info = err } case 3: buff := make([]byte, 1000) if err := Decode(buff, data); err != nil { info = err } case 4: encoder := NewEncoder(100) if err := encoder.Value(data); err != nil { info = err } } return } testCode := func(data interface{}) (info interface{}) { for i := 1; i <= 4; i++ { if _info := testCase(data, i); _info != nil && info == nil { info = _info } } return } if info := testCode(&a); info == nil { t.Errorf("BinarySerializer: have err == nil, want none-nil") } if info := testCode(&b); info == nil { t.Errorf("BinarySerializer: have err == nil, want none-nil") } if info := testCode(&c); info == nil { t.Errorf("BinarySerializer: have err == nil, want none-nil") } if info := testCode(&d); info == nil { t.Errorf("BinarySerializer: have err == nil, want none-nil") } if info := testCode(&e); info == nil { t.Errorf("BinarySerializer: have err == nil, want none-nil") } if info := testCode(&f); info == nil { t.Errorf("BinarySerializer: have err == nil, want none-nil") } if info := testCode(&g); info == nil { t.Errorf("BinarySerializer: have err == nil, want none-nil") } if info := testCode(&h); info != nil { t.Errorf("BinarySerializer: have err == %#v, want nil", info) } } func TestFastSizeof(t *testing.T) { type interSize struct { iter interface{} size int } var cases = []interSize{ interSize{bool(false), 1}, interSize{int8(0), 1}, interSize{uint8(0), 1}, interSize{int16(0), 2}, interSize{uint16(0), 2}, interSize{int32(0), 4}, interSize{uint32(0), 4}, interSize{int64(0), 8}, interSize{uint64(0), 8}, interSize{float32(0), 4}, interSize{float64(0), 8}, interSize{complex64(0), 8}, interSize{complex128(0), 16}, interSize{string("hello"), 6}, interSize{int(0), 1}, interSize{uint(0), 1}, interSize{[]bool{false, false, true}, 2}, interSize{[]int8{0}, 2}, interSize{[]uint8{0}, 2}, interSize{[]int16{0}, 3}, interSize{[]uint16{0}, 3}, interSize{[]int32{0}, 5}, interSize{[]uint32{0}, 5}, interSize{[]int64{0}, 9}, interSize{[]uint64{0}, 9}, interSize{[]float32{0}, 5}, interSize{[]float64{0}, 9}, interSize{[]complex64{0}, 9}, interSize{[]complex128{0}, 17}, interSize{[]string{"hello"}, 7}, interSize{&[]bool{false, false, true}, 2}, interSize{&[]int8{0}, 2}, interSize{&[]uint8{0}, 2}, interSize{&[]int16{0}, 3}, interSize{&[]uint16{0}, 3}, interSize{&[]int32{0}, 5}, interSize{&[]uint32{0}, 5}, interSize{&[]int64{0}, 9}, interSize{&[]uint64{0}, 9}, interSize{&[]float32{0}, 5}, interSize{&[]float64{0}, 9}, interSize{&[]complex64{0}, 9}, interSize{&[]complex128{0}, 17}, interSize{&[]string{"hello"}, 7}, interSize{uintptr(0), -1}, interSize{(*[]int)(nil), -1}, } for i, v := range cases { s := fastSizeof(v.iter) if s != v.size { t.Errorf("%d %#v got %d need %d", i, v.iter, s, v.size) } } } func TestPackedInts(t *testing.T) { type packedInts struct { A int16 `binary:"packed"` B int32 `binary:"packed"` C int64 `binary:"packed"` D uint16 `binary:"packed"` E uint32 `binary:"packed"` F uint64 `binary:"packed"` G []uint64 `binary:"packed"` } var data = packedInts{1, 2, 3, 4, 5, 6, []uint64{7, 8, 9}} RegStruct((*packedInts)(nil)) b, err := Encode(data, nil) if err != nil { t.Error(err) } if s := Sizeof(data); s != len(b) { t.Errorf("PackedInts got %+v %+v\nneed %+v\n", len(b), b, s) } check := []byte{0x2, 0x4, 0x6, 0x4, 0x5, 0x6, 0x3, 0x7, 0x8, 0x9} if !reflect.DeepEqual(b, check) { t.Errorf("PackedInts %#v\n got %+v\nneed %+v\n", data, b, check) } var dataDecode packedInts err = Decode(b, &dataDecode) if err != nil { t.Error(err) } if !reflect.DeepEqual(dataDecode, data) { t.Errorf("PackedInts got %+v\nneed %+v\n", dataDecode, data) } } func TestBools(t *testing.T) { type boolset struct { A uint8 //0x11 B bool //true C uint8 //0x22 D []bool //[]bool{true, false, true} E bool //true F *uint32 //false G bool //true H uint8 //0x33 } var data = boolset{ 0x11, true, 0x22, []bool{true, false, true}, true, nil, true, 0x33, } b, err := Encode(data, nil) if err != nil { fmt.Println(err) } size := Sizeof(data) if size != len(b) { fmt.Printf("EncodeBools got %#v %+v\nneed %+v\n", len(b), b, size) } check := []byte{0x11, 0xb, 0x22, 0x3, 0x5, 0x33} if !reflect.DeepEqual(b, check) { t.Errorf("EncodeBools %#v\n got %+v\nneed %+v\n", data, b, check) } var dataDecode boolset err = Decode(b, &dataDecode) if err != nil { t.Error(err) } if !reflect.DeepEqual(dataDecode, data) { t.Errorf("EncodeBools got %+v\nneed %+v\n", dataDecode, data) } }