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