commit fcfeefe314ac14302941aa0a05095df1fd690e84
parent f05ad706815ae3c0915d540f345a973fe92e838f
Author: Dan Callaghan <djc@djc.id.au>
Date: Sat, 21 Jul 2012 21:20:19 +1000
new method to return literal value converted to a suitable glib type
Diffstat:
4 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
@@ -13,7 +13,7 @@ REQUIRES = glib-2.0 gobject-2.0 raptor2 redland
CC = gcc
CFLAGS ?= -g -O -Wall
-CFLAGS += -fPIC -std=c99 $(shell pkg-config --cflags $(REQUIRES))
+CFLAGS += -fPIC -std=c99 -D_XOPEN_SOURCE $(shell pkg-config --cflags $(REQUIRES))
LD = gcc
LDFLAGS ?= -Wl,--as-needed -Wl,-O1
LIBS = $(shell pkg-config --libs $(REQUIRES))
diff --git a/glibrdf.c b/glibrdf.c
@@ -1,4 +1,6 @@
+#include <stdbool.h>
+#include <time.h>
#include "glibrdf.h"
GType librdf_node_get_gtype(void) {
@@ -11,3 +13,55 @@ GType librdf_node_get_gtype(void) {
}
return _librdf_node_type_id;
}
+
+// glib should do this for me >:(
+static GDate *parse_iso8601_date(const gchar *s) {
+ struct tm tm;
+ if (*strptime(s, "%Y-%m-%d", &tm) != '\0')
+ return NULL;
+ return g_date_new_dmy(tm.tm_mday, 1 + tm.tm_mon, 1900 + tm.tm_year);
+}
+
+// XXX handle parse failures more gracefully?
+// XXX should have some kind of registry so that callers can add new types
+void librdf_node_get_literal_gvalue(librdf_node *node, GValue *value_out) {
+ g_return_if_fail(librdf_node_is_literal(node));
+ const gchar *lv = (const gchar *)librdf_node_get_literal_value(node);
+ g_return_if_fail(lv != NULL);
+ librdf_uri *datatype_uri = librdf_node_get_literal_value_datatype_uri(node);
+ if (datatype_uri == NULL) {
+ g_value_init(value_out, G_TYPE_STRING);
+ g_value_set_string(value_out, lv);
+ return;
+ }
+ const gchar *datatype_uri_string =
+ (const gchar *)librdf_uri_as_string(datatype_uri);
+ if (g_strcmp0(datatype_uri_string,
+ "http://www.w3.org/2001/XMLSchema#integer") == 0) {
+ g_value_init(value_out, G_TYPE_INT64);
+ gchar *lv_unconsumed;
+ g_value_set_int64(value_out, g_ascii_strtoll(lv, &lv_unconsumed, 10));
+ g_return_if_fail(*lv_unconsumed == '\0');
+ return;
+ }
+ if (g_strcmp0(datatype_uri_string,
+ "http://www.w3.org/TR/xmlschema-2/#date") == 0) {
+ GDate *date = parse_iso8601_date(lv);
+ g_return_if_fail(date != NULL);
+ g_value_init(value_out, G_TYPE_DATE);
+ g_value_set_boxed(value_out, date);
+ return;
+ }
+ if (g_strcmp0(datatype_uri_string,
+ "http://www.w3.org/TR/xmlschema-2/#datetime") == 0) {
+ GTimeVal tv;
+ bool parsed = g_time_val_from_iso8601(lv, &tv);
+ g_return_if_fail(parsed);
+ g_value_init(value_out, G_TYPE_DATE_TIME);
+ g_value_set_boxed(value_out, g_date_time_new_from_timeval_utc(&tv));
+ return;
+ }
+ g_warning("Unhandled RDF type %s", librdf_uri_as_string(datatype_uri));
+ g_value_init(value_out, G_TYPE_STRING);
+ g_value_set_string(value_out, lv);
+}
diff --git a/glibrdf.h b/glibrdf.h
@@ -7,5 +7,6 @@
GType librdf_node_get_gtype(void);
#define G_TYPE_RDF_NODE librdf_node_get_gtype()
+void librdf_node_get_literal_gvalue(librdf_node *node, GValue *value_out);
#endif
diff --git a/glibrdf.vapi b/glibrdf.vapi
@@ -449,6 +449,8 @@ namespace Rdf {
public bool get_literal_value_is_wf_xml ();
[CCode (cname = "librdf_node_get_literal_value_datatype_uri")]
public unowned Uri? get_literal_value_datatype_uri ();
+ [CCode (cname = "librdf_node_get_literal_gvalue")]
+ public GLib.Value get_literal_gvalue();
[CCode (cname = "librdf_node_get_li_ordinal")]
public int get_li_ordinal ();