add Yaml.serialize & Yaml.deserialize

This commit is contained in:
a-sansara 2018-08-24 14:11:19 +02:00
parent 7dde273ef7
commit 2b11962eb6
11 changed files with 391 additions and 29 deletions

View File

@ -61,7 +61,9 @@ configure_file(
sources = [
'build/install.vala',
'src/vala/Pluie/Io.Reader.vala',
'src/vala/Pluie/Io.InputChunkStream.vala',
'src/vala/Pluie/Io.StreamLineMark.vala',
'src/vala/Pluie/Io.Writter.vala',
'src/vala/Pluie/Yaml.global.vala',
'src/vala/Pluie/Yaml.AbstractChild.vala',
'src/vala/Pluie/Yaml.AbstractNode.vala',

View File

@ -64,7 +64,7 @@ int main (string[] args)
// sum of the bytes of 'text' that already have been written to the stream
written += dos.write (data[written:data.length]);
}
of.echo ("write %lld bytes in `%s`".printf ((long) written, genpath));
of.echo ("write %ld bytes in `%s`".printf ((long) written, genpath));
Yaml.Dumper.show_yaml_string (root, true, true, true);
} catch (Error e) {
stderr.printf ("%s\n", e.message);

113
samples/yaml-serialize.vala Normal file
View File

@ -0,0 +1,113 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* @software : pluie-yaml <https://git.pluie.org/pluie/lib-yaml>
* @version : 0.5
* @type : library
* @date : 2018
* @licence : GPLv3.0 <http://www.gnu.org/licenses/>
* @author : a-Sansara <[dev]at[pluie]dot[org]>
* @copyright : pluie.org <http://www.pluie.org/>
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* This file is part of pluie-yaml.
*
* pluie-yaml is free software (free as in speech) : you can redistribute it
* and/or modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* pluie-yaml is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with pluie-yaml. If not, see <http://www.gnu.org/licenses/>.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
using GLib;
using Gee;
using Pluie;
public void test_object(Yaml.Example obj)
{
of.action ("Test Object", obj.yaml_name);
obj.type_object.method_a ();
if (obj.type_gee_al != null) {
of.keyval("yaml_name" , "%s" .printf(obj.yaml_name));
of.keyval("type_int" , "%d" .printf(obj.type_int));
of.keyval("type_bool" , "%s" .printf(obj.type_bool.to_string ()));
of.keyval("type_char" , "%c" .printf(obj.type_char));
of.keyval("type_string" , "%s" .printf(obj.type_string));
of.keyval("type_uchar" , "%u" .printf(obj.type_uchar));
of.keyval("type_uint" , "%u" .printf(obj.type_uint));
of.keyval("type_float" , "%f" .printf(obj.type_float));
of.keyval("type_double" , "%f" .printf(obj.type_double));
of.keyval("type_struct" , "%s" .printf(obj.type_struct.to_string ()));
of.keyval("type_enum" , "%d (%s)" .printf(obj.type_enum, obj.type_enum.infos()));
of.keyval("type_gee_al", "(%s<%s>)" .printf(obj.type_gee_al.get_type ().name (), obj.type_gee_al.element_type.name ()));
foreach (var v in obj.type_gee_al) {
of.echo(" - item : %g".printf (v));
}
of.keyval("type_object", "(%s)" .printf(obj.type_object.get_type ().name ()));
of.keyval(" toto" , "%s (string)" .printf(obj.type_object.toto));
of.keyval(" tapa" , "%s (string)" .printf(obj.type_object.tata));
of.keyval(" titi" , "%d (int)" .printf(obj.type_object.titi));
of.keyval(" tutu" , "%s (bool)" .printf(obj.type_object.tutu.to_string ()));
obj.type_object.method_a ();
of.keyval("type_gee_alobject", "(%s<%s>)" .printf(obj.type_gee_alobject.get_type ().name (), obj.type_gee_alobject.element_type.name ()));
foreach (var child in obj.type_gee_alobject) {
of.echo(" == entry (%s) ==".printf(child.get_type ().name ()));
of.keyval(" toto" , "%s (string)" .printf(child.toto));
of.keyval(" tapa" , "%s (string)" .printf(child.tata));
of.keyval(" titi" , "%d (int)" .printf(child.titi));
of.keyval(" tutu" , "%s (bool)" .printf(child.tutu.to_string ()));
child.method_a ();
}
}
}
int main (string[] args)
{
Echo.init(false);
var path = Yaml.DATA_PATH + "/tag.yml";
var done = false;
of.title ("Pluie Yaml Library", Pluie.Yaml.VERSION, "a-sansara");
Pluie.Yaml.DEBUG = false;
var config = new Yaml.Config (path, true);
var root = config.root_node ();
if ((done = root != null)) {
root.display_childs ();
of.action ("Yaml build first child", root.first ().name);
Yaml.Example obj = (Yaml.Example) Yaml.Builder.from_node (root.first ());
obj = (Yaml.Example) Yaml.Builder.from_node (root.first ());
test_object (obj);
of.action ("Serialize", obj.yaml_name);
uint8[] zdata = Yaml.serialize (obj);
of.echo ("zdata size : %ld".printf (zdata.length));
for (var i = 0; i < zdata.length; i++) {
print ("%02x", zdata[i]);
}
of.echo ("");
of.action ("Deserialize zdata from", obj.yaml_name);
message ("*");
root = Yaml.deserialize (zdata);
message ("*");
root.display_childs ();
of.action ("Yaml build first child", obj.yaml_name);
obj = (Yaml.Example) Yaml.Builder.from_node (root.first ());
message ("*");
test_object (obj);
}
return (int) done;
}

View File

@ -0,0 +1,79 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* @software : pluie-yaml <https://git.pluie.org/pluie/lib-yaml>
* @version : 0.5
* @type : library
* @date : 2018
* @licence : GPLv3.0 <http://www.gnu.org/licenses/>
* @author : a-Sansara <[dev]at[pluie]dot[org]>
* @copyright : pluie.org <http://www.pluie.org/>
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* This file is part of pluie-yaml.
*
* pluie-yaml is free software (free as in speech) : you can redistribute it
* and/or modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* pluie-yaml is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with pluie-yaml. If not, see <http://www.gnu.org/licenses/>.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
using GLib;
class Pluie.Io.InputChunkStream : Object
{
protected ulong chunk_index;
protected uint8 chunk_size;
protected uint8 buffer_size;
protected uint8[] buffer;
protected FileStream fs;
public InputChunkStream (string path, uint8 chunk_size)
{
this.chunk_size = chunk_size;
this.buffer = new uint8[this.chunk_size];
this.fs = FileStream.open (path, "r");
this.chunk_index = 0;
}
public bool eof ()
{
bool stop = this.fs.eof ();
if (stop) {
this.buffer = null;
}
return stop;
}
public unowned uint8[] read ()
{
if (!this.eof ()) {
this.buffer_size = (uint8) this.fs.read (this.buffer);
this.chunk_index++;
}
return this.buffer;
}
public unowned uint8 get_buffer_size ()
{
return this.buffer_size;
}
public unowned uint8[] get_buffer ()
{
return this.buffer;
}
public ulong get_chunk_index ()
{
return this.chunk_index-1;
}
public uint8 get_chunk_size ()
{
return this.chunk_size;
}
}

View File

@ -142,4 +142,18 @@ public class Pluie.Io.Reader
return this.readable;
}
/**
*
*/
public string? get_contents ()
{
string? read = null;
try {
FileUtils.get_contents (this.path, out read);
}
catch(GLib.Error e) {
of.error (e.message);
}
return read;
}
}

View File

@ -0,0 +1,95 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* @software : pluie-yaml <https://git.pluie.org/pluie/lib-yaml>
* @version : 0.5
* @type : library
* @date : 2018
* @licence : GPLv3.0 <http://www.gnu.org/licenses/>
* @author : a-Sansara <[dev]at[pluie]dot[org]>
* @copyright : pluie.org <http://www.pluie.org/>
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* This file is part of pluie-yaml.
*
* pluie-yaml is free software (free as in speech) : you can redistribute it
* and/or modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* pluie-yaml is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with pluie-yaml. If not, see <http://www.gnu.org/licenses/>.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
using GLib;
using Gee;
using Pluie;
/**
* basic writer
*/
public class Pluie.Io.Writter
{
/**
* current file path
*/
public string path { get; internal set; }
/**
*
*/
public File file { get; internal set; }
/**
* stream used to read the file
*/
DataOutputStream stream;
/**
* construct a reader
* by adding {@link Io.StreamLineMark}
* @param path the path to load
*/
public Writter (string path)
{
this.path = path;
this.file = File.new_for_path (path);
try {
this.stream = new DataOutputStream(file.create (FileCreateFlags.NONE));
if (!file.query_exists ()) {
of.error ("cannot create file '%s'".printf (path));
}
}
catch (GLib.Error e) {
of.error (e.message);
}
}
/**
* read current stream by line
* @param mark a mark used to operate possible future rewind
* @return current readed line
*/
public bool write (uint8[] data)
{
bool done = false;
try {
long written = 0;
while (written < data.length) {
// sum of the bytes that already have been written to the stream
written += stream.write (data[written:data.length]);
}
done = written == data.length;
}
catch (GLib.Error e) {
of.error (e.message);
}
return done;
}
}

View File

@ -110,8 +110,7 @@ public abstract class Pluie.Yaml.AbstractNode : GLib.Object
int indent = Yaml.Dumper.DEFAULT_INDENT,
bool show_doc = Yaml.Dumper.SHOW_DOC,
bool show_tags = Yaml.Dumper.SHOW_TAGS,
bool show_fullkeys = Yaml.Dumper.SHOW_FULL_KEYS,
bool show_colors = Yaml.Dumper.SHOW_COLORS
bool show_fullkeys = Yaml.Dumper.SHOW_FULL_KEYS
)
{
return Yaml.Dumper.dump (
@ -119,8 +118,7 @@ public abstract class Pluie.Yaml.AbstractNode : GLib.Object
indent,
show_doc,
show_tags,
show_fullkeys,
show_colors
show_fullkeys
);
}
}

View File

@ -101,9 +101,9 @@ public class Pluie.Yaml.Config
/**
*
*/
public Yaml.Node root_node ()
public Yaml.Root root_node ()
{
return this.finder.context;
return this.finder.context as Yaml.Root;
}
/**

View File

@ -56,11 +56,11 @@ public class Pluie.Yaml.Dumper
/**
*
*/
public static bool SHOW_COLORS { get; internal set; default = false; }
static bool SHOW_COLOR { get; internal set; default = false; }
/**
*
*/
public static bool SHOW_LINE { get; internal set; default = false; }
static bool SHOW_LINE { get; internal set; default = false; }
/**
*
*/
@ -86,16 +86,11 @@ public class Pluie.Yaml.Dumper
bool show_fullkeys = Yaml.Dumper.SHOW_FULL_KEYS
)
{
bool prev1 = SHOW_LINE;
bool prev2 = SHOW_COLORS;
bool prev3 = SHOW_TAGS;
SHOW_LINE = show_line;
SHOW_COLORS = show_color;
SHOW_TAGS = show_tags;
string yaml = dump (node, indent, show_doc, show_tags, show_fullkeys, show_color);
SHOW_LINE = prev1;
SHOW_COLORS = prev2;
SHOW_TAGS = prev3;
SHOW_COLOR = show_color;
string yaml = dump (node, indent, show_doc, show_tags, show_fullkeys);
SHOW_LINE = false;
SHOW_COLOR = false;
of.action ("Yaml string representation for", node!= null ? node.name : "null");
print ("%s%s%s", "\n", yaml, "\n");
}
@ -108,8 +103,7 @@ public class Pluie.Yaml.Dumper
int indent = Yaml.Dumper.DEFAULT_INDENT,
bool show_doc = Yaml.Dumper.SHOW_DOC,
bool show_tags = Yaml.Dumper.SHOW_TAGS,
bool show_fullkeys = Yaml.Dumper.SHOW_FULL_KEYS,
bool show_colors = Yaml.Dumper.SHOW_COLORS
bool show_fullkeys = Yaml.Dumper.SHOW_FULL_KEYS
)
{
var yaml = new StringBuilder("");
@ -118,7 +112,7 @@ public class Pluie.Yaml.Dumper
line = 0;
yaml_root (ref yaml, node as Yaml.Root, show_doc);
foreach (var child in node) {
yaml.append (Yaml.Dumper.dump (child, indent, show_doc, show_tags, show_fullkeys, show_colors));
yaml.append (Yaml.Dumper.dump (child, indent, show_doc, show_tags, show_fullkeys));
}
}
else if (node.ntype.is_single_pair ()) {
@ -128,7 +122,7 @@ public class Pluie.Yaml.Dumper
else if (node.ntype.is_collection ()) {
yaml_key (ref yaml, node, indent, show_tags);
foreach (var child in node) {
yaml.append (Yaml.Dumper.dump (child, indent, show_doc, show_tags, show_fullkeys, show_colors));
yaml.append (Yaml.Dumper.dump (child, indent, show_doc, show_tags, show_fullkeys));
}
}
else if (node.ntype.is_scalar ()) {
@ -156,12 +150,12 @@ public class Pluie.Yaml.Dumper
private static void yaml_tag (ref StringBuilder yaml, Yaml.Node node, bool show_tags)
{
if (node.tag != null && show_tags) {
if (SHOW_COLORS) yaml.append (of.c (ECHO.COMMAND).to_string ());
if (SHOW_COLOR) yaml.append (of.c (ECHO.COMMAND).to_string ());
yaml.append ("!%s!%s".printf (
node.tag.handle,
node.tag.value
));
yaml.append ("%s ".printf (SHOW_COLORS ? Color.off () : ""));
yaml.append ("%s ".printf (SHOW_COLOR ? Color.off () : ""));
}
}
@ -193,7 +187,7 @@ public class Pluie.Yaml.Dumper
else if (!node.is_first ()) {
yaml_indent (ref yaml, node, indent, true);
}
if (node.parent != null && node.parent.ntype.is_sequence ()) yaml.append (!SHOW_COLORS ? "- " : of.c (ECHO.DATE).s ("- "));
if (node.parent != null && node.parent.ntype.is_sequence ()) yaml.append (!SHOW_COLOR ? "- " : of.c (ECHO.DATE).s ("- "));
if (wrapseq) {
if (Yaml.DEBUG) of.warn ("node %s wrapseq ? %s".printf (node.name, wrapseq.to_string ()));
}
@ -205,8 +199,8 @@ public class Pluie.Yaml.Dumper
}
len = (!show_tags || (node.tag == null && !node.ntype.is_collection ()) && len > 0) ? len +1 - node.name.length : 0;
yaml.append("%s%s%s".printf(
!SHOW_COLORS ? @"%s%$(len)s ".printf (node.name, " ") : of.c (node.ntype.is_collection() ? ECHO.TIME : ECHO.OPTION).s(@"%s%$(len)s".printf (node.name, " ")),
!SHOW_COLORS ? ":" : of.c (ECHO.DATE).s(":"),
!SHOW_COLOR ? @"%s%$(len)s ".printf (node.name, " ") : of.c (node.ntype.is_collection() ? ECHO.TIME : ECHO.OPTION).s(@"%s%$(len)s".printf (node.name, " ")),
!SHOW_COLOR ? ":" : of.c (ECHO.DATE).s(":"),
node.ntype.is_collection () ? "\n" : " "
));
}
@ -218,10 +212,10 @@ public class Pluie.Yaml.Dumper
private static void yaml_scalar (ref StringBuilder yaml, Yaml.Node node, int indent, bool show_tags)
{
if (!(node.parent !=null && node.parent.ntype.is_single_pair ())) yaml_indent (ref yaml, node, indent);
if (node.parent != null && node.parent.ntype.is_sequence ()) yaml.append (!SHOW_COLORS ? "- " : of.c (ECHO.DATE).s ("- "));
if (node.parent != null && node.parent.ntype.is_sequence ()) yaml.append (!SHOW_COLOR ? "- " : of.c (ECHO.DATE).s ("- "));
yaml_tag (ref yaml, node, show_tags);
yaml.append ("%s\n".printf (
!SHOW_COLORS ? node.data : of.c (ECHO.OPTION_SEP).s (node.data)
!SHOW_COLOR ? node.data : of.c (ECHO.OPTION_SEP).s (node.data)
));
}
}

View File

@ -116,6 +116,7 @@ public class Pluie.Yaml.Register
/**
* add one or multiple namespace for tag resolution
* namespace value ar same as in vala source code (so with dot separator)
* @param name a namespace to register
*/
public static bool add_namespace (string name, ...)

View File

@ -87,6 +87,72 @@ namespace Pluie
MAPPING_NOT_SINGLE_PAIR
}
private const ZlibCompressorFormat ZFORMAT = ZlibCompressorFormat.GZIP;
/**
*
*/
private void convert (File source, File dest, Converter converter) throws Error {
var src_stream = source.read ();
var dst_stream = dest.replace (null, false, 0);
var conv_stream = new ConverterOutputStream (dst_stream, converter);
// 'splice' pumps all data from an InputStream to an OutputStream
conv_stream.splice (src_stream, 0);
}
/**
*
*/
public static uint8[] serialize (GLib.Object? obj)
{
Array<uint8> a = new Array<uint8> ();
if (obj != null) {
var node = obj.get_type ().is_a (typeof (Yaml.Node)) ? obj as Yaml.Node : Yaml.Builder.to_node (obj);
if (node != null) {
var content = node.to_yaml_string ();
var date = new GLib.DateTime.now_local ().format ("%s");
var path = Path.build_filename (Environment.get_tmp_dir (), "pluie-yaml-%s-%s.source".printf (date, node.uuid));
var writter = new Io.Writter (path);
if (writter.write (content.data)) {
try {
var gzfile = File.new_for_path (path + ".gz");
convert (writter.file, gzfile, new ZlibCompressor (ZFORMAT));
var reader = new Io.InputChunkStream(path + ".gz", 80);
while (!reader.eof ()) {
var b = reader.read ();
a.append_vals (b, reader.get_buffer_size ());
}
}
catch (GLib.Error e) {
of.error (e.message);
}
}
}
}
return a.data;
}
/**
*
*/
public static Yaml.Root deserialize (uint8[] zdata)
{
Yaml.Root? obj = null;
if (zdata.length > 0) {
var date = new GLib.DateTime.now_local ().format ("%s");
var path = Path.build_filename (Environment.get_tmp_dir (), "pluie-yaml-%s.gz".printf (date));
var dpath = Path.build_filename (Environment.get_tmp_dir (), "pluie-yaml-%s.source".printf (date));
var writter = new Io.Writter (path);
if (writter.write (zdata)) {
var file = File.new_for_path (dpath);
convert (writter.file, file, new ZlibDecompressor (ZFORMAT));
var config = new Yaml.Config (dpath);
obj = config.root_node ();
}
}
return obj;
}
/**
* haxadecimal sequence
*/