diff --git a/CMakeLists.txt b/CMakeLists.txt index abb5e18..1fde87b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,8 @@ endif() include(FindLibXml2) find_package(LibXml2 REQUIRED) -target_link_libraries(tmx LibXml2::LibXml2) +include_directories(${LIBXML2_INCLUDE_DIR}) +list(APPEND libs ${LIBXML2_LIBRARIES}) # -- Build diff --git a/src/tmx_xml.c b/src/tmx_xml.c index dd1521d..a21392d 100644 --- a/src/tmx_xml.c +++ b/src/tmx_xml.c @@ -13,6 +13,21 @@ #include "tmx.h" #include "tmx_utils.h" +/* + - Loaders - + This functions override the default XML loaders if you want to use an external filesystem instead. + */ + +xmlTextReaderPtr (*tmx_xml_reader_load_func) (const char *path, const char *encoding, int options) = NULL; +void (*tmx_xml_reader_free_func) (xmlTextReaderPtr reader) = NULL; + +static void +set_xml_functions(void) +{ + if (!tmx_xml_reader_load_func) { tmx_xml_reader_load_func = xmlReaderForFile; } + if (!tmx_xml_reader_free_func) { tmx_xml_reader_free_func = xmlFreeTextReader; } +} + /* - Parsers - Each function is called when the XML reader is on an element @@ -239,6 +254,8 @@ static int parse_object(xmlTextReaderPtr reader, tmx_object *obj, int is_on_map, resource_holder *tmpl; xmlTextReaderPtr sub_reader; + set_xml_functions(); + /* parses each attribute */ if ((value = (char*)xmlTextReaderGetAttribute(reader, (xmlChar*)"id"))) { /* id */ obj->id = atoi(value); @@ -273,7 +290,7 @@ static int parse_object(xmlTextReaderPtr reader, tmx_object *obj, int is_on_map, } if (!(obj->template_ref)) { if (!(ab_path = mk_absolute_path(filename, value))) return 0; - if (!(sub_reader = xmlReaderForFile(ab_path, NULL, 0))) { /* opens */ + if (!(sub_reader = tmx_xml_reader_load_func(ab_path, NULL, 0))) { /* opens */ tmx_err(E_XDATA, "xml parser: cannot open object template file '%s'", ab_path); tmx_free_func(ab_path); tmx_free_func(value); @@ -836,6 +853,8 @@ static int parse_tileset_list(xmlTextReaderPtr reader, tmx_tileset_list **ts_hea char *value, *ab_path; xmlTextReaderPtr sub_reader; + set_xml_functions(); + if (!(res_list = alloc_tileset_list())) return 0; res_list->next = *ts_headadr; *ts_headadr = res_list; @@ -873,13 +892,14 @@ static int parse_tileset_list(xmlTextReaderPtr reader, tmx_tileset_list **ts_hea res_list->is_embedded = 1; } if (!(ab_path = mk_absolute_path(filename, value))) return 0; - if (!(sub_reader = xmlReaderForFile(ab_path, NULL, 0)) || !check_reader(sub_reader)) { /* opens */ + tmx_free_func(value); + if (!(sub_reader = tmx_xml_reader_load_func(ab_path, NULL, 0)) || !check_reader(sub_reader)) { /* opens */ tmx_err(E_XDATA, "xml parser: cannot open extern tileset '%s'", ab_path); tmx_free_func(ab_path); return 0; } ret = parse_tileset(sub_reader, res, rc_mgr, ab_path); /* and parses the tsx file */ - xmlFreeTextReader(sub_reader); + tmx_xml_reader_free_func(sub_reader); tmx_free_func(ab_path); return ret; } @@ -1037,6 +1057,8 @@ static tmx_map* parse_map_document(xmlTextReaderPtr reader, tmx_resource_manager tmx_map *res = NULL; char *name; + set_xml_functions(); + if (check_reader(reader)) { /* DTD before root element */ if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_DOCUMENT_TYPE) @@ -1056,7 +1078,7 @@ static tmx_map* parse_map_document(xmlTextReaderPtr reader, tmx_resource_manager } } cleanup: - xmlFreeTextReader(reader); + tmx_xml_reader_free_func(reader); return res; } @@ -1064,6 +1086,8 @@ static tmx_tileset* parse_tileset_document(xmlTextReaderPtr reader, const char * tmx_tileset *res = NULL; char *name; + set_xml_functions(); + if (check_reader(reader)) { name = (char*) xmlTextReaderConstName(reader); if (strcmp(name, "tileset")) { @@ -1077,7 +1101,7 @@ static tmx_tileset* parse_tileset_document(xmlTextReaderPtr reader, const char * } } } - xmlFreeTextReader(reader); + tmx_xml_reader_free_func(reader); return res; } @@ -1085,6 +1109,8 @@ static tmx_template* parse_template_document(xmlTextReaderPtr reader, tmx_resour tmx_template *res = NULL; char *name; + set_xml_functions(); + if (check_reader(reader)) { name = (char*) xmlTextReaderConstName(reader); if (strcmp(name, "template")) { @@ -1098,7 +1124,7 @@ static tmx_template* parse_template_document(xmlTextReaderPtr reader, tmx_resour } } } - xmlFreeTextReader(reader); + tmx_xml_reader_free_func(reader); return res; } @@ -1111,8 +1137,9 @@ tmx_map *parse_xml(tmx_resource_manager *rc_mgr, const char *filename) { tmx_map *res = NULL; setup_libxml_mem(); + set_xml_functions(); - if ((reader = xmlReaderForFile(filename, NULL, 0))) { + if ((reader = tmx_xml_reader_load_func(filename, NULL, 0))) { res = parse_map_document(reader, rc_mgr, filename); } else { tmx_err(E_UNKN, "xml parser: unable to open %s", filename); @@ -1175,8 +1202,9 @@ tmx_tileset* parse_tsx_xml(const char *filename) { tmx_tileset *res = NULL; setup_libxml_mem(); + set_xml_functions(); - if ((reader = xmlReaderForFile(filename, NULL, 0))) { + if ((reader = tmx_xml_reader_load_func(filename, NULL, 0))) { res = parse_tileset_document(reader, filename); } else { tmx_err(E_UNKN, "xml parser: unable to open %s", filename); @@ -1239,8 +1267,9 @@ tmx_template* parse_tx_xml(tmx_resource_manager *rc_mgr, const char *filename) { tmx_template *res = NULL; setup_libxml_mem(); + set_xml_functions(); - if ((reader = xmlReaderForFile(filename, NULL, 0))) { + if ((reader = tmx_xml_reader_load_func(filename, NULL, 0))) { res = parse_template_document(reader, rc_mgr, filename); } else { tmx_err(E_UNKN, "xml parser: unable to open %s", filename); diff --git a/src/tmx_xml.h b/src/tmx_xml.h new file mode 100644 index 0000000..4b3ff9a --- /dev/null +++ b/src/tmx_xml.h @@ -0,0 +1,23 @@ +#ifndef TMX_XML_H +#define TMX_XML_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "tmx.h" + +#include + +/* + - Loaders - + This functions override the default XML loaders if you want to use an external filesystem instead. + */ +TMXEXPORT extern xmlTextReaderPtr (*tmx_xml_reader_load_func) (const char *path, const char *encoding, int options); +TMXEXPORT extern void (*tmx_xml_reader_free_func) (xmlTextReaderPtr reader); + +#ifdef __cplusplus +} +#endif + +#endif