structs.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package optdec
  2. import (
  3. "reflect"
  4. "unsafe"
  5. "github.com/bytedance/sonic/internal/decoder/consts"
  6. caching "github.com/bytedance/sonic/internal/optcaching"
  7. "github.com/bytedance/sonic/internal/resolver"
  8. )
  9. type fieldEntry struct {
  10. resolver.FieldMeta
  11. fieldDec decFunc
  12. }
  13. type structDecoder struct {
  14. fieldMap caching.FieldLookup
  15. fields []fieldEntry
  16. structName string
  17. typ reflect.Type
  18. }
  19. func (d *structDecoder) FromDom(vp unsafe.Pointer, node Node, ctx *context) error {
  20. if node.IsNull() {
  21. return nil
  22. }
  23. var gerr error
  24. obj, ok := node.AsObj()
  25. if !ok {
  26. return error_mismatch(node, ctx, d.typ)
  27. }
  28. next := obj.Children()
  29. for i := 0; i < obj.Len(); i++ {
  30. key, _ := NewNode(next).AsStrRef(ctx)
  31. val := NewNode(PtrOffset(next, 1))
  32. next = val.Next()
  33. // find field idx
  34. idx := d.fieldMap.Get(key, ctx.Options()&uint64(consts.OptionCaseSensitive) != 0)
  35. if idx == -1 {
  36. if Options(ctx.Options())&OptionDisableUnknown != 0 {
  37. return error_field(key)
  38. }
  39. continue
  40. }
  41. offset := d.fields[idx].Path[0].Size
  42. elem := unsafe.Pointer(uintptr(vp) + offset)
  43. err := d.fields[idx].fieldDec.FromDom(elem, val, ctx)
  44. // deal with mismatch type errors
  45. if gerr == nil && err != nil {
  46. // TODO: better error info
  47. gerr = err
  48. }
  49. }
  50. return gerr
  51. }