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