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