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