1 package json
2
3 import (
4 "context"
5 "fmt"
6 "io"
7 "reflect"
8 "unsafe"
9
10 "github.com/goccy/go-json/internal/decoder"
11 "github.com/goccy/go-json/internal/errors"
12 "github.com/goccy/go-json/internal/runtime"
13 )
14
15 type Decoder struct {
16 s *decoder.Stream
17 }
18
19 const (
20 nul = '\000'
21 )
22
23 type emptyInterface struct {
24 typ *runtime.Type
25 ptr unsafe.Pointer
26 }
27
28 func unmarshal(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
29 src := make([]byte, len(data)+1)
30 copy(src, data)
31
32 header := (*emptyInterface)(unsafe.Pointer(&v))
33
34 if err := validateType(header.typ, uintptr(header.ptr)); err != nil {
35 return err
36 }
37 dec, err := decoder.CompileToGetDecoder(header.typ)
38 if err != nil {
39 return err
40 }
41 ctx := decoder.TakeRuntimeContext()
42 ctx.Buf = src
43 ctx.Option.Flags = 0
44 for _, optFunc := range optFuncs {
45 optFunc(ctx.Option)
46 }
47 cursor, err := dec.Decode(ctx, 0, 0, header.ptr)
48 if err != nil {
49 decoder.ReleaseRuntimeContext(ctx)
50 return err
51 }
52 decoder.ReleaseRuntimeContext(ctx)
53 return validateEndBuf(src, cursor)
54 }
55
56 func unmarshalContext(ctx context.Context, data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
57 src := make([]byte, len(data)+1)
58 copy(src, data)
59
60 header := (*emptyInterface)(unsafe.Pointer(&v))
61
62 if err := validateType(header.typ, uintptr(header.ptr)); err != nil {
63 return err
64 }
65 dec, err := decoder.CompileToGetDecoder(header.typ)
66 if err != nil {
67 return err
68 }
69 rctx := decoder.TakeRuntimeContext()
70 rctx.Buf = src
71 rctx.Option.Flags = 0
72 rctx.Option.Flags |= decoder.ContextOption
73 rctx.Option.Context = ctx
74 for _, optFunc := range optFuncs {
75 optFunc(rctx.Option)
76 }
77 cursor, err := dec.Decode(rctx, 0, 0, header.ptr)
78 if err != nil {
79 decoder.ReleaseRuntimeContext(rctx)
80 return err
81 }
82 decoder.ReleaseRuntimeContext(rctx)
83 return validateEndBuf(src, cursor)
84 }
85
86 var (
87 pathDecoder = decoder.NewPathDecoder()
88 )
89
90 func extractFromPath(path *Path, data []byte, optFuncs ...DecodeOptionFunc) ([][]byte, error) {
91 if path.path.RootSelectorOnly {
92 return [][]byte{data}, nil
93 }
94 src := make([]byte, len(data)+1)
95 copy(src, data)
96
97 ctx := decoder.TakeRuntimeContext()
98 ctx.Buf = src
99 ctx.Option.Flags = 0
100 ctx.Option.Flags |= decoder.PathOption
101 ctx.Option.Path = path.path
102 for _, optFunc := range optFuncs {
103 optFunc(ctx.Option)
104 }
105 paths, cursor, err := pathDecoder.DecodePath(ctx, 0, 0)
106 if err != nil {
107 decoder.ReleaseRuntimeContext(ctx)
108 return nil, err
109 }
110 decoder.ReleaseRuntimeContext(ctx)
111 if err := validateEndBuf(src, cursor); err != nil {
112 return nil, err
113 }
114 return paths, nil
115 }
116
117 func unmarshalNoEscape(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
118 src := make([]byte, len(data)+1)
119 copy(src, data)
120
121 header := (*emptyInterface)(unsafe.Pointer(&v))
122
123 if err := validateType(header.typ, uintptr(header.ptr)); err != nil {
124 return err
125 }
126 dec, err := decoder.CompileToGetDecoder(header.typ)
127 if err != nil {
128 return err
129 }
130
131 ctx := decoder.TakeRuntimeContext()
132 ctx.Buf = src
133 ctx.Option.Flags = 0
134 for _, optFunc := range optFuncs {
135 optFunc(ctx.Option)
136 }
137 cursor, err := dec.Decode(ctx, 0, 0, noescape(header.ptr))
138 if err != nil {
139 decoder.ReleaseRuntimeContext(ctx)
140 return err
141 }
142 decoder.ReleaseRuntimeContext(ctx)
143 return validateEndBuf(src, cursor)
144 }
145
146 func validateEndBuf(src []byte, cursor int64) error {
147 for {
148 switch src[cursor] {
149 case ' ', '\t', '\n', '\r':
150 cursor++
151 continue
152 case nul:
153 return nil
154 }
155 return errors.ErrSyntax(
156 fmt.Sprintf("invalid character '%c' after top-level value", src[cursor]),
157 cursor+1,
158 )
159 }
160 }
161
162
163
164 func noescape(p unsafe.Pointer) unsafe.Pointer {
165 x := uintptr(p)
166 return unsafe.Pointer(x ^ 0)
167 }
168
169 func validateType(typ *runtime.Type, p uintptr) error {
170 if typ == nil || typ.Kind() != reflect.Ptr || p == 0 {
171 return &InvalidUnmarshalError{Type: runtime.RType2Type(typ)}
172 }
173 return nil
174 }
175
176
177
178
179
180 func NewDecoder(r io.Reader) *Decoder {
181 s := decoder.NewStream(r)
182 return &Decoder{
183 s: s,
184 }
185 }
186
187
188
189 func (d *Decoder) Buffered() io.Reader {
190 return d.s.Buffered()
191 }
192
193
194
195
196
197
198 func (d *Decoder) Decode(v interface{}) error {
199 return d.DecodeWithOption(v)
200 }
201
202
203
204 func (d *Decoder) DecodeContext(ctx context.Context, v interface{}) error {
205 d.s.Option.Flags |= decoder.ContextOption
206 d.s.Option.Context = ctx
207 return d.DecodeWithOption(v)
208 }
209
210 func (d *Decoder) DecodeWithOption(v interface{}, optFuncs ...DecodeOptionFunc) error {
211 header := (*emptyInterface)(unsafe.Pointer(&v))
212 typ := header.typ
213 ptr := uintptr(header.ptr)
214 typeptr := uintptr(unsafe.Pointer(typ))
215
216 copiedType := *(**runtime.Type)(unsafe.Pointer(&typeptr))
217
218 if err := validateType(copiedType, ptr); err != nil {
219 return err
220 }
221
222 dec, err := decoder.CompileToGetDecoder(typ)
223 if err != nil {
224 return err
225 }
226 if err := d.s.PrepareForDecode(); err != nil {
227 return err
228 }
229 s := d.s
230 for _, optFunc := range optFuncs {
231 optFunc(s.Option)
232 }
233 if err := dec.DecodeStream(s, 0, header.ptr); err != nil {
234 return err
235 }
236 s.Reset()
237 return nil
238 }
239
240 func (d *Decoder) More() bool {
241 return d.s.More()
242 }
243
244 func (d *Decoder) Token() (Token, error) {
245 return d.s.Token()
246 }
247
248
249
250
251 func (d *Decoder) DisallowUnknownFields() {
252 d.s.DisallowUnknownFields = true
253 }
254
255 func (d *Decoder) InputOffset() int64 {
256 return d.s.TotalOffset()
257 }
258
259
260
261 func (d *Decoder) UseNumber() {
262 d.s.UseNumber = true
263 }
264
View as plain text