github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/pkg/state/wire/wire.go (about) 1 // Copyright 2020 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package wire contains a few basic types that can be composed to serialize 16 // graph information for the state package. This package defines the wire 17 // protocol. 18 // 19 // Note that these types are careful about how they implement the relevant 20 // interfaces (either value receiver or pointer receiver), so that native-sized 21 // types, such as integers and simple pointers, can fit inside the interface 22 // object. 23 // 24 // This package also uses panic as control flow, so called should be careful to 25 // wrap calls in appropriate handlers. 26 // 27 // Testing for this package is driven by the state test package. 28 package wire 29 30 import ( 31 "fmt" 32 "io" 33 "math" 34 35 "github.com/nicocha30/gvisor-ligolo/pkg/gohacks" 36 ) 37 38 // Reader is the required reader interface. 39 type Reader interface { 40 io.Reader 41 ReadByte() (byte, error) 42 } 43 44 // Writer is the required writer interface. 45 type Writer interface { 46 io.Writer 47 WriteByte(byte) error 48 } 49 50 // readFull is a utility. The equivalent is not needed for Write, but the API 51 // contract dictates that it must always complete all bytes given or return an 52 // error. 53 func readFull(r io.Reader, p []byte) { 54 for done := 0; done < len(p); { 55 n, err := r.Read(p[done:]) 56 done += n 57 if n == 0 && err != nil { 58 panic(err) 59 } 60 } 61 } 62 63 // Object is a generic object. 64 type Object interface { 65 // save saves the given object. 66 // 67 // Panic is used for error control flow. 68 save(Writer) 69 70 // load loads a new object of the given type. 71 // 72 // Panic is used for error control flow. 73 load(Reader) Object 74 } 75 76 // Bool is a boolean. 77 type Bool bool 78 79 // loadBool loads an object of type Bool. 80 func loadBool(r Reader) Bool { 81 b := loadUint(r) 82 return Bool(b == 1) 83 } 84 85 // save implements Object.save. 86 func (b Bool) save(w Writer) { 87 var v Uint 88 if b { 89 v = 1 90 } else { 91 v = 0 92 } 93 v.save(w) 94 } 95 96 // load implements Object.load. 97 func (Bool) load(r Reader) Object { return loadBool(r) } 98 99 // Int is a signed integer. 100 // 101 // This uses varint encoding. 102 type Int int64 103 104 // loadInt loads an object of type Int. 105 func loadInt(r Reader) Int { 106 u := loadUint(r) 107 x := Int(u >> 1) 108 if u&1 != 0 { 109 x = ^x 110 } 111 return x 112 } 113 114 // save implements Object.save. 115 func (i Int) save(w Writer) { 116 u := Uint(i) << 1 117 if i < 0 { 118 u = ^u 119 } 120 u.save(w) 121 } 122 123 // load implements Object.load. 124 func (Int) load(r Reader) Object { return loadInt(r) } 125 126 // Uint is an unsigned integer. 127 type Uint uint64 128 129 // loadUint loads an object of type Uint. 130 func loadUint(r Reader) Uint { 131 var ( 132 u Uint 133 s uint 134 ) 135 for i := 0; i <= 9; i++ { 136 b, err := r.ReadByte() 137 if err != nil { 138 panic(err) 139 } 140 if b < 0x80 { 141 if i == 9 && b > 1 { 142 panic("overflow") 143 } 144 u |= Uint(b) << s 145 return u 146 } 147 u |= Uint(b&0x7f) << s 148 s += 7 149 } 150 panic("unreachable") 151 } 152 153 // save implements Object.save. 154 func (u Uint) save(w Writer) { 155 for u >= 0x80 { 156 if err := w.WriteByte(byte(u) | 0x80); err != nil { 157 panic(err) 158 } 159 u >>= 7 160 } 161 if err := w.WriteByte(byte(u)); err != nil { 162 panic(err) 163 } 164 } 165 166 // load implements Object.load. 167 func (Uint) load(r Reader) Object { return loadUint(r) } 168 169 // Float32 is a 32-bit floating point number. 170 type Float32 float32 171 172 // loadFloat32 loads an object of type Float32. 173 func loadFloat32(r Reader) Float32 { 174 n := loadUint(r) 175 return Float32(math.Float32frombits(uint32(n))) 176 } 177 178 // save implements Object.save. 179 func (f Float32) save(w Writer) { 180 n := Uint(math.Float32bits(float32(f))) 181 n.save(w) 182 } 183 184 // load implements Object.load. 185 func (Float32) load(r Reader) Object { return loadFloat32(r) } 186 187 // Float64 is a 64-bit floating point number. 188 type Float64 float64 189 190 // loadFloat64 loads an object of type Float64. 191 func loadFloat64(r Reader) Float64 { 192 n := loadUint(r) 193 return Float64(math.Float64frombits(uint64(n))) 194 } 195 196 // save implements Object.save. 197 func (f Float64) save(w Writer) { 198 n := Uint(math.Float64bits(float64(f))) 199 n.save(w) 200 } 201 202 // load implements Object.load. 203 func (Float64) load(r Reader) Object { return loadFloat64(r) } 204 205 // Complex64 is a 64-bit complex number. 206 type Complex64 complex128 207 208 // loadComplex64 loads an object of type Complex64. 209 func loadComplex64(r Reader) Complex64 { 210 re := loadFloat32(r) 211 im := loadFloat32(r) 212 return Complex64(complex(float32(re), float32(im))) 213 } 214 215 // save implements Object.save. 216 func (c *Complex64) save(w Writer) { 217 re := Float32(real(*c)) 218 im := Float32(imag(*c)) 219 re.save(w) 220 im.save(w) 221 } 222 223 // load implements Object.load. 224 func (*Complex64) load(r Reader) Object { 225 c := loadComplex64(r) 226 return &c 227 } 228 229 // Complex128 is a 128-bit complex number. 230 type Complex128 complex128 231 232 // loadComplex128 loads an object of type Complex128. 233 func loadComplex128(r Reader) Complex128 { 234 re := loadFloat64(r) 235 im := loadFloat64(r) 236 return Complex128(complex(float64(re), float64(im))) 237 } 238 239 // save implements Object.save. 240 func (c *Complex128) save(w Writer) { 241 re := Float64(real(*c)) 242 im := Float64(imag(*c)) 243 re.save(w) 244 im.save(w) 245 } 246 247 // load implements Object.load. 248 func (*Complex128) load(r Reader) Object { 249 c := loadComplex128(r) 250 return &c 251 } 252 253 // String is a string. 254 type String string 255 256 // loadString loads an object of type String. 257 func loadString(r Reader) String { 258 l := loadUint(r) 259 p := make([]byte, l) 260 readFull(r, p) 261 return String(gohacks.StringFromImmutableBytes(p)) 262 } 263 264 // save implements Object.save. 265 func (s *String) save(w Writer) { 266 l := Uint(len(*s)) 267 l.save(w) 268 p := gohacks.ImmutableBytesFromString(string(*s)) 269 _, err := w.Write(p) // Must write all bytes. 270 if err != nil { 271 panic(err) 272 } 273 } 274 275 // load implements Object.load. 276 func (*String) load(r Reader) Object { 277 s := loadString(r) 278 return &s 279 } 280 281 // Dot is a kind of reference: one of Index and FieldName. 282 type Dot interface { 283 isDot() 284 } 285 286 // Index is a reference resolution. 287 type Index uint32 288 289 func (Index) isDot() {} 290 291 // FieldName is a reference resolution. 292 type FieldName string 293 294 func (*FieldName) isDot() {} 295 296 // Ref is a reference to an object. 297 type Ref struct { 298 // Root is the root object. 299 Root Uint 300 301 // Dots is the set of traversals required from the Root object above. 302 // Note that this will be stored in reverse order for efficiency. 303 Dots []Dot 304 305 // Type is the base type for the root object. This is non-nil iff Dots 306 // is non-zero length (that is, this is a complex reference). This is 307 // not *strictly* necessary, but can be used to simplify decoding. 308 Type TypeSpec 309 } 310 311 // loadRef loads an object of type Ref (abstract). 312 func loadRef(r Reader) Ref { 313 ref := Ref{ 314 Root: loadUint(r), 315 } 316 l := loadUint(r) 317 ref.Dots = make([]Dot, l) 318 for i := 0; i < int(l); i++ { 319 // Disambiguate between an Index (non-negative) and a field 320 // name (negative). This does some space and avoids a dedicate 321 // loadDot function. See Ref.save for the other side. 322 d := loadInt(r) 323 if d >= 0 { 324 ref.Dots[i] = Index(d) 325 continue 326 } 327 p := make([]byte, -d) 328 readFull(r, p) 329 fieldName := FieldName(gohacks.StringFromImmutableBytes(p)) 330 ref.Dots[i] = &fieldName 331 } 332 if l != 0 { 333 // Only if dots is non-zero. 334 ref.Type = loadTypeSpec(r) 335 } 336 return ref 337 } 338 339 // save implements Object.save. 340 func (r *Ref) save(w Writer) { 341 r.Root.save(w) 342 l := Uint(len(r.Dots)) 343 l.save(w) 344 for _, d := range r.Dots { 345 // See LoadRef. We use non-negative numbers to encode Index 346 // objects and negative numbers to encode field lengths. 347 switch x := d.(type) { 348 case Index: 349 i := Int(x) 350 i.save(w) 351 case *FieldName: 352 d := Int(-len(*x)) 353 d.save(w) 354 p := gohacks.ImmutableBytesFromString(string(*x)) 355 if _, err := w.Write(p); err != nil { 356 panic(err) 357 } 358 default: 359 panic("unknown dot implementation") 360 } 361 } 362 if l != 0 { 363 // See above. 364 saveTypeSpec(w, r.Type) 365 } 366 } 367 368 // load implements Object.load. 369 func (*Ref) load(r Reader) Object { 370 ref := loadRef(r) 371 return &ref 372 } 373 374 // Nil is a primitive zero value of any type. 375 type Nil struct{} 376 377 // loadNil loads an object of type Nil. 378 func loadNil(r Reader) Nil { 379 return Nil{} 380 } 381 382 // save implements Object.save. 383 func (Nil) save(w Writer) {} 384 385 // load implements Object.load. 386 func (Nil) load(r Reader) Object { return loadNil(r) } 387 388 // Slice is a slice value. 389 type Slice struct { 390 Length Uint 391 Capacity Uint 392 Ref Ref 393 } 394 395 // loadSlice loads an object of type Slice. 396 func loadSlice(r Reader) Slice { 397 return Slice{ 398 Length: loadUint(r), 399 Capacity: loadUint(r), 400 Ref: loadRef(r), 401 } 402 } 403 404 // save implements Object.save. 405 func (s *Slice) save(w Writer) { 406 s.Length.save(w) 407 s.Capacity.save(w) 408 s.Ref.save(w) 409 } 410 411 // load implements Object.load. 412 func (*Slice) load(r Reader) Object { 413 s := loadSlice(r) 414 return &s 415 } 416 417 // Array is an array value. 418 type Array struct { 419 Contents []Object 420 } 421 422 // loadArray loads an object of type Array. 423 func loadArray(r Reader) Array { 424 l := loadUint(r) 425 if l == 0 { 426 // Note that there isn't a single object available to encode 427 // the type of, so we need this additional branch. 428 return Array{} 429 } 430 // All the objects here have the same type, so use dynamic dispatch 431 // only once. All other objects will automatically take the same type 432 // as the first object. 433 contents := make([]Object, l) 434 v := Load(r) 435 contents[0] = v 436 for i := 1; i < int(l); i++ { 437 contents[i] = v.load(r) 438 } 439 return Array{ 440 Contents: contents, 441 } 442 } 443 444 // save implements Object.save. 445 func (a *Array) save(w Writer) { 446 l := Uint(len(a.Contents)) 447 l.save(w) 448 if l == 0 { 449 // See LoadArray. 450 return 451 } 452 // See above. 453 Save(w, a.Contents[0]) 454 for i := 1; i < int(l); i++ { 455 a.Contents[i].save(w) 456 } 457 } 458 459 // load implements Object.load. 460 func (*Array) load(r Reader) Object { 461 a := loadArray(r) 462 return &a 463 } 464 465 // Map is a map value. 466 type Map struct { 467 Keys []Object 468 Values []Object 469 } 470 471 // loadMap loads an object of type Map. 472 func loadMap(r Reader) Map { 473 l := loadUint(r) 474 if l == 0 { 475 // See LoadArray. 476 return Map{} 477 } 478 // See type dispatch notes in Array. 479 keys := make([]Object, l) 480 values := make([]Object, l) 481 k := Load(r) 482 v := Load(r) 483 keys[0] = k 484 values[0] = v 485 for i := 1; i < int(l); i++ { 486 keys[i] = k.load(r) 487 values[i] = v.load(r) 488 } 489 return Map{ 490 Keys: keys, 491 Values: values, 492 } 493 } 494 495 // save implements Object.save. 496 func (m *Map) save(w Writer) { 497 l := Uint(len(m.Keys)) 498 if int(l) != len(m.Values) { 499 panic(fmt.Sprintf("mismatched keys (%d) Aand values (%d)", len(m.Keys), len(m.Values))) 500 } 501 l.save(w) 502 if l == 0 { 503 // See LoadArray. 504 return 505 } 506 // See above. 507 Save(w, m.Keys[0]) 508 Save(w, m.Values[0]) 509 for i := 1; i < int(l); i++ { 510 m.Keys[i].save(w) 511 m.Values[i].save(w) 512 } 513 } 514 515 // load implements Object.load. 516 func (*Map) load(r Reader) Object { 517 m := loadMap(r) 518 return &m 519 } 520 521 // TypeSpec is a type dereference. 522 type TypeSpec interface { 523 isTypeSpec() 524 } 525 526 // TypeID is a concrete type ID. 527 type TypeID Uint 528 529 func (TypeID) isTypeSpec() {} 530 531 // TypeSpecPointer is a pointer type. 532 type TypeSpecPointer struct { 533 Type TypeSpec 534 } 535 536 func (*TypeSpecPointer) isTypeSpec() {} 537 538 // TypeSpecArray is an array type. 539 type TypeSpecArray struct { 540 Count Uint 541 Type TypeSpec 542 } 543 544 func (*TypeSpecArray) isTypeSpec() {} 545 546 // TypeSpecSlice is a slice type. 547 type TypeSpecSlice struct { 548 Type TypeSpec 549 } 550 551 func (*TypeSpecSlice) isTypeSpec() {} 552 553 // TypeSpecMap is a map type. 554 type TypeSpecMap struct { 555 Key TypeSpec 556 Value TypeSpec 557 } 558 559 func (*TypeSpecMap) isTypeSpec() {} 560 561 // TypeSpecNil is an empty type. 562 type TypeSpecNil struct{} 563 564 func (TypeSpecNil) isTypeSpec() {} 565 566 // TypeSpec types. 567 // 568 // These use a distinct encoding on the wire, as they are used only in the 569 // interface object. They are decoded through the dedicated loadTypeSpec and 570 // saveTypeSpec functions. 571 const ( 572 typeSpecTypeID Uint = iota 573 typeSpecPointer 574 typeSpecArray 575 typeSpecSlice 576 typeSpecMap 577 typeSpecNil 578 ) 579 580 // loadTypeSpec loads TypeSpec values. 581 func loadTypeSpec(r Reader) TypeSpec { 582 switch hdr := loadUint(r); hdr { 583 case typeSpecTypeID: 584 return TypeID(loadUint(r)) 585 case typeSpecPointer: 586 return &TypeSpecPointer{ 587 Type: loadTypeSpec(r), 588 } 589 case typeSpecArray: 590 return &TypeSpecArray{ 591 Count: loadUint(r), 592 Type: loadTypeSpec(r), 593 } 594 case typeSpecSlice: 595 return &TypeSpecSlice{ 596 Type: loadTypeSpec(r), 597 } 598 case typeSpecMap: 599 return &TypeSpecMap{ 600 Key: loadTypeSpec(r), 601 Value: loadTypeSpec(r), 602 } 603 case typeSpecNil: 604 return TypeSpecNil{} 605 default: 606 // This is not a valid stream? 607 panic(fmt.Errorf("unknown header: %d", hdr)) 608 } 609 } 610 611 // saveTypeSpec saves TypeSpec values. 612 func saveTypeSpec(w Writer, t TypeSpec) { 613 switch x := t.(type) { 614 case TypeID: 615 typeSpecTypeID.save(w) 616 Uint(x).save(w) 617 case *TypeSpecPointer: 618 typeSpecPointer.save(w) 619 saveTypeSpec(w, x.Type) 620 case *TypeSpecArray: 621 typeSpecArray.save(w) 622 x.Count.save(w) 623 saveTypeSpec(w, x.Type) 624 case *TypeSpecSlice: 625 typeSpecSlice.save(w) 626 saveTypeSpec(w, x.Type) 627 case *TypeSpecMap: 628 typeSpecMap.save(w) 629 saveTypeSpec(w, x.Key) 630 saveTypeSpec(w, x.Value) 631 case TypeSpecNil: 632 typeSpecNil.save(w) 633 default: 634 // This should not happen? 635 panic(fmt.Errorf("unknown type %T", t)) 636 } 637 } 638 639 // Interface is an interface value. 640 type Interface struct { 641 Type TypeSpec 642 Value Object 643 } 644 645 // loadInterface loads an object of type Interface. 646 func loadInterface(r Reader) Interface { 647 return Interface{ 648 Type: loadTypeSpec(r), 649 Value: Load(r), 650 } 651 } 652 653 // save implements Object.save. 654 func (i *Interface) save(w Writer) { 655 saveTypeSpec(w, i.Type) 656 Save(w, i.Value) 657 } 658 659 // load implements Object.load. 660 func (*Interface) load(r Reader) Object { 661 i := loadInterface(r) 662 return &i 663 } 664 665 // Type is type information. 666 type Type struct { 667 Name string 668 Fields []string 669 } 670 671 // loadType loads an object of type Type. 672 func loadType(r Reader) Type { 673 name := string(loadString(r)) 674 l := loadUint(r) 675 fields := make([]string, l) 676 for i := 0; i < int(l); i++ { 677 fields[i] = string(loadString(r)) 678 } 679 return Type{ 680 Name: name, 681 Fields: fields, 682 } 683 } 684 685 // save implements Object.save. 686 func (t *Type) save(w Writer) { 687 s := String(t.Name) 688 s.save(w) 689 l := Uint(len(t.Fields)) 690 l.save(w) 691 for i := 0; i < int(l); i++ { 692 s := String(t.Fields[i]) 693 s.save(w) 694 } 695 } 696 697 // load implements Object.load. 698 func (*Type) load(r Reader) Object { 699 t := loadType(r) 700 return &t 701 } 702 703 // multipleObjects is a special type for serializing multiple objects. 704 type multipleObjects []Object 705 706 // loadMultipleObjects loads a series of objects. 707 func loadMultipleObjects(r Reader) multipleObjects { 708 l := loadUint(r) 709 m := make(multipleObjects, l) 710 for i := 0; i < int(l); i++ { 711 m[i] = Load(r) 712 } 713 return m 714 } 715 716 // save implements Object.save. 717 func (m *multipleObjects) save(w Writer) { 718 l := Uint(len(*m)) 719 l.save(w) 720 for i := 0; i < int(l); i++ { 721 Save(w, (*m)[i]) 722 } 723 } 724 725 // load implements Object.load. 726 func (*multipleObjects) load(r Reader) Object { 727 m := loadMultipleObjects(r) 728 return &m 729 } 730 731 // noObjects represents no objects. 732 type noObjects struct{} 733 734 // loadNoObjects loads a sentinel. 735 func loadNoObjects(r Reader) noObjects { return noObjects{} } 736 737 // save implements Object.save. 738 func (noObjects) save(w Writer) {} 739 740 // load implements Object.load. 741 func (noObjects) load(r Reader) Object { return loadNoObjects(r) } 742 743 // Struct is a basic composite value. 744 type Struct struct { 745 TypeID TypeID 746 fields Object // Optionally noObjects or *multipleObjects. 747 } 748 749 // Field returns a pointer to the given field slot. 750 // 751 // This must be called after Alloc. 752 func (s *Struct) Field(i int) *Object { 753 if fields, ok := s.fields.(*multipleObjects); ok { 754 return &((*fields)[i]) 755 } 756 if _, ok := s.fields.(noObjects); ok { 757 // Alloc may be optionally called; can't call twice. 758 panic("Field called inappropriately, wrong Alloc?") 759 } 760 return &s.fields 761 } 762 763 // Alloc allocates the given number of fields. 764 // 765 // This must be called before Add and Save. 766 // 767 // Precondition: slots must be positive. 768 func (s *Struct) Alloc(slots int) { 769 switch { 770 case slots == 0: 771 s.fields = noObjects{} 772 case slots == 1: 773 // Leave it alone. 774 case slots > 1: 775 fields := make(multipleObjects, slots) 776 s.fields = &fields 777 default: 778 // Violates precondition. 779 panic(fmt.Sprintf("Alloc called with negative slots %d?", slots)) 780 } 781 } 782 783 // Fields returns the number of fields. 784 func (s *Struct) Fields() int { 785 switch x := s.fields.(type) { 786 case *multipleObjects: 787 return len(*x) 788 case noObjects: 789 return 0 790 default: 791 return 1 792 } 793 } 794 795 // loadStruct loads an object of type Struct. 796 func loadStruct(r Reader) Struct { 797 return Struct{ 798 TypeID: TypeID(loadUint(r)), 799 fields: Load(r), 800 } 801 } 802 803 // save implements Object.save. 804 // 805 // Precondition: Alloc must have been called, and the fields all filled in 806 // appropriately. See Alloc and Add for more details. 807 func (s *Struct) save(w Writer) { 808 Uint(s.TypeID).save(w) 809 Save(w, s.fields) 810 } 811 812 // load implements Object.load. 813 func (*Struct) load(r Reader) Object { 814 s := loadStruct(r) 815 return &s 816 } 817 818 // Object types. 819 // 820 // N.B. Be careful about changing the order or introducing new elements in the 821 // middle here. This is part of the wire format and shouldn't change. 822 const ( 823 typeBool Uint = iota 824 typeInt 825 typeUint 826 typeFloat32 827 typeFloat64 828 typeNil 829 typeRef 830 typeString 831 typeSlice 832 typeArray 833 typeMap 834 typeStruct 835 typeNoObjects 836 typeMultipleObjects 837 typeInterface 838 typeComplex64 839 typeComplex128 840 typeType 841 ) 842 843 // Save saves the given object. 844 // 845 // +checkescape all 846 // 847 // N.B. This function will panic on error. 848 func Save(w Writer, obj Object) { 849 switch x := obj.(type) { 850 case Bool: 851 typeBool.save(w) 852 x.save(w) 853 case Int: 854 typeInt.save(w) 855 x.save(w) 856 case Uint: 857 typeUint.save(w) 858 x.save(w) 859 case Float32: 860 typeFloat32.save(w) 861 x.save(w) 862 case Float64: 863 typeFloat64.save(w) 864 x.save(w) 865 case Nil: 866 typeNil.save(w) 867 x.save(w) 868 case *Ref: 869 typeRef.save(w) 870 x.save(w) 871 case *String: 872 typeString.save(w) 873 x.save(w) 874 case *Slice: 875 typeSlice.save(w) 876 x.save(w) 877 case *Array: 878 typeArray.save(w) 879 x.save(w) 880 case *Map: 881 typeMap.save(w) 882 x.save(w) 883 case *Struct: 884 typeStruct.save(w) 885 x.save(w) 886 case noObjects: 887 typeNoObjects.save(w) 888 x.save(w) 889 case *multipleObjects: 890 typeMultipleObjects.save(w) 891 x.save(w) 892 case *Interface: 893 typeInterface.save(w) 894 x.save(w) 895 case *Type: 896 typeType.save(w) 897 x.save(w) 898 case *Complex64: 899 typeComplex64.save(w) 900 x.save(w) 901 case *Complex128: 902 typeComplex128.save(w) 903 x.save(w) 904 default: 905 panic(fmt.Errorf("unknown type: %#v", obj)) 906 } 907 } 908 909 // Load loads a new object. 910 // 911 // +checkescape all 912 // 913 // N.B. This function will panic on error. 914 func Load(r Reader) Object { 915 switch hdr := loadUint(r); hdr { 916 case typeBool: 917 return loadBool(r) 918 case typeInt: 919 return loadInt(r) 920 case typeUint: 921 return loadUint(r) 922 case typeFloat32: 923 return loadFloat32(r) 924 case typeFloat64: 925 return loadFloat64(r) 926 case typeNil: 927 return loadNil(r) 928 case typeRef: 929 return ((*Ref)(nil)).load(r) // Escapes. 930 case typeString: 931 return ((*String)(nil)).load(r) // Escapes. 932 case typeSlice: 933 return ((*Slice)(nil)).load(r) // Escapes. 934 case typeArray: 935 return ((*Array)(nil)).load(r) // Escapes. 936 case typeMap: 937 return ((*Map)(nil)).load(r) // Escapes. 938 case typeStruct: 939 return ((*Struct)(nil)).load(r) // Escapes. 940 case typeNoObjects: // Special for struct. 941 return loadNoObjects(r) 942 case typeMultipleObjects: // Special for struct. 943 return ((*multipleObjects)(nil)).load(r) // Escapes. 944 case typeInterface: 945 return ((*Interface)(nil)).load(r) // Escapes. 946 case typeComplex64: 947 return ((*Complex64)(nil)).load(r) // Escapes. 948 case typeComplex128: 949 return ((*Complex128)(nil)).load(r) // Escapes. 950 case typeType: 951 return ((*Type)(nil)).load(r) // Escapes. 952 default: 953 // This is not a valid stream? 954 panic(fmt.Errorf("unknown header: %d", hdr)) 955 } 956 } 957 958 // LoadUint loads a single unsigned integer. 959 // 960 // N.B. This function will panic on error. 961 func LoadUint(r Reader) uint64 { 962 return uint64(loadUint(r)) 963 } 964 965 // SaveUint saves a single unsigned integer. 966 // 967 // N.B. This function will panic on error. 968 func SaveUint(w Writer, v uint64) { 969 Uint(v).save(w) 970 }