Add gres:// type links support for libxml2
This commit is contained in:
		
							
								
								
									
										108
									
								
								src/astrognome.c
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								src/astrognome.c
									
									
									
									
									
								
							| @@ -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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user