82 lines
1.7 KiB
Go
82 lines
1.7 KiB
Go
|
package rundeck
|
||
|
|
||
|
import (
|
||
|
"encoding/xml"
|
||
|
"fmt"
|
||
|
"sort"
|
||
|
)
|
||
|
|
||
|
func marshalMapToXML(c *map[string]string, e *xml.Encoder, start xml.StartElement, entryName string, keyName string, valueName string) error {
|
||
|
if len(*c) == 0 {
|
||
|
return nil
|
||
|
}
|
||
|
e.EncodeToken(start)
|
||
|
|
||
|
// Sort the keys so we'll have a deterministic result.
|
||
|
keys := []string{}
|
||
|
for k, _ := range *c {
|
||
|
keys = append(keys, k)
|
||
|
}
|
||
|
sort.Strings(keys)
|
||
|
|
||
|
for _, k := range keys {
|
||
|
v := (*c)[k]
|
||
|
e.EncodeToken(xml.StartElement{
|
||
|
Name: xml.Name{Local: entryName},
|
||
|
Attr: []xml.Attr{
|
||
|
xml.Attr{
|
||
|
Name: xml.Name{Local: keyName},
|
||
|
Value: k,
|
||
|
},
|
||
|
xml.Attr{
|
||
|
Name: xml.Name{Local: valueName},
|
||
|
Value: v,
|
||
|
},
|
||
|
},
|
||
|
})
|
||
|
e.EncodeToken(xml.EndElement{xml.Name{Local: entryName}})
|
||
|
}
|
||
|
e.EncodeToken(xml.EndElement{start.Name})
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func unmarshalMapFromXML(c *map[string]string, d *xml.Decoder, start xml.StartElement, entryName string, keyName string, valueName string) error {
|
||
|
result := map[string]string{}
|
||
|
for {
|
||
|
token, err := d.Token()
|
||
|
if token == nil {
|
||
|
err = fmt.Errorf("EOF while decoding job command plugin config")
|
||
|
}
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
switch t := token.(type) {
|
||
|
default:
|
||
|
continue
|
||
|
case xml.StartElement:
|
||
|
if t.Name.Local != entryName {
|
||
|
return fmt.Errorf("unexpected element %s while looking for config entries", t.Name.Local)
|
||
|
}
|
||
|
var k string
|
||
|
var v string
|
||
|
for _, attr := range t.Attr {
|
||
|
if attr.Name.Local == keyName {
|
||
|
k = attr.Value
|
||
|
} else if attr.Name.Local == valueName {
|
||
|
v = attr.Value
|
||
|
}
|
||
|
}
|
||
|
if k == "" {
|
||
|
return fmt.Errorf("found config entry with empty key")
|
||
|
}
|
||
|
result[k] = v
|
||
|
case xml.EndElement:
|
||
|
if t.Name.Local == start.Name.Local {
|
||
|
*c = result
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|