diff --git a/gxml/TwDocument.vala b/gxml/TwDocument.vala index 5fe699ea63505096c7dd4100632a1eace6047ec0..987bf93ff1a3342edf9155a6b55d7898e5735bea 100644 --- a/gxml/TwDocument.vala +++ b/gxml/TwDocument.vala @@ -31,6 +31,7 @@ using Xml; public class GXml.TwDocument : GXml.TwNode, GXml.Document { GXml.Element _root = null; + Xml.Buffer _buffer; construct { _name = "#document"; } @@ -117,8 +118,34 @@ public class GXml.TwDocument : GXml.TwNode, GXml.Document } public bool save_to (GLib.File f, GLib.Cancellable? cancellable = null) { - var tw = new Xml.TextWriter.filename (f.get_path ()); + file = f; + var buf = new Xml.Buffer (); + var tw = Xmlx.new_text_writer_memory (buf, 0); + GLib.Test.message ("Writing down to buffer"); write_document (tw); + GLib.Test.message ("Writing down to file"); + GLib.Test.message ("TextWriter buffer:\n"+buf.content ()); + var s = new GLib.StringBuilder (); + s.append (buf.content ()); + try { + GLib.Test.message ("Writing down to file: Creating input stream"); + var b = new GLib.MemoryInputStream.from_data (s.data, null); + GLib.OutputStream ostream; + if (file.query_exists ()) { + GLib.Test.message ("Writing down to file: Replacing with backup"); + ostream = file.replace (null, true, GLib.FileCreateFlags.NONE, cancellable); + ostream.splice (b, GLib.OutputStreamSpliceFlags.NONE); + ostream.close (); + } else { + GLib.Test.message ("Writing down to file: Creating a new File"); + ostream = file.create (GLib.FileCreateFlags.NONE, cancellable); + ostream.splice (b, GLib.OutputStreamSpliceFlags.NONE); + ostream.close (); + } + } catch (GLib.Error e) { + GLib.warning ("Error on Save to file: "+e.message); + return false; + } return true; } public virtual void write_document (Xml.TextWriter tw) diff --git a/gxml/xlibxml.c b/gxml/xlibxml.c index 1365580a5f1759ccdbcfb65f08771fbbce80df19..887338a959aa7422ae05233748ee04aca6422ff1 100644 --- a/gxml/xlibxml.c +++ b/gxml/xlibxml.c @@ -23,11 +23,13 @@ void* gxml_doc_get_intsubset_entities (xmlDoc *doc) { + g_return_if_fail (doc != NULL); return doc->intSubset->entities; } int gxml_validate_name (xmlChar* name, int space) { + g_return_if_fail (name != NULL); return xmlValidateName (name, space); } @@ -43,20 +45,34 @@ xmlErrorPtr gxml_get_last_error () xmlNsPtr* gxml_doc_get_ns_list (xmlDoc* doc, xmlNode* node) { + g_return_if_fail (doc != NULL); + g_return_if_fail (node != NULL); return xmlGetNsList (doc, node); } xmlTextWriterPtr gxml_new_text_writer_doc (xmlDoc** doc) { + g_return_if_fail (doc != NULL); return xmlNewTextWriterDoc (doc, 0); } +xmlTextWriterPtr gxml_new_text_writer_memory (xmlBufferPtr buffer, gint compression) +{ + g_return_if_fail (buffer != NULL); + return xmlNewTextWriterMemory (buffer, compression); +} + int gxml_text_writer_write_cdata (xmlTextWriterPtr tw, const xmlChar* text) { + g_return_if_fail (tw != NULL); + g_return_if_fail (text != NULL); return xmlTextWriterWriteCDATA (tw, text); } int gxml_text_writer_write_pi (xmlTextWriterPtr tw, const xmlChar* target, const xmlChar* data) { + g_return_if_fail (tw != NULL); + g_return_if_fail (target != NULL); + g_return_if_fail (data != NULL); return xmlTextWriterWritePI (tw, target, data); } diff --git a/gxml/xlibxml.h b/gxml/xlibxml.h index 6ec601c5bc29729d92376db001e04ab18be63110..ea173e7584a540568fd93dc6598e749f0a3e3695 100644 --- a/gxml/xlibxml.h +++ b/gxml/xlibxml.h @@ -24,12 +24,15 @@ #include #include #include +#include void* gxml_doc_get_intsubset_entities (xmlDoc *doc); int gxml_validate_name (xmlChar* name, int space); xmlErrorPtr gxml_parser_context_get_last_error (void* ctx); xmlErrorPtr gxml_get_last_error (); xmlNsPtr* gxml_doc_get_ns_list (xmlDoc* doc, xmlNode* node); +xmlTextWriterPtr gxml_new_text_writer_doc (xmlDoc** doc); +xmlTextWriterPtr gxml_new_text_writer_memory (xmlBufferPtr buffer, gint compression); int gxml_text_writer_write_cdata (xmlTextWriter* tw, const xmlChar* text); int gxml_text_writer_write_pi (xmlTextWriter* tw, const xmlChar* target, const xmlChar* data); diff --git a/test/TwDocumentTest.vala b/test/TwDocumentTest.vala index 0d709070647305476f79446ef6bd5e525087eb77..4be9429e5db8317e9ef2a6228a79c31de2712321 100644 --- a/test/TwDocumentTest.vala +++ b/test/TwDocumentTest.vala @@ -23,6 +23,12 @@ using GXml; class TwDocumentTest : GXmlTest { + public class TwTestObject : SerializableObjectModel + { + public string name { get; set; } + public override string node_name () { return "Test"; } + public override string to_string () { return "TestNode"; } + } public static void add_tests () { Test.add_func ("/gxml/tw-document", () => { try { @@ -71,13 +77,15 @@ class TwDocumentTest : GXmlTest { assert (d.root != null); assert (d.root.name == "root"); assert (d.root.value == ""); - d.save (); + GLib.Test.message ("Saving document to: "+f.get_path ()); + assert (d.save ()); + GLib.Test.message ("Reading saved document to: "+f.get_path ()); + assert (f.query_exists ()); var istream = f.read (); - uint8[] buffer = new uint8[2048]; - istream.read_all (buffer, null); - istream.close (); - assert ("" in ((string)buffer)); - assert ("" in ((string)buffer)); + var ostream = new MemoryOutputStream.resizable (); + ostream.splice (istream, 0); + assert ("" in ((string)ostream.data)); + assert ("" in ((string)ostream.data)); } catch (GLib.Error e) { #if DEBUG @@ -326,7 +334,41 @@ class TwDocumentTest : GXmlTest { assert_not_reached (); } }); - + Test.add_func ("/gxml/tw-document/save/backup", () => { + try { + var f = GLib.File.new_for_path (GXmlTestConfig.TEST_SAVE_DIR+"/tw-test.xml"); + if (f.query_exists ()) f.delete (); + var ot = new TwTestObject (); + ot.name = "test1"; + var dt = new TwDocument (); + ot.serialize (dt); + dt.save_to (f); + var d = new TwDocument (); + var e = d.create_element ("root"); + d.childs.add (e); + assert (d.childs.size == 1); + assert (d.root != null); + assert (d.root.name == "root"); + assert (d.root.value == ""); + d.save_to (f); + assert (f.query_exists ()); + var bf = GLib.File.new_for_path (GXmlTestConfig.TEST_SAVE_DIR+"/tw-test.xml~"); + assert (bf.query_exists ()); + var istream = f.read (); + var b = new MemoryOutputStream.resizable (); + b.splice (istream, 0); + assert ("" in ((string)b.data)); + assert ("" in ((string)b.data)); + f.delete (); + bf.delete (); + } + catch (GLib.Error e) { +#if DEBUG + GLib.message (@"ERROR: $(e.message)"); +#endif + assert_not_reached (); + } + }); Test.add_func ("/gxml/tw-document/to_string", () => { var doc = new TwDocument (); var r = doc.create_element ("root"); diff --git a/vapi/xlibxml-1.0.vapi b/vapi/xlibxml-1.0.vapi index 17fa24ddb4af37a18627d82e47a9b480694f8ff9..282a962dd65512551f4c88ac753318d1d938179a 100644 --- a/vapi/xlibxml-1.0.vapi +++ b/vapi/xlibxml-1.0.vapi @@ -38,6 +38,8 @@ namespace Xmlx { public static Xml.Ns*[] doc_get_ns_list (Xml.Doc* doc, Xml.Node* node); [CCode (cname = "gxml_new_text_writer_doc", cheader_filename = "gxml/xlibxml.h")] public static Xml.TextWriter new_text_writer_doc (ref Xml.Doc doc); + [CCode (cname = "gxml_new_text_writer_memory", cheader_filename = "gxml/xlibxml.h")] + public static Xml.TextWriter new_text_writer_memory (Xml.Buffer buffer, int compression); [CCode (cname = "gxml_text_writer_write_cdata", cheader_filename = "gxml/xlibxml.h")] public static int text_writer_write_cdata (Xml.TextWriter tw, string text); [CCode (cname = "gxml_text_writer_write_pi", cheader_filename = "gxml/xlibxml.h")]