]>
Commit | Line | Data |
---|---|---|
15c0b25d AP |
1 | package cty |
2 | ||
3 | import ( | |
4 | "bytes" | |
5 | "encoding/gob" | |
6 | "fmt" | |
7 | "math/big" | |
8 | ) | |
9 | ||
10 | // GobEncode is an implementation of the gob.GobEncoder interface, which | |
11 | // allows Values to be included in structures encoded with encoding/gob. | |
12 | // | |
13 | // Currently it is not possible to represent values of capsule types in gob, | |
14 | // because the types themselves cannot be represented. | |
15 | func (val Value) GobEncode() ([]byte, error) { | |
16 | buf := &bytes.Buffer{} | |
17 | enc := gob.NewEncoder(buf) | |
18 | ||
19 | gv := gobValue{ | |
20 | Version: 0, | |
21 | Ty: val.ty, | |
22 | V: val.v, | |
23 | } | |
24 | ||
25 | err := enc.Encode(gv) | |
26 | if err != nil { | |
27 | return nil, fmt.Errorf("error encoding cty.Value: %s", err) | |
28 | } | |
29 | ||
30 | return buf.Bytes(), nil | |
31 | } | |
32 | ||
33 | // GobDecode is an implementation of the gob.GobDecoder interface, which | |
34 | // inverts the operation performed by GobEncode. See the documentation of | |
35 | // GobEncode for considerations when using cty.Value instances with gob. | |
36 | func (val *Value) GobDecode(buf []byte) error { | |
37 | r := bytes.NewReader(buf) | |
38 | dec := gob.NewDecoder(r) | |
39 | ||
40 | var gv gobValue | |
41 | err := dec.Decode(&gv) | |
42 | if err != nil { | |
43 | return fmt.Errorf("error decoding cty.Value: %s", err) | |
44 | } | |
45 | if gv.Version != 0 { | |
46 | return fmt.Errorf("unsupported cty.Value encoding version %d; only 0 is supported", gv.Version) | |
47 | } | |
48 | ||
49 | // big.Float seems to, for some reason, lose its "pointerness" when we | |
50 | // round-trip it, so we'll fix that here. | |
51 | if bf, ok := gv.V.(big.Float); ok { | |
52 | gv.V = &bf | |
53 | } | |
54 | ||
55 | val.ty = gv.Ty | |
56 | val.v = gv.V | |
57 | ||
58 | return nil | |
59 | } | |
60 | ||
61 | // GobEncode is an implementation of the gob.GobEncoder interface, which | |
62 | // allows Types to be included in structures encoded with encoding/gob. | |
63 | // | |
64 | // Currently it is not possible to represent capsule types in gob. | |
65 | func (t Type) GobEncode() ([]byte, error) { | |
66 | buf := &bytes.Buffer{} | |
67 | enc := gob.NewEncoder(buf) | |
68 | ||
69 | gt := gobType{ | |
70 | Version: 0, | |
71 | Impl: t.typeImpl, | |
72 | } | |
73 | ||
74 | err := enc.Encode(gt) | |
75 | if err != nil { | |
76 | return nil, fmt.Errorf("error encoding cty.Type: %s", err) | |
77 | } | |
78 | ||
79 | return buf.Bytes(), nil | |
80 | } | |
81 | ||
82 | // GobDecode is an implementatino of the gob.GobDecoder interface, which | |
83 | // reverses the encoding performed by GobEncode to allow types to be recovered | |
84 | // from gob buffers. | |
85 | func (t *Type) GobDecode(buf []byte) error { | |
86 | r := bytes.NewReader(buf) | |
87 | dec := gob.NewDecoder(r) | |
88 | ||
89 | var gt gobType | |
90 | err := dec.Decode(>) | |
91 | if err != nil { | |
92 | return fmt.Errorf("error decoding cty.Type: %s", err) | |
93 | } | |
94 | if gt.Version != 0 { | |
95 | return fmt.Errorf("unsupported cty.Type encoding version %d; only 0 is supported", gt.Version) | |
96 | } | |
97 | ||
98 | t.typeImpl = gt.Impl | |
99 | ||
100 | return nil | |
101 | } | |
102 | ||
103 | // Capsule types cannot currently be gob-encoded, because they rely on pointer | |
104 | // equality and we have no way to recover the original pointer on decode. | |
105 | func (t *capsuleType) GobEncode() ([]byte, error) { | |
107c1cdb | 106 | return nil, fmt.Errorf("cannot gob-encode capsule type %q", t.FriendlyName(friendlyTypeName)) |
15c0b25d AP |
107 | } |
108 | ||
109 | func (t *capsuleType) GobDecode() ([]byte, error) { | |
107c1cdb | 110 | return nil, fmt.Errorf("cannot gob-decode capsule type %q", t.FriendlyName(friendlyTypeName)) |
15c0b25d AP |
111 | } |
112 | ||
113 | type gobValue struct { | |
114 | Version int | |
115 | Ty Type | |
116 | V interface{} | |
117 | } | |
118 | ||
119 | type gobType struct { | |
120 | Version int | |
121 | Impl typeImpl | |
122 | } | |
123 | ||
124 | type gobCapsuleTypeImpl struct { | |
125 | } |