You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			203 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Go
		
	
			
		
		
	
	
			203 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Go
		
	
package stt
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"fmt"
 | 
						|
	"github.com/modern-go/reflect2"
 | 
						|
	"io"
 | 
						|
	"strings"
 | 
						|
	"unsafe"
 | 
						|
)
 | 
						|
 | 
						|
func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder {
 | 
						|
	bindings := map[string]*Binding{}
 | 
						|
	structDescriptor := describeStruct(ctx, typ)
 | 
						|
	for _, binding := range structDescriptor.Fields {
 | 
						|
		for _, fromName := range binding.FromNames {
 | 
						|
			old := bindings[fromName]
 | 
						|
			if old == nil {
 | 
						|
				bindings[fromName] = binding
 | 
						|
				continue
 | 
						|
			}
 | 
						|
			ignoreOld, ignoreNew := resolveConflictBinding(ctx.frozenConfig, old, binding)
 | 
						|
			if ignoreOld {
 | 
						|
				delete(bindings, fromName)
 | 
						|
			}
 | 
						|
			if !ignoreNew {
 | 
						|
				bindings[fromName] = binding
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	fields := map[string]*structFieldDecoder{}
 | 
						|
	for k, binding := range bindings {
 | 
						|
		fields[k] = binding.Decoder.(*structFieldDecoder)
 | 
						|
	}
 | 
						|
	return createStructDecoder(ctx, typ, fields)
 | 
						|
}
 | 
						|
 | 
						|
func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structFieldDecoder) ValDecoder {
 | 
						|
	switch len(fields) {
 | 
						|
	case 0:
 | 
						|
		return &skipObjectDecoder{typ}
 | 
						|
	}
 | 
						|
	return &generalStructDecoder{typ, fields}
 | 
						|
}
 | 
						|
 | 
						|
type generalStructDecoder struct {
 | 
						|
	typ    reflect2.Type
 | 
						|
	fields map[string]*structFieldDecoder
 | 
						|
}
 | 
						|
 | 
						|
func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 | 
						|
	if !iter.incrementDepth() {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	var splitBytes = encryptBytes([]byte{'/'}, iter.depth)
 | 
						|
	cc := splitBytes
 | 
						|
	var c byte = '/'
 | 
						|
	for {
 | 
						|
		if iter.head >= iter.tail {
 | 
						|
			break
 | 
						|
		}
 | 
						|
		if iter.depth > 1 {
 | 
						|
			if bytes.Equal(cc, splitBytes) {
 | 
						|
				nc := iter.nextToken()
 | 
						|
				iter.unreadByte()
 | 
						|
				if nc != '/' && nc != '@' {
 | 
						|
					decoder.decodeOneField(ptr, iter)
 | 
						|
					cc = cc[:0]
 | 
						|
					for i, sbLen := 0, len(splitBytes); i < sbLen; i++ {
 | 
						|
						cc = append(cc, iter.nextToken())
 | 
						|
					}
 | 
						|
				} else {
 | 
						|
					break
 | 
						|
				}
 | 
						|
			} else {
 | 
						|
				cc = cc[:1]
 | 
						|
				for i, sbLen := 0, len(splitBytes); i < sbLen; i++ {
 | 
						|
					cc = append(cc, iter.nextToken())
 | 
						|
				}
 | 
						|
				continue
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			if c == '/' {
 | 
						|
				nc := iter.nextToken()
 | 
						|
				iter.unreadByte()
 | 
						|
				if nc != '/' {
 | 
						|
					decoder.decodeOneField(ptr, iter)
 | 
						|
					c = iter.nextToken()
 | 
						|
				} else {
 | 
						|
					break
 | 
						|
				}
 | 
						|
			} else {
 | 
						|
				c = iter.nextToken()
 | 
						|
				continue
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if iter.Error != nil && iter.Error != io.EOF && len(decoder.typ.Type1().Name()) != 0 {
 | 
						|
		iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
 | 
						|
	}
 | 
						|
	if c != '/' {
 | 
						|
		iter.ReportError("struct Decode", `expect /, but found `+string([]byte{c}))
 | 
						|
	}
 | 
						|
	iter.decrementDepth()
 | 
						|
}
 | 
						|
 | 
						|
func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *Iterator) {
 | 
						|
	var field string
 | 
						|
	var fieldDecoder *structFieldDecoder
 | 
						|
 | 
						|
	field = iter.ReadFieldName()
 | 
						|
	fieldDecoder = decoder.fields[field]
 | 
						|
	if fieldDecoder == nil && !iter.cfg.caseSensitive {
 | 
						|
		fieldDecoder = decoder.fields[strings.ToLower(field)]
 | 
						|
	}
 | 
						|
 | 
						|
	if fieldDecoder == nil {
 | 
						|
		c := iter.nextToken()
 | 
						|
		if c != '@' {
 | 
						|
			iter.ReportError("ReadObject", "expect @ after object field, but found "+string([]byte{c}))
 | 
						|
		}
 | 
						|
		iter.skipBytes('=')
 | 
						|
		iter.Skip()
 | 
						|
		return
 | 
						|
	}
 | 
						|
	c := iter.nextToken()
 | 
						|
	if c != '@' {
 | 
						|
		iter.ReportError("ReadObject", "expect @ after object field, but found "+string([]byte{c}))
 | 
						|
	}
 | 
						|
	iter.unreadByte()
 | 
						|
	if iter.depth > 1 {
 | 
						|
		iter.skipBytes(encryptBytes([]byte("@="), iter.depth)...)
 | 
						|
	} else {
 | 
						|
		iter.skipBytes('@', '=')
 | 
						|
	}
 | 
						|
	fieldDecoder.Decode(ptr, iter)
 | 
						|
}
 | 
						|
 | 
						|
type skipObjectDecoder struct {
 | 
						|
	typ reflect2.Type
 | 
						|
}
 | 
						|
 | 
						|
func (decoder *skipObjectDecoder) Decode(_ unsafe.Pointer, iter *Iterator) {
 | 
						|
	valueType := iter.WhatIsNext()
 | 
						|
	if valueType != NilValue {
 | 
						|
		iter.ReportError("skipObjectDecoder", "expect object or null")
 | 
						|
		return
 | 
						|
	}
 | 
						|
	iter.Skip()
 | 
						|
}
 | 
						|
 | 
						|
type structFieldDecoder struct {
 | 
						|
	field        reflect2.StructField
 | 
						|
	fieldDecoder ValDecoder
 | 
						|
}
 | 
						|
 | 
						|
func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 | 
						|
	fieldPtr := decoder.field.UnsafeGet(ptr)
 | 
						|
	decoder.fieldDecoder.Decode(fieldPtr, iter)
 | 
						|
	if iter.Error != nil && iter.Error != io.EOF {
 | 
						|
		iter.Error = fmt.Errorf("%s: %s", decoder.field.Name(), iter.Error.Error())
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
type stringModeStringDecoder struct {
 | 
						|
	elemDecoder ValDecoder
 | 
						|
	cfg         *frozenConfig
 | 
						|
}
 | 
						|
 | 
						|
func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 | 
						|
	decoder.elemDecoder.Decode(ptr, iter)
 | 
						|
	str := *((*string)(ptr))
 | 
						|
	tempIter := decoder.cfg.BorrowIterator([]byte(str))
 | 
						|
	defer decoder.cfg.ReturnIterator(tempIter)
 | 
						|
	*((*string)(ptr)) = tempIter.ReadString()
 | 
						|
}
 | 
						|
 | 
						|
type stringModeNumberDecoder struct {
 | 
						|
	elemDecoder ValDecoder
 | 
						|
}
 | 
						|
 | 
						|
func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 | 
						|
	if iter.WhatIsNext() == NilValue {
 | 
						|
		decoder.elemDecoder.Decode(ptr, iter)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	c := iter.nextToken()
 | 
						|
	if c != '"' {
 | 
						|
		iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c}))
 | 
						|
		return
 | 
						|
	}
 | 
						|
	decoder.elemDecoder.Decode(ptr, iter)
 | 
						|
	if iter.Error != nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	c = iter.readByte()
 | 
						|
	if c != '"' {
 | 
						|
		iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c}))
 | 
						|
		return
 | 
						|
	}
 | 
						|
}
 |