diff options
Diffstat (limited to 'src/raptor_serialize.c')
-rw-r--r-- | src/raptor_serialize.c | 791 |
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; +} |