forked from mirror/go-json
Support SyntaxError
This commit is contained in:
parent
12b34f0663
commit
4acc22e0fe
|
@ -24,7 +24,7 @@ type Token interface{}
|
||||||
type Delim rune
|
type Delim rune
|
||||||
|
|
||||||
type decoder interface {
|
type decoder interface {
|
||||||
decode([]byte, int, uintptr) (int, error)
|
decode([]byte, int64, uintptr) (int64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Decoder struct {
|
type Decoder struct {
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
package json
|
package json
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type arrayDecoder struct {
|
type arrayDecoder struct {
|
||||||
elemType *rtype
|
elemType *rtype
|
||||||
size uintptr
|
size uintptr
|
||||||
|
@ -20,8 +16,8 @@ func newArrayDecoder(dec decoder, elemType *rtype, alen int) *arrayDecoder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *arrayDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
func (d *arrayDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) {
|
||||||
buflen := len(buf)
|
buflen := int64(len(buf))
|
||||||
for ; cursor < buflen; cursor++ {
|
for ; cursor < buflen; cursor++ {
|
||||||
switch buf[cursor] {
|
switch buf[cursor] {
|
||||||
case ' ', '\n', '\t', '\r':
|
case ' ', '\n', '\t', '\r':
|
||||||
|
@ -44,10 +40,10 @@ func (d *arrayDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||||
idx++
|
idx++
|
||||||
continue
|
continue
|
||||||
default:
|
default:
|
||||||
return 0, errors.New("syntax error array")
|
return 0, errInvalidCharacter(buf[cursor], "array", cursor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0, errors.New("unexpected error array")
|
return 0, errUnexpectedEndOfJSON("array", cursor)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package json
|
package json
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -11,40 +10,40 @@ func newBoolDecoder() *boolDecoder {
|
||||||
return &boolDecoder{}
|
return &boolDecoder{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *boolDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
func (d *boolDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) {
|
||||||
buflen := len(buf)
|
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 cursor+3 >= buflen {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errUnexpectedEndOfJSON("bool(true)", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+1] != 'r' {
|
if buf[cursor+1] != 'r' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errInvalidCharacter(buf[cursor+1], "bool(true)", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+2] != 'u' {
|
if buf[cursor+2] != 'u' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errInvalidCharacter(buf[cursor+2], "bool(true)", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+3] != 'e' {
|
if buf[cursor+3] != 'e' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errInvalidCharacter(buf[cursor+3], "bool(true)", cursor)
|
||||||
}
|
}
|
||||||
cursor += 4
|
cursor += 4
|
||||||
*(*bool)(unsafe.Pointer(p)) = true
|
*(*bool)(unsafe.Pointer(p)) = true
|
||||||
case 'f':
|
case 'f':
|
||||||
if cursor+4 >= buflen {
|
if cursor+4 >= buflen {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errUnexpectedEndOfJSON("bool(false)", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+1] != 'a' {
|
if buf[cursor+1] != 'a' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errInvalidCharacter(buf[cursor+1], "bool(false)", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+2] != 'l' {
|
if buf[cursor+2] != 'l' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errInvalidCharacter(buf[cursor+2], "bool(false)", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+3] != 's' {
|
if buf[cursor+3] != 's' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errInvalidCharacter(buf[cursor+3], "bool(false)", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+4] != 'e' {
|
if buf[cursor+4] != 'e' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errInvalidCharacter(buf[cursor+4], "bool(false)", cursor)
|
||||||
}
|
}
|
||||||
cursor += 5
|
cursor += 5
|
||||||
*(*bool)(unsafe.Pointer(p)) = false
|
*(*bool)(unsafe.Pointer(p)) = false
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
package json
|
package json
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
isWhiteSpace = [256]bool{}
|
isWhiteSpace = [256]bool{}
|
||||||
)
|
)
|
||||||
|
@ -15,7 +11,7 @@ func init() {
|
||||||
isWhiteSpace['\r'] = true
|
isWhiteSpace['\r'] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func skipWhiteSpace(buf []byte, cursor int) int {
|
func skipWhiteSpace(buf []byte, cursor int64) int64 {
|
||||||
LOOP:
|
LOOP:
|
||||||
if isWhiteSpace[buf[cursor]] {
|
if isWhiteSpace[buf[cursor]] {
|
||||||
cursor++
|
cursor++
|
||||||
|
@ -24,15 +20,15 @@ LOOP:
|
||||||
return cursor
|
return cursor
|
||||||
}
|
}
|
||||||
|
|
||||||
func skipValue(buf []byte, cursor int) (int, error) {
|
func skipValue(buf []byte, cursor int64) (int64, error) {
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
cursor = skipWhiteSpace(buf, cursor)
|
||||||
braceCount := 0
|
braceCount := 0
|
||||||
bracketCount := 0
|
bracketCount := 0
|
||||||
buflen := len(buf)
|
buflen := int64(len(buf))
|
||||||
for {
|
for {
|
||||||
switch buf[cursor] {
|
switch buf[cursor] {
|
||||||
case '\000':
|
case '\000':
|
||||||
return cursor, errors.New("unexpected error value")
|
return cursor, errUnexpectedEndOfJSON("value of object", cursor)
|
||||||
case '{':
|
case '{':
|
||||||
braceCount++
|
braceCount++
|
||||||
case '[':
|
case '[':
|
||||||
|
@ -79,5 +75,5 @@ func skipValue(buf []byte, cursor int) (int, error) {
|
||||||
}
|
}
|
||||||
cursor++
|
cursor++
|
||||||
}
|
}
|
||||||
return cursor, errors.New("unexpected error value")
|
return cursor, errUnexpectedEndOfJSON("value of object", cursor)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package json
|
package json
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
@ -14,8 +13,8 @@ func newFloatDecoder(op func(uintptr, float64)) *floatDecoder {
|
||||||
return &floatDecoder{op: op}
|
return &floatDecoder{op: op}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *floatDecoder) decodeByte(buf []byte, cursor int) ([]byte, int, error) {
|
func (d *floatDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
|
||||||
buflen := len(buf)
|
buflen := int64(len(buf))
|
||||||
for ; cursor < buflen; cursor++ {
|
for ; cursor < buflen; cursor++ {
|
||||||
switch buf[cursor] {
|
switch buf[cursor] {
|
||||||
case ' ', '\n', '\t', '\r':
|
case ' ', '\n', '\t', '\r':
|
||||||
|
@ -34,10 +33,10 @@ func (d *floatDecoder) decodeByte(buf []byte, cursor int) ([]byte, int, error) {
|
||||||
return num, cursor, nil
|
return num, cursor, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, 0, errors.New("unexpected error number")
|
return nil, 0, errUnexpectedEndOfJSON("float", cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *floatDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
func (d *floatDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) {
|
||||||
bytes, c, err := d.decodeByte(buf, cursor)
|
bytes, c, err := d.decodeByte(buf, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
package json
|
package json
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type intDecoder struct {
|
type intDecoder struct {
|
||||||
op func(uintptr, int64)
|
op func(uintptr, int64)
|
||||||
}
|
}
|
||||||
|
@ -53,7 +49,7 @@ var (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *intDecoder) decodeByte(buf []byte, cursor int) ([]byte, int, error) {
|
func (d *intDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
|
||||||
for {
|
for {
|
||||||
switch buf[cursor] {
|
switch buf[cursor] {
|
||||||
case ' ', '\n', '\t', '\r':
|
case ' ', '\n', '\t', '\r':
|
||||||
|
@ -70,14 +66,13 @@ func (d *intDecoder) decodeByte(buf []byte, cursor int) ([]byte, int, error) {
|
||||||
num := buf[start:cursor]
|
num := buf[start:cursor]
|
||||||
return num, cursor, nil
|
return num, cursor, nil
|
||||||
default:
|
default:
|
||||||
goto ERROR
|
return nil, 0, errInvalidCharacter(buf[cursor], "number(integer)", cursor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ERROR:
|
return nil, 0, errUnexpectedEndOfJSON("number(integer)", cursor)
|
||||||
return nil, 0, errors.New("unexpected error number")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *intDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
func (d *intDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) {
|
||||||
bytes, c, err := d.decodeByte(buf, cursor)
|
bytes, c, err := d.decodeByte(buf, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package json
|
package json
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
@ -21,7 +20,7 @@ var (
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *interfaceDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
func (d *interfaceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) {
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
cursor = skipWhiteSpace(buf, cursor)
|
||||||
switch buf[cursor] {
|
switch buf[cursor] {
|
||||||
case '{':
|
case '{':
|
||||||
|
@ -63,62 +62,62 @@ func (d *interfaceDecoder) decode(buf []byte, cursor int, p uintptr) (int, error
|
||||||
*(*interface{})(unsafe.Pointer(p)) = *(*string)(unsafe.Pointer(&literal))
|
*(*interface{})(unsafe.Pointer(p)) = *(*string)(unsafe.Pointer(&literal))
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
case '\000':
|
case '\000':
|
||||||
return 0, errors.New("unexpected error string")
|
return 0, errUnexpectedEndOfJSON("string", cursor)
|
||||||
}
|
}
|
||||||
cursor++
|
cursor++
|
||||||
}
|
}
|
||||||
return 0, errors.New("unexpected error string")
|
return 0, errUnexpectedEndOfJSON("string", cursor)
|
||||||
case 't':
|
case 't':
|
||||||
if cursor+3 >= len(buf) {
|
if cursor+3 >= int64(len(buf)) {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errUnexpectedEndOfJSON("bool(true)", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+1] != 'r' {
|
if buf[cursor+1] != 'r' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errInvalidCharacter(buf[cursor+1], "bool(true)", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+2] != 'u' {
|
if buf[cursor+2] != 'u' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errInvalidCharacter(buf[cursor+2], "bool(true)", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+3] != 'e' {
|
if buf[cursor+3] != 'e' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
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 >= len(buf) {
|
if cursor+4 >= int64(len(buf)) {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errUnexpectedEndOfJSON("bool(false)", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+1] != 'a' {
|
if buf[cursor+1] != 'a' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errInvalidCharacter(buf[cursor+1], "bool(false)", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+2] != 'l' {
|
if buf[cursor+2] != 'l' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errInvalidCharacter(buf[cursor+2], "bool(false)", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+3] != 's' {
|
if buf[cursor+3] != 's' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errInvalidCharacter(buf[cursor+3], "bool(false)", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+4] != 'e' {
|
if buf[cursor+4] != 'e' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
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 >= len(buf) {
|
if cursor+3 >= int64(len(buf)) {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errUnexpectedEndOfJSON("null", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+1] != 'u' {
|
if buf[cursor+1] != 'u' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errInvalidCharacter(buf[cursor+1], "null", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+2] != 'l' {
|
if buf[cursor+2] != 'l' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errInvalidCharacter(buf[cursor+2], "null", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+3] != 'l' {
|
if buf[cursor+3] != 'l' {
|
||||||
return 0, errors.New("unexpected error. invalid bool character")
|
return 0, errInvalidCharacter(buf[cursor+3], "null", cursor)
|
||||||
}
|
}
|
||||||
cursor += 4
|
cursor += 4
|
||||||
*(*interface{})(unsafe.Pointer(p)) = nil
|
*(*interface{})(unsafe.Pointer(p)) = nil
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
}
|
}
|
||||||
return cursor, errors.New("unexpected error value")
|
return cursor, errNotAtBeginningOfValue(cursor)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package json
|
package json
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,24 +25,24 @@ func makemap(*rtype, int) unsafe.Pointer
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func mapassign(t *rtype, m unsafe.Pointer, key, val unsafe.Pointer)
|
func mapassign(t *rtype, m unsafe.Pointer, key, val unsafe.Pointer)
|
||||||
|
|
||||||
func (d *mapDecoder) setKey(buf []byte, cursor int, key interface{}) (int, error) {
|
func (d *mapDecoder) setKey(buf []byte, cursor int64, key interface{}) (int64, error) {
|
||||||
header := (*interfaceHeader)(unsafe.Pointer(&key))
|
header := (*interfaceHeader)(unsafe.Pointer(&key))
|
||||||
return d.keyDecoder.decode(buf, cursor, uintptr(header.ptr))
|
return d.keyDecoder.decode(buf, cursor, uintptr(header.ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *mapDecoder) setValue(buf []byte, cursor int, key interface{}) (int, error) {
|
func (d *mapDecoder) setValue(buf []byte, cursor int64, key interface{}) (int64, error) {
|
||||||
header := (*interfaceHeader)(unsafe.Pointer(&key))
|
header := (*interfaceHeader)(unsafe.Pointer(&key))
|
||||||
return d.valueDecoder.decode(buf, cursor, uintptr(header.ptr))
|
return d.valueDecoder.decode(buf, cursor, uintptr(header.ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *mapDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
func (d *mapDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) {
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
cursor = skipWhiteSpace(buf, cursor)
|
||||||
buflen := len(buf)
|
buflen := int64(len(buf))
|
||||||
if buflen < 2 {
|
if buflen < 2 {
|
||||||
return 0, errors.New("unexpected error {}")
|
return 0, errExpected("{} for map", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor] != '{' {
|
if buf[cursor] != '{' {
|
||||||
return 0, errors.New("unexpected error {")
|
return 0, errExpected("{ character for map value", cursor)
|
||||||
}
|
}
|
||||||
cursor++
|
cursor++
|
||||||
mapValue := makemap(d.mapType, 0)
|
mapValue := makemap(d.mapType, 0)
|
||||||
|
@ -56,11 +55,11 @@ func (d *mapDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||||
cursor = keyCursor
|
cursor = keyCursor
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
cursor = skipWhiteSpace(buf, cursor)
|
||||||
if buf[cursor] != ':' {
|
if buf[cursor] != ':' {
|
||||||
return 0, errors.New("unexpected error invalid delimiter for object")
|
return 0, errExpected("colon after object key", cursor)
|
||||||
}
|
}
|
||||||
cursor++
|
cursor++
|
||||||
if cursor >= buflen {
|
if cursor >= buflen {
|
||||||
return 0, errors.New("unexpected error missing value")
|
return 0, errUnexpectedEndOfJSON("map", cursor)
|
||||||
}
|
}
|
||||||
var value interface{}
|
var value interface{}
|
||||||
valueCursor, err := d.setValue(buf, cursor, &value)
|
valueCursor, err := d.setValue(buf, cursor, &value)
|
||||||
|
@ -75,7 +74,7 @@ func (d *mapDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
}
|
}
|
||||||
if buf[cursor] != ',' {
|
if buf[cursor] != ',' {
|
||||||
return 0, errors.New("unexpected error ,")
|
return 0, errExpected("semicolon after object value", cursor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
|
|
|
@ -16,7 +16,7 @@ func newPtrDecoder(dec decoder, typ *rtype) *ptrDecoder {
|
||||||
//go:linkname unsafe_New reflect.unsafe_New
|
//go:linkname unsafe_New reflect.unsafe_New
|
||||||
func unsafe_New(*rtype) uintptr
|
func unsafe_New(*rtype) uintptr
|
||||||
|
|
||||||
func (d *ptrDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
func (d *ptrDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) {
|
||||||
newptr := unsafe_New(d.typ)
|
newptr := unsafe_New(d.typ)
|
||||||
c, err := d.dec.decode(buf, cursor, newptr)
|
c, err := d.dec.decode(buf, cursor, newptr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package json
|
package json
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
@ -48,8 +47,8 @@ func copySlice(elemType *rtype, dst, src reflect.SliceHeader) int
|
||||||
//go:linkname newArray reflect.unsafe_NewArray
|
//go:linkname newArray reflect.unsafe_NewArray
|
||||||
func newArray(*rtype, int) unsafe.Pointer
|
func newArray(*rtype, int) unsafe.Pointer
|
||||||
|
|
||||||
func (d *sliceDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
func (d *sliceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) {
|
||||||
buflen := len(buf)
|
buflen := int64(len(buf))
|
||||||
for ; cursor < buflen; cursor++ {
|
for ; cursor < buflen; cursor++ {
|
||||||
switch buf[cursor] {
|
switch buf[cursor] {
|
||||||
case ' ', '\n', '\t', '\r':
|
case ' ', '\n', '\t', '\r':
|
||||||
|
@ -97,10 +96,10 @@ func (d *sliceDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||||
slice.Cap = cap
|
slice.Cap = cap
|
||||||
slice.Data = data
|
slice.Data = data
|
||||||
d.releaseSlice(slice)
|
d.releaseSlice(slice)
|
||||||
return 0, errors.New("syntax error slice")
|
return 0, errInvalidCharacter(buf[cursor], "slice", cursor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0, errors.New("unexpected error slice")
|
return 0, errUnexpectedEndOfJSON("slice", cursor)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package json
|
package json
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,7 +11,7 @@ func newStringDecoder() *stringDecoder {
|
||||||
return &stringDecoder{}
|
return &stringDecoder{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *stringDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
func (d *stringDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) {
|
||||||
bytes, c, err := d.decodeByte(buf, cursor)
|
bytes, c, err := d.decodeByte(buf, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -22,7 +21,7 @@ func (d *stringDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *stringDecoder) decodeByte(buf []byte, cursor int) ([]byte, int, error) {
|
func (d *stringDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
|
||||||
for {
|
for {
|
||||||
switch buf[cursor] {
|
switch buf[cursor] {
|
||||||
case ' ', '\n', '\t', '\r':
|
case ' ', '\n', '\t', '\r':
|
||||||
|
@ -39,24 +38,24 @@ func (d *stringDecoder) decodeByte(buf []byte, cursor int) ([]byte, int, error)
|
||||||
cursor++
|
cursor++
|
||||||
return literal, cursor, nil
|
return literal, cursor, nil
|
||||||
case '\000':
|
case '\000':
|
||||||
return nil, 0, errors.New("unexpected error string")
|
return nil, 0, errUnexpectedEndOfJSON("string", cursor)
|
||||||
}
|
}
|
||||||
cursor++
|
cursor++
|
||||||
}
|
}
|
||||||
return nil, 0, errors.New("unexpected error string")
|
return nil, 0, errUnexpectedEndOfJSON("string", cursor)
|
||||||
case 'n':
|
case 'n':
|
||||||
buflen := len(buf)
|
buflen := int64(len(buf))
|
||||||
if cursor+3 >= buflen {
|
if cursor+3 >= buflen {
|
||||||
return nil, 0, errors.New("unexpected error. invalid bool character")
|
return nil, 0, errUnexpectedEndOfJSON("null", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+1] != 'u' {
|
if buf[cursor+1] != 'u' {
|
||||||
return nil, 0, errors.New("unexpected error. invalid bool character")
|
return nil, 0, errInvalidCharacter(buf[cursor+1], "null", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+2] != 'l' {
|
if buf[cursor+2] != 'l' {
|
||||||
return nil, 0, errors.New("unexpected error. invalid bool character")
|
return nil, 0, errInvalidCharacter(buf[cursor+2], "null", cursor)
|
||||||
}
|
}
|
||||||
if buf[cursor+3] != 'l' {
|
if buf[cursor+3] != 'l' {
|
||||||
return nil, 0, errors.New("unexpected error. invalid bool character")
|
return nil, 0, errInvalidCharacter(buf[cursor+3], "null", cursor)
|
||||||
}
|
}
|
||||||
cursor += 5
|
cursor += 5
|
||||||
return []byte{'n', 'u', 'l', 'l'}, cursor, nil
|
return []byte{'n', 'u', 'l', 'l'}, cursor, nil
|
||||||
|
@ -65,5 +64,5 @@ func (d *stringDecoder) decodeByte(buf []byte, cursor int) ([]byte, int, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ERROR:
|
ERROR:
|
||||||
return nil, 0, errors.New("unexpected error key delimiter")
|
return nil, 0, errNotAtBeginningOfValue(cursor)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package json
|
package json
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,14 +21,14 @@ func newStructDecoder(fieldMap map[string]*structFieldSet) *structDecoder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *structDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
func (d *structDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) {
|
||||||
buflen := len(buf)
|
buflen := int64(len(buf))
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
cursor = skipWhiteSpace(buf, cursor)
|
||||||
if buflen < 2 {
|
|
||||||
return 0, errors.New("unexpected error {}")
|
|
||||||
}
|
|
||||||
if buf[cursor] != '{' {
|
if buf[cursor] != '{' {
|
||||||
return 0, errors.New("unexpected error {")
|
return 0, errNotAtBeginningOfValue(cursor)
|
||||||
|
}
|
||||||
|
if buflen < 2 {
|
||||||
|
return 0, errUnexpectedEndOfJSON("object", cursor)
|
||||||
}
|
}
|
||||||
cursor++
|
cursor++
|
||||||
for ; cursor < buflen; cursor++ {
|
for ; cursor < buflen; cursor++ {
|
||||||
|
@ -40,11 +39,11 @@ func (d *structDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||||
cursor = c
|
cursor = c
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
cursor = skipWhiteSpace(buf, cursor)
|
||||||
if buf[cursor] != ':' {
|
if buf[cursor] != ':' {
|
||||||
return 0, errors.New("unexpected error invalid delimiter for object")
|
return 0, errExpected("colon after object key", cursor)
|
||||||
}
|
}
|
||||||
cursor++
|
cursor++
|
||||||
if cursor >= buflen {
|
if cursor >= buflen {
|
||||||
return 0, errors.New("unexpected error missing value")
|
return 0, errExpected("object value after colon", cursor)
|
||||||
}
|
}
|
||||||
k := *(*string)(unsafe.Pointer(&key))
|
k := *(*string)(unsafe.Pointer(&key))
|
||||||
field, exists := d.fieldMap[k]
|
field, exists := d.fieldMap[k]
|
||||||
|
@ -67,7 +66,7 @@ func (d *structDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
}
|
}
|
||||||
if buf[cursor] != ',' {
|
if buf[cursor] != ',' {
|
||||||
return 0, errors.New("unexpected error ,")
|
return 0, errExpected("comma after object element", cursor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
package json
|
package json
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type uintDecoder struct {
|
type uintDecoder struct {
|
||||||
op func(uintptr, uint64)
|
op func(uintptr, uint64)
|
||||||
}
|
}
|
||||||
|
@ -28,8 +24,8 @@ func (d *uintDecoder) parseUint(b []byte) uint64 {
|
||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *uintDecoder) decodeByte(buf []byte, cursor int) ([]byte, int, error) {
|
func (d *uintDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
|
||||||
buflen := len(buf)
|
buflen := int64(len(buf))
|
||||||
for ; cursor < buflen; cursor++ {
|
for ; cursor < buflen; cursor++ {
|
||||||
switch buf[cursor] {
|
switch buf[cursor] {
|
||||||
case ' ', '\n', '\t', '\r':
|
case ' ', '\n', '\t', '\r':
|
||||||
|
@ -46,12 +42,14 @@ func (d *uintDecoder) decodeByte(buf []byte, cursor int) ([]byte, int, error) {
|
||||||
}
|
}
|
||||||
num := buf[start:cursor]
|
num := buf[start:cursor]
|
||||||
return num, cursor, nil
|
return num, cursor, nil
|
||||||
|
default:
|
||||||
|
return nil, 0, errInvalidCharacter(buf[cursor], "number(unsigned integer)", cursor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, 0, errors.New("unexpected error number")
|
return nil, 0, errUnexpectedEndOfJSON("number(unsigned integer)", cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *uintDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
func (d *uintDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) {
|
||||||
bytes, c, err := d.decodeByte(buf, cursor)
|
bytes, c, err := d.decodeByte(buf, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|
|
@ -12,7 +12,7 @@ func newUnmarshalJSONDecoder(typ *rtype) *unmarshalJSONDecoder {
|
||||||
return &unmarshalJSONDecoder{typ: typ}
|
return &unmarshalJSONDecoder{typ: typ}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *unmarshalJSONDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
func (d *unmarshalJSONDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) {
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
cursor = skipWhiteSpace(buf, cursor)
|
||||||
start := cursor
|
start := cursor
|
||||||
end, err := skipValue(buf, cursor)
|
end, err := skipValue(buf, cursor)
|
||||||
|
|
|
@ -13,7 +13,7 @@ func newUnmarshalTextDecoder(typ *rtype) *unmarshalTextDecoder {
|
||||||
return &unmarshalTextDecoder{typ: typ}
|
return &unmarshalTextDecoder{typ: typ}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *unmarshalTextDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
func (d *unmarshalTextDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error) {
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
cursor = skipWhiteSpace(buf, cursor)
|
||||||
start := cursor
|
start := cursor
|
||||||
end, err := skipValue(buf, cursor)
|
end, err := skipValue(buf, cursor)
|
||||||
|
|
22
error.go
22
error.go
|
@ -116,3 +116,25 @@ type UnsupportedValueError struct {
|
||||||
func (e *UnsupportedValueError) Error() string {
|
func (e *UnsupportedValueError) Error() string {
|
||||||
return fmt.Sprintf("json: unsupported value: %s", e.Str)
|
return fmt.Sprintf("json: unsupported value: %s", e.Str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func errNotAtBeginningOfValue(cursor int64) *SyntaxError {
|
||||||
|
return &SyntaxError{msg: "not at beginning of value", Offset: cursor}
|
||||||
|
}
|
||||||
|
|
||||||
|
func errUnexpectedEndOfJSON(msg string, cursor int64) *SyntaxError {
|
||||||
|
return &SyntaxError{
|
||||||
|
msg: fmt.Sprintf("unexpected end of JSON input for %s", msg),
|
||||||
|
Offset: cursor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func errExpected(msg string, cursor int64) *SyntaxError {
|
||||||
|
return &SyntaxError{msg: fmt.Sprintf("expected %s", msg), Offset: cursor}
|
||||||
|
}
|
||||||
|
|
||||||
|
func errInvalidCharacter(c byte, context string, cursor int64) *SyntaxError {
|
||||||
|
return &SyntaxError{
|
||||||
|
msg: fmt.Sprintf("invalid character %c as %s", c, context),
|
||||||
|
Offset: cursor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue