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