17
17
package rtl
18
18
19
19
import (
20
+ "encoding"
21
+ "errors"
20
22
"fmt"
21
23
"reflect"
22
24
)
23
25
24
26
type headerValueReader func (th TypeHeader , length int , vr ValueReader , value reflect.Value , nesting int ) error
25
27
26
28
var (
27
- _priorStructReaders = map [reflect.Type ]headerValueReader {
28
- typeOfBigInt : bigIntReader0 ,
29
- typeOfBigRat : bigRatReader0 ,
30
- typeOfBigFloat : bigFloatReader0 ,
29
+ _priorStructReaders = map [reflect.Type ]map [TypeHeader ]typeReaderFunc {
30
+ typeOfBigInt : bigIntReaders ,
31
+ typeOfBigRat : bigRatReaders ,
32
+ typeOfBigFloat : bigFloatReaders ,
33
+ typeOfTime : binaryUnmarshalerReaders ,
34
+ }
35
+
36
+ binaryUnmarshalerReaders = map [TypeHeader ]typeReaderFunc {
37
+ THSingleByte : func (length int , vr ValueReader , value reflect.Value , nesting int ) error {
38
+ return setToBinaryUnmarshaler (value , []byte {byte (length )})
39
+ },
40
+ THZeroValue : func (length int , vr ValueReader , value reflect.Value , nesting int ) error {
41
+ value .Set (reflect .Zero (value .Type ()))
42
+ return nil
43
+ },
44
+ THStringSingle : func (length int , vr ValueReader , value reflect.Value , nesting int ) error {
45
+ buf , err := vr .ReadBytes (length , nil )
46
+ if err != nil {
47
+ return err
48
+ }
49
+ return setToBinaryUnmarshaler (value , buf )
50
+ },
51
+ THStringMulti : func (length int , vr ValueReader , value reflect.Value , nesting int ) error {
52
+ l , err := vr .ReadMultiLength (length )
53
+ if err != nil {
54
+ return err
55
+ }
56
+ buf , err := vr .ReadBytes (int (l ), nil )
57
+ if err != nil {
58
+ return err
59
+ }
60
+ return setToBinaryUnmarshaler (value , buf )
61
+ },
31
62
}
32
63
)
33
64
34
65
func checkPriorStructsReader (th TypeHeader , length int , vr ValueReader , value reflect.Value , nesting int ) (matched bool , err error ) {
35
66
typ := value .Type ()
36
67
for _ , prior := range _priorStructOrder {
37
68
if typ .AssignableTo (prior ) || typ .AssignableTo (reflect .PtrTo (prior )) {
38
- fn , exist := _priorStructReaders [prior ]
69
+ readers , exist := _priorStructReaders [prior ]
39
70
if exist {
40
- err = fn (th , length , vr , value , nesting )
71
+ fn := getFunc (typ , readers , th )
72
+ if typ .AssignableTo (prior ) {
73
+ err = fn (length , vr , value .Addr (), nesting )
74
+ } else {
75
+ err = fn (length , vr , value , nesting )
76
+ }
41
77
return true , err
42
78
}
43
79
}
@@ -62,36 +98,48 @@ func bigIntReader0(th TypeHeader, length int, vr ValueReader, value reflect.Valu
62
98
return fmt .Errorf ("rtl: should be big.Int or *big.Int, but %s" , typ .Name ())
63
99
}
64
100
65
- func bigRatReader0 (th TypeHeader , length int , vr ValueReader , value reflect.Value , nesting int ) error {
66
- typ := value .Type ()
67
-
68
- // big.Rat
69
- if typ .AssignableTo (typeOfBigRat ) {
70
- f := getFunc (typ , bigRatReaders , th )
71
- return f (length , vr , value .Addr (), nesting )
72
- }
73
- // *big.Rat
74
- if typ .AssignableTo (reflect .PtrTo (typeOfBigRat )) {
75
- f := getFunc (typ , bigRatReaders , th )
76
- return f (length , vr , value , nesting )
77
- }
78
-
79
- return fmt .Errorf ("rtl: should be big.Rat or *big.Rat, but %s" , typ .Name ())
80
- }
81
-
82
- func bigFloatReader0 (th TypeHeader , length int , vr ValueReader , value reflect.Value , nesting int ) error {
83
- typ := value .Type ()
101
+ // func bigRatReader0(th TypeHeader, length int, vr ValueReader, value reflect.Value, nesting int) error {
102
+ // typ := value.Type()
103
+ //
104
+ // // big.Rat
105
+ // if typ.AssignableTo(typeOfBigRat) {
106
+ // f := getFunc(typ, bigRatReaders, th)
107
+ // return f(length, vr, value.Addr(), nesting)
108
+ // }
109
+ // // *big.Rat
110
+ // if typ.AssignableTo(reflect.PtrTo(typeOfBigRat)) {
111
+ // f := getFunc(typ, bigRatReaders, th)
112
+ // return f(length, vr, value, nesting)
113
+ // }
114
+ //
115
+ // return fmt.Errorf("rtl: should be big.Rat or *big.Rat, but %s", typ.Name())
116
+ // }
117
+ //
118
+ // func bigFloatReader0(th TypeHeader, length int, vr ValueReader, value reflect.Value, nesting int) error {
119
+ // typ := value.Type()
120
+ //
121
+ // // big.Float
122
+ // if typ.AssignableTo(typeOfBigFloat) {
123
+ // f := getFunc(typ, bigFloatReaders, th)
124
+ // return f(length, vr, value.Addr(), nesting)
125
+ // }
126
+ // // *big.Float
127
+ // if typ.AssignableTo(reflect.PtrTo(typeOfBigFloat)) {
128
+ // f := getFunc(typ, bigFloatReaders, th)
129
+ // return f(length, vr, value, nesting)
130
+ // }
131
+ //
132
+ // return fmt.Errorf("rtl: should be big.Float or *big.Float, but %s", typ.Name())
133
+ // }
84
134
85
- // big.Float
86
- if typ . AssignableTo ( typeOfBigFloat ) {
87
- f := getFunc ( typ , bigFloatReaders , th )
88
- return f ( length , vr , value . Addr (), nesting )
135
+ // value must be a pointer of a type, and implemented encoding.BinaryUnmarshaler
136
+ func setToBinaryUnmarshaler ( value reflect. Value , bs [] byte ) error {
137
+ if value . Kind () != reflect . Pointer {
138
+ return errors . New ( "rtl: BinaryUnmarshaler need a pointer" )
89
139
}
90
- // *big.Float
91
- if typ .AssignableTo (reflect .PtrTo (typeOfBigFloat )) {
92
- f := getFunc (typ , bigFloatReaders , th )
93
- return f (length , vr , value , nesting )
140
+ if value .IsNil () {
141
+ value .Set (reflect .New (value .Type ().Elem ()))
94
142
}
95
-
96
- return fmt . Errorf ( "rtl: should be big.Float or *big.Float, but %s" , typ . Name () )
143
+ bu := value . Interface ().(encoding. BinaryUnmarshaler )
144
+ return bu . UnmarshalBinary ( bs )
97
145
}
0 commit comments