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++
s.skipWhiteSpace()
switch s.char() {
switch s.skipWhiteSpace() {
case ']':
for idx < d.alen {
*(*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 {
s.skipWhiteSpace()
c := s.skipWhiteSpace()
for {
switch s.char() {
switch c {
case 't':
if err := trueBytes(s); err != nil {
return err
@ -38,6 +38,7 @@ func (d *boolDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) err
return nil
case nul:
if s.read() {
c = s.char()
continue
}
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 {
s.skipWhiteSpace()
c := s.skipWhiteSpace()
for {
switch s.char() {
switch c {
case '{':
var v map[string]interface{}
ptr := unsafe.Pointer(&v)
@ -239,6 +239,7 @@ func (d *interfaceDecoder) decodeStreamEmptyInterface(s *Stream, depth int64, p
return nil
case nul:
if s.read() {
c = s.char()
continue
}
}
@ -265,8 +266,7 @@ func (d *interfaceDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer
if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
return decodeStreamTextUnmarshaler(s, depth, u, p)
}
s.skipWhiteSpace()
if s.char() == 'n' {
if s.skipWhiteSpace() == 'n' {
if err := nullBytes(s); err != nil {
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 {
return d.decodeStreamEmptyInterface(s, depth, p)
}
s.skipWhiteSpace()
if s.char() == 'n' {
if s.skipWhiteSpace() == 'n' {
if err := nullBytes(s); err != nil {
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)
}
s.skipWhiteSpace()
switch s.char() {
switch s.skipWhiteSpace() {
case 'n':
if err := nullBytes(s); err != nil {
return err
@ -54,7 +53,6 @@ func (d *mapDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) erro
default:
return errors.ErrExpected("{ character for map value", s.totalOffset())
}
s.skipWhiteSpace()
mapValue := *(*unsafe.Pointer)(p)
if mapValue == nil {
mapValue = makemap(d.mapType, 0)

View File

@ -35,8 +35,7 @@ func (d *ptrDecoder) contentDecoder() Decoder {
func unsafe_New(*runtime.Type) unsafe.Pointer
func (d *ptrDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
s.skipWhiteSpace()
if s.char() == nul {
if s.skipWhiteSpace() == nul {
s.read()
}
if s.char() == 'n' {

View File

@ -111,8 +111,7 @@ func (d *sliceDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) er
return nil
case '[':
s.cursor++
s.skipWhiteSpace()
if s.char() == ']' {
if s.skipWhiteSpace() == ']' {
dst := (*sliceHeader)(p)
if dst.data == nil {
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
}
func (s *Stream) bufptr() unsafe.Pointer {
return (*sliceHeader)(unsafe.Pointer(&s.buf)).data
}
func (s *Stream) statForRetry() ([]byte, int64, unsafe.Pointer) {
s.cursor-- // for retry ( because caller progress cursor position in each loop )
return s.buf, s.cursor, (*sliceHeader)(unsafe.Pointer(&s.buf)).data
@ -219,17 +223,21 @@ func (s *Stream) read() bool {
return true
}
func (s *Stream) skipWhiteSpace() {
func (s *Stream) skipWhiteSpace() byte {
p := s.bufptr()
LOOP:
switch s.char() {
c := char(p, s.cursor)
switch c {
case ' ', '\n', '\t', '\r':
s.cursor++
goto LOOP
case nul:
if s.read() {
p = s.bufptr()
goto LOOP
}
}
return c
}
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)
}
s.skipWhiteSpace()
switch s.char() {
c := s.skipWhiteSpace()
switch c {
case 'n':
if err := nullBytes(s); err != nil {
return err
}
return nil
case nul:
s.read()
default:
if s.char() != '{' {
return errors.ErrNotAtBeginningOfValue(s.totalOffset())
}
}
s.cursor++
s.skipWhiteSpace()
if s.char() == '}' {
if s.skipWhiteSpace() == '}' {
s.cursor++
return nil
}
@ -653,16 +650,10 @@ func (d *structDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) e
if err != nil {
return err
}
s.skipWhiteSpace()
if s.char() != ':' {
if s.skipWhiteSpace() != ':' {
return errors.ErrExpected("colon after object key", s.totalOffset())
}
s.cursor++
if s.char() == nul {
if !s.read() {
return errors.ErrExpected("object value after colon", s.totalOffset())
}
}
if field != nil {
if field.err != nil {
return field.err
@ -677,8 +668,7 @@ func (d *structDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) e
return err
}
}
s.skipWhiteSpace()
c := s.char()
c := s.skipWhiteSpace()
if c == '}' {
s.cursor++
return nil