aboutsummaryrefslogtreecommitdiffstats
path: root/src/node.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2019-10-06 20:59:12 +0200
committerDavid Robillard <d@drobilla.net>2022-01-13 23:03:44 -0500
commitd88b5a797f8502c40d0da964d653a1cd3028c872 (patch)
treebf2cbf8370515f24333b2c859fedf6c27877da12 /src/node.c
parent2ddf10fb8bfabff3ecdbe9ea866a905631ec2866 (diff)
downloadserd-d88b5a797f8502c40d0da964d653a1cd3028c872.tar.gz
serd-d88b5a797f8502c40d0da964d653a1cd3028c872.tar.bz2
serd-d88b5a797f8502c40d0da964d653a1cd3028c872.zip
Clean up numeric node construction and access API
Diffstat (limited to 'src/node.c')
-rw-r--r--src/node.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/src/node.c b/src/node.c
index b5a7816b..5016200d 100644
--- a/src/node.c
+++ b/src/node.c
@@ -25,6 +25,7 @@
#include "serd/serd.h"
#include <assert.h>
+#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
@@ -306,6 +307,85 @@ serd_new_curie(const SerdStringView str)
return serd_new_simple_node(SERD_CURIE, str);
}
+ExessResult
+serd_node_get_value_as(const SerdNode* const node,
+ const ExessDatatype value_type,
+ const size_t value_size,
+ void* const value)
+{
+ const SerdNode* const datatype_node = serd_node_datatype(node);
+
+ const ExessDatatype node_type =
+ datatype_node ? exess_datatype_from_uri(serd_node_string(datatype_node))
+ : EXESS_NOTHING;
+
+ if (node_type == EXESS_NOTHING ||
+ (node_type == EXESS_HEX && value_type == EXESS_BASE64) ||
+ (node_type == EXESS_BASE64 && value_type == EXESS_HEX)) {
+ // Try to read the large or untyped node string directly into the result
+ const ExessVariableResult vr =
+ exess_read_value(value_type, value_size, value, serd_node_string(node));
+
+ const ExessResult r = {vr.status, vr.write_count};
+ return r;
+ }
+
+ // Read the (smallish) value from the node
+ ExessValue node_value = {false};
+ const ExessVariableResult vr = exess_read_value(
+ node_type, sizeof(node_value), &node_value, serd_node_string(node));
+
+ if (vr.status) {
+ const ExessResult r = {vr.status, 0u};
+ return r;
+ }
+
+ // Coerce value to the desired type if possible
+ return exess_value_coerce(EXESS_REDUCE_PRECISION,
+ node_type,
+ vr.write_count,
+ &node_value,
+ value_type,
+ value_size,
+ value);
+}
+
+bool
+serd_get_boolean(const SerdNode* const node)
+{
+ bool value = false;
+ serd_node_get_value_as(node, EXESS_BOOLEAN, sizeof(value), &value);
+
+ return value;
+}
+
+double
+serd_get_double(const SerdNode* const node)
+{
+ double value = (double)NAN; // NOLINT(google-readability-casting)
+ serd_node_get_value_as(node, EXESS_DOUBLE, sizeof(value), &value);
+
+ return value;
+}
+
+float
+serd_get_float(const SerdNode* const node)
+{
+ float value = (float)NAN; // NOLINT(google-readability-casting)
+ serd_node_get_value_as(node, EXESS_FLOAT, sizeof(value), &value);
+
+ return value;
+}
+
+int64_t
+serd_get_integer(const SerdNode* const node)
+{
+ int64_t value = 0;
+ serd_node_get_value_as(node, EXESS_LONG, sizeof(value), &value);
+
+ return value;
+}
+
SerdNode*
serd_node_copy(const SerdNode* node)
{
@@ -515,6 +595,30 @@ serd_new_custom_literal(const void* const user_data,
}
SerdNode*
+serd_new_double(const double d)
+{
+ char buf[EXESS_MAX_DOUBLE_LENGTH + 1] = {0};
+
+ const ExessResult r = exess_write_double(d, sizeof(buf), buf);
+
+ return r.status ? NULL
+ : serd_new_typed_literal(SERD_SUBSTRING(buf, r.count),
+ SERD_STRING(EXESS_XSD_URI "double"));
+}
+
+SerdNode*
+serd_new_float(const float f)
+{
+ char buf[EXESS_MAX_FLOAT_LENGTH + 1] = {0};
+
+ const ExessResult r = exess_write_float(f, sizeof(buf), buf);
+
+ return r.status ? NULL
+ : serd_new_typed_literal(SERD_SUBSTRING(buf, r.count),
+ SERD_STRING(EXESS_XSD_URI "float"));
+}
+
+SerdNode*
serd_new_boolean(bool b)
{
return serd_new_typed_literal(b ? SERD_STRING("true") : SERD_STRING("false"),