[gxml] StreamReader: Implemented deserialization
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gxml] StreamReader: Implemented deserialization
- Date: Sun, 28 Jul 2019 04:04:59 +0000 (UTC)
commit dd6ad0233d0e66f04761034c875795834bd75faf
Author: Daniel Espinosa <esodan gmail com>
Date: Sat Jul 27 20:35:44 2019 -0500
StreamReader: Implemented deserialization
gxml/StreamReader.vala | 76 +++++++++++++++++++++++++++++++++++++++++++---
test/StreamReaderTest.vala | 21 ++++++++++++-
2 files changed, 92 insertions(+), 5 deletions(-)
---
diff --git a/gxml/StreamReader.vala b/gxml/StreamReader.vala
index 9d0ff67..b9a4439 100644
--- a/gxml/StreamReader.vala
+++ b/gxml/StreamReader.vala
@@ -28,6 +28,7 @@ public errordomain GXml.StreamReaderError {
public class GXml.StreamReader : GLib.Object {
uint8[] buf = new uint8[2];
+ Gee.HashMap<string,GXml.Collection> root_collections = new Gee.HashMap<string,GXml.Collection> ();
public DataInputStream stream { get; }
public Cancellable? cancellable { get; set; }
public DomDocument document { get; }
@@ -84,7 +85,13 @@ public class GXml.StreamReader : GLib.Object {
public GXml.Element read_root_element () throws GLib.Error {
return read_element (true);
}
- public GXml.Element read_element (bool children) throws GLib.Error {
+ public GXml.Element read_element (bool children, GXml.Element? parent = null) throws GLib.Error {
+ if (parent != null) {
+ if (!(parent is GXml.Object)) {
+ throw new DomError.INVALID_NODE_TYPE_ERROR
+ (_("Parent '%s' is not implemeting GXml.Object interface"), parent.get_type ().name
());
+ }
+ }
GXml.Element e = null;
var buf = new MemoryOutputStream.resizable ();
var dbuf = new DataOutputStream (buf);
@@ -122,6 +129,40 @@ public class GXml.StreamReader : GLib.Object {
document.append_child (e);
}
}
+ if (document.document_element == e && parent == null) {
+ foreach (ParamSpec pspec in
+ (e as GXml.Object).get_property_element_list ()) {
+ if (!(pspec.value_type.is_a (typeof (Collection)))) continue;
+ Collection col;
+ Value vc = Value (pspec.value_type);
+ e.get_property (pspec.name, ref vc);
+ col = vc.get_object () as Collection;
+ if (col == null) {
+ col = GLib.Object.new (pspec.value_type,
+ "element", e) as Collection;
+ vc.set_object (col);
+ e.set_property (pspec.name, vc);
+ }
+ if (col.items_type == GLib.Type.INVALID
+ || !(col.items_type.is_a (typeof (GXml.Object)))) {
+ throw new DomError.INVALID_NODE_TYPE_ERROR
+ (_("Collection '%s' hasn't been constructed properly: items' type property was not set
at construction time or set to invalid type"), col.get_type ().name ());
+ }
+ if (col.items_name == "" || col.items_name == null) {
+ throw new DomError.INVALID_NODE_TYPE_ERROR
+ (_("Collection '%s' hasn't been constructed properly: items' name property was not set
at construction time"), col.get_type ().name ());
+ }
+ if (col.element == null || !(col.element is GXml.Object)) {
+ throw new DomError.INVALID_NODE_TYPE_ERROR
+ (_("Collection '%s' hasn't been constructed properly: element property was not set at
construction time"), col.get_type ().name ());
+ }
+ if (!(col.element is GXml.Object)) {
+ throw new DomError.INVALID_NODE_TYPE_ERROR
+ (_("Invalid object of type '%s' doesn't implement GXml.Object interface: can't be
handled by the collection"), col.element.get_type ().name ());
+ }
+ root_collections.set (col.items_name.down (), col);
+ }
+ }
e.read_buffer = buf;
if (is_empty) {
return e;
@@ -139,9 +180,36 @@ public class GXml.StreamReader : GLib.Object {
if (closetag == (string) oname_buf.get_data ()) {
return e;
}
- } else if (children) {
- var ce = read_element (false);
- e.append_child (ce);
+ } else if (children && parent == null) {
+ GXml.Element ce = read_element (false, e);;
+ message ("Parsing node: %s", ce.local_name);
+ var col = root_collections.get (ce.local_name.down ());
+ if (col != null) {
+ var cobj = GLib.Object.new (col.items_type,
+ "owner-document", document) as Element;
+ cobj.read_buffer = ce.read_buffer;
+ e.append_child (cobj);
+ col.append (cobj);
+ message ("Added node: %s to %s", cobj.local_name, col.get_type ().name ());
+ } else {
+ message ("Searching node property");
+ foreach (ParamSpec pspec in
+ (e as GXml.Object).get_property_element_list ()) {
+ if (pspec.value_type.is_a (typeof (Collection))) continue;
+ var obj = GLib.Object.new (pspec.value_type,
+ "owner-document", document) as Element;
+ message ("%s == %s", obj.local_name, ce.local_name.down ());
+ if (obj.local_name.down ()
+ == ce.local_name.down ()) {
+ Value v = Value (pspec.value_type);
+ v.set_object (obj);
+ e.set_property (pspec.name, v);
+ obj.read_buffer = ce.read_buffer;
+ ce = obj;
+ }
+ }
+ e.append_child (ce);
+ }
} else {
dbuf.put_byte ('<', cancellable);
dbuf.put_byte (cur_byte (), cancellable);
diff --git a/test/StreamReaderTest.vala b/test/StreamReaderTest.vala
index 8b55e3b..01cf557 100644
--- a/test/StreamReaderTest.vala
+++ b/test/StreamReaderTest.vala
@@ -91,6 +91,7 @@ class Book : GXml.Element {
public int year { get; set; }
[Description(nick="::ISBN")]
public string ISBN { get; set; }
+ public Authors authors { get; set; }
construct {
try {
initialize ("Book");
@@ -110,6 +111,7 @@ class Book : GXml.Element {
}
class BookStore : GXml.Element {
+ public Name name { get; set; }
public Book.Collection books { get; set; }
construct {
try {
@@ -141,6 +143,7 @@ class GXmlTest {
var doc = sr.read ();
message (doc.write_string ());
var rootbuf = (string) (doc.document_element as
GXml.Element).read_buffer.data;
+ assert (doc.document_element.child_nodes.length > 0);
var childbuf = (string) (doc.document_element.child_nodes.item (0) as
GXml.Element).read_buffer.data;
message (rootbuf);
message (childbuf);
@@ -232,6 +235,7 @@ class GXmlTest {
Idle.add (()=>{
string str = """<?xml version="1.0"?>
<BookStore>
+ <Name>Magic Book</Name>
<book year="2014" isbn="ISBN83763550019---11">
<Authors>
<Author>
@@ -265,7 +269,13 @@ class GXmlTest {
assert (doc.document_element != null);
assert (doc.document_element is BookStore);
var bs = doc.document_element as BookStore;
- assert (bs.child_nodes.length == 2);
+ assert (bs != null);
+ assert (bs.name != null);
+ assert (bs.name is Name);
+ assert (bs.books != null);
+ assert (bs.books.length == 2);
+ assert (bs.books.get_item (0) is Book);
+ assert (bs.books.get_item (1) is Book);
foreach (DomNode n in bs.child_nodes) {
if (n is DomElement) {
assert ((n as GXml.Element).read_buffer != null);
@@ -277,6 +287,15 @@ class GXmlTest {
message (doc.write_string ());
assert (bs.read_buffer == null);
assert (bs.books != null);
+ assert (bs.books.length == 2);
+ var b1 = bs.books.get_item (0) as Book;
+ assert (b1 != null);
+ assert (b1 is Book);
+ assert (b1.authors != null);
+ var b2 = bs.books.get_item (0) as Book;
+ assert (b2 != null);
+ assert (b2 is Book);
+ assert (b2.authors != null);
loop.quit ();
} catch (GLib.Error e) {
warning ("Error: %s", e.message);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]