structures.
#include "output_event.h"
#define SHOW_URIS 0
#define SHOW_ENTITIES 0
void
output_text(const FAXPP_Text *text, FILE *stream)
{
char *buffer = (char*)text->ptr;
char *buffer_end = buffer + text->len;
while(buffer < buffer_end) {
putc(*buffer++, stream);
}
}
void
output_escaped_attr_text(const FAXPP_Text *text, FILE *stream)
{
char *buffer = (char*)text->ptr;
char *buffer_end = buffer + text->len;
while(buffer < buffer_end) {
if(*buffer == '&') {
fprintf(stream, "&");
}
else if(*buffer == '<') {
fprintf(stream, "<");
}
else if(*buffer == '"') {
fprintf(stream, """);
}
else {
putc(*buffer, stream);
}
++buffer;
}
}
void output_attr_value(const FAXPP_AttrValue *atval, FILE *stream)
{
while(atval) {
switch(atval->type) {
case CHARACTERS_EVENT:
output_escaped_attr_text(&atval->value, stream);
break;
case ENTITY_REFERENCE_EVENT:
fprintf(stream, "&");
output_text(&atval->name, stream);
fprintf(stream, ";");
break;
case DEC_CHAR_REFERENCE_EVENT:
fprintf(stream, "&#");
output_text(&atval->name, stream);
fprintf(stream, ";");
break;
case HEX_CHAR_REFERENCE_EVENT:
fprintf(stream, "&#x");
output_text(&atval->name, stream);
fprintf(stream, ";");
break;
case ENTITY_REFERENCE_START_EVENT:
#if SHOW_ENTITIES
fprintf(stream, "&");
output_text(&atval->name, stream);
fprintf(stream, ";(");
#endif
break;
case ENTITY_REFERENCE_END_EVENT:
#if SHOW_ENTITIES
fprintf(stream, ")");
#endif
break;
default:
break;
}
atval = atval->next;
}
}
void
output_event(const FAXPP_Event *event, FILE *stream)
{
int i;
switch(event->type) {
case START_DOCUMENT_EVENT:
if(event->version.ptr != 0) {
fprintf(stream, "<?xml version=\"");
output_text(&event->version, stream);
if(event->encoding.ptr != 0) {
fprintf(stream, "\" encoding=\"");
output_text(&event->encoding, stream);
}
if(event->standalone.ptr != 0) {
fprintf(stream, "\" standalone=\"");
output_text(&event->standalone, stream);
}
fprintf(stream, "\"?>");
}
break;
case END_DOCUMENT_EVENT:
break;
case DOCTYPE_EVENT:
fprintf(stream, "<!DOCTYPE ");
if(event->prefix.ptr != 0) {
output_text(&event->prefix, stream);
fprintf(stream, ":");
}
output_text(&event->name, stream);
if(event->system_id.ptr != 0) {
if(event->public_id.ptr != 0) {
fprintf(stream, " PUBLIC \"");
output_text(&event->public_id, stream);
fprintf(stream, "\" \"");
output_text(&event->system_id, stream);
fprintf(stream, "\"");
}
else {
fprintf(stream, " SYSTEM \"");
output_text(&event->system_id, stream);
fprintf(stream, "\"");
}
}
fprintf(stream, ">");
break;
case START_ELEMENT_EVENT:
case SELF_CLOSING_ELEMENT_EVENT:
fprintf(stream, "<");
#if SHOW_URIS
if(event->uri.ptr != 0) {
fprintf(stream, "{");
output_text(&event->uri, stream);
fprintf(stream, "}");
} else
#endif
if(event->prefix.ptr != 0) {
output_text(&event->prefix, stream);
fprintf(stream, ":");
}
output_text(&event->name, stream);
for(i = 0; i < event->attr_count; ++i) {
fprintf(stream, " ");
#if SHOW_URIS
if(event->attrs[i].uri.ptr != 0) {
fprintf(stream, "{");
output_text(&event->attrs[i].uri, stream);
fprintf(stream, "}");
} else
#endif
if(event->attrs[i].prefix.ptr != 0) {
output_text(&event->attrs[i].prefix, stream);
fprintf(stream, ":");
}
output_text(&event->attrs[i].name, stream);
fprintf(stream, "=\"");
output_attr_value(&event->attrs[i].value, stream);
fprintf(stream, "\"");
}
if(event->type == SELF_CLOSING_ELEMENT_EVENT)
fprintf(stream, "/>");
else
fprintf(stream, ">");
break;
case END_ELEMENT_EVENT:
fprintf(stream, "</");
#if SHOW_URIS
if(event->uri.ptr != 0) {
fprintf(stream, "{");
output_text(&event->uri, stream);
fprintf(stream, "}");
} else
#endif
if(event->prefix.ptr != 0) {
output_text(&event->prefix, stream);
fprintf(stream, ":");
}
output_text(&event->name, stream);
fprintf(stream, ">");
break;
case CHARACTERS_EVENT:
output_text(&event->value, stream);
break;
case CDATA_EVENT:
fprintf(stream, "<![CDATA[");
output_text(&event->value, stream);
fprintf(stream, "]]>");
break;
case IGNORABLE_WHITESPACE_EVENT:
output_text(&event->value, stream);
break;
case COMMENT_EVENT:
fprintf(stream, "<!--");
output_text(&event->value, stream);
fprintf(stream, "-->");
break;
case PI_EVENT:
fprintf(stream, "<?");
output_text(&event->name, stream);
if(event->value.ptr != 0) {
fprintf(stream, " ");
output_text(&event->value, stream);
}
fprintf(stream, "?>");
break;
case ENTITY_REFERENCE_EVENT:
fprintf(stream, "&");
output_text(&event->name, stream);
fprintf(stream, ";");
break;
case DEC_CHAR_REFERENCE_EVENT:
fprintf(stream, "&#");
output_text(&event->name, stream);
fprintf(stream, ";");
break;
case HEX_CHAR_REFERENCE_EVENT:
fprintf(stream, "&#x");
output_text(&event->name, stream);
fprintf(stream, ";");
break;
case ENTITY_REFERENCE_START_EVENT:
#if SHOW_ENTITIES
fprintf(stream, "&");
output_text(&event->name, stream);
fprintf(stream, ";(");
#endif
break;
case ENTITY_REFERENCE_END_EVENT:
#if SHOW_ENTITIES
fprintf(stream, ")");
#endif
break;
case START_EXTERNAL_ENTITY_EVENT:
case END_EXTERNAL_ENTITY_EVENT:
case NO_EVENT:
break;
}
}