github.com/davecgh/go-xdr@v0.0.0-20161123171359-e6a2ba005892/xdr2/decode_test.go (about)

     1  /*
     2   * Copyright (c) 2012-2014 Dave Collins <dave@davec.name>
     3   *
     4   * Permission to use, copy, modify, and distribute this software for any
     5   * purpose with or without fee is hereby granted, provided that the above
     6   * copyright notice and this permission notice appear in all copies.
     7   *
     8   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     9   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    10   * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    11   * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    12   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    13   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    14   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    15   */
    16  
    17  package xdr_test
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"math"
    23  	"reflect"
    24  	"testing"
    25  	"time"
    26  
    27  	. "github.com/davecgh/go-xdr/xdr2"
    28  )
    29  
    30  // subTest is used to allow testing of the Unmarshal function into struct fields
    31  // which are structs themselves.
    32  type subTest struct {
    33  	A string
    34  	B uint8
    35  }
    36  
    37  // allTypesTest is used to allow testing of the Unmarshal function into struct
    38  // fields of all supported types.
    39  type allTypesTest struct {
    40  	A int8
    41  	B uint8
    42  	C int16
    43  	D uint16
    44  	E int32
    45  	F uint32
    46  	G int64
    47  	H uint64
    48  	I bool
    49  	J float32
    50  	K float64
    51  	L string
    52  	M []byte
    53  	N [3]byte
    54  	O []int16
    55  	P [2]subTest
    56  	Q *subTest
    57  	R map[string]uint32
    58  	S time.Time
    59  }
    60  
    61  // opaqueStruct is used to test handling of uint8 slices and arrays.
    62  type opaqueStruct struct {
    63  	Slice []uint8  `xdropaque:"false"`
    64  	Array [1]uint8 `xdropaque:"false"`
    65  }
    66  
    67  // testExpectedURet is a convenience method to test an expected number of bytes
    68  // read and error for an unmarshal.
    69  func testExpectedURet(t *testing.T, name string, n, wantN int, err, wantErr error) bool {
    70  	// First ensure the number of bytes read is the expected value.  The
    71  	// byes read should be accurate even when an error occurs.
    72  	if n != wantN {
    73  		t.Errorf("%s: unexpected num bytes read - got: %v want: %v\n",
    74  			name, n, wantN)
    75  		return false
    76  	}
    77  
    78  	// Next check for the expected error.
    79  	if reflect.TypeOf(err) != reflect.TypeOf(wantErr) {
    80  		t.Errorf("%s: failed to detect error - got: %v <%[2]T> want: %T",
    81  			name, err, wantErr)
    82  		return false
    83  	}
    84  	if rerr, ok := err.(*UnmarshalError); ok {
    85  		if werr, ok := wantErr.(*UnmarshalError); ok {
    86  			if rerr.ErrorCode != werr.ErrorCode {
    87  				t.Errorf("%s: failed to detect error code - "+
    88  					"got: %v want: %v", name,
    89  					rerr.ErrorCode, werr.ErrorCode)
    90  				return false
    91  			}
    92  		}
    93  	}
    94  
    95  	return true
    96  }
    97  
    98  // TestUnmarshal ensures the Unmarshal function works properly with all types.
    99  func TestUnmarshal(t *testing.T) {
   100  	// Variables for various unsupported Unmarshal types.
   101  	var nilInterface interface{}
   102  	var testChan chan int
   103  	var testFunc func()
   104  	var testComplex64 complex64
   105  	var testComplex128 complex128
   106  
   107  	// structTestIn is input data for the big struct test of all supported
   108  	// types.
   109  	structTestIn := []byte{
   110  		0x00, 0x00, 0x00, 0x7F, // A
   111  		0x00, 0x00, 0x00, 0xFF, // B
   112  		0x00, 0x00, 0x7F, 0xFF, // C
   113  		0x00, 0x00, 0xFF, 0xFF, // D
   114  		0x7F, 0xFF, 0xFF, 0xFF, // E
   115  		0xFF, 0xFF, 0xFF, 0xFF, // F
   116  		0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // G
   117  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // H
   118  		0x00, 0x00, 0x00, 0x01, // I
   119  		0x40, 0x48, 0xF5, 0xC3, // J
   120  		0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18, // K
   121  		0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00, // L
   122  		0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, // M
   123  		0x01, 0x02, 0x03, 0x00, // N
   124  		0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00,
   125  		0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, // O
   126  		0x00, 0x00, 0x00, 0x03, 0x6F, 0x6E, 0x65, 0x00, // P[0].A
   127  		0x00, 0x00, 0x00, 0x01, // P[0].B
   128  		0x00, 0x00, 0x00, 0x03, 0x74, 0x77, 0x6F, 0x00, // P[1].A
   129  		0x00, 0x00, 0x00, 0x02, // P[1].B
   130  		0x00, 0x00, 0x00, 0x03, 0x62, 0x61, 0x72, 0x00, // Q.A
   131  		0x00, 0x00, 0x00, 0x03, // Q.B
   132  		0x00, 0x00, 0x00, 0x02, // R length
   133  		0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x31, // R key map1
   134  		0x00, 0x00, 0x00, 0x01, // R value map1
   135  		0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x32, // R key map2
   136  		0x00, 0x00, 0x00, 0x02, // R value map2
   137  		0x00, 0x00, 0x00, 0x14, 0x32, 0x30, 0x31, 0x34,
   138  		0x2d, 0x30, 0x34, 0x2d, 0x30, 0x34, 0x54, 0x30,
   139  		0x33, 0x3a, 0x32, 0x34, 0x3a, 0x34, 0x38, 0x5a, // S
   140  	}
   141  
   142  	// structTestWant is the expected output after unmarshalling
   143  	// structTestIn.
   144  	structTestWant := allTypesTest{
   145  		127,                                     // A
   146  		255,                                     // B
   147  		32767,                                   // C
   148  		65535,                                   // D
   149  		2147483647,                              // E
   150  		4294967295,                              // F
   151  		9223372036854775807,                     // G
   152  		18446744073709551615,                    // H
   153  		true,                                    // I
   154  		3.14,                                    // J
   155  		3.141592653589793,                       // K
   156  		"xdr",                                   // L
   157  		[]byte{1, 2, 3, 4},                      // M
   158  		[3]byte{1, 2, 3},                        // N
   159  		[]int16{512, 1024, 2048},                // O
   160  		[2]subTest{{"one", 1}, {"two", 2}},      // P
   161  		&subTest{"bar", 3},                      // Q
   162  		map[string]uint32{"map1": 1, "map2": 2}, // R
   163  		time.Unix(1396581888, 0).UTC(),          // S
   164  	}
   165  
   166  	tests := []struct {
   167  		in      []byte      // input bytes
   168  		wantVal interface{} // expected value
   169  		wantN   int         // expected number of bytes read
   170  		err     error       // expected error
   171  	}{
   172  		// int8 - XDR Integer
   173  		{[]byte{0x00, 0x00, 0x00, 0x00}, int8(0), 4, nil},
   174  		{[]byte{0x00, 0x00, 0x00, 0x40}, int8(64), 4, nil},
   175  		{[]byte{0x00, 0x00, 0x00, 0x7F}, int8(127), 4, nil},
   176  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF}, int8(-1), 4, nil},
   177  		{[]byte{0xFF, 0xFF, 0xFF, 0x80}, int8(-128), 4, nil},
   178  		// Expected Failures -- 128, -129 overflow int8 and not enough
   179  		// bytes
   180  		{[]byte{0x00, 0x00, 0x00, 0x80}, int8(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   181  		{[]byte{0xFF, 0xFF, 0xFF, 0x7F}, int8(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   182  		{[]byte{0x00, 0x00, 0x00}, int8(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   183  
   184  		// uint8 - XDR Unsigned Integer
   185  		{[]byte{0x00, 0x00, 0x00, 0x00}, uint8(0), 4, nil},
   186  		{[]byte{0x00, 0x00, 0x00, 0x40}, uint8(64), 4, nil},
   187  		{[]byte{0x00, 0x00, 0x00, 0xFF}, uint8(255), 4, nil},
   188  		// Expected Failures -- 256, -1 overflow uint8 and not enough
   189  		// bytes
   190  		{[]byte{0x00, 0x00, 0x01, 0x00}, uint8(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   191  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF}, uint8(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   192  		{[]byte{0x00, 0x00, 0x00}, uint8(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   193  
   194  		// int16 - XDR Integer
   195  		{[]byte{0x00, 0x00, 0x00, 0x00}, int16(0), 4, nil},
   196  		{[]byte{0x00, 0x00, 0x04, 0x00}, int16(1024), 4, nil},
   197  		{[]byte{0x00, 0x00, 0x7F, 0xFF}, int16(32767), 4, nil},
   198  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF}, int16(-1), 4, nil},
   199  		{[]byte{0xFF, 0xFF, 0x80, 0x00}, int16(-32768), 4, nil},
   200  		// Expected Failures -- 32768, -32769 overflow int16 and not
   201  		// enough bytes
   202  		{[]byte{0x00, 0x00, 0x80, 0x00}, int16(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   203  		{[]byte{0xFF, 0xFF, 0x7F, 0xFF}, int16(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   204  		{[]byte{0x00, 0x00, 0x00}, uint16(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   205  
   206  		// uint16 - XDR Unsigned Integer
   207  		{[]byte{0x00, 0x00, 0x00, 0x00}, uint16(0), 4, nil},
   208  		{[]byte{0x00, 0x00, 0x04, 0x00}, uint16(1024), 4, nil},
   209  		{[]byte{0x00, 0x00, 0xFF, 0xFF}, uint16(65535), 4, nil},
   210  		// Expected Failures -- 65536, -1 overflow uint16 and not enough
   211  		// bytes
   212  		{[]byte{0x00, 0x01, 0x00, 0x00}, uint16(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   213  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF}, uint16(0), 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   214  		{[]byte{0x00, 0x00, 0x00}, uint16(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   215  
   216  		// int32 - XDR Integer
   217  		{[]byte{0x00, 0x00, 0x00, 0x00}, int32(0), 4, nil},
   218  		{[]byte{0x00, 0x04, 0x00, 0x00}, int32(262144), 4, nil},
   219  		{[]byte{0x7F, 0xFF, 0xFF, 0xFF}, int32(2147483647), 4, nil},
   220  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF}, int32(-1), 4, nil},
   221  		{[]byte{0x80, 0x00, 0x00, 0x00}, int32(-2147483648), 4, nil},
   222  		// Expected Failure -- not enough bytes
   223  		{[]byte{0x00, 0x00, 0x00}, int32(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   224  
   225  		// uint32 - XDR Unsigned Integer
   226  		{[]byte{0x00, 0x00, 0x00, 0x00}, uint32(0), 4, nil},
   227  		{[]byte{0x00, 0x04, 0x00, 0x00}, uint32(262144), 4, nil},
   228  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF}, uint32(4294967295), 4, nil},
   229  		// Expected Failure -- not enough bytes
   230  		{[]byte{0x00, 0x00, 0x00}, uint32(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   231  
   232  		// int64 - XDR Hyper Integer
   233  		{[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(0), 8, nil},
   234  		{[]byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, int64(1 << 34), 8, nil},
   235  		{[]byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(1 << 42), 8, nil},
   236  		{[]byte{0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(9223372036854775807), 8, nil},
   237  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(-1), 8, nil},
   238  		{[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(-9223372036854775808), 8, nil},
   239  		// Expected Failures -- not enough bytes
   240  		{[]byte{0x7f, 0xff, 0xff}, int64(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   241  		{[]byte{0x7f, 0x00, 0xff, 0x00}, int64(0), 4, &UnmarshalError{ErrorCode: ErrIO}},
   242  
   243  		// uint64 - XDR Unsigned Hyper Integer
   244  		{[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(0), 8, nil},
   245  		{[]byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 34), 8, nil},
   246  		{[]byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 42), 8, nil},
   247  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, uint64(18446744073709551615), 8, nil},
   248  		{[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(9223372036854775808), 8, nil},
   249  		// Expected Failures -- not enough bytes
   250  		{[]byte{0xff, 0xff, 0xff}, uint64(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   251  		{[]byte{0xff, 0x00, 0xff, 0x00}, uint64(0), 4, &UnmarshalError{ErrorCode: ErrIO}},
   252  
   253  		// bool - XDR Integer
   254  		{[]byte{0x00, 0x00, 0x00, 0x00}, false, 4, nil},
   255  		{[]byte{0x00, 0x00, 0x00, 0x01}, true, 4, nil},
   256  		// Expected Failures -- only 0 or 1 is a valid bool
   257  		{[]byte{0x01, 0x00, 0x00, 0x00}, true, 4, &UnmarshalError{ErrorCode: ErrBadEnumValue}},
   258  		{[]byte{0x00, 0x00, 0x40, 0x00}, true, 4, &UnmarshalError{ErrorCode: ErrBadEnumValue}},
   259  
   260  		// float32 - XDR Floating-Point
   261  		{[]byte{0x00, 0x00, 0x00, 0x00}, float32(0), 4, nil},
   262  		{[]byte{0x40, 0x48, 0xF5, 0xC3}, float32(3.14), 4, nil},
   263  		{[]byte{0x49, 0x96, 0xB4, 0x38}, float32(1234567.0), 4, nil},
   264  		{[]byte{0xFF, 0x80, 0x00, 0x00}, float32(math.Inf(-1)), 4, nil},
   265  		{[]byte{0x7F, 0x80, 0x00, 0x00}, float32(math.Inf(0)), 4, nil},
   266  		// Expected Failures -- not enough bytes
   267  		{[]byte{0xff, 0xff}, float32(0), 2, &UnmarshalError{ErrorCode: ErrIO}},
   268  		{[]byte{0xff, 0x00, 0xff}, float32(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   269  
   270  		// float64 - XDR Double-precision Floating-Point
   271  		{[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(0), 8, nil},
   272  		{[]byte{0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18}, float64(3.141592653589793), 8, nil},
   273  		{[]byte{0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(-1)), 8, nil},
   274  		{[]byte{0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(0)), 8, nil},
   275  		// Expected Failures -- not enough bytes
   276  		{[]byte{0xff, 0xff, 0xff}, float64(0), 3, &UnmarshalError{ErrorCode: ErrIO}},
   277  		{[]byte{0xff, 0x00, 0xff, 0x00}, float64(0), 4, &UnmarshalError{ErrorCode: ErrIO}},
   278  
   279  		// string - XDR String
   280  		{[]byte{0x00, 0x00, 0x00, 0x00}, "", 4, nil},
   281  		{[]byte{0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00}, "xdr", 8, nil},
   282  		{[]byte{0x00, 0x00, 0x00, 0x06, 0xCF, 0x84, 0x3D, 0x32, 0xCF, 0x80, 0x00, 0x00}, "τ=2π", 12, nil},
   283  		// Expected Failures -- not enough bytes for length, length
   284  		// larger than allowed, and len larger than available bytes.
   285  		{[]byte{0x00, 0x00, 0xFF}, "", 3, &UnmarshalError{ErrorCode: ErrIO}},
   286  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF}, "", 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   287  		{[]byte{0x00, 0x00, 0x00, 0xFF}, "", 4, &UnmarshalError{ErrorCode: ErrIO}},
   288  
   289  		// []byte - XDR Variable Opaque
   290  		{[]byte{0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00}, []byte{0x01}, 8, nil},
   291  		{[]byte{0x00, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00}, []byte{0x01, 0x02, 0x03}, 8, nil},
   292  		// Expected Failures -- not enough bytes for length, length
   293  		// larger than allowed, and data larger than available bytes.
   294  		{[]byte{0x00, 0x00, 0xFF}, []byte{}, 3, &UnmarshalError{ErrorCode: ErrIO}},
   295  		{[]byte{0xFF, 0xFF, 0xFF, 0xFF}, []byte{}, 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   296  		{[]byte{0x00, 0x00, 0x00, 0xFF}, []byte{}, 4, &UnmarshalError{ErrorCode: ErrIO}},
   297  
   298  		// [#]byte - XDR Fixed Opaque
   299  		{[]byte{0x01, 0x00, 0x00, 0x00}, [1]byte{0x01}, 4, nil},
   300  		{[]byte{0x01, 0x02, 0x00, 0x00}, [2]byte{0x01, 0x02}, 4, nil},
   301  		{[]byte{0x01, 0x02, 0x03, 0x00}, [3]byte{0x01, 0x02, 0x03}, 4, nil},
   302  		{[]byte{0x01, 0x02, 0x03, 0x04}, [4]byte{0x01, 0x02, 0x03, 0x04}, 4, nil},
   303  		{[]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00, 0x00}, [5]byte{0x01, 0x02, 0x03, 0x04, 0x05}, 8, nil},
   304  		// Expected Failure -- fixed opaque data not padded
   305  		{[]byte{0x01}, [1]byte{}, 1, &UnmarshalError{ErrorCode: ErrIO}},
   306  
   307  		// []<type> - XDR Variable-Length Array
   308  		{[]byte{0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00},
   309  			[]int16{512, 1024, 2048}, 16, nil},
   310  		{[]byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}, []bool{true, false}, 12, nil},
   311  		// Expected Failure -- 2 entries in array - not enough bytes
   312  		{[]byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01}, []bool{}, 8, &UnmarshalError{ErrorCode: ErrIO}},
   313  
   314  		// [#]<type> - XDR Fixed-Length Array
   315  		{[]byte{0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00}, [2]uint32{512, 1024}, 8, nil},
   316  		// Expected Failure -- 2 entries in array - not enough bytes
   317  		{[]byte{0x00, 0x00, 0x00, 0x02}, [2]uint32{}, 4, &UnmarshalError{ErrorCode: ErrIO}},
   318  
   319  		// map[string]uint32
   320  		{[]byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x31, 0x00, 0x00, 0x00, 0x01},
   321  			map[string]uint32{"map1": 1}, 16, nil},
   322  		// Expected Failures -- not enough bytes in length, 1 map
   323  		// element no extra bytes, 1 map element not enough bytes for
   324  		// key, 1 map element not enough bytes for value.
   325  		{[]byte{0x00, 0x00, 0x00}, map[string]uint32{}, 3, &UnmarshalError{ErrorCode: ErrIO}},
   326  		{[]byte{0x00, 0x00, 0x00, 0x01}, map[string]uint32{}, 4, &UnmarshalError{ErrorCode: ErrIO}},
   327  		{[]byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}, map[string]uint32{}, 7, &UnmarshalError{ErrorCode: ErrIO}},
   328  		{[]byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x31},
   329  			map[string]uint32{}, 12, &UnmarshalError{ErrorCode: ErrIO}},
   330  
   331  		// time.Time - XDR String per RFC3339
   332  		{[]byte{
   333  			0x00, 0x00, 0x00, 0x14, 0x32, 0x30, 0x31, 0x34,
   334  			0x2d, 0x30, 0x34, 0x2d, 0x30, 0x34, 0x54, 0x30,
   335  			0x33, 0x3a, 0x32, 0x34, 0x3a, 0x34, 0x38, 0x5a,
   336  		}, time.Unix(1396581888, 0).UTC(), 24, nil},
   337  		// Expected Failures -- not enough bytes, improperly formatted
   338  		// time
   339  		{[]byte{0x00, 0x00, 0x00}, time.Time{}, 3, &UnmarshalError{ErrorCode: ErrIO}},
   340  		{[]byte{0x00, 0x00, 0x00, 0x00}, time.Time{}, 4, &UnmarshalError{ErrorCode: ErrParseTime}},
   341  
   342  		// struct - XDR Structure -- test struct contains all supported types
   343  		{structTestIn, structTestWant, len(structTestIn), nil},
   344  		{[]byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02},
   345  			opaqueStruct{[]uint8{1}, [1]uint8{2}}, 12, nil},
   346  		// Expected Failures -- normal struct not enough bytes, non
   347  		// opaque data not enough bytes for slice, non opaque data not
   348  		// enough bytes for slice.
   349  		{[]byte{0x00, 0x00}, allTypesTest{}, 2, &UnmarshalError{ErrorCode: ErrIO}},
   350  		{[]byte{0x00, 0x00, 0x00}, opaqueStruct{}, 3, &UnmarshalError{ErrorCode: ErrIO}},
   351  		{[]byte{0x00, 0x00, 0x00, 0x00, 0x00}, opaqueStruct{}, 5, &UnmarshalError{ErrorCode: ErrIO}},
   352  
   353  		// Expected errors
   354  		{nil, nilInterface, 0, &UnmarshalError{ErrorCode: ErrNilInterface}},
   355  		{nil, &nilInterface, 0, &UnmarshalError{ErrorCode: ErrNilInterface}},
   356  		{nil, testChan, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}},
   357  		{nil, &testChan, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}},
   358  		{nil, testFunc, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}},
   359  		{nil, &testFunc, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}},
   360  		{nil, testComplex64, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}},
   361  		{nil, &testComplex64, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}},
   362  		{nil, testComplex128, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}},
   363  		{nil, &testComplex128, 0, &UnmarshalError{ErrorCode: ErrUnsupportedType}},
   364  	}
   365  
   366  	for i, test := range tests {
   367  		// Attempt to unmarshal to a non-pointer version of each
   368  		// positive test type to ensure the appropriate error is
   369  		// returned.
   370  		if test.err == nil && test.wantVal != nil {
   371  			testName := fmt.Sprintf("Unmarshal #%d (non-pointer)", i)
   372  			wantErr := &UnmarshalError{ErrorCode: ErrBadArguments}
   373  
   374  			wvt := reflect.TypeOf(test.wantVal)
   375  			want := reflect.New(wvt).Elem().Interface()
   376  			n, err := Unmarshal(bytes.NewReader(test.in), want)
   377  			if !testExpectedURet(t, testName, n, 0, err, wantErr) {
   378  				continue
   379  			}
   380  		}
   381  
   382  		testName := fmt.Sprintf("Unmarshal #%d", i)
   383  		// Create a new pointer to the appropriate type.
   384  		var want interface{}
   385  		if test.wantVal != nil {
   386  			wvt := reflect.TypeOf(test.wantVal)
   387  			want = reflect.New(wvt).Interface()
   388  		}
   389  		n, err := Unmarshal(bytes.NewReader(test.in), want)
   390  
   391  		// First ensure the number of bytes read is the expected value
   392  		// and the error is the expected one.
   393  		if !testExpectedURet(t, testName, n, test.wantN, err, test.err) {
   394  			continue
   395  		}
   396  		if test.err != nil {
   397  			continue
   398  		}
   399  
   400  		// Finally, ensure the read value is the expected one.
   401  		wantElem := reflect.Indirect(reflect.ValueOf(want)).Interface()
   402  		if !reflect.DeepEqual(wantElem, test.wantVal) {
   403  			t.Errorf("%s: unexpected result - got: %v want: %v\n",
   404  				testName, wantElem, test.wantVal)
   405  			continue
   406  		}
   407  	}
   408  }
   409  
   410  // decodeFunc is used to identify which public function of the Decoder object
   411  // a test applies to.
   412  type decodeFunc int
   413  
   414  const (
   415  	fDecodeBool decodeFunc = iota
   416  	fDecodeDouble
   417  	fDecodeEnum
   418  	fDecodeFixedOpaque
   419  	fDecodeFloat
   420  	fDecodeHyper
   421  	fDecodeInt
   422  	fDecodeOpaque
   423  	fDecodeString
   424  	fDecodeUhyper
   425  	fDecodeUint
   426  )
   427  
   428  // Map of decodeFunc values to names for pretty printing.
   429  var decodeFuncStrings = map[decodeFunc]string{
   430  	fDecodeBool:        "DecodeBool",
   431  	fDecodeDouble:      "DecodeDouble",
   432  	fDecodeEnum:        "DecodeEnum",
   433  	fDecodeFixedOpaque: "DecodeFixedOpaque",
   434  	fDecodeFloat:       "DecodeFloat",
   435  	fDecodeHyper:       "DecodeHyper",
   436  	fDecodeInt:         "DecodeInt",
   437  	fDecodeOpaque:      "DecodeOpaque",
   438  	fDecodeString:      "DecodeString",
   439  	fDecodeUhyper:      "DecodeUhyper",
   440  	fDecodeUint:        "DecodeUint",
   441  }
   442  
   443  // String implements the fmt.Stringer interface and returns the encode function
   444  // as a human-readable string.
   445  func (f decodeFunc) String() string {
   446  	if s := decodeFuncStrings[f]; s != "" {
   447  		return s
   448  	}
   449  	return fmt.Sprintf("Unknown decodeFunc (%d)", f)
   450  }
   451  
   452  // TestDecoder ensures a Decoder works as intended.
   453  func TestDecoder(t *testing.T) {
   454  	type test struct {
   455  		f       decodeFunc  // function to use to decode
   456  		in      []byte      // input bytes
   457  		wantVal interface{} // expected value
   458  		wantN   int         // expected number of bytes read
   459  		maxSize uint        // read limiter value
   460  		err     error       // expected error
   461  	}
   462  	tests := []test{
   463  		// Bool
   464  		{fDecodeBool, []byte{0x00, 0x00, 0x00, 0x00}, false, 4, 0, nil},
   465  		{fDecodeBool, []byte{0x00, 0x00, 0x00, 0x01}, true, 4, 0, nil},
   466  		// Expected Failures -- only 0 or 1 is a valid bool
   467  		{fDecodeBool, []byte{0x01, 0x00, 0x00, 0x00}, true, 4, 0, &UnmarshalError{ErrorCode: ErrBadEnumValue}},
   468  		{fDecodeBool, []byte{0x00, 0x00, 0x40, 0x00}, true, 4, 0, &UnmarshalError{ErrorCode: ErrBadEnumValue}},
   469  
   470  		// Double
   471  		{fDecodeDouble, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(0), 8, 0, nil},
   472  		{fDecodeDouble, []byte{0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18}, float64(3.141592653589793), 8, 0, nil},
   473  		{fDecodeDouble, []byte{0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(-1)), 8, 0, nil},
   474  		{fDecodeDouble, []byte{0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(0)), 8, 0, nil},
   475  
   476  		// Enum
   477  		{fDecodeEnum, []byte{0x00, 0x00, 0x00, 0x00}, int32(0), 4, 0, nil},
   478  		{fDecodeEnum, []byte{0x00, 0x00, 0x00, 0x01}, int32(1), 4, 0, nil},
   479  		{fDecodeEnum, []byte{0x00, 0x00, 0x00, 0x02}, nil, 4, 0, &UnmarshalError{ErrorCode: ErrBadEnumValue}},
   480  		{fDecodeEnum, []byte{0x12, 0x34, 0x56, 0x78}, nil, 4, 0, &UnmarshalError{ErrorCode: ErrBadEnumValue}},
   481  		{fDecodeEnum, []byte{0x00}, nil, 1, 0, &UnmarshalError{ErrorCode: ErrIO}},
   482  
   483  		// FixedOpaque
   484  		{fDecodeFixedOpaque, []byte{0x01, 0x00, 0x00, 0x00}, []byte{0x01}, 4, 0, nil},
   485  		{fDecodeFixedOpaque, []byte{0x01, 0x02, 0x00, 0x00}, []byte{0x01, 0x02}, 4, 0, nil},
   486  		{fDecodeFixedOpaque, []byte{0x01, 0x02, 0x03, 0x00}, []byte{0x01, 0x02, 0x03}, 4, 0, nil},
   487  		{fDecodeFixedOpaque, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, 4, 0, nil},
   488  		{fDecodeFixedOpaque, []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00, 0x00}, []byte{0x01, 0x02, 0x03, 0x04, 0x05}, 8, 0, nil},
   489  		// Expected Failure -- fixed opaque data not padded
   490  		{fDecodeFixedOpaque, []byte{0x01}, []byte{0x00}, 1, 0, &UnmarshalError{ErrorCode: ErrIO}},
   491  
   492  		// Float
   493  		{fDecodeFloat, []byte{0x00, 0x00, 0x00, 0x00}, float32(0), 4, 0, nil},
   494  		{fDecodeFloat, []byte{0x40, 0x48, 0xF5, 0xC3}, float32(3.14), 4, 0, nil},
   495  		{fDecodeFloat, []byte{0x49, 0x96, 0xB4, 0x38}, float32(1234567.0), 4, 0, nil},
   496  		{fDecodeFloat, []byte{0xFF, 0x80, 0x00, 0x00}, float32(math.Inf(-1)), 4, 0, nil},
   497  		{fDecodeFloat, []byte{0x7F, 0x80, 0x00, 0x00}, float32(math.Inf(0)), 4, 0, nil},
   498  
   499  		// Hyper
   500  		{fDecodeHyper, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(0), 8, 0, nil},
   501  		{fDecodeHyper, []byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, int64(1 << 34), 8, 0, nil},
   502  		{fDecodeHyper, []byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(1 << 42), 8, 0, nil},
   503  		{fDecodeHyper, []byte{0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(9223372036854775807), 8, 0, nil},
   504  		{fDecodeHyper, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(-1), 8, 0, nil},
   505  		{fDecodeHyper, []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(-9223372036854775808), 8, 0, nil},
   506  
   507  		// Int
   508  		{fDecodeInt, []byte{0x00, 0x00, 0x00, 0x00}, int32(0), 4, 0, nil},
   509  		{fDecodeInt, []byte{0x00, 0x04, 0x00, 0x00}, int32(262144), 4, 0, nil},
   510  		{fDecodeInt, []byte{0x7F, 0xFF, 0xFF, 0xFF}, int32(2147483647), 4, 0, nil},
   511  		{fDecodeInt, []byte{0xFF, 0xFF, 0xFF, 0xFF}, int32(-1), 4, 0, nil},
   512  		{fDecodeInt, []byte{0x80, 0x00, 0x00, 0x00}, int32(-2147483648), 4, 0, nil},
   513  
   514  		// Opaque
   515  		{fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00}, []byte{0x01}, 8, 0, nil},
   516  		{fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00}, []byte{0x01, 0x02, 0x03}, 8, 0, nil},
   517  		// Expected Failures -- not enough bytes for length, length
   518  		// larger than allowed, and data larger than available bytes.
   519  		{fDecodeOpaque, []byte{0x00, 0x00, 0xFF}, []byte{}, 3, 0, &UnmarshalError{ErrorCode: ErrIO}},
   520  		{fDecodeOpaque, []byte{0xFF, 0xFF, 0xFF, 0xFF}, []byte{}, 4, 0, &UnmarshalError{ErrorCode: ErrOverflow}},
   521  		{fDecodeOpaque, []byte{0x7F, 0xFF, 0xFF, 0xFD}, []byte{}, 4, 0, &UnmarshalError{ErrorCode: ErrOverflow}},
   522  		{fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0xFF}, []byte{}, 4, 0, &UnmarshalError{ErrorCode: ErrIO}},
   523  		// Hit maxReadSize in opaque
   524  		{fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00}, []byte{0x01}, 8, 4, nil},
   525  		{fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00}, []byte{}, 4, 4, &UnmarshalError{ErrorCode: ErrOverflow}},
   526  
   527  		// String
   528  		{fDecodeString, []byte{0x00, 0x00, 0x00, 0x00}, "", 4, 0, nil},
   529  		{fDecodeString, []byte{0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00}, "xdr", 8, 0, nil},
   530  		{fDecodeString, []byte{0x00, 0x00, 0x00, 0x06, 0xCF, 0x84, 0x3D, 0x32, 0xCF, 0x80, 0x00, 0x00}, "τ=2π", 12, 0, nil},
   531  		// Expected Failures -- not enough bytes for length, length
   532  		// larger than allowed, and len larger than available bytes.
   533  		{fDecodeString, []byte{0x00, 0x00, 0xFF}, "", 3, 0, &UnmarshalError{ErrorCode: ErrIO}},
   534  		{fDecodeString, []byte{0xFF, 0xFF, 0xFF, 0xFF}, "", 4, 0, &UnmarshalError{ErrorCode: ErrOverflow}},
   535  		{fDecodeString, []byte{0x00, 0x00, 0x00, 0xFF}, "", 4, 0, &UnmarshalError{ErrorCode: ErrIO}},
   536  		// Hit maxReadSize in string
   537  		{fDecodeString, []byte{0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00}, "xdr", 8, 4, nil},
   538  		{fDecodeString, []byte{0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00}, "xdr", 4, 2, &UnmarshalError{ErrorCode: ErrOverflow}},
   539  
   540  		// Uhyper
   541  		{fDecodeUhyper, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(0), 8, 0, nil},
   542  		{fDecodeUhyper, []byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 34), 8, 0, nil},
   543  		{fDecodeUhyper, []byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 42), 8, 0, nil},
   544  		{fDecodeUhyper, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, uint64(18446744073709551615), 8, 0, nil},
   545  		{fDecodeUhyper, []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(9223372036854775808), 8, 0, nil},
   546  
   547  		// Uint
   548  		{fDecodeUint, []byte{0x00, 0x00, 0x00, 0x00}, uint32(0), 4, 0, nil},
   549  		{fDecodeUint, []byte{0x00, 0x04, 0x00, 0x00}, uint32(262144), 4, 0, nil},
   550  		{fDecodeUint, []byte{0xFF, 0xFF, 0xFF, 0xFF}, uint32(4294967295), 4, 0, nil},
   551  	}
   552  
   553  	validEnums := make(map[int32]bool)
   554  	validEnums[0] = true
   555  	validEnums[1] = true
   556  
   557  	var rv interface{}
   558  	var n int
   559  	var err error
   560  
   561  	decoders := []func(test) *Decoder{
   562  		func(t test) *Decoder {
   563  			// return DecoderLimited for test cases that can't succeed.
   564  			if t.maxSize == 0 {
   565  				return NewDecoder(bytes.NewReader(t.in))
   566  			}
   567  			return NewDecoderLimited(bytes.NewReader(t.in), t.maxSize)
   568  		},
   569  		func(t test) *Decoder {
   570  			return NewDecoderLimited(bytes.NewReader(t.in), t.maxSize)
   571  		},
   572  	}
   573  	for _, decoder := range decoders {
   574  		for i, test := range tests {
   575  			err = nil
   576  			var dec *Decoder
   577  			dec = decoder(test)
   578  			switch test.f {
   579  			case fDecodeBool:
   580  				rv, n, err = dec.DecodeBool()
   581  			case fDecodeDouble:
   582  				rv, n, err = dec.DecodeDouble()
   583  			case fDecodeEnum:
   584  				rv, n, err = dec.DecodeEnum(validEnums)
   585  			case fDecodeFixedOpaque:
   586  				want := test.wantVal.([]byte)
   587  				rv, n, err = dec.DecodeFixedOpaque(int32(len(want)))
   588  			case fDecodeFloat:
   589  				rv, n, err = dec.DecodeFloat()
   590  			case fDecodeHyper:
   591  				rv, n, err = dec.DecodeHyper()
   592  			case fDecodeInt:
   593  				rv, n, err = dec.DecodeInt()
   594  			case fDecodeOpaque:
   595  				rv, n, err = dec.DecodeOpaque()
   596  			case fDecodeString:
   597  				rv, n, err = dec.DecodeString()
   598  			case fDecodeUhyper:
   599  				rv, n, err = dec.DecodeUhyper()
   600  			case fDecodeUint:
   601  				rv, n, err = dec.DecodeUint()
   602  			default:
   603  				t.Errorf("%v #%d unrecognized function", test.f, i)
   604  				continue
   605  			}
   606  
   607  			// First ensure the number of bytes read is the expected value
   608  			// and the error is the expected one.
   609  			testName := fmt.Sprintf("%v #%d", test.f, i)
   610  			if !testExpectedURet(t, testName, n, test.wantN, err, test.err) {
   611  				continue
   612  			}
   613  			if test.err != nil {
   614  				continue
   615  			}
   616  
   617  			// Finally, ensure the read value is the expected one.
   618  			if !reflect.DeepEqual(rv, test.wantVal) {
   619  				t.Errorf("%s: unexpected result - got: %v want: %v\n",
   620  					testName, rv, test.wantVal)
   621  				continue
   622  			}
   623  		}
   624  	}
   625  }
   626  
   627  // TestUnmarshalLimited ensures the UnmarshalLimited function properly handles
   628  // various cases not already covered by the other tests.
   629  func TestUnmarshalLimited(t *testing.T) {
   630  	buf := []byte{
   631  		0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
   632  		0x00, 0x00, 0x00, 0x02,
   633  	}
   634  
   635  	testName := "UnmarshalLimited to capped slice"
   636  	cappedSlice := make([]bool, 0, 1)
   637  	expectedN := 8
   638  	expectedErr := error(nil)
   639  	expectedVal := []bool{true}
   640  	n, err := UnmarshalLimited(bytes.NewReader(buf), &cappedSlice, 8)
   641  	if testExpectedURet(t, testName, n, expectedN, err, expectedErr) {
   642  		if !reflect.DeepEqual(cappedSlice, expectedVal) {
   643  			t.Errorf("%s: unexpected result - got: %v want: %v\n",
   644  				testName, cappedSlice, expectedVal)
   645  		}
   646  	}
   647  
   648  	// Positive map test.
   649  	buf = []byte{
   650  		0x00, 0x00, 0x00, 0x02, // R length
   651  		0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x31, // R key map1
   652  		0x00, 0x00, 0x00, 0x01, // R value map1
   653  		0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x32, // R key map2
   654  		0x00, 0x00, 0x00, 0x02, // R value map2
   655  	}
   656  	type myMap struct {
   657  		R map[string]uint32
   658  	}
   659  	expectedMapVal := &myMap{
   660  		R: map[string]uint32{"map1": 1, "map2": 2}, // R
   661  	}
   662  	var m myMap
   663  	n, err = UnmarshalLimited(bytes.NewReader(buf), &m, 28)
   664  	expectedN = 28
   665  	if testExpectedURet(t, testName, n, expectedN, err, expectedErr) {
   666  		if !reflect.DeepEqual(&m, expectedMapVal) {
   667  			t.Errorf("%s: unexpected result - got: %v want: %v\n",
   668  				testName, m, expectedMapVal)
   669  		}
   670  	}
   671  }
   672  
   673  // TestUnmarshalCorners ensures the Unmarshal function properly handles various
   674  // cases not already covered by the other tests.
   675  func TestUnmarshalCorners(t *testing.T) {
   676  	buf := []byte{
   677  		0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
   678  		0x00, 0x00, 0x00, 0x02,
   679  	}
   680  
   681  	// Ensure unmarshal to unsettable pointer returns the expected error.
   682  	testName := "Unmarshal to unsettable pointer"
   683  	var i32p *int32
   684  	expectedN := 0
   685  	expectedErr := error(&UnmarshalError{ErrorCode: ErrNotSettable})
   686  	n, err := Unmarshal(bytes.NewReader(buf), i32p)
   687  	testExpectedURet(t, testName, n, expectedN, err, expectedErr)
   688  
   689  	// Ensure decode of unsettable pointer returns the expected error.
   690  	testName = "Decode to unsettable pointer"
   691  	expectedN = 0
   692  	expectedErr = &UnmarshalError{ErrorCode: ErrNotSettable}
   693  	n, err = TstDecode(bytes.NewReader(buf))(reflect.ValueOf(i32p))
   694  	testExpectedURet(t, testName, n, expectedN, err, expectedErr)
   695  
   696  	// Ensure unmarshal to indirected unsettable pointer returns the
   697  	// expected error.
   698  	testName = "Unmarshal to indirected unsettable pointer"
   699  	ii32p := interface{}(i32p)
   700  	expectedN = 0
   701  	expectedErr = &UnmarshalError{ErrorCode: ErrNotSettable}
   702  	n, err = Unmarshal(bytes.NewReader(buf), &ii32p)
   703  	testExpectedURet(t, testName, n, expectedN, err, expectedErr)
   704  
   705  	// Ensure unmarshal to embedded unsettable interface value returns the
   706  	// expected error.
   707  	testName = "Unmarshal to embedded unsettable interface value"
   708  	var i32 int32
   709  	ii32 := interface{}(i32)
   710  	expectedN = 0
   711  	expectedErr = &UnmarshalError{ErrorCode: ErrNotSettable}
   712  	n, err = Unmarshal(bytes.NewReader(buf), &ii32)
   713  	testExpectedURet(t, testName, n, expectedN, err, expectedErr)
   714  
   715  	// Ensure unmarshal to embedded interface value works properly.
   716  	testName = "Unmarshal to embedded interface value"
   717  	ii32vp := interface{}(&i32)
   718  	expectedN = 4
   719  	expectedErr = nil
   720  	ii32vpr := int32(1)
   721  	expectedVal := interface{}(&ii32vpr)
   722  	n, err = Unmarshal(bytes.NewReader(buf), &ii32vp)
   723  	if testExpectedURet(t, testName, n, expectedN, err, expectedErr) {
   724  		if !reflect.DeepEqual(ii32vp, expectedVal) {
   725  			t.Errorf("%s: unexpected result - got: %v want: %v\n",
   726  				testName, ii32vp, expectedVal)
   727  		}
   728  	}
   729  
   730  	// Ensure decode of an invalid reflect value returns the expected
   731  	// error.
   732  	testName = "Decode invalid reflect value"
   733  	expectedN = 0
   734  	expectedErr = error(&UnmarshalError{ErrorCode: ErrUnsupportedType})
   735  	n, err = TstDecode(bytes.NewReader(buf))(reflect.Value{})
   736  	testExpectedURet(t, testName, n, expectedN, err, expectedErr)
   737  
   738  	// Ensure unmarshal to a slice with a cap and 0 length adjusts the
   739  	// length properly.
   740  	testName = "Unmarshal to capped slice"
   741  	cappedSlice := make([]bool, 0, 1)
   742  	expectedN = 8
   743  	expectedErr = nil
   744  	expectedVal = []bool{true}
   745  	n, err = Unmarshal(bytes.NewReader(buf), &cappedSlice)
   746  	if testExpectedURet(t, testName, n, expectedN, err, expectedErr) {
   747  		if !reflect.DeepEqual(cappedSlice, expectedVal) {
   748  			t.Errorf("%s: unexpected result - got: %v want: %v\n",
   749  				testName, cappedSlice, expectedVal)
   750  		}
   751  	}
   752  
   753  	// Ensure unmarshal to struct with both exported and unexported fields
   754  	// skips the unexported fields but still unmarshals to the exported
   755  	// fields.
   756  	type unexportedStruct struct {
   757  		unexported int
   758  		Exported   int
   759  	}
   760  	testName = "Unmarshal to struct with exported and unexported fields"
   761  	var tstruct unexportedStruct
   762  	expectedN = 4
   763  	expectedErr = nil
   764  	expectedVal = unexportedStruct{0, 1}
   765  	n, err = Unmarshal(bytes.NewReader(buf), &tstruct)
   766  	if testExpectedURet(t, testName, n, expectedN, err, expectedErr) {
   767  		if !reflect.DeepEqual(tstruct, expectedVal) {
   768  			t.Errorf("%s: unexpected result - got: %v want: %v\n",
   769  				testName, tstruct, expectedVal)
   770  		}
   771  	}
   772  
   773  	// Ensure decode to struct with unsettable fields return expected error.
   774  	type unsettableStruct struct {
   775  		Exported int
   776  	}
   777  	testName = "Decode to struct with unsettable fields"
   778  	var ustruct unsettableStruct
   779  	expectedN = 0
   780  	expectedErr = error(&UnmarshalError{ErrorCode: ErrNotSettable})
   781  	n, err = TstDecode(bytes.NewReader(buf))(reflect.ValueOf(ustruct))
   782  	testExpectedURet(t, testName, n, expectedN, err, expectedErr)
   783  
   784  	// Ensure decode to struct with unsettable pointer fields return
   785  	// expected error.
   786  	type unsettablePointerStruct struct {
   787  		Exported *int
   788  	}
   789  	testName = "Decode to struct with unsettable pointer fields"
   790  	var upstruct unsettablePointerStruct
   791  	expectedN = 0
   792  	expectedErr = error(&UnmarshalError{ErrorCode: ErrNotSettable})
   793  	n, err = TstDecode(bytes.NewReader(buf))(reflect.ValueOf(upstruct))
   794  	testExpectedURet(t, testName, n, expectedN, err, expectedErr)
   795  }