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