Add gres:// type links support for libxml2

This commit is contained in:
Gergely Polonkai 2014-07-12 10:27:11 +02:00
parent a5d76beb23
commit c31ddb6fe7
1 changed files with 108 additions and 0 deletions

View File

@ -20,6 +20,7 @@
GtkBuilder *builder;
GtkFileFilter *filter_all = NULL;
GtkFileFilter *filter_chart = NULL;
GHashTable *xinclude_positions;
const char *moonStateName[] = {
"New Moon",
@ -47,6 +48,100 @@ init_filters(void)
g_object_ref_sink(filter_chart);
}
static int
xml_match_gresource(const char *uri)
{
if ((uri != NULL) && (!strncmp("gres://", uri, 7))) {
g_debug("Matched gres:// type link.");
return 1;
} else {
return 0;
}
}
static void *
xml_open_gresource(const gchar *uri)
{
gchar *path;
GBytes *res_location;
gsize *position;
if ((uri == NULL) || (strncmp("gres://", uri, 7))) {
return NULL;
}
path = g_strdup_printf("/eu/polonkai/gergely/Astrognome/%s", uri + 7);
g_debug("Opening gresource %s", path);
res_location = g_resources_lookup_data(
path,
G_RESOURCE_LOOKUP_FLAGS_NONE,
NULL
);
g_free(path);
if ((position = g_hash_table_lookup(xinclude_positions, res_location)) == NULL) {
g_hash_table_insert(xinclude_positions, res_location, g_new0(gsize, 1));
} else {
g_warning("Reopening gres:// link?");
*position = 0;
}
return res_location;
}
static int
xml_close_gresource(void *context)
{
if (context == NULL) {
return -1;
}
g_debug("Closing gres:// link");
g_hash_table_remove(xinclude_positions, context);
g_bytes_unref((GBytes *)context);
return 0;
}
static int
xml_read_gresource(void *context, char *buffer, int len)
{
const gchar *data;
gsize max_length;
GBytes *data_holder = (GBytes *)context;
gsize *position;
if ((context == NULL) || (buffer == NULL) || (len < 0)) {
return -1;
}
data = g_bytes_get_data(data_holder, &max_length);
position = g_hash_table_lookup(xinclude_positions, data_holder);
if (position == NULL) {
g_warning("Trying to read non-opened gres:// link!");
return -1;
}
if (*position >= max_length) {
return 0;
}
if (len > max_length - *position) {
len = max_length - *position;
}
memcpy(buffer, data + *position, len);
g_debug("Read %d bytes", len);
*position += len;
return len;
}
int
main(int argc, char *argv[])
{
@ -89,10 +184,22 @@ main(int argc, char *argv[])
LIBXML_TEST_VERSION;
xmlSubstituteEntitiesDefault(1);
xmlLoadExtDtdDefaultValue = 1;
xmlRegisterInputCallbacks(
xml_match_gresource,
xml_open_gresource,
xml_read_gresource,
xml_close_gresource
);
xsltInit();
xsltSetXIncludeDefault(1);
exsltRegisterAll();
gswe_init();
xinclude_positions = g_hash_table_new_full(
g_bytes_hash,
g_bytes_equal,
(GDestroyNotify)g_bytes_unref,
(GDestroyNotify)g_free
);
memset(&options, 0, sizeof(AstrognomeOptions));
@ -135,6 +242,7 @@ main(int argc, char *argv[])
status = g_application_run(G_APPLICATION(app), argc, argv);
g_hash_table_destroy(xinclude_positions);
g_object_unref(app);
return status;