/
value_writer.go
128 lines (120 loc) · 2.82 KB
/
value_writer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package vdl
import (
"fmt"
)
// VDLWrite writes this vdl Value to the encoder.
func (vv *Value) VDLWrite(enc Encoder) error {
// TODO(bprosnitz) Change this for new vv logic
if vv.Kind() == Any {
if vv.IsNil() {
return enc.NilValue(vv.Type())
}
vv = vv.Elem()
}
if vv.Kind() == Optional {
enc.SetNextStartValueIsOptional()
if vv.IsNil() {
return enc.NilValue(vv.Type())
}
vv = vv.Elem()
}
if err := enc.StartValue(vv.Type()); err != nil {
return err
}
if err := vv.writeNonNilValue(enc); err != nil {
return err
}
return enc.FinishValue()
}
func (vv *Value) writeNonNilValue(enc Encoder) error {
if vv.Type().IsBytes() {
return enc.EncodeBytes(vv.Bytes())
}
switch vv.Kind() {
case Bool:
return enc.EncodeBool(vv.Bool())
case Byte, Uint16, Uint32, Uint64:
return enc.EncodeUint(vv.Uint())
case Int8, Int16, Int32, Int64:
return enc.EncodeInt(vv.Int())
case Float32, Float64:
return enc.EncodeFloat(vv.Float())
case String:
return enc.EncodeString(vv.RawString())
case TypeObject:
return enc.EncodeTypeObject(vv.TypeObject())
case Enum:
return enc.EncodeString(vv.EnumLabel())
case Array, List:
return vv.writeArrayOrList(enc)
case Set, Map:
return vv.writeSetOrMap(enc)
case Struct:
return vv.writeStruct(enc)
case Union:
return vv.writeUnion(enc)
}
panic(fmt.Sprintf("unknown kind: %v", vv.Kind()))
}
func (vv *Value) writeArrayOrList(enc Encoder) error {
if vv.Kind() == List {
if err := enc.SetLenHint(vv.Len()); err != nil {
return err
}
}
for i := 0; i < vv.Len(); i++ {
if err := enc.NextEntry(false); err != nil {
return err
}
if err := vv.Index(i).VDLWrite(enc); err != nil {
return err
}
}
return enc.NextEntry(true)
}
func (vv *Value) writeSetOrMap(enc Encoder) error {
if err := enc.SetLenHint(vv.Len()); err != nil {
return err
}
for _, key := range vv.Keys() {
if err := enc.NextEntry(false); err != nil {
return err
}
if err := key.VDLWrite(enc); err != nil {
return err
}
if vv.Kind() == Map {
if err := vv.MapIndex(key).VDLWrite(enc); err != nil {
return err
}
}
}
return enc.NextEntry(true)
}
func (vv *Value) writeStruct(enc Encoder) error {
for index := 0; index < vv.Type().NumField(); index++ {
if vv.StructField(index).IsZero() {
continue
}
if err := enc.NextField(index); err != nil {
return err
}
if err := vv.StructField(index).VDLWrite(enc); err != nil {
return err
}
}
return enc.NextField(-1)
}
func (vv *Value) writeUnion(enc Encoder) error {
index, field := vv.UnionField()
if err := enc.NextField(index); err != nil {
return err
}
if err := field.VDLWrite(enc); err != nil {
return err
}
return enc.NextField(-1)
}