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