@@ -2,7 +2,6 @@ package xmlrpc
2
2
3
3
import (
4
4
"encoding/base64"
5
- "encoding/xml"
6
5
"fmt"
7
6
"reflect"
8
7
"strconv"
@@ -14,81 +13,59 @@ const (
14
13
errFormatInvalidFieldType = "invalid field type: expected '%s', got '%s'"
15
14
)
16
15
17
- type respWrapper struct {
18
- Params []respParam `xml:"params>param"`
19
- Fault * respFault `xml:"fault,omitempty"`
16
+ // Decoder implementations provide mechanisms for parsing of XML-RPC responses to native data-types.
17
+ type Decoder interface {
18
+ DecodeRaw (body []byte , v interface {}) error
19
+ Decode (response * Response , v interface {}) error
20
+ DecodeFault (response * Response ) * Fault
20
21
}
21
22
22
- type respParam struct {
23
- Value respValue `xml:"value"`
24
- }
25
-
26
- type respValue struct {
27
- Array []* respValue `xml:"array>data>value"`
28
- Struct []* respStructMember `xml:"struct>member"`
29
- String string `xml:"string"`
30
- Int string `xml:"int"`
31
- Int4 string `xml:"i4"`
32
- Double string `xml:"double"`
33
- Boolean string `xml:"boolean"`
34
- DateTime string `xml:"dateTime.iso8601"`
35
- Base64 string `xml:"base64"`
36
-
37
- Raw string `xml:",innerxml"` // the value can be default string
38
- }
39
-
40
- type respStructMember struct {
41
- Name string `xml:"name"`
42
- Value respValue `xml:"value"`
43
- }
44
-
45
- type respFault struct {
46
- Value respValue `xml:"value"`
47
- }
23
+ // StdDecoder is the default implementation of the Decoder interface.
24
+ type StdDecoder struct {}
48
25
49
- func DecodeResponse (body []byte , v interface {}) error {
26
+ func ( d * StdDecoder ) DecodeRaw (body []byte , v interface {}) error {
50
27
51
- wrapper , err := toRespWrapper (body )
28
+ response , err := NewResponse (body )
52
29
if err != nil {
53
30
return err
54
31
}
55
32
56
- if wrapper .Fault != nil {
57
- return decodeFault (wrapper .Fault )
58
- }
59
-
60
- return decodeWrapper (wrapper , v )
61
- }
62
-
63
- func toRespWrapper (body []byte ) (* respWrapper , error ) {
64
- wrapper := & respWrapper {}
65
- if err := xml .Unmarshal (body , wrapper ); err != nil {
66
- return nil , err
33
+ if response .Fault != nil {
34
+ return d .decodeFault (response .Fault )
67
35
}
68
36
69
- return wrapper , nil
37
+ return d . Decode ( response , v )
70
38
}
71
39
72
- func decodeWrapper ( wrapper * respWrapper , v interface {}) error {
40
+ func ( d * StdDecoder ) Decode ( response * Response , v interface {}) error {
73
41
74
42
// Validate that v has same number of public fields as response params
75
- if err := fieldsMustEqual (v , len (wrapper .Params )); err != nil {
43
+ if err := fieldsMustEqual (v , len (response .Params )); err != nil {
76
44
return err
77
45
}
78
46
79
47
vElem := reflect .Indirect (reflect .ValueOf (v ))
80
- for i , param := range wrapper .Params {
48
+ for i , param := range response .Params {
81
49
field := vElem .Field (i )
82
50
83
- if err := decodeValue (& param .Value , & field ); err != nil {
51
+ if err := d . decodeValue (& param .Value , & field ); err != nil {
84
52
return err
85
53
}
86
54
}
87
55
88
56
return nil
89
57
}
90
58
91
- func decodeFault (fault * respFault ) * Fault {
59
+ func (d * StdDecoder ) DecodeFault (response * Response ) * Fault {
60
+
61
+ if response .Fault == nil {
62
+ return nil
63
+ }
64
+
65
+ return d .decodeFault (response .Fault )
66
+ }
67
+
68
+ func (d * StdDecoder ) decodeFault (fault * ResponseFault ) * Fault {
92
69
93
70
f := & Fault {}
94
71
for _ , m := range fault .Value .Struct {
@@ -107,7 +84,7 @@ func decodeFault(fault *respFault) *Fault {
107
84
return f
108
85
}
109
86
110
- func decodeValue (value * respValue , field * reflect.Value ) error {
87
+ func ( d * StdDecoder ) decodeValue (value * ResponseValue , field * reflect.Value ) error {
111
88
112
89
var val interface {}
113
90
var err error
@@ -124,16 +101,16 @@ func decodeValue(value *respValue, field *reflect.Value) error {
124
101
val , err = strconv .ParseFloat (value .Double , 64 )
125
102
126
103
case value .Boolean != "" :
127
- val , err = decodeBoolean (value .Boolean )
104
+ val , err = d . decodeBoolean (value .Boolean )
128
105
129
106
case value .String != "" :
130
107
val , err = value .String , nil
131
108
132
109
case value .Base64 != "" :
133
- val , err = decodeBase64 (value .Base64 )
110
+ val , err = d . decodeBase64 (value .Base64 )
134
111
135
112
case value .DateTime != "" :
136
- val , err = decodeDateTime (value .DateTime )
113
+ val , err = d . decodeDateTime (value .DateTime )
137
114
138
115
// Array decoding
139
116
case len (value .Array ) > 0 :
@@ -145,7 +122,7 @@ func decodeValue(value *respValue, field *reflect.Value) error {
145
122
slice := reflect .MakeSlice (reflect .TypeOf (field .Interface ()), len (value .Array ), len (value .Array ))
146
123
for i , v := range value .Array {
147
124
item := slice .Index (i )
148
- if err := decodeValue (v , & item ); err != nil {
125
+ if err := d . decodeValue (v , & item ); err != nil {
149
126
return fmt .Errorf ("failed decoding array item at index %d: %w" , i , err )
150
127
}
151
128
}
@@ -168,7 +145,7 @@ func decodeValue(value *respValue, field *reflect.Value) error {
168
145
return fmt .Errorf ("cannot find field '%s' on struct" , fName )
169
146
}
170
147
171
- if err := decodeValue (& m .Value , & f ); err != nil {
148
+ if err := d . decodeValue (& m .Value , & f ); err != nil {
172
149
return fmt .Errorf ("failed decoding struct member '%s': %w" , m .Name , err )
173
150
}
174
151
}
@@ -188,7 +165,7 @@ func decodeValue(value *respValue, field *reflect.Value) error {
188
165
return nil
189
166
}
190
167
191
- func decodeBoolean (value string ) (bool , error ) {
168
+ func ( d * StdDecoder ) decodeBoolean (value string ) (bool , error ) {
192
169
193
170
switch value {
194
171
case "1" , "true" , "TRUE" , "True" :
@@ -199,12 +176,12 @@ func decodeBoolean(value string) (bool, error) {
199
176
return false , fmt .Errorf ("unrecognized value '%s' for boolean" , value )
200
177
}
201
178
202
- func decodeBase64 (value string ) ([]byte , error ) {
179
+ func ( d * StdDecoder ) decodeBase64 (value string ) ([]byte , error ) {
203
180
204
181
return base64 .StdEncoding .DecodeString (value )
205
182
}
206
183
207
- func decodeDateTime (value string ) (time.Time , error ) {
184
+ func ( d * StdDecoder ) decodeDateTime (value string ) (time.Time , error ) {
208
185
209
186
return time .Parse (time .RFC3339 , value )
210
187
}
0 commit comments