github.com/c12o16h1/go/src@v0.0.0-20200114212001-5a151c0f00ed/encoding/binary/binary_test.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package binary
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"io"
    11  	"io/ioutil"
    12  	"math"
    13  	"reflect"
    14  	"strings"
    15  	"sync"
    16  	"testing"
    17  )
    18  
    19  type Struct struct {
    20  	Int8       int8
    21  	Int16      int16
    22  	Int32      int32
    23  	Int64      int64
    24  	Uint8      uint8
    25  	Uint16     uint16
    26  	Uint32     uint32
    27  	Uint64     uint64
    28  	Float32    float32
    29  	Float64    float64
    30  	Complex64  complex64
    31  	Complex128 complex128
    32  	Array      [4]uint8
    33  	Bool       bool
    34  	BoolArray  [4]bool
    35  }
    36  
    37  type T struct {
    38  	Int     int
    39  	Uint    uint
    40  	Uintptr uintptr
    41  	Array   [4]int
    42  }
    43  
    44  var s = Struct{
    45  	0x01,
    46  	0x0203,
    47  	0x04050607,
    48  	0x08090a0b0c0d0e0f,
    49  	0x10,
    50  	0x1112,
    51  	0x13141516,
    52  	0x1718191a1b1c1d1e,
    53  
    54  	math.Float32frombits(0x1f202122),
    55  	math.Float64frombits(0x232425262728292a),
    56  	complex(
    57  		math.Float32frombits(0x2b2c2d2e),
    58  		math.Float32frombits(0x2f303132),
    59  	),
    60  	complex(
    61  		math.Float64frombits(0x333435363738393a),
    62  		math.Float64frombits(0x3b3c3d3e3f404142),
    63  	),
    64  
    65  	[4]uint8{0x43, 0x44, 0x45, 0x46},
    66  
    67  	true,
    68  	[4]bool{true, false, true, false},
    69  }
    70  
    71  var big = []byte{
    72  	1,
    73  	2, 3,
    74  	4, 5, 6, 7,
    75  	8, 9, 10, 11, 12, 13, 14, 15,
    76  	16,
    77  	17, 18,
    78  	19, 20, 21, 22,
    79  	23, 24, 25, 26, 27, 28, 29, 30,
    80  
    81  	31, 32, 33, 34,
    82  	35, 36, 37, 38, 39, 40, 41, 42,
    83  	43, 44, 45, 46, 47, 48, 49, 50,
    84  	51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
    85  
    86  	67, 68, 69, 70,
    87  
    88  	1,
    89  	1, 0, 1, 0,
    90  }
    91  
    92  var little = []byte{
    93  	1,
    94  	3, 2,
    95  	7, 6, 5, 4,
    96  	15, 14, 13, 12, 11, 10, 9, 8,
    97  	16,
    98  	18, 17,
    99  	22, 21, 20, 19,
   100  	30, 29, 28, 27, 26, 25, 24, 23,
   101  
   102  	34, 33, 32, 31,
   103  	42, 41, 40, 39, 38, 37, 36, 35,
   104  	46, 45, 44, 43, 50, 49, 48, 47,
   105  	58, 57, 56, 55, 54, 53, 52, 51, 66, 65, 64, 63, 62, 61, 60, 59,
   106  
   107  	67, 68, 69, 70,
   108  
   109  	1,
   110  	1, 0, 1, 0,
   111  }
   112  
   113  var src = []byte{1, 2, 3, 4, 5, 6, 7, 8}
   114  var res = []int32{0x01020304, 0x05060708}
   115  var putbuf = []byte{0, 0, 0, 0, 0, 0, 0, 0}
   116  
   117  func checkResult(t *testing.T, dir string, order ByteOrder, err error, have, want interface{}) {
   118  	if err != nil {
   119  		t.Errorf("%v %v: %v", dir, order, err)
   120  		return
   121  	}
   122  	if !reflect.DeepEqual(have, want) {
   123  		t.Errorf("%v %v:\n\thave %+v\n\twant %+v", dir, order, have, want)
   124  	}
   125  }
   126  
   127  func testRead(t *testing.T, order ByteOrder, b []byte, s1 interface{}) {
   128  	var s2 Struct
   129  	err := Read(bytes.NewReader(b), order, &s2)
   130  	checkResult(t, "Read", order, err, s2, s1)
   131  }
   132  
   133  func testWrite(t *testing.T, order ByteOrder, b []byte, s1 interface{}) {
   134  	buf := new(bytes.Buffer)
   135  	err := Write(buf, order, s1)
   136  	checkResult(t, "Write", order, err, buf.Bytes(), b)
   137  }
   138  
   139  func TestLittleEndianRead(t *testing.T)     { testRead(t, LittleEndian, little, s) }
   140  func TestLittleEndianWrite(t *testing.T)    { testWrite(t, LittleEndian, little, s) }
   141  func TestLittleEndianPtrWrite(t *testing.T) { testWrite(t, LittleEndian, little, &s) }
   142  
   143  func TestBigEndianRead(t *testing.T)     { testRead(t, BigEndian, big, s) }
   144  func TestBigEndianWrite(t *testing.T)    { testWrite(t, BigEndian, big, s) }
   145  func TestBigEndianPtrWrite(t *testing.T) { testWrite(t, BigEndian, big, &s) }
   146  
   147  func TestReadSlice(t *testing.T) {
   148  	slice := make([]int32, 2)
   149  	err := Read(bytes.NewReader(src), BigEndian, slice)
   150  	checkResult(t, "ReadSlice", BigEndian, err, slice, res)
   151  }
   152  
   153  func TestWriteSlice(t *testing.T) {
   154  	buf := new(bytes.Buffer)
   155  	err := Write(buf, BigEndian, res)
   156  	checkResult(t, "WriteSlice", BigEndian, err, buf.Bytes(), src)
   157  }
   158  
   159  func TestReadBool(t *testing.T) {
   160  	var res bool
   161  	var err error
   162  	err = Read(bytes.NewReader([]byte{0}), BigEndian, &res)
   163  	checkResult(t, "ReadBool", BigEndian, err, res, false)
   164  	res = false
   165  	err = Read(bytes.NewReader([]byte{1}), BigEndian, &res)
   166  	checkResult(t, "ReadBool", BigEndian, err, res, true)
   167  	res = false
   168  	err = Read(bytes.NewReader([]byte{2}), BigEndian, &res)
   169  	checkResult(t, "ReadBool", BigEndian, err, res, true)
   170  }
   171  
   172  func TestReadBoolSlice(t *testing.T) {
   173  	slice := make([]bool, 4)
   174  	err := Read(bytes.NewReader([]byte{0, 1, 2, 255}), BigEndian, slice)
   175  	checkResult(t, "ReadBoolSlice", BigEndian, err, slice, []bool{false, true, true, true})
   176  }
   177  
   178  // Addresses of arrays are easier to manipulate with reflection than are slices.
   179  var intArrays = []interface{}{
   180  	&[100]int8{},
   181  	&[100]int16{},
   182  	&[100]int32{},
   183  	&[100]int64{},
   184  	&[100]uint8{},
   185  	&[100]uint16{},
   186  	&[100]uint32{},
   187  	&[100]uint64{},
   188  }
   189  
   190  func TestSliceRoundTrip(t *testing.T) {
   191  	buf := new(bytes.Buffer)
   192  	for _, array := range intArrays {
   193  		src := reflect.ValueOf(array).Elem()
   194  		unsigned := false
   195  		switch src.Index(0).Kind() {
   196  		case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   197  			unsigned = true
   198  		}
   199  		for i := 0; i < src.Len(); i++ {
   200  			if unsigned {
   201  				src.Index(i).SetUint(uint64(i * 0x07654321))
   202  			} else {
   203  				src.Index(i).SetInt(int64(i * 0x07654321))
   204  			}
   205  		}
   206  		buf.Reset()
   207  		srcSlice := src.Slice(0, src.Len())
   208  		err := Write(buf, BigEndian, srcSlice.Interface())
   209  		if err != nil {
   210  			t.Fatal(err)
   211  		}
   212  		dst := reflect.New(src.Type()).Elem()
   213  		dstSlice := dst.Slice(0, dst.Len())
   214  		err = Read(buf, BigEndian, dstSlice.Interface())
   215  		if err != nil {
   216  			t.Fatal(err)
   217  		}
   218  		if !reflect.DeepEqual(src.Interface(), dst.Interface()) {
   219  			t.Fatal(src)
   220  		}
   221  	}
   222  }
   223  
   224  func TestWriteT(t *testing.T) {
   225  	buf := new(bytes.Buffer)
   226  	ts := T{}
   227  	if err := Write(buf, BigEndian, ts); err == nil {
   228  		t.Errorf("WriteT: have err == nil, want non-nil")
   229  	}
   230  
   231  	tv := reflect.Indirect(reflect.ValueOf(ts))
   232  	for i, n := 0, tv.NumField(); i < n; i++ {
   233  		typ := tv.Field(i).Type().String()
   234  		if typ == "[4]int" {
   235  			typ = "int" // the problem is int, not the [4]
   236  		}
   237  		if err := Write(buf, BigEndian, tv.Field(i).Interface()); err == nil {
   238  			t.Errorf("WriteT.%v: have err == nil, want non-nil", tv.Field(i).Type())
   239  		} else if !strings.Contains(err.Error(), typ) {
   240  			t.Errorf("WriteT: have err == %q, want it to mention %s", err, typ)
   241  		}
   242  	}
   243  }
   244  
   245  type BlankFields struct {
   246  	A uint32
   247  	_ int32
   248  	B float64
   249  	_ [4]int16
   250  	C byte
   251  	_ [7]byte
   252  	_ struct {
   253  		f [8]float32
   254  	}
   255  }
   256  
   257  type BlankFieldsProbe struct {
   258  	A  uint32
   259  	P0 int32
   260  	B  float64
   261  	P1 [4]int16
   262  	C  byte
   263  	P2 [7]byte
   264  	P3 struct {
   265  		F [8]float32
   266  	}
   267  }
   268  
   269  func TestBlankFields(t *testing.T) {
   270  	buf := new(bytes.Buffer)
   271  	b1 := BlankFields{A: 1234567890, B: 2.718281828, C: 42}
   272  	if err := Write(buf, LittleEndian, &b1); err != nil {
   273  		t.Error(err)
   274  	}
   275  
   276  	// zero values must have been written for blank fields
   277  	var p BlankFieldsProbe
   278  	if err := Read(buf, LittleEndian, &p); err != nil {
   279  		t.Error(err)
   280  	}
   281  
   282  	// quick test: only check first value of slices
   283  	if p.P0 != 0 || p.P1[0] != 0 || p.P2[0] != 0 || p.P3.F[0] != 0 {
   284  		t.Errorf("non-zero values for originally blank fields: %#v", p)
   285  	}
   286  
   287  	// write p and see if we can probe only some fields
   288  	if err := Write(buf, LittleEndian, &p); err != nil {
   289  		t.Error(err)
   290  	}
   291  
   292  	// read should ignore blank fields in b2
   293  	var b2 BlankFields
   294  	if err := Read(buf, LittleEndian, &b2); err != nil {
   295  		t.Error(err)
   296  	}
   297  	if b1.A != b2.A || b1.B != b2.B || b1.C != b2.C {
   298  		t.Errorf("%#v != %#v", b1, b2)
   299  	}
   300  }
   301  
   302  func TestSizeStructCache(t *testing.T) {
   303  	// Reset the cache, otherwise multiple test runs fail.
   304  	structSize = sync.Map{}
   305  
   306  	count := func() int {
   307  		var i int
   308  		structSize.Range(func(_, _ interface{}) bool {
   309  			i++
   310  			return true
   311  		})
   312  		return i
   313  	}
   314  
   315  	var total int
   316  	added := func() int {
   317  		delta := count() - total
   318  		total += delta
   319  		return delta
   320  	}
   321  
   322  	type foo struct {
   323  		A uint32
   324  	}
   325  
   326  	type bar struct {
   327  		A Struct
   328  		B foo
   329  		C Struct
   330  	}
   331  
   332  	testcases := []struct {
   333  		val  interface{}
   334  		want int
   335  	}{
   336  		{new(foo), 1},
   337  		{new(bar), 1},
   338  		{new(bar), 0},
   339  		{new(struct{ A Struct }), 1},
   340  		{new(struct{ A Struct }), 0},
   341  	}
   342  
   343  	for _, tc := range testcases {
   344  		if Size(tc.val) == -1 {
   345  			t.Fatalf("Can't get the size of %T", tc.val)
   346  		}
   347  
   348  		if n := added(); n != tc.want {
   349  			t.Errorf("Sizing %T added %d entries to the cache, want %d", tc.val, n, tc.want)
   350  		}
   351  	}
   352  }
   353  
   354  // An attempt to read into a struct with an unexported field will
   355  // panic. This is probably not the best choice, but at this point
   356  // anything else would be an API change.
   357  
   358  type Unexported struct {
   359  	a int32
   360  }
   361  
   362  func TestUnexportedRead(t *testing.T) {
   363  	var buf bytes.Buffer
   364  	u1 := Unexported{a: 1}
   365  	if err := Write(&buf, LittleEndian, &u1); err != nil {
   366  		t.Fatal(err)
   367  	}
   368  
   369  	defer func() {
   370  		if recover() == nil {
   371  			t.Fatal("did not panic")
   372  		}
   373  	}()
   374  	var u2 Unexported
   375  	Read(&buf, LittleEndian, &u2)
   376  }
   377  
   378  func TestReadErrorMsg(t *testing.T) {
   379  	var buf bytes.Buffer
   380  	read := func(data interface{}) {
   381  		err := Read(&buf, LittleEndian, data)
   382  		want := "binary.Read: invalid type " + reflect.TypeOf(data).String()
   383  		if err == nil {
   384  			t.Errorf("%T: got no error; want %q", data, want)
   385  			return
   386  		}
   387  		if got := err.Error(); got != want {
   388  			t.Errorf("%T: got %q; want %q", data, got, want)
   389  		}
   390  	}
   391  	read(0)
   392  	s := new(struct{})
   393  	read(&s)
   394  	p := &s
   395  	read(&p)
   396  }
   397  
   398  func TestReadTruncated(t *testing.T) {
   399  	const data = "0123456789abcdef"
   400  
   401  	var b1 = make([]int32, 4)
   402  	var b2 struct {
   403  		A, B, C, D byte
   404  		E          int32
   405  		F          float64
   406  	}
   407  
   408  	for i := 0; i <= len(data); i++ {
   409  		var errWant error
   410  		switch i {
   411  		case 0:
   412  			errWant = io.EOF
   413  		case len(data):
   414  			errWant = nil
   415  		default:
   416  			errWant = io.ErrUnexpectedEOF
   417  		}
   418  
   419  		if err := Read(strings.NewReader(data[:i]), LittleEndian, &b1); err != errWant {
   420  			t.Errorf("Read(%d) with slice: got %v, want %v", i, err, errWant)
   421  		}
   422  		if err := Read(strings.NewReader(data[:i]), LittleEndian, &b2); err != errWant {
   423  			t.Errorf("Read(%d) with struct: got %v, want %v", i, err, errWant)
   424  		}
   425  	}
   426  }
   427  
   428  func testUint64SmallSliceLengthPanics() (panicked bool) {
   429  	defer func() {
   430  		panicked = recover() != nil
   431  	}()
   432  	b := [8]byte{1, 2, 3, 4, 5, 6, 7, 8}
   433  	LittleEndian.Uint64(b[:4])
   434  	return false
   435  }
   436  
   437  func testPutUint64SmallSliceLengthPanics() (panicked bool) {
   438  	defer func() {
   439  		panicked = recover() != nil
   440  	}()
   441  	b := [8]byte{}
   442  	LittleEndian.PutUint64(b[:4], 0x0102030405060708)
   443  	return false
   444  }
   445  
   446  func TestEarlyBoundsChecks(t *testing.T) {
   447  	if testUint64SmallSliceLengthPanics() != true {
   448  		t.Errorf("binary.LittleEndian.Uint64 expected to panic for small slices, but didn't")
   449  	}
   450  	if testPutUint64SmallSliceLengthPanics() != true {
   451  		t.Errorf("binary.LittleEndian.PutUint64 expected to panic for small slices, but didn't")
   452  	}
   453  }
   454  
   455  func TestReadInvalidDestination(t *testing.T) {
   456  	testReadInvalidDestination(t, BigEndian)
   457  	testReadInvalidDestination(t, LittleEndian)
   458  }
   459  
   460  func testReadInvalidDestination(t *testing.T, order ByteOrder) {
   461  	destinations := []interface{}{
   462  		int8(0),
   463  		int16(0),
   464  		int32(0),
   465  		int64(0),
   466  
   467  		uint8(0),
   468  		uint16(0),
   469  		uint32(0),
   470  		uint64(0),
   471  
   472  		bool(false),
   473  	}
   474  
   475  	for _, dst := range destinations {
   476  		err := Read(bytes.NewReader([]byte{1, 2, 3, 4, 5, 6, 7, 8}), order, dst)
   477  		want := fmt.Sprintf("binary.Read: invalid type %T", dst)
   478  		if err == nil || err.Error() != want {
   479  			t.Fatalf("for type %T: got %q; want %q", dst, err, want)
   480  		}
   481  	}
   482  }
   483  
   484  type byteSliceReader struct {
   485  	remain []byte
   486  }
   487  
   488  func (br *byteSliceReader) Read(p []byte) (int, error) {
   489  	n := copy(p, br.remain)
   490  	br.remain = br.remain[n:]
   491  	return n, nil
   492  }
   493  
   494  func BenchmarkReadSlice1000Int32s(b *testing.B) {
   495  	bsr := &byteSliceReader{}
   496  	slice := make([]int32, 1000)
   497  	buf := make([]byte, len(slice)*4)
   498  	b.SetBytes(int64(len(buf)))
   499  	b.ResetTimer()
   500  	for i := 0; i < b.N; i++ {
   501  		bsr.remain = buf
   502  		Read(bsr, BigEndian, slice)
   503  	}
   504  }
   505  
   506  func BenchmarkReadStruct(b *testing.B) {
   507  	bsr := &byteSliceReader{}
   508  	var buf bytes.Buffer
   509  	Write(&buf, BigEndian, &s)
   510  	b.SetBytes(int64(dataSize(reflect.ValueOf(s))))
   511  	t := s
   512  	b.ResetTimer()
   513  	for i := 0; i < b.N; i++ {
   514  		bsr.remain = buf.Bytes()
   515  		Read(bsr, BigEndian, &t)
   516  	}
   517  	b.StopTimer()
   518  	if b.N > 0 && !reflect.DeepEqual(s, t) {
   519  		b.Fatalf("struct doesn't match:\ngot  %v;\nwant %v", t, s)
   520  	}
   521  }
   522  
   523  func BenchmarkWriteStruct(b *testing.B) {
   524  	b.SetBytes(int64(Size(&s)))
   525  	b.ResetTimer()
   526  	for i := 0; i < b.N; i++ {
   527  		Write(ioutil.Discard, BigEndian, &s)
   528  	}
   529  }
   530  
   531  func BenchmarkReadInts(b *testing.B) {
   532  	var ls Struct
   533  	bsr := &byteSliceReader{}
   534  	var r io.Reader = bsr
   535  	b.SetBytes(2 * (1 + 2 + 4 + 8))
   536  	b.ResetTimer()
   537  	for i := 0; i < b.N; i++ {
   538  		bsr.remain = big
   539  		Read(r, BigEndian, &ls.Int8)
   540  		Read(r, BigEndian, &ls.Int16)
   541  		Read(r, BigEndian, &ls.Int32)
   542  		Read(r, BigEndian, &ls.Int64)
   543  		Read(r, BigEndian, &ls.Uint8)
   544  		Read(r, BigEndian, &ls.Uint16)
   545  		Read(r, BigEndian, &ls.Uint32)
   546  		Read(r, BigEndian, &ls.Uint64)
   547  	}
   548  	b.StopTimer()
   549  	want := s
   550  	want.Float32 = 0
   551  	want.Float64 = 0
   552  	want.Complex64 = 0
   553  	want.Complex128 = 0
   554  	want.Array = [4]uint8{0, 0, 0, 0}
   555  	want.Bool = false
   556  	want.BoolArray = [4]bool{false, false, false, false}
   557  	if b.N > 0 && !reflect.DeepEqual(ls, want) {
   558  		b.Fatalf("struct doesn't match:\ngot  %v;\nwant %v", ls, want)
   559  	}
   560  }
   561  
   562  func BenchmarkWriteInts(b *testing.B) {
   563  	buf := new(bytes.Buffer)
   564  	var w io.Writer = buf
   565  	b.SetBytes(2 * (1 + 2 + 4 + 8))
   566  	b.ResetTimer()
   567  	for i := 0; i < b.N; i++ {
   568  		buf.Reset()
   569  		Write(w, BigEndian, s.Int8)
   570  		Write(w, BigEndian, s.Int16)
   571  		Write(w, BigEndian, s.Int32)
   572  		Write(w, BigEndian, s.Int64)
   573  		Write(w, BigEndian, s.Uint8)
   574  		Write(w, BigEndian, s.Uint16)
   575  		Write(w, BigEndian, s.Uint32)
   576  		Write(w, BigEndian, s.Uint64)
   577  	}
   578  	b.StopTimer()
   579  	if b.N > 0 && !bytes.Equal(buf.Bytes(), big[:30]) {
   580  		b.Fatalf("first half doesn't match: %x %x", buf.Bytes(), big[:30])
   581  	}
   582  }
   583  
   584  func BenchmarkWriteSlice1000Int32s(b *testing.B) {
   585  	slice := make([]int32, 1000)
   586  	buf := new(bytes.Buffer)
   587  	var w io.Writer = buf
   588  	b.SetBytes(4 * 1000)
   589  	b.ResetTimer()
   590  	for i := 0; i < b.N; i++ {
   591  		buf.Reset()
   592  		Write(w, BigEndian, slice)
   593  	}
   594  	b.StopTimer()
   595  }
   596  
   597  func BenchmarkPutUint16(b *testing.B) {
   598  	b.SetBytes(2)
   599  	for i := 0; i < b.N; i++ {
   600  		BigEndian.PutUint16(putbuf[:], uint16(i))
   601  	}
   602  }
   603  
   604  func BenchmarkPutUint32(b *testing.B) {
   605  	b.SetBytes(4)
   606  	for i := 0; i < b.N; i++ {
   607  		BigEndian.PutUint32(putbuf[:], uint32(i))
   608  	}
   609  }
   610  
   611  func BenchmarkPutUint64(b *testing.B) {
   612  	b.SetBytes(8)
   613  	for i := 0; i < b.N; i++ {
   614  		BigEndian.PutUint64(putbuf[:], uint64(i))
   615  	}
   616  }
   617  func BenchmarkLittleEndianPutUint16(b *testing.B) {
   618  	b.SetBytes(2)
   619  	for i := 0; i < b.N; i++ {
   620  		LittleEndian.PutUint16(putbuf[:], uint16(i))
   621  	}
   622  }
   623  
   624  func BenchmarkLittleEndianPutUint32(b *testing.B) {
   625  	b.SetBytes(4)
   626  	for i := 0; i < b.N; i++ {
   627  		LittleEndian.PutUint32(putbuf[:], uint32(i))
   628  	}
   629  }
   630  
   631  func BenchmarkLittleEndianPutUint64(b *testing.B) {
   632  	b.SetBytes(8)
   633  	for i := 0; i < b.N; i++ {
   634  		LittleEndian.PutUint64(putbuf[:], uint64(i))
   635  	}
   636  }
   637  
   638  func BenchmarkReadFloats(b *testing.B) {
   639  	var ls Struct
   640  	bsr := &byteSliceReader{}
   641  	var r io.Reader = bsr
   642  	b.SetBytes(4 + 8)
   643  	b.ResetTimer()
   644  	for i := 0; i < b.N; i++ {
   645  		bsr.remain = big[30:]
   646  		Read(r, BigEndian, &ls.Float32)
   647  		Read(r, BigEndian, &ls.Float64)
   648  	}
   649  	b.StopTimer()
   650  	want := s
   651  	want.Int8 = 0
   652  	want.Int16 = 0
   653  	want.Int32 = 0
   654  	want.Int64 = 0
   655  	want.Uint8 = 0
   656  	want.Uint16 = 0
   657  	want.Uint32 = 0
   658  	want.Uint64 = 0
   659  	want.Complex64 = 0
   660  	want.Complex128 = 0
   661  	want.Array = [4]uint8{0, 0, 0, 0}
   662  	want.Bool = false
   663  	want.BoolArray = [4]bool{false, false, false, false}
   664  	if b.N > 0 && !reflect.DeepEqual(ls, want) {
   665  		b.Fatalf("struct doesn't match:\ngot  %v;\nwant %v", ls, want)
   666  	}
   667  }
   668  
   669  func BenchmarkWriteFloats(b *testing.B) {
   670  	buf := new(bytes.Buffer)
   671  	var w io.Writer = buf
   672  	b.SetBytes(4 + 8)
   673  	b.ResetTimer()
   674  	for i := 0; i < b.N; i++ {
   675  		buf.Reset()
   676  		Write(w, BigEndian, s.Float32)
   677  		Write(w, BigEndian, s.Float64)
   678  	}
   679  	b.StopTimer()
   680  	if b.N > 0 && !bytes.Equal(buf.Bytes(), big[30:30+4+8]) {
   681  		b.Fatalf("first half doesn't match: %x %x", buf.Bytes(), big[30:30+4+8])
   682  	}
   683  }
   684  
   685  func BenchmarkReadSlice1000Float32s(b *testing.B) {
   686  	bsr := &byteSliceReader{}
   687  	slice := make([]float32, 1000)
   688  	buf := make([]byte, len(slice)*4)
   689  	b.SetBytes(int64(len(buf)))
   690  	b.ResetTimer()
   691  	for i := 0; i < b.N; i++ {
   692  		bsr.remain = buf
   693  		Read(bsr, BigEndian, slice)
   694  	}
   695  }
   696  
   697  func BenchmarkWriteSlice1000Float32s(b *testing.B) {
   698  	slice := make([]float32, 1000)
   699  	buf := new(bytes.Buffer)
   700  	var w io.Writer = buf
   701  	b.SetBytes(4 * 1000)
   702  	b.ResetTimer()
   703  	for i := 0; i < b.N; i++ {
   704  		buf.Reset()
   705  		Write(w, BigEndian, slice)
   706  	}
   707  	b.StopTimer()
   708  }