gitee.com/quant1x/gox@v1.21.2/encoding/binary/struc/struc_test.go (about) 1 package struc 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 "reflect" 8 "testing" 9 ) 10 11 type Nested struct { 12 Test2 int `struc:"int8"` 13 } 14 15 type Example struct { 16 Pad []byte `struc:"[5]pad"` // 00 00 00 00 00 17 I8f int `struc:"int8"` // 01 18 I16f int `struc:"int16"` // 00 02 19 I32f int `struc:"int32"` // 00 00 00 03 20 I64f int `struc:"int64"` // 00 00 00 00 00 00 00 04 21 U8f int `struc:"uint8,little"` // 05 22 U16f int `struc:"uint16,little"` // 06 00 23 U32f int `struc:"uint32,little"` // 07 00 00 00 24 U64f int `struc:"uint64,little"` // 08 00 00 00 00 00 00 00 25 Boolf int `struc:"bool"` // 01 26 Byte4f []byte `struc:"[4]byte"` // "abcd" 27 28 I8 int8 // 09 29 I16 int16 // 00 0a 30 I32 int32 // 00 00 00 0b 31 I64 int64 // 00 00 00 00 00 00 00 0c 32 U8 uint8 `struc:"little"` // 0d 33 U16 uint16 `struc:"little"` // 0e 00 34 U32 uint32 `struc:"little"` // 0f 00 00 00 35 U64 uint64 `struc:"little"` // 10 00 00 00 00 00 00 00 36 BoolT bool // 01 37 BoolF bool // 00 38 Byte4 [4]byte // "efgh" 39 Float1 float32 // 41 a0 00 00 40 Float2 float64 // 41 35 00 00 00 00 00 00 41 42 I32f2 int64 `struc:"int32"` // ff ff ff ff 43 U32f2 int64 `struc:"uint32"` // ff ff ff ff 44 45 I32f3 int32 `struc:"int64"` // ff ff ff ff ff ff ff ff 46 47 Size int `struc:"sizeof=Str,little"` // 0a 00 00 00 48 Str string `struc:"[]byte"` // "ijklmnopqr" 49 Strb string `struc:"[4]byte"` // "stuv" 50 51 Size2 int `struc:"uint8,sizeof=Str2"` // 04 52 Str2 string // "1234" 53 54 Size3 int `struc:"uint8,sizeof=Bstr"` // 04 55 Bstr []byte // "5678" 56 57 Size4 int `struc:"little"` // 07 00 00 00 58 Str4a string `struc:"[]byte,sizefrom=Size4"` // "ijklmno" 59 Str4b string `struc:"[]byte,sizefrom=Size4"` // "pqrstuv" 60 61 Size5 int `struc:"uint8"` // 04 62 Bstr2 []byte `struc:"sizefrom=Size5"` // "5678" 63 64 Nested Nested // 00 00 00 01 65 NestedP *Nested // 00 00 00 02 66 TestP64 *int `struc:"int64"` // 00 00 00 05 67 68 NestedSize int `struc:"sizeof=NestedA"` // 00 00 00 02 69 NestedA []Nested // [00 00 00 03, 00 00 00 04] 70 71 Skip int `struc:"skip"` 72 73 CustomTypeSize Int3 `struc:"sizeof=CustomTypeSizeArr"` // 00 00 00 04 74 CustomTypeSizeArr []byte // "ABCD" 75 } 76 77 var five = 5 78 79 type ExampleStructWithin struct { 80 a uint8 81 } 82 83 type ExampleSlice struct { 84 PropsLen uint8 `struc:"sizeof=Props"` 85 Props []ExampleStructWithin 86 } 87 88 type ExampleArray struct { 89 PropsLen uint8 90 Props [16]ExampleStructWithin `struc:"[16]ExampleStructWithin"` 91 } 92 93 var arraySliceReferenceBytes = []byte{ 94 16, 95 0, 0, 0, 1, 96 0, 0, 0, 1, 97 0, 0, 0, 2, 98 0, 0, 0, 3, 99 0, 0, 0, 4, 100 0, 0, 0, 5, 101 0, 0, 0, 6, 102 0, 0, 0, 7, 103 0, 0, 0, 8, 104 0, 0, 0, 9, 105 0, 0, 0, 10, 106 0, 0, 0, 11, 107 0, 0, 0, 12, 108 0, 0, 0, 13, 109 0, 0, 0, 14, 110 0, 0, 0, 15, 111 0, 0, 0, 16, 112 } 113 114 var arrayReference = &ExampleArray{ 115 16, 116 [16]ExampleStructWithin{ 117 ExampleStructWithin{1}, 118 ExampleStructWithin{2}, 119 ExampleStructWithin{3}, 120 ExampleStructWithin{4}, 121 ExampleStructWithin{5}, 122 ExampleStructWithin{6}, 123 ExampleStructWithin{7}, 124 ExampleStructWithin{8}, 125 ExampleStructWithin{9}, 126 ExampleStructWithin{10}, 127 ExampleStructWithin{11}, 128 ExampleStructWithin{12}, 129 ExampleStructWithin{13}, 130 ExampleStructWithin{14}, 131 ExampleStructWithin{15}, 132 ExampleStructWithin{16}, 133 }, 134 } 135 136 var sliceReference = &ExampleSlice{ 137 16, 138 []ExampleStructWithin{ 139 ExampleStructWithin{1}, 140 ExampleStructWithin{2}, 141 ExampleStructWithin{3}, 142 ExampleStructWithin{4}, 143 ExampleStructWithin{5}, 144 ExampleStructWithin{6}, 145 ExampleStructWithin{7}, 146 ExampleStructWithin{8}, 147 ExampleStructWithin{9}, 148 ExampleStructWithin{10}, 149 ExampleStructWithin{11}, 150 ExampleStructWithin{12}, 151 ExampleStructWithin{13}, 152 ExampleStructWithin{14}, 153 ExampleStructWithin{15}, 154 ExampleStructWithin{16}, 155 }, 156 } 157 158 var reference = &Example{ 159 nil, 160 1, 2, 3, 4, 5, 6, 7, 8, 0, []byte{'a', 'b', 'c', 'd'}, 161 9, 10, 11, 12, 13, 14, 15, 16, true, false, [4]byte{'e', 'f', 'g', 'h'}, 162 20, 21, 163 -1, 164 4294967295, 165 -1, 166 10, "ijklmnopqr", "stuv", 167 4, "1234", 168 4, []byte("5678"), 169 7, "ijklmno", "pqrstuv", 170 4, []byte("5678"), 171 Nested{1}, &Nested{2}, &five, 172 6, []Nested{{3}, {4}, {5}, {6}, {7}, {8}}, 173 0, 174 Int3(4), []byte("ABCD"), 175 } 176 177 var referenceBytes = []byte{ 178 0, 0, 0, 0, 0, // pad(5) 179 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, // fake int8-int64(1-4) 180 5, 6, 0, 7, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, // fake little-endian uint8-uint64(5-8) 181 0, // fake bool(0) 182 'a', 'b', 'c', 'd', // fake [4]byte 183 184 9, 0, 10, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 12, // real int8-int64(9-12) 185 13, 14, 0, 15, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, // real little-endian uint8-uint64(13-16) 186 1, 0, // real bool(1), bool(0) 187 'e', 'f', 'g', 'h', // real [4]byte 188 65, 160, 0, 0, // real float32(20) 189 64, 53, 0, 0, 0, 0, 0, 0, // real float64(21) 190 191 255, 255, 255, 255, // fake int32(-1) 192 255, 255, 255, 255, // fake uint32(4294967295) 193 194 255, 255, 255, 255, 255, 255, 255, 255, // fake int64(-1) 195 196 10, 0, 0, 0, // little-endian int32(10) sizeof=Str 197 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', // Str 198 's', 't', 'u', 'v', // fake string([4]byte) 199 04, '1', '2', '3', '4', // real string 200 04, '5', '6', '7', '8', // fake []byte(string) 201 202 7, 0, 0, 0, // little-endian int32(7) 203 'i', 'j', 'k', 'l', 'm', 'n', 'o', // Str4a sizefrom=Size4 204 'p', 'q', 'r', 's', 't', 'u', 'v', // Str4b sizefrom=Size4 205 04, '5', '6', '7', '8', // fake []byte(string) 206 207 1, 2, // Nested{1}, Nested{2} 208 0, 0, 0, 0, 0, 0, 0, 5, // &five 209 210 0, 0, 0, 6, // int32(6) 211 3, 4, 5, 6, 7, 8, // [Nested{3}, ...Nested{8}] 212 213 0, 0, 4, 'A', 'B', 'C', 'D', // Int3(4), []byte("ABCD") 214 } 215 216 func TestCodec(t *testing.T) { 217 var buf bytes.Buffer 218 if err := Pack(&buf, reference); err != nil { 219 t.Fatal(err) 220 } 221 out := &Example{} 222 if err := Unpack(&buf, out); err != nil { 223 t.Fatal(err) 224 } 225 if !reflect.DeepEqual(reference, out) { 226 fmt.Printf("got: %#v\nwant: %#v\n", out, reference) 227 t.Fatal("encode/decode failed") 228 } 229 } 230 231 func TestEncode(t *testing.T) { 232 var buf bytes.Buffer 233 if err := Pack(&buf, reference); err != nil { 234 t.Fatal(err) 235 } 236 if !bytes.Equal(buf.Bytes(), referenceBytes) { 237 fmt.Printf("got: %#v\nwant: %#v\n", buf.Bytes(), referenceBytes) 238 t.Fatal("encode failed") 239 } 240 } 241 242 func TestDecode(t *testing.T) { 243 buf := bytes.NewReader(referenceBytes) 244 out := &Example{} 245 if err := Unpack(buf, out); err != nil { 246 t.Fatal(err) 247 } 248 if !reflect.DeepEqual(reference, out) { 249 fmt.Printf("got: %#v\nwant: %#v\n", out, reference) 250 t.Fatal("decode failed") 251 } 252 } 253 254 func TestSizeof(t *testing.T) { 255 size, err := Sizeof(reference) 256 if err != nil { 257 t.Fatal(err) 258 } 259 if size != len(referenceBytes) { 260 t.Fatalf("sizeof failed; expected %d, got %d", len(referenceBytes), size) 261 } 262 } 263 264 type ExampleEndian struct { 265 T int `struc:"int16,big"` 266 } 267 268 func TestEndianSwap(t *testing.T) { 269 var buf bytes.Buffer 270 big := &ExampleEndian{1} 271 if err := PackWithOrder(&buf, big, binary.BigEndian); err != nil { 272 t.Fatal(err) 273 } 274 little := &ExampleEndian{} 275 if err := UnpackWithOrder(&buf, little, binary.LittleEndian); err != nil { 276 t.Fatal(err) 277 } 278 if little.T != 256 { 279 t.Fatal("big -> little conversion failed") 280 } 281 } 282 283 func TestNilValue(t *testing.T) { 284 var buf bytes.Buffer 285 if err := Pack(&buf, nil); err == nil { 286 t.Fatal("failed throw error for bad struct value") 287 } 288 if err := Unpack(&buf, nil); err == nil { 289 t.Fatal("failed throw error for bad struct value") 290 } 291 if _, err := Sizeof(nil); err == nil { 292 t.Fatal("failed to throw error for bad struct value") 293 } 294 } 295 296 type sliceUnderrun struct { 297 Str string `struc:"[10]byte"` 298 Arr []uint16 `struc:"[10]uint16"` 299 } 300 301 func TestSliceUnderrun(t *testing.T) { 302 var buf bytes.Buffer 303 v := sliceUnderrun{ 304 Str: "foo", 305 Arr: []uint16{1, 2, 3}, 306 } 307 if err := Pack(&buf, &v); err != nil { 308 t.Fatal(err) 309 } 310 }