From d88b5a797f8502c40d0da964d653a1cd3028c872 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 6 Oct 2019 20:59:12 +0200 Subject: Clean up numeric node construction and access API --- src/node.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/node.h | 7 ++++ src/static_nodes.h | 2 ++ src/string.c | 14 -------- 4 files changed, 113 insertions(+), 14 deletions(-) (limited to 'src') 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 +#include #include #include #include @@ -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) { @@ -514,6 +594,30 @@ serd_new_custom_literal(const void* const user_data, return node; } +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) { 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 @@ -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 -#include #include #include @@ -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; -} -- cgit v1.2.1