libgo: Merge to master revision 19184.
[official-gcc.git] / libgo / go / encoding / binary / binary_test.go
blob1aa6ecd2486ba007cd565209e49bbd05928bff70
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.
5 package binary
7 import (
8 "bytes"
9 "io"
10 "math"
11 "reflect"
12 "strings"
13 "testing"
16 type Struct struct {
17 Int8 int8
18 Int16 int16
19 Int32 int32
20 Int64 int64
21 Uint8 uint8
22 Uint16 uint16
23 Uint32 uint32
24 Uint64 uint64
25 Float32 float32
26 Float64 float64
27 Complex64 complex64
28 Complex128 complex128
29 Array [4]uint8
32 type T struct {
33 Int int
34 Uint uint
35 Uintptr uintptr
36 Array [4]int
39 var s = Struct{
40 0x01,
41 0x0203,
42 0x04050607,
43 0x08090a0b0c0d0e0f,
44 0x10,
45 0x1112,
46 0x13141516,
47 0x1718191a1b1c1d1e,
49 math.Float32frombits(0x1f202122),
50 math.Float64frombits(0x232425262728292a),
51 complex(
52 math.Float32frombits(0x2b2c2d2e),
53 math.Float32frombits(0x2f303132),
55 complex(
56 math.Float64frombits(0x333435363738393a),
57 math.Float64frombits(0x3b3c3d3e3f404142),
60 [4]uint8{0x43, 0x44, 0x45, 0x46},
63 var big = []byte{
65 2, 3,
66 4, 5, 6, 7,
67 8, 9, 10, 11, 12, 13, 14, 15,
68 16,
69 17, 18,
70 19, 20, 21, 22,
71 23, 24, 25, 26, 27, 28, 29, 30,
73 31, 32, 33, 34,
74 35, 36, 37, 38, 39, 40, 41, 42,
75 43, 44, 45, 46, 47, 48, 49, 50,
76 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
78 67, 68, 69, 70,
81 var little = []byte{
83 3, 2,
84 7, 6, 5, 4,
85 15, 14, 13, 12, 11, 10, 9, 8,
86 16,
87 18, 17,
88 22, 21, 20, 19,
89 30, 29, 28, 27, 26, 25, 24, 23,
91 34, 33, 32, 31,
92 42, 41, 40, 39, 38, 37, 36, 35,
93 46, 45, 44, 43, 50, 49, 48, 47,
94 58, 57, 56, 55, 54, 53, 52, 51, 66, 65, 64, 63, 62, 61, 60, 59,
96 67, 68, 69, 70,
99 var src = []byte{1, 2, 3, 4, 5, 6, 7, 8}
100 var res = []int32{0x01020304, 0x05060708}
102 func checkResult(t *testing.T, dir string, order ByteOrder, err error, have, want interface{}) {
103 if err != nil {
104 t.Errorf("%v %v: %v", dir, order, err)
105 return
107 if !reflect.DeepEqual(have, want) {
108 t.Errorf("%v %v:\n\thave %+v\n\twant %+v", dir, order, have, want)
112 func testRead(t *testing.T, order ByteOrder, b []byte, s1 interface{}) {
113 var s2 Struct
114 err := Read(bytes.NewReader(b), order, &s2)
115 checkResult(t, "Read", order, err, s2, s1)
118 func testWrite(t *testing.T, order ByteOrder, b []byte, s1 interface{}) {
119 buf := new(bytes.Buffer)
120 err := Write(buf, order, s1)
121 checkResult(t, "Write", order, err, buf.Bytes(), b)
124 func TestLittleEndianRead(t *testing.T) { testRead(t, LittleEndian, little, s) }
125 func TestLittleEndianWrite(t *testing.T) { testWrite(t, LittleEndian, little, s) }
126 func TestLittleEndianPtrWrite(t *testing.T) { testWrite(t, LittleEndian, little, &s) }
128 func TestBigEndianRead(t *testing.T) { testRead(t, BigEndian, big, s) }
129 func TestBigEndianWrite(t *testing.T) { testWrite(t, BigEndian, big, s) }
130 func TestBigEndianPtrWrite(t *testing.T) { testWrite(t, BigEndian, big, &s) }
132 func TestReadSlice(t *testing.T) {
133 slice := make([]int32, 2)
134 err := Read(bytes.NewReader(src), BigEndian, slice)
135 checkResult(t, "ReadSlice", BigEndian, err, slice, res)
138 func TestWriteSlice(t *testing.T) {
139 buf := new(bytes.Buffer)
140 err := Write(buf, BigEndian, res)
141 checkResult(t, "WriteSlice", BigEndian, err, buf.Bytes(), src)
144 // Addresses of arrays are easier to manipulate with reflection than are slices.
145 var intArrays = []interface{}{
146 &[100]int8{},
147 &[100]int16{},
148 &[100]int32{},
149 &[100]int64{},
150 &[100]uint8{},
151 &[100]uint16{},
152 &[100]uint32{},
153 &[100]uint64{},
156 func TestSliceRoundTrip(t *testing.T) {
157 buf := new(bytes.Buffer)
158 for _, array := range intArrays {
159 src := reflect.ValueOf(array).Elem()
160 unsigned := false
161 switch src.Index(0).Kind() {
162 case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
163 unsigned = true
165 for i := 0; i < src.Len(); i++ {
166 if unsigned {
167 src.Index(i).SetUint(uint64(i * 0x07654321))
168 } else {
169 src.Index(i).SetInt(int64(i * 0x07654321))
172 buf.Reset()
173 srcSlice := src.Slice(0, src.Len())
174 err := Write(buf, BigEndian, srcSlice.Interface())
175 if err != nil {
176 t.Fatal(err)
178 dst := reflect.New(src.Type()).Elem()
179 dstSlice := dst.Slice(0, dst.Len())
180 err = Read(buf, BigEndian, dstSlice.Interface())
181 if err != nil {
182 t.Fatal(err)
184 if !reflect.DeepEqual(src.Interface(), dst.Interface()) {
185 t.Fatal(src)
190 func TestWriteT(t *testing.T) {
191 buf := new(bytes.Buffer)
192 ts := T{}
193 if err := Write(buf, BigEndian, ts); err == nil {
194 t.Errorf("WriteT: have err == nil, want non-nil")
197 tv := reflect.Indirect(reflect.ValueOf(ts))
198 for i, n := 0, tv.NumField(); i < n; i++ {
199 typ := tv.Field(i).Type().String()
200 if typ == "[4]int" {
201 typ = "int" // the problem is int, not the [4]
203 if err := Write(buf, BigEndian, tv.Field(i).Interface()); err == nil {
204 t.Errorf("WriteT.%v: have err == nil, want non-nil", tv.Field(i).Type())
205 } else if !strings.Contains(err.Error(), typ) {
206 t.Errorf("WriteT: have err == %q, want it to mention %s", err, typ)
211 type BlankFields struct {
212 A uint32
213 _ int32
214 B float64
215 _ [4]int16
216 C byte
217 _ [7]byte
218 _ struct {
219 f [8]float32
223 type BlankFieldsProbe struct {
224 A uint32
225 P0 int32
226 B float64
227 P1 [4]int16
228 C byte
229 P2 [7]byte
230 P3 struct {
231 F [8]float32
235 func TestBlankFields(t *testing.T) {
236 buf := new(bytes.Buffer)
237 b1 := BlankFields{A: 1234567890, B: 2.718281828, C: 42}
238 if err := Write(buf, LittleEndian, &b1); err != nil {
239 t.Error(err)
242 // zero values must have been written for blank fields
243 var p BlankFieldsProbe
244 if err := Read(buf, LittleEndian, &p); err != nil {
245 t.Error(err)
248 // quick test: only check first value of slices
249 if p.P0 != 0 || p.P1[0] != 0 || p.P2[0] != 0 || p.P3.F[0] != 0 {
250 t.Errorf("non-zero values for originally blank fields: %#v", p)
253 // write p and see if we can probe only some fields
254 if err := Write(buf, LittleEndian, &p); err != nil {
255 t.Error(err)
258 // read should ignore blank fields in b2
259 var b2 BlankFields
260 if err := Read(buf, LittleEndian, &b2); err != nil {
261 t.Error(err)
263 if b1.A != b2.A || b1.B != b2.B || b1.C != b2.C {
264 t.Errorf("%#v != %#v", b1, b2)
268 type byteSliceReader struct {
269 remain []byte
272 func (br *byteSliceReader) Read(p []byte) (int, error) {
273 n := copy(p, br.remain)
274 br.remain = br.remain[n:]
275 return n, nil
278 func BenchmarkReadSlice1000Int32s(b *testing.B) {
279 bsr := &byteSliceReader{}
280 slice := make([]int32, 1000)
281 buf := make([]byte, len(slice)*4)
282 b.SetBytes(int64(len(buf)))
283 b.ResetTimer()
284 for i := 0; i < b.N; i++ {
285 bsr.remain = buf
286 Read(bsr, BigEndian, slice)
290 func BenchmarkReadStruct(b *testing.B) {
291 bsr := &byteSliceReader{}
292 var buf bytes.Buffer
293 Write(&buf, BigEndian, &s)
294 n, _ := dataSize(reflect.ValueOf(s))
295 b.SetBytes(int64(n))
296 t := s
297 b.ResetTimer()
298 for i := 0; i < b.N; i++ {
299 bsr.remain = buf.Bytes()
300 Read(bsr, BigEndian, &t)
302 b.StopTimer()
303 if !reflect.DeepEqual(s, t) {
304 b.Fatal("no match")
308 func BenchmarkReadInts(b *testing.B) {
309 var ls Struct
310 bsr := &byteSliceReader{}
311 var r io.Reader = bsr
312 b.SetBytes(2 * (1 + 2 + 4 + 8))
313 b.ResetTimer()
314 for i := 0; i < b.N; i++ {
315 bsr.remain = big
316 Read(r, BigEndian, &ls.Int8)
317 Read(r, BigEndian, &ls.Int16)
318 Read(r, BigEndian, &ls.Int32)
319 Read(r, BigEndian, &ls.Int64)
320 Read(r, BigEndian, &ls.Uint8)
321 Read(r, BigEndian, &ls.Uint16)
322 Read(r, BigEndian, &ls.Uint32)
323 Read(r, BigEndian, &ls.Uint64)
326 want := s
327 want.Float32 = 0
328 want.Float64 = 0
329 want.Complex64 = 0
330 want.Complex128 = 0
331 for i := range want.Array {
332 want.Array[i] = 0
334 b.StopTimer()
335 if !reflect.DeepEqual(ls, want) {
336 panic("no match")
340 func BenchmarkWriteInts(b *testing.B) {
341 buf := new(bytes.Buffer)
342 var w io.Writer = buf
343 b.SetBytes(2 * (1 + 2 + 4 + 8))
344 b.ResetTimer()
345 for i := 0; i < b.N; i++ {
346 buf.Reset()
347 Write(w, BigEndian, s.Int8)
348 Write(w, BigEndian, s.Int16)
349 Write(w, BigEndian, s.Int32)
350 Write(w, BigEndian, s.Int64)
351 Write(w, BigEndian, s.Uint8)
352 Write(w, BigEndian, s.Uint16)
353 Write(w, BigEndian, s.Uint32)
354 Write(w, BigEndian, s.Uint64)
356 b.StopTimer()
357 if !bytes.Equal(buf.Bytes(), big[:30]) {
358 b.Fatalf("first half doesn't match: %x %x", buf.Bytes(), big[:30])
362 func BenchmarkWriteSlice1000Int32s(b *testing.B) {
363 slice := make([]int32, 1000)
364 buf := new(bytes.Buffer)
365 var w io.Writer = buf
366 b.SetBytes(4 * 1000)
367 b.ResetTimer()
368 for i := 0; i < b.N; i++ {
369 buf.Reset()
370 Write(w, BigEndian, slice)
372 b.StopTimer()