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