diff options
author | David Robillard <d@drobilla.net> | 2019-10-06 20:59:12 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2022-01-13 23:03:44 -0500 |
commit | d88b5a797f8502c40d0da964d653a1cd3028c872 (patch) | |
tree | bf2cbf8370515f24333b2c859fedf6c27877da12 /src | |
parent | 2ddf10fb8bfabff3ecdbe9ea866a905631ec2866 (diff) | |
download | serd-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.c | 104 | ||||
-rw-r--r-- | src/node.h | 7 | ||||
-rw-r--r-- | src/static_nodes.h | 2 | ||||
-rw-r--r-- | src/string.c | 14 |
4 files changed, 113 insertions, 14 deletions
@@ -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"), @@ -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; -} |