mirror of https://github.com/goccy/go-json.git
Remove context for decoding
This commit is contained in:
parent
82e8cc766f
commit
f198ef6517
26
decode.go
26
decode.go
|
@ -23,7 +23,7 @@ type Token interface{}
|
|||
type Delim rune
|
||||
|
||||
type decoder interface {
|
||||
decode(*context, uintptr) error
|
||||
decode([]byte, int, uintptr) (int, error)
|
||||
}
|
||||
|
||||
type Decoder struct {
|
||||
|
@ -47,17 +47,11 @@ func (m *decoderMap) set(k uintptr, dec decoder) {
|
|||
}
|
||||
|
||||
var (
|
||||
ctxPool sync.Pool
|
||||
cachedDecoder decoderMap
|
||||
)
|
||||
|
||||
func init() {
|
||||
cachedDecoder = decoderMap{}
|
||||
ctxPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return newContext()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// NewDecoder returns a new decoder that reads from r.
|
||||
|
@ -90,13 +84,9 @@ func (d *Decoder) decode(src []byte, header *interfaceHeader) error {
|
|||
dec = compiledDec
|
||||
}
|
||||
ptr := uintptr(header.ptr)
|
||||
ctx := ctxPool.Get().(*context)
|
||||
ctx.setBuf(src)
|
||||
if err := dec.decode(ctx, ptr); err != nil {
|
||||
ctxPool.Put(ctx)
|
||||
if _, err := dec.decode(src, 0, ptr); err != nil {
|
||||
return err
|
||||
}
|
||||
ctxPool.Put(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -133,11 +123,6 @@ func (d *Decoder) Decode(v interface{}) error {
|
|||
dec = compiledDec
|
||||
}
|
||||
ptr := uintptr(header.ptr)
|
||||
ctx := ctxPool.Get().(*context)
|
||||
defer ctxPool.Put(ctx)
|
||||
d.buffered = func() io.Reader {
|
||||
return bytes.NewReader(ctx.buf[ctx.cursor:])
|
||||
}
|
||||
for {
|
||||
buf := make([]byte, 1024)
|
||||
n, err := d.r.Read(buf)
|
||||
|
@ -147,10 +132,13 @@ func (d *Decoder) Decode(v interface{}) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.setBuf(buf[:n])
|
||||
if err := dec.decode(ctx, ptr); err != nil {
|
||||
cursor, err := dec.decode(buf[:n], 0, ptr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.buffered = func() io.Reader {
|
||||
return bytes.NewReader(buf[cursor:])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -20,10 +20,8 @@ func newArrayDecoder(dec decoder, elemType *rtype, alen int) *arrayDecoder {
|
|||
}
|
||||
}
|
||||
|
||||
func (d *arrayDecoder) decode(ctx *context, p uintptr) error {
|
||||
buf := ctx.buf
|
||||
buflen := ctx.buflen
|
||||
cursor := ctx.cursor
|
||||
func (d *arrayDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||
buflen := len(buf)
|
||||
for ; cursor < buflen; cursor++ {
|
||||
switch buf[cursor] {
|
||||
case ' ', '\n', '\t', '\r':
|
||||
|
@ -31,23 +29,25 @@ func (d *arrayDecoder) decode(ctx *context, p uintptr) error {
|
|||
case '[':
|
||||
idx := 0
|
||||
for {
|
||||
ctx.cursor = cursor + 1
|
||||
if err := d.valueDecoder.decode(ctx, p+uintptr(idx)*d.size); err != nil {
|
||||
return err
|
||||
cursor++
|
||||
c, err := d.valueDecoder.decode(buf, cursor, p+uintptr(idx)*d.size)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
cursor = ctx.skipWhiteSpace()
|
||||
cursor = c
|
||||
cursor = skipWhiteSpace(buf, cursor)
|
||||
switch buf[cursor] {
|
||||
case ']':
|
||||
ctx.cursor++
|
||||
return nil
|
||||
cursor++
|
||||
return cursor, nil
|
||||
case ',':
|
||||
idx++
|
||||
continue
|
||||
default:
|
||||
return errors.New("syntax error array")
|
||||
return 0, errors.New("syntax error array")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return errors.New("unexpected error array")
|
||||
return 0, errors.New("unexpected error array")
|
||||
}
|
||||
|
|
|
@ -11,44 +11,43 @@ func newBoolDecoder() *boolDecoder {
|
|||
return &boolDecoder{}
|
||||
}
|
||||
|
||||
func (d *boolDecoder) decode(ctx *context, p uintptr) error {
|
||||
ctx.skipWhiteSpace()
|
||||
buf := ctx.buf
|
||||
cursor := ctx.cursor
|
||||
func (d *boolDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||
buflen := len(buf)
|
||||
cursor = skipWhiteSpace(buf, cursor)
|
||||
switch buf[cursor] {
|
||||
case 't':
|
||||
if cursor+3 >= ctx.buflen {
|
||||
return errors.New("unexpected error. invalid bool character")
|
||||
if cursor+3 >= buflen {
|
||||
return 0, errors.New("unexpected error. invalid bool character")
|
||||
}
|
||||
if buf[cursor+1] != 'r' {
|
||||
return errors.New("unexpected error. invalid bool character")
|
||||
return 0, errors.New("unexpected error. invalid bool character")
|
||||
}
|
||||
if buf[cursor+2] != 'u' {
|
||||
return errors.New("unexpected error. invalid bool character")
|
||||
return 0, errors.New("unexpected error. invalid bool character")
|
||||
}
|
||||
if buf[cursor+3] != 'e' {
|
||||
return errors.New("unexpected error. invalid bool character")
|
||||
return 0, errors.New("unexpected error. invalid bool character")
|
||||
}
|
||||
ctx.cursor += 4
|
||||
cursor += 4
|
||||
*(*bool)(unsafe.Pointer(p)) = true
|
||||
case 'f':
|
||||
if cursor+4 >= ctx.buflen {
|
||||
return errors.New("unexpected error. invalid bool character")
|
||||
if cursor+4 >= buflen {
|
||||
return 0, errors.New("unexpected error. invalid bool character")
|
||||
}
|
||||
if buf[cursor+1] != 'a' {
|
||||
return errors.New("unexpected error. invalid bool character")
|
||||
return 0, errors.New("unexpected error. invalid bool character")
|
||||
}
|
||||
if buf[cursor+2] != 'l' {
|
||||
return errors.New("unexpected error. invalid bool character")
|
||||
return 0, errors.New("unexpected error. invalid bool character")
|
||||
}
|
||||
if buf[cursor+3] != 's' {
|
||||
return errors.New("unexpected error. invalid bool character")
|
||||
return 0, errors.New("unexpected error. invalid bool character")
|
||||
}
|
||||
if buf[cursor+4] != 'e' {
|
||||
return errors.New("unexpected error. invalid bool character")
|
||||
return 0, errors.New("unexpected error. invalid bool character")
|
||||
}
|
||||
ctx.cursor += 5
|
||||
cursor += 5
|
||||
*(*bool)(unsafe.Pointer(p)) = false
|
||||
}
|
||||
return nil
|
||||
return cursor, nil
|
||||
}
|
||||
|
|
|
@ -11,31 +11,13 @@ func init() {
|
|||
isWhiteSpace['\r'] = true
|
||||
}
|
||||
|
||||
type context struct {
|
||||
cursor int
|
||||
buf []byte
|
||||
buflen int
|
||||
}
|
||||
|
||||
func (c *context) setBuf(buf []byte) {
|
||||
c.buf = buf
|
||||
c.buflen = len(buf)
|
||||
c.cursor = 0
|
||||
}
|
||||
|
||||
func (c *context) skipWhiteSpace() int {
|
||||
buflen := c.buflen
|
||||
buf := c.buf
|
||||
for cursor := c.cursor; cursor < buflen; cursor++ {
|
||||
func skipWhiteSpace(buf []byte, cursor int) int {
|
||||
buflen := len(buf)
|
||||
for ; cursor < buflen; cursor++ {
|
||||
if isWhiteSpace[buf[cursor]] {
|
||||
continue
|
||||
}
|
||||
c.cursor = cursor
|
||||
return cursor
|
||||
}
|
||||
return buflen
|
||||
}
|
||||
|
||||
func newContext() *context {
|
||||
return &context{}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,8 @@ func newFloatDecoder(op func(uintptr, float64)) *floatDecoder {
|
|||
return &floatDecoder{op: op}
|
||||
}
|
||||
|
||||
func (d *floatDecoder) decodeByte(ctx *context) ([]byte, error) {
|
||||
buf := ctx.buf
|
||||
cursor := ctx.cursor
|
||||
buflen := ctx.buflen
|
||||
func (d *floatDecoder) decodeByte(buf []byte, cursor int) ([]byte, int, error) {
|
||||
buflen := len(buf)
|
||||
for ; cursor < buflen; cursor++ {
|
||||
switch buf[cursor] {
|
||||
case ' ', '\n', '\t', '\r':
|
||||
|
@ -32,24 +30,24 @@ func (d *floatDecoder) decodeByte(ctx *context) ([]byte, error) {
|
|||
}
|
||||
break
|
||||
}
|
||||
num := ctx.buf[start:cursor]
|
||||
ctx.cursor = cursor
|
||||
return num, nil
|
||||
num := buf[start:cursor]
|
||||
return num, cursor, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("unexpected error number")
|
||||
return nil, 0, errors.New("unexpected error number")
|
||||
}
|
||||
|
||||
func (d *floatDecoder) decode(ctx *context, p uintptr) error {
|
||||
bytes, err := d.decodeByte(ctx)
|
||||
func (d *floatDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||
bytes, c, err := d.decodeByte(buf, cursor)
|
||||
if err != nil {
|
||||
return err
|
||||
return 0, err
|
||||
}
|
||||
cursor = c
|
||||
s := *(*string)(unsafe.Pointer(&bytes))
|
||||
f64, err := strconv.ParseFloat(s, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
return 0, err
|
||||
}
|
||||
d.op(p, f64)
|
||||
return nil
|
||||
return cursor, nil
|
||||
}
|
||||
|
|
|
@ -38,10 +38,8 @@ func (d *intDecoder) parseInt(b []byte) int64 {
|
|||
return sum
|
||||
}
|
||||
|
||||
func (d *intDecoder) decodeByte(ctx *context) ([]byte, error) {
|
||||
buf := ctx.buf
|
||||
cursor := ctx.cursor
|
||||
buflen := ctx.buflen
|
||||
func (d *intDecoder) decodeByte(buf []byte, cursor int) ([]byte, int, error) {
|
||||
buflen := len(buf)
|
||||
for ; cursor < buflen; cursor++ {
|
||||
switch buf[cursor] {
|
||||
case ' ', '\n', '\t', '\r':
|
||||
|
@ -56,19 +54,19 @@ func (d *intDecoder) decodeByte(ctx *context) ([]byte, error) {
|
|||
}
|
||||
break
|
||||
}
|
||||
num := ctx.buf[start:cursor]
|
||||
ctx.cursor = cursor
|
||||
return num, nil
|
||||
num := buf[start:cursor]
|
||||
return num, cursor, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("unexpected error number")
|
||||
return nil, 0, errors.New("unexpected error number")
|
||||
}
|
||||
|
||||
func (d *intDecoder) decode(ctx *context, p uintptr) error {
|
||||
bytes, err := d.decodeByte(ctx)
|
||||
func (d *intDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||
bytes, c, err := d.decodeByte(buf, cursor)
|
||||
if err != nil {
|
||||
return err
|
||||
return 0, err
|
||||
}
|
||||
cursor = c
|
||||
d.op(p, d.parseInt(bytes))
|
||||
return nil
|
||||
return cursor, nil
|
||||
}
|
||||
|
|
|
@ -26,57 +26,57 @@ func makemap(*rtype, int) unsafe.Pointer
|
|||
//go:noescape
|
||||
func mapassign(t *rtype, m unsafe.Pointer, key, val unsafe.Pointer)
|
||||
|
||||
func (d *mapDecoder) setKey(ctx *context, key interface{}) error {
|
||||
func (d *mapDecoder) setKey(buf []byte, cursor int, key interface{}) (int, error) {
|
||||
header := (*interfaceHeader)(unsafe.Pointer(&key))
|
||||
return d.keyDecoder.decode(ctx, uintptr(header.ptr))
|
||||
return d.keyDecoder.decode(buf, cursor, uintptr(header.ptr))
|
||||
}
|
||||
|
||||
func (d *mapDecoder) setValue(ctx *context, key interface{}) error {
|
||||
func (d *mapDecoder) setValue(buf []byte, cursor int, key interface{}) (int, error) {
|
||||
header := (*interfaceHeader)(unsafe.Pointer(&key))
|
||||
return d.valueDecoder.decode(ctx, uintptr(header.ptr))
|
||||
return d.valueDecoder.decode(buf, cursor, uintptr(header.ptr))
|
||||
}
|
||||
|
||||
func (d *mapDecoder) decode(ctx *context, p uintptr) error {
|
||||
ctx.skipWhiteSpace()
|
||||
buf := ctx.buf
|
||||
buflen := ctx.buflen
|
||||
cursor := ctx.cursor
|
||||
func (d *mapDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||
cursor = skipWhiteSpace(buf, cursor)
|
||||
buflen := len(buf)
|
||||
if buflen < 2 {
|
||||
return errors.New("unexpected error {}")
|
||||
return 0, errors.New("unexpected error {}")
|
||||
}
|
||||
if buf[cursor] != '{' {
|
||||
return errors.New("unexpected error {")
|
||||
return 0, errors.New("unexpected error {")
|
||||
}
|
||||
cursor++
|
||||
mapValue := makemap(d.mapType, 0)
|
||||
for ; cursor < buflen; cursor++ {
|
||||
ctx.cursor = cursor
|
||||
var key interface{}
|
||||
if err := d.setKey(ctx, &key); err != nil {
|
||||
return err
|
||||
keyCursor, err := d.setKey(buf, cursor, &key)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
cursor = ctx.skipWhiteSpace()
|
||||
cursor = keyCursor
|
||||
cursor = skipWhiteSpace(buf, cursor)
|
||||
if buf[cursor] != ':' {
|
||||
return errors.New("unexpected error invalid delimiter for object")
|
||||
return 0, errors.New("unexpected error invalid delimiter for object")
|
||||
}
|
||||
cursor++
|
||||
if cursor >= buflen {
|
||||
return errors.New("unexpected error missing value")
|
||||
return 0, errors.New("unexpected error missing value")
|
||||
}
|
||||
ctx.cursor = cursor
|
||||
var value interface{}
|
||||
if err := d.setValue(ctx, &value); err != nil {
|
||||
return err
|
||||
valueCursor, err := d.setValue(buf, cursor, &value)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
cursor = valueCursor
|
||||
mapassign(d.mapType, mapValue, unsafe.Pointer(&key), unsafe.Pointer(&value))
|
||||
cursor = ctx.skipWhiteSpace()
|
||||
cursor = skipWhiteSpace(buf, valueCursor)
|
||||
if buf[cursor] == '}' {
|
||||
*(*unsafe.Pointer)(unsafe.Pointer(p)) = mapValue
|
||||
return nil
|
||||
return cursor, nil
|
||||
}
|
||||
if buf[cursor] != ',' {
|
||||
return errors.New("unexpected error ,")
|
||||
return 0, errors.New("unexpected error ,")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return cursor, nil
|
||||
}
|
||||
|
|
|
@ -16,11 +16,13 @@ func newPtrDecoder(dec decoder, typ *rtype) *ptrDecoder {
|
|||
//go:linkname unsafe_New reflect.unsafe_New
|
||||
func unsafe_New(*rtype) uintptr
|
||||
|
||||
func (d *ptrDecoder) decode(ctx *context, p uintptr) error {
|
||||
func (d *ptrDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||
newptr := unsafe_New(d.typ)
|
||||
if err := d.dec.decode(ctx, newptr); err != nil {
|
||||
return err
|
||||
c, err := d.dec.decode(buf, cursor, newptr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
cursor = c
|
||||
*(*uintptr)(unsafe.Pointer(p)) = newptr
|
||||
return nil
|
||||
return cursor, nil
|
||||
}
|
||||
|
|
|
@ -26,10 +26,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(ctx *context, p uintptr) error {
|
||||
buf := ctx.buf
|
||||
buflen := ctx.buflen
|
||||
cursor := ctx.cursor
|
||||
func (d *sliceDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||
buflen := len(buf)
|
||||
for ; cursor < buflen; cursor++ {
|
||||
switch buf[cursor] {
|
||||
case ' ', '\n', '\t', '\r':
|
||||
|
@ -39,7 +37,7 @@ func (d *sliceDecoder) decode(ctx *context, p uintptr) error {
|
|||
cap := 2
|
||||
data := uintptr(newArray(d.elemType, cap))
|
||||
for {
|
||||
ctx.cursor = cursor + 1
|
||||
cursor++
|
||||
if cap <= idx {
|
||||
src := reflect.SliceHeader{Data: data, Len: idx, Cap: cap}
|
||||
cap *= 2
|
||||
|
@ -47,10 +45,12 @@ func (d *sliceDecoder) decode(ctx *context, p uintptr) error {
|
|||
dst := reflect.SliceHeader{Data: data, Len: idx, Cap: cap}
|
||||
copySlice(d.elemType, dst, src)
|
||||
}
|
||||
if err := d.valueDecoder.decode(ctx, data+uintptr(idx)*d.size); err != nil {
|
||||
return err
|
||||
c, err := d.valueDecoder.decode(buf, cursor, data+uintptr(idx)*d.size)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
cursor = ctx.skipWhiteSpace()
|
||||
cursor = c
|
||||
cursor = skipWhiteSpace(buf, cursor)
|
||||
switch buf[cursor] {
|
||||
case ']':
|
||||
*(*reflect.SliceHeader)(unsafe.Pointer(p)) = reflect.SliceHeader{
|
||||
|
@ -58,16 +58,16 @@ func (d *sliceDecoder) decode(ctx *context, p uintptr) error {
|
|||
Len: idx + 1,
|
||||
Cap: cap,
|
||||
}
|
||||
ctx.cursor++
|
||||
return nil
|
||||
cursor++
|
||||
return cursor, nil
|
||||
case ',':
|
||||
idx++
|
||||
continue
|
||||
default:
|
||||
return errors.New("syntax error slice")
|
||||
return 0, errors.New("syntax error slice")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return errors.New("unexpected error slice")
|
||||
return 0, errors.New("unexpected error slice")
|
||||
}
|
||||
|
|
|
@ -12,19 +12,18 @@ func newStringDecoder() *stringDecoder {
|
|||
return &stringDecoder{}
|
||||
}
|
||||
|
||||
func (d *stringDecoder) decode(ctx *context, p uintptr) error {
|
||||
bytes, err := d.decodeByte(ctx)
|
||||
func (d *stringDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||
bytes, c, err := d.decodeByte(buf, cursor)
|
||||
if err != nil {
|
||||
return err
|
||||
return 0, err
|
||||
}
|
||||
cursor = c
|
||||
*(*string)(unsafe.Pointer(p)) = *(*string)(unsafe.Pointer(&bytes))
|
||||
return nil
|
||||
return cursor, nil
|
||||
}
|
||||
|
||||
func (d *stringDecoder) decodeByte(ctx *context) ([]byte, error) {
|
||||
buf := ctx.buf
|
||||
buflen := ctx.buflen
|
||||
cursor := ctx.cursor
|
||||
func (d *stringDecoder) decodeByte(buf []byte, cursor int) ([]byte, int, error) {
|
||||
buflen := len(buf)
|
||||
for ; cursor < buflen; cursor++ {
|
||||
switch buf[cursor] {
|
||||
case ' ', '\n', '\t', '\r':
|
||||
|
@ -39,27 +38,26 @@ func (d *stringDecoder) decodeByte(ctx *context) ([]byte, error) {
|
|||
case '"':
|
||||
literal := buf[start:cursor]
|
||||
cursor++
|
||||
ctx.cursor = cursor
|
||||
return literal, nil
|
||||
return literal, cursor, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("unexpected error string")
|
||||
return nil, 0, errors.New("unexpected error string")
|
||||
case 'n':
|
||||
if cursor+3 >= ctx.buflen {
|
||||
return nil, errors.New("unexpected error. invalid bool character")
|
||||
if cursor+3 >= buflen {
|
||||
return nil, 0, errors.New("unexpected error. invalid bool character")
|
||||
}
|
||||
if buf[cursor+1] != 'u' {
|
||||
return nil, errors.New("unexpected error. invalid bool character")
|
||||
return nil, 0, errors.New("unexpected error. invalid bool character")
|
||||
}
|
||||
if buf[cursor+2] != 'l' {
|
||||
return nil, errors.New("unexpected error. invalid bool character")
|
||||
return nil, 0, errors.New("unexpected error. invalid bool character")
|
||||
}
|
||||
if buf[cursor+3] != 'l' {
|
||||
return nil, errors.New("unexpected error. invalid bool character")
|
||||
return nil, 0, errors.New("unexpected error. invalid bool character")
|
||||
}
|
||||
ctx.cursor += 5
|
||||
return []byte{}, nil
|
||||
cursor += 5
|
||||
return []byte{}, cursor, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("unexpected error key delimiter")
|
||||
return nil, 0, errors.New("unexpected error key delimiter")
|
||||
}
|
||||
|
|
|
@ -22,13 +22,11 @@ func newStructDecoder(fieldMap map[string]*structFieldSet) *structDecoder {
|
|||
}
|
||||
}
|
||||
|
||||
func (d *structDecoder) skipValue(ctx *context) error {
|
||||
ctx.skipWhiteSpace()
|
||||
func (d *structDecoder) skipValue(buf []byte, cursor int) (int, error) {
|
||||
cursor = skipWhiteSpace(buf, cursor)
|
||||
braceCount := 0
|
||||
bracketCount := 0
|
||||
cursor := ctx.cursor
|
||||
buf := ctx.buf
|
||||
buflen := ctx.buflen
|
||||
buflen := len(buf)
|
||||
for ; cursor < buflen; cursor++ {
|
||||
switch buf[cursor] {
|
||||
case '{':
|
||||
|
@ -38,15 +36,13 @@ func (d *structDecoder) skipValue(ctx *context) error {
|
|||
case '}':
|
||||
braceCount--
|
||||
if braceCount == -1 && bracketCount == 0 {
|
||||
ctx.cursor = cursor
|
||||
return nil
|
||||
return cursor, nil
|
||||
}
|
||||
case ']':
|
||||
bracketCount--
|
||||
case ',':
|
||||
if bracketCount == 0 && braceCount == 0 {
|
||||
ctx.cursor = cursor
|
||||
return nil
|
||||
return cursor, nil
|
||||
}
|
||||
case '"':
|
||||
cursor++
|
||||
|
@ -56,8 +52,7 @@ func (d *structDecoder) skipValue(ctx *context) error {
|
|||
cursor++
|
||||
case '"':
|
||||
if bracketCount == 0 && braceCount == 0 {
|
||||
ctx.cursor = cursor + 1
|
||||
return nil
|
||||
return cursor + 1, nil
|
||||
}
|
||||
goto QUOTE_END
|
||||
}
|
||||
|
@ -65,55 +60,56 @@ func (d *structDecoder) skipValue(ctx *context) error {
|
|||
QUOTE_END:
|
||||
}
|
||||
}
|
||||
return errors.New("unexpected error value")
|
||||
return cursor, errors.New("unexpected error value")
|
||||
}
|
||||
|
||||
func (d *structDecoder) decode(ctx *context, p uintptr) error {
|
||||
ctx.skipWhiteSpace()
|
||||
buf := ctx.buf
|
||||
buflen := ctx.buflen
|
||||
cursor := ctx.cursor
|
||||
func (d *structDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||
buflen := len(buf)
|
||||
cursor = skipWhiteSpace(buf, cursor)
|
||||
if buflen < 2 {
|
||||
return errors.New("unexpected error {}")
|
||||
return 0, errors.New("unexpected error {}")
|
||||
}
|
||||
if buf[cursor] != '{' {
|
||||
return errors.New("unexpected error {")
|
||||
return 0, errors.New("unexpected error {")
|
||||
}
|
||||
cursor++
|
||||
for ; cursor < buflen; cursor++ {
|
||||
ctx.cursor = cursor
|
||||
key, err := d.keyDecoder.decodeByte(ctx)
|
||||
key, c, err := d.keyDecoder.decodeByte(buf, cursor)
|
||||
if err != nil {
|
||||
return err
|
||||
return 0, err
|
||||
}
|
||||
cursor = ctx.skipWhiteSpace()
|
||||
cursor = c
|
||||
cursor = skipWhiteSpace(buf, cursor)
|
||||
if buf[cursor] != ':' {
|
||||
return errors.New("unexpected error invalid delimiter for object")
|
||||
return 0, errors.New("unexpected error invalid delimiter for object")
|
||||
}
|
||||
cursor++
|
||||
if cursor >= buflen {
|
||||
return errors.New("unexpected error missing value")
|
||||
return 0, errors.New("unexpected error missing value")
|
||||
}
|
||||
ctx.cursor = cursor
|
||||
k := *(*string)(unsafe.Pointer(&key))
|
||||
field, exists := d.fieldMap[k]
|
||||
if exists {
|
||||
if err := field.dec.decode(ctx, p+field.offset); err != nil {
|
||||
return err
|
||||
c, err := field.dec.decode(buf, cursor, p+field.offset)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
cursor = c
|
||||
} else {
|
||||
if err := d.skipValue(ctx); err != nil {
|
||||
return err
|
||||
c, err := d.skipValue(buf, cursor)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
cursor = c
|
||||
}
|
||||
cursor = ctx.skipWhiteSpace()
|
||||
cursor = skipWhiteSpace(buf, cursor)
|
||||
if buf[cursor] == '}' {
|
||||
ctx.cursor++
|
||||
return nil
|
||||
cursor++
|
||||
return cursor, nil
|
||||
}
|
||||
if buf[cursor] != ',' {
|
||||
return errors.New("unexpected error ,")
|
||||
return 0, errors.New("unexpected error ,")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return cursor, nil
|
||||
}
|
||||
|
|
|
@ -28,10 +28,8 @@ func (d *uintDecoder) parseUint(b []byte) uint64 {
|
|||
return sum
|
||||
}
|
||||
|
||||
func (d *uintDecoder) decodeByte(ctx *context) ([]byte, error) {
|
||||
buf := ctx.buf
|
||||
buflen := ctx.buflen
|
||||
cursor := ctx.cursor
|
||||
func (d *uintDecoder) decodeByte(buf []byte, cursor int) ([]byte, int, error) {
|
||||
buflen := len(buf)
|
||||
for ; cursor < buflen; cursor++ {
|
||||
switch buf[cursor] {
|
||||
case ' ', '\n', '\t', '\r':
|
||||
|
@ -47,18 +45,18 @@ func (d *uintDecoder) decodeByte(ctx *context) ([]byte, error) {
|
|||
break
|
||||
}
|
||||
num := buf[start:cursor]
|
||||
ctx.cursor = cursor
|
||||
return num, nil
|
||||
return num, cursor, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("unexpected error number")
|
||||
return nil, 0, errors.New("unexpected error number")
|
||||
}
|
||||
|
||||
func (d *uintDecoder) decode(ctx *context, p uintptr) error {
|
||||
bytes, err := d.decodeByte(ctx)
|
||||
func (d *uintDecoder) decode(buf []byte, cursor int, p uintptr) (int, error) {
|
||||
bytes, c, err := d.decodeByte(buf, cursor)
|
||||
if err != nil {
|
||||
return err
|
||||
return 0, err
|
||||
}
|
||||
cursor = c
|
||||
d.op(p, d.parseUint(bytes))
|
||||
return nil
|
||||
return cursor, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue