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