...
1
16
17 package decoder
18
19 import (
20 `unsafe`
21 `encoding/json`
22 `reflect`
23 `runtime`
24
25 `github.com/bytedance/sonic/internal/native`
26 `github.com/bytedance/sonic/internal/native/types`
27 `github.com/bytedance/sonic/internal/rt`
28 `github.com/bytedance/sonic/option`
29 `github.com/bytedance/sonic/utf8`
30 )
31
32 const (
33 _F_use_int64 = 0
34 _F_disable_urc = 2
35 _F_disable_unknown = 3
36 _F_copy_string = 4
37
38 _F_use_number = types.B_USE_NUMBER
39 _F_validate_string = types.B_VALIDATE_STRING
40 _F_allow_control = types.B_ALLOW_CONTROL
41 )
42
43 type Options uint64
44
45 const (
46 OptionUseInt64 Options = 1 << _F_use_int64
47 OptionUseNumber Options = 1 << _F_use_number
48 OptionUseUnicodeErrors Options = 1 << _F_disable_urc
49 OptionDisableUnknown Options = 1 << _F_disable_unknown
50 OptionCopyString Options = 1 << _F_copy_string
51 OptionValidateString Options = 1 << _F_validate_string
52 )
53
54 func (self *Decoder) SetOptions(opts Options) {
55 if (opts & OptionUseNumber != 0) && (opts & OptionUseInt64 != 0) {
56 panic("can't set OptionUseInt64 and OptionUseNumber both!")
57 }
58 self.f = uint64(opts)
59 }
60
61
62
63 type Decoder struct {
64 i int
65 f uint64
66 s string
67 }
68
69
70 func NewDecoder(s string) *Decoder {
71 return &Decoder{s: s}
72 }
73
74
75 func (self *Decoder) Pos() int {
76 return self.i
77 }
78
79 func (self *Decoder) Reset(s string) {
80 self.s = s
81 self.i = 0
82
83 }
84
85 func (self *Decoder) CheckTrailings() error {
86 pos := self.i
87 buf := self.s
88
89 if pos != len(buf) {
90 for pos < len(buf) && (types.SPACE_MASK & (1 << buf[pos])) != 0 {
91 pos++
92 }
93 }
94
95
96 if pos == len(buf) {
97 return nil
98 }
99
100
101 return SyntaxError {
102 Src : buf,
103 Pos : pos,
104 Code : types.ERR_INVALID_CHAR,
105 }
106 }
107
108
109
110
111 func (self *Decoder) Decode(val interface{}) error {
112
113 if (self.f & (1 << _F_validate_string)) != 0 && !utf8.ValidateString(self.s){
114 dbuf := utf8.CorrectWith(nil, rt.Str2Mem(self.s), "\ufffd")
115 self.s = rt.Mem2Str(dbuf)
116 }
117
118 vv := rt.UnpackEface(val)
119 vp := vv.Value
120
121
122 if vv.Type == nil {
123 return &json.InvalidUnmarshalError{}
124 }
125
126
127 if vp == nil || vv.Type.Kind() != reflect.Ptr {
128 return &json.InvalidUnmarshalError{Type: vv.Type.Pack()}
129 }
130
131 etp := rt.PtrElem(vv.Type)
132
133
134 if vv.Type.IsNamed() {
135 newp := vp
136 etp = vv.Type
137 vp = unsafe.Pointer(&newp)
138 }
139
140
141 sb := newStack()
142 nb, err := decodeTypedPointer(self.s, self.i, etp, vp, sb, self.f)
143
144 self.i = nb
145 freeStack(sb)
146
147
148 runtime.KeepAlive(vv)
149 return err
150 }
151
152
153
154 func (self *Decoder) UseInt64() {
155 self.f |= 1 << _F_use_int64
156 self.f &^= 1 << _F_use_number
157 }
158
159
160
161 func (self *Decoder) UseNumber() {
162 self.f &^= 1 << _F_use_int64
163 self.f |= 1 << _F_use_number
164 }
165
166
167
168 func (self *Decoder) UseUnicodeErrors() {
169 self.f |= 1 << _F_disable_urc
170 }
171
172
173
174
175 func (self *Decoder) DisallowUnknownFields() {
176 self.f |= 1 << _F_disable_unknown
177 }
178
179
180 func (self *Decoder) CopyString() {
181 self.f |= 1 << _F_copy_string
182 }
183
184
185
186
187 func (self *Decoder) ValidateString() {
188 self.f |= 1 << _F_validate_string
189 }
190
191
192
193
194
195
196 func Pretouch(vt reflect.Type, opts ...option.CompileOption) error {
197 cfg := option.DefaultCompileOptions()
198 for _, opt := range opts {
199 opt(&cfg)
200 }
201 return pretouchRec(map[reflect.Type]bool{vt:true}, cfg)
202 }
203
204 func pretouchType(_vt reflect.Type, opts option.CompileOptions) (map[reflect.Type]bool, error) {
205
206 compiler := newCompiler().apply(opts)
207 decoder := func(vt *rt.GoType, _ ...interface{}) (interface{}, error) {
208 if pp, err := compiler.compile(_vt); err != nil {
209 return nil, err
210 } else {
211 as := newAssembler(pp)
212 as.name = _vt.String()
213 return as.Load(), nil
214 }
215 }
216
217
218 vt := rt.UnpackType(_vt)
219 if val := programCache.Get(vt); val != nil {
220 return nil, nil
221 } else if _, err := programCache.Compute(vt, decoder); err == nil {
222 return compiler.rec, nil
223 } else {
224 return nil, err
225 }
226 }
227
228 func pretouchRec(vtm map[reflect.Type]bool, opts option.CompileOptions) error {
229 if opts.RecursiveDepth < 0 || len(vtm) == 0 {
230 return nil
231 }
232 next := make(map[reflect.Type]bool)
233 for vt := range(vtm) {
234 sub, err := pretouchType(vt, opts)
235 if err != nil {
236 return err
237 }
238 for svt := range(sub) {
239 next[svt] = true
240 }
241 }
242 opts.RecursiveDepth -= 1
243 return pretouchRec(next, opts)
244 }
245
246
247
248 func Skip(data []byte) (start int, end int) {
249 s := rt.Mem2Str(data)
250 p := 0
251 m := types.NewStateMachine()
252 ret := native.SkipOne(&s, &p, m, uint64(0))
253 types.FreeStateMachine(m)
254 return ret, p
255 }
256
View as plain text