diff options
author | David Robillard <d@drobilla.net> | 2021-02-25 20:08:20 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2021-03-08 23:23:05 -0500 |
commit | 01a76c7d703650df7f39d21c704f5b7c4f41ca14 (patch) | |
tree | 0d662aaceb9b6dee2cc2f566cd67aa20fa0939ca /src | |
parent | 3bf35cb9e72709fb417cff0d5a2dc9b681e5ecb1 (diff) | |
download | serd-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.c | 64 | ||||
-rw-r--r-- | src/node.h | 5 | ||||
-rw-r--r-- | src/string.c | 12 |
3 files changed, 68 insertions, 13 deletions
@@ -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; @@ -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; -} |