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