1 module plist; 2 public import plist.types.element; 3 import dxml.dom; 4 import std.range; 5 import plist.types; 6 import plist.conv; 7 8 class Plist { 9 bool read(string input) { 10 import std.stdio; 11 auto dom = parseDOM(input); 12 13 auto root = dom.children[0]; 14 { 15 // sanity checking 16 assert(root.name == "plist"); 17 assert(root.type == EntityType.elementStart); 18 auto attrs = root.attributes(); 19 assert(attrs.length == 1); 20 assert(attrs[0].name == "version"); 21 assert(attrs[0].value == "1.0"); 22 } 23 24 foreach(child; root.children) { 25 if (validateDataType(child)) { 26 auto element = coerceRuntime(cast(PlistElementType)child.name, child); 27 _elements ~= element; 28 } else { 29 writeln("Skipped child with name: ", child.name); 30 } 31 } 32 33 return true; 34 } 35 36 override string toString() { 37 string output = ""; 38 foreach(element; _elements) { 39 output ~= element.toString() ~ "\n"; 40 } 41 42 return output; 43 } 44 45 ref PlistElement opIndex(size_t index) { 46 return _elements[index]; 47 } 48 49 size_t length() { 50 return _elements.length; 51 } 52 53 string write() { 54 import std.array : Appender, appender; 55 auto app = appender!string(); 56 app.writeXMLDecl!string(); 57 app.put("\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); 58 auto writer = xmlWriter(app); 59 writer.openStartTag("plist"); 60 writer.writeAttr("version", "1.0"); 61 writer.closeStartTag(); 62 63 foreach(element; _elements) { 64 element.write(writer); 65 } 66 writer.writeEndTag("plist"); 67 return writer.output.data; 68 } 69 70 private { 71 PlistElement[] _elements; 72 } 73 } 74 75