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