github.com/vmware/govmomi@v0.51.0/cli/esx/response.go (about) 1 // © Broadcom. All Rights Reserved. 2 // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 // SPDX-License-Identifier: Apache-2.0 4 5 package esx 6 7 import ( 8 "io" 9 10 "github.com/vmware/govmomi/vim25/xml" 11 ) 12 13 type Values map[string][]string 14 15 type Response struct { 16 Info *CommandInfoMethod `json:"info"` 17 Values []Values `json:"values"` 18 String string `json:"string"` 19 Kind string `json:"-"` 20 } 21 22 func (v Values) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 23 for { 24 t, err := d.Token() 25 if err != nil { 26 if err == io.EOF { 27 return nil 28 } 29 return err 30 } 31 32 if s, ok := t.(xml.StartElement); ok { 33 t, err = d.Token() 34 if err != nil { 35 return err 36 } 37 38 key := s.Name.Local 39 var val string 40 if c, ok := t.(xml.CharData); ok { 41 val = string(c) 42 } 43 v[key] = append(v[key], val) 44 } 45 } 46 } 47 48 func (s Values) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 49 tokens := []xml.Token{start} 50 51 for key, val := range s { 52 field := xml.StartElement{Name: xml.Name{Local: key}} 53 for _, v := range val { 54 tokens = append(tokens, field, xml.CharData(v), field.End()) 55 } 56 } 57 58 tokens = append(tokens, start.End()) 59 60 for _, t := range tokens { 61 err := e.EncodeToken(t) 62 if err != nil { 63 return err 64 } 65 } 66 67 return nil 68 } 69 70 func (v Values) Value(name string) string { 71 if val, ok := v[name]; ok { 72 if len(val) != 0 { 73 return val[0] 74 } 75 } 76 return "" 77 } 78 79 func (r *Response) Type(start xml.StartElement) string { 80 for _, a := range start.Attr { 81 if a.Name.Local == "type" { 82 return a.Value 83 } 84 } 85 return "" 86 } 87 88 func (r *Response) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 89 stype := r.Type(start) 90 91 if stype != "ArrayOfDataObject" { 92 switch stype { 93 case "xsd:string", "xsd:boolean", "xsd:long": 94 return d.DecodeElement(&r.String, &start) 95 } 96 v := Values{} 97 if err := d.DecodeElement(&v, &start); err != nil { 98 return err 99 } 100 r.Values = append(r.Values, v) 101 return nil 102 } 103 104 for { 105 t, err := d.Token() 106 if err != nil { 107 if err == io.EOF { 108 return nil 109 } 110 return err 111 } 112 113 if s, ok := t.(xml.StartElement); ok { 114 if s.Name.Local == "DataObject" { 115 v := Values{} 116 if err := d.DecodeElement(&v, &s); err != nil { 117 return err 118 } 119 r.Values = append(r.Values, v) 120 } 121 } 122 } 123 } 124 125 func (r *Response) MarshalXML(e *xml.Encoder, _ xml.StartElement) error { 126 kind := "ArrayOfDataObject" 127 native := r.String != "" 128 if native { 129 kind = "xsd:" + r.Kind 130 } 131 132 start := xml.StartElement{ 133 Name: xml.Name{ 134 Space: "urn:vim25", 135 Local: "obj", 136 }, 137 Attr: []xml.Attr{ 138 { 139 Name: xml.Name{Local: "xmlns:xsd"}, 140 Value: "http://www.w3.org/2001/XMLSchema", 141 }, 142 { 143 Name: xml.Name{Local: "xmlns:xsi"}, 144 Value: "http://www.w3.org/2001/XMLSchema-instance", 145 }, 146 { 147 Name: xml.Name{Local: "xsi:type"}, 148 Value: kind, 149 }, 150 }, 151 } 152 153 if err := e.EncodeToken(start); err != nil { 154 return err 155 } 156 157 var err error 158 if native { 159 err = e.EncodeToken(xml.CharData(r.String)) 160 } else { 161 obj := xml.StartElement{ 162 Name: xml.Name{Local: "DataObject"}, 163 Attr: []xml.Attr{{ 164 Name: xml.Name{Local: "xsi:type"}, 165 Value: r.Kind, 166 }}, 167 } 168 err = e.EncodeElement(r.Values, obj) 169 } 170 171 if err != nil { 172 return err 173 } 174 175 return e.EncodeToken(start.End()) 176 }