1 package decoder
2
3 import (
4 "bytes"
5 "encoding"
6 "encoding/json"
7 "reflect"
8 "unsafe"
9
10 "github.com/goccy/go-json/internal/errors"
11 "github.com/goccy/go-json/internal/runtime"
12 )
13
14 type interfaceDecoder struct {
15 typ *runtime.Type
16 structName string
17 fieldName string
18 sliceDecoder *sliceDecoder
19 mapDecoder *mapDecoder
20 floatDecoder *floatDecoder
21 numberDecoder *numberDecoder
22 stringDecoder *stringDecoder
23 }
24
25 func newEmptyInterfaceDecoder(structName, fieldName string) *interfaceDecoder {
26 ifaceDecoder := &interfaceDecoder{
27 typ: emptyInterfaceType,
28 structName: structName,
29 fieldName: fieldName,
30 floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
31 *(*interface{})(p) = v
32 }),
33 numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) {
34 *(*interface{})(p) = v
35 }),
36 stringDecoder: newStringDecoder(structName, fieldName),
37 }
38 ifaceDecoder.sliceDecoder = newSliceDecoder(
39 ifaceDecoder,
40 emptyInterfaceType,
41 emptyInterfaceType.Size(),
42 structName, fieldName,
43 )
44 ifaceDecoder.mapDecoder = newMapDecoder(
45 interfaceMapType,
46 stringType,
47 ifaceDecoder.stringDecoder,
48 interfaceMapType.Elem(),
49 ifaceDecoder,
50 structName,
51 fieldName,
52 )
53 return ifaceDecoder
54 }
55
56 func newInterfaceDecoder(typ *runtime.Type, structName, fieldName string) *interfaceDecoder {
57 emptyIfaceDecoder := newEmptyInterfaceDecoder(structName, fieldName)
58 stringDecoder := newStringDecoder(structName, fieldName)
59 return &interfaceDecoder{
60 typ: typ,
61 structName: structName,
62 fieldName: fieldName,
63 sliceDecoder: newSliceDecoder(
64 emptyIfaceDecoder,
65 emptyInterfaceType,
66 emptyInterfaceType.Size(),
67 structName, fieldName,
68 ),
69 mapDecoder: newMapDecoder(
70 interfaceMapType,
71 stringType,
72 stringDecoder,
73 interfaceMapType.Elem(),
74 emptyIfaceDecoder,
75 structName,
76 fieldName,
77 ),
78 floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
79 *(*interface{})(p) = v
80 }),
81 numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) {
82 *(*interface{})(p) = v
83 }),
84 stringDecoder: stringDecoder,
85 }
86 }
87
88 func (d *interfaceDecoder) numDecoder(s *Stream) Decoder {
89 if s.UseNumber {
90 return d.numberDecoder
91 }
92 return d.floatDecoder
93 }
94
95 var (
96 emptyInterfaceType = runtime.Type2RType(reflect.TypeOf((*interface{})(nil)).Elem())
97 EmptyInterfaceType = emptyInterfaceType
98 interfaceMapType = runtime.Type2RType(
99 reflect.TypeOf((*map[string]interface{})(nil)).Elem(),
100 )
101 stringType = runtime.Type2RType(
102 reflect.TypeOf(""),
103 )
104 )
105
106 func decodeStreamUnmarshaler(s *Stream, depth int64, unmarshaler json.Unmarshaler) error {
107 start := s.cursor
108 if err := s.skipValue(depth); err != nil {
109 return err
110 }
111 src := s.buf[start:s.cursor]
112 dst := make([]byte, len(src))
113 copy(dst, src)
114
115 if err := unmarshaler.UnmarshalJSON(dst); err != nil {
116 return err
117 }
118 return nil
119 }
120
121 func decodeStreamUnmarshalerContext(s *Stream, depth int64, unmarshaler unmarshalerContext) error {
122 start := s.cursor
123 if err := s.skipValue(depth); err != nil {
124 return err
125 }
126 src := s.buf[start:s.cursor]
127 dst := make([]byte, len(src))
128 copy(dst, src)
129
130 if err := unmarshaler.UnmarshalJSON(s.Option.Context, dst); err != nil {
131 return err
132 }
133 return nil
134 }
135
136 func decodeUnmarshaler(buf []byte, cursor, depth int64, unmarshaler json.Unmarshaler) (int64, error) {
137 cursor = skipWhiteSpace(buf, cursor)
138 start := cursor
139 end, err := skipValue(buf, cursor, depth)
140 if err != nil {
141 return 0, err
142 }
143 src := buf[start:end]
144 dst := make([]byte, len(src))
145 copy(dst, src)
146
147 if err := unmarshaler.UnmarshalJSON(dst); err != nil {
148 return 0, err
149 }
150 return end, nil
151 }
152
153 func decodeUnmarshalerContext(ctx *RuntimeContext, buf []byte, cursor, depth int64, unmarshaler unmarshalerContext) (int64, error) {
154 cursor = skipWhiteSpace(buf, cursor)
155 start := cursor
156 end, err := skipValue(buf, cursor, depth)
157 if err != nil {
158 return 0, err
159 }
160 src := buf[start:end]
161 dst := make([]byte, len(src))
162 copy(dst, src)
163
164 if err := unmarshaler.UnmarshalJSON(ctx.Option.Context, dst); err != nil {
165 return 0, err
166 }
167 return end, nil
168 }
169
170 func decodeStreamTextUnmarshaler(s *Stream, depth int64, unmarshaler encoding.TextUnmarshaler, p unsafe.Pointer) error {
171 start := s.cursor
172 if err := s.skipValue(depth); err != nil {
173 return err
174 }
175 src := s.buf[start:s.cursor]
176 if bytes.Equal(src, nullbytes) {
177 *(*unsafe.Pointer)(p) = nil
178 return nil
179 }
180
181 dst := make([]byte, len(src))
182 copy(dst, src)
183
184 if err := unmarshaler.UnmarshalText(dst); err != nil {
185 return err
186 }
187 return nil
188 }
189
190 func decodeTextUnmarshaler(buf []byte, cursor, depth int64, unmarshaler encoding.TextUnmarshaler, p unsafe.Pointer) (int64, error) {
191 cursor = skipWhiteSpace(buf, cursor)
192 start := cursor
193 end, err := skipValue(buf, cursor, depth)
194 if err != nil {
195 return 0, err
196 }
197 src := buf[start:end]
198 if bytes.Equal(src, nullbytes) {
199 *(*unsafe.Pointer)(p) = nil
200 return end, nil
201 }
202 if s, ok := unquoteBytes(src); ok {
203 src = s
204 }
205 if err := unmarshaler.UnmarshalText(src); err != nil {
206 return 0, err
207 }
208 return end, nil
209 }
210
211 func (d *interfaceDecoder) decodeStreamEmptyInterface(s *Stream, depth int64, p unsafe.Pointer) error {
212 c := s.skipWhiteSpace()
213 for {
214 switch c {
215 case '{':
216 var v map[string]interface{}
217 ptr := unsafe.Pointer(&v)
218 if err := d.mapDecoder.DecodeStream(s, depth, ptr); err != nil {
219 return err
220 }
221 *(*interface{})(p) = v
222 return nil
223 case '[':
224 var v []interface{}
225 ptr := unsafe.Pointer(&v)
226 if err := d.sliceDecoder.DecodeStream(s, depth, ptr); err != nil {
227 return err
228 }
229 *(*interface{})(p) = v
230 return nil
231 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
232 return d.numDecoder(s).DecodeStream(s, depth, p)
233 case '"':
234 s.cursor++
235 start := s.cursor
236 for {
237 switch s.char() {
238 case '\\':
239 if _, err := decodeEscapeString(s, nil); err != nil {
240 return err
241 }
242 case '"':
243 literal := s.buf[start:s.cursor]
244 s.cursor++
245 *(*interface{})(p) = string(literal)
246 return nil
247 case nul:
248 if s.read() {
249 continue
250 }
251 return errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
252 }
253 s.cursor++
254 }
255 case 't':
256 if err := trueBytes(s); err != nil {
257 return err
258 }
259 **(**interface{})(unsafe.Pointer(&p)) = true
260 return nil
261 case 'f':
262 if err := falseBytes(s); err != nil {
263 return err
264 }
265 **(**interface{})(unsafe.Pointer(&p)) = false
266 return nil
267 case 'n':
268 if err := nullBytes(s); err != nil {
269 return err
270 }
271 *(*interface{})(p) = nil
272 return nil
273 case nul:
274 if s.read() {
275 c = s.char()
276 continue
277 }
278 }
279 break
280 }
281 return errors.ErrInvalidBeginningOfValue(c, s.totalOffset())
282 }
283
284 type emptyInterface struct {
285 typ *runtime.Type
286 ptr unsafe.Pointer
287 }
288
289 func (d *interfaceDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
290 runtimeInterfaceValue := *(*interface{})(unsafe.Pointer(&emptyInterface{
291 typ: d.typ,
292 ptr: p,
293 }))
294 rv := reflect.ValueOf(runtimeInterfaceValue)
295 if rv.NumMethod() > 0 && rv.CanInterface() {
296 if u, ok := rv.Interface().(unmarshalerContext); ok {
297 return decodeStreamUnmarshalerContext(s, depth, u)
298 }
299 if u, ok := rv.Interface().(json.Unmarshaler); ok {
300 return decodeStreamUnmarshaler(s, depth, u)
301 }
302 if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
303 return decodeStreamTextUnmarshaler(s, depth, u, p)
304 }
305 if s.skipWhiteSpace() == 'n' {
306 if err := nullBytes(s); err != nil {
307 return err
308 }
309 *(*interface{})(p) = nil
310 return nil
311 }
312 return d.errUnmarshalType(rv.Type(), s.totalOffset())
313 }
314 iface := rv.Interface()
315 ifaceHeader := (*emptyInterface)(unsafe.Pointer(&iface))
316 typ := ifaceHeader.typ
317 if ifaceHeader.ptr == nil || d.typ == typ || typ == nil {
318
319 return d.decodeStreamEmptyInterface(s, depth, p)
320 }
321 if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr {
322 return d.decodeStreamEmptyInterface(s, depth, p)
323 }
324 if s.skipWhiteSpace() == 'n' {
325 if err := nullBytes(s); err != nil {
326 return err
327 }
328 *(*interface{})(p) = nil
329 return nil
330 }
331 decoder, err := CompileToGetDecoder(typ)
332 if err != nil {
333 return err
334 }
335 return decoder.DecodeStream(s, depth, ifaceHeader.ptr)
336 }
337
338 func (d *interfaceDecoder) errUnmarshalType(typ reflect.Type, offset int64) *errors.UnmarshalTypeError {
339 return &errors.UnmarshalTypeError{
340 Value: typ.String(),
341 Type: typ,
342 Offset: offset,
343 Struct: d.structName,
344 Field: d.fieldName,
345 }
346 }
347
348 func (d *interfaceDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
349 buf := ctx.Buf
350 runtimeInterfaceValue := *(*interface{})(unsafe.Pointer(&emptyInterface{
351 typ: d.typ,
352 ptr: p,
353 }))
354 rv := reflect.ValueOf(runtimeInterfaceValue)
355 if rv.NumMethod() > 0 && rv.CanInterface() {
356 if u, ok := rv.Interface().(unmarshalerContext); ok {
357 return decodeUnmarshalerContext(ctx, buf, cursor, depth, u)
358 }
359 if u, ok := rv.Interface().(json.Unmarshaler); ok {
360 return decodeUnmarshaler(buf, cursor, depth, u)
361 }
362 if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
363 return decodeTextUnmarshaler(buf, cursor, depth, u, p)
364 }
365 cursor = skipWhiteSpace(buf, cursor)
366 if buf[cursor] == 'n' {
367 if err := validateNull(buf, cursor); err != nil {
368 return 0, err
369 }
370 cursor += 4
371 **(**interface{})(unsafe.Pointer(&p)) = nil
372 return cursor, nil
373 }
374 return 0, d.errUnmarshalType(rv.Type(), cursor)
375 }
376
377 iface := rv.Interface()
378 ifaceHeader := (*emptyInterface)(unsafe.Pointer(&iface))
379 typ := ifaceHeader.typ
380 if ifaceHeader.ptr == nil || d.typ == typ || typ == nil {
381
382 return d.decodeEmptyInterface(ctx, cursor, depth, p)
383 }
384 if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr {
385 return d.decodeEmptyInterface(ctx, cursor, depth, p)
386 }
387 cursor = skipWhiteSpace(buf, cursor)
388 if buf[cursor] == 'n' {
389 if err := validateNull(buf, cursor); err != nil {
390 return 0, err
391 }
392 cursor += 4
393 **(**interface{})(unsafe.Pointer(&p)) = nil
394 return cursor, nil
395 }
396 decoder, err := CompileToGetDecoder(typ)
397 if err != nil {
398 return 0, err
399 }
400 return decoder.Decode(ctx, cursor, depth, ifaceHeader.ptr)
401 }
402
403 func (d *interfaceDecoder) decodeEmptyInterface(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
404 buf := ctx.Buf
405 cursor = skipWhiteSpace(buf, cursor)
406 switch buf[cursor] {
407 case '{':
408 var v map[string]interface{}
409 ptr := unsafe.Pointer(&v)
410 cursor, err := d.mapDecoder.Decode(ctx, cursor, depth, ptr)
411 if err != nil {
412 return 0, err
413 }
414 **(**interface{})(unsafe.Pointer(&p)) = v
415 return cursor, nil
416 case '[':
417 var v []interface{}
418 ptr := unsafe.Pointer(&v)
419 cursor, err := d.sliceDecoder.Decode(ctx, cursor, depth, ptr)
420 if err != nil {
421 return 0, err
422 }
423 **(**interface{})(unsafe.Pointer(&p)) = v
424 return cursor, nil
425 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
426 return d.floatDecoder.Decode(ctx, cursor, depth, p)
427 case '"':
428 var v string
429 ptr := unsafe.Pointer(&v)
430 cursor, err := d.stringDecoder.Decode(ctx, cursor, depth, ptr)
431 if err != nil {
432 return 0, err
433 }
434 **(**interface{})(unsafe.Pointer(&p)) = v
435 return cursor, nil
436 case 't':
437 if err := validateTrue(buf, cursor); err != nil {
438 return 0, err
439 }
440 cursor += 4
441 **(**interface{})(unsafe.Pointer(&p)) = true
442 return cursor, nil
443 case 'f':
444 if err := validateFalse(buf, cursor); err != nil {
445 return 0, err
446 }
447 cursor += 5
448 **(**interface{})(unsafe.Pointer(&p)) = false
449 return cursor, nil
450 case 'n':
451 if err := validateNull(buf, cursor); err != nil {
452 return 0, err
453 }
454 cursor += 4
455 **(**interface{})(unsafe.Pointer(&p)) = nil
456 return cursor, nil
457 }
458 return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
459 }
460
461 func NewPathDecoder() Decoder {
462 ifaceDecoder := &interfaceDecoder{
463 typ: emptyInterfaceType,
464 structName: "",
465 fieldName: "",
466 floatDecoder: newFloatDecoder("", "", func(p unsafe.Pointer, v float64) {
467 *(*interface{})(p) = v
468 }),
469 numberDecoder: newNumberDecoder("", "", func(p unsafe.Pointer, v json.Number) {
470 *(*interface{})(p) = v
471 }),
472 stringDecoder: newStringDecoder("", ""),
473 }
474 ifaceDecoder.sliceDecoder = newSliceDecoder(
475 ifaceDecoder,
476 emptyInterfaceType,
477 emptyInterfaceType.Size(),
478 "", "",
479 )
480 ifaceDecoder.mapDecoder = newMapDecoder(
481 interfaceMapType,
482 stringType,
483 ifaceDecoder.stringDecoder,
484 interfaceMapType.Elem(),
485 ifaceDecoder,
486 "", "",
487 )
488 return ifaceDecoder
489 }
490
491 var (
492 truebytes = []byte("true")
493 falsebytes = []byte("false")
494 )
495
496 func (d *interfaceDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
497 buf := ctx.Buf
498 cursor = skipWhiteSpace(buf, cursor)
499 switch buf[cursor] {
500 case '{':
501 return d.mapDecoder.DecodePath(ctx, cursor, depth)
502 case '[':
503 return d.sliceDecoder.DecodePath(ctx, cursor, depth)
504 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
505 return d.floatDecoder.DecodePath(ctx, cursor, depth)
506 case '"':
507 return d.stringDecoder.DecodePath(ctx, cursor, depth)
508 case 't':
509 if err := validateTrue(buf, cursor); err != nil {
510 return nil, 0, err
511 }
512 cursor += 4
513 return [][]byte{truebytes}, cursor, nil
514 case 'f':
515 if err := validateFalse(buf, cursor); err != nil {
516 return nil, 0, err
517 }
518 cursor += 5
519 return [][]byte{falsebytes}, cursor, nil
520 case 'n':
521 if err := validateNull(buf, cursor); err != nil {
522 return nil, 0, err
523 }
524 cursor += 4
525 return [][]byte{nullbytes}, cursor, nil
526 }
527 return nil, cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
528 }
529
View as plain text