summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-tidy1
-rw-r--r--bindings/cpp/include/sratom/sratom.hpp44
-rw-r--r--bindings/cpp/meson.build16
-rw-r--r--doc/c/overview.rst2
-rw-r--r--doc/summary.rst2
-rw-r--r--include/sratom/sratom.h114
-rwxr-xr-xscripts/dox_to_sphinx.py3
-rw-r--r--src/dumper.c200
-rw-r--r--src/loader.c384
-rw-r--r--test/test_sratom.c49
10 files changed, 438 insertions, 377 deletions
diff --git a/.clang-tidy b/.clang-tidy
index 40c511c..449495e 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -9,6 +9,7 @@ Checks: >
-hicpp-signed-bitwise,
-llvm-header-guard,
-llvmlibc-*,
+ -misc-misplaced-const,
-misc-no-recursion,
WarningsAsErrors: '*'
HeaderFilterRegex: '.*'
diff --git a/bindings/cpp/include/sratom/sratom.hpp b/bindings/cpp/include/sratom/sratom.hpp
index b12d5e1..8be6644 100644
--- a/bindings/cpp/include/sratom/sratom.hpp
+++ b/bindings/cpp/include/sratom/sratom.hpp
@@ -79,21 +79,21 @@ public:
: BasicWrapper(sratom_dumper_new(world.cobj(), &map, &unmap))
{}
- int write(const serd::Env& env,
- serd::SinkView sink,
- const LV2_Atom& atom,
- const Flags flags)
+ SratomStatus write(const serd::Env& env,
+ serd::SinkView sink,
+ const LV2_Atom& atom,
+ const Flags flags)
{
return sratom_dump_atom(
cobj(), env.cobj(), sink.cobj(), nullptr, nullptr, &atom, flags);
}
- int write(const serd::Env& env,
- serd::SinkView sink,
- const serd::Node& subject,
- const serd::Node& predicate,
- const LV2_Atom& atom,
- const Flags flags)
+ SratomStatus write(const serd::Env& env,
+ serd::SinkView sink,
+ const serd::Node& subject,
+ const serd::Node& predicate,
+ const LV2_Atom& atom,
+ const Flags flags)
{
return sratom_dump_atom(cobj(),
env.cobj(),
@@ -104,14 +104,14 @@ public:
flags);
}
- int write(const serd::Env& env,
- serd::SinkView sink,
- const serd::Node& subject,
- const serd::Node& predicate,
- LV2_URID type,
- uint32_t size,
- const void* body,
- const Flags flags)
+ SratomStatus write(const serd::Env& env,
+ serd::SinkView sink,
+ const serd::Node& subject,
+ const serd::Node& predicate,
+ LV2_URID type,
+ uint32_t size,
+ const void* body,
+ const Flags flags)
{
return sratom_dump(cobj(),
env.cobj(),
@@ -153,10 +153,10 @@ public:
: BasicWrapper(sratom_loader_new(world.cobj(), &map))
{}
- int load(const serd::Optional<serd::Node>& base_uri,
- LV2_Atom_Forge& forge,
- const serd::Model& model,
- const serd::Node& node)
+ SratomStatus load(const serd::Optional<serd::Node>& base_uri,
+ LV2_Atom_Forge& forge,
+ const serd::Model& model,
+ const serd::Node& node)
{
return sratom_load(
cobj(), base_uri.cobj(), &forge, model.cobj(), node.cobj());
diff --git a/bindings/cpp/meson.build b/bindings/cpp/meson.build
index ee1dc4f..02f4d53 100644
--- a/bindings/cpp/meson.build
+++ b/bindings/cpp/meson.build
@@ -67,10 +67,12 @@ install_headers(cpp_headers, subdir: versioned_cpp_name / 'sratom')
cpp_test_args = cpp.get_supported_arguments(['-Wno-float-equal'])
-test('bindings',
- executable('test_sratom_hpp',
- 'test/test_sratom_hpp.cpp',
- include_directories: include_directories(['include']),
- cpp_args: exess_cpp_args + cpp_test_args,
- dependencies: [sratom_dep, serdpp_dep, sratompp_dep]),
- suite: 'cpp')
+test(
+ 'bindings',
+ executable(
+ 'test_sratom_hpp',
+ 'test/test_sratom_hpp.cpp',
+ include_directories: include_directories(['include', '../../test']),
+ cpp_args: exess_cpp_args + cpp_test_args,
+ dependencies: [sratom_dep, serdpp_dep, sratompp_dep]),
+ suite: 'cpp')
diff --git a/doc/c/overview.rst b/doc/c/overview.rst
index 3b26a5b..b5d75c1 100644
--- a/doc/c/overview.rst
+++ b/doc/c/overview.rst
@@ -5,7 +5,7 @@ Overview
.. default-domain:: c
.. highlight:: c
-The complete API is declared in ``sratom.h``:
+The entire API is declared in ``sratom.h``:
.. code-block:: c
diff --git a/doc/summary.rst b/doc/summary.rst
index 7e28f6e..715e82e 100644
--- a/doc/summary.rst
+++ b/doc/summary.rst
@@ -1,6 +1,6 @@
Sratom is a small library for reading and writing `LV2 atoms`_ in RDF,
for representing them as strings or storing them in a data model.
Sratom is useful for representing LV2 atoms in a portable and human-readable form,
-in, for example, saved files, network protocols, or logs.
+for example in save files, network protocols, or logs.
.. _LV2 atoms: http://lv2plug.in/ns/ext/atom
diff --git a/include/sratom/sratom.h b/include/sratom/sratom.h
index 68bff33..6934fb8 100644
--- a/include/sratom/sratom.h
+++ b/include/sratom/sratom.h
@@ -43,10 +43,17 @@ extern "C" {
/**
@defgroup sratom Sratom C API
- This is the complete public C API of sratom.
@{
*/
+/// Return status code
+typedef enum {
+ SRATOM_SUCCESS, ///< No error
+ SRATOM_BAD_FILE_URI, ///< Invalid file URI encountered
+ SRATOM_BAD_VECTOR, ///< Invalid vector (missing atom:childType)
+ SRATOM_BAD_FORGE, ///< Error forging output atom (likely overflow)
+} SratomStatus;
+
/// Free memory allocated in the sratom library
SRATOM_API
void
@@ -71,16 +78,23 @@ typedef enum {
/**
Write pretty numeric literals in Turtle or TriG.
- If set, numbers may be written as pretty literals instead of string
- literals with explicit data types. Note that enabling this means that
- types will not survive a round trip.
+ If set, numbers may be written as "pretty" xsd:integer or xsd:decimal
+ literals (without quoting or an explicit datatype) instead of string
+ literals with explicit data types. It is best to leave this off in
+ contexts where human readability doesn't matter very much, since the
+ explicit form is more consistent and likely to survive storage,
+ transmission, and transformation with perfect fidelity.
*/
SRATOM_PRETTY_NUMBERS = 1u << 2u,
/**
Write terse output without newlines.
- If set, top level atoms will be written as a single long line.
+ If set when writing to a string, top-level atoms will be written as a
+ single long line. From a machine perspective, the output is identical,
+ but this can be convenient in contexts where taking up less space for the
+ representation of atoms is desirable, such as developer logs or
+ transmission over a network.
*/
SRATOM_TERSE = 1u << 3u,
} SratomDumperFlag;
@@ -117,30 +131,40 @@ sratom_dumper_free(SratomDumper* dumper);
series of statements. It can be used with any sink, such as a Turtle
writer, model inserter, or a custom sink provided by the application.
- This function takes the `type`, `size`, and `body` separately to allow
- writing atoms from data in memory that does not have an atom header. For
- true atom pointers, the simpler sratom_dump_atom() can be used instead.
-
- Since all statements must be triples, a subject and predicate can be
- provided to serialise literals like `subject predicate "literal"`. If
- `subject` and `predicate` are null, resources will be written as the
- subject, but literals will be written as the only element of an anonymous
- list. A subject and predicate should always be given for lossless
- round-tripping. This corresponds to using atoms as property values.
-
- @param dumper Dumper instance
- @param env Environment defining the base URI and any prefixes
- @param sink Sink which receives the serialised statements
- @param subject Subject of first statement, or NULL
- @param predicate Predicate of first statement, or NULL
- @param type Type of the atom
- @param size Size of the atom body in bytes
- @param body Atom body
- @param flags Option flags
- @return Zero on success
+ This function takes the `type`, `size`, and `body` separately to enable
+ writing values that are not a contiguous `LV2_Atom` in memory. For writing
+ existing atoms, the simpler sratom_dump_atom() can be used instead.
+
+ A subject and predicate can be provided so that writing simple atoms will
+ produce a statement like `subject predicate "literal"`. If either `subject`
+ or `predicate` are null, objects will be written as the subject, and
+ literals will be written as the only element of an anonymous list. For
+ example:
+
+ @verbatim
+ my:object some:property 42 .
+ [ some:property 42 ] .
+ ( "literal" ) .
+ @endverbatim
+
+ Generally, this function is intended for writing the value of some property
+ (for example, the current value of a plugin parameter in a preset), and the
+ appropriate subject and predicate for the context should always be provided.
+ This avoids any ambiguities and guarantees lossless round-tripping.
+
+ @param dumper Dumper instance.
+ @param env Environment defining the base URI and any prefixes.
+ @param sink Sink which receives the statements describing the atom.
+ @param subject Subject of first statement, or NULL.
+ @param predicate Predicate of first statement, or NULL.
+ @param type Type of the atom.
+ @param size Size of the atom body in bytes.
+ @param body Atom body.
+ @param flags Option flags.
+ @return Zero on success.
*/
SRATOM_API
-int
+SratomStatus
sratom_dump(SratomDumper* dumper,
const SerdEnv* env,
const SerdSink* sink,
@@ -157,17 +181,17 @@ sratom_dump(SratomDumper* dumper,
Convenience wrapper that takes a pointer to a complete atom, see the
sratom_dump() documentation for details.
- @param dumper Dumper instance
- @param env Environment defining the base URI and any prefixes
- @param sink Sink which receives the serialised statements
- @param subject Subject of first statement, or NULL
- @param predicate Predicate of first statement, or NULL
- @param atom Atom to serialise
- @param flags Option flags
- @return Zero on success
+ @param dumper Dumper instance.
+ @param env Environment defining the base URI and any prefixes.
+ @param sink Sink which receives the statements describing the atom.
+ @param subject Subject of first statement, or NULL.
+ @param predicate Predicate of first statement, or NULL.
+ @param atom Atom to write.
+ @param flags Option flags.
+ @return Zero on success.
*/
SRATOM_API
-int
+SratomStatus
sratom_dump_atom(SratomDumper* dumper,
const SerdEnv* env,
const SerdSink* sink,
@@ -182,10 +206,10 @@ sratom_dump_atom(SratomDumper* dumper,
The returned string can be forged back into an atom using
sratom_from_string().
- @param dumper Dumper instance
- @param env Environment for namespaces and relative URIs
- @param atom Atom to serialise
- @param flags Option flags
+ @param dumper Dumper instance.
+ @param env Environment for namespaces and relative URIs.
+ @param atom Atom to write.
+ @param flags Option flags.
@return A string that must be freed using sratom_free(), or NULL on error.
*/
SRATOM_API
@@ -207,9 +231,9 @@ typedef struct SratomLoaderImpl SratomLoader;
/**
Create a new loader for forging atoms from a document.
- @param world RDF world
- @param map URID mapper
- @return A new object that must be freed with sratom_loader_free()
+ @param world RDF world.
+ @param map URID mapper.
+ @return A new object that must be freed with sratom_loader_free().
*/
SRATOM_API
SratomLoader*
@@ -243,10 +267,10 @@ sratom_loader_free(SratomLoader* loader);
primitive atoms, or the subject resource for more complex structures like
objects and vectors.
- @return Zero on success.
+ @return A status code which is zero on success.
*/
SRATOM_API
-int
+SratomStatus
sratom_load(SratomLoader* loader,
const SerdNode* base_uri,
LV2_Atom_Forge* forge,
diff --git a/scripts/dox_to_sphinx.py b/scripts/dox_to_sphinx.py
index c9d401c..f0dcd2c 100755
--- a/scripts/dox_to_sphinx.py
+++ b/scripts/dox_to_sphinx.py
@@ -322,6 +322,9 @@ def dox_to_rst(index, lang, node):
if node.tag == "ulink":
return "`%s <%s>`_" % (node.text, node.get("url"))
+ if node.tag == "verbatim":
+ return "::\n\n" + indent(plain_text(node), 1)
+
raise RuntimeError("Unknown documentation command: %s" % node.tag)
diff --git a/src/dumper.c b/src/dumper.c
index b2bb852..b6cd08e 100644
--- a/src/dumper.c
+++ b/src/dumper.c
@@ -33,12 +33,12 @@
#define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
#define NS_XSD "http://www.w3.org/2001/XMLSchema#"
-#define STREAM_WARN(msg) \
- serd_world_logf( \
+#define DUMP_WARN(msg) \
+ serd_world_logf( \
writer->world, "sratom", SERD_LOG_LEVEL_WARNING, 0, NULL, msg);
-#define STREAM_ERRORF(msg, ...) \
- serd_world_logf( \
+#define DUMP_ERRORF(msg, ...) \
+ serd_world_logf( \
writer->world, "sratom", SERD_LOG_LEVEL_ERROR, 0, NULL, msg, __VA_ARGS__);
struct SratomDumperImpl {
@@ -92,53 +92,53 @@ sratom_dumper_new(SerdWorld* const world,
LV2_URID_Map* const map,
LV2_URID_Unmap* const unmap)
{
- SratomDumper* writer = (SratomDumper*)calloc(1, sizeof(SratomDumper));
- if (!writer) {
+ SratomDumper* const dumper = (SratomDumper*)calloc(1, sizeof(SratomDumper));
+ if (!dumper) {
return NULL;
}
- writer->world = world;
- writer->unmap = unmap;
- writer->atom_Event = map->map(map->handle, LV2_ATOM__Event);
- writer->atom_beatTime = map->map(map->handle, LV2_ATOM__beatTime);
- writer->midi_MidiEvent = map->map(map->handle, LV2_MIDI__MidiEvent);
- lv2_atom_forge_init(&writer->forge, map);
+ dumper->world = world;
+ dumper->unmap = unmap;
+ dumper->atom_Event = map->map(map->handle, LV2_ATOM__Event);
+ dumper->atom_beatTime = map->map(map->handle, LV2_ATOM__beatTime);
+ dumper->midi_MidiEvent = map->map(map->handle, LV2_MIDI__MidiEvent);
+ lv2_atom_forge_init(&dumper->forge, map);
#define MANAGE_URI(uri) \
serd_nodes_manage(serd_world_nodes(world), \
serd_new_uri(SERD_STATIC_STRING(uri)))
- writer->nodes.atom_Path = MANAGE_URI(LV2_ATOM__Path);
- writer->nodes.atom_beatTime = MANAGE_URI(LV2_ATOM__beatTime);
- writer->nodes.atom_childType = MANAGE_URI(LV2_ATOM__childType);
- writer->nodes.atom_frameTime = MANAGE_URI(LV2_ATOM__frameTime);
- writer->nodes.midi_MidiEvent = MANAGE_URI(LV2_MIDI__MidiEvent);
- writer->nodes.rdf_first = MANAGE_URI(NS_RDF "first");
- writer->nodes.rdf_nil = MANAGE_URI(NS_RDF "nil");
- writer->nodes.rdf_rest = MANAGE_URI(NS_RDF "rest");
- writer->nodes.rdf_type = MANAGE_URI(NS_RDF "type");
- writer->nodes.rdf_value = MANAGE_URI(NS_RDF "value");
- writer->nodes.xsd_base64Binary = MANAGE_URI(NS_XSD "base64Binary");
- writer->nodes.xsd_boolean = MANAGE_URI(NS_XSD "boolean");
- writer->nodes.xsd_decimal = MANAGE_URI(NS_XSD "decimal");
- writer->nodes.xsd_double = MANAGE_URI(NS_XSD "double");
- writer->nodes.xsd_float = MANAGE_URI(NS_XSD "float");
- writer->nodes.xsd_int = MANAGE_URI(NS_XSD "int");
- writer->nodes.xsd_integer = MANAGE_URI(NS_XSD "integer");
- writer->nodes.xsd_long = MANAGE_URI(NS_XSD "long");
+ dumper->nodes.atom_Path = MANAGE_URI(LV2_ATOM__Path);
+ dumper->nodes.atom_beatTime = MANAGE_URI(LV2_ATOM__beatTime);
+ dumper->nodes.atom_childType = MANAGE_URI(LV2_ATOM__childType);
+ dumper->nodes.atom_frameTime = MANAGE_URI(LV2_ATOM__frameTime);
+ dumper->nodes.midi_MidiEvent = MANAGE_URI(LV2_MIDI__MidiEvent);
+ dumper->nodes.rdf_first = MANAGE_URI(NS_RDF "first");
+ dumper->nodes.rdf_nil = MANAGE_URI(NS_RDF "nil");
+ dumper->nodes.rdf_rest = MANAGE_URI(NS_RDF "rest");
+ dumper->nodes.rdf_type = MANAGE_URI(NS_RDF "type");
+ dumper->nodes.rdf_value = MANAGE_URI(NS_RDF "value");
+ dumper->nodes.xsd_base64Binary = MANAGE_URI(NS_XSD "base64Binary");
+ dumper->nodes.xsd_boolean = MANAGE_URI(NS_XSD "boolean");
+ dumper->nodes.xsd_decimal = MANAGE_URI(NS_XSD "decimal");
+ dumper->nodes.xsd_double = MANAGE_URI(NS_XSD "double");
+ dumper->nodes.xsd_float = MANAGE_URI(NS_XSD "float");
+ dumper->nodes.xsd_int = MANAGE_URI(NS_XSD "int");
+ dumper->nodes.xsd_integer = MANAGE_URI(NS_XSD "integer");
+ dumper->nodes.xsd_long = MANAGE_URI(NS_XSD "long");
#undef MANAGE_URI
- return writer;
+ return dumper;
}
void
-sratom_dumper_free(SratomDumper* writer)
+sratom_dumper_free(SratomDumper* const writer)
{
free(writer);
}
-static int
+static SratomStatus
write_atom(StreamContext* ctx,
const SerdNode* subject,
const SerdNode* predicate,
@@ -147,15 +147,16 @@ write_atom(StreamContext* ctx,
const void* body);
static void
-list_append(StreamContext* ctx,
- SerdNode** s,
- const SerdNode** p,
- uint32_t size,
- uint32_t type,
- const void* body)
+list_append(StreamContext* const ctx,
+ SerdNode** const s,
+ const SerdNode** const p,
+ const uint32_t size,
+ const uint32_t type,
+ const void* const body)
{
// Generate a list node
- SerdNode* node = serd_node_copy(serd_world_get_blank(ctx->writer->world));
+ SerdNode* const node =
+ serd_node_copy(serd_world_get_blank(ctx->writer->world));
serd_sink_write(ctx->sink, ctx->sflags, *s, *p, node, NULL);
// _:node rdf:first value
@@ -170,19 +171,20 @@ list_append(StreamContext* ctx,
}
static void
-list_end(StreamContext* ctx, const SerdNode* s, const SerdNode* p)
+list_end(const StreamContext* const ctx,
+ const SerdNode* const s,
+ const SerdNode* const p)
{
// _:node rdf:rest rdf:nil
- serd_sink_write(
- ctx->sink, ctx->sflags, s, p, ctx->writer->nodes.rdf_nil, NULL);
+ serd_sink_write(ctx->sink, 0, s, p, ctx->writer->nodes.rdf_nil, NULL);
}
static void
-start_object(StreamContext* ctx,
- const SerdNode* subject,
- const SerdNode* predicate,
- const SerdNode* node,
- const char* type)
+start_object(StreamContext* const ctx,
+ const SerdNode* const subject,
+ const SerdNode* const predicate,
+ const SerdNode* const node,
+ const char* const type)
{
if (subject && predicate) {
serd_sink_write(
@@ -192,7 +194,7 @@ start_object(StreamContext* ctx,
}
if (type) {
- SerdNode* o = serd_new_uri(SERD_MEASURE_STRING(type));
+ SerdNode* const o = serd_new_uri(SERD_MEASURE_STRING(type));
serd_sink_write(
ctx->sink, ctx->sflags, node, ctx->writer->nodes.rdf_type, o, NULL);
@@ -202,10 +204,10 @@ start_object(StreamContext* ctx,
}
static void
-end_object(StreamContext* ctx,
- const SerdNode* subject,
- const SerdNode* predicate,
- const SerdNode* node)
+end_object(const StreamContext* const ctx,
+ const SerdNode* const subject,
+ const SerdNode* const predicate,
+ const SerdNode* const node)
{
if (subject && predicate) {
serd_sink_write_end(ctx->sink, node);
@@ -213,30 +215,33 @@ end_object(StreamContext* ctx,
}
static bool
-path_is_absolute(const char* path)
+path_is_absolute(const char* const path)
{
return (path[0] == '/' || (isalpha(path[0]) && path[1] == ':' &&
(path[2] == '/' || path[2] == '\\')));
}
static const SerdNode*
-number_type(StreamContext* ctx, const SerdNode* type)
+number_type(const StreamContext* const ctx, const SerdNode* const type)
{
SratomDumper* const writer = ctx->writer;
const bool pretty = (ctx->flags & SRATOM_PRETTY_NUMBERS);
+
if (pretty) {
if (type == writer->nodes.xsd_int || type == writer->nodes.xsd_long) {
return writer->nodes.xsd_integer;
- } else if (type == writer->nodes.xsd_float ||
- type == writer->nodes.xsd_double) {
+ }
+
+ if (type == writer->nodes.xsd_float || type == writer->nodes.xsd_double) {
return writer->nodes.xsd_decimal;
}
}
+
return type;
}
static bool
-is_primitive_type(StreamContext* ctx, const LV2_URID type)
+is_primitive_type(const StreamContext* const ctx, const LV2_URID type)
{
SratomDumper* const writer = ctx->writer;
return (!type || type == writer->forge.Bool || type == writer->forge.Double ||
@@ -246,20 +251,22 @@ is_primitive_type(StreamContext* ctx, const LV2_URID type)
type == writer->forge.URI || type == writer->forge.URID);
}
-static int
-write_atom(StreamContext* const ctx,
- const SerdNode* subject,
- const SerdNode* predicate,
- const LV2_URID type,
- const uint32_t size,
- const void* const body)
+static SratomStatus
+write_atom(StreamContext* const ctx,
+ const SerdNode* const subject,
+ const SerdNode* const predicate,
+ const LV2_URID type,
+ const uint32_t size,
+ const void* const body)
{
- SratomDumper* writer = ctx->writer;
- LV2_URID_Unmap* unmap = writer->unmap;
- const SerdSink* sink = ctx->sink;
- const SerdEnv* env = ctx->env;
- const char* const type_uri = unmap->unmap(unmap->handle, type);
- SerdNode* object = NULL;
+ SratomDumper* const writer = ctx->writer;
+ LV2_URID_Unmap* const unmap = writer->unmap;
+ const SerdSink* const sink = ctx->sink;
+ const SerdEnv* const env = ctx->env;
+ const char* const type_uri = unmap->unmap(unmap->handle, type);
+ SerdNode* object = NULL;
+ SratomStatus st = SRATOM_SUCCESS;
+
if (type == 0 && size == 0) {
object = serd_node_copy(writer->nodes.rdf_nil);
} else if (type == writer->forge.String) {
@@ -281,7 +288,7 @@ write_atom(StreamContext* const ctx,
object = serd_new_plain_literal(SERD_MEASURE_STRING(str),
SERD_MEASURE_STRING(lang + prefix_len));
} else {
- STREAM_ERRORF("Unknown language URID %u\n", lit->lang);
+ DUMP_ERRORF("Unknown language URID %u\n", lit->lang);
}
}
} else if (type == writer->forge.URID) {
@@ -296,8 +303,8 @@ write_atom(StreamContext* const ctx,
} else {
const SerdNode* base_uri = serd_env_base_uri(env);
if (!base_uri || strncmp(serd_node_string(base_uri), "file://", 7)) {
- STREAM_WARN("Relative path but base is not a file URI.\n");
- STREAM_WARN("Writing ambiguous atom:Path literal.\n");
+ DUMP_WARN("Relative path but base is not a file URI.\n");
+ DUMP_WARN("Writing ambiguous atom:Path literal.\n");
object = serd_new_typed_literal(
str, serd_node_string_view(writer->nodes.atom_Path));
} else {
@@ -341,8 +348,8 @@ write_atom(StreamContext* const ctx,
free(str);
} else if (type == writer->atom_Event) {
- const LV2_Atom_Event* ev = (const LV2_Atom_Event*)body;
- const SerdNode* id = serd_world_get_blank(writer->world);
+ const LV2_Atom_Event* const ev = (const LV2_Atom_Event*)body;
+ const SerdNode* const id = serd_world_get_blank(writer->world);
start_object(ctx, subject, predicate, id, NULL);
SerdNode* time = NULL;
const SerdNode* p = NULL;
@@ -362,28 +369,34 @@ write_atom(StreamContext* const ctx,
ctx, id, p, ev->body.type, ev->body.size, LV2_ATOM_BODY_CONST(&ev->body));
end_object(ctx, subject, predicate, id);
} else if (type == writer->forge.Tuple) {
- SerdNode* id = serd_node_copy(serd_world_get_blank(writer->world));
+ SerdNode* id = serd_node_copy(serd_world_get_blank(writer->world));
+ const SerdNode* p = writer->nodes.rdf_value;
start_object(ctx, subject, predicate, id, type_uri);
- const SerdNode* p = writer->nodes.rdf_value;
+
ctx->sflags |= SERD_LIST_O | SERD_TERSE_O;
LV2_ATOM_TUPLE_BODY_FOREACH (body, size, i) {
if (!is_primitive_type(ctx, i->type)) {
ctx->sflags &= ~SERD_TERSE_O;
}
}
+
LV2_ATOM_TUPLE_BODY_FOREACH (body, size, i) {
list_append(ctx, &id, &p, i->size, i->type, LV2_ATOM_BODY(i));
}
- list_end(ctx, id, p);
+
+ serd_sink_write(ctx->sink, 0, id, p, ctx->writer->nodes.rdf_nil, NULL);
end_object(ctx, subject, predicate, id);
serd_node_free(id);
} else if (type == writer->forge.Vector) {
- const LV2_Atom_Vector_Body* vec = (const LV2_Atom_Vector_Body*)body;
+ const LV2_Atom_Vector_Body* const vec = (const LV2_Atom_Vector_Body*)body;
+
SerdNode* id = serd_node_copy(serd_world_get_blank(writer->world));
start_object(ctx, subject, predicate, id, type_uri);
+
const SerdNode* p = writer->nodes.atom_childType;
- SerdNode* child_type = serd_new_uri(
+ SerdNode* const child_type = serd_new_uri(
SERD_MEASURE_STRING(unmap->unmap(unmap->handle, vec->child_type)));
+
serd_sink_write(sink, ctx->sflags, id, p, child_type, NULL);
p = writer->nodes.rdf_value;
serd_node_free(child_type);
@@ -391,16 +404,18 @@ write_atom(StreamContext* const ctx,
if (is_primitive_type(ctx, vec->child_type)) {
ctx->sflags |= SERD_TERSE_O;
}
+
for (const char* i = (const char*)(vec + 1); i < (const char*)vec + size;
i += vec->child_size) {
list_append(ctx, &id, &p, vec->child_size, vec->child_type, i);
}
- list_end(ctx, id, p);
+
+ serd_sink_write(ctx->sink, 0, id, p, ctx->writer->nodes.rdf_nil, NULL);
end_object(ctx, subject, predicate, id);
serd_node_free(id);
} else if (lv2_atom_forge_is_object_type(&writer->forge, type)) {
const LV2_Atom_Object_Body* obj = (const LV2_Atom_Object_Body*)body;
- const char* otype = unmap->unmap(unmap->handle, obj->otype);
+ const char* const otype = unmap->unmap(unmap->handle, obj->otype);
SerdNode* id = NULL;
if (lv2_atom_forge_is_blank(&writer->forge, type, obj)) {
@@ -414,7 +429,7 @@ write_atom(StreamContext* const ctx,
}
LV2_ATOM_OBJECT_BODY_FOREACH (obj, size, prop) {
const char* const key = unmap->unmap(unmap->handle, prop->key);
- SerdNode* pred = serd_new_uri(SERD_MEASURE_STRING(key));
+ SerdNode* const pred = serd_new_uri(SERD_MEASURE_STRING(key));
write_atom(ctx,
id,
pred,
@@ -454,18 +469,17 @@ write_atom(StreamContext* const ctx,
}
if (object) {
- if (!subject && !predicate) {
- subject = serd_world_get_blank(writer->world);
- predicate = writer->nodes.rdf_first;
+ if (!subject || !predicate) {
+ const SerdNode* const blank = serd_world_get_blank(writer->world);
serd_sink_write(sink,
ctx->sflags | SERD_LIST_S | SERD_TERSE_S,
- subject,
- predicate,
+ blank,
+ writer->nodes.rdf_first,
object,
NULL);
serd_sink_write(sink,
SERD_TERSE_S,
- subject,
+ blank,
writer->nodes.rdf_rest,
writer->nodes.rdf_nil,
NULL);
@@ -476,10 +490,10 @@ write_atom(StreamContext* const ctx,
serd_node_free(object);
- return 0;
+ return st;
}
-int
+SratomStatus
sratom_dump(SratomDumper* const writer,
const SerdEnv* const env,
const SerdSink* const sink,
@@ -500,7 +514,7 @@ sratom_dump(SratomDumper* const writer,
return write_atom(&ctx, subject, predicate, type, size, body);
}
-int
+SratomStatus
sratom_dump_atom(SratomDumper* const writer,
const SerdEnv* const env,
const SerdSink* const sink,
diff --git a/src/loader.c b/src/loader.c
index 46e7c51..46a23f3 100644
--- a/src/loader.c
+++ b/src/loader.c
@@ -23,7 +23,6 @@
#include "serd/serd.h"
#include <assert.h>
-#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -37,6 +36,17 @@
typedef enum { MODE_SUBJECT, MODE_BODY, MODE_SEQUENCE } ReadMode;
+typedef struct {
+ const SerdNode* atom_beatTime;
+ const SerdNode* atom_childType;
+ const SerdNode* atom_frameTime;
+ const SerdNode* rdf_first;
+ const SerdNode* rdf_rest;
+ const SerdNode* rdf_type;
+ const SerdNode* rdf_value;
+ const SerdNode* xsd_base64Binary;
+} LoaderNodes;
+
struct SratomLoaderImpl {
LV2_URID_Map* map;
LV2_Atom_Forge forge;
@@ -44,25 +54,16 @@ struct SratomLoaderImpl {
LV2_URID atom_frameTime;
LV2_URID atom_beatTime;
LV2_URID midi_MidiEvent;
- struct {
- const SerdNode* atom_beatTime;
- const SerdNode* atom_childType;
- const SerdNode* atom_frameTime;
- const SerdNode* rdf_first;
- const SerdNode* rdf_rest;
- const SerdNode* rdf_type;
- const SerdNode* rdf_value;
- const SerdNode* xsd_base64Binary;
- } nodes;
+ LoaderNodes nodes;
};
typedef struct {
- SratomLoader* loader;
- const SerdNode* base_uri;
- LV2_URID seq_unit;
+ SratomLoader* SERD_NONNULL loader;
+ const SerdNode* SERD_NONNULL base_uri;
+ LV2_URID seq_unit;
} LoadContext;
-static void
+static SratomStatus
read_node(LoadContext* ctx,
LV2_Atom_Forge* forge,
const SerdModel* model,
@@ -70,55 +71,58 @@ read_node(LoadContext* ctx,
ReadMode mode);
SratomLoader*
-sratom_loader_new(SerdWorld* world, LV2_URID_Map* map)
+sratom_loader_new(SerdWorld* const world, LV2_URID_Map* const map)
{
- SratomLoader* sratom = (SratomLoader*)calloc(1, sizeof(SratomLoader));
- if (!sratom) {
+ SratomLoader* const loader = (SratomLoader*)calloc(1, sizeof(SratomLoader));
+ if (!loader) {
return NULL;
}
- sratom->world = world;
- sratom->map = map;
- sratom->atom_frameTime = map->map(map->handle, LV2_ATOM__frameTime);
- sratom->atom_beatTime = map->map(map->handle, LV2_ATOM__beatTime);
- sratom->midi_MidiEvent = map->map(map->handle, LV2_MIDI__MidiEvent);
- lv2_atom_forge_init(&sratom->forge, map);
+ loader->world = world;
+ loader->map = map;
+ loader->atom_frameTime = map->map(map->handle, LV2_ATOM__frameTime);
+ loader->atom_beatTime = map->map(map->handle, LV2_ATOM__beatTime);
+ loader->midi_MidiEvent = map->map(map->handle, LV2_MIDI__MidiEvent);
+
+ lv2_atom_forge_init(&loader->forge, map);
#define MANAGE_URI(uri) \
serd_nodes_manage(serd_world_nodes(world), \
serd_new_uri(SERD_STATIC_STRING(uri)))
- sratom->nodes.atom_beatTime = MANAGE_URI(LV2_ATOM__beatTime);
- sratom->nodes.atom_childType = MANAGE_URI(LV2_ATOM__childType);
- sratom->nodes.atom_frameTime = MANAGE_URI(LV2_ATOM__frameTime);
- sratom->nodes.rdf_first = MANAGE_URI(NS_RDF "first");
- sratom->nodes.rdf_rest = MANAGE_URI(NS_RDF "rest");
- sratom->nodes.rdf_type = MANAGE_URI(NS_RDF "type");
- sratom->nodes.rdf_value = MANAGE_URI(NS_RDF "value");
- sratom->nodes.xsd_base64Binary = MANAGE_URI(NS_XSD "base64Binary");
+ loader->nodes.atom_beatTime = MANAGE_URI(LV2_ATOM__beatTime);
+ loader->nodes.atom_childType = MANAGE_URI(LV2_ATOM__childType);
+ loader->nodes.atom_frameTime = MANAGE_URI(LV2_ATOM__frameTime);
+ loader->nodes.rdf_first = MANAGE_URI(NS_RDF "first");
+ loader->nodes.rdf_rest = MANAGE_URI(NS_RDF "rest");
+ loader->nodes.rdf_type = MANAGE_URI(NS_RDF "type");
+ loader->nodes.rdf_value = MANAGE_URI(NS_RDF "value");
+ loader->nodes.xsd_base64Binary = MANAGE_URI(NS_XSD "base64Binary");
-#undef INTERN_URI
+#undef MANAGE_URI
- return sratom;
+ return loader;
}
void
-sratom_loader_free(SratomLoader* loader)
+sratom_loader_free(SratomLoader* const loader)
{
free(loader);
}
static void
-read_list_value(LoadContext* ctx,
- LV2_Atom_Forge* forge,
- const SerdModel* model,
- const SerdNode* node,
- ReadMode mode)
+read_list_value(LoadContext* const ctx,
+ LV2_Atom_Forge* const forge,
+ const SerdModel* const model,
+ const SerdNode* const node,
+ const ReadMode mode)
{
- const SerdNode* fst =
+ const SerdNode* const fst =
serd_model_get(model, node, ctx->loader->nodes.rdf_first, NULL, NULL);
- const SerdNode* rst =
+
+ const SerdNode* const rst =
serd_model_get(model, node, ctx->loader->nodes.rdf_rest, NULL, NULL);
+
if (fst && rst) {
read_node(ctx, forge, model, fst, mode);
read_list_value(ctx, forge, model, rst, mode);
@@ -126,21 +130,21 @@ read_list_value(LoadContext* ctx,
}
static void
-read_resource(LoadContext* ctx,
- LV2_Atom_Forge* forge,
- const SerdModel* model,
- const SerdNode* node,
- LV2_URID otype)
+read_resource(LoadContext* const ctx,
+ LV2_Atom_Forge* const forge,
+ const SerdModel* const model,
+ const SerdNode* const node,
+ const LV2_URID otype)
{
- LV2_URID_Map* map = ctx->loader->map;
- SerdRange* r = serd_model_range(model, node, NULL, NULL, NULL);
+ LV2_URID_Map* const map = ctx->loader->map;
+ SerdRange* const r = serd_model_range(model, node, NULL, NULL, NULL);
for (; !serd_range_empty(r); serd_range_next(r)) {
const SerdStatement* match = serd_range_front(r);
- const SerdNode* p = serd_statement_predicate(match);
- const SerdNode* o = serd_statement_object(match);
- if (p) {
- const char* p_uri = serd_node_string(p);
- uint32_t p_urid = map->map(map->handle, p_uri);
+ if (match) {
+ const SerdNode* const p = serd_statement_predicate(match);
+ const SerdNode* const o = serd_statement_object(match);
+ const char* const p_uri = serd_node_string(p);
+ const uint32_t p_urid = map->map(map->handle, p_uri);
if (!(serd_node_equals(p, ctx->loader->nodes.rdf_type) &&
serd_node_type(o) == SERD_URI &&
map->map(map->handle, serd_node_string(o)) == otype)) {
@@ -153,146 +157,184 @@ read_resource(LoadContext* ctx,
}
static uint32_t
-atom_size(SratomLoader* loader, uint32_t type_urid)
+atom_size(SratomLoader* const loader, const uint32_t type_urid)
{
- if (type_urid == loader->forge.Int) {
+ if (type_urid == loader->forge.Int || type_urid == loader->forge.Bool) {
return sizeof(int32_t);
- } else if (type_urid == loader->forge.Long) {
+ }
+
+ if (type_urid == loader->forge.URID) {
+ return sizeof(uint32_t);
+ }
+
+ if (type_urid == loader->forge.Long) {
return sizeof(int64_t);
- } else if (type_urid == loader->forge.Float) {
+ }
+
+ if (type_urid == loader->forge.Float) {
return sizeof(float);
- } else if (type_urid == loader->forge.Double) {
+ }
+
+ if (type_urid == loader->forge.Double) {
return sizeof(double);
- } else if (type_urid == loader->forge.Bool) {
- return sizeof(int32_t);
- } else if (type_urid == loader->forge.URID) {
- return sizeof(uint32_t);
}
+
return 0;
}
-static void
-read_uri(LoadContext* ctx, LV2_Atom_Forge* forge, const SerdNode* node)
+static SratomStatus
+read_uri(LoadContext* const ctx,
+ LV2_Atom_Forge* const forge,
+ const SerdNode* const node)
{
SratomLoader* const loader = ctx->loader;
LV2_URID_Map* const map = loader->map;
const char* const str = serd_node_string(node);
+ LV2_Atom_Forge_Ref ref = 0;
if (!strcmp(str, NS_RDF "nil")) {
- lv2_atom_forge_atom(forge, 0, 0);
+ ref = lv2_atom_forge_atom(forge, 0, 0);
} else if (!strncmp(str, "file://", 7)) {
- const SerdURIView base_uri = serd_node_uri_view(ctx->base_uri);
- const SerdURIView uri = serd_parse_uri(str);
- if (serd_uri_is_within(uri, base_uri)) {
+ const SerdURIView uri = serd_parse_uri(str);
+ if (ctx->base_uri &&
+ serd_uri_is_within(uri, serd_node_uri_view(ctx->base_uri))) {
SerdNode* const rel = serd_new_parsed_uri(serd_relative_uri(
serd_parse_uri(str), serd_node_uri_view(ctx->base_uri)));
- char* path = serd_parse_file_uri(serd_node_string(rel), NULL);
- lv2_atom_forge_path(forge, path, strlen(path));
+ char* const path = serd_parse_file_uri(serd_node_string(rel), NULL);
+ if (!path) {
+ return SRATOM_BAD_FILE_URI;
+ }
+
+ ref = lv2_atom_forge_path(forge, path, strlen(path));
serd_free(path);
serd_node_free(rel);
} else {
char* const path = serd_parse_file_uri(str, NULL);
- lv2_atom_forge_path(forge, path, strlen(path));
+ if (!path) {
+ return SRATOM_BAD_FILE_URI;
+ }
+
+ ref = lv2_atom_forge_path(forge, path, strlen(path));
serd_free(path);
}
} else {
- lv2_atom_forge_urid(forge, map->map(map->handle, str));
+ ref = lv2_atom_forge_urid(forge, map->map(map->handle, str));
}
+
+ return ref ? SRATOM_SUCCESS : SRATOM_BAD_FORGE;
}
-static void
+static SratomStatus
read_typed_literal(SratomLoader* const loader,
LV2_Atom_Forge* const forge,
const SerdNode* const node,
const SerdNode* const datatype)
{
- const char* const str = serd_node_string(node);
- const size_t len = serd_node_length(node);
- const char* const type_uri = serd_node_string(datatype);
+ const char* const str = serd_node_string(node);
+ const size_t len = serd_node_length(node);
+ const char* const type_uri = serd_node_string(datatype);
+ LV2_Atom_Forge_Ref ref = 0;
if (!strcmp(type_uri, NS_XSD "int") || !strcmp(type_uri, NS_XSD "integer")) {
- lv2_atom_forge_int(forge, strtol(str, NULL, 10));
+ ref = lv2_atom_forge_int(forge, strtol(str, NULL, 10));
} else if (!strcmp(type_uri, NS_XSD "long")) {
- lv2_atom_forge_long(forge, strtol(str, NULL, 10));
- } else if (!strcmp(type_uri, NS_XSD "float") ||
- !strcmp(type_uri, NS_XSD "decimal")) {
- lv2_atom_forge_float(forge, serd_get_float(node));
- } else if (!strcmp(type_uri, NS_XSD "double")) {
- lv2_atom_forge_double(forge, serd_get_double(node));
+ ref = lv2_atom_forge_long(forge, strtol(str, NULL, 10));
+ } else if (!strcmp(type_uri, NS_XSD "decimal") ||
+ !strcmp(type_uri, NS_XSD "double")) {
+ ref = lv2_atom_forge_double(forge, serd_get_double(node));
+ } else if (!strcmp(type_uri, NS_XSD "float")) {
+ ref = lv2_atom_forge_float(forge, serd_get_float(node));
} else if (!strcmp(type_uri, NS_XSD "boolean")) {
- lv2_atom_forge_bool(forge, serd_get_boolean(node));
+ ref = lv2_atom_forge_bool(forge, serd_get_boolean(node));
} else if (!strcmp(type_uri, NS_XSD "base64Binary")) {
- size_t size = 0;
- void* body = serd_base64_decode(str, len, &size);
- lv2_atom_forge_atom(forge, size, forge->Chunk);
- lv2_atom_forge_write(forge, body, size);
+ size_t size = 0;
+ void* const body = serd_base64_decode(str, len, &size);
+ if ((ref = lv2_atom_forge_atom(forge, size, forge->Chunk))) {
+ ref = lv2_atom_forge_write(forge, body, size);
+ }
free(body);
} else if (!strcmp(type_uri, LV2_ATOM__Path)) {
- lv2_atom_forge_path(forge, str, len);
+ ref = lv2_atom_forge_path(forge, str, len);
} else if (!strcmp(type_uri, LV2_MIDI__MidiEvent)) {
- lv2_atom_forge_atom(forge, len / 2, loader->midi_MidiEvent);
- for (const char* s = str; s < str + len; s += 2) {
- unsigned num;
- sscanf(s, "%2X", &num);
- const uint8_t c = num;
- lv2_atom_forge_raw(forge, &c, 1);
+ if ((ref = lv2_atom_forge_atom(forge, len / 2, loader->midi_MidiEvent))) {
+ for (const char* s = str; s < str + len; s += 2) {
+ unsigned num = 0u;
+ sscanf(s, "%2X", &num);
+ const uint8_t c = num;
+ if (!(ref = lv2_atom_forge_raw(forge, &c, 1))) {
+ return SRATOM_BAD_FORGE;
+ }
+ }
+ lv2_atom_forge_pad(forge, len / 2);
}
- lv2_atom_forge_pad(forge, len / 2);
} else {
- lv2_atom_forge_literal(
+ ref = lv2_atom_forge_literal(
forge, str, len, loader->map->map(loader->map->handle, type_uri), 0);
}
+
+ return ref ? SRATOM_SUCCESS : SRATOM_BAD_FORGE;
}
-static void
+static SratomStatus
read_plain_literal(SratomLoader* const loader,
LV2_Atom_Forge* const forge,
const SerdNode* const node,
const SerdNode* const language)
{
- const char* const str = serd_node_string(node);
- const size_t len = serd_node_length(node);
- const char* lang_str = serd_node_string(language);
- const char* prefix = "http://lexvo.org/id/iso639-3/";
- const size_t lang_len = strlen(prefix) + strlen(lang_str);
- char* const lang_uri = (char*)calloc(lang_len + 1, 1);
+ static const char* const prefix = "http://lexvo.org/id/iso639-3/";
+
+ const char* const str = serd_node_string(node);
+ const size_t len = serd_node_length(node);
+ const char* lang_str = serd_node_string(language);
+ const size_t prefix_len = strlen(prefix);
+ const size_t lang_len = prefix_len + strlen(lang_str);
+ char* const lang_uri = (char*)calloc(lang_len + 1, 1);
snprintf(lang_uri, lang_len + 1, "%s%s", prefix, lang_str);
- lv2_atom_forge_literal(
+ const LV2_Atom_Forge_Ref ref = lv2_atom_forge_literal(
forge, str, len, 0, loader->map->map(loader->map->handle, lang_uri));
free(lang_uri);
+
+ return ref ? SRATOM_SUCCESS : SRATOM_BAD_FORGE;
}
-static void
-read_literal(SratomLoader* loader, LV2_Atom_Forge* forge, const SerdNode* node)
+static SratomStatus
+read_literal(SratomLoader* const loader,
+ LV2_Atom_Forge* const forge,
+ const SerdNode* const node)
{
assert(serd_node_type(node) == SERD_LITERAL);
const SerdNode* const datatype = serd_node_datatype(node);
- const SerdNode* const language = serd_node_language(node);
if (datatype) {
- read_typed_literal(loader, forge, node, datatype);
- } else if (language) {
- read_plain_literal(loader, forge, node, language);
- } else {
- lv2_atom_forge_string(
- forge, serd_node_string(node), serd_node_length(node));
+ return read_typed_literal(loader, forge, node, datatype);
+ }
+
+ const SerdNode* const language = serd_node_language(node);
+ if (language) {
+ return read_plain_literal(loader, forge, node, language);
}
+
+ const LV2_Atom_Forge_Ref ref = lv2_atom_forge_string(
+ forge, serd_node_string(node), serd_node_length(node));
+
+ return ref ? SRATOM_SUCCESS : SRATOM_BAD_FORGE;
}
-static void
-read_object(LoadContext* ctx,
- LV2_Atom_Forge* forge,
- const SerdModel* model,
- const SerdNode* node,
- ReadMode mode)
+static SratomStatus
+read_object(LoadContext* const ctx,
+ LV2_Atom_Forge* const forge,
+ const SerdModel* const model,
+ const SerdNode* const node,
+ const ReadMode mode)
{
SratomLoader* const loader = ctx->loader;
LV2_URID_Map* const map = loader->map;
const char* const str = serd_node_string(node);
+ SratomStatus st = SRATOM_SUCCESS;
const SerdNode* const type =
serd_model_get(model, node, loader->nodes.rdf_type, NULL, NULL);
@@ -336,7 +378,7 @@ read_object(LoadContext* ctx,
ctx->seq_unit = 0;
read_list_value(ctx, forge, model, value, MODE_SEQUENCE);
- LV2_Atom_Sequence* seq =
+ LV2_Atom_Sequence* const seq =
(LV2_Atom_Sequence*)lv2_atom_forge_deref(forge, ref);
seq->body.unit =
((ctx->seq_unit == loader->atom_frameTime) ? 0 : ctx->seq_unit);
@@ -344,9 +386,13 @@ read_object(LoadContext* ctx,
} else if (type_urid == loader->forge.Vector) {
const SerdNode* child_type_node =
serd_model_get(model, node, loader->nodes.atom_childType, NULL, NULL);
- uint32_t child_type =
+ if (!child_type_node) {
+ return SRATOM_BAD_VECTOR;
+ }
+
+ const uint32_t child_type =
map->map(map->handle, serd_node_string(child_type_node));
- uint32_t child_size = atom_size(loader, child_type);
+ const uint32_t child_size = atom_size(loader, child_type);
if (child_size > 0) {
LV2_Atom_Forge_Ref ref =
lv2_atom_forge_vector_head(forge, &frame, child_size, child_type);
@@ -358,10 +404,10 @@ read_object(LoadContext* ctx,
} else if (value && serd_node_equals(serd_node_datatype(value),
loader->nodes.xsd_base64Binary)) {
- const char* vstr = serd_node_string(value);
- const size_t vlen = serd_node_length(value);
- size_t size = 0;
- void* body = serd_base64_decode(vstr, vlen, &size);
+ const char* const vstr = serd_node_string(value);
+ const size_t vlen = serd_node_length(value);
+ size_t size = 0;
+ void* body = serd_base64_decode(vstr, vlen, &size);
lv2_atom_forge_atom(forge, size, type_urid);
lv2_atom_forge_write(forge, body, size);
free(body);
@@ -372,7 +418,7 @@ read_object(LoadContext* ctx,
lv2_atom_forge_object(forge, &frame, urid, type_urid);
read_resource(ctx, forge, model, node, type_urid);
} else {
- read_uri(ctx, forge, node);
+ st = read_uri(ctx, forge, node);
}
} else {
@@ -383,41 +429,46 @@ read_object(LoadContext* ctx,
if (frame.ref) {
lv2_atom_forge_pop(forge, &frame);
}
+
+ return st;
}
-static void
-read_node(LoadContext* ctx,
- LV2_Atom_Forge* forge,
- const SerdModel* model,
- const SerdNode* node,
- ReadMode mode)
+static SratomStatus
+read_node(LoadContext* const ctx,
+ LV2_Atom_Forge* const forge,
+ const SerdModel* const model,
+ const SerdNode* const node,
+ const ReadMode mode)
{
if (serd_node_type(node) == SERD_LITERAL) {
- read_literal(ctx->loader, forge, node);
- } else if (serd_node_type(node) == SERD_URI && mode != MODE_SUBJECT) {
- read_uri(ctx, forge, node);
- } else {
- read_object(ctx, forge, model, node, mode);
+ return read_literal(ctx->loader, forge, node);
}
+
+ if (serd_node_type(node) == SERD_URI && mode != MODE_SUBJECT) {
+ return read_uri(ctx, forge, node);
+ }
+
+ return read_object(ctx, forge, model, node, mode);
}
-int
-sratom_load(SratomLoader* loader,
- const SerdNode* base_uri,
- LV2_Atom_Forge* forge,
- const SerdModel* model,
- const SerdNode* node)
+SratomStatus
+sratom_load(SratomLoader* const loader,
+ const SerdNode* const base_uri,
+ LV2_Atom_Forge* const forge,
+ const SerdModel* const model,
+ const SerdNode* const node)
{
LoadContext ctx = {loader, base_uri, 0};
- read_node(&ctx, forge, model, node, MODE_SUBJECT);
- return 0;
+ return read_node(&ctx, forge, model, node, MODE_SUBJECT);
}
static SerdModel*
-model_from_string(SratomLoader* loader, SerdEnv* env, const char* str)
+model_from_string(SratomLoader* const loader,
+ SerdEnv* const env,
+ const char* const str)
{
SerdModel* const model = serd_model_new(loader->world, SERD_INDEX_SPO);
- SerdSink* const inserter = serd_inserter_new(model, env, NULL);
+ SerdSink* const inserter = serd_inserter_new(model, NULL);
SerdNode* const name = serd_new_string(SERD_STATIC_STRING("string"));
SerdByteSource* const source = serd_byte_source_new_string(str, name);
@@ -446,15 +497,17 @@ sratom_from_string(SratomLoader* const loader,
SerdEnv* const env,
const char* const str)
{
- SerdModel* model = model_from_string(loader, env, str);
+ SerdModel* const model = model_from_string(loader, env, str);
if (!model || serd_model_empty(model)) {
LOAD_ERROR("Failed to read string into model");
return NULL;
}
- const SerdNode* node = NULL;
- SerdIter* begin = serd_model_begin(model);
- const SerdStatement* s = serd_iter_get(begin);
+ const SerdNode* node = NULL;
+ SerdIter* const begin = serd_model_begin(model);
+ const SerdStatement* const s = serd_iter_get(begin);
+
+ assert(s);
if (serd_model_size(model) == 2 &&
serd_node_type(serd_statement_subject(s)) == SERD_BLANK &&
serd_node_equals(serd_statement_predicate(s), loader->nodes.rdf_first)) {
@@ -478,28 +531,31 @@ sratom_from_string(SratomLoader* const loader,
}
static LV2_Atom_Forge_Ref
-sratom_forge_sink(LV2_Atom_Forge_Sink_Handle handle,
- const void* buf,
- uint32_t size)
+sratom_forge_sink(const LV2_Atom_Forge_Sink_Handle handle,
+ const void* const buf,
+ const uint32_t size)
{
- SerdBuffer* chunk = (SerdBuffer*)handle;
+ SerdBuffer* const chunk = (SerdBuffer*)handle;
const LV2_Atom_Forge_Ref ref = chunk->len + 1;
+
serd_buffer_sink(buf, 1, size, chunk);
return ref;
}
static LV2_Atom*
-sratom_forge_deref(LV2_Atom_Forge_Sink_Handle handle, LV2_Atom_Forge_Ref ref)
+sratom_forge_deref(const LV2_Atom_Forge_Sink_Handle handle,
+ const LV2_Atom_Forge_Ref ref)
{
- SerdBuffer* chunk = (SerdBuffer*)handle;
+ SerdBuffer* const chunk = (SerdBuffer*)handle;
+
return (LV2_Atom*)((char*)chunk->buf + ref - 1);
}
LV2_Atom*
-sratom_from_model(SratomLoader* loader,
- const SerdNode* base_uri,
- const SerdModel* model,
- const SerdNode* subject)
+sratom_from_model(SratomLoader* const loader,
+ const SerdNode* const base_uri,
+ const SerdModel* const model,
+ const SerdNode* const subject)
{
if (!subject) {
return NULL;
diff --git a/test/test_sratom.c b/test/test_sratom.c
index 12daea3..11154d4 100644
--- a/test/test_sratom.c
+++ b/test/test_sratom.c
@@ -1,5 +1,5 @@
/*
- Copyright 2012-2016 David Robillard <http://drobilla.net>
+ Copyright 2012-2021 David Robillard <d@drobilla.net>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -14,16 +14,20 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include "test_utils.h"
+
#include "sratom/sratom.h"
#include "lv2/atom/atom.h"
#include "lv2/atom/forge.h"
+#include "lv2/atom/util.h"
#include "lv2/midi/midi.h"
#include "lv2/urid/urid.h"
#include "serd/serd.h"
#include <assert.h>
#include <stdbool.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -32,49 +36,6 @@
#define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
#define NS_XSD "http://www.w3.org/2001/XMLSchema#"
-/// Simple O(n) URI map
-typedef struct {
- char** uris;
- uint32_t n_uris;
-} Uris;
-
-static char*
-copy_string(const char* str)
-{
- const size_t len = strlen(str);
- char* dup = (char*)malloc(len + 1);
- memcpy(dup, str, len + 1);
- return dup;
-}
-
-static LV2_URID
-urid_map(LV2_URID_Map_Handle handle, const char* uri)
-{
- Uris* const uris = (Uris*)handle;
-
- for (uint32_t i = 0; i < uris->n_uris; ++i) {
- if (!strcmp(uris->uris[i], uri)) {
- return i + 1;
- }
- }
-
- uris->uris = (char**)realloc(uris->uris, ++uris->n_uris * sizeof(char*));
- uris->uris[uris->n_uris - 1] = copy_string(uri);
- return uris->n_uris;
-}
-
-static const char*
-urid_unmap(LV2_URID_Unmap_Handle handle, LV2_URID urid)
-{
- Uris* const uris = (Uris*)handle;
-
- if (urid > 0 && urid <= uris->n_uris) {
- return uris->uris[urid - 1];
- }
-
- return NULL;
-}
-
static int
check_round_trip(Uris* uris,
SerdEnv* env,