summaryrefslogtreecommitdiffstats
path: root/src/raptor_serialize.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/raptor_serialize.c')
-rw-r--r--src/raptor_serialize.c791
1 files changed, 791 insertions, 0 deletions
diff --git a/src/raptor_serialize.c b/src/raptor_serialize.c
new file mode 100644
index 0000000..bf9f81e
--- /dev/null
+++ b/src/raptor_serialize.c
@@ -0,0 +1,791 @@
+/* -*- Mode: c; c-basic-offset: 2 -*-
+ *
+ * raptor_serialize.c - Raptor Serializer API
+ *
+ * Copyright (C) 2004-2010, David Beckett http://www.dajobe.org/
+ * Copyright (C) 2004-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
+
+#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 "raptor2.h"
+#include "raptor_internal.h"
+
+
+/* prototypes for helper functions */
+static raptor_serializer_factory* raptor_get_serializer_factory(raptor_world* world, const char *name);
+
+
+/* helper methods */
+
+static void
+raptor_free_serializer_factory(raptor_serializer_factory* factory)
+{
+ RAPTOR_ASSERT_OBJECT_POINTER_RETURN(factory, raptor_serializer_factory);
+
+ if(factory->finish_factory)
+ factory->finish_factory(factory);
+
+ RAPTOR_FREE(raptor_serializer_factory, factory);
+}
+
+
+/* class methods */
+
+int
+raptor_serializers_init(raptor_world* world)
+{
+ int rc = 0;
+
+ world->serializers = raptor_new_sequence((raptor_data_free_handler)raptor_free_serializer_factory, NULL);
+ if(!world->serializers)
+ return 1;
+
+#ifdef RAPTOR_SERIALIZER_NTRIPLES
+ rc += raptor_init_serializer_ntriples(world) != 0;
+#endif
+
+#ifdef RAPTOR_SERIALIZER_TURTLE
+ rc += raptor_init_serializer_turtle(world) != 0;
+#endif
+
+#ifdef RAPTOR_SERIALIZER_MKR
+ rc += raptor_init_serializer_mkr(world) != 0;
+#endif
+
+#ifdef RAPTOR_SERIALIZER_RDFXML_ABBREV
+ rc += raptor_init_serializer_rdfxmla(world) != 0;
+#endif
+
+#ifdef RAPTOR_SERIALIZER_RDFXML
+ rc += raptor_init_serializer_rdfxml(world) != 0;
+#endif
+
+#ifdef RAPTOR_SERIALIZER_RSS_1_0
+ rc += raptor_init_serializer_rss10(world) != 0;
+#endif
+
+#ifdef RAPTOR_SERIALIZER_ATOM
+ rc += raptor_init_serializer_atom(world) != 0;
+#endif
+
+#ifdef RAPTOR_SERIALIZER_DOT
+ rc += raptor_init_serializer_dot(world) != 0;
+#endif
+
+#ifdef RAPTOR_SERIALIZER_JSON
+ rc += raptor_init_serializer_json(world) != 0;
+#endif
+
+#ifdef RAPTOR_SERIALIZER_HTML
+ rc += raptor_init_serializer_html(world) != 0;
+#endif
+
+#ifdef RAPTOR_SERIALIZER_NQUADS
+ rc += raptor_init_serializer_nquads(world) != 0;
+#endif
+
+ return rc;
+}
+
+
+/*
+ * raptor_serializers_finish - delete all the registered serializers
+ */
+void
+raptor_serializers_finish(raptor_world* world)
+{
+ if(world->serializers) {
+ raptor_free_sequence(world->serializers);
+ world->serializers = NULL;
+ }
+}
+
+
+/*
+ * raptor_serializer_register_factory:
+ * @world: raptor_world object
+ * @name: the short syntax name
+ * @label: readable label for syntax
+ * @mime_type: MIME type of the syntax generated by the serializer (or NULL)
+ * @uri_string: URI string of the syntax (or NULL)
+ * @factory: pointer to function to call to register the factory
+ *
+ * INTERNAL - Register a syntax that can be generated by a serializer factory
+ *
+ * Return value: non-0 on failure
+ **/
+RAPTOR_EXTERN_C
+raptor_serializer_factory*
+raptor_serializer_register_factory(raptor_world* world,
+ int (*factory) (raptor_serializer_factory*))
+{
+ raptor_serializer_factory *serializer;
+
+ serializer = RAPTOR_CALLOC(raptor_serializer_factory*, 1, sizeof(*serializer));
+ if(!serializer)
+ return NULL;
+
+ serializer->world = world;
+
+ serializer->desc.mime_types = NULL;
+
+ if(raptor_sequence_push(world->serializers, serializer))
+ return NULL; /* on error, serializer is already freed by the sequence */
+
+ /* Call the serializer registration function on the new object */
+ if(factory(serializer))
+ return NULL; /* serializer is owned and freed by the serializers sequence */
+
+ if(raptor_syntax_description_validate(&serializer->desc)) {
+ raptor_log_error(world, RAPTOR_LOG_LEVEL_ERROR, NULL,
+ "Serializer description failed to validate\n");
+ goto tidy;
+ }
+
+#if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1
+ RAPTOR_DEBUG2("Registered serializer %s\n", serializer->desc.names[0]);
+#endif
+
+ return serializer;
+
+ /* Clean up on failure */
+ tidy:
+ raptor_free_serializer_factory(serializer);
+ return NULL;
+}
+
+
+/**
+ * raptor_get_serializer_factory:
+ * @world: raptor_world object
+ * @name: the factory name or NULL for the default factory
+ *
+ * Get a serializer factory by name.
+ *
+ * Return value: the factory object or NULL if there is no such factory
+ **/
+static raptor_serializer_factory*
+raptor_get_serializer_factory(raptor_world* world, const char *name)
+{
+ raptor_serializer_factory *factory = NULL;
+
+ RAPTOR_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, raptor_world, NULL);
+
+ raptor_world_open(world);
+
+ /* return 1st serializer if no particular one wanted - why? */
+ if(!name) {
+ factory = (raptor_serializer_factory *)raptor_sequence_get_at(world->serializers, 0);
+ if(!factory) {
+ RAPTOR_DEBUG1("No (default) serializers registered\n");
+ return NULL;
+ }
+ } else {
+ int i;
+
+ for(i = 0;
+ (factory = (raptor_serializer_factory*)raptor_sequence_get_at(world->serializers, i));
+ i++) {
+ int namei;
+ const char* fname;
+
+ for(namei = 0; (fname = factory->desc.names[namei]); namei++) {
+ if(!strcmp(fname, name))
+ break;
+ }
+ if(fname)
+ break;
+ }
+ }
+
+ return factory;
+}
+
+
+/**
+ * raptor_world_get_serializers_count:
+ * @world: world object
+ *
+ * Get number of serializers
+ *
+ * Return value: number of serializers or <0 on failure
+ **/
+int
+raptor_world_get_serializers_count(raptor_world* world)
+{
+ RAPTOR_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, raptor_world, -1);
+
+ raptor_world_open(world);
+
+ return raptor_sequence_size(world->serializers);
+}
+
+
+/**
+ * raptor_world_get_serializer_description:
+ * @world: world object
+ * @counter: index into the list of serializers
+ *
+ * Get serializer descriptive syntax information
+ *
+ * Return value: description or NULL if counter is out of range
+ **/
+const raptor_syntax_description*
+raptor_world_get_serializer_description(raptor_world* world,
+ unsigned int counter)
+{
+ raptor_serializer_factory *factory;
+
+ RAPTOR_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, raptor_world, NULL);
+
+ raptor_world_open(world);
+
+ factory = (raptor_serializer_factory*)raptor_sequence_get_at(world->serializers,
+ counter);
+
+ if(!factory)
+ return NULL;
+
+ return &factory->desc;
+}
+
+
+/**
+ * raptor_world_is_serializer_name:
+ * @world: raptor_world object
+ * @name: the syntax name
+ *
+ * Check name of a serializer.
+ *
+ * Return value: non 0 if name is a known syntax name
+ */
+int
+raptor_world_is_serializer_name(raptor_world* world, const char *name)
+{
+ if(!name)
+ return 0;
+
+ RAPTOR_ASSERT_OBJECT_POINTER_RETURN_VALUE(world, raptor_world, 0);
+
+ raptor_world_open(world);
+
+ return (raptor_get_serializer_factory(world, name) != NULL);
+}
+
+
+/**
+ * raptor_new_serializer:
+ * @world: raptor_world object
+ * @name: the serializer name or NULL for default syntax
+ *
+ * Constructor - create a new raptor_serializer object.
+ *
+ * Return value: a new #raptor_serializer object or NULL on failure
+ */
+raptor_serializer*
+raptor_new_serializer(raptor_world* world, const char *name)
+{
+ raptor_serializer_factory* factory;
+ raptor_serializer* rdf_serializer;
+
+ RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);
+
+ raptor_world_open(world);
+
+ factory = raptor_get_serializer_factory(world, name);
+ if(!factory)
+ return NULL;
+
+ rdf_serializer = RAPTOR_CALLOC(raptor_serializer*, 1, sizeof(*rdf_serializer));
+ if(!rdf_serializer)
+ return NULL;
+
+ rdf_serializer->world = world;
+
+ rdf_serializer->context = RAPTOR_CALLOC(void*, 1, factory->context_length);
+ if(!rdf_serializer->context) {
+ raptor_free_serializer(rdf_serializer);
+ return NULL;
+ }
+
+ rdf_serializer->factory = factory;
+
+ raptor_object_options_init(&rdf_serializer->options,
+ RAPTOR_OPTION_AREA_SERIALIZER);
+
+ if(factory->init(rdf_serializer, name)) {
+ raptor_free_serializer(rdf_serializer);
+ return NULL;
+ }
+
+ return rdf_serializer;
+}
+
+
+/**
+ * raptor_serializer_start_to_iostream:
+ * @rdf_serializer: the #raptor_serializer
+ * @uri: base URI or NULL if no base URI is required
+ * @iostream: #raptor_iostream to write serialization to
+ *
+ * Start serialization to an iostream with given base URI
+ *
+ * The passed in @iostream does not become owned by the serializer
+ * and can be used by the caller after serializing is done. It
+ * must be destroyed by the caller.
+ *
+ * Return value: non-0 on failure.
+ **/
+int
+raptor_serializer_start_to_iostream(raptor_serializer *rdf_serializer,
+ raptor_uri *uri, raptor_iostream *iostream)
+{
+ if(rdf_serializer->base_uri)
+ raptor_free_uri(rdf_serializer->base_uri);
+
+ if(!iostream)
+ return 1;
+
+ if(uri)
+ uri = raptor_uri_copy(uri);
+
+ rdf_serializer->base_uri = uri;
+ rdf_serializer->locator.uri = uri;
+ rdf_serializer->locator.line = rdf_serializer->locator.column = 0;
+
+ rdf_serializer->iostream = iostream;
+
+ rdf_serializer->free_iostream_on_end = 0;
+
+ if(rdf_serializer->factory->serialize_start)
+ return rdf_serializer->factory->serialize_start(rdf_serializer);
+ return 0;
+}
+
+
+/**
+ * raptor_serializer_start_to_filename:
+ * @rdf_serializer: the #raptor_serializer
+ * @filename: filename to serialize to
+ *
+ * Start serializing to a filename.
+ *
+ * Return value: non-0 on failure.
+ **/
+int
+raptor_serializer_start_to_filename(raptor_serializer *rdf_serializer,
+ const char *filename)
+{
+ unsigned char *uri_string = raptor_uri_filename_to_uri_string(filename);
+ if(!uri_string)
+ return 1;
+
+ if(rdf_serializer->base_uri)
+ raptor_free_uri(rdf_serializer->base_uri);
+
+ rdf_serializer->base_uri = raptor_new_uri(rdf_serializer->world, uri_string);
+ rdf_serializer->locator.uri = rdf_serializer->base_uri;
+ rdf_serializer->locator.line = rdf_serializer->locator.column = 0;
+
+ RAPTOR_FREE(char*, uri_string);
+
+ rdf_serializer->iostream = raptor_new_iostream_to_filename(rdf_serializer->world,
+ filename);
+ if(!rdf_serializer->iostream)
+ return 1;
+
+ rdf_serializer->free_iostream_on_end = 1;
+
+ if(rdf_serializer->factory->serialize_start)
+ return rdf_serializer->factory->serialize_start(rdf_serializer);
+ return 0;
+}
+
+
+
+/**
+ * raptor_serializer_start_to_string:
+ * @rdf_serializer: the #raptor_serializer
+ * @uri: base URI or NULL if no base URI is required
+ * @string_p: pointer to location to hold string
+ * @length_p: pointer to location to hold length of string (or NULL)
+ *
+ * Start serializing to a string.
+ *
+ * Return value: non-0 on failure.
+ **/
+int
+raptor_serializer_start_to_string(raptor_serializer *rdf_serializer,
+ raptor_uri *uri,
+ void **string_p, size_t *length_p)
+{
+ if(rdf_serializer->base_uri)
+ raptor_free_uri(rdf_serializer->base_uri);
+
+ if(uri)
+ rdf_serializer->base_uri = raptor_uri_copy(uri);
+ else
+ rdf_serializer->base_uri = NULL;
+ rdf_serializer->locator.uri = rdf_serializer->base_uri;
+ rdf_serializer->locator.line = rdf_serializer->locator.column = 0;
+
+
+ rdf_serializer->iostream = raptor_new_iostream_to_string(rdf_serializer->world,
+ string_p, length_p,
+ NULL);
+ if(!rdf_serializer->iostream)
+ return 1;
+
+ rdf_serializer->free_iostream_on_end = 1;
+
+ if(rdf_serializer->factory->serialize_start)
+ return rdf_serializer->factory->serialize_start(rdf_serializer);
+ return 0;
+}
+
+
+/**
+ * raptor_serializer_start_to_file_handle:
+ * @rdf_serializer: the #raptor_serializer
+ * @uri: base URI or NULL if no base URI is required
+ * @fh: FILE* to serialize to
+ *
+ * Start serializing to a FILE*.
+ *
+ * NOTE: This does not fclose the handle when it is finished.
+ *
+ * Return value: non-0 on failure.
+ **/
+int
+raptor_serializer_start_to_file_handle(raptor_serializer *rdf_serializer,
+ raptor_uri *uri, FILE *fh)
+{
+ if(rdf_serializer->base_uri)
+ raptor_free_uri(rdf_serializer->base_uri);
+
+ if(uri)
+ rdf_serializer->base_uri = raptor_uri_copy(uri);
+ else
+ rdf_serializer->base_uri = NULL;
+ rdf_serializer->locator.uri = rdf_serializer->base_uri;
+ rdf_serializer->locator.line = rdf_serializer->locator.column = 0;
+
+ rdf_serializer->iostream = raptor_new_iostream_to_file_handle(rdf_serializer->world, fh);
+ if(!rdf_serializer->iostream)
+ return 1;
+
+ rdf_serializer->free_iostream_on_end = 1;
+
+ if(rdf_serializer->factory->serialize_start)
+ return rdf_serializer->factory->serialize_start(rdf_serializer);
+ return 0;
+}
+
+
+/**
+ * raptor_serializer_set_namespace:
+ * @rdf_serializer: the #raptor_serializer
+ * @uri: #raptor_uri of namespace or NULL
+ * @prefix: prefix to use or NULL
+ *
+ * set a namespace uri/prefix mapping for serializing.
+ *
+ * return value: non-0 on failure.
+ **/
+int
+raptor_serializer_set_namespace(raptor_serializer* rdf_serializer,
+ raptor_uri *uri, const unsigned char *prefix)
+{
+ if(prefix && !*prefix)
+ prefix = NULL;
+
+ if(rdf_serializer->factory->declare_namespace)
+ return rdf_serializer->factory->declare_namespace(rdf_serializer,
+ uri, prefix);
+
+ return 1;
+}
+
+
+/**
+ * raptor_serializer_set_namespace_from_namespace:
+ * @rdf_serializer: the #raptor_serializer
+ * @nspace: #raptor_namespace to set
+ *
+ * Set a namespace uri/prefix mapping for serializing from an existing namespace.
+ *
+ * Return value: non-0 on failure.
+ **/
+int
+raptor_serializer_set_namespace_from_namespace(raptor_serializer* rdf_serializer,
+ raptor_namespace *nspace)
+{
+ if(rdf_serializer->factory->declare_namespace_from_namespace)
+ return rdf_serializer->factory->declare_namespace_from_namespace(rdf_serializer,
+ nspace);
+ else if(rdf_serializer->factory->declare_namespace)
+ return rdf_serializer->factory->declare_namespace(rdf_serializer,
+ raptor_namespace_get_uri(nspace),
+ raptor_namespace_get_prefix(nspace));
+
+ return 1;
+}
+
+
+/**
+ * raptor_serializer_serialize_statement:
+ * @rdf_serializer: the #raptor_serializer
+ * @statement: #raptor_statement to serialize to a syntax
+ *
+ * Serialize a statement.
+ *
+ * Return value: non-0 on failure.
+ **/
+int
+raptor_serializer_serialize_statement(raptor_serializer* rdf_serializer,
+ raptor_statement *statement)
+{
+ if(!rdf_serializer->iostream)
+ return 1;
+
+ return rdf_serializer->factory->serialize_statement(rdf_serializer,
+ statement);
+}
+
+
+/**
+ * raptor_serializer_serialize_end:
+ * @rdf_serializer: the #raptor_serializer
+ *
+ * End a serialization.
+ *
+ * Return value: non-0 on failure.
+ **/
+int
+raptor_serializer_serialize_end(raptor_serializer *rdf_serializer)
+{
+ int rc;
+
+ if(!rdf_serializer->iostream)
+ return 1;
+
+ if(rdf_serializer->factory->serialize_end)
+ rc = rdf_serializer->factory->serialize_end(rdf_serializer);
+ else
+ rc = 0;
+
+ if(rdf_serializer->iostream) {
+ if(rdf_serializer->free_iostream_on_end)
+ raptor_free_iostream(rdf_serializer->iostream);
+ rdf_serializer->iostream = NULL;
+ }
+ return rc;
+}
+
+
+
+/**
+ * raptor_free_serializer:
+ * @rdf_serializer: #raptor_serializer object
+ *
+ * Destructor - destroy a raptor_serializer object.
+ *
+ **/
+void
+raptor_free_serializer(raptor_serializer* rdf_serializer)
+{
+ if(!rdf_serializer)
+ return;
+
+ if(rdf_serializer->factory)
+ rdf_serializer->factory->terminate(rdf_serializer);
+
+ if(rdf_serializer->context)
+ RAPTOR_FREE(raptor_serializer_context, rdf_serializer->context);
+
+ if(rdf_serializer->base_uri)
+ raptor_free_uri(rdf_serializer->base_uri);
+
+ raptor_object_options_clear(&rdf_serializer->options);
+
+ RAPTOR_FREE(raptor_serializer, rdf_serializer);
+}
+
+
+/**
+ * raptor_serializer_get_iostream:
+ * @serializer: #raptor_serializer object
+ *
+ * Get the current serializer iostream.
+ *
+ * Return value: the serializer's current iostream or NULL if
+ **/
+raptor_iostream*
+raptor_serializer_get_iostream(raptor_serializer *serializer)
+{
+ return serializer->iostream;
+}
+
+
+/**
+ * raptor_serializer_set_option:
+ * @serializer: #raptor_serializer serializer object
+ * @option: option to set from enumerated #raptor_option values
+ * @string: string option value (or NULL)
+ * @integer: integer option value
+ *
+ * Set serializer option.
+ *
+ * If @string is not NULL and the option type is numeric, the string
+ * value is converted to an integer and used in preference to @integer.
+ *
+ * If @string is NULL and the option type is not numeric, an error is
+ * returned.
+ *
+ * The @string values used are copied.
+ *
+ * The allowed options are available via
+ * raptor_world_get_option_description().
+ *
+ * Return value: non 0 on failure or if the option is unknown
+ **/
+int
+raptor_serializer_set_option(raptor_serializer *serializer,
+ raptor_option option,
+ const char* string, int integer)
+{
+ return raptor_object_options_set_option(&serializer->options, option,
+ string, integer);
+}
+
+
+/**
+ * raptor_serializer_get_option:
+ * @serializer: #raptor_serializer serializer object
+ * @option: option to get value
+ * @string_p: pointer to where to store string value
+ * @integer_p: pointer to where to store integer value
+ *
+ * Get serializer option.
+ *
+ * Any string value returned in *@string_p is shared and must
+ * be copied by the caller.
+ *
+ * The allowed options are available via
+ * raptor_world_get_option_description().
+ *
+ * Return value: option value or < 0 for an illegal option
+ **/
+int
+raptor_serializer_get_option(raptor_serializer *serializer,
+ raptor_option option,
+ char** string_p, int* integer_p)
+{
+ return raptor_object_options_get_option(&serializer->options, option,
+ string_p, integer_p);
+}
+
+
+/**
+ * raptor_serializer_get_locator:
+ * @rdf_serializer: raptor serializer
+ *
+ * Get the serializer raptor locator object.
+ *
+ * Return value: raptor locator
+ **/
+raptor_locator*
+raptor_serializer_get_locator(raptor_serializer *rdf_serializer)
+{
+ return &rdf_serializer->locator;
+}
+
+
+/**
+ * raptor_serializer_get_world:
+ * @rdf_serializer: raptor serializer
+ *
+ * Get the #raptor_world object associated with a serializer.
+ *
+ * Return value: raptor_world* pointer
+ **/
+raptor_world *
+raptor_serializer_get_world(raptor_serializer* rdf_serializer)
+{
+ return rdf_serializer->world;
+}
+
+
+/**
+ * raptor_serializer_get_description:
+ * @rdf_serializer: #raptor_serializer serializer object
+ *
+ * Get description of the syntaxes of the serializer.
+ *
+ * The returned description is static and lives as long as the raptor
+ * library (raptor world).
+ *
+ * Return value: description of syntax
+ **/
+const raptor_syntax_description*
+raptor_serializer_get_description(raptor_serializer *rdf_serializer)
+{
+ return &rdf_serializer->factory->desc;
+}
+
+
+/**
+ * raptor_serializer_flush:
+ * @rdf_serializer: raptor serializer
+ *
+ * Flush the current serializer output and free any pending state
+ *
+ * In serializers that can generate blocks of content, this causes
+ * the writing of any current pending block. For example in Turtle
+ * this may write all pending triples.
+ *
+ * Return value: non-0 on failure
+ **/
+int
+raptor_serializer_flush(raptor_serializer *rdf_serializer)
+{
+ int rc;
+
+ if(rdf_serializer->factory->serialize_flush)
+ rc = rdf_serializer->factory->serialize_flush(rdf_serializer);
+ else
+ rc = 0;
+
+ return rc;
+}