diff --git a/encode.go b/encode.go
index 78eb981..508b16c 100644
--- a/encode.go
+++ b/encode.go
@@ -51,6 +51,7 @@ func (e *Encoder) Encode(v interface{}) error {
}
enc := newXMLEncoder(e.w)
+ enc.indent = e.indent
enc.Indent("", e.indent)
return enc.generateDocument(pval)
}
diff --git a/encode_test.go b/encode_test.go
index 2210abf..7d99f55 100644
--- a/encode_test.go
+++ b/encode_test.go
@@ -79,39 +79,63 @@ var dictRef = `
var indentRef = `
+
+ Boolean
+
+ BooleanList
+
+
+
+
+ CFBundleInfoDictionaryVersion
+ 6.0
+ Strings
+
+ a
+ b
+
+ band-size
+ 8388608
+ bundle-backingstore-version
+ 1
+ diskimage-bundle-type
+ com.apple.diskimage.sparsebundle
+ size
+ 4398046511104
+ useless
- CFBundleInfoDictionaryVersion
- 6.0
- band-size
- 8388608
- bundle-backingstore-version
- 1
- diskimage-bundle-type
- com.apple.diskimage.sparsebundle
- size
- 4398046511104
- useless
-
- unused-string
- unused
-
+ unused-string
+ unused
+
`
var indentRefOmit = `
-
- CFBundleInfoDictionaryVersion
- 6.0
- bundle-backingstore-version
- 1
- diskimage-bundle-type
- com.apple.diskimage.sparsebundle
- size
- 4398046511104
-
+
+ Boolean
+
+ BooleanList
+
+
+
+
+ CFBundleInfoDictionaryVersion
+ 6.0
+ Strings
+
+ a
+ b
+
+ bundle-backingstore-version
+ 1
+ diskimage-bundle-type
+ com.apple.diskimage.sparsebundle
+ size
+ 4398046511104
+
`
@@ -180,11 +204,11 @@ func TestNewLineString(t *testing.T) {
var ok = `
-
- Content
- foo
+
+ Content
+ foo
bar
-
+
`
out := string(b)
@@ -203,6 +227,9 @@ func TestIndent(t *testing.T) {
DiskImageBundleType string `plist:"diskimage-bundle-type"`
Size uint64 `plist:"size"`
Unused testStruct `plist:"useless"`
+ Boolean bool
+ BooleanList []bool
+ Strings []string
}{
InfoDictionaryVersion: "6.0",
BandSize: 8388608,
@@ -210,6 +237,9 @@ func TestIndent(t *testing.T) {
DiskImageBundleType: "com.apple.diskimage.sparsebundle",
BackingStoreVersion: 1,
Unused: testStruct{UnusedString: "unused"},
+ Boolean: true,
+ BooleanList: []bool{true, false},
+ Strings: []string{"a", "b"},
}
b, err := MarshalIndent(sparseBundleHeader, " ")
if err != nil {
@@ -217,7 +247,7 @@ func TestIndent(t *testing.T) {
}
out := string(b)
if out != indentRef {
- t.Errorf("MarshalIndent(%v) = \n%v, \nwant\n %v", sparseBundleHeader, out, indentRef)
+ t.Errorf("MarshalIndent(%v) = \n%v, \nwant\n%v", sparseBundleHeader, out, indentRef)
}
}
@@ -230,6 +260,9 @@ func TestOmitNotEmpty(t *testing.T) {
DiskImageBundleType string `plist:"diskimage-bundle-type"`
Size uint64 `plist:"size"`
Unused testStruct `plist:"useless"`
+ Boolean bool
+ BooleanList []bool
+ Strings []string
}{
InfoDictionaryVersion: "6.0",
BandSize: 8388608,
@@ -237,6 +270,9 @@ func TestOmitNotEmpty(t *testing.T) {
DiskImageBundleType: "com.apple.diskimage.sparsebundle",
BackingStoreVersion: 1,
Unused: testStruct{UnusedString: "unused"},
+ Boolean: true,
+ BooleanList: []bool{true, false},
+ Strings: []string{"a", "b"},
}
b, err := MarshalIndent(sparseBundleHeader, " ")
if err != nil {
@@ -244,7 +280,7 @@ func TestOmitNotEmpty(t *testing.T) {
}
out := string(b)
if out != indentRef {
- t.Errorf("MarshalIndent(%v) = \n%v, \nwant\n %v", sparseBundleHeader, out, indentRef)
+ t.Errorf("MarshalIndent(%v) = \n%v, \nwant\n %v", sparseBundleHeader, out, indentRefOmit)
}
}
@@ -257,11 +293,17 @@ func TestOmitIsEmpty(t *testing.T) {
DiskImageBundleType string `plist:"diskimage-bundle-type"`
Size uint64 `plist:"size"`
Unused testStruct `plist:"useless,omitempty"`
+ Boolean bool
+ BooleanList []bool
+ Strings []string
}{
InfoDictionaryVersion: "6.0",
Size: 4 * 1048576 * 1024 * 1024,
DiskImageBundleType: "com.apple.diskimage.sparsebundle",
BackingStoreVersion: 1,
+ Boolean: true,
+ BooleanList: []bool{true, false},
+ Strings: []string{"a", "b"},
}
b, err := MarshalIndent(sparseBundleHeader, " ")
if err != nil {
diff --git a/xml_writer.go b/xml_writer.go
index 1058acd..199e7a8 100644
--- a/xml_writer.go
+++ b/xml_writer.go
@@ -11,52 +11,47 @@ import (
)
const xmlDOCTYPE = ``
+const plistStart = ``
+const plistEnd = ``
type xmlEncoder struct {
- writer io.Writer
+ indent string
+ indentCount int
+ err error
+ writer io.Writer
*xml.Encoder
}
+func (e *xmlEncoder) write(buf []byte) {
+ if e.err != nil {
+ return
+ }
+ _, e.err = e.writer.Write(buf)
+}
+
func newXMLEncoder(w io.Writer) *xmlEncoder {
- return &xmlEncoder{w, xml.NewEncoder(w)}
+ return &xmlEncoder{writer: w, Encoder: xml.NewEncoder(w)}
}
func (e *xmlEncoder) generateDocument(pval *plistValue) error {
- // xml version=1.0
- _, err := e.writer.Write([]byte(xml.Header))
- if err != nil {
- return err
- }
-
- //!DOCTYPE plist
- _, err = e.writer.Write([]byte(xmlDOCTYPE))
- if err != nil {
- return err
+ e.write([]byte(xml.Header))
+ e.write([]byte(xmlDOCTYPE))
+ e.write([]byte("\n"))
+ e.write([]byte(plistStart))
+ if e.indent != "" {
+ e.write([]byte("\n"))
}
- // newline after doctype
- // tag starts on new line
- _, err = e.writer.Write([]byte("\n"))
- if err != nil {
+ if err := e.writePlistValue(pval); err != nil {
return err
}
- tokenFunc := func(pval *plistValue) error {
- if err := e.writePlistValue(pval); err != nil {
- return err
- }
- return nil
- }
- err = e.writeElement("plist", pval, tokenFunc)
- if err != nil {
- return err
+ if e.indent != "" {
+ e.write([]byte("\n"))
}
- // newline at the end of a plist document
- _, err = e.writer.Write([]byte("\n"))
- if err != nil {
- return err
- }
- return nil
+ e.write([]byte(plistEnd))
+ e.write([]byte("\n"))
+ return e.err
}
func (e *xmlEncoder) writePlistValue(pval *plistValue) error {
@@ -108,15 +103,11 @@ func (e *xmlEncoder) writeElement(name string, pval *plistValue, valFunc func(*p
Name: xml.Name{
Space: "",
Local: name,
- }}
-
- if name == "plist" {
- startElement.Attr = []xml.Attr{{
- Name: xml.Name{
- Space: "",
- Local: "version"},
- Value: "1.0"},
- }
+ },
+ }
+
+ if name == "dict" || name == "array" {
+ e.indentCount++
}
// Encode xml.StartElement token
@@ -139,6 +130,10 @@ func (e *xmlEncoder) writeElement(name string, pval *plistValue, valFunc func(*p
return err
}
+ if name == "dict" || name == "array" {
+ e.indentCount--
+ }
+
// flush
return e.Flush()
}
@@ -147,11 +142,20 @@ func (e *xmlEncoder) writeArrayValue(pval *plistValue) error {
tokenFunc := func(pval *plistValue) error {
encodedValue := pval.value
values := encodedValue.([]*plistValue)
+ wroteBool := false
for _, v := range values {
+ if !wroteBool {
+ wroteBool = v.kind == Boolean
+ }
if err := e.writePlistValue(v); err != nil {
return err
}
}
+
+ if e.indent != "" && wroteBool {
+ e.writer.Write([]byte("\n"))
+ e.writer.Write([]byte(e.indent))
+ }
return nil
}
return e.writeElement("array", pval, tokenFunc)
@@ -214,11 +218,14 @@ func (e *xmlEncoder) writeBoolValue(pval *plistValue) error {
// EncodeElement results in instead of
// use writer to write self closing tags
b := pval.value.(bool)
- _, err := e.writer.Write([]byte(fmt.Sprintf("<%t/>", b)))
- if err != nil {
- return err
+ if e.indent != "" {
+ e.write([]byte("\n"))
+ for i := 0; i < e.indentCount; i++ {
+ e.write([]byte(e.indent))
+ }
}
- return nil
+ e.write([]byte(fmt.Sprintf("<%t/>", b)))
+ return e.err
}
func (e *xmlEncoder) writeIntegerValue(pval *plistValue) error {