|
@@ -1,332 +0,0 @@
|
|
|
-
|
|
|
-namespace InvercargillJson {
|
|
|
-
|
|
|
-
|
|
|
- public class JsonElement : Object, Invercargill.Element {
|
|
|
-
|
|
|
- private Json.Node node;
|
|
|
-
|
|
|
- public JsonElement.from_string(string json) throws GLib.Error {
|
|
|
- node = Json.from_string (json);
|
|
|
- }
|
|
|
-
|
|
|
- public JsonElement.from_file(string path) throws GLib.Error {
|
|
|
- var parser = new Json.Parser();
|
|
|
- parser.load_from_file(path);
|
|
|
- node = parser.get_root();
|
|
|
- }
|
|
|
-
|
|
|
- public JsonElement.from_stream(InputStream stream) throws GLib.Error {
|
|
|
- var parser = new Json.Parser();
|
|
|
- parser.load_from_stream(stream);
|
|
|
- node = parser.get_root();
|
|
|
- }
|
|
|
-
|
|
|
- public async JsonElement.from_stream_async(InputStream stream, GLib.Cancellable cancellable) throws GLib.Error {
|
|
|
- var parser = new Json.Parser();
|
|
|
- yield parser.load_from_stream_async (stream, cancellable);
|
|
|
- node = parser.get_root();
|
|
|
- }
|
|
|
-
|
|
|
- internal JsonElement.from_node(Json.Node node) {
|
|
|
- this.node = node;
|
|
|
- }
|
|
|
-
|
|
|
- public JsonElement.from_properties(Invercargill.Properties properties) throws Invercargill.ElementError {
|
|
|
- node = new Json.Node (Json.NodeType.OBJECT);
|
|
|
- var object = new JsonObject();
|
|
|
- foreach (var item in properties) {
|
|
|
- object.set(item.key, new JsonElement.from_element(item.value));
|
|
|
- }
|
|
|
- node.set_object (object.json_glib_object);
|
|
|
- }
|
|
|
-
|
|
|
- public JsonElement.from_elements(Invercargill.Elements elements) throws Invercargill.ElementError {
|
|
|
- node = new Json.Node (Json.NodeType.ARRAY);
|
|
|
- var array = new JsonArray();
|
|
|
- foreach (var item in elements) {
|
|
|
- array.add(new JsonElement.from_element (item));
|
|
|
- }
|
|
|
- node.set_array (array.json_glib_object);
|
|
|
- }
|
|
|
-
|
|
|
- public JsonElement.from_element(Invercargill.Element element) throws Invercargill.ElementError {
|
|
|
- // Null node is top priority
|
|
|
- if(element.is_null ()) {
|
|
|
- node = new Json.Node(Json.NodeType.NULL);
|
|
|
- node.init_null ();
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // Second priority is creation of arrays and objects
|
|
|
- if(element.assignable_to<Invercargill.Properties>()) {
|
|
|
- node = new Json.Node (Json.NodeType.OBJECT);
|
|
|
- var object = new JsonObject();
|
|
|
- foreach (var item in element.as<Invercargill.Properties>()) {
|
|
|
- object.set(item.key, new JsonElement.from_element(item.value));
|
|
|
- }
|
|
|
- node.set_object (object.json_glib_object);
|
|
|
- return;
|
|
|
- }
|
|
|
- if(element.assignable_to<Invercargill.Elements>()) {
|
|
|
- node = new Json.Node (Json.NodeType.ARRAY);
|
|
|
- var array = new JsonArray();
|
|
|
- foreach (var item in element.as<Invercargill.Elements>()) {
|
|
|
- array.add(new JsonElement.from_element (item));
|
|
|
- }
|
|
|
- node.set_array (array.json_glib_object);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- node = new Json.Node (Json.NodeType.VALUE);
|
|
|
- var type = element.type();
|
|
|
-
|
|
|
- // Third priority is conversion of known types
|
|
|
- if(type == typeof(DateTime)) {
|
|
|
- node.set_string (element.as<DateTime>().format_iso8601());
|
|
|
- return;
|
|
|
- }
|
|
|
- if(type == typeof(Invercargill.BinaryData)) {
|
|
|
- node.set_string (element.as<Invercargill.BinaryData>().to_base64());
|
|
|
- return;
|
|
|
- }
|
|
|
- if(type == typeof(string)) {
|
|
|
- node.set_string (element.as<string>());
|
|
|
- return;
|
|
|
- }
|
|
|
- if(type == typeof(bool)) {
|
|
|
- node.set_boolean (element.as<bool>());
|
|
|
- return;
|
|
|
- }
|
|
|
- if(type == typeof(double)) {
|
|
|
- node.set_double (element.as<double?>());
|
|
|
- return;
|
|
|
- }
|
|
|
- if(type == typeof(int64)) {
|
|
|
- node.set_int (element.as<int64?>());
|
|
|
- return;
|
|
|
- }
|
|
|
- if(type == typeof(uint8)) {
|
|
|
- node.set_int (element.as<uint>());
|
|
|
- return;
|
|
|
- }
|
|
|
- if(type == typeof(int8)) {
|
|
|
- node.set_int (element.as<int>());
|
|
|
- return;
|
|
|
- }
|
|
|
- if(type == typeof(uint16)) {
|
|
|
- node.set_int (element.as<uint16>());
|
|
|
- return;
|
|
|
- }
|
|
|
- if(type == typeof(int16)) {
|
|
|
- node.set_int (element.as<int16>());
|
|
|
- return;
|
|
|
- }
|
|
|
- if(type == typeof(uint32)) {
|
|
|
- node.set_int (element.as<uint32>());
|
|
|
- return;
|
|
|
- }
|
|
|
- if(type == typeof(int32)) {
|
|
|
- node.set_int (element.as<int32>());
|
|
|
- return;
|
|
|
- }
|
|
|
- if(type == typeof(uint64?)) {
|
|
|
- node.set_int ((int64)element.as<uint64?>());
|
|
|
- return;
|
|
|
- }
|
|
|
- if(type == typeof(float?)) {
|
|
|
- node.set_double (element.as<float?>());
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // Last priority is the element's native conversions
|
|
|
- if(element.assignable_to<string>()) {
|
|
|
- node.set_string (element.as<string>());
|
|
|
- return;
|
|
|
- }
|
|
|
- if(element.assignable_to<bool> ()) {
|
|
|
- node.set_boolean(element.as<bool>());
|
|
|
- return;
|
|
|
- }
|
|
|
- if(element.assignable_to<double?>()) {
|
|
|
- node.set_double(element.as<double?>());
|
|
|
- return;
|
|
|
- }
|
|
|
- if(element.assignable_to<int64?>()) {
|
|
|
- node.set_int(element.as<int64?>());
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // Could not convert
|
|
|
- throw new Invercargill.ElementError.INVALID_CONVERSION(@"No way to convert element $(element.get_type ().name()) containing type $(type.name()) to a type suitable for a JsonElement.");
|
|
|
- }
|
|
|
-
|
|
|
- public bool assignable_to_type (GLib.Type type) {
|
|
|
- if(node.is_null() || type == typeof(Json.Node)) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(node.get_node_type() == Json.NodeType.ARRAY) {
|
|
|
- return
|
|
|
- type == typeof(JsonArray) ||
|
|
|
- type == typeof(JsonElements) ||
|
|
|
- type == typeof(Invercargill.Elements) ||
|
|
|
- type == typeof(Json.Array);
|
|
|
- }
|
|
|
- if(node.get_node_type() == Json.NodeType.OBJECT) {
|
|
|
- return
|
|
|
- type == typeof(JsonObject) ||
|
|
|
- type == typeof(Invercargill.Properties) ||
|
|
|
- type == typeof(Json.Object);
|
|
|
- }
|
|
|
- if(node.get_value_type().is_a(typeof(int64)) || node.get_value_type ().is_a(typeof(double))) {
|
|
|
- return
|
|
|
- type == typeof(uint8) ||
|
|
|
- type == typeof(int8) ||
|
|
|
- type == typeof(uint16) ||
|
|
|
- type == typeof(int16) ||
|
|
|
- type == typeof(uint32) ||
|
|
|
- type == typeof(int32) ||
|
|
|
- type == typeof(uint64) ||
|
|
|
- type == typeof(int64) ||
|
|
|
- type == typeof(double) ||
|
|
|
- type == typeof(float) ||
|
|
|
- type == typeof(string);
|
|
|
- }
|
|
|
- if(node.get_value_type().is_a(typeof(string))) {
|
|
|
- return
|
|
|
- type == typeof(string) ||
|
|
|
- type == typeof(Invercargill.BinaryData) ||
|
|
|
- (type == typeof(DateTime) && new DateTime.from_iso8601(node.get_string(), null) != null);
|
|
|
- }
|
|
|
- if(node.get_value_type().is_a(typeof(bool))) {
|
|
|
- return type == typeof(bool);
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
- public bool is_null () {
|
|
|
- return node.is_null();
|
|
|
- }
|
|
|
- public bool try_get_as<T> (out T result) {
|
|
|
- if(!assignable_to<T>()) {
|
|
|
- result = null;
|
|
|
- return false;
|
|
|
- }
|
|
|
- if(typeof(T) == typeof(Json.Node)) {
|
|
|
- result = node;
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(node.is_null ()) {
|
|
|
- result = null;
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T) == typeof(JsonArray) || typeof(T) == typeof(Invercargill.Elements)) {
|
|
|
- result = new JsonArray.from_existing (node.get_array ());
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T) == typeof(Json.Array)) {
|
|
|
- result = node.get_array();
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T) == typeof(JsonObject) || typeof(T) == typeof(Invercargill.Properties)) {
|
|
|
- result = new JsonObject.from_existing (node.get_object());
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T) == typeof(Json.Object)) {
|
|
|
- result = node.get_object();
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T).is_a(typeof(uint8))) {
|
|
|
- result = (uint8)node.get_int();
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T).is_a(typeof(int8))) {
|
|
|
- result = (int8)node.get_int();
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T).is_a(typeof(uint16))) {
|
|
|
- result = (uint16)node.get_int();
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T).is_a(typeof(int16))) {
|
|
|
- result = (int16)node.get_int();
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T).is_a(typeof(uint32))) {
|
|
|
- result = (uint32)node.get_int();
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T).is_a(typeof(int32))) {
|
|
|
- result = (int32)node.get_int();
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T).is_a(typeof(uint64))) {
|
|
|
- uint64? r = node.get_int();
|
|
|
- result = r;
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T).is_a(typeof(int64))) {
|
|
|
- int64? r = node.get_int();
|
|
|
- result = r;
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T).is_a(typeof(double))) {
|
|
|
- double? r = node.get_double();
|
|
|
- result = r;
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T).is_a(typeof(float))) {
|
|
|
- float? r = (float)node.get_double();
|
|
|
- result = r;
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T).is_a(typeof(string))) {
|
|
|
- if(node.get_value_type().is_a (typeof(double))) {
|
|
|
- result = node.get_double().to_string();
|
|
|
- }
|
|
|
- else if(node.get_value_type().is_a(typeof(int64))) {
|
|
|
- result = node.get_int().to_string();
|
|
|
- }
|
|
|
- result = node.get_string();
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T).is_a(typeof(DateTime))) {
|
|
|
- result = new DateTime.from_iso8601(node.get_string (), null);
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T).is_a(typeof(Invercargill.BinaryData))) {
|
|
|
- result = new Invercargill.BinaryData.from_base64(node.get_string ());
|
|
|
- return true;
|
|
|
- }
|
|
|
- if(typeof(T).is_a(typeof(bool))) {
|
|
|
- result = node.get_boolean();
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- warning(@"Type \"$(typeof(T).name())\" passed assignable check but the conversion is not implemented");
|
|
|
- result = null;
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- public GLib.Type? type () {
|
|
|
- return typeof(Json.Node);
|
|
|
- }
|
|
|
-
|
|
|
- public string stringify(bool pretty = false) {
|
|
|
- return Json.to_string (node, pretty);
|
|
|
- }
|
|
|
-
|
|
|
- public void write_to_stream(OutputStream stream) throws Error {
|
|
|
- var gen = new Json.Generator();
|
|
|
- gen.set_root (node);
|
|
|
- gen.to_stream (stream);
|
|
|
- }
|
|
|
-
|
|
|
- public void write_to_file(string path) throws Error {
|
|
|
- var gen = new Json.Generator();
|
|
|
- gen.set_root (node);
|
|
|
- gen.to_file (path);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-}
|