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