1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-25 17:08:07 +02:00
audacity/lib-src/libraptor/src/raptor_xml_writer.c
2010-01-24 09:19:39 +00:00

1182 lines
35 KiB
C

/* -*- Mode: c; c-basic-offset: 2 -*-
*
* raptor_xml_writer.c - Raptor XML Writer for SAX2 events API
*
* Copyright (C) 2003-2006, David Beckett http://purl.org/net/dajobe/
* Copyright (C) 2003-2005, University of Bristol, UK http://www.bristol.ac.uk/
*
* This package is Free Software and part of Redland http://librdf.org/
*
* It is licensed under the following three licenses as alternatives:
* 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
* 2. GNU General Public License (GPL) V2 or any newer version
* 3. Apache License, V2.0 or any newer version
*
* You may not use this file except in compliance with at least one of
* the above three licenses.
*
* See LICENSE.html or LICENSE.txt at the top of this package for the
* complete terms and further detail along with the license texts for
* the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
*
*
*/
#ifdef HAVE_CONFIG_H
#include <raptor_config.h>
#endif
#ifdef WIN32
#include <win32_raptor_config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
/* Raptor includes */
#include "raptor.h"
#include "raptor_internal.h"
#ifndef STANDALONE
typedef enum {
XML_WRITER_AUTO_INDENT = 1,
XML_WRITER_AUTO_EMPTY = 2
} raptor_xml_writer_flags;
#define XML_WRITER_AUTO_INDENT(xml_writer) ((xml_writer->flags & XML_WRITER_AUTO_INDENT) != 0)
#define XML_WRITER_AUTO_EMPTY(xml_writer) ((xml_writer->flags & XML_WRITER_AUTO_EMPTY) != 0)
#define XML_WRITER_FLUSH_CLOSE_BRACKET(xml_writer) \
if ((xml_writer->flags & XML_WRITER_AUTO_EMPTY) && \
xml_writer->current_element && \
!(xml_writer->current_element->content_cdata_seen || \
xml_writer->current_element->content_element_seen)) { \
raptor_iostream_write_byte(xml_writer->iostr, '>'); \
}
/* Define this for far too much output */
#undef RAPTOR_DEBUG_CDATA
struct raptor_xml_writer_s {
int canonicalize;
int depth;
int my_nstack;
raptor_namespace_stack *nstack;
int nstack_depth;
const raptor_uri_handler *uri_handler;
void *uri_context;
raptor_simple_message_handler error_handler;
void *error_data;
raptor_xml_element* current_element;
/* outputting to this iostream */
raptor_iostream *iostr;
/* XML Writer flags - bits defined in enum raptor_xml_writer_flags */
int flags;
/* indentation per level if formatting */
int indent;
/* XML 1.0 (10) or XML 1.1 (11) */
int xml_version;
/* Write XML 1.0 or 1.1 declaration (default 1) */
int xml_declaration;
/* Has writing the XML declaration writing been checked? */
int xml_declaration_checked;
};
/* 16 spaces */
#define SPACES_BUFFER_SIZE sizeof(spaces_buffer)
static const unsigned char spaces_buffer[] = {
' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ',
' ', ' ', ' ', ' '
};
/* helper functions */
static int
raptor_xml_writer_indent(raptor_xml_writer *xml_writer)
{
int num_spaces;
num_spaces = xml_writer->depth * xml_writer->indent;
/* Do not write an extra newline at the start of the document
* (after the XML declaration or XMP processing instruction has
* been writtten)
*/
if(xml_writer->xml_declaration_checked == 1)
xml_writer->xml_declaration_checked++;
else
raptor_iostream_write_byte(xml_writer->iostr, '\n');
while (num_spaces > 0) {
int count = (num_spaces > (int)SPACES_BUFFER_SIZE) ? (int)SPACES_BUFFER_SIZE : num_spaces;
raptor_iostream_write_counted_string(xml_writer->iostr, spaces_buffer, count);
num_spaces -= count;
}
if(xml_writer->current_element)
xml_writer->current_element->content_cdata_seen=1;
return 0;
}
struct nsd {
const raptor_namespace *nspace;
unsigned char *declaration;
size_t length;
};
/*
* FIXME: This is duplicate code taken from raptor_sax2.c:
* struct nsd
* raptor_xml_writer_nsd_compare (from raptor_nsd_compare)
*/
static int
raptor_xml_writer_nsd_compare(const void *a, const void *b)
{
struct nsd* nsd_a=(struct nsd*)a;
struct nsd* nsd_b=(struct nsd*)b;
return strcmp((const char*)nsd_a->declaration, (const char*)nsd_b->declaration);
}
static int
raptor_iostream_write_xml_element_start(raptor_iostream* iostr,
raptor_xml_element *element,
raptor_namespace_stack *nstack,
raptor_simple_message_handler error_handler,
void *error_data,
int auto_empty,
int depth,
int xml_version)
{
struct nsd *nspace_declarations=NULL;
size_t nspace_declarations_count=0;
unsigned int i;
/* max is 1 per element and 1 for each attribute + size of declared */
if(nstack) {
int nspace_max_count=element->attribute_count+1;
if(element->declared_nspaces)
nspace_max_count += raptor_sequence_size(element->declared_nspaces);
nspace_declarations=(struct nsd*)RAPTOR_CALLOC(nsdarray, nspace_max_count, sizeof(struct nsd));
if(!nspace_declarations)
return 1;
}
if(element->name->nspace) {
if(nstack && !raptor_namespaces_namespace_in_scope(nstack, element->name->nspace)) {
nspace_declarations[0].declaration=
raptor_namespaces_format(element->name->nspace,
&nspace_declarations[0].length);
if(!nspace_declarations[0].declaration)
goto error;
nspace_declarations[0].nspace=element->name->nspace;
nspace_declarations_count++;
}
}
if (element->attributes) {
for(i=0; i < element->attribute_count; i++) {
/* qname */
if(element->attributes[i]->nspace) {
if(nstack &&
!raptor_namespaces_namespace_in_scope(nstack, element->attributes[i]->nspace) && element->attributes[i]->nspace != element->name->nspace) {
/* not in scope and not same as element (so already going to be declared)*/
unsigned int j;
int declare_me=1;
/* check it wasn't an earlier declaration too */
for (j=0; j < nspace_declarations_count; j++)
if(nspace_declarations[j].nspace == element->attributes[j]->nspace) {
declare_me=0;
break;
}
if(declare_me) {
nspace_declarations[nspace_declarations_count].declaration=
raptor_namespaces_format(element->attributes[i]->nspace,
&nspace_declarations[nspace_declarations_count].length);
if(!nspace_declarations[nspace_declarations_count].declaration)
goto error;
nspace_declarations[nspace_declarations_count].nspace=element->attributes[i]->nspace;
nspace_declarations_count++;
}
}
}
}
}
if(nstack && element->declared_nspaces &&
raptor_sequence_size(element->declared_nspaces) > 0) {
for(i=0; i< (unsigned int)raptor_sequence_size(element->declared_nspaces); i++) {
raptor_namespace* nspace=(raptor_namespace*)raptor_sequence_get_at(element->declared_nspaces, i);
unsigned int j;
int declare_me=1;
/* check it wasn't an earlier declaration too */
for (j=0; j < nspace_declarations_count; j++)
if(nspace_declarations[j].nspace == nspace) {
declare_me=0;
break;
}
if(declare_me) {
nspace_declarations[nspace_declarations_count].declaration=
raptor_namespaces_format(nspace,
&nspace_declarations[nspace_declarations_count].length);
if(!nspace_declarations[nspace_declarations_count].declaration)
goto error;
nspace_declarations[nspace_declarations_count].nspace=nspace;
nspace_declarations_count++;
}
}
}
raptor_iostream_write_byte(iostr, '<');
if(element->name->nspace && element->name->nspace->prefix_length > 0) {
raptor_iostream_write_counted_string(iostr,
(const char*)element->name->nspace->prefix,
element->name->nspace->prefix_length);
raptor_iostream_write_byte(iostr, ':');
}
raptor_iostream_write_counted_string(iostr,
(const char*)element->name->local_name,
element->name->local_name_length);
/* declare namespaces */
if(nspace_declarations_count) {
/* sort them into the canonical order */
qsort((void*)nspace_declarations,
nspace_declarations_count, sizeof(struct nsd),
raptor_xml_writer_nsd_compare);
/* add them */
for (i=0; i < nspace_declarations_count; i++) {
raptor_iostream_write_byte(iostr, ' ');
raptor_iostream_write_counted_string(iostr,
(const char*)nspace_declarations[i].declaration,
nspace_declarations[i].length);
RAPTOR_FREE(cstring, nspace_declarations[i].declaration);
nspace_declarations[i].declaration=NULL;
if(raptor_namespace_copy(nstack,
(raptor_namespace*)nspace_declarations[i].nspace,
depth))
goto error;
}
}
if(element->attributes) {
for(i=0; i < element->attribute_count; i++) {
raptor_iostream_write_byte(iostr, ' ');
if(element->attributes[i]->nspace &&
element->attributes[i]->nspace->prefix_length > 0) {
raptor_iostream_write_counted_string(iostr,
(char*)element->attributes[i]->nspace->prefix,
element->attributes[i]->nspace->prefix_length);
raptor_iostream_write_byte(iostr, ':');
}
raptor_iostream_write_counted_string(iostr,
(const char*)element->attributes[i]->local_name,
element->attributes[i]->local_name_length);
raptor_iostream_write_counted_string(iostr, "=\"", 2);
raptor_iostream_write_xml_any_escaped_string(iostr,
element->attributes[i]->value,
element->attributes[i]->value_length,
'"',
xml_version,
error_handler, error_data);
raptor_iostream_write_byte(iostr, '"');
}
}
if (!auto_empty)
raptor_iostream_write_byte(iostr, '>');
if(nstack)
RAPTOR_FREE(stringarray, nspace_declarations);
return 0;
/* Clean up nspace_declarations on error */
error:
for (i=0; i < nspace_declarations_count; i++) {
if(nspace_declarations[i].declaration)
RAPTOR_FREE(cstring, nspace_declarations[i].declaration);
}
if(nspace_declarations)
RAPTOR_FREE(stringarray, nspace_declarations);
return 1;
}
static int
raptor_iostream_write_xml_element_end(raptor_iostream* iostr,
raptor_xml_element *element,
int is_empty)
{
if (is_empty)
raptor_iostream_write_byte(iostr, '/');
else {
raptor_iostream_write_byte(iostr, '<');
raptor_iostream_write_byte(iostr, '/');
if(element->name->nspace && element->name->nspace->prefix_length > 0) {
raptor_iostream_write_counted_string(iostr,
(const char*)element->name->nspace->prefix,
element->name->nspace->prefix_length);
raptor_iostream_write_byte(iostr, ':');
}
raptor_iostream_write_counted_string(iostr,
(const char*)element->name->local_name,
element->name->local_name_length);
}
raptor_iostream_write_byte(iostr, '>');
return 0;
}
/**
* raptor_new_xml_writer:
* @nstack: Namespace stack for the writer to start with (or NULL)
* @uri_handler: URI handler function
* @uri_context: URI handler context data
* @iostr: I/O stream to write to
* @error_handler: error handler function
* @error_data: error handler data
* @canonicalize: unused
*
* Constructor - Create a new XML Writer writing XML to a raptor_iostream
*
* Return value: a new #raptor_xml_writer object or NULL on failure
**/
raptor_xml_writer*
raptor_new_xml_writer(raptor_namespace_stack *nstack,
const raptor_uri_handler *uri_handler,
void *uri_context,
raptor_iostream* iostr,
raptor_simple_message_handler error_handler,
void *error_data,
int canonicalize)
{
raptor_xml_writer* xml_writer;
xml_writer=(raptor_xml_writer*)RAPTOR_CALLOC(raptor_xml_writer, 1, sizeof(raptor_xml_writer)+1);
if(!xml_writer)
return NULL;
xml_writer->nstack_depth=0;
xml_writer->uri_handler=uri_handler;
xml_writer->uri_context=uri_context;
xml_writer->error_handler=error_handler;
xml_writer->error_data=error_data;
xml_writer->nstack=nstack;
if(!xml_writer->nstack) {
xml_writer->nstack=nstack=raptor_new_namespaces(uri_handler, uri_context,
error_handler, error_data,
1);
xml_writer->my_nstack=1;
}
xml_writer->iostr=iostr;
xml_writer->flags = 0;
xml_writer->indent = 2;
xml_writer->xml_version = 10;
/* Write XML declaration */
xml_writer->xml_declaration=1;
return xml_writer;
}
/**
* raptor_free_xml_writer:
* @xml_writer: XML writer object
*
* Destructor - Free XML Writer
*
**/
void
raptor_free_xml_writer(raptor_xml_writer* xml_writer)
{
if(xml_writer->nstack && xml_writer->my_nstack)
raptor_free_namespaces(xml_writer->nstack);
RAPTOR_FREE(raptor_xml_writer, xml_writer);
}
static void
raptor_xml_writer_write_xml_declaration(raptor_xml_writer* xml_writer)
{
if(!xml_writer->xml_declaration_checked) {
/* check that it should be written once only */
xml_writer->xml_declaration_checked=1;
if(xml_writer->xml_declaration) {
raptor_iostream_write_string(xml_writer->iostr,
(const unsigned char*)"<?xml version=\"");
raptor_iostream_write_counted_string(xml_writer->iostr,
(xml_writer->xml_version == 10) ?
(const unsigned char*)"1.0" :
(const unsigned char*)"1.1",
3);
raptor_iostream_write_string(xml_writer->iostr,
(const unsigned char*)"\" encoding=\"utf-8\"?>\n");
}
}
}
/**
* raptor_xml_writer_empty_element:
* @xml_writer: XML writer object
* @element: XML element object
*
* Write an empty XML element to the XML writer.
*
* Closes any previous empty element if XML writer feature AUTO_EMPTY
* is enabled.
**/
void
raptor_xml_writer_empty_element(raptor_xml_writer* xml_writer,
raptor_xml_element *element)
{
raptor_xml_writer_write_xml_declaration(xml_writer);
XML_WRITER_FLUSH_CLOSE_BRACKET(xml_writer);
raptor_iostream_write_xml_element_start(xml_writer->iostr,
element,
xml_writer->nstack,
xml_writer->error_handler,
xml_writer->error_data,
1,
xml_writer->depth,
xml_writer->xml_version);
raptor_iostream_write_xml_element_end(xml_writer->iostr, element, 1);
raptor_namespaces_end_for_depth(xml_writer->nstack, xml_writer->depth);
}
/**
* raptor_xml_writer_start_element:
* @xml_writer: XML writer object
* @element: XML element object
*
* Write a start XML element to the XML writer.
*
* Closes any previous empty element if XML writer feature AUTO_EMPTY
* is enabled.
*
* Indents the start element if XML writer feature AUTO_INDENT is enabled.
**/
void
raptor_xml_writer_start_element(raptor_xml_writer* xml_writer,
raptor_xml_element *element)
{
raptor_xml_writer_write_xml_declaration(xml_writer);
XML_WRITER_FLUSH_CLOSE_BRACKET(xml_writer);
if(XML_WRITER_AUTO_INDENT(xml_writer))
raptor_xml_writer_indent(xml_writer);
raptor_iostream_write_xml_element_start(xml_writer->iostr,
element,
xml_writer->nstack,
xml_writer->error_handler,
xml_writer->error_data,
XML_WRITER_AUTO_EMPTY(xml_writer),
xml_writer->depth,
xml_writer->xml_version);
xml_writer->depth++;
/* SJS Note: This "if" clause is necessary because raptor_rdfxml.c
* uses xml_writer for parseType="literal" and passes in elements
* whose parent field is already set. The first time this function
* is called, it sets element->parent to 0, causing the warn-07.rdf
* test to fail. Subsequent calls to this function set
* element->parent to its existing value.
*/
if (xml_writer->current_element)
element->parent = xml_writer->current_element;
xml_writer->current_element=element;
if(element && element->parent)
element->parent->content_element_seen=1;
}
/**
* raptor_xml_writer_end_element:
* @xml_writer: XML writer object
* @element: XML element object
*
* Write an end XML element to the XML writer.
*
* Indents the end element if XML writer feature AUTO_INDENT is enabled.
**/
void
raptor_xml_writer_end_element(raptor_xml_writer* xml_writer,
raptor_xml_element* element)
{
int is_empty;
xml_writer->depth--;
if (XML_WRITER_AUTO_INDENT(xml_writer) && element->content_element_seen)
raptor_xml_writer_indent(xml_writer);
is_empty = XML_WRITER_AUTO_EMPTY(xml_writer) ?
!(element->content_cdata_seen || element->content_element_seen) : 0;
raptor_iostream_write_xml_element_end(xml_writer->iostr, element, is_empty);
raptor_namespaces_end_for_depth(xml_writer->nstack, xml_writer->depth);
if(xml_writer->current_element)
xml_writer->current_element = xml_writer->current_element->parent;
}
/**
* raptor_xml_writer_cdata:
* @xml_writer: XML writer object
* @s: string to XML escape and write
*
* Write CDATA XML-escaped to the XML writer.
*
* Closes any previous empty element if XML writer feature AUTO_EMPTY
* is enabled.
*
**/
void
raptor_xml_writer_cdata(raptor_xml_writer* xml_writer,
const unsigned char *s)
{
raptor_xml_writer_write_xml_declaration(xml_writer);
XML_WRITER_FLUSH_CLOSE_BRACKET(xml_writer);
raptor_iostream_write_xml_any_escaped_string(xml_writer->iostr,
s, strlen((const char*)s),
'\0',
xml_writer->xml_version,
xml_writer->error_handler,
xml_writer->error_data);
if(xml_writer->current_element)
xml_writer->current_element->content_cdata_seen=1;
}
/**
* raptor_xml_writer_cdata_counted:
* @xml_writer: XML writer object
* @s: string to XML escape and write
* @len: length of string
*
* Write counted CDATA XML-escaped to the XML writer.
*
* Closes any previous empty element if XML writer feature AUTO_EMPTY
* is enabled.
*
**/
void
raptor_xml_writer_cdata_counted(raptor_xml_writer* xml_writer,
const unsigned char *s, unsigned int len)
{
raptor_xml_writer_write_xml_declaration(xml_writer);
XML_WRITER_FLUSH_CLOSE_BRACKET(xml_writer);
raptor_iostream_write_xml_any_escaped_string(xml_writer->iostr,
s, len,
'\0',
xml_writer->xml_version,
xml_writer->error_handler,
xml_writer->error_data);
if(xml_writer->current_element)
xml_writer->current_element->content_cdata_seen=1;
}
/**
* raptor_xml_writer_raw:
* @xml_writer: XML writer object
* @s: string to write
*
* Write a string raw to the XML writer.
*
* Closes any previous empty element if XML writer feature AUTO_EMPTY
* is enabled.
*
**/
void
raptor_xml_writer_raw(raptor_xml_writer* xml_writer,
const unsigned char *s)
{
raptor_xml_writer_write_xml_declaration(xml_writer);
XML_WRITER_FLUSH_CLOSE_BRACKET(xml_writer);
raptor_iostream_write_string(xml_writer->iostr, s);
if(xml_writer->current_element)
xml_writer->current_element->content_cdata_seen=1;
}
/**
* raptor_xml_writer_raw_counted:
* @xml_writer: XML writer object
* @s: string to write
* @len: length of string
*
* Write a counted string raw to the XML writer.
*
* Closes any previous empty element if XML writer feature AUTO_EMPTY
* is enabled.
*
**/
void
raptor_xml_writer_raw_counted(raptor_xml_writer* xml_writer,
const unsigned char *s, unsigned int len)
{
raptor_xml_writer_write_xml_declaration(xml_writer);
XML_WRITER_FLUSH_CLOSE_BRACKET(xml_writer);
raptor_iostream_write_counted_string(xml_writer->iostr, s, len);
if(xml_writer->current_element)
xml_writer->current_element->content_cdata_seen=1;
}
/**
* raptor_xml_writer_comment:
* @xml_writer: XML writer object
* @s: comment string to write
*
* Write an XML comment to the XML writer.
*
* Closes any previous empty element if XML writer feature AUTO_EMPTY
* is enabled.
*
**/
void
raptor_xml_writer_comment(raptor_xml_writer* xml_writer,
const unsigned char *s)
{
XML_WRITER_FLUSH_CLOSE_BRACKET(xml_writer);
raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"<!-- ", 5);
raptor_xml_writer_cdata(xml_writer, s);
raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" -->", 4);
}
/**
* raptor_xml_writer_comment_counted:
* @xml_writer: XML writer object
* @s: comment string to write
* @len: length of string
*
* Write a counted XML comment to the XML writer.
*
* Closes any previous empty element if XML writer feature AUTO_EMPTY
* is enabled.
*
**/
void
raptor_xml_writer_comment_counted(raptor_xml_writer* xml_writer,
const unsigned char *s, unsigned int len)
{
XML_WRITER_FLUSH_CLOSE_BRACKET(xml_writer);
raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"<!-- ", 5);
raptor_xml_writer_cdata_counted(xml_writer, s, len);
raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" -->", 4);
}
/**
* raptor_xml_writer_features_enumerate:
* @feature: feature enumeration (0+)
* @name: pointer to store feature short name (or NULL)
* @uri: pointer to store feature URI (or NULL)
* @label: pointer to feature label (or NULL)
*
* Get list of xml_writer features.
*
* If uri is not NULL, a pointer to a new raptor_uri is returned
* that must be freed by the caller with raptor_free_uri().
*
* Return value: 0 on success, <0 on failure, >0 if feature is unknown
**/
int
raptor_xml_writer_features_enumerate(const raptor_feature feature,
const char **name,
raptor_uri **uri, const char **label)
{
return raptor_features_enumerate_common(feature, name, uri, label, 8);
}
/**
* raptor_xml_writer_set_feature:
* @xml_writer: #raptor_xml_writer xml_writer object
* @feature: feature to set from enumerated #raptor_feature values
* @value: integer feature value (0 or larger)
*
* Set xml_writer features with integer values.
*
* The allowed features are available via raptor_features_enumerate().
*
* Return value: non 0 on failure or if the feature is unknown
**/
int
raptor_xml_writer_set_feature(raptor_xml_writer *xml_writer,
raptor_feature feature, int value)
{
if(value < 0)
return -1;
switch(feature) {
case RAPTOR_FEATURE_WRITER_AUTO_INDENT:
if (value)
xml_writer->flags |= XML_WRITER_AUTO_INDENT;
else
xml_writer->flags &= ~XML_WRITER_AUTO_INDENT;
break;
case RAPTOR_FEATURE_WRITER_AUTO_EMPTY:
if (value)
xml_writer->flags |= XML_WRITER_AUTO_EMPTY;
else
xml_writer->flags &= ~XML_WRITER_AUTO_EMPTY;
break;
case RAPTOR_FEATURE_WRITER_INDENT_WIDTH:
xml_writer->indent = value;
break;
case RAPTOR_FEATURE_WRITER_XML_VERSION:
if(value == 10 || value == 11)
xml_writer->xml_version = value;
break;
case RAPTOR_FEATURE_WRITER_XML_DECLARATION:
xml_writer->xml_declaration = value;
break;
/* parser features */
case RAPTOR_FEATURE_SCANNING:
case RAPTOR_FEATURE_ASSUME_IS_RDF:
case RAPTOR_FEATURE_ALLOW_NON_NS_ATTRIBUTES:
case RAPTOR_FEATURE_ALLOW_OTHER_PARSETYPES:
case RAPTOR_FEATURE_ALLOW_BAGID:
case RAPTOR_FEATURE_ALLOW_RDF_TYPE_RDF_LIST:
case RAPTOR_FEATURE_NORMALIZE_LANGUAGE:
case RAPTOR_FEATURE_NON_NFC_FATAL:
case RAPTOR_FEATURE_WARN_OTHER_PARSETYPES:
case RAPTOR_FEATURE_CHECK_RDF_ID:
case RAPTOR_FEATURE_HTML_TAG_SOUP:
case RAPTOR_FEATURE_MICROFORMATS:
case RAPTOR_FEATURE_HTML_LINK:
case RAPTOR_FEATURE_WWW_TIMEOUT:
/* Shared */
case RAPTOR_FEATURE_NO_NET:
/* XML writer features */
case RAPTOR_FEATURE_RELATIVE_URIS:
case RAPTOR_FEATURE_START_URI:
/* DOT serializer features */
case RAPTOR_FEATURE_RESOURCE_BORDER:
case RAPTOR_FEATURE_LITERAL_BORDER:
case RAPTOR_FEATURE_BNODE_BORDER:
case RAPTOR_FEATURE_RESOURCE_FILL:
case RAPTOR_FEATURE_LITERAL_FILL:
case RAPTOR_FEATURE_BNODE_FILL:
/* JSON serializer features */
case RAPTOR_FEATURE_JSON_CALLBACK:
case RAPTOR_FEATURE_JSON_EXTRA_DATA:
/* Turtle serializer feature */
case RAPTOR_FEATURE_WRITE_BASE_URI:
/* WWW feature */
case RAPTOR_FEATURE_WWW_HTTP_CACHE_CONTROL:
case RAPTOR_FEATURE_WWW_HTTP_USER_AGENT:
default:
return -1;
break;
}
return 0;
}
/**
* raptor_xml_writer_set_feature_string:
* @xml_writer: #raptor_xml_writer xml_writer object
* @feature: feature to set from enumerated #raptor_feature values
* @value: feature value
*
* Set xml_writer features with string values.
*
* The allowed features are available via raptor_xml_writer_features_enumerate().
* If the feature type is integer, the value is interpreted as an integer.
*
* Return value: non 0 on failure or if the feature is unknown
**/
int
raptor_xml_writer_set_feature_string(raptor_xml_writer *xml_writer,
raptor_feature feature,
const unsigned char *value)
{
int value_is_string=(raptor_feature_value_type(feature) == 1);
if(!value_is_string)
return raptor_xml_writer_set_feature(xml_writer, feature,
atoi((const char*)value));
else
return -1;
}
/**
* raptor_xml_writer_get_feature:
* @xml_writer: #raptor_xml_writer serializer object
* @feature: feature to get value
*
* Get various xml_writer features.
*
* The allowed features are available via raptor_features_enumerate().
*
* Note: no feature value is negative
*
* Return value: feature value or < 0 for an illegal feature
**/
int
raptor_xml_writer_get_feature(raptor_xml_writer *xml_writer,
raptor_feature feature)
{
int result= -1;
switch(feature) {
case RAPTOR_FEATURE_WRITER_AUTO_INDENT:
result=XML_WRITER_AUTO_INDENT(xml_writer);
break;
case RAPTOR_FEATURE_WRITER_AUTO_EMPTY:
result=XML_WRITER_AUTO_EMPTY(xml_writer);
break;
case RAPTOR_FEATURE_WRITER_INDENT_WIDTH:
result=xml_writer->indent;
break;
case RAPTOR_FEATURE_WRITER_XML_VERSION:
result=xml_writer->xml_version;
break;
case RAPTOR_FEATURE_WRITER_XML_DECLARATION:
result=xml_writer->xml_declaration;
break;
/* parser features */
case RAPTOR_FEATURE_SCANNING:
case RAPTOR_FEATURE_ASSUME_IS_RDF:
case RAPTOR_FEATURE_ALLOW_NON_NS_ATTRIBUTES:
case RAPTOR_FEATURE_ALLOW_OTHER_PARSETYPES:
case RAPTOR_FEATURE_ALLOW_BAGID:
case RAPTOR_FEATURE_ALLOW_RDF_TYPE_RDF_LIST:
case RAPTOR_FEATURE_NORMALIZE_LANGUAGE:
case RAPTOR_FEATURE_NON_NFC_FATAL:
case RAPTOR_FEATURE_WARN_OTHER_PARSETYPES:
case RAPTOR_FEATURE_CHECK_RDF_ID:
case RAPTOR_FEATURE_HTML_TAG_SOUP:
case RAPTOR_FEATURE_MICROFORMATS:
case RAPTOR_FEATURE_HTML_LINK:
case RAPTOR_FEATURE_WWW_TIMEOUT:
/* Shared */
case RAPTOR_FEATURE_NO_NET:
/* XML writer features */
case RAPTOR_FEATURE_RELATIVE_URIS:
case RAPTOR_FEATURE_START_URI:
/* DOT serializer features */
case RAPTOR_FEATURE_RESOURCE_BORDER:
case RAPTOR_FEATURE_LITERAL_BORDER:
case RAPTOR_FEATURE_BNODE_BORDER:
case RAPTOR_FEATURE_RESOURCE_FILL:
case RAPTOR_FEATURE_LITERAL_FILL:
case RAPTOR_FEATURE_BNODE_FILL:
/* JSON serializer features */
case RAPTOR_FEATURE_JSON_CALLBACK:
case RAPTOR_FEATURE_JSON_EXTRA_DATA:
/* Turtle serializer feature */
case RAPTOR_FEATURE_WRITE_BASE_URI:
/* WWW feature */
case RAPTOR_FEATURE_WWW_HTTP_CACHE_CONTROL:
case RAPTOR_FEATURE_WWW_HTTP_USER_AGENT:
default:
break;
}
return result;
}
/**
* raptor_xml_writer_get_feature_string:
* @xml_writer: #raptor_xml_writer serializer object
* @feature: feature to get value
*
* Get xml_writer features with string values.
*
* The allowed features are available via raptor_features_enumerate().
*
* Return value: feature value or NULL for an illegal feature or no value
**/
const unsigned char *
raptor_xml_writer_get_feature_string(raptor_xml_writer *xml_writer,
raptor_feature feature)
{
return NULL;
}
#endif
#ifdef STANDALONE
/* one more prototype */
int main(int argc, char *argv[]);
const unsigned char *base_uri_string=(const unsigned char*)"http://example.org/base#";
#define OUT_BYTES_COUNT 135
int
main(int argc, char *argv[])
{
const char *program=raptor_basename(argv[0]);
const raptor_uri_handler *uri_handler;
void *uri_context;
raptor_iostream *iostr;
raptor_namespace_stack *nstack;
raptor_namespace* foo_ns;
raptor_xml_writer* xml_writer;
raptor_uri* base_uri;
raptor_qname* el_name;
raptor_xml_element *element;
unsigned long offset;
raptor_qname **attrs;
raptor_uri* base_uri_copy=NULL;
/* for raptor_new_iostream_to_string */
void *string=NULL;
size_t string_len=0;
raptor_init();
iostr=raptor_new_iostream_to_string(&string, &string_len, NULL);
if(!iostr) {
fprintf(stderr, "%s: Failed to create iostream to string\n", program);
exit(1);
}
raptor_uri_get_handler(&uri_handler, &uri_context);
nstack=raptor_new_namespaces(uri_handler, uri_context,
NULL, NULL, /* errors */
1);
xml_writer=raptor_new_xml_writer(nstack,
uri_handler, uri_context,
iostr,
NULL, NULL, /* errors */
1);
if(!xml_writer) {
fprintf(stderr, "%s: Failed to create xml_writer to iostream\n", program);
exit(1);
}
base_uri=raptor_new_uri(base_uri_string);
foo_ns=raptor_new_namespace(nstack,
(const unsigned char*)"foo",
(const unsigned char*)"http://example.org/foo-ns#",
0);
el_name=raptor_new_qname_from_namespace_local_name(foo_ns,
(const unsigned char*)"bar",
NULL);
base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL;
element=raptor_new_xml_element(el_name,
NULL, /* language */
base_uri_copy);
raptor_xml_writer_start_element(xml_writer, element);
raptor_xml_writer_cdata_counted(xml_writer, (const unsigned char*)"hello\n", 6);
raptor_xml_writer_comment_counted(xml_writer, (const unsigned char*)"comment", 7);
raptor_xml_writer_cdata(xml_writer, (const unsigned char*)"\n");
raptor_xml_writer_end_element(xml_writer, element);
raptor_free_xml_element(element);
raptor_xml_writer_cdata(xml_writer, (const unsigned char*)"\n");
el_name=raptor_new_qname(nstack,
(const unsigned char*)"blah",
NULL, /* no attribute value - element */
NULL, NULL); /* errors */
base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL;
element=raptor_new_xml_element(el_name,
NULL, /* language */
base_uri_copy);
attrs=(raptor_qname **)RAPTOR_CALLOC(qnamearray, 1, sizeof(raptor_qname*));
attrs[0]=raptor_new_qname(nstack,
(const unsigned char*)"a",
(const unsigned char*)"b", /* attribute value */
NULL, NULL); /* errors */
raptor_xml_element_set_attributes(element, attrs, 1);
raptor_xml_writer_empty_element(xml_writer, element);
raptor_xml_writer_cdata(xml_writer, (const unsigned char*)"\n");
raptor_free_xml_writer(xml_writer);
raptor_free_xml_element(element);
raptor_free_namespace(foo_ns);
raptor_free_namespaces(nstack);
raptor_free_uri(base_uri);
offset=raptor_iostream_tell(iostr);
#if RAPTOR_DEBUG > 1
fprintf(stderr, "%s: Freeing iostream\n", program);
#endif
raptor_free_iostream(iostr);
if(offset != OUT_BYTES_COUNT) {
fprintf(stderr, "%s: I/O stream wrote %d bytes, expected %d\n", program,
(int)offset, (int)OUT_BYTES_COUNT);
fputs("[[", stderr);
(void)fwrite(string, 1, string_len, stderr);
fputs("]]\n", stderr);
return 1;
}
if(!string) {
fprintf(stderr, "%s: I/O stream failed to create a string\n", program);
return 1;
}
string_len=strlen((const char*)string);
if(string_len != offset) {
fprintf(stderr, "%s: I/O stream created a string length %d, expected %d\n", program, (int)string_len, (int)offset);
return 1;
}
#if RAPTOR_DEBUG > 1
fprintf(stderr, "%s: Made XML string of %d bytes\n", program, (int)string_len);
fputs("[[", stderr);
(void)fwrite(string, 1, string_len, stderr);
fputs("]]\n", stderr);
#endif
raptor_free_memory(string);
raptor_finish();
/* keep gcc -Wall happy */
return(0);
}
#endif