Source file src/pkg/encoding/xml/read.go
1
2
3
4
5 package xml
6
7 import (
8 "bytes"
9 "errors"
10 "reflect"
11 "strconv"
12 "strings"
13 "time"
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 func Unmarshal(data []byte, v interface{}) error {
114 return NewDecoder(bytes.NewBuffer(data)).Decode(v)
115 }
116
117
118
119 func (d *Decoder) Decode(v interface{}) error {
120 return d.DecodeElement(v, nil)
121 }
122
123
124
125
126
127 func (d *Decoder) DecodeElement(v interface{}, start *StartElement) error {
128 val := reflect.ValueOf(v)
129 if val.Kind() != reflect.Ptr {
130 return errors.New("non-pointer passed to Unmarshal")
131 }
132 return d.unmarshal(val.Elem(), start)
133 }
134
135
136 type UnmarshalError string
137
138 func (e UnmarshalError) Error() string { return string(e) }
139
140
141 func (p *Decoder) unmarshal(val reflect.Value, start *StartElement) error {
142
143 if start == nil {
144 for {
145 tok, err := p.Token()
146 if err != nil {
147 return err
148 }
149 if t, ok := tok.(StartElement); ok {
150 start = &t
151 break
152 }
153 }
154 }
155
156 if pv := val; pv.Kind() == reflect.Ptr {
157 if pv.IsNil() {
158 pv.Set(reflect.New(pv.Type().Elem()))
159 }
160 val = pv.Elem()
161 }
162
163 var (
164 data []byte
165 saveData reflect.Value
166 comment []byte
167 saveComment reflect.Value
168 saveXML reflect.Value
169 saveXMLIndex int
170 saveXMLData []byte
171 saveAny reflect.Value
172 sv reflect.Value
173 tinfo *typeInfo
174 err error
175 )
176
177 switch v := val; v.Kind() {
178 default:
179 return errors.New("unknown type " + v.Type().String())
180
181 case reflect.Interface:
182
183
184
185 return p.Skip()
186
187 case reflect.Slice:
188 typ := v.Type()
189 if typ.Elem().Kind() == reflect.Uint8 {
190
191 saveData = v
192 break
193 }
194
195
196
197 n := v.Len()
198 if n >= v.Cap() {
199 ncap := 2 * n
200 if ncap < 4 {
201 ncap = 4
202 }
203 new := reflect.MakeSlice(typ, n, ncap)
204 reflect.Copy(new, v)
205 v.Set(new)
206 }
207 v.SetLen(n + 1)
208
209
210 if err := p.unmarshal(v.Index(n), start); err != nil {
211 v.SetLen(n)
212 return err
213 }
214 return nil
215
216 case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.String:
217 saveData = v
218
219 case reflect.Struct:
220 typ := v.Type()
221 if typ == nameType {
222 v.Set(reflect.ValueOf(start.Name))
223 break
224 }
225 if typ == timeType {
226 saveData = v
227 break
228 }
229
230 sv = v
231 tinfo, err = getTypeInfo(typ)
232 if err != nil {
233 return err
234 }
235
236
237 if tinfo.xmlname != nil {
238 finfo := tinfo.xmlname
239 if finfo.name != "" && finfo.name != start.Name.Local {
240 return UnmarshalError("expected element type <" + finfo.name + "> but have <" + start.Name.Local + ">")
241 }
242 if finfo.xmlns != "" && finfo.xmlns != start.Name.Space {
243 e := "expected element <" + finfo.name + "> in name space " + finfo.xmlns + " but have "
244 if start.Name.Space == "" {
245 e += "no name space"
246 } else {
247 e += start.Name.Space
248 }
249 return UnmarshalError(e)
250 }
251 fv := finfo.value(sv)
252 if _, ok := fv.Interface().(Name); ok {
253 fv.Set(reflect.ValueOf(start.Name))
254 }
255 }
256
257
258
259 for i := range tinfo.fields {
260 finfo := &tinfo.fields[i]
261 switch finfo.flags & fMode {
262 case fAttr:
263 strv := finfo.value(sv)
264
265 for _, a := range start.Attr {
266 if a.Name.Local == finfo.name && (finfo.xmlns == "" || finfo.xmlns == a.Name.Space) {
267 copyValue(strv, []byte(a.Value))
268 break
269 }
270 }
271
272 case fCharData:
273 if !saveData.IsValid() {
274 saveData = finfo.value(sv)
275 }
276
277 case fComment:
278 if !saveComment.IsValid() {
279 saveComment = finfo.value(sv)
280 }
281
282 case fAny, fAny | fElement:
283 if !saveAny.IsValid() {
284 saveAny = finfo.value(sv)
285 }
286
287 case fInnerXml:
288 if !saveXML.IsValid() {
289 saveXML = finfo.value(sv)
290 if p.saved == nil {
291 saveXMLIndex = 0
292 p.saved = new(bytes.Buffer)
293 } else {
294 saveXMLIndex = p.savedOffset()
295 }
296 }
297 }
298 }
299 }
300
301
302
303 Loop:
304 for {
305 var savedOffset int
306 if saveXML.IsValid() {
307 savedOffset = p.savedOffset()
308 }
309 tok, err := p.Token()
310 if err != nil {
311 return err
312 }
313 switch t := tok.(type) {
314 case StartElement:
315 consumed := false
316 if sv.IsValid() {
317 consumed, err = p.unmarshalPath(tinfo, sv, nil, &t)
318 if err != nil {
319 return err
320 }
321 if !consumed && saveAny.IsValid() {
322 consumed = true
323 if err := p.unmarshal(saveAny, &t); err != nil {
324 return err
325 }
326 }
327 }
328 if !consumed {
329 if err := p.Skip(); err != nil {
330 return err
331 }
332 }
333
334 case EndElement:
335 if saveXML.IsValid() {
336 saveXMLData = p.saved.Bytes()[saveXMLIndex:savedOffset]
337 if saveXMLIndex == 0 {
338 p.saved = nil
339 }
340 }
341 break Loop
342
343 case CharData:
344 if saveData.IsValid() {
345 data = append(data, t...)
346 }
347
348 case Comment:
349 if saveComment.IsValid() {
350 comment = append(comment, t...)
351 }
352 }
353 }
354
355 if err := copyValue(saveData, data); err != nil {
356 return err
357 }
358
359 switch t := saveComment; t.Kind() {
360 case reflect.String:
361 t.SetString(string(comment))
362 case reflect.Slice:
363 t.Set(reflect.ValueOf(comment))
364 }
365
366 switch t := saveXML; t.Kind() {
367 case reflect.String:
368 t.SetString(string(saveXMLData))
369 case reflect.Slice:
370 t.Set(reflect.ValueOf(saveXMLData))
371 }
372
373 return nil
374 }
375
376 func copyValue(dst reflect.Value, src []byte) (err error) {
377 if dst.Kind() == reflect.Ptr {
378 if dst.IsNil() {
379 dst.Set(reflect.New(dst.Type().Elem()))
380 }
381 dst = dst.Elem()
382 }
383
384
385 switch dst.Kind() {
386 case reflect.Invalid:
387
388 default:
389 return errors.New("cannot happen: unknown type " + dst.Type().String())
390 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
391 itmp, err := strconv.ParseInt(string(src), 10, dst.Type().Bits())
392 if err != nil {
393 return err
394 }
395 dst.SetInt(itmp)
396 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
397 utmp, err := strconv.ParseUint(string(src), 10, dst.Type().Bits())
398 if err != nil {
399 return err
400 }
401 dst.SetUint(utmp)
402 case reflect.Float32, reflect.Float64:
403 ftmp, err := strconv.ParseFloat(string(src), dst.Type().Bits())
404 if err != nil {
405 return err
406 }
407 dst.SetFloat(ftmp)
408 case reflect.Bool:
409 value, err := strconv.ParseBool(strings.TrimSpace(string(src)))
410 if err != nil {
411 return err
412 }
413 dst.SetBool(value)
414 case reflect.String:
415 dst.SetString(string(src))
416 case reflect.Slice:
417 if len(src) == 0 {
418
419 src = []byte{}
420 }
421 dst.SetBytes(src)
422 case reflect.Struct:
423 if dst.Type() == timeType {
424 tv, err := time.Parse(time.RFC3339, string(src))
425 if err != nil {
426 return err
427 }
428 dst.Set(reflect.ValueOf(tv))
429 }
430 }
431 return nil
432 }
433
434
435
436
437
438
439 func (p *Decoder) unmarshalPath(tinfo *typeInfo, sv reflect.Value, parents []string, start *StartElement) (consumed bool, err error) {
440 recurse := false
441 Loop:
442 for i := range tinfo.fields {
443 finfo := &tinfo.fields[i]
444 if finfo.flags&fElement == 0 || len(finfo.parents) < len(parents) || finfo.xmlns != "" && finfo.xmlns != start.Name.Space {
445 continue
446 }
447 for j := range parents {
448 if parents[j] != finfo.parents[j] {
449 continue Loop
450 }
451 }
452 if len(finfo.parents) == len(parents) && finfo.name == start.Name.Local {
453
454 return true, p.unmarshal(finfo.value(sv), start)
455 }
456 if len(finfo.parents) > len(parents) && finfo.parents[len(parents)] == start.Name.Local {
457
458
459
460 recurse = true
461
462
463
464 parents = finfo.parents[:len(parents)+1]
465 break
466 }
467 }
468 if !recurse {
469
470 return false, nil
471 }
472
473
474
475 for {
476 var tok Token
477 tok, err = p.Token()
478 if err != nil {
479 return true, err
480 }
481 switch t := tok.(type) {
482 case StartElement:
483 consumed2, err := p.unmarshalPath(tinfo, sv, parents, &t)
484 if err != nil {
485 return true, err
486 }
487 if !consumed2 {
488 if err := p.Skip(); err != nil {
489 return true, err
490 }
491 }
492 case EndElement:
493 return true, nil
494 }
495 }
496 }
497
498
499
500
501
502
503
504 func (d *Decoder) Skip() error {
505 for {
506 tok, err := d.Token()
507 if err != nil {
508 return err
509 }
510 switch tok.(type) {
511 case StartElement:
512 if err := d.Skip(); err != nil {
513 return err
514 }
515 case EndElement:
516 return nil
517 }
518 }
519 }
View as plain text