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