2
* Copyright 2022 ByteDance Inc.
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
25
`github.com/bytedance/sonic/internal/native/types`
26
`github.com/bytedance/sonic/internal/rt`
29
const _blankCharsMask = (1 << ' ') | (1 << '\t') | (1 << '\r') | (1 << '\n')
39
func isSpace(c byte) bool {
40
return (int(1<<c) & _blankCharsMask) != 0
44
func skipBlank(src string, pos int) int {
45
se := uintptr(rt.IndexChar(src, len(src)))
46
sp := uintptr(rt.IndexChar(src, pos))
49
if !isSpace(*(*byte)(unsafe.Pointer(sp))) {
55
return -int(types.ERR_EOF)
57
runtime.KeepAlive(src)
58
return int(sp - uintptr(rt.IndexChar(src, 0)))
61
func decodeNull(src string, pos int) (ret int) {
64
return -int(types.ERR_EOF)
66
if src[pos:ret] == bytesNull {
69
return -int(types.ERR_INVALID_CHAR)
73
func decodeTrue(src string, pos int) (ret int) {
76
return -int(types.ERR_EOF)
78
if src[pos:ret] == bytesTrue {
81
return -int(types.ERR_INVALID_CHAR)
86
func decodeFalse(src string, pos int) (ret int) {
89
return -int(types.ERR_EOF)
91
if src[pos:ret] == bytesFalse {
94
return -int(types.ERR_INVALID_CHAR)
98
func decodeString(src string, pos int) (ret int, v string) {
99
ret, ep := skipString(src, pos)
101
(*rt.GoString)(unsafe.Pointer(&v)).Ptr = rt.IndexChar(src, pos+1)
102
(*rt.GoString)(unsafe.Pointer(&v)).Len = ret - pos - 2
106
vv, ok := unquoteBytes(rt.Str2Mem(src[pos:ret]))
108
return -int(types.ERR_INVALID_CHAR), ""
111
runtime.KeepAlive(src)
112
return ret, rt.Mem2Str(vv)
115
func decodeBinary(src string, pos int) (ret int, v []byte) {
117
ret, vv = decodeString(src, pos)
122
v, err = base64.StdEncoding.DecodeString(vv)
124
return -int(types.ERR_INVALID_CHAR), nil
129
func isDigit(c byte) bool {
130
return c >= '0' && c <= '9'
134
func decodeInt64(src string, pos int) (ret int, v int64, err error) {
135
sp := uintptr(rt.IndexChar(src, pos))
137
se := uintptr(rt.IndexChar(src, len(src)))
138
if uintptr(sp) >= se {
139
return -int(types.ERR_EOF), 0, nil
142
if c := *(*byte)(unsafe.Pointer(sp)); c == '-' {
146
return -int(types.ERR_EOF), 0, nil
149
for ; sp < se; sp += uintptr(1) {
150
if !isDigit(*(*byte)(unsafe.Pointer(sp))) {
156
if c := *(*byte)(unsafe.Pointer(sp)); c == '.' || c == 'e' || c == 'E' {
157
return -int(types.ERR_INVALID_NUMBER_FMT), 0, nil
162
ret = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
163
(*rt.GoString)(unsafe.Pointer(&vv)).Ptr = unsafe.Pointer(ss)
164
(*rt.GoString)(unsafe.Pointer(&vv)).Len = ret - pos
166
v, err = strconv.ParseInt(vv, 10, 64)
168
//NOTICE: allow overflow here
169
if err.(*strconv.NumError).Err == strconv.ErrRange {
172
return -int(types.ERR_INVALID_CHAR), 0, err
175
runtime.KeepAlive(src)
179
func isNumberChars(c byte) bool {
180
return (c >= '0' && c <= '9') || c == '+' || c == '-' || c == 'e' || c == 'E' || c == '.'
184
func decodeFloat64(src string, pos int) (ret int, v float64, err error) {
185
sp := uintptr(rt.IndexChar(src, pos))
187
se := uintptr(rt.IndexChar(src, len(src)))
188
if uintptr(sp) >= se {
189
return -int(types.ERR_EOF), 0, nil
192
if c := *(*byte)(unsafe.Pointer(sp)); c == '-' {
196
return -int(types.ERR_EOF), 0, nil
199
for ; sp < se; sp += uintptr(1) {
200
if !isNumberChars(*(*byte)(unsafe.Pointer(sp))) {
206
ret = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
207
(*rt.GoString)(unsafe.Pointer(&vv)).Ptr = unsafe.Pointer(ss)
208
(*rt.GoString)(unsafe.Pointer(&vv)).Len = ret - pos
210
v, err = strconv.ParseFloat(vv, 64)
212
//NOTICE: allow overflow here
213
if err.(*strconv.NumError).Err == strconv.ErrRange {
216
return -int(types.ERR_INVALID_CHAR), 0, err
219
runtime.KeepAlive(src)
223
func decodeValue(src string, pos int, skipnum bool) (ret int, v types.JsonState) {
224
pos = skipBlank(src, pos)
226
return pos, types.JsonState{Vt: types.ValueType(pos)}
228
switch c := src[pos]; c {
230
ret = decodeNull(src, pos)
232
return ret, types.JsonState{Vt: types.ValueType(ret)}
234
return ret, types.JsonState{Vt: types.V_NULL}
237
ret, ep = skipString(src, pos)
239
return ret, types.JsonState{Vt: types.ValueType(ret)}
241
return ret, types.JsonState{Vt: types.V_STRING, Iv: int64(pos + 1), Ep: ep}
243
return pos + 1, types.JsonState{Vt: types.V_OBJECT}
245
return pos + 1, types.JsonState{Vt: types.V_ARRAY}
247
ret = decodeTrue(src, pos)
249
return ret, types.JsonState{Vt: types.ValueType(ret)}
251
return ret, types.JsonState{Vt: types.V_TRUE}
253
ret = decodeFalse(src, pos)
255
return ret, types.JsonState{Vt: types.ValueType(ret)}
257
return ret, types.JsonState{Vt: types.V_FALSE}
258
case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
260
ret = skipNumber(src, pos)
262
return ret, types.JsonState{Vt: types.V_DOUBLE, Iv: 0, Ep: pos}
264
return ret, types.JsonState{Vt: types.ValueType(ret)}
268
ret, iv, _ = decodeInt64(src, pos)
270
return ret, types.JsonState{Vt: types.V_INTEGER, Iv: iv, Ep: pos}
271
} else if ret != -int(types.ERR_INVALID_NUMBER_FMT) {
272
return ret, types.JsonState{Vt: types.ValueType(ret)}
275
ret, fv, _ = decodeFloat64(src, pos)
277
return ret, types.JsonState{Vt: types.V_DOUBLE, Dv: fv, Ep: pos}
279
return ret, types.JsonState{Vt: types.ValueType(ret)}
284
return -int(types.ERR_INVALID_CHAR), types.JsonState{Vt:-types.ValueType(types.ERR_INVALID_CHAR)}
289
func skipNumber(src string, pos int) (ret int) {
290
sp := uintptr(rt.IndexChar(src, pos))
291
se := uintptr(rt.IndexChar(src, len(src)))
292
if uintptr(sp) >= se {
293
return -int(types.ERR_EOF)
296
if c := *(*byte)(unsafe.Pointer(sp)); c == '-' {
304
var nextNeedDigit = true
306
for ; sp < se; sp += uintptr(1) {
307
c := *(*byte)(unsafe.Pointer(sp))
310
nextNeedDigit = false
312
} else if nextNeedDigit {
313
return -int(types.ERR_INVALID_CHAR)
315
if !lastIsDigit || pointer || exponent || sp == ss {
316
return -int(types.ERR_INVALID_CHAR)
322
} else if c == 'e' || c == 'E' {
323
if !lastIsDigit || exponent {
324
return -int(types.ERR_INVALID_CHAR)
327
return -int(types.ERR_EOF)
331
nextNeedDigit = false
333
} else if c == '-' || c == '+' {
334
if prev := *(*byte)(unsafe.Pointer(sp - 1)); prev != 'e' && prev != 'E' {
335
return -int(types.ERR_INVALID_CHAR)
346
return -int(types.ERR_EOF)
349
runtime.KeepAlive(src)
350
return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
354
func skipString(src string, pos int) (ret int, ep int) {
355
if pos+1 >= len(src) {
356
return -int(types.ERR_EOF), -1
359
sp := uintptr(rt.IndexChar(src, pos))
360
se := uintptr(rt.IndexChar(src, len(src)))
362
// not start with quote
363
if *(*byte)(unsafe.Pointer(sp)) != '"' {
364
return -int(types.ERR_INVALID_CHAR), -1
370
c := *(*byte)(unsafe.Pointer(sp))
373
ep = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
380
return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)), ep
384
runtime.KeepAlive(src)
385
// not found the closed quote until EOF
386
return -int(types.ERR_EOF), -1
390
func skipPair(src string, pos int, lchar byte, rchar byte) (ret int) {
391
if pos+1 >= len(src) {
392
return -int(types.ERR_EOF)
395
sp := uintptr(rt.IndexChar(src, pos))
396
se := uintptr(rt.IndexChar(src, len(src)))
398
if *(*byte)(unsafe.Pointer(sp)) != lchar {
399
return -int(types.ERR_INVALID_CHAR)
407
c := *(*byte)(unsafe.Pointer(sp))
413
} else if c == lchar {
417
} else if c == rchar {
430
return -int(types.ERR_INVALID_CHAR)
433
runtime.KeepAlive(src)
434
return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr))
437
func skipValueFast(src string, pos int) (ret int, start int) {
438
pos = skipBlank(src, pos)
442
switch c := src[pos]; c {
444
ret = decodeNull(src, pos)
446
ret, _ = skipString(src, pos)
448
ret = skipPair(src, pos, '{', '}')
450
ret = skipPair(src, pos, '[', ']')
452
ret = decodeTrue(src, pos)
454
ret = decodeFalse(src, pos)
455
case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
456
ret = skipNumber(src, pos)
458
ret = -int(types.ERR_INVALID_CHAR)
463
func skipValue(src string, pos int) (ret int, start int) {
464
pos = skipBlank(src, pos)
468
switch c := src[pos]; c {
470
ret = decodeNull(src, pos)
472
ret, _ = skipString(src, pos)
474
ret, _ = skipObject(src, pos)
476
ret, _ = skipArray(src, pos)
478
ret = decodeTrue(src, pos)
480
ret = decodeFalse(src, pos)
481
case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
482
ret = skipNumber(src, pos)
484
ret = -int(types.ERR_INVALID_CHAR)
489
func skipObject(src string, pos int) (ret int, start int) {
490
start = skipBlank(src, pos)
495
if src[start] != '{' {
496
return -int(types.ERR_INVALID_CHAR), -1
500
pos = skipBlank(src, pos)
505
return pos + 1, start
509
pos, _ = skipString(src, pos)
514
pos = skipBlank(src, pos)
519
return -int(types.ERR_INVALID_CHAR), -1
523
pos, _ = skipValue(src, pos)
528
pos = skipBlank(src, pos)
533
return pos + 1, start
536
return -int(types.ERR_INVALID_CHAR), -1
540
pos = skipBlank(src, pos)
548
func skipArray(src string, pos int) (ret int, start int) {
549
start = skipBlank(src, pos)
554
if src[start] != '[' {
555
return -int(types.ERR_INVALID_CHAR), -1
559
pos = skipBlank(src, pos)
564
return pos + 1, start
568
pos, _ = skipValue(src, pos)
573
pos = skipBlank(src, pos)
578
return pos + 1, start
581
return -int(types.ERR_INVALID_CHAR), -1