aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-02-25 20:08:20 -0500
committerDavid Robillard <d@drobilla.net>2021-03-08 23:23:05 -0500
commit01a76c7d703650df7f39d21c704f5b7c4f41ca14 (patch)
tree0d662aaceb9b6dee2cc2f566cd67aa20fa0939ca /src
parent3bf35cb9e72709fb417cff0d5a2dc9b681e5ecb1 (diff)
downloadserd-01a76c7d703650df7f39d21c704f5b7c4f41ca14.tar.gz
serd-01a76c7d703650df7f39d21c704f5b7c4f41ca14.tar.bz2
serd-01a76c7d703650df7f39d21c704f5b7c4f41ca14.zip
Add numeric node construction and access API
Diffstat (limited to 'src')
-rw-r--r--src/node.c64
-rw-r--r--src/node.h5
-rw-r--r--src/string.c12
3 files changed, 68 insertions, 13 deletions
diff --git a/src/node.c b/src/node.c
index db183fc0..f071fc97 100644
--- a/src/node.c
+++ b/src/node.c
@@ -276,6 +276,68 @@ serd_new_curie(const SerdStringView str)
return serd_new_simple_node(SERD_CURIE, str);
}
+ExessVariant
+serd_node_get_value_as(const SerdNode* const node,
+ const ExessDatatype value_type)
+{
+ 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) {
+ // No datatype, assume it matches and try reading the value directly
+ ExessVariant v = exess_make_nothing(EXESS_SUCCESS);
+ const ExessResult r =
+ exess_read_variant(&v, value_type, serd_node_string(node));
+
+ return r.status ? exess_make_nothing(r.status) : v;
+ }
+
+ // Read the value from the node
+ ExessVariant v = exess_make_nothing(EXESS_SUCCESS);
+ const ExessResult r =
+ exess_read_variant(&v, node_type, serd_node_string(node));
+
+ // Coerce value to the desired type if possible
+ return r.status ? exess_make_nothing(r.status)
+ : exess_coerce(v, value_type, EXESS_REDUCE_PRECISION);
+}
+
+bool
+serd_get_boolean(const SerdNode* const node)
+{
+ const ExessVariant value = serd_node_get_value_as(node, EXESS_BOOLEAN);
+
+ return (value.datatype == EXESS_BOOLEAN) ? *exess_get_boolean(&value) : false;
+}
+
+double
+serd_get_double(const SerdNode* const node)
+{
+ const ExessVariant value = serd_node_get_value_as(node, EXESS_DOUBLE);
+
+ return (value.datatype == EXESS_DOUBLE) ? *exess_get_double(&value)
+ : (double)NAN;
+}
+
+float
+serd_get_float(const SerdNode* const node)
+{
+ const ExessVariant value = serd_node_get_value_as(node, EXESS_FLOAT);
+
+ return (value.datatype == EXESS_FLOAT) ? *exess_get_float(&value) : NAN;
+}
+
+int64_t
+serd_get_integer(const SerdNode* const node)
+{
+ const ExessVariant value = serd_node_get_value_as(node, EXESS_LONG);
+
+ return (value.datatype == EXESS_LONG) ? *exess_get_long(&value) : 0;
+}
+
SerdNode*
serd_node_copy(const SerdNode* node)
{
@@ -585,7 +647,7 @@ serd_new_decimal(const double d, const SerdNode* const datatype)
}
SerdNode*
-serd_new_integer(int64_t i, const SerdNode* datatype)
+serd_new_integer(const int64_t i, const SerdNode* datatype)
{
const ExessVariant variant = exess_make_long(i);
const size_t len = exess_write_variant(variant, 0, NULL).count;
diff --git a/src/node.h b/src/node.h
index 6bebdb6d..3d01bae7 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>
@@ -53,4 +54,8 @@ serd_node_zero_pad(SerdNode* SERD_NONNULL node);
SerdNode* SERD_ALLOCATED
serd_new_resolved_uri(SerdStringView string, SerdURIView base_uri);
+ExessVariant
+serd_node_get_value_as(const SerdNode* SERD_NONNULL node,
+ ExessDatatype value_type);
+
#endif // SERD_NODE_H
diff --git a/src/string.c b/src/string.c
index 6e28778b..f59a5fd6 100644
--- a/src/string.c
+++ b/src/string.c
@@ -107,15 +107,3 @@ serd_strlen(const char* str, SerdNodeFlags* flags)
return strlen(str);
}
-
-double
-serd_strtod(const char* const str, const char** 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;
-}