Fix skipWhiteSpace for stream decoder

This commit is contained in:
Masaaki Goshima 2021-06-04 14:59:43 +09:00
parent a973797e61
commit e7b7118f4e
8 changed files with 27 additions and 34 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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