...
1 package decoder
2
3 import (
4 "fmt"
5 "unsafe"
6
7 "github.com/goccy/go-json/internal/runtime"
8 )
9
10 type ptrDecoder struct {
11 dec Decoder
12 typ *runtime.Type
13 structName string
14 fieldName string
15 }
16
17 func newPtrDecoder(dec Decoder, typ *runtime.Type, structName, fieldName string) *ptrDecoder {
18 return &ptrDecoder{
19 dec: dec,
20 typ: typ,
21 structName: structName,
22 fieldName: fieldName,
23 }
24 }
25
26 func (d *ptrDecoder) contentDecoder() Decoder {
27 dec, ok := d.dec.(*ptrDecoder)
28 if !ok {
29 return d.dec
30 }
31 return dec.contentDecoder()
32 }
33
34
35
36 func unsafe_New(*runtime.Type) unsafe.Pointer
37
38 func UnsafeNew(t *runtime.Type) unsafe.Pointer {
39 return unsafe_New(t)
40 }
41
42 func (d *ptrDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
43 if s.skipWhiteSpace() == nul {
44 s.read()
45 }
46 if s.char() == 'n' {
47 if err := nullBytes(s); err != nil {
48 return err
49 }
50 *(*unsafe.Pointer)(p) = nil
51 return nil
52 }
53 var newptr unsafe.Pointer
54 if *(*unsafe.Pointer)(p) == nil {
55 newptr = unsafe_New(d.typ)
56 *(*unsafe.Pointer)(p) = newptr
57 } else {
58 newptr = *(*unsafe.Pointer)(p)
59 }
60 if err := d.dec.DecodeStream(s, depth, newptr); err != nil {
61 return err
62 }
63 return nil
64 }
65
66 func (d *ptrDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
67 buf := ctx.Buf
68 cursor = skipWhiteSpace(buf, cursor)
69 if buf[cursor] == 'n' {
70 if err := validateNull(buf, cursor); err != nil {
71 return 0, err
72 }
73 if p != nil {
74 *(*unsafe.Pointer)(p) = nil
75 }
76 cursor += 4
77 return cursor, nil
78 }
79 var newptr unsafe.Pointer
80 if *(*unsafe.Pointer)(p) == nil {
81 newptr = unsafe_New(d.typ)
82 *(*unsafe.Pointer)(p) = newptr
83 } else {
84 newptr = *(*unsafe.Pointer)(p)
85 }
86 c, err := d.dec.Decode(ctx, cursor, depth, newptr)
87 if err != nil {
88 return 0, err
89 }
90 cursor = c
91 return cursor, nil
92 }
93
94 func (d *ptrDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
95 return nil, 0, fmt.Errorf("json: ptr decoder does not support decode path")
96 }
97
View as plain text