From 7b022006c47586dc00ed8bca85fcb0bdf5f9465d Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 3 Mar 2012 20:55:00 +0000 Subject: Add serd_chunk_sink for easy writing to a string. git-svn-id: http://svn.drobilla.net/serd/trunk@329 490d8e77-9747-427b-9fa3-0b8f29cee8a0 --- ChangeLog | 3 ++- serd/serd.h | 24 +++++++++++++++++++++++- src/writer.c | 19 +++++++++++++++++++ tests/serd_test.c | 21 +++++++++++++++++++++ wscript | 2 +- 5 files changed, 66 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5aee313c..b44938da 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,7 +15,8 @@ serd (UNRELEASED) unstable; urgency=low other tools fail to parse. * Add serd_strtod(), serd_node_new_decimal(), and serd_node_new_integer() for locale-independent numeric node parsing/serialising. - * Add serd_file_sink for the common case of writing to a FILE* stream. + * Add serd_file_sink for easy writing to a FILE* stream. + * Add serd_chunk_sink for easy writing to a string. * Escape ASCII control characters in output (e.g. fix problems with string literals that start with a backspace) * Improve URI resolution to cover most of the abnormal cases from RFC3986 diff --git a/serd/serd.h b/serd/serd.h index 8cca4a3f..ba4e6fb5 100644 --- a/serd/serd.h +++ b/serd/serd.h @@ -696,12 +696,34 @@ serd_writer_free(SerdWriter* writer); A convenience sink function for writing to a FILE*. This function can be used as a SerdSink when writing to a FILE*. The - associated @c stream parameter must be a FILE* opened for writing. + @c stream parameter must be a FILE* opened for writing. */ SERD_API size_t serd_file_sink(const void* buf, size_t len, void* stream); +/** + A convenience sink function for writing to a string. + + This function can be used as a SerdSink to write to a SerdChunk which is + resized as necessary with realloc(). The @c stream parameter must point to + an initialized SerdChunk. When the write is finished, the string should be + retrieved with serd_chunk_sink_finish(). +*/ +SERD_API +size_t +serd_chunk_sink(const void* buf, size_t len, void* stream); + +/** + Finish a serialisation to a chunk with serd_chunk_sink(). + + The returned string is the result of the serialisation, which is NULL + terminated (by this function) and owned by the caller. +*/ +SERD_API +uint8_t* +serd_chunk_sink_finish(SerdChunk* stream); + /** Set a prefix to be removed from matching blank node identifiers. */ diff --git a/src/writer.c b/src/writer.c index 8bdd3382..eb9c5b2d 100644 --- a/src/writer.c +++ b/src/writer.c @@ -714,3 +714,22 @@ serd_file_sink(const void* buf, size_t len, void* stream) { return fwrite(buf, 1, len, (FILE*)stream); } + +SERD_API +size_t +serd_chunk_sink(const void* buf, size_t len, void* stream) +{ + SerdChunk* chunk = (SerdChunk*)stream; + chunk->buf = realloc((uint8_t*)chunk->buf, chunk->len + len); + memcpy((uint8_t*)chunk->buf + chunk->len, buf, len); + chunk->len += len; + return len; +} + +SERD_API +uint8_t* +serd_chunk_sink_finish(SerdChunk* stream) +{ + serd_chunk_sink("", 1, stream); + return (uint8_t*)stream->buf; +} diff --git a/tests/serd_test.c b/tests/serd_test.c index 12129280..1474c37d 100644 --- a/tests/serd_test.c +++ b/tests/serd_test.c @@ -443,6 +443,27 @@ main() } serd_writer_free(writer); + + // Test chunk sink + SerdChunk chunk = { NULL, 0 }; + writer = serd_writer_new( + SERD_TURTLE, (SerdStyle)0, env, NULL, serd_chunk_sink, &chunk); + + o = serd_node_from_string(SERD_URI, USTR("http://example.org/base")); + if (serd_writer_set_base_uri(writer, &o)) { + return failure("Failed to write to chunk sink\n"); + } + + serd_writer_free(writer); + uint8_t* out = serd_chunk_sink_finish(&chunk); + + if (strcmp((const char*)out, "@base .\n")) { + return failure("Incorrect chunk output:\n%s\n", chunk.buf); + } + + free(out); + + // Rewind and test reader fseek(fd, 0, SEEK_SET); SerdReader* reader = serd_reader_new( diff --git a/wscript b/wscript index 94554b74..c4c65a37 100644 --- a/wscript +++ b/wscript @@ -9,7 +9,7 @@ from waflib.extras import autowaf as autowaf import waflib.Logs as Logs, waflib.Options as Options # Version of this package (even if built as a child) -SERD_VERSION = '0.10.0' +SERD_VERSION = '0.11.0' SERD_MAJOR_VERSION = '0' # Library version (UNIX style major, minor, micro) -- cgit v1.2.1