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  }