forked from mirror/go-json
Merge pull request #221 from goccy/feature/refactor-validator
Refactor validator
This commit is contained in:
commit
835c00e18b
|
@ -39,10 +39,20 @@ jobs:
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: 1.16
|
go-version: 1.16
|
||||||
- name: checkout
|
- name: checkout ( feature )
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- name: run benchmark
|
- name: run benchmark ( feature )
|
||||||
run: cd benchmarks && go test -bench .
|
run: cd benchmarks && go test -bench GoJson | tee $HOME/new.txt
|
||||||
|
- name: install benchcmp
|
||||||
|
run: go get -u golang.org/x/tools/cmd/benchcmp
|
||||||
|
- name: checkout ( master )
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: master
|
||||||
|
- name: run benchmark ( master )
|
||||||
|
run: cd benchmarks && go test -bench GoJson | tee $HOME/old.txt
|
||||||
|
- name: compare benchmark results
|
||||||
|
run: benchcmp $HOME/old.txt $HOME/new.txt
|
||||||
coverage:
|
coverage:
|
||||||
name: Coverage
|
name: Coverage
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
|
@ -95,24 +95,14 @@ func (d *arrayDecoder) decode(buf []byte, cursor, depth int64, p unsafe.Pointer)
|
||||||
return 0, errExceededMaxDepth(buf[cursor], cursor)
|
return 0, errExceededMaxDepth(buf[cursor], cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
buflen := int64(len(buf))
|
for {
|
||||||
for ; cursor < buflen; cursor++ {
|
|
||||||
switch buf[cursor] {
|
switch buf[cursor] {
|
||||||
case ' ', '\n', '\t', '\r':
|
case ' ', '\n', '\t', '\r':
|
||||||
|
cursor++
|
||||||
continue
|
continue
|
||||||
case 'n':
|
case 'n':
|
||||||
buflen := int64(len(buf))
|
if err := validateNull(buf, cursor); err != nil {
|
||||||
if cursor+3 >= buflen {
|
return 0, err
|
||||||
return 0, errUnexpectedEndOfJSON("null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'u' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+1], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'l' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+2], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 'l' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+3], "null", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 4
|
cursor += 4
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
|
@ -149,7 +139,8 @@ func (d *arrayDecoder) decode(buf []byte, cursor, depth int64, p unsafe.Pointer)
|
||||||
return 0, errInvalidCharacter(buf[cursor], "array", cursor)
|
return 0, errInvalidCharacter(buf[cursor], "array", cursor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
default:
|
||||||
}
|
|
||||||
return 0, errUnexpectedEndOfJSON("array", cursor)
|
return 0, errUnexpectedEndOfJSON("array", cursor)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -47,56 +47,25 @@ ERROR:
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *boolDecoder) decode(buf []byte, cursor, depth int64, p unsafe.Pointer) (int64, error) {
|
func (d *boolDecoder) decode(buf []byte, cursor, depth int64, p unsafe.Pointer) (int64, error) {
|
||||||
buflen := int64(len(buf))
|
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
cursor = skipWhiteSpace(buf, cursor)
|
||||||
switch buf[cursor] {
|
switch buf[cursor] {
|
||||||
case 't':
|
case 't':
|
||||||
if cursor+3 >= buflen {
|
if err := validateTrue(buf, cursor); err != nil {
|
||||||
return 0, errUnexpectedEndOfJSON("bool(true)", cursor)
|
return 0, err
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'r' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+1], "bool(true)", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'u' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+2], "bool(true)", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 'e' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+3], "bool(true)", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 4
|
cursor += 4
|
||||||
**(**bool)(unsafe.Pointer(&p)) = true
|
**(**bool)(unsafe.Pointer(&p)) = true
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
case 'f':
|
case 'f':
|
||||||
if cursor+4 >= buflen {
|
if err := validateFalse(buf, cursor); err != nil {
|
||||||
return 0, errUnexpectedEndOfJSON("bool(false)", cursor)
|
return 0, err
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'a' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+1], "bool(false)", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'l' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+2], "bool(false)", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 's' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+3], "bool(false)", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+4] != 'e' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+4], "bool(false)", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 5
|
cursor += 5
|
||||||
**(**bool)(unsafe.Pointer(&p)) = false
|
**(**bool)(unsafe.Pointer(&p)) = false
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
case 'n':
|
case 'n':
|
||||||
if cursor+3 >= buflen {
|
if err := validateNull(buf, cursor); err != nil {
|
||||||
return 0, errUnexpectedEndOfJSON("null", cursor)
|
return 0, err
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'u' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+1], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'l' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+2], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 'l' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+3], "null", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 4
|
cursor += 4
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
|
|
|
@ -166,9 +166,7 @@ func (d *bytesDecoder) decodeBinary(buf []byte, cursor, depth int64, p unsafe.Po
|
||||||
cursor += 4
|
cursor += 4
|
||||||
return nil, cursor, nil
|
return nil, cursor, nil
|
||||||
default:
|
default:
|
||||||
goto ERROR
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ERROR:
|
|
||||||
return nil, 0, errNotAtBeginningOfValue(cursor)
|
return nil, 0, errNotAtBeginningOfValue(cursor)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -153,37 +153,14 @@ func skipValue(buf []byte, cursor, depth int64) (int64, error) {
|
||||||
}
|
}
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
case 't':
|
case 't':
|
||||||
buflen := int64(len(buf))
|
if err := validateTrue(buf, cursor); err != nil {
|
||||||
if cursor+3 >= buflen {
|
return 0, err
|
||||||
return 0, errUnexpectedEndOfJSON("bool of object", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'r' {
|
|
||||||
return 0, errUnexpectedEndOfJSON("bool of object", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'u' {
|
|
||||||
return 0, errUnexpectedEndOfJSON("bool of object", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 'e' {
|
|
||||||
return 0, errUnexpectedEndOfJSON("bool of object", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 4
|
cursor += 4
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
case 'f':
|
case 'f':
|
||||||
buflen := int64(len(buf))
|
if err := validateFalse(buf, cursor); err != nil {
|
||||||
if cursor+4 >= buflen {
|
return 0, err
|
||||||
return 0, errUnexpectedEndOfJSON("bool of object", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'a' {
|
|
||||||
return 0, errUnexpectedEndOfJSON("bool of object", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'l' {
|
|
||||||
return 0, errUnexpectedEndOfJSON("bool of object", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 's' {
|
|
||||||
return 0, errUnexpectedEndOfJSON("bool of object", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+4] != 'e' {
|
|
||||||
return 0, errUnexpectedEndOfJSON("bool of object", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 5
|
cursor += 5
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
|
@ -199,6 +176,41 @@ func skipValue(buf []byte, cursor, depth int64) (int64, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateTrue(buf []byte, cursor int64) error {
|
||||||
|
if cursor+3 >= int64(len(buf)) {
|
||||||
|
return errUnexpectedEndOfJSON("true", cursor)
|
||||||
|
}
|
||||||
|
if buf[cursor+1] != 'r' {
|
||||||
|
return errInvalidCharacter(buf[cursor+1], "true", cursor)
|
||||||
|
}
|
||||||
|
if buf[cursor+2] != 'u' {
|
||||||
|
return errInvalidCharacter(buf[cursor+2], "true", cursor)
|
||||||
|
}
|
||||||
|
if buf[cursor+3] != 'e' {
|
||||||
|
return errInvalidCharacter(buf[cursor+3], "true", cursor)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateFalse(buf []byte, cursor int64) error {
|
||||||
|
if cursor+4 >= int64(len(buf)) {
|
||||||
|
return errUnexpectedEndOfJSON("false", cursor)
|
||||||
|
}
|
||||||
|
if buf[cursor+1] != 'a' {
|
||||||
|
return errInvalidCharacter(buf[cursor+1], "false", cursor)
|
||||||
|
}
|
||||||
|
if buf[cursor+2] != 'l' {
|
||||||
|
return errInvalidCharacter(buf[cursor+2], "false", cursor)
|
||||||
|
}
|
||||||
|
if buf[cursor+3] != 's' {
|
||||||
|
return errInvalidCharacter(buf[cursor+3], "false", cursor)
|
||||||
|
}
|
||||||
|
if buf[cursor+4] != 'e' {
|
||||||
|
return errInvalidCharacter(buf[cursor+4], "false", cursor)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func validateNull(buf []byte, cursor int64) error {
|
func validateNull(buf []byte, cursor int64) error {
|
||||||
if cursor+3 >= int64(len(buf)) {
|
if cursor+3 >= int64(len(buf)) {
|
||||||
return errUnexpectedEndOfJSON("null", cursor)
|
return errUnexpectedEndOfJSON("null", cursor)
|
||||||
|
|
|
@ -91,34 +91,22 @@ ERROR:
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *floatDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
|
func (d *floatDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
|
||||||
buflen := int64(len(buf))
|
for {
|
||||||
for ; cursor < buflen; cursor++ {
|
|
||||||
switch buf[cursor] {
|
switch buf[cursor] {
|
||||||
case ' ', '\n', '\t', '\r':
|
case ' ', '\n', '\t', '\r':
|
||||||
|
cursor++
|
||||||
continue
|
continue
|
||||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
start := cursor
|
start := cursor
|
||||||
cursor++
|
cursor++
|
||||||
for ; cursor < buflen; cursor++ {
|
for floatTable[buf[cursor]] {
|
||||||
if floatTable[buf[cursor]] {
|
cursor++
|
||||||
continue
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
num := buf[start:cursor]
|
num := buf[start:cursor]
|
||||||
return num, cursor, nil
|
return num, cursor, nil
|
||||||
case 'n':
|
case 'n':
|
||||||
if cursor+3 >= buflen {
|
if err := validateNull(buf, cursor); err != nil {
|
||||||
return nil, 0, errUnexpectedEndOfJSON("null", cursor)
|
return nil, 0, err
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'u' {
|
|
||||||
return nil, 0, errInvalidCharacter(buf[cursor+1], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'l' {
|
|
||||||
return nil, 0, errInvalidCharacter(buf[cursor+2], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 'l' {
|
|
||||||
return nil, 0, errInvalidCharacter(buf[cursor+3], "null", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 4
|
cursor += 4
|
||||||
return nil, cursor, nil
|
return nil, cursor, nil
|
||||||
|
@ -126,7 +114,6 @@ func (d *floatDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, erro
|
||||||
return nil, 0, errUnexpectedEndOfJSON("float", cursor)
|
return nil, 0, errUnexpectedEndOfJSON("float", cursor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, 0, errUnexpectedEndOfJSON("float", cursor)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *floatDecoder) decodeStream(s *stream, depth int64, p unsafe.Pointer) error {
|
func (d *floatDecoder) decodeStream(s *stream, depth int64, p unsafe.Pointer) error {
|
||||||
|
|
|
@ -154,26 +154,14 @@ func (d *intDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error)
|
||||||
case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
start := cursor
|
start := cursor
|
||||||
cursor++
|
cursor++
|
||||||
LOOP:
|
for numTable[char(b, cursor)] {
|
||||||
if numTable[char(b, cursor)] {
|
|
||||||
cursor++
|
cursor++
|
||||||
goto LOOP
|
|
||||||
}
|
}
|
||||||
num := buf[start:cursor]
|
num := buf[start:cursor]
|
||||||
return num, cursor, nil
|
return num, cursor, nil
|
||||||
case 'n':
|
case 'n':
|
||||||
buflen := int64(len(buf))
|
if err := validateNull(buf, cursor); err != nil {
|
||||||
if cursor+3 >= buflen {
|
return nil, 0, err
|
||||||
return nil, 0, errUnexpectedEndOfJSON("null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'u' {
|
|
||||||
return nil, 0, errInvalidCharacter(buf[cursor+1], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'l' {
|
|
||||||
return nil, 0, errInvalidCharacter(buf[cursor+2], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 'l' {
|
|
||||||
return nil, 0, errInvalidCharacter(buf[cursor+3], "null", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 4
|
cursor += 4
|
||||||
return nil, cursor, nil
|
return nil, cursor, nil
|
||||||
|
|
|
@ -385,52 +385,22 @@ func (d *interfaceDecoder) decodeEmptyInterface(buf []byte, cursor, depth int64,
|
||||||
**(**interface{})(unsafe.Pointer(&p)) = v
|
**(**interface{})(unsafe.Pointer(&p)) = v
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
case 't':
|
case 't':
|
||||||
if cursor+3 >= int64(len(buf)) {
|
if err := validateTrue(buf, cursor); err != nil {
|
||||||
return 0, errUnexpectedEndOfJSON("bool(true)", cursor)
|
return 0, err
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'r' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+1], "bool(true)", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'u' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+2], "bool(true)", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 'e' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+3], "bool(true)", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 4
|
cursor += 4
|
||||||
**(**interface{})(unsafe.Pointer(&p)) = true
|
**(**interface{})(unsafe.Pointer(&p)) = true
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
case 'f':
|
case 'f':
|
||||||
if cursor+4 >= int64(len(buf)) {
|
if err := validateFalse(buf, cursor); err != nil {
|
||||||
return 0, errUnexpectedEndOfJSON("bool(false)", cursor)
|
return 0, err
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'a' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+1], "bool(false)", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'l' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+2], "bool(false)", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 's' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+3], "bool(false)", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+4] != 'e' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+4], "bool(false)", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 5
|
cursor += 5
|
||||||
**(**interface{})(unsafe.Pointer(&p)) = false
|
**(**interface{})(unsafe.Pointer(&p)) = false
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
case 'n':
|
case 'n':
|
||||||
if cursor+3 >= int64(len(buf)) {
|
if err := validateNull(buf, cursor); err != nil {
|
||||||
return 0, errUnexpectedEndOfJSON("null", cursor)
|
return 0, err
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'u' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+1], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'l' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+2], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 'l' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+3], "null", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 4
|
cursor += 4
|
||||||
**(**interface{})(unsafe.Pointer(&p)) = nil
|
**(**interface{})(unsafe.Pointer(&p)) = nil
|
||||||
|
|
|
@ -102,17 +102,8 @@ func (d *mapDecoder) decode(buf []byte, cursor, depth int64, p unsafe.Pointer) (
|
||||||
}
|
}
|
||||||
switch buf[cursor] {
|
switch buf[cursor] {
|
||||||
case 'n':
|
case 'n':
|
||||||
if cursor+3 >= buflen {
|
if err := validateNull(buf, cursor); err != nil {
|
||||||
return 0, errUnexpectedEndOfJSON("null", cursor)
|
return 0, err
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'u' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+1], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'l' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+2], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 'l' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+3], "null", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 4
|
cursor += 4
|
||||||
**(**unsafe.Pointer)(unsafe.Pointer(&p)) = nil
|
**(**unsafe.Pointer)(unsafe.Pointer(&p)) = nil
|
||||||
|
|
|
@ -77,34 +77,22 @@ ERROR:
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *numberDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
|
func (d *numberDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
|
||||||
buflen := int64(len(buf))
|
for {
|
||||||
for ; cursor < buflen; cursor++ {
|
|
||||||
switch buf[cursor] {
|
switch buf[cursor] {
|
||||||
case ' ', '\n', '\t', '\r':
|
case ' ', '\n', '\t', '\r':
|
||||||
|
cursor++
|
||||||
continue
|
continue
|
||||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
start := cursor
|
start := cursor
|
||||||
cursor++
|
cursor++
|
||||||
for ; cursor < buflen; cursor++ {
|
for floatTable[buf[cursor]] {
|
||||||
if floatTable[buf[cursor]] {
|
cursor++
|
||||||
continue
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
num := buf[start:cursor]
|
num := buf[start:cursor]
|
||||||
return num, cursor, nil
|
return num, cursor, nil
|
||||||
case 'n':
|
case 'n':
|
||||||
if cursor+3 >= buflen {
|
if err := validateNull(buf, cursor); err != nil {
|
||||||
return nil, 0, errUnexpectedEndOfJSON("null", cursor)
|
return nil, 0, err
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'u' {
|
|
||||||
return nil, 0, errInvalidCharacter(buf[cursor+1], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'l' {
|
|
||||||
return nil, 0, errInvalidCharacter(buf[cursor+2], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 'l' {
|
|
||||||
return nil, 0, errInvalidCharacter(buf[cursor+3], "null", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 4
|
cursor += 4
|
||||||
return nil, cursor, nil
|
return nil, cursor, nil
|
||||||
|
@ -114,5 +102,4 @@ func (d *numberDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, err
|
||||||
return nil, 0, errUnexpectedEndOfJSON("json.Number", cursor)
|
return nil, 0, errUnexpectedEndOfJSON("json.Number", cursor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, 0, errUnexpectedEndOfJSON("json.Number", cursor)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,18 +60,8 @@ func (d *ptrDecoder) decodeStream(s *stream, depth int64, p unsafe.Pointer) erro
|
||||||
func (d *ptrDecoder) decode(buf []byte, cursor, depth int64, p unsafe.Pointer) (int64, error) {
|
func (d *ptrDecoder) decode(buf []byte, cursor, depth int64, p unsafe.Pointer) (int64, error) {
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
cursor = skipWhiteSpace(buf, cursor)
|
||||||
if buf[cursor] == 'n' {
|
if buf[cursor] == 'n' {
|
||||||
buflen := int64(len(buf))
|
if err := validateNull(buf, cursor); err != nil {
|
||||||
if cursor+3 >= buflen {
|
return 0, err
|
||||||
return 0, errUnexpectedEndOfJSON("null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'u' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+1], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'l' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+2], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 'l' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+3], "null", cursor)
|
|
||||||
}
|
}
|
||||||
if p != nil {
|
if p != nil {
|
||||||
*(*unsafe.Pointer)(p) = nil
|
*(*unsafe.Pointer)(p) = nil
|
||||||
|
|
|
@ -186,24 +186,14 @@ func (d *sliceDecoder) decode(buf []byte, cursor, depth int64, p unsafe.Pointer)
|
||||||
return 0, errExceededMaxDepth(buf[cursor], cursor)
|
return 0, errExceededMaxDepth(buf[cursor], cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
buflen := int64(len(buf))
|
for {
|
||||||
for ; cursor < buflen; cursor++ {
|
|
||||||
switch buf[cursor] {
|
switch buf[cursor] {
|
||||||
case ' ', '\n', '\t', '\r':
|
case ' ', '\n', '\t', '\r':
|
||||||
|
cursor++
|
||||||
continue
|
continue
|
||||||
case 'n':
|
case 'n':
|
||||||
buflen := int64(len(buf))
|
if err := validateNull(buf, cursor); err != nil {
|
||||||
if cursor+3 >= buflen {
|
return 0, err
|
||||||
return 0, errUnexpectedEndOfJSON("null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'u' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+1], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'l' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+2], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 'l' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+3], "null", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 4
|
cursor += 4
|
||||||
*(*unsafe.Pointer)(p) = nil
|
*(*unsafe.Pointer)(p) = nil
|
||||||
|
@ -274,9 +264,7 @@ func (d *sliceDecoder) decode(buf []byte, cursor, depth int64, p unsafe.Pointer)
|
||||||
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
return 0, d.errNumber(cursor)
|
return 0, d.errNumber(cursor)
|
||||||
default:
|
default:
|
||||||
goto ERROR
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ERROR:
|
|
||||||
return 0, errUnexpectedEndOfJSON("slice", cursor)
|
return 0, errUnexpectedEndOfJSON("slice", cursor)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -343,25 +343,13 @@ func (d *stringDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, err
|
||||||
cursor++
|
cursor++
|
||||||
}
|
}
|
||||||
case 'n':
|
case 'n':
|
||||||
buflen := int64(len(buf))
|
if err := validateNull(buf, cursor); err != nil {
|
||||||
if cursor+3 >= buflen {
|
return nil, 0, err
|
||||||
return nil, 0, errUnexpectedEndOfJSON("null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'u' {
|
|
||||||
return nil, 0, errInvalidCharacter(buf[cursor+1], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'l' {
|
|
||||||
return nil, 0, errInvalidCharacter(buf[cursor+2], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 'l' {
|
|
||||||
return nil, 0, errInvalidCharacter(buf[cursor+3], "null", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 4
|
cursor += 4
|
||||||
return nil, cursor, nil
|
return nil, cursor, nil
|
||||||
default:
|
default:
|
||||||
goto ERROR
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ERROR:
|
|
||||||
return nil, 0, errNotAtBeginningOfValue(cursor)
|
return nil, 0, errNotAtBeginningOfValue(cursor)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -566,17 +566,8 @@ func (d *structDecoder) decode(buf []byte, cursor, depth int64, p unsafe.Pointer
|
||||||
b := (*sliceHeader)(unsafe.Pointer(&buf)).data
|
b := (*sliceHeader)(unsafe.Pointer(&buf)).data
|
||||||
switch char(b, cursor) {
|
switch char(b, cursor) {
|
||||||
case 'n':
|
case 'n':
|
||||||
if cursor+3 >= buflen {
|
if err := validateNull(buf, cursor); err != nil {
|
||||||
return 0, errUnexpectedEndOfJSON("null", cursor)
|
return 0, err
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'u' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+1], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'l' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+2], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 'l' {
|
|
||||||
return 0, errInvalidCharacter(buf[cursor+3], "null", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 4
|
cursor += 4
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
|
|
|
@ -1147,7 +1147,7 @@ var unmarshalTests = []unmarshalTest{
|
||||||
{in: `{"B":"true"}`, ptr: new(B), out: B{true}, golden: true}, // 127
|
{in: `{"B":"true"}`, ptr: new(B), out: B{true}, golden: true}, // 127
|
||||||
{in: `{"B":"false"}`, ptr: new(B), out: B{false}, golden: true}, // 128
|
{in: `{"B":"false"}`, ptr: new(B), out: B{false}, golden: true}, // 128
|
||||||
{in: `{"B": "maybe"}`, ptr: new(B), err: errors.New(`json: bool unexpected end of JSON input`)}, // 129
|
{in: `{"B": "maybe"}`, ptr: new(B), err: errors.New(`json: bool unexpected end of JSON input`)}, // 129
|
||||||
{in: `{"B": "tru"}`, ptr: new(B), err: errors.New(`json: invalid character as bool(true)`)}, // 130
|
{in: `{"B": "tru"}`, ptr: new(B), err: errors.New(`json: invalid character as true`)}, // 130
|
||||||
{in: `{"B": "False"}`, ptr: new(B), err: errors.New(`json: bool unexpected end of JSON input`)}, // 131
|
{in: `{"B": "False"}`, ptr: new(B), err: errors.New(`json: bool unexpected end of JSON input`)}, // 131
|
||||||
{in: `{"B": "null"}`, ptr: new(B), out: B{false}}, // 132
|
{in: `{"B": "null"}`, ptr: new(B), out: B{false}}, // 132
|
||||||
{in: `{"B": "nul"}`, ptr: new(B), err: errors.New(`json: invalid character as null`)}, // 133
|
{in: `{"B": "nul"}`, ptr: new(B), err: errors.New(`json: invalid character as null`)}, // 133
|
||||||
|
|
|
@ -97,10 +97,10 @@ func (d *uintDecoder) decodeStreamByte(s *stream) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *uintDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
|
func (d *uintDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
|
||||||
buflen := int64(len(buf))
|
for {
|
||||||
for ; cursor < buflen; cursor++ {
|
|
||||||
switch buf[cursor] {
|
switch buf[cursor] {
|
||||||
case ' ', '\n', '\t', '\r':
|
case ' ', '\n', '\t', '\r':
|
||||||
|
cursor++
|
||||||
continue
|
continue
|
||||||
case '0':
|
case '0':
|
||||||
cursor++
|
cursor++
|
||||||
|
@ -108,27 +108,14 @@ func (d *uintDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error
|
||||||
case '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
case '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
start := cursor
|
start := cursor
|
||||||
cursor++
|
cursor++
|
||||||
for ; cursor < buflen; cursor++ {
|
for numTable[buf[cursor]] {
|
||||||
tk := int(buf[cursor])
|
cursor++
|
||||||
if int('0') <= tk && tk <= int('9') {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
num := buf[start:cursor]
|
num := buf[start:cursor]
|
||||||
return num, cursor, nil
|
return num, cursor, nil
|
||||||
case 'n':
|
case 'n':
|
||||||
if cursor+3 >= buflen {
|
if err := validateNull(buf, cursor); err != nil {
|
||||||
return nil, 0, errUnexpectedEndOfJSON("null", cursor)
|
return nil, 0, err
|
||||||
}
|
|
||||||
if buf[cursor+1] != 'u' {
|
|
||||||
return nil, 0, errInvalidCharacter(buf[cursor+1], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+2] != 'l' {
|
|
||||||
return nil, 0, errInvalidCharacter(buf[cursor+2], "null", cursor)
|
|
||||||
}
|
|
||||||
if buf[cursor+3] != 'l' {
|
|
||||||
return nil, 0, errInvalidCharacter(buf[cursor+3], "null", cursor)
|
|
||||||
}
|
}
|
||||||
cursor += 4
|
cursor += 4
|
||||||
return nil, cursor, nil
|
return nil, cursor, nil
|
||||||
|
@ -136,7 +123,6 @@ func (d *uintDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error
|
||||||
return nil, 0, d.typeError([]byte{buf[cursor]}, cursor)
|
return nil, 0, d.typeError([]byte{buf[cursor]}, cursor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, 0, errUnexpectedEndOfJSON("number(unsigned integer)", cursor)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *uintDecoder) decodeStream(s *stream, depth int64, p unsafe.Pointer) error {
|
func (d *uintDecoder) decodeStream(s *stream, depth int64, p unsafe.Pointer) error {
|
||||||
|
|
Loading…
Reference in New Issue