diff options
author | David Robillard <d@drobilla.net> | 2022-12-18 21:06:25 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2023-12-02 18:49:07 -0500 |
commit | 9c613b337712314c169d4add61212f4fc4102022 (patch) | |
tree | fe9191bed8d6aaf6339c82fe447def74e22ef11b /src/node.c | |
parent | a970f06aba98736223214a6fa995f4e82acd7132 (diff) | |
download | serd-9c613b337712314c169d4add61212f4fc4102022.tar.gz serd-9c613b337712314c169d4add61212f4fc4102022.tar.bz2 serd-9c613b337712314c169d4add61212f4fc4102022.zip |
Clean up numeric node construction and access API
Diffstat (limited to 'src/node.c')
-rw-r--r-- | src/node.c | 104 |
1 files changed, 104 insertions, 0 deletions
@@ -16,6 +16,7 @@ #include "serd/uri.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_token(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) { @@ -534,6 +614,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_decimal(const double d, const SerdNode* const datatype) { // Use given datatype, or xsd:decimal as a default if it is null |