aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/node.c104
-rw-r--r--src/node.h7
-rw-r--r--src/static_nodes.h2
-rw-r--r--src/string.c14
4 files changed, 113 insertions, 14 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"),
diff --git a/src/node.h b/src/node.h
index 73af0d63..bb03f949 100644
--- a/src/node.h
+++ b/src/node.h
@@ -17,6 +17,7 @@
#ifndef SERD_NODE_H
#define SERD_NODE_H
+#include "exess/exess.h"
#include "serd/serd.h"
#include <stddef.h>
@@ -56,4 +57,10 @@ serd_node_zero_pad(SerdNode* SERD_NONNULL node);
SerdNode* SERD_ALLOCATED
serd_new_resolved_uri(SerdStringView string, SerdURIView base_uri);
+ExessResult
+serd_node_get_value_as(const SerdNode* SERD_NONNULL node,
+ ExessDatatype value_type,
+ size_t value_size,
+ void* SERD_NONNULL value);
+
#endif // SERD_NODE_H
diff --git a/src/static_nodes.h b/src/static_nodes.h
index 952c0634..adbb5849 100644
--- a/src/static_nodes.h
+++ b/src/static_nodes.h
@@ -34,6 +34,8 @@ typedef struct StaticNode {
DEFINE_XSD_NODE(base64Binary)
DEFINE_XSD_NODE(boolean)
DEFINE_XSD_NODE(decimal)
+DEFINE_XSD_NODE(double)
+DEFINE_XSD_NODE(float)
DEFINE_XSD_NODE(integer)
#endif // SERD_STATIC_NODES_H
diff --git a/src/string.c b/src/string.c
index c5b1d6f7..842beeef 100644
--- a/src/string.c
+++ b/src/string.c
@@ -16,11 +16,9 @@
#include "string_utils.h"
-#include "exess/exess.h"
#include "serd/serd.h"
#include <assert.h>
-#include <math.h>
#include <stdlib.h>
#include <string.h>
@@ -105,15 +103,3 @@ serd_strlen(const char* const str, SerdNodeFlags* const flags)
return strlen(str);
}
-
-double
-serd_strtod(const char* const str, const char** const end)
-{
- double value = (double)NAN;
- const ExessResult r = exess_read_double(&value, str);
- if (end) {
- *end = str + r.count;
- }
-
- return r.status ? (double)NAN : value;
-}