github.com/stellar/go-xdr@v0.0.0-20231122183749-b53fb00bcac2/xdr/decode.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
    18  
    19  import (
    20  	"fmt"
    21  	"math"
    22  	"reflect"
    23  	"time"
    24  )
    25  
    26  const maxInt = int(^uint(0) >> 1)
    27  
    28  var errMaxSlice = "data exceeds max slice limit"
    29  var errInsufficientBytes = "insufficient bytes to decode %d bytes"
    30  var errInsufficientPad = "insufficient pad bytes to decode %d bytes"
    31  
    32  /*
    33  Unmarshal parses XDR-encoded data into the value pointed to by v.  An
    34  addressable pointer must be provided since Unmarshal needs to both store the
    35  result of the decode as well as obtain target type information.  Unmarhsal
    36  traverses v recursively and automatically indirects pointers through arbitrary
    37  depth, allocating them as necessary, to decode the data into the underlying value
    38  pointed to.
    39  
    40  Unmarshal uses reflection to determine the type of the concrete value contained
    41  by v and performs a mapping of underlying XDR types to Go types as follows:
    42  
    43  	Go Type <- XDR Type
    44  	--------------------
    45  	int8, int16, int32, int <- XDR Integer
    46  	uint8, uint16, uint32, uint <- XDR Unsigned Integer
    47  	int64 <- XDR Hyper Integer
    48  	uint64 <- XDR Unsigned Hyper Integer
    49  	bool <- XDR Boolean
    50  	float32 <- XDR Floating-Point
    51  	float64 <- XDR Double-Precision Floating-Point
    52  	string <- XDR String
    53  	byte <- XDR Integer
    54  	[]byte <- XDR Variable-Length Opaque Data
    55  	[#]byte <- XDR Fixed-Length Opaque Data
    56  	[]<type> <- XDR Variable-Length Array
    57  	[#]<type> <- XDR Fixed-Length Array
    58  	struct <- XDR Structure
    59  	map <- XDR Variable-Length Array of two-element XDR Structures
    60  	time.Time <- XDR String encoded with RFC3339 nanosecond precision
    61  
    62  Notes and Limitations:
    63  
    64    - Automatic unmarshalling of variable and fixed-length arrays of uint8s
    65      requires a special struct tag `xdropaque:"false"` since byte slices and
    66      byte arrays are assumed to be opaque data and byte is a Go alias for uint8
    67      thus indistinguishable under reflection
    68    - Cyclic data structures are not supported and will result in infinite loops
    69  
    70  If any issues are encountered during the unmarshalling process, an
    71  UnmarshalError is returned with a human readable description as well as
    72  an ErrorCode value for further inspection from sophisticated callers.  Some
    73  potential issues are unsupported Go types, attempting to decode a value which is
    74  too large to fit into a specified Go type, and exceeding max slice limitations.
    75  */
    76  func Unmarshal(data []byte, v interface{}) (rest []byte, err error) {
    77  	if v == nil {
    78  		msg := "can't unmarshal to nil interface"
    79  		err = unmarshalError("Unmarshal", ErrNilInterface, msg, nil)
    80  		return data, err
    81  	}
    82  
    83  	vv := reflect.ValueOf(v)
    84  	if vv.Kind() != reflect.Ptr {
    85  		msg := fmt.Sprintf("can't unmarshal to non-pointer '%v' - use & operator",
    86  			vv.Type().String())
    87  		err = unmarshalError("Unmarshal", ErrBadArguments, msg, nil)
    88  		return data, err
    89  	}
    90  	if vv.IsNil() && !vv.CanSet() {
    91  		msg := fmt.Sprintf("can't unmarshal to unsettable '%v' - use & operator",
    92  			vv.Type().String())
    93  		err = unmarshalError("Unmarshal", ErrNotSettable, msg, nil)
    94  		return data, err
    95  	}
    96  
    97  	d := Decoder{data: data, off: 0}
    98  	err = d.decode(vv)
    99  	return d.data, err
   100  }
   101  
   102  // A Decoder contains information about the state of a decode operation
   103  // from an XDR-encoded byte slice into interface values and provides several
   104  // exposed methods to manually decode various XDR primitives without relying
   105  // on reflection.  The NewDecoder function can be used to get a new Decoder
   106  // directly.
   107  //
   108  // Typically, Unmarshal should be used instead of manual decoding.  A
   109  // Decoder is exposed so it is possible to perform manual decoding should it be
   110  // necessary in complex scenarios where automatic reflection-based decoding
   111  // won't work.
   112  type Decoder struct {
   113  	data []byte
   114  	off  int
   115  }
   116  
   117  // DecodeInt treats the next 4 bytes as an XDR encoded integer and returns the
   118  // result as an int32.
   119  //
   120  // An UnmarshalError is returned if there are insufficient bytes remaining.
   121  //
   122  // Reference:
   123  //
   124  //	RFC Section 4.1 - Integer
   125  //	32-bit big-endian signed integer in range [-2147483648, 2147483647]
   126  func (d *Decoder) DecodeInt() (rv int32, err error) {
   127  	data := d.data
   128  	if len(data) < 4 {
   129  		msg := fmt.Sprintf(errInsufficientBytes, 4)
   130  		err = unmarshalError("DecodeInt", ErrUnexpectedEnd, msg, data)
   131  		return
   132  	}
   133  	rv = int32(data[3]) | int32(data[2])<<8 |
   134  		int32(data[1])<<16 | int32(data[0])<<24
   135  
   136  	d.data = data[4:]
   137  	return
   138  }
   139  
   140  // DecodeUint treats the next 4 bytes as an XDR encoded unsigned integer and
   141  // returns the result as a uint32.
   142  //
   143  // An UnmarshalError is returned if there are insufficient bytes remaining.
   144  //
   145  // Reference:
   146  //
   147  //	RFC Section 4.2 - Unsigned Integer
   148  //	32-bit big-endian unsigned integer in range [0, 4294967295]
   149  func (d *Decoder) DecodeUint() (rv uint32, err error) {
   150  	data := d.data
   151  	if len(data) < 4 {
   152  		msg := fmt.Sprintf(errInsufficientBytes, 4)
   153  		err = unmarshalError("DecodeUint", ErrUnexpectedEnd, msg, data)
   154  		return
   155  	}
   156  	rv = uint32(data[3]) | uint32(data[2])<<8 |
   157  		uint32(data[1])<<16 | uint32(data[0])<<24
   158  
   159  	d.data = data[4:]
   160  	return
   161  }
   162  
   163  // DecodeEnum treats the next 4 bytes as an XDR encoded enumeration value and
   164  // returns the result as an int32 after verifying that the value is in the
   165  // provided map of valid values.
   166  //
   167  // An UnmarshalError is returned if there are insufficient bytes remaining or
   168  // the parsed enumeration value is not one of the provided valid values.
   169  //
   170  // Reference:
   171  //
   172  //	RFC Section 4.3 - Enumeration
   173  //	Represented as an XDR encoded signed integer
   174  func (d *Decoder) DecodeEnum(validEnums map[int32]bool) (rv int32, err error) {
   175  	val, err := d.DecodeInt()
   176  	if err != nil {
   177  		return
   178  	}
   179  	if !validEnums[val] {
   180  		err = unmarshalError("DecodeEnum", ErrBadEnumValue, "invalid enum", val)
   181  		return
   182  	}
   183  	return val, nil
   184  }
   185  
   186  // DecodeBool treats the next 4 bytes as an XDR encoded boolean value and
   187  // returns the result as a bool.
   188  //
   189  // An UnmarshalError is returned if there are insufficient bytes remaining or
   190  // the parsed value is not a 0 or 1.
   191  //
   192  // Reference:
   193  //
   194  //	RFC Section 4.4 - Boolean
   195  //	Represented as an XDR encoded enumeration where 0 is false and 1 is true
   196  func (d *Decoder) DecodeBool() (rv bool, err error) {
   197  	val, err := d.DecodeInt()
   198  	if err != nil {
   199  		return
   200  	}
   201  	switch val {
   202  	case 0:
   203  		return false, nil
   204  	case 1:
   205  		return true, nil
   206  	}
   207  	err = unmarshalError("DecodeBool", ErrBadEnumValue, "bool not 0 or 1", val)
   208  	return
   209  }
   210  
   211  // DecodeHyper treats the next 8 bytes as an XDR encoded hyper value and
   212  // returns the result as an int64.
   213  //
   214  // An UnmarshalError is returned if there are insufficient bytes remaining.
   215  //
   216  // Reference:
   217  //
   218  //	RFC Section 4.5 - Hyper Integer
   219  //	64-bit big-endian signed integer in range [-9223372036854775808, 9223372036854775807]
   220  func (d *Decoder) DecodeHyper() (rv int64, err error) {
   221  	data := d.data
   222  	if len(data) < 8 {
   223  		msg := fmt.Sprintf(errInsufficientBytes, 8)
   224  		err = unmarshalError("DecodeHyper", ErrUnexpectedEnd, msg, data)
   225  		return
   226  	}
   227  	rv = int64(data[7]) | int64(data[6])<<8 |
   228  		int64(data[5])<<16 | int64(data[4])<<24 |
   229  		int64(data[3])<<32 | int64(data[2])<<40 |
   230  		int64(data[1])<<48 | int64(data[0])<<56
   231  
   232  	d.data = data[8:]
   233  	return
   234  }
   235  
   236  // DecodeUhyper treats the next 8  bytes as an XDR encoded unsigned hyper value
   237  // and returns the result as a uint64.
   238  //
   239  // An UnmarshalError is returned if there are insufficient bytes remaining.
   240  //
   241  // Reference:
   242  //
   243  //	RFC Section 4.5 - Unsigned Hyper Integer
   244  //	64-bit big-endian unsigned integer in range [0, 18446744073709551615]
   245  func (d *Decoder) DecodeUhyper() (rv uint64, err error) {
   246  	data := d.data
   247  	if len(data) < 8 {
   248  		msg := fmt.Sprintf(errInsufficientBytes, 8)
   249  		err = unmarshalError("DecodeUhyper", ErrUnexpectedEnd, msg, data)
   250  		return
   251  	}
   252  	rv = uint64(data[7]) | uint64(data[6])<<8 |
   253  		uint64(data[5])<<16 | uint64(data[4])<<24 |
   254  		uint64(data[3])<<32 | uint64(data[2])<<40 |
   255  		uint64(data[1])<<48 | uint64(data[0])<<56
   256  
   257  	d.data = data[8:]
   258  	return
   259  }
   260  
   261  // DecodeFloat treats the next 4 bytes as an XDR encoded floating point and
   262  // returns the result as a float32.
   263  //
   264  // An UnmarshalError is returned if there are insufficient bytes remaining.
   265  //
   266  // Reference:
   267  //
   268  //	RFC Section 4.6 - Floating Point
   269  //	32-bit single-precision IEEE 754 floating point
   270  func (d *Decoder) DecodeFloat() (rv float32, err error) {
   271  	data := d.data
   272  	if len(data) < 4 {
   273  		msg := fmt.Sprintf(errInsufficientBytes, 4)
   274  		err = unmarshalError("DecodeFloat", ErrUnexpectedEnd, msg, data)
   275  		return
   276  	}
   277  	val := uint32(data[3]) | uint32(data[2])<<8 |
   278  		uint32(data[1])<<16 | uint32(data[0])<<24
   279  
   280  	d.data = data[4:]
   281  	return math.Float32frombits(val), nil
   282  }
   283  
   284  // DecodeDouble treats the next 8 bytes as an XDR encoded double-precision
   285  // floating point and returns the result as a float64.
   286  //
   287  // An UnmarshalError is returned if there are insufficient bytes remaining.
   288  //
   289  // Reference:
   290  //
   291  //	RFC Section 4.7 -  Double-Precision Floating Point
   292  //	64-bit double-precision IEEE 754 floating point
   293  func (d *Decoder) DecodeDouble() (rv float64, err error) {
   294  	data := d.data
   295  	if len(data) < 8 {
   296  		msg := fmt.Sprintf(errInsufficientBytes, 8)
   297  		err = unmarshalError("DecodeDouble", ErrUnexpectedEnd, msg, data)
   298  		return
   299  	}
   300  	val := uint64(data[7]) | uint64(data[6])<<8 |
   301  		uint64(data[5])<<16 | uint64(data[4])<<24 |
   302  		uint64(data[3])<<32 | uint64(data[2])<<40 |
   303  		uint64(data[1])<<48 | uint64(data[0])<<56
   304  
   305  	d.data = data[8:]
   306  	return math.Float64frombits(val), nil
   307  }
   308  
   309  // RFC Section 4.8 -  Quadruple-Precision Floating Point
   310  // 128-bit quadruple-precision floating point
   311  // Not Implemented
   312  
   313  // DecodeFixedOpaque treats the next 'size' bytes as XDR encoded opaque data and
   314  // returns the result as a byte slice.
   315  //
   316  // An UnmarshalError is returned if there are insufficient bytes remaining to
   317  // satisfy the passed size, including the necessary padding to make it a
   318  // multiple of 4.
   319  //
   320  // Reference:
   321  //
   322  //	RFC Section 4.9 - Fixed-Length Opaque Data
   323  //	Fixed-length uninterpreted data zero-padded to a multiple of four
   324  func (d *Decoder) DecodeFixedOpaque(size int32) (rv []byte, err error) {
   325  	if size == 0 {
   326  		return
   327  	}
   328  	data := d.data
   329  	if int32(len(data)) < size {
   330  		msg := fmt.Sprintf(errInsufficientBytes, size)
   331  		err = unmarshalError("DecodeFixedOpaque", ErrUnexpectedEnd, msg, data)
   332  		return
   333  	}
   334  	pad := (4 - (size % 4)) % 4
   335  	if int32(len(data[size:])) < pad {
   336  		msg := fmt.Sprintf(errInsufficientPad, size+pad)
   337  		err = unmarshalError("DecodeFixedOpaque", ErrUnexpectedEnd, msg, data)
   338  		return
   339  	}
   340  	rv = data[0:size]
   341  
   342  	d.data = data[size+pad:]
   343  	return
   344  }
   345  
   346  // DecodeOpaque treats the next bytes as variable length XDR encoded opaque
   347  // data and returns the result as a byte slice.
   348  //
   349  // An UnmarshalError is returned if there are insufficient bytes remaining or
   350  // the opaque data is larger than the max length of a Go slice.
   351  //
   352  // Reference:
   353  //
   354  //	RFC Section 4.10 - Variable-Length Opaque Data
   355  //	Unsigned integer length followed by fixed opaque data of that length
   356  func (d *Decoder) DecodeOpaque() (rv []byte, err error) {
   357  	dataLen, err := d.DecodeUint()
   358  	if err != nil {
   359  		return
   360  	}
   361  	if uint(dataLen) > uint(maxInt) {
   362  		err = unmarshalError("DecodeOpaque", ErrOverflow, errMaxSlice, dataLen)
   363  		return
   364  	}
   365  	return d.DecodeFixedOpaque(int32(dataLen))
   366  }
   367  
   368  // DecodeString treats the next bytes as a variable length XDR encoded string
   369  // and returns the result as a string.  Character encoding is assumed to be
   370  // UTF-8 and therefore ASCII compatible.  If the underlying character encoding
   371  // is not compatibile with this assumption, the data can instead be read as
   372  // variable-length opaque data (DecodeOpaque) and manually converted as needed.
   373  //
   374  // An UnmarshalError is returned if there are insufficient bytes remaining or
   375  // the string data is larger than the max length of a Go slice.
   376  //
   377  // Reference:
   378  //
   379  //	RFC Section 4.11 - String
   380  //	Unsigned integer length followed by bytes zero-padded to a multiple of four
   381  func (d *Decoder) DecodeString() (rv string, err error) {
   382  	dataLen, err := d.DecodeUint()
   383  	if err != nil {
   384  		return
   385  	}
   386  	if uint(dataLen) > uint(maxInt) {
   387  		err = unmarshalError("DecodeString", ErrOverflow, errMaxSlice, dataLen)
   388  		return
   389  	}
   390  	opaque, err := d.DecodeFixedOpaque(int32(dataLen))
   391  	if err != nil {
   392  		return
   393  	}
   394  	rv = string(opaque)
   395  	return
   396  }
   397  
   398  // decodeFixedArray treats the next bytes as a series of XDR encoded elements
   399  // of the same type as the array represented by the reflection value and decodes
   400  // each element into the passed array.  The ignoreOpaque flag controls whether
   401  // or not uint8 (byte) elements should be decoded individually or as a fixed
   402  // sequence of opaque data.
   403  //
   404  // An UnmarshalError is returned if any issues are encountered while decoding
   405  // the array elements.
   406  //
   407  // Reference:
   408  //
   409  //	RFC Section 4.12 - Fixed-Length Array
   410  //	Individually XDR encoded array elements
   411  func (d *Decoder) decodeFixedArray(v reflect.Value, ignoreOpaque bool) (err error) {
   412  	// Treat [#]byte (byte is alias for uint8) as opaque data unless ignored.
   413  	if !ignoreOpaque && v.Type().Elem().Kind() == reflect.Uint8 {
   414  		data, err := d.DecodeFixedOpaque(int32(v.Len()))
   415  		if err != nil {
   416  			return err
   417  		}
   418  		reflect.Copy(v, reflect.ValueOf(data))
   419  		return nil
   420  	}
   421  
   422  	// Decode each array element.
   423  	for i := 0; i < v.Len(); i++ {
   424  		err = d.decode(v.Index(i))
   425  		if err != nil {
   426  			return
   427  		}
   428  	}
   429  	return
   430  }
   431  
   432  // decodeArray treats the next bytes as a variable length series of XDR encoded
   433  // elements of the same type as the array represented by the reflection value.
   434  // The number of elements is obtained by first decoding the unsigned integer
   435  // element count.  Then each element is decoded into the passed array. The
   436  // ignoreOpaque flag controls whether or not uint8 (byte) elements should be
   437  // decoded individually or as a variable sequence of opaque data.
   438  //
   439  // An UnmarshalError is returned if any issues are encountered while decoding
   440  // the array elements.
   441  //
   442  // Reference:
   443  //
   444  //	RFC Section 4.13 - Variable-Length Array
   445  //	Unsigned integer length followed by individually XDR encoded array elements
   446  func (d *Decoder) decodeArray(v reflect.Value, ignoreOpaque bool) (err error) {
   447  	dataLen, err := d.DecodeUint()
   448  	if err != nil {
   449  		return
   450  	}
   451  	if uint(dataLen) > uint(maxInt) {
   452  		err = unmarshalError("decodeArray", ErrOverflow, errMaxSlice, dataLen)
   453  		return
   454  	}
   455  
   456  	// Allocate storage for the slice elements (the underlying array) if
   457  	// existing slice does not enough capacity.
   458  	sliceLen := int(dataLen)
   459  	if v.Cap() < sliceLen {
   460  		v.Set(reflect.MakeSlice(v.Type(), sliceLen, sliceLen))
   461  	}
   462  	if v.Len() < sliceLen {
   463  		v.SetLen(sliceLen)
   464  	}
   465  
   466  	// Treat []byte (byte is alias for uint8) as opaque data unless ignored.
   467  	if !ignoreOpaque && v.Type().Elem().Kind() == reflect.Uint8 {
   468  		data, err := d.DecodeFixedOpaque(int32(sliceLen))
   469  		if err != nil {
   470  			return err
   471  		}
   472  		v.SetBytes(data)
   473  		return nil
   474  	}
   475  
   476  	// Decode each slice element.
   477  	for i := 0; i < sliceLen; i++ {
   478  		err = d.decode(v.Index(i))
   479  		if err != nil {
   480  			return err
   481  		}
   482  	}
   483  	return
   484  }
   485  
   486  // decodeStruct treats the next bytes as a series of XDR encoded elements
   487  // of the same type as the exported fields of the struct represented by the
   488  // passed reflection value.  Pointers are automatically indirected and
   489  // allocated as necessary.
   490  //
   491  // An UnmarshalError is returned if any issues are encountered while decoding
   492  // the elements.
   493  //
   494  // Reference:
   495  //
   496  //	RFC Section 4.14 - Structure
   497  //	XDR encoded elements in the order of their declaration in the struct
   498  func (d *Decoder) decodeStruct(v reflect.Value) (err error) {
   499  	vt := v.Type()
   500  	for i := 0; i < v.NumField(); i++ {
   501  		// Skip unexported fields.
   502  		vtf := vt.Field(i)
   503  		if vtf.PkgPath != "" {
   504  			continue
   505  		}
   506  
   507  		// Indirect through pointers allocating them as needed and ensure
   508  		// the field is settable.
   509  		vf := v.Field(i)
   510  		vf, err = d.indirect(vf)
   511  		if err != nil {
   512  			return err
   513  		}
   514  		if !vf.CanSet() {
   515  			msg := fmt.Sprintf("can't decode to unsettable '%v'",
   516  				vf.Type().String())
   517  			err = unmarshalError("decodeStruct", ErrNotSettable, msg, nil)
   518  			return err
   519  		}
   520  
   521  		// Handle non-opaque data to []uint8 and [#]uint8 based on struct tag.
   522  		tag := vtf.Tag.Get("xdropaque")
   523  		if tag == "false" {
   524  			switch vf.Kind() {
   525  			case reflect.Slice:
   526  				err = d.decodeArray(vf, true)
   527  				if err != nil {
   528  					return
   529  				}
   530  				continue
   531  
   532  			case reflect.Array:
   533  				err = d.decodeFixedArray(vf, true)
   534  				if err != nil {
   535  					return
   536  				}
   537  				continue
   538  			}
   539  		}
   540  
   541  		// Decode each struct field.
   542  		err = d.decode(vf)
   543  		if err != nil {
   544  			return err
   545  		}
   546  	}
   547  	return
   548  }
   549  
   550  // RFC Section 4.15 - Discriminated Union
   551  // RFC Section 4.16 - Void
   552  // RFC Section 4.17 - Constant
   553  // RFC Section 4.18 - Typedef
   554  // RFC Section 4.19 - Optional data
   555  // RFC Sections 4.15 though 4.19 only apply to the data specification language
   556  // which is not implemented by this package.  In the case of discriminated
   557  // unions, struct tags are used to perform a similar function.
   558  
   559  // decodeMap treats the next bytes as an XDR encoded variable array of 2-element
   560  // structures whose fields are of the same type as the map keys and elements
   561  // represented by the passed reflection value.  Pointers are automatically
   562  // indirected and allocated as necessary.
   563  //
   564  // An UnmarshalError is returned if any issues are encountered while decoding
   565  // the elements.
   566  func (d *Decoder) decodeMap(v reflect.Value) (err error) {
   567  	dataLen, err := d.DecodeUint()
   568  	if err != nil {
   569  		return
   570  	}
   571  
   572  	// Allocate storage for the underlying map if needed.
   573  	vt := v.Type()
   574  	if v.IsNil() {
   575  		v.Set(reflect.MakeMap(vt))
   576  	}
   577  
   578  	// Decode each key and value according to their type.
   579  	keyType := vt.Key()
   580  	elemType := vt.Elem()
   581  	for i := uint32(0); i < dataLen; i++ {
   582  		key := reflect.New(keyType).Elem()
   583  		err = d.decode(key)
   584  		if err != nil {
   585  			return
   586  		}
   587  
   588  		val := reflect.New(elemType).Elem()
   589  		err = d.decode(val)
   590  		if err != nil {
   591  			return
   592  		}
   593  		v.SetMapIndex(key, val)
   594  	}
   595  	return
   596  }
   597  
   598  // decodeInterface examines the interface represented by the passed reflection
   599  // value to detect whether it is an interface that can be decoded into and
   600  // if it is, extracts the underlying value to pass back into the decode function
   601  // for decoding according to its type.
   602  //
   603  // An UnmarshalError is returned if any issues are encountered while decoding
   604  // the interface.
   605  func (d *Decoder) decodeInterface(v reflect.Value) (err error) {
   606  	if v.IsNil() || !v.CanInterface() {
   607  		msg := fmt.Sprintf("can't decode to nil interface")
   608  		err = unmarshalError("decodeInterface", ErrNilInterface, msg, nil)
   609  		return err
   610  	}
   611  
   612  	// Extract underlying value from the interface and indirect through pointers
   613  	// allocating them as needed.
   614  	ve := reflect.ValueOf(v.Interface())
   615  	ve, err = d.indirect(ve)
   616  	if err != nil {
   617  		return err
   618  	}
   619  	if !ve.CanSet() {
   620  		msg := fmt.Sprintf("can't decode to unsettable '%v'", ve.Type().String())
   621  		err = unmarshalError("decodeInterface", ErrNotSettable, msg, nil)
   622  		return err
   623  	}
   624  	return d.decode(ve)
   625  }
   626  
   627  // decode is the main workhorse for unmarshalling via reflection.  It uses
   628  // the passed reflection value to choose the XDR primitives to decode from
   629  // the XDR encoded data stored in the Decoder.  It is a recursive function,
   630  // so cyclic data structures are not supported and will result in an infinite
   631  // loop.
   632  func (d *Decoder) decode(v reflect.Value) (err error) {
   633  	if !v.IsValid() {
   634  		msg := fmt.Sprintf("type '%s' is not valid", v.Kind().String())
   635  		err = unmarshalError("decode", ErrUnsupportedType, msg, nil)
   636  		return
   637  	}
   638  
   639  	// Indirect through pointers allocating them as needed.
   640  	ve, err := d.indirect(v)
   641  	if err != nil {
   642  		return err
   643  	}
   644  
   645  	// Handle time.Time values by decoding them as an RFC3339 formatted
   646  	// string with nanosecond precision.  Check the type string rather
   647  	// than doing a full blown conversion to interface and type assertion
   648  	// since checking a string is much quicker.
   649  	if ve.Type().String() == "time.Time" {
   650  		// Read the value as a string and parse it.
   651  		timeString, err := d.DecodeString()
   652  		if err != nil {
   653  			return err
   654  		}
   655  		ttv, err := time.Parse(time.RFC3339, timeString)
   656  		if err != nil {
   657  			return err
   658  		}
   659  		ve.Set(reflect.ValueOf(ttv))
   660  		return nil
   661  	}
   662  
   663  	// Handle native Go types.
   664  	switch ve.Kind() {
   665  	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int:
   666  		i, err := d.DecodeInt()
   667  		if err != nil {
   668  			return err
   669  		}
   670  		if ve.OverflowInt(int64(i)) {
   671  			msg := fmt.Sprintf("signed integer too large to fit '%s'",
   672  				ve.Kind().String())
   673  			err = unmarshalError("decode", ErrOverflow, msg, i)
   674  			return err
   675  		}
   676  		ve.SetInt(int64(i))
   677  
   678  	case reflect.Int64:
   679  		i, err := d.DecodeHyper()
   680  		if err != nil {
   681  			return err
   682  		}
   683  		ve.SetInt(i)
   684  
   685  	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint:
   686  		ui, err := d.DecodeUint()
   687  		if err != nil {
   688  			return err
   689  		}
   690  		if ve.OverflowUint(uint64(ui)) {
   691  			msg := fmt.Sprintf("unsigned integer too large to fit '%s'",
   692  				ve.Kind().String())
   693  			err = unmarshalError("decode", ErrOverflow, msg, ui)
   694  			return err
   695  		}
   696  		ve.SetUint(uint64(ui))
   697  
   698  	case reflect.Uint64:
   699  		ui, err := d.DecodeUhyper()
   700  		if err != nil {
   701  			return err
   702  		}
   703  		ve.SetUint(ui)
   704  
   705  	case reflect.Bool:
   706  		b, err := d.DecodeBool()
   707  		if err != nil {
   708  			return err
   709  		}
   710  		ve.SetBool(b)
   711  
   712  	case reflect.Float32:
   713  		f, err := d.DecodeFloat()
   714  		if err != nil {
   715  			return err
   716  		}
   717  		ve.SetFloat(float64(f))
   718  
   719  	case reflect.Float64:
   720  		f, err := d.DecodeDouble()
   721  		if err != nil {
   722  			return err
   723  		}
   724  		ve.SetFloat(f)
   725  
   726  	case reflect.String:
   727  		s, err := d.DecodeString()
   728  		if err != nil {
   729  			return err
   730  		}
   731  		ve.SetString(s)
   732  
   733  	case reflect.Array:
   734  		err := d.decodeFixedArray(ve, false)
   735  		if err != nil {
   736  			return err
   737  		}
   738  
   739  	case reflect.Slice:
   740  		err := d.decodeArray(ve, false)
   741  		if err != nil {
   742  			return err
   743  		}
   744  
   745  	case reflect.Struct:
   746  		err := d.decodeStruct(ve)
   747  		if err != nil {
   748  			return err
   749  		}
   750  
   751  	case reflect.Map:
   752  		err := d.decodeMap(ve)
   753  		if err != nil {
   754  			return err
   755  		}
   756  
   757  	case reflect.Interface:
   758  		err := d.decodeInterface(ve)
   759  		if err != nil {
   760  			return err
   761  		}
   762  
   763  	// reflect.Uintptr, reflect.UnsafePointer
   764  	default:
   765  		msg := fmt.Sprintf("unsupported Go type '%s'", ve.Kind().String())
   766  		err = unmarshalError("decode", ErrUnsupportedType, msg, nil)
   767  	}
   768  
   769  	return
   770  }
   771  
   772  // indirect dereferences pointers allocating them as needed until it reaches
   773  // a non-pointer.  This allows transparent decoding through arbitrary levels
   774  // of indirection.
   775  func (d *Decoder) indirect(v reflect.Value) (rv reflect.Value, err error) {
   776  	rv = v
   777  	for rv.Kind() == reflect.Ptr {
   778  		// Allocate pointer if needed.
   779  		isNil := rv.IsNil()
   780  		if isNil && !rv.CanSet() {
   781  			msg := fmt.Sprintf("unable to allocate pointer for '%v'", rv.Type().String())
   782  			err = unmarshalError("indirect", ErrNotSettable, msg, nil)
   783  			return
   784  		}
   785  		if isNil {
   786  			rv.Set(reflect.New(rv.Type().Elem()))
   787  		}
   788  		rv = rv.Elem()
   789  	}
   790  	return
   791  }
   792  
   793  // NewDecoder returns a Decoder that can be used to manually decode XDR data
   794  // from a provided byte slice.  Typically, Unmarshal should be used instead of
   795  // manually creating a Decoder.
   796  func NewDecoder(bytes []byte) *Decoder {
   797  	return &Decoder{data: bytes}
   798  }