188 lines
3.7 KiB
Go
188 lines
3.7 KiB
Go
/*
|
|
Copyright (c) 2014-2024 VMware, Inc. All Rights Reserved.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package esx
|
|
|
|
import (
|
|
"io"
|
|
|
|
"github.com/vmware/govmomi/vim25/xml"
|
|
)
|
|
|
|
type Values map[string][]string
|
|
|
|
type Response struct {
|
|
Info *CommandInfoMethod `json:"info"`
|
|
Values []Values `json:"values"`
|
|
String string `json:"string"`
|
|
Kind string `json:"-"`
|
|
}
|
|
|
|
func (v Values) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
|
for {
|
|
t, err := d.Token()
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
|
|
if s, ok := t.(xml.StartElement); ok {
|
|
t, err = d.Token()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
key := s.Name.Local
|
|
var val string
|
|
if c, ok := t.(xml.CharData); ok {
|
|
val = string(c)
|
|
}
|
|
v[key] = append(v[key], val)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s Values) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
tokens := []xml.Token{start}
|
|
|
|
for key, val := range s {
|
|
field := xml.StartElement{Name: xml.Name{Local: key}}
|
|
for _, v := range val {
|
|
tokens = append(tokens, field, xml.CharData(v), field.End())
|
|
}
|
|
}
|
|
|
|
tokens = append(tokens, start.End())
|
|
|
|
for _, t := range tokens {
|
|
err := e.EncodeToken(t)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (v Values) Value(name string) string {
|
|
if val, ok := v[name]; ok {
|
|
if len(val) != 0 {
|
|
return val[0]
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (r *Response) Type(start xml.StartElement) string {
|
|
for _, a := range start.Attr {
|
|
if a.Name.Local == "type" {
|
|
return a.Value
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (r *Response) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
|
stype := r.Type(start)
|
|
|
|
if stype != "ArrayOfDataObject" {
|
|
switch stype {
|
|
case "xsd:string", "xsd:boolean", "xsd:long":
|
|
return d.DecodeElement(&r.String, &start)
|
|
}
|
|
v := Values{}
|
|
if err := d.DecodeElement(&v, &start); err != nil {
|
|
return err
|
|
}
|
|
r.Values = append(r.Values, v)
|
|
return nil
|
|
}
|
|
|
|
for {
|
|
t, err := d.Token()
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
|
|
if s, ok := t.(xml.StartElement); ok {
|
|
if s.Name.Local == "DataObject" {
|
|
v := Values{}
|
|
if err := d.DecodeElement(&v, &s); err != nil {
|
|
return err
|
|
}
|
|
r.Values = append(r.Values, v)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (r *Response) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
|
|
kind := "ArrayOfDataObject"
|
|
native := r.String != ""
|
|
if native {
|
|
kind = "xsd:" + r.Kind
|
|
}
|
|
|
|
start := xml.StartElement{
|
|
Name: xml.Name{
|
|
Space: "urn:vim25",
|
|
Local: "obj",
|
|
},
|
|
Attr: []xml.Attr{
|
|
{
|
|
Name: xml.Name{Local: "xmlns:xsd"},
|
|
Value: "http://www.w3.org/2001/XMLSchema",
|
|
},
|
|
{
|
|
Name: xml.Name{Local: "xmlns:xsi"},
|
|
Value: "http://www.w3.org/2001/XMLSchema-instance",
|
|
},
|
|
{
|
|
Name: xml.Name{Local: "xsi:type"},
|
|
Value: kind,
|
|
},
|
|
},
|
|
}
|
|
|
|
if err := e.EncodeToken(start); err != nil {
|
|
return err
|
|
}
|
|
|
|
var err error
|
|
if native {
|
|
err = e.EncodeToken(xml.CharData(r.String))
|
|
} else {
|
|
obj := xml.StartElement{
|
|
Name: xml.Name{Local: "DataObject"},
|
|
Attr: []xml.Attr{{
|
|
Name: xml.Name{Local: "xsi:type"},
|
|
Value: r.Kind,
|
|
}},
|
|
}
|
|
err = e.EncodeElement(r.Values, obj)
|
|
}
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return e.EncodeToken(start.End())
|
|
}
|