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