...

Source file src/encoding/binary/binary_test.go

Documentation: encoding/binary

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

View as plain text