Support SyntaxError

This commit is contained in:
Masaaki Goshima 2020-05-23 12:51:09 +09:00
parent 12b34f0663
commit 4acc22e0fe
16 changed files with 112 additions and 112 deletions

View File

@ -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 {

View File

@ -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)
} }

View File

@ -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

View File

@ -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)
} }

View File

@ -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

View File

@ -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

View File

@ -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)
} }

View File

@ -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

View File

@ -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 {

View File

@ -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)
} }

View File

@ -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)
} }

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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,
}
}