aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--include/serd/serd.h24
-rw-r--r--src/node.c14
-rw-r--r--src/uri.c12
-rw-r--r--src/writer.c16
-rw-r--r--test/test_reader_writer.c22
-rw-r--r--test/test_writer.c6
7 files changed, 50 insertions, 45 deletions
diff --git a/NEWS b/NEWS
index bc5de92f..1734a1bd 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,6 @@
serd (1.1.1) unstable; urgency=medium
+ * Add SerdBuffer for mutable buffers to keep SerdChunk const-correct
* Remove SERD_DISABLE_DEPRECATED and SERD_DEPRECATED_BY
* Remove serd_uri_to_path()
* Remove support for reading Turtle named inline nodes extension
diff --git a/include/serd/serd.h b/include/serd/serd.h
index 3b47ce5c..80d6b230 100644
--- a/include/serd/serd.h
+++ b/include/serd/serd.h
@@ -82,6 +82,12 @@ typedef struct {
size_t len; ///< Length of chunk in bytes
} SerdChunk;
+/// A mutable buffer in memory
+typedef struct {
+ void* SERD_NULLABLE buf; ///< Buffer
+ size_t len; ///< Size of buffer in bytes
+} SerdBuffer;
+
/**
Free memory allocated by Serd.
@@ -851,24 +857,24 @@ serd_file_sink(const void* SERD_NONNULL buf,
/**
A convenience sink function for writing to a string.
- This function can be used as a SerdSink to write to a SerdChunk which is
+ This function can be used as a SerdSink to write to a SerdBuffer which is
resized as necessary with realloc(). The `stream` parameter must point to
- an initialized SerdChunk. When the write is finished, the string should be
- retrieved with serd_chunk_sink_finish().
+ an initialized SerdBuffer. When the write is finished, the string should be
+ retrieved with serd_buffer_sink_finish().
*/
SERD_API size_t
-serd_chunk_sink(const void* SERD_NONNULL buf,
- size_t len,
- void* SERD_NONNULL stream);
+serd_buffer_sink(const void* SERD_NONNULL buf,
+ size_t len,
+ void* SERD_NONNULL stream);
/**
- Finish a serialisation to a chunk with serd_chunk_sink().
+ Finish a serialisation to a chunk with serd_buffer_sink().
The returned string is the result of the serialisation, which is null
terminated (by this function) and owned by the caller.
*/
-SERD_API char* SERD_NULLABLE
-serd_chunk_sink_finish(SerdChunk* SERD_NONNULL stream);
+SERD_API char* SERD_NONNULL
+serd_buffer_sink_finish(SerdBuffer* SERD_NONNULL stream);
/**
Set a function to be called when errors occur during writing.
diff --git a/src/node.c b/src/node.c
index 39612f8f..8f7a3aad 100644
--- a/src/node.c
+++ b/src/node.c
@@ -200,29 +200,29 @@ serd_node_new_file_uri(const char* const path,
}
}
- SerdChunk chunk = {uri, uri_len};
+ SerdBuffer buffer = {uri, uri_len};
for (size_t i = 0; i < path_len; ++i) {
if (path[i] == '%') {
- serd_chunk_sink("%%", 2, &chunk);
+ serd_buffer_sink("%%", 2, &buffer);
} else if (is_uri_path_char(path[i])) {
- serd_chunk_sink(path + i, 1, &chunk);
+ serd_buffer_sink(path + i, 1, &buffer);
#ifdef _WIN32
} else if (path[i] == '\\') {
- serd_chunk_sink("/", 1, &chunk);
+ serd_buffer_sink("/", 1, &buffer);
#endif
} else {
char escape_str[10] = {'%', 0, 0, 0, 0, 0, 0, 0, 0, 0};
snprintf(escape_str + 1, sizeof(escape_str) - 1, "%X", (unsigned)path[i]);
- serd_chunk_sink(escape_str, 3, &chunk);
+ serd_buffer_sink(escape_str, 3, &buffer);
}
}
- const char* const string = serd_chunk_sink_finish(&chunk);
+ const char* const string = serd_buffer_sink_finish(&buffer);
if (string && out) {
serd_uri_parse(string, out);
}
- return serd_node_from_substring(SERD_URI, string, chunk.len);
+ return serd_node_from_substring(SERD_URI, string, buffer.len);
}
SerdNode
diff --git a/src/uri.c b/src/uri.c
index 9f70aa40..c25f2155 100644
--- a/src/uri.c
+++ b/src/uri.c
@@ -27,7 +27,6 @@ serd_file_uri_parse(const char* const uri, char** const hostname)
if (!(path = strchr(auth, '/'))) {
return NULL;
}
-
if (hostname) {
const size_t len = (size_t)(path - auth);
*hostname = (char*)calloc(len + 1, 1);
@@ -40,27 +39,26 @@ serd_file_uri_parse(const char* const uri, char** const hostname)
++path;
}
- SerdChunk chunk = {NULL, 0};
+ SerdBuffer buffer = {NULL, 0};
for (const char* s = path; *s; ++s) {
if (*s == '%') {
if (*(s + 1) == '%') {
- serd_chunk_sink("%", 1, &chunk);
+ serd_buffer_sink("%", 1, &buffer);
++s;
} else if (is_hexdig(*(s + 1)) && is_hexdig(*(s + 2))) {
const uint8_t hi = hex_digit_value((const uint8_t)s[1]);
const uint8_t lo = hex_digit_value((const uint8_t)s[2]);
const char c = (char)((hi << 4U) | lo);
- serd_chunk_sink(&c, 1, &chunk);
+ serd_buffer_sink(&c, 1, &buffer);
s += 2;
} else {
s += 2; // Junk escape, ignore
}
} else {
- serd_chunk_sink(s, 1, &chunk);
+ serd_buffer_sink(s, 1, &buffer);
}
}
-
- return serd_chunk_sink_finish(&chunk);
+ return serd_buffer_sink_finish(&buffer);
}
bool
diff --git a/src/writer.c b/src/writer.c
index 751df38f..241e6fbf 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -1256,21 +1256,21 @@ serd_file_sink(const void* buf, size_t len, void* stream)
}
size_t
-serd_chunk_sink(const void* buf, size_t len, void* stream)
+serd_buffer_sink(const void* const buf, const size_t len, void* const stream)
{
- SerdChunk* chunk = (SerdChunk*)stream;
- char* new_buf = (char*)realloc((char*)chunk->buf, chunk->len + len);
+ SerdBuffer* buffer = (SerdBuffer*)stream;
+ char* new_buf = (char*)realloc((char*)buffer->buf, buffer->len + len);
if (new_buf) {
- memcpy(new_buf + chunk->len, buf, len);
- chunk->buf = new_buf;
- chunk->len += len;
+ memcpy(new_buf + buffer->len, buf, len);
+ buffer->buf = new_buf;
+ buffer->len += len;
}
return len;
}
char*
-serd_chunk_sink_finish(SerdChunk* stream)
+serd_buffer_sink_finish(SerdBuffer* const stream)
{
- serd_chunk_sink("", 1, stream);
+ serd_buffer_sink("", 1, stream);
return (char*)stream->buf;
}
diff --git a/test/test_reader_writer.c b/test/test_reader_writer.c
index 0555e7bb..bb27cf3e 100644
--- a/test/test_reader_writer.c
+++ b/test/test_reader_writer.c
@@ -514,16 +514,16 @@ test_writer(const char* const path)
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);
+ // Test buffer sink
+ SerdBuffer buffer = {NULL, 0};
+ writer = serd_writer_new(
+ SERD_TURTLE, (SerdStyle)0, env, NULL, serd_buffer_sink, &buffer);
o = serd_node_from_string(SERD_URI, "http://example.org/base");
assert(!serd_writer_set_base_uri(writer, &o));
serd_writer_free(writer);
- char* out = serd_chunk_sink_finish(&chunk);
+ char* out = serd_buffer_sink_finish(&buffer);
assert(!strcmp(out, "@base <http://example.org/base> .\n"));
serd_free(out);
@@ -531,19 +531,19 @@ test_writer(const char* const path)
// Test writing empty node
SerdNode nothing = serd_node_from_string(SERD_NOTHING, "");
- chunk.buf = NULL;
- chunk.len = 0;
- writer = serd_writer_new(
- SERD_TURTLE, (SerdStyle)0, env, NULL, serd_chunk_sink, &chunk);
+ buffer.buf = NULL;
+ buffer.len = 0;
+ writer = serd_writer_new(
+ SERD_TURTLE, (SerdStyle)0, env, NULL, serd_buffer_sink, &buffer);
assert(!serd_writer_write_statement(
writer, 0, NULL, &s, &p, &nothing, NULL, NULL));
assert(
- !strncmp((const char*)chunk.buf, "<>\n\t<http://example.org/pred> ", 30));
+ !strncmp((const char*)buffer.buf, "<>\n\t<http://example.org/pred> ", 30));
serd_writer_free(writer);
- out = serd_chunk_sink_finish(&chunk);
+ out = serd_buffer_sink_finish(&buffer);
assert(!strcmp((const char*)out, "<>\n\t<http://example.org/pred> .\n"));
serd_free(out);
diff --git a/test/test_writer.c b/test/test_writer.c
index 7033db76..aa1b05e7 100644
--- a/test/test_writer.c
+++ b/test/test_writer.c
@@ -14,9 +14,9 @@ static void
test_write_long_literal(void)
{
SerdEnv* env = serd_env_new(NULL);
- SerdChunk chunk = {NULL, 0};
+ SerdBuffer buffer = {NULL, 0};
SerdWriter* writer = serd_writer_new(
- SERD_TURTLE, (SerdStyle)0, env, NULL, serd_chunk_sink, &chunk);
+ SERD_TURTLE, (SerdStyle)0, env, NULL, serd_buffer_sink, &buffer);
assert(writer);
@@ -29,7 +29,7 @@ test_write_long_literal(void)
serd_writer_free(writer);
serd_env_free(env);
- char* out = serd_chunk_sink_finish(&chunk);
+ char* out = serd_buffer_sink_finish(&buffer);
static const char* const expected =
"<http://example.org/s>\n"