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