diff options
Diffstat (limited to 'src/raptor_json_writer.c')
-rw-r--r-- | src/raptor_json_writer.c | 345 |
1 files changed, 345 insertions, 0 deletions
diff --git a/src/raptor_json_writer.c b/src/raptor_json_writer.c new file mode 100644 index 0000000..dd57be0 --- /dev/null +++ b/src/raptor_json_writer.c @@ -0,0 +1,345 @@ +/* -*- Mode: c; c-basic-offset: 2 -*- + * + * raptor_json_writer.c - Raptor JSON Writer + * + * Copyright (C) 2008, David Beckett http://www.dajobe.org/ + * + * 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 +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + + +/* Raptor includes */ +#include "raptor2.h" +#include "raptor_internal.h" + +#ifndef STANDALONE + +struct raptor_json_writer_s { + raptor_world* world; + + raptor_uri* base_uri; + + /* outputting to this iostream */ + raptor_iostream *iostr; + + /* current indent */ + int indent; + + /* indent step */ + int indent_step; +}; + + + +/** + * raptor_new_json_writer: + * @world: raptor_world object + * @base_uri: Base URI for the writer + * @iostr: I/O stream to write to + * + * INTERNAL - Constructor - Create a new JSON writer writing to a raptor_iostream + * + * Return value: a new #raptor_json_writer object or NULL on failure + **/ +raptor_json_writer* +raptor_new_json_writer(raptor_world* world, + raptor_uri* base_uri, + raptor_iostream* iostr) +{ + raptor_json_writer* json_writer; + + json_writer = RAPTOR_CALLOC(raptor_json_writer*, 1, sizeof(*json_writer)); + + if(!json_writer) + return NULL; + + json_writer->world = world; + json_writer->iostr = iostr; + json_writer->base_uri = base_uri; + + json_writer->indent_step = 2; + + return json_writer; +} + + +/** + * raptor_free_json_writer: + * @json_writer: JSON writer object + * + * INTERNAL - Destructor - Free JSON Writer + * + **/ +void +raptor_free_json_writer(raptor_json_writer* json_writer) +{ + RAPTOR_ASSERT_OBJECT_POINTER_RETURN(json_writer, raptor_json_writer); + + RAPTOR_FREE(raptor_json_writer, json_writer); +} + + +static int +raptor_json_writer_quoted(raptor_json_writer* json_writer, + const char *value, size_t value_len) +{ + int rc = 0; + + if(!value) { + raptor_iostream_counted_string_write("\"\"", 2, json_writer->iostr); + return 0; + } + + raptor_iostream_write_byte('\"', json_writer->iostr); + rc = raptor_string_escaped_write((const unsigned char*)value, value_len, + '"', RAPTOR_ESCAPED_WRITE_JSON_LITERAL, + json_writer->iostr); + raptor_iostream_write_byte('\"', json_writer->iostr); + + return rc; +} + + +static int +raptor_json_writer_spaces(raptor_json_writer* json_writer, int depth) +{ + int i; + for(i = 0; i < depth; i++) + raptor_iostream_write_byte(' ', json_writer->iostr); + return 0; +} + + +int +raptor_json_writer_newline(raptor_json_writer* json_writer) +{ + raptor_iostream_write_byte('\n', json_writer->iostr); + if(json_writer->indent) + raptor_json_writer_spaces(json_writer, json_writer->indent); + return 0; +} + + +int +raptor_json_writer_key_value(raptor_json_writer* json_writer, + const char* key, size_t key_len, + const char* value, size_t value_len) +{ + if(!key_len && key) + key_len = strlen(key); + if(!value_len && value) + value_len = strlen(value); + + raptor_json_writer_quoted(json_writer, key, key_len); + raptor_iostream_counted_string_write(" : ", 3, json_writer->iostr); + raptor_json_writer_quoted(json_writer, value, value_len); + + return 0; +} + + +int +raptor_json_writer_key_uri_value(raptor_json_writer* json_writer, + const char* key, size_t key_len, + raptor_uri* uri) +{ + const char* value; + size_t value_len; + int rc = 0; + + value = (const char*)raptor_uri_to_relative_counted_uri_string(json_writer->base_uri, uri, &value_len); + if(!value) + return 1; + + if(key) + rc = raptor_json_writer_key_value(json_writer, key, key_len, + value, value_len); + else + rc = raptor_json_writer_quoted(json_writer, value, value_len); + + RAPTOR_FREE(char*, value); + + return rc; +} + + +int +raptor_json_writer_start_block(raptor_json_writer* json_writer, char c) +{ + json_writer->indent += json_writer->indent_step; + raptor_iostream_write_byte(c, json_writer->iostr); + return 0; +} + + +int +raptor_json_writer_end_block(raptor_json_writer* json_writer, char c) +{ + raptor_iostream_write_byte(c, json_writer->iostr); + json_writer->indent -= json_writer->indent_step; + return 0; +} + + +int +raptor_json_writer_literal_object(raptor_json_writer* json_writer, + unsigned char* s, size_t s_len, + unsigned char* lang, + raptor_uri* datatype) +{ + raptor_json_writer_start_block(json_writer, '{'); + raptor_json_writer_newline(json_writer); + + raptor_iostream_counted_string_write("\"value\" : ", 10, json_writer->iostr); + + raptor_json_writer_quoted(json_writer, (const char*)s, s_len); + + if(datatype || lang) { + raptor_iostream_write_byte(',', json_writer->iostr); + raptor_json_writer_newline(json_writer); + + if(datatype) + raptor_json_writer_key_uri_value(json_writer, "datatype", 8, datatype); + + if(lang) { + if(datatype) { + raptor_iostream_write_byte(',', json_writer->iostr); + raptor_json_writer_newline(json_writer); + } + + raptor_json_writer_key_value(json_writer, "lang", 4, + (const char*)lang, 0); + } + } + + raptor_iostream_write_byte(',', json_writer->iostr); + raptor_json_writer_newline(json_writer); + + raptor_json_writer_key_value(json_writer, "type", 4, "literal", 7); + + raptor_json_writer_newline(json_writer); + + raptor_json_writer_end_block(json_writer, '}'); + raptor_json_writer_newline(json_writer); + + return 0; +} + + +int +raptor_json_writer_blank_object(raptor_json_writer* json_writer, + const unsigned char* blank, + size_t blank_len) +{ + raptor_json_writer_start_block(json_writer, '{'); + raptor_json_writer_newline(json_writer); + + raptor_iostream_counted_string_write("\"value\" : \"_:", 13, + json_writer->iostr); + raptor_iostream_counted_string_write((const char*)blank, blank_len, + json_writer->iostr); + raptor_iostream_counted_string_write("\",", 2, json_writer->iostr); + raptor_json_writer_newline(json_writer); + + raptor_iostream_counted_string_write("\"type\" : \"bnode\"", 16, + json_writer->iostr); + raptor_json_writer_newline(json_writer); + + raptor_json_writer_end_block(json_writer, '}'); + return 0; +} + + +int +raptor_json_writer_uri_object(raptor_json_writer* json_writer, + raptor_uri* uri) +{ + raptor_json_writer_start_block(json_writer, '{'); + raptor_json_writer_newline(json_writer); + + raptor_json_writer_key_uri_value(json_writer, "value", 5, uri); + raptor_iostream_write_byte(',', json_writer->iostr); + raptor_json_writer_newline(json_writer); + + raptor_iostream_counted_string_write("\"type\" : \"uri\"", 14, + json_writer->iostr); + raptor_json_writer_newline(json_writer); + + raptor_json_writer_end_block(json_writer, '}'); + + return 0; +} + + +int +raptor_json_writer_term(raptor_json_writer* json_writer, + raptor_term *term) +{ + int rc = 0; + + switch(term->type) { + case RAPTOR_TERM_TYPE_URI: + rc = raptor_json_writer_uri_object(json_writer, term->value.uri); + break; + + case RAPTOR_TERM_TYPE_LITERAL: + rc = raptor_json_writer_literal_object(json_writer, + term->value.literal.string, + term->value.literal.string_len, + term->value.literal.language, + term->value.literal.datatype); + break; + + case RAPTOR_TERM_TYPE_BLANK: + rc = raptor_json_writer_blank_object(json_writer, + term->value.blank.string, + term->value.blank.string_len); + break; + + case RAPTOR_TERM_TYPE_UNKNOWN: + default: + raptor_log_error_formatted(json_writer->world, RAPTOR_LOG_LEVEL_ERROR, + NULL, + "Triple has unsupported term type %u", + term->type); + rc = 1; + break; + } + + return rc; +} + +#endif |