From 235eef1849b96bad3697f44c022f7a4e986299ff Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 21 Jan 2011 01:48:53 +0000 Subject: Make writer write to any sink passed in by the user. git-svn-id: http://svn.drobilla.net/serd/trunk@20 490d8e77-9747-427b-9fa3-0b8f29cee8a0 --- serd/serd.h | 7 +++-- src/serdi.c | 15 +++++++--- src/uri.c | 2 +- src/write.c | 96 ++++++++++++++++++++++++++++--------------------------------- 4 files changed, 60 insertions(+), 60 deletions(-) diff --git a/serd/serd.h b/serd/serd.h index 822b4b10..8efaab20 100644 --- a/serd/serd.h +++ b/serd/serd.h @@ -119,7 +119,7 @@ bool serd_uri_write(const SerdURI* uri, FILE* file); /** Sink function for raw string output. */ -typedef size_t (*SerdSink)(const uint8_t* buf, size_t len, void* stream); +typedef size_t (*SerdSink)(const void* buf, size_t len, void* stream); /** Serialise @a uri with a series of calls to @a sink. */ SERD_API @@ -249,8 +249,9 @@ SERD_API SerdWriter serd_writer_new(SerdSyntax syntax, SerdNamespaces ns, - FILE* file, - const SerdURI* base_uri); + const SerdURI* base_uri, + SerdSink sink, + void* stream); /** Free @a writer. */ SERD_API diff --git a/src/serdi.c b/src/serdi.c index 549bf2bd..5db96388 100644 --- a/src/serdi.c +++ b/src/serdi.c @@ -123,6 +123,13 @@ print_usage(const char* name, bool error) return error ? 1 : 0; } +static size_t +file_sink(const void* buf, size_t len, void* stream) +{ + FILE* file = (FILE*)stream; + return fwrite(buf, 1, len, file); +} + int main(int argc, char** argv) { @@ -168,10 +175,10 @@ main(int argc, char** argv) } SerdNamespaces ns = serd_namespaces_new(); - State state = { serd_writer_new(SERD_NTRIPLES, ns, out_fd, &base_uri), - ns, - base_uri_str, - base_uri }; + State state = { + serd_writer_new(SERD_NTRIPLES, ns, &base_uri, file_sink, out_fd), + ns, base_uri_str, base_uri + }; SerdReader reader = serd_reader_new( SERD_TURTLE, &state, event_base, event_prefix, event_statement); diff --git a/src/uri.c b/src/uri.c index 2d4fdc9f..9aac5313 100644 --- a/src/uri.c +++ b/src/uri.c @@ -366,7 +366,7 @@ serd_uri_string_length(const SerdURI* uri) } static size_t -string_sink(const uint8_t* buf, size_t len, void* stream) +string_sink(const void* buf, size_t len, void* stream) { uint8_t** ptr = (uint8_t**)stream; memcpy(*ptr, buf, len); diff --git a/src/write.c b/src/write.c index e4d524c6..ef10594b 100644 --- a/src/write.c +++ b/src/write.c @@ -16,6 +16,7 @@ */ #include +#include #include #include "serd/serd.h" @@ -23,39 +24,29 @@ struct SerdWriterImpl { SerdSyntax syntax; SerdNamespaces ns; - FILE* fd; SerdURI base_uri; + SerdSink sink; + void* stream; }; -static size_t -file_sink(const uint8_t* buf, size_t len, void* stream) -{ - FILE* file = (FILE*)stream; - return fwrite(buf, 1, len, file); -} - -static inline bool -serd_write_uri(FILE* file, const SerdURI* uri) -{ - return serd_uri_serialise(uri, file_sink, file); -} - static bool -serd_write_ascii(const uint8_t* utf8, size_t n_bytes, FILE* out_fd, const uint8_t esc) +serd_write_ascii(SerdWriter writer, const uint8_t* utf8, size_t n_bytes, const uint8_t esc) { + char escape[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; for (size_t i = 0; i < n_bytes;) { uint8_t in = utf8[i++]; switch (in) { - case '\\': fwrite("\\\\", 1, 2, out_fd); continue; - case '\n': fwrite("\\n", 1, 2, out_fd); continue; - case '\r': fwrite("\\r", 1, 2, out_fd); continue; - case '\t': fwrite("\\t", 1, 2, out_fd); continue; - case '"': if (esc == '"') { fwrite("\\\"", 1, 2, out_fd); continue; } + case '\\': writer->sink("\\\\", 2, writer->stream); continue; + case '\n': writer->sink("\\n", 2, writer->stream); continue; + case '\r': writer->sink("\\r", 2, writer->stream); continue; + case '\t': writer->sink("\\t", 2, writer->stream); continue; + case '"': if (esc == '"') { writer->sink("\\\"", 2, writer->stream); continue; } default: break; } if (in == esc) { - fprintf(out_fd, "\\u%04X", esc); + sprintf(escape, "\\u%04X", esc); + writer->sink(escape, 6, writer->stream); continue; } @@ -65,7 +56,7 @@ serd_write_ascii(const uint8_t* utf8, size_t n_bytes, FILE* out_fd, const uint8_ size = 1; c = in & 0x7F; if ((in >= 0x20) && (in <= 0x7E)) { // Printable ASCII - fwrite(&in, 1, 1, out_fd); + writer->sink(&in, 1, writer->stream); continue; } } else if ((in & 0xE0) == 0xC0) { // Starts with `110' @@ -104,23 +95,23 @@ serd_write_ascii(const uint8_t* utf8, size_t n_bytes, FILE* out_fd, const uint8_ } if (c < 0xFFFF) { - fprintf(out_fd, "\\u%04X", c); + sprintf(escape, "\\u%04X", c); + writer->sink(escape, 6, writer->stream); } else { - fprintf(out_fd, "\\U%08X", c); + sprintf(escape, "\\U%08X", c); + writer->sink(escape, 10, writer->stream); } } return true; } -SERD_API -bool +static bool serd_write_node(SerdWriter writer, SerdNodeType type, const SerdString* str, const SerdString* datatype, const SerdString* lang) { - FILE* const fd = writer->fd; const SerdURI* base_uri = &writer->base_uri; SerdNamespaces ns = writer->ns; @@ -128,18 +119,18 @@ serd_write_node(SerdWriter writer, SerdChunk uri_suffix; switch (type) { case BLANK: - fwrite("_:", 1, 2, fd); - fwrite(str->buf, 1, str->n_bytes - 1, fd); + writer->sink("_:", 2, writer->stream); + writer->sink(str->buf, str->n_bytes - 1, writer->stream); break; case QNAME: if (!serd_namespaces_expand(ns, str, &uri_prefix, &uri_suffix)) { fprintf(stderr, "error: undefined namespace prefix `%s'\n", str->buf); return false; } - fwrite("<", 1, 1, fd); - serd_write_ascii(uri_prefix.buf, uri_prefix.len, fd, '>'); - serd_write_ascii(uri_suffix.buf, uri_suffix.len, fd, '>'); - fwrite(">", 1, 1, fd); + writer->sink("<", 1, writer->stream); + serd_write_ascii(writer, uri_prefix.buf, uri_prefix.len, '>'); + serd_write_ascii(writer, uri_suffix.buf, uri_suffix.len, '>'); + writer->sink(">", 1, writer->stream); break; case URI: if (!serd_uri_string_has_scheme(str->buf)) { @@ -147,28 +138,28 @@ serd_write_node(SerdWriter writer, if (serd_uri_parse(str->buf, &uri)) { SerdURI abs_uri; if (serd_uri_resolve(&uri, base_uri, &abs_uri)) { - fwrite("<", 1, 1, fd); - serd_write_uri(fd, &abs_uri); - fwrite(">", 1, 1, fd); + writer->sink("<", 1, writer->stream); + serd_uri_serialise(&abs_uri, writer->sink, writer->stream); + writer->sink(">", 1, writer->stream); return true; } } } else { - fwrite("<", 1, 1, fd); - serd_write_ascii(str->buf, str->n_bytes - 1, fd, '>'); - fwrite(">", 1, 1, fd); + writer->sink("<", 1, writer->stream); + serd_write_ascii(writer, str->buf, str->n_bytes - 1, '>'); + writer->sink(">", 1, writer->stream); return true; } return false; case LITERAL: - fwrite("\"", 1, 1, fd); - serd_write_ascii(str->buf, str->n_bytes - 1, fd, '"'); - fwrite("\"", 1, 1, fd); + writer->sink("\"", 1, writer->stream); + serd_write_ascii(writer, str->buf, str->n_bytes - 1, '"'); + writer->sink("\"", 1, writer->stream); if (lang) { - fwrite("@", 1, 1, fd); - fwrite(lang->buf, 1, lang->n_bytes - 1, fd); + writer->sink("@", 1, writer->stream); + writer->sink(lang->buf, lang->n_bytes - 1, writer->stream); } else if (datatype) { - fwrite("^^", 1, 2, fd); + writer->sink("^^", 2, writer->stream); serd_write_node(writer, URI, datatype, NULL, NULL); } break; @@ -189,13 +180,12 @@ serd_writer_write_statement(SerdWriter writer, const SerdString* object_datatype, const SerdString* object_lang) { - FILE* const fd = writer->fd; serd_write_node(writer, subject_type, subject, NULL, NULL); - fwrite(" ", 1, 1, fd); + writer->sink(" ", 1, writer->stream); serd_write_node(writer, predicate_type, predicate, NULL, NULL); - fwrite(" ", 1, 1, fd); + writer->sink(" ", 1, writer->stream); serd_write_node(writer, object_type, object, object_datatype, object_lang); - fwrite(" .\n", 1, 3, fd); + writer->sink(" .\n", 3, writer->stream); return true; } @@ -203,14 +193,16 @@ SERD_API SerdWriter serd_writer_new(SerdSyntax syntax, SerdNamespaces ns, - FILE* file, - const SerdURI* base_uri) + const SerdURI* base_uri, + SerdSink sink, + void* stream) { SerdWriter writer = malloc(sizeof(struct SerdWriterImpl)); writer->syntax = syntax; writer->ns = ns; - writer->fd = file; writer->base_uri = *base_uri; + writer->sink = sink; + writer->stream = stream; return writer; } -- cgit v1.2.1