forked from mirror/go-json
Fix skipWhiteSpace for stream decoder
This commit is contained in:
parent
a973797e61
commit
e7b7118f4e
|
@ -58,8 +58,7 @@ func (d *arrayDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) er
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
idx++
|
idx++
|
||||||
s.skipWhiteSpace()
|
switch s.skipWhiteSpace() {
|
||||||
switch s.char() {
|
|
||||||
case ']':
|
case ']':
|
||||||
for idx < d.alen {
|
for idx < d.alen {
|
||||||
*(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue
|
*(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue
|
||||||
|
|
|
@ -16,9 +16,9 @@ func newBoolDecoder(structName, fieldName string) *boolDecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *boolDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
|
func (d *boolDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
|
||||||
s.skipWhiteSpace()
|
c := s.skipWhiteSpace()
|
||||||
for {
|
for {
|
||||||
switch s.char() {
|
switch c {
|
||||||
case 't':
|
case 't':
|
||||||
if err := trueBytes(s); err != nil {
|
if err := trueBytes(s); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -38,6 +38,7 @@ func (d *boolDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) err
|
||||||
return nil
|
return nil
|
||||||
case nul:
|
case nul:
|
||||||
if s.read() {
|
if s.read() {
|
||||||
|
c = s.char()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
goto ERROR
|
goto ERROR
|
||||||
|
|
|
@ -176,9 +176,9 @@ func decodeTextUnmarshaler(buf []byte, cursor, depth int64, unmarshaler encoding
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *interfaceDecoder) decodeStreamEmptyInterface(s *Stream, depth int64, p unsafe.Pointer) error {
|
func (d *interfaceDecoder) decodeStreamEmptyInterface(s *Stream, depth int64, p unsafe.Pointer) error {
|
||||||
s.skipWhiteSpace()
|
c := s.skipWhiteSpace()
|
||||||
for {
|
for {
|
||||||
switch s.char() {
|
switch c {
|
||||||
case '{':
|
case '{':
|
||||||
var v map[string]interface{}
|
var v map[string]interface{}
|
||||||
ptr := unsafe.Pointer(&v)
|
ptr := unsafe.Pointer(&v)
|
||||||
|
@ -239,6 +239,7 @@ func (d *interfaceDecoder) decodeStreamEmptyInterface(s *Stream, depth int64, p
|
||||||
return nil
|
return nil
|
||||||
case nul:
|
case nul:
|
||||||
if s.read() {
|
if s.read() {
|
||||||
|
c = s.char()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,8 +266,7 @@ func (d *interfaceDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer
|
||||||
if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
|
if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
|
||||||
return decodeStreamTextUnmarshaler(s, depth, u, p)
|
return decodeStreamTextUnmarshaler(s, depth, u, p)
|
||||||
}
|
}
|
||||||
s.skipWhiteSpace()
|
if s.skipWhiteSpace() == 'n' {
|
||||||
if s.char() == 'n' {
|
|
||||||
if err := nullBytes(s); err != nil {
|
if err := nullBytes(s); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -285,8 +285,7 @@ func (d *interfaceDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer
|
||||||
if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr {
|
if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr {
|
||||||
return d.decodeStreamEmptyInterface(s, depth, p)
|
return d.decodeStreamEmptyInterface(s, depth, p)
|
||||||
}
|
}
|
||||||
s.skipWhiteSpace()
|
if s.skipWhiteSpace() == 'n' {
|
||||||
if s.char() == 'n' {
|
|
||||||
if err := nullBytes(s); err != nil {
|
if err := nullBytes(s); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,7 @@ func (d *mapDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) erro
|
||||||
return errors.ErrExceededMaxDepth(s.char(), s.cursor)
|
return errors.ErrExceededMaxDepth(s.char(), s.cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.skipWhiteSpace()
|
switch s.skipWhiteSpace() {
|
||||||
switch s.char() {
|
|
||||||
case 'n':
|
case 'n':
|
||||||
if err := nullBytes(s); err != nil {
|
if err := nullBytes(s); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -54,7 +53,6 @@ func (d *mapDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) erro
|
||||||
default:
|
default:
|
||||||
return errors.ErrExpected("{ character for map value", s.totalOffset())
|
return errors.ErrExpected("{ character for map value", s.totalOffset())
|
||||||
}
|
}
|
||||||
s.skipWhiteSpace()
|
|
||||||
mapValue := *(*unsafe.Pointer)(p)
|
mapValue := *(*unsafe.Pointer)(p)
|
||||||
if mapValue == nil {
|
if mapValue == nil {
|
||||||
mapValue = makemap(d.mapType, 0)
|
mapValue = makemap(d.mapType, 0)
|
||||||
|
|
|
@ -35,8 +35,7 @@ func (d *ptrDecoder) contentDecoder() Decoder {
|
||||||
func unsafe_New(*runtime.Type) unsafe.Pointer
|
func unsafe_New(*runtime.Type) unsafe.Pointer
|
||||||
|
|
||||||
func (d *ptrDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
|
func (d *ptrDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
|
||||||
s.skipWhiteSpace()
|
if s.skipWhiteSpace() == nul {
|
||||||
if s.char() == nul {
|
|
||||||
s.read()
|
s.read()
|
||||||
}
|
}
|
||||||
if s.char() == 'n' {
|
if s.char() == 'n' {
|
||||||
|
|
|
@ -111,8 +111,7 @@ func (d *sliceDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) er
|
||||||
return nil
|
return nil
|
||||||
case '[':
|
case '[':
|
||||||
s.cursor++
|
s.cursor++
|
||||||
s.skipWhiteSpace()
|
if s.skipWhiteSpace() == ']' {
|
||||||
if s.char() == ']' {
|
|
||||||
dst := (*sliceHeader)(p)
|
dst := (*sliceHeader)(p)
|
||||||
if dst.data == nil {
|
if dst.data == nil {
|
||||||
dst.data = newArray(d.elemType, 0)
|
dst.data = newArray(d.elemType, 0)
|
||||||
|
|
|
@ -90,6 +90,10 @@ func (s *Stream) stat() ([]byte, int64, unsafe.Pointer) {
|
||||||
return s.buf, s.cursor, (*sliceHeader)(unsafe.Pointer(&s.buf)).data
|
return s.buf, s.cursor, (*sliceHeader)(unsafe.Pointer(&s.buf)).data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Stream) bufptr() unsafe.Pointer {
|
||||||
|
return (*sliceHeader)(unsafe.Pointer(&s.buf)).data
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Stream) statForRetry() ([]byte, int64, unsafe.Pointer) {
|
func (s *Stream) statForRetry() ([]byte, int64, unsafe.Pointer) {
|
||||||
s.cursor-- // for retry ( because caller progress cursor position in each loop )
|
s.cursor-- // for retry ( because caller progress cursor position in each loop )
|
||||||
return s.buf, s.cursor, (*sliceHeader)(unsafe.Pointer(&s.buf)).data
|
return s.buf, s.cursor, (*sliceHeader)(unsafe.Pointer(&s.buf)).data
|
||||||
|
@ -219,17 +223,21 @@ func (s *Stream) read() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Stream) skipWhiteSpace() {
|
func (s *Stream) skipWhiteSpace() byte {
|
||||||
|
p := s.bufptr()
|
||||||
LOOP:
|
LOOP:
|
||||||
switch s.char() {
|
c := char(p, s.cursor)
|
||||||
|
switch c {
|
||||||
case ' ', '\n', '\t', '\r':
|
case ' ', '\n', '\t', '\r':
|
||||||
s.cursor++
|
s.cursor++
|
||||||
goto LOOP
|
goto LOOP
|
||||||
case nul:
|
case nul:
|
||||||
if s.read() {
|
if s.read() {
|
||||||
|
p = s.bufptr()
|
||||||
goto LOOP
|
goto LOOP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Stream) skipObject(depth int64) error {
|
func (s *Stream) skipObject(depth int64) error {
|
||||||
|
|
|
@ -627,23 +627,20 @@ func (d *structDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) e
|
||||||
return errors.ErrExceededMaxDepth(s.char(), s.cursor)
|
return errors.ErrExceededMaxDepth(s.char(), s.cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.skipWhiteSpace()
|
c := s.skipWhiteSpace()
|
||||||
switch s.char() {
|
switch c {
|
||||||
case 'n':
|
case 'n':
|
||||||
if err := nullBytes(s); err != nil {
|
if err := nullBytes(s); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case nul:
|
|
||||||
s.read()
|
|
||||||
default:
|
default:
|
||||||
if s.char() != '{' {
|
if s.char() != '{' {
|
||||||
return errors.ErrNotAtBeginningOfValue(s.totalOffset())
|
return errors.ErrNotAtBeginningOfValue(s.totalOffset())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.cursor++
|
s.cursor++
|
||||||
s.skipWhiteSpace()
|
if s.skipWhiteSpace() == '}' {
|
||||||
if s.char() == '}' {
|
|
||||||
s.cursor++
|
s.cursor++
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -653,16 +650,10 @@ func (d *structDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) e
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.skipWhiteSpace()
|
if s.skipWhiteSpace() != ':' {
|
||||||
if s.char() != ':' {
|
|
||||||
return errors.ErrExpected("colon after object key", s.totalOffset())
|
return errors.ErrExpected("colon after object key", s.totalOffset())
|
||||||
}
|
}
|
||||||
s.cursor++
|
s.cursor++
|
||||||
if s.char() == nul {
|
|
||||||
if !s.read() {
|
|
||||||
return errors.ErrExpected("object value after colon", s.totalOffset())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if field != nil {
|
if field != nil {
|
||||||
if field.err != nil {
|
if field.err != nil {
|
||||||
return field.err
|
return field.err
|
||||||
|
@ -677,8 +668,7 @@ func (d *structDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) e
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.skipWhiteSpace()
|
c := s.skipWhiteSpace()
|
||||||
c := s.char()
|
|
||||||
if c == '}' {
|
if c == '}' {
|
||||||
s.cursor++
|
s.cursor++
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue