-
Notifications
You must be signed in to change notification settings - Fork 0
/
handler_struct.go
76 lines (65 loc) · 1.96 KB
/
handler_struct.go
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package jsonpack
import (
"unsafe"
ibuf "github.com/arloliu/jsonpack/buffer"
"github.com/modern-go/reflect2"
"github.com/pkg/errors"
)
type structOp struct{}
func (p *structOp) decodeStruct(buf *ibuf.Buffer, opNode *structOperation, ptr unsafe.Pointer) error {
var err error
var fieldPtr unsafe.Pointer
for _, op := range opNode.children {
fieldPtr = op.field.UnsafeGet(ptr)
if op.isPtrType {
ptrType := (op.field.Type()).(*reflect2.UnsafePtrType)
elemType := ptrType.Elem()
// check if current pointer of field is null
if derefPtr(fieldPtr) == nil {
//pointer to null, need to allocate memory to hold the value
newPtr := elemType.UnsafeNew()
err = op.handler.decodeStruct(buf, op, newPtr)
if err != nil {
return err
}
// assign new allocated data back to current field pointer
assignPtr(fieldPtr, newPtr)
} else {
//reuse existing instance
err = op.handler.decodeStruct(buf, op, derefPtr(fieldPtr))
if err != nil {
return err
}
}
} else {
err = op.handler.decodeStruct(buf, op, fieldPtr)
if err != nil {
return err
}
}
}
return nil
}
func (p *structOp) encodeStruct(buf *ibuf.Buffer, opNode *structOperation, ptr unsafe.Pointer) error {
var err error
var fieldPtr unsafe.Pointer
for _, op := range opNode.children {
fieldPtr = op.field.UnsafeGet(ptr)
// dereference pointer
if op.isPtrType {
// logger.Debugf("encodeStruct: op is pointer type, field name: %v", op.field.Name())
fieldPtr = derefPtr(fieldPtr)
}
err = op.handler.encodeStruct(buf, op, fieldPtr)
if err != nil {
return err
}
}
return nil
}
func (p *structOp) encodeDynamic(buf *ibuf.Buffer, opNode *operation, data interface{}) error {
return errors.WithStack(&NotImplementedError{"structOp.encodeDynamic"})
}
func (p *structOp) decodeDynamic(buf *ibuf.Buffer, opNode *operation, v interface{}) (interface{}, error) {
return nil, errors.WithStack(&NotImplementedError{"structOp.decodeDynamic"})
}