1
2
3
4
5
6
7 package json
8
9 import (
10 "cmp"
11 "reflect"
12 "strconv"
13
14 "encoding/json/internal"
15 "encoding/json/internal/jsonflags"
16 "encoding/json/internal/jsonopts"
17 "encoding/json/internal/jsonwire"
18 "encoding/json/jsontext"
19 )
20
21
22
23
24
25
26
27
28
29 func marshalValueAny(enc *jsontext.Encoder, val any, mo *jsonopts.Struct) error {
30 switch val := val.(type) {
31 case nil:
32 return enc.WriteToken(jsontext.Null)
33 case bool:
34 return enc.WriteToken(jsontext.Bool(val))
35 case string:
36 return enc.WriteToken(jsontext.String(val))
37 case float64:
38 return enc.WriteToken(jsontext.Float(val))
39 case map[string]any:
40 return marshalObjectAny(enc, val, mo)
41 case []any:
42 return marshalArrayAny(enc, val, mo)
43 default:
44 v := newAddressableValue(reflect.TypeOf(val))
45 v.Set(reflect.ValueOf(val))
46 marshal := lookupArshaler(v.Type()).marshal
47 if mo.Marshalers != nil {
48 marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, v.Type())
49 }
50 return marshal(enc, v, mo)
51 }
52 }
53
54
55
56
57
58 func unmarshalValueAny(dec *jsontext.Decoder, uo *jsonopts.Struct) (any, error) {
59 switch k := dec.PeekKind(); k {
60 case '{':
61 return unmarshalObjectAny(dec, uo)
62 case '[':
63 return unmarshalArrayAny(dec, uo)
64 default:
65 xd := export.Decoder(dec)
66 var flags jsonwire.ValueFlags
67 val, err := xd.ReadValue(&flags)
68 if err != nil {
69 return nil, err
70 }
71 switch val.Kind() {
72 case 'n':
73 return nil, nil
74 case 'f':
75 return false, nil
76 case 't':
77 return true, nil
78 case '"':
79 val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
80 if xd.StringCache == nil {
81 xd.StringCache = new(stringCache)
82 }
83 return makeString(xd.StringCache, val), nil
84 case '0':
85 if uo.Flags.Get(jsonflags.UnmarshalAnyWithRawNumber) {
86 return internal.RawNumberOf(val), nil
87 }
88 fv, ok := jsonwire.ParseFloat(val, 64)
89 if !ok {
90 return fv, newUnmarshalErrorAfterWithValue(dec, float64Type, strconv.ErrRange)
91 }
92 return fv, nil
93 default:
94 panic("BUG: invalid kind: " + k.String())
95 }
96 }
97 }
98
99
100
101 func marshalObjectAny(enc *jsontext.Encoder, obj map[string]any, mo *jsonopts.Struct) error {
102
103 xe := export.Encoder(enc)
104 if xe.Tokens.Depth() > startDetectingCyclesAfter {
105 v := reflect.ValueOf(obj)
106 if err := visitPointer(&xe.SeenPointers, v); err != nil {
107 return newMarshalErrorBefore(enc, anyType, err)
108 }
109 defer leavePointer(&xe.SeenPointers, v)
110 }
111
112
113 if len(obj) == 0 {
114 if mo.Flags.Get(jsonflags.FormatNilMapAsNull) && obj == nil {
115 return enc.WriteToken(jsontext.Null)
116 }
117
118 if !mo.Flags.Get(jsonflags.AnyWhitespace) && !xe.Tokens.Last.NeedObjectName() {
119 xe.Buf = append(xe.Tokens.MayAppendDelim(xe.Buf, '{'), "{}"...)
120 xe.Tokens.Last.Increment()
121 if xe.NeedFlush() {
122 return xe.Flush()
123 }
124 return nil
125 }
126 }
127
128 if err := enc.WriteToken(jsontext.BeginObject); err != nil {
129 return err
130 }
131
132
133 if !mo.Flags.Get(jsonflags.AllowInvalidUTF8) {
134 xe.Tokens.Last.DisableNamespace()
135 }
136 if !mo.Flags.Get(jsonflags.Deterministic) || len(obj) <= 1 {
137 for name, val := range obj {
138 if err := enc.WriteToken(jsontext.String(name)); err != nil {
139 return err
140 }
141 if err := marshalValueAny(enc, val, mo); err != nil {
142 return err
143 }
144 }
145 } else {
146 names := getStrings(len(obj))
147 var i int
148 for name := range obj {
149 (*names)[i] = name
150 i++
151 }
152 names.Sort()
153 for _, name := range *names {
154 if err := enc.WriteToken(jsontext.String(name)); err != nil {
155 return err
156 }
157 if err := marshalValueAny(enc, obj[name], mo); err != nil {
158 return err
159 }
160 }
161 putStrings(names)
162 }
163 if err := enc.WriteToken(jsontext.EndObject); err != nil {
164 return err
165 }
166 return nil
167 }
168
169
170
171 func unmarshalObjectAny(dec *jsontext.Decoder, uo *jsonopts.Struct) (map[string]any, error) {
172 switch tok, err := dec.ReadToken(); {
173 case err != nil:
174 return nil, err
175 case tok.Kind() != '{':
176 panic("BUG: invalid kind: " + tok.Kind().String())
177 }
178 obj := make(map[string]any)
179
180
181 if !uo.Flags.Get(jsonflags.AllowInvalidUTF8) {
182 export.Decoder(dec).Tokens.Last.DisableNamespace()
183 }
184 var errUnmarshal error
185 for dec.PeekKind() != '}' {
186 tok, err := dec.ReadToken()
187 if err != nil {
188 return obj, err
189 }
190 name := tok.String()
191
192
193 if _, ok := obj[name]; ok {
194
195 name := export.Decoder(dec).PreviousTokenOrValue()
196 err := newDuplicateNameError(dec.StackPointer(), nil, dec.InputOffset()-len64(name))
197 return obj, err
198 }
199
200 val, err := unmarshalValueAny(dec, uo)
201 obj[name] = val
202 if err != nil {
203 if isFatalError(err, uo.Flags) {
204 return obj, err
205 }
206 errUnmarshal = cmp.Or(err, errUnmarshal)
207 }
208 }
209 if _, err := dec.ReadToken(); err != nil {
210 return obj, err
211 }
212 return obj, errUnmarshal
213 }
214
215
216
217 func marshalArrayAny(enc *jsontext.Encoder, arr []any, mo *jsonopts.Struct) error {
218
219 xe := export.Encoder(enc)
220 if xe.Tokens.Depth() > startDetectingCyclesAfter {
221 v := reflect.ValueOf(arr)
222 if err := visitPointer(&xe.SeenPointers, v); err != nil {
223 return newMarshalErrorBefore(enc, sliceAnyType, err)
224 }
225 defer leavePointer(&xe.SeenPointers, v)
226 }
227
228
229 if len(arr) == 0 {
230 if mo.Flags.Get(jsonflags.FormatNilSliceAsNull) && arr == nil {
231 return enc.WriteToken(jsontext.Null)
232 }
233
234 if !mo.Flags.Get(jsonflags.AnyWhitespace) && !xe.Tokens.Last.NeedObjectName() {
235 xe.Buf = append(xe.Tokens.MayAppendDelim(xe.Buf, '['), "[]"...)
236 xe.Tokens.Last.Increment()
237 if xe.NeedFlush() {
238 return xe.Flush()
239 }
240 return nil
241 }
242 }
243
244 if err := enc.WriteToken(jsontext.BeginArray); err != nil {
245 return err
246 }
247 for _, val := range arr {
248 if err := marshalValueAny(enc, val, mo); err != nil {
249 return err
250 }
251 }
252 if err := enc.WriteToken(jsontext.EndArray); err != nil {
253 return err
254 }
255 return nil
256 }
257
258
259
260 func unmarshalArrayAny(dec *jsontext.Decoder, uo *jsonopts.Struct) ([]any, error) {
261 switch tok, err := dec.ReadToken(); {
262 case err != nil:
263 return nil, err
264 case tok.Kind() != '[':
265 panic("BUG: invalid kind: " + tok.Kind().String())
266 }
267 arr := []any{}
268 var errUnmarshal error
269 for dec.PeekKind() != ']' {
270 val, err := unmarshalValueAny(dec, uo)
271 arr = append(arr, val)
272 if err != nil {
273 if isFatalError(err, uo.Flags) {
274 return arr, err
275 }
276 errUnmarshal = cmp.Or(errUnmarshal, err)
277 }
278 }
279 if _, err := dec.ReadToken(); err != nil {
280 return arr, err
281 }
282 return arr, errUnmarshal
283 }
284
View as plain text