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