entity_resolver.c
An example of an implementation of a FAXPP_ExternalEntityCallback function.
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "entity_resolver.h"
char *resolve_paths(const char *base, unsigned int base_len, const char *path, unsigned int path_len)
{
char *result = malloc(base_len + path_len + 1);
char *ptr = result;
strncpy(ptr, base, base_len);
ptr += base_len - 1;
while(ptr >= result && *ptr != '/') {
--ptr;
}
++ptr;
strncpy(ptr, path, path_len);
ptr += path_len;
*ptr = 0;
return result;
}
unsigned int file_read_callback(void *userData, void *buffer, unsigned int length)
{
unsigned int result = fread(buffer, 1, length, (FILE*)userData);
if(result < length) {
fclose((FILE*)userData);
}
return result;
}
FAXPP_Error entity_callback(void *userData, FAXPP_Parser *parser, FAXPP_EntityType type,
const FAXPP_Text *base_uri, const FAXPP_Text *system, const FAXPP_Text *public)
{
FAXPP_Error err;
FILE *file;
char *path;
path = resolve_paths((char*)base_uri->ptr, base_uri->len, (char*)system->ptr, system->len);
file = fopen(path, "r");
if(file == 0) {
return CANT_LOCATE_EXTERNAL_ENTITY;
}
err = FAXPP_parse_external_entity_callback(parser, type, file_read_callback, file);
if(err == NO_ERROR)
err = FAXPP_set_base_uri_str(parser, path);
free(path);
return err;
}