diff options
author | David Robillard <d@drobilla.net> | 2022-01-02 21:21:50 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2022-01-28 21:57:29 -0500 |
commit | 0b6260d46e57acfbe6f65301d9951836178bde6e (patch) | |
tree | 77d0ce977336ce03d0b98064335e22662652f45e | |
parent | 6e274953587941934e8f291d2dd99b843d5580ab (diff) | |
download | serd-0b6260d46e57acfbe6f65301d9951836178bde6e.tar.gz serd-0b6260d46e57acfbe6f65301d9951836178bde6e.tar.bz2 serd-0b6260d46e57acfbe6f65301d9951836178bde6e.zip |
Consolidate number support into a single "value" API
-rw-r--r-- | doc/conf.py.in | 5 | ||||
-rw-r--r-- | include/serd/serd.h | 267 | ||||
-rw-r--r-- | meson.build | 1 | ||||
-rw-r--r-- | src/node.c | 309 | ||||
-rw-r--r-- | src/node.h | 7 | ||||
-rw-r--r-- | src/nodes.c | 22 | ||||
-rw-r--r-- | src/value.c | 114 | ||||
-rw-r--r-- | test/test_node.c | 351 | ||||
-rw-r--r-- | test/test_node_syntax.c | 15 | ||||
-rw-r--r-- | test/test_nodes.c | 16 |
10 files changed, 685 insertions, 422 deletions
diff --git a/doc/conf.py.in b/doc/conf.py.in index 39d9568f..8760bbd9 100644 --- a/doc/conf.py.in +++ b/doc/conf.py.in @@ -35,9 +35,14 @@ _opaque = [ "SerdStatementImpl", "SerdWorldImpl", "SerdWriterImpl", + "int16_t", + "int32_t", "int64_t", + "int8_t", "size_t", + "uint16_t", "uint32_t", + "uint64_t", "uint8_t", "uintptr_t", "va_list", diff --git a/include/serd/serd.h b/include/serd/serd.h index 49046054..c09494bc 100644 --- a/include/serd/serd.h +++ b/include/serd/serd.h @@ -741,6 +741,116 @@ typedef enum { } SerdNodeType; /** + @defgroup serd_node_value Values + + Serd supports reading and writing machine-native numbers, called "values", + in a standards-conformant and portable way. The value structure is used in + the API to allow passing and returning a primitive value of any supported + type. Note that this is just an API convenience, literal nodes themselves + always store their values as strings. + + @{ +*/ + +/// The type of a #SerdValue +typedef enum { + SERD_NOTHING, ///< Sentinel for unknown datatypes or errors + SERD_BOOL, ///< xsd:boolean (bool) + SERD_DOUBLE, ///< xsd:double (double) + SERD_FLOAT, ///< xsd:float (float) + SERD_LONG, ///< xsd:long (int64_t) + SERD_INT, ///< xsd:integer (int32_t) + SERD_SHORT, ///< xsd:short (int16_t) + SERD_BYTE, ///< xsd:byte (int8_t) + SERD_ULONG, ///< xsd:unsignedLong (uint64_t) + SERD_UINT, ///< xsd:unsignedInt (uint32_t) + SERD_USHORT, ///< xsd:unsignedShort (uint16_t) + SERD_UBYTE, ///< xsd:unsignedByte (uint8_t) +} SerdValueType; + +/// The data of a #SerdValue (the actual machine-native primitive) +typedef union { + bool as_bool; + double as_double; + float as_float; + int64_t as_long; + int32_t as_int; + int16_t as_short; + int8_t as_byte; + uint64_t as_ulong; + uint32_t as_uint; + uint16_t as_ushort; + uint8_t as_ubyte; +} SerdValueData; + +/// A primitive value with a type tag +typedef struct { + SerdValueType type; + SerdValueData data; +} SerdValue; + +/// Convenience constructor to make a #SERD_NOTHING (non-)value +SERD_CONST_API +SerdValue +serd_nothing(void); + +/// Convenience constructor to make a #SERD_BOOL value +SERD_CONST_API +SerdValue +serd_bool(bool v); + +/// Convenience constructor to make a #SERD_DOUBLE value +SERD_CONST_API +SerdValue +serd_double(double v); + +/// Convenience constructor to make a #SERD_FLOAT value +SERD_CONST_API +SerdValue +serd_float(float v); + +/// Convenience constructor to make a #SERD_LONG value +SERD_CONST_API +SerdValue +serd_long(int64_t v); + +/// Convenience constructor to make a #SERD_INT value +SERD_CONST_API +SerdValue +serd_int(int32_t v); + +/// Convenience constructor to make a #SERD_SHORT value +SERD_CONST_API +SerdValue +serd_short(int16_t v); + +/// Convenience constructor to make a #SERD_BYTE value +SERD_CONST_API +SerdValue +serd_byte(int8_t v); + +/// Convenience constructor to make a #SERD_ULONG value +SERD_CONST_API +SerdValue +serd_ulong(uint64_t v); + +/// Convenience constructor to make a #SERD_UINT value +SERD_CONST_API +SerdValue +serd_uint(uint32_t v); + +/// Convenience constructor to make a #SERD_USHORT value +SERD_CONST_API +SerdValue +serd_ushort(uint16_t v); + +/// Convenience constructor to make a #SERD_UBYTE value +SERD_CONST_API +SerdValue +serd_ubyte(uint8_t v); + +/** + @} @defgroup serd_node_construction Construction This is the low-level node construction API, which can be used to construct @@ -864,18 +974,15 @@ serd_node_construct_literal(size_t buf_size, SerdStringView meta); /** - Construct a canonical xsd:boolean literal. - - The constructed node will be either "true" or "false", with datatype - xsd:boolean. + Construct a canonical literal for a primitive value. - This is a convenience wrapper for serd_node_construct_literal() that - constructs a node directly from a `bool`. + The constructed node will be a typed literal in canonical form for the xsd + datatype corresponding to the value. */ SerdWriteResult -serd_node_construct_boolean(size_t buf_size, - void* SERD_NULLABLE buf, - bool value); +serd_node_construct_value(size_t buf_size, + void* SERD_NULLABLE buf, + SerdValue value); /** Construct a canonical xsd:decimal literal. @@ -896,38 +1003,6 @@ serd_node_construct_decimal(size_t buf_size, double value); /** - Construct a canonical xsd:double literal. - - The constructed node will be an xsd:double literal, like "1.23E45", with - datatype xsd:double. A canonical xsd:double is always in scientific - notation. - - This is a convenience wrapper for serd_node_construct_literal() that - constructs a node directly from a `double`. -*/ -SerdWriteResult -serd_node_construct_double(size_t buf_size, - void* SERD_NULLABLE buf, - double value); - -/** - Construct a canonical xsd:float literal. - - The constructed node will be an xsd:float literal, like "1.23E45", with - datatype xsd:float. A canonical xsd:float is always in scientific notation. - - Uses identical formatting to serd_node_construct_double(), except with at - most 9 significant digits (under 14 characters total). - - This is a convenience wrapper for serd_node_construct_literal() that - constructs a node directly from a `float`. -*/ -SerdWriteResult -serd_node_construct_float(size_t buf_size, - void* SERD_NULLABLE buf, - float value); - -/** Construct a canonical xsd:integer literal. The constructed node will be an xsd:integer literal like "1234", with the @@ -1069,17 +1144,17 @@ serd_new_literal(SerdAllocator* SERD_NULLABLE allocator, SerdStringView meta); /** - Create a new canonical xsd:boolean node. + Create a new canonical value node. - This is a wrapper for serd_node_construct_boolean() that allocates a new - node on the heap. + This is a wrapper for serd_node_construct_value() that allocates a new node + on the heap. @return A newly allocated node that must be freed with serd_node_free(), or null. */ SERD_API SerdNode* SERD_ALLOCATED -serd_new_boolean(SerdAllocator* SERD_NULLABLE allocator, bool b); +serd_new_value(SerdAllocator* SERD_NULLABLE allocator, SerdValue value); /** Create a new canonical xsd:decimal literal. @@ -1095,32 +1170,6 @@ SerdNode* SERD_ALLOCATED serd_new_decimal(SerdAllocator* SERD_NULLABLE allocator, double d); /** - Create a new canonical xsd:double literal. - - This is a wrapper for serd_node_construct_double() that allocates a new - node on the heap. - - @return A newly allocated node that must be freed with serd_node_free(), or - null. -*/ -SERD_API -SerdNode* SERD_ALLOCATED -serd_new_double(SerdAllocator* SERD_NULLABLE allocator, double d); - -/** - Create a new canonical xsd:float literal. - - This is a wrapper for serd_node_construct_float() that allocates a new - node on the heap. - - @return A newly allocated node that must be freed with serd_node_free(), or - null. -*/ -SERD_API -SerdNode* SERD_ALLOCATED -serd_new_float(SerdAllocator* SERD_NULLABLE allocator, float f); - -/** Create a new canonical xsd:integer literal. This is a wrapper for serd_node_construct_integer() that allocates a new @@ -1153,49 +1202,39 @@ serd_new_base64(SerdAllocator* SERD_NULLABLE allocator, */ /** - Return the value of `node` as a boolean. + Return the primitive value of `node`. - This will work for booleans, and numbers of any datatype if they are 0 or - 1. + This will return a typed value if the node can be read as one, or a value + with type #SERD_NOTHING otherwise. - @return The value of `node` as a `bool`, or `false` on error. + @return The value of `node` as a #SerdValue, if possible. */ SERD_API -bool -serd_get_boolean(const SerdNode* SERD_NONNULL node); +SerdValue +serd_get_value(const SerdNode* SERD_NONNULL node); /** - Return the value of `node` as a double. + Return the value of `node` as a specific type of number. - This will coerce numbers of any datatype to double, if the value fits. + This is like serd_get_number(), but will coerce the value of the node to the + requrested type if possible. - @return The value of `node` as a `double`, or NaN on error. -*/ -SERD_API -double -serd_get_double(const SerdNode* SERD_NONNULL node); + @param node The node to interpret as a number. -/** - Return the value of `node` as a float. + @param type The desired numeric datatype of the result. - This will coerce numbers of any datatype to float, if the value fits. + @param lossy Whether lossy conversions can be used. If this is false, then + this function only succeeds if the value could be converted back to the + original datatype of the node without loss. Otherwise, precision may be + reduced or values may be truncated to fit the result. - @return The value of `node` as a `float`, or NaN on error. + @return The value of `node` as a #SerdValue, or nothing. */ SERD_API -float -serd_get_float(const SerdNode* SERD_NONNULL node); - -/** - Return the value of `node` as a long (signed 64-bit integer). - - This will coerce numbers of any datatype to long, if the value fits. - - @return The value of `node` as a `int64_t`, or 0 on error. -*/ -SERD_API -int64_t -serd_get_integer(const SerdNode* SERD_NONNULL node); +SerdValue +serd_get_value_as(const SerdNode* SERD_NONNULL node, + SerdValueType type, + bool lossy); /** Return the maximum size of a decoded base64 node in bytes. @@ -1426,14 +1465,14 @@ serd_nodes_literal(SerdNodes* SERD_NONNULL nodes, SerdStringView meta); /** - Make a canonical xsd:boolean node. + Make a canonical value node. - A new node will be constructed with serd_node_construct_boolean() if an + A new node will be constructed with serd_node_construct_value() if an equivalent one is not already in the set. */ SERD_API const SerdNode* SERD_ALLOCATED -serd_nodes_boolean(SerdNodes* SERD_NONNULL nodes, bool value); +serd_nodes_value(SerdNodes* SERD_NONNULL nodes, SerdValue value); /** Make a canonical xsd:decimal node. @@ -1446,26 +1485,6 @@ const SerdNode* SERD_ALLOCATED serd_nodes_decimal(SerdNodes* SERD_NONNULL nodes, double value); /** - Make a canonical xsd:double node. - - A new node will be constructed with serd_node_construct_double() if an - equivalent one is not already in the set. -*/ -SERD_API -const SerdNode* SERD_ALLOCATED -serd_nodes_double(SerdNodes* SERD_NONNULL nodes, double value); - -/** - Make a canonical xsd:float node. - - A new node will be constructed with serd_node_construct_float() if an - equivalent one is not already in the set. -*/ -SERD_API -const SerdNode* SERD_ALLOCATED -serd_nodes_float(SerdNodes* SERD_NONNULL nodes, float value); - -/** Make a canonical xsd:integer node. A new node will be constructed with serd_node_construct_integer() if an diff --git a/meson.build b/meson.build index 57547bfc..f94c9dd1 100644 --- a/meson.build +++ b/meson.build @@ -118,6 +118,7 @@ sources = [ 'src/syntax.c', 'src/system.c', 'src/uri.c', + 'src/value.c', 'src/world.c', 'src/writer.c', ] @@ -24,7 +24,6 @@ #include "serd/serd.h" #include <assert.h> -#include <math.h> #include <stdbool.h> #include <stdint.h> #include <string.h> @@ -37,6 +36,21 @@ static const SerdNodeFlags meta_mask = (SERD_HAS_DATATYPE | SERD_HAS_LANGUAGE); +static const ExessDatatype value_type_datatypes[] = { + EXESS_NOTHING, + EXESS_BOOLEAN, + EXESS_DOUBLE, + EXESS_FLOAT, + EXESS_LONG, + EXESS_INT, + EXESS_SHORT, + EXESS_BYTE, + EXESS_ULONG, + EXESS_UINT, + EXESS_USHORT, + EXESS_UBYTE, +}; + // Round size up to an even multiple of the node alignment static size_t serd_node_pad_size(const size_t size) @@ -281,21 +295,122 @@ serd_node_construct(const size_t buf_size, : serd_node_construct_token(buf_size, buf, type, string)); } +static ExessDatatype +value_type_datatype(const SerdValueType value_type) +{ + return (value_type > SERD_UBYTE) ? EXESS_NOTHING + : value_type_datatypes[value_type]; +} + +static const char* +value_type_uri(const SerdValueType value_type) +{ + return exess_datatype_uri(value_type_datatype(value_type)); +} + +static inline SerdValueType +datatype_value_type(const ExessDatatype datatype) +{ + switch (datatype) { + case EXESS_NOTHING: + return SERD_NOTHING; + case EXESS_BOOLEAN: + return SERD_BOOL; + case EXESS_DECIMAL: + case EXESS_DOUBLE: + return SERD_DOUBLE; + case EXESS_FLOAT: + return SERD_FLOAT; + case EXESS_INTEGER: + case EXESS_NON_POSITIVE_INTEGER: + case EXESS_NEGATIVE_INTEGER: + case EXESS_LONG: + return SERD_LONG; + case EXESS_INT: + return SERD_INT; + case EXESS_SHORT: + return SERD_SHORT; + case EXESS_BYTE: + return SERD_BYTE; + case EXESS_NON_NEGATIVE_INTEGER: + case EXESS_ULONG: + return SERD_ULONG; + case EXESS_UINT: + return SERD_UINT; + case EXESS_USHORT: + return SERD_USHORT; + case EXESS_UBYTE: + return SERD_UBYTE; + case EXESS_POSITIVE_INTEGER: + return SERD_ULONG; + + case EXESS_DURATION: + case EXESS_DATETIME: + case EXESS_TIME: + case EXESS_DATE: + case EXESS_HEX: + case EXESS_BASE64: + break; + } + + return SERD_NOTHING; +} + SerdWriteResult -serd_node_construct_boolean(const size_t buf_size, - void* const buf, - const bool value) -{ - char temp[EXESS_MAX_BOOLEAN_LENGTH + 1] = {0}; +serd_node_construct_value(const size_t buf_size, + void* const buf, + const SerdValue value) +{ + char temp[EXESS_MAX_DOUBLE_LENGTH + 1] = {0}; + ExessResult r = {EXESS_UNSUPPORTED, 0u}; + switch (value.type) { + case SERD_NOTHING: + return result(SERD_BAD_ARG, 0u); + case SERD_BOOL: + r = exess_write_boolean(value.data.as_bool, sizeof(temp), temp); + break; + case SERD_DOUBLE: + r = exess_write_double(value.data.as_double, sizeof(temp), temp); + break; + case SERD_FLOAT: + r = exess_write_float(value.data.as_float, sizeof(temp), temp); + break; + case SERD_LONG: + r = exess_write_long(value.data.as_long, sizeof(temp), temp); + break; + case SERD_INT: + r = exess_write_int(value.data.as_int, sizeof(temp), temp); + break; + case SERD_SHORT: + r = exess_write_short(value.data.as_short, sizeof(temp), temp); + break; + case SERD_BYTE: + r = exess_write_byte(value.data.as_byte, sizeof(temp), temp); + break; + case SERD_ULONG: + r = exess_write_ulong(value.data.as_ulong, sizeof(temp), temp); + break; + case SERD_UINT: + r = exess_write_uint(value.data.as_uint, sizeof(temp), temp); + break; + case SERD_USHORT: + r = exess_write_ushort(value.data.as_ushort, sizeof(temp), temp); + break; + case SERD_UBYTE: + r = exess_write_ubyte(value.data.as_ubyte, sizeof(temp), temp); + break; + } - const ExessResult r = exess_write_boolean(value, sizeof(temp), temp); MUST_SUCCEED(r.status); // The only error is buffer overrun + const char* const datatype_uri = value_type_uri(value.type); + assert(datatype_uri); + return serd_node_construct_literal(buf_size, buf, SERD_SUBSTRING(temp, r.count), SERD_HAS_DATATYPE, - SERD_STRING(EXESS_XSD_URI "boolean")); + SERD_OPTIONAL_STRING(datatype_uri)); } SerdWriteResult @@ -316,40 +431,6 @@ serd_node_construct_decimal(const size_t buf_size, } SerdWriteResult -serd_node_construct_double(const size_t buf_size, - void* const buf, - const double value) -{ - char temp[EXESS_MAX_DOUBLE_LENGTH + 1] = {0}; - - const ExessResult r = exess_write_double(value, sizeof(temp), temp); - MUST_SUCCEED(r.status); // The only error is buffer overrun - - return serd_node_construct_literal(buf_size, - buf, - SERD_SUBSTRING(temp, r.count), - SERD_HAS_DATATYPE, - SERD_STRING(EXESS_XSD_URI "double")); -} - -SerdWriteResult -serd_node_construct_float(const size_t buf_size, - void* const buf, - const float value) -{ - char temp[EXESS_MAX_FLOAT_LENGTH + 1] = {0}; - - const ExessResult r = exess_write_float(value, sizeof(temp), temp); - MUST_SUCCEED(r.status); // The only error is buffer overrun - - return serd_node_construct_literal(buf_size, - buf, - SERD_SUBSTRING(temp, r.count), - SERD_HAS_DATATYPE, - SERD_STRING(EXESS_XSD_URI "float")); -} - -SerdWriteResult serd_node_construct_integer(const size_t buf_size, void* const buf, const int64_t value) @@ -503,91 +584,69 @@ serd_new_literal(SerdAllocator* const allocator, return serd_node_new(allocator, SERD_LITERAL, str, flags, meta); } -ExessResult -serd_node_get_value_as(const SerdNode* const node, - const ExessDatatype value_type, - const size_t value_size, - void* const value) +SerdValue +serd_get_value(const SerdNode* const node) { + assert(node); + const SerdNode* const datatype_node = serd_node_datatype(node); - const ExessDatatype node_type = + const ExessDatatype datatype = 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; + const SerdValueType value_type = datatype_value_type(datatype); + if (value_type == SERD_NOTHING) { + return serd_nothing(); } - // 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)); + ExessValue value = {false}; + const ExessVariableResult vr = + exess_read_value(datatype, sizeof(value), &value, serd_node_string(node)); if (vr.status) { - const ExessResult r = {vr.status, 0u}; - return r; + return serd_nothing(); } - // 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) -{ - assert(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) -{ - assert(node); - - double value = (double)NAN; // NOLINT(google-readability-casting) - serd_node_get_value_as(node, EXESS_DOUBLE, sizeof(value), &value); + SerdValue result = {value_type, {false}}; + memcpy(&result.data, &value, vr.write_count); - return value; + return result; } -float -serd_get_float(const SerdNode* const node) +SerdValue +serd_get_value_as(const SerdNode* const node, + const SerdValueType type, + const bool lossy) { - assert(node); + // Get the value as it is + const SerdValue value = serd_get_value(node); + if (!value.type || value.type == type) { + return value; + } - float value = (float)NAN; // NOLINT(google-readability-casting) - serd_node_get_value_as(node, EXESS_FLOAT, sizeof(value), &value); + const ExessCoercions coercions = + lossy ? (EXESS_REDUCE_PRECISION | EXESS_ROUND | EXESS_TRUNCATE) + : EXESS_LOSSLESS; - return value; -} + const ExessDatatype node_datatype = value_type_datatype(value.type); + const ExessDatatype datatype = value_type_datatype(type); + SerdValue result = {type, {false}}; -int64_t -serd_get_integer(const SerdNode* const node) -{ - assert(node); + // Coerce to the desired type + const ExessResult r = exess_value_coerce(coercions, + node_datatype, + exess_value_size(node_datatype), + &value.data, + datatype, + exess_value_size(datatype), + &result.data); - int64_t value = 0; - serd_node_get_value_as(node, EXESS_LONG, sizeof(value), &value); + if (r.status) { + result.type = SERD_NOTHING; + } - return value; + return result; } size_t @@ -784,45 +843,13 @@ serd_new_file_uri(SerdAllocator* const allocator, } SerdNode* -serd_new_double(SerdAllocator* const allocator, const double d) -{ - SerdWriteResult r = serd_node_construct_double(0, NULL, d); - SerdNode* const node = serd_node_try_malloc(allocator, r); - - if (node) { - r = serd_node_construct_double(r.count, node, d); - MUST_SUCCEED(r.status); - assert(serd_node_length(node) == strlen(serd_node_string(node))); - serd_node_check_padding(node); - } - - return node; -} - -SerdNode* -serd_new_float(SerdAllocator* const allocator, const float f) -{ - SerdWriteResult r = serd_node_construct_float(0, NULL, f); - SerdNode* const node = serd_node_try_malloc(allocator, r); - - if (node) { - r = serd_node_construct_float(r.count, node, f); - MUST_SUCCEED(r.status); - assert(serd_node_length(node) == strlen(serd_node_string(node))); - serd_node_check_padding(node); - } - - return node; -} - -SerdNode* -serd_new_boolean(SerdAllocator* const allocator, bool b) +serd_new_value(SerdAllocator* const allocator, const SerdValue value) { - SerdWriteResult r = serd_node_construct_boolean(0, NULL, b); + SerdWriteResult r = serd_node_construct_value(0, NULL, value); SerdNode* const node = serd_node_try_malloc(allocator, r); if (node) { - r = serd_node_construct_boolean(r.count, node, b); + r = serd_node_construct_value(r.count, node, value); MUST_SUCCEED(r.status); assert(serd_node_length(node) == strlen(serd_node_string(node))); serd_node_check_padding(node); @@ -17,7 +17,6 @@ #ifndef SERD_NODE_H #define SERD_NODE_H -#include "exess/exess.h" #include "serd/serd.h" #include <assert.h> @@ -121,10 +120,4 @@ serd_node_total_size(const SerdNode* SERD_NONNULL node); void serd_node_zero_pad(SerdNode* SERD_NONNULL node); -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/nodes.c b/src/nodes.c index 90dd4f2c..c048863b 100644 --- a/src/nodes.c +++ b/src/nodes.c @@ -415,12 +415,12 @@ try_intern(SerdNodes* const nodes, } const SerdNode* -serd_nodes_boolean(SerdNodes* const nodes, bool value) +serd_nodes_value(SerdNodes* const nodes, const SerdValue value) { StaticNode key = empty_static_node; return try_intern( - nodes, serd_node_construct_boolean(sizeof(key), &key, value), &key.node); + nodes, serd_node_construct_value(sizeof(key), &key, value), &key.node); } const SerdNode* @@ -433,24 +433,6 @@ serd_nodes_decimal(SerdNodes* const nodes, const double value) } const SerdNode* -serd_nodes_double(SerdNodes* const nodes, const double value) -{ - StaticNode key = empty_static_node; - - return try_intern( - nodes, serd_node_construct_double(sizeof(key), &key, value), &key.node); -} - -const SerdNode* -serd_nodes_float(SerdNodes* const nodes, const float value) -{ - StaticNode key = empty_static_node; - - return try_intern( - nodes, serd_node_construct_float(sizeof(key), &key, value), &key.node); -} - -const SerdNode* serd_nodes_integer(SerdNodes* const nodes, const int64_t value) { StaticNode key = empty_static_node; diff --git a/src/value.c b/src/value.c new file mode 100644 index 00000000..bd6320bf --- /dev/null +++ b/src/value.c @@ -0,0 +1,114 @@ +/* + Copyright 2022 David Robillard <d@drobilla.net> + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include "serd/serd.h" + +#include <stdbool.h> +#include <stdint.h> + +SerdValue +serd_nothing(void) +{ + static const SerdValue value = {SERD_NOTHING, {0}}; + return value; +} + +SerdValue +serd_bool(const bool v) +{ + const SerdValue value = {SERD_BOOL, {v}}; + return value; +} + +SerdValue +serd_double(const double v) +{ + SerdValue value = {SERD_DOUBLE, {0}}; + value.data.as_double = v; + return value; +} + +SerdValue +serd_float(const float v) +{ + SerdValue value = {SERD_FLOAT, {0}}; + value.data.as_float = v; + return value; +} + +SerdValue +serd_long(const int64_t v) +{ + SerdValue value = {SERD_LONG, {0}}; + value.data.as_long = v; + return value; +} + +SerdValue +serd_int(const int32_t v) +{ + SerdValue value = {SERD_INT, {0}}; + value.data.as_int = v; + return value; +} + +SerdValue +serd_short(const int16_t v) +{ + SerdValue value = {SERD_SHORT, {0}}; + value.data.as_short = v; + return value; +} + +SerdValue +serd_byte(const int8_t v) +{ + SerdValue value = {SERD_BYTE, {0}}; + value.data.as_byte = v; + return value; +} + +SerdValue +serd_ulong(const uint64_t v) +{ + SerdValue value = {SERD_ULONG, {0}}; + value.data.as_ulong = v; + return value; +} + +SerdValue +serd_uint(const uint32_t v) +{ + SerdValue value = {SERD_UINT, {0}}; + value.data.as_uint = v; + return value; +} + +SerdValue +serd_ushort(const uint16_t v) +{ + SerdValue value = {SERD_USHORT, {0}}; + value.data.as_ushort = v; + return value; +} + +SerdValue +serd_ubyte(const uint8_t v) +{ + SerdValue value = {SERD_UBYTE, {0}}; + value.data.as_ubyte = v; + return value; +} diff --git a/test/test_node.c b/test/test_node.c index c1d39053..5cba7013 100644 --- a/test/test_node.c +++ b/test/test_node.c @@ -57,54 +57,156 @@ #endif static void +test_value(void) +{ + static const double double_one = 1.0; + static const float float_two = 2.0f; + + SerdNode* const null_node = serd_new_value(NULL, serd_nothing()); + SerdNode* const bool_node = serd_new_value(NULL, serd_bool(false)); + SerdNode* const double_node = serd_new_value(NULL, serd_double(1.0)); + SerdNode* const float_node = serd_new_value(NULL, serd_float(2.0f)); + SerdNode* const long_node = serd_new_value(NULL, serd_long(3)); + SerdNode* const int_node = serd_new_value(NULL, serd_int(4)); + SerdNode* const short_node = serd_new_value(NULL, serd_short(5)); + SerdNode* const byte_node = serd_new_value(NULL, serd_byte(6)); + SerdNode* const ulong_node = serd_new_value(NULL, serd_ulong(7u)); + SerdNode* const uint_node = serd_new_value(NULL, serd_uint(8u)); + SerdNode* const ushort_node = serd_new_value(NULL, serd_ushort(9u)); + SerdNode* const ubyte_node = serd_new_value(NULL, serd_ubyte(10u)); + + assert(!null_node); + + assert(!strcmp(serd_node_string(bool_node), "false")); + assert(serd_get_value(bool_node).type == SERD_BOOL); + assert(serd_get_value(bool_node).data.as_bool == false); + + assert(!strcmp(serd_node_string(double_node), "1.0E0")); + assert(serd_get_value(double_node).type == SERD_DOUBLE); + { + const double double_value = serd_get_value(double_node).data.as_double; + assert(!memcmp(&double_value, &double_one, sizeof(double))); + } + + assert(!strcmp(serd_node_string(float_node), "2.0E0")); + assert(serd_get_value(float_node).type == SERD_FLOAT); + { + const float float_value = serd_get_value(float_node).data.as_float; + assert(!memcmp(&float_value, &float_two, sizeof(float))); + } + + assert(!strcmp(serd_node_string(long_node), "3")); + assert(serd_get_value(long_node).type == SERD_LONG); + assert(serd_get_value(long_node).data.as_long == 3); + + assert(!strcmp(serd_node_string(int_node), "4")); + assert(serd_get_value(int_node).type == SERD_INT); + assert(serd_get_value(int_node).data.as_int == 4); + + assert(!strcmp(serd_node_string(short_node), "5")); + assert(serd_get_value(short_node).type == SERD_SHORT); + assert(serd_get_value(short_node).data.as_short == 5); + + assert(!strcmp(serd_node_string(byte_node), "6")); + assert(serd_get_value(byte_node).type == SERD_BYTE); + assert(serd_get_value(byte_node).data.as_byte == 6); + + assert(!strcmp(serd_node_string(ulong_node), "7")); + assert(serd_get_value(ulong_node).type == SERD_ULONG); + assert(serd_get_value(ulong_node).data.as_ulong == 7u); + + assert(!strcmp(serd_node_string(uint_node), "8")); + assert(serd_get_value(uint_node).type == SERD_UINT); + assert(serd_get_value(uint_node).data.as_uint == 8u); + + assert(!strcmp(serd_node_string(ushort_node), "9")); + assert(serd_get_value(ushort_node).type == SERD_USHORT); + assert(serd_get_value(ushort_node).data.as_ushort == 9u); + + assert(!strcmp(serd_node_string(ubyte_node), "10")); + assert(serd_get_value(ubyte_node).type == SERD_UBYTE); + assert(serd_get_value(ubyte_node).data.as_ubyte == 10u); + + serd_node_free(NULL, bool_node); + serd_node_free(NULL, double_node); + serd_node_free(NULL, float_node); + serd_node_free(NULL, long_node); + serd_node_free(NULL, int_node); + serd_node_free(NULL, short_node); + serd_node_free(NULL, byte_node); + serd_node_free(NULL, ulong_node); + serd_node_free(NULL, uint_node); + serd_node_free(NULL, ushort_node); + serd_node_free(NULL, ubyte_node); +} + +static void test_boolean(void) { - SerdNode* const true_node = serd_new_boolean(NULL, true); - assert(!strcmp(serd_node_string(true_node), "true")); - assert(serd_get_boolean(true_node)); - - const SerdNode* const true_datatype = serd_node_datatype(true_node); - assert(true_datatype); - assert(!strcmp(serd_node_string(true_datatype), NS_XSD "boolean")); - serd_node_free(NULL, true_node); - - SerdNode* const false_node = serd_new_boolean(NULL, false); - assert(!strcmp(serd_node_string(false_node), "false")); - assert(!serd_get_boolean(false_node)); - - const SerdNode* const false_datatype = serd_node_datatype(false_node); - assert(false_datatype); - assert(!strcmp(serd_node_string(false_datatype), NS_XSD "boolean")); - serd_node_free(NULL, false_node); + { + SerdNode* const true_node = serd_new_value(NULL, serd_bool(true)); + assert(true_node); + assert(!strcmp(serd_node_string(true_node), "true")); + assert(serd_get_value(true_node).data.as_bool); + + const SerdNode* const true_datatype = serd_node_datatype(true_node); + assert(true_datatype); + assert(!strcmp(serd_node_string(true_datatype), NS_XSD "boolean")); + serd_node_free(NULL, true_node); + } + { + SerdNode* const false_node = serd_new_value(NULL, serd_bool(false)); + assert(false_node); + assert(!strcmp(serd_node_string(false_node), "false")); + assert(!serd_get_value(false_node).data.as_bool); + + const SerdNode* const false_datatype = serd_node_datatype(false_node); + assert(false_datatype); + assert(!strcmp(serd_node_string(false_datatype), NS_XSD "boolean")); + serd_node_free(NULL, false_node); + } } static void -check_get_boolean(const char* string, - const char* datatype_uri, - const bool expected) +check_get_bool(const char* string, + const char* datatype_uri, + const bool lossy, + const SerdValueType value_type, + const bool expected) { SerdNode* const node = serd_new_literal( NULL, SERD_STRING(string), SERD_HAS_DATATYPE, SERD_STRING(datatype_uri)); assert(node); - assert(serd_get_boolean(node) == expected); + + const SerdValue value = serd_get_value_as(node, SERD_BOOL, lossy); + + assert(value.type == value_type); + assert(value.data.as_bool == expected); serd_node_free(NULL, node); } static void -test_get_boolean(void) +test_get_bool(void) { - check_get_boolean("false", NS_XSD "boolean", false); - check_get_boolean("true", NS_XSD "boolean", true); - check_get_boolean("0", NS_XSD "boolean", false); - check_get_boolean("1", NS_XSD "boolean", true); - check_get_boolean("0", NS_XSD "integer", false); - check_get_boolean("1", NS_XSD "integer", true); - check_get_boolean("0.0", NS_XSD "double", false); - check_get_boolean("1.0", NS_XSD "double", true); - check_get_boolean("unknown", NS_XSD "string", false); - check_get_boolean("!invalid", NS_XSD "long", false); + check_get_bool("false", NS_XSD "boolean", false, SERD_BOOL, false); + check_get_bool("true", NS_XSD "boolean", false, SERD_BOOL, true); + check_get_bool("0", NS_XSD "boolean", false, SERD_BOOL, false); + check_get_bool("1", NS_XSD "boolean", false, SERD_BOOL, true); + check_get_bool("0", NS_XSD "integer", false, SERD_BOOL, false); + check_get_bool("1", NS_XSD "integer", false, SERD_BOOL, true); + check_get_bool("0.0", NS_XSD "double", false, SERD_BOOL, false); + check_get_bool("1.0", NS_XSD "double", false, SERD_BOOL, true); + + check_get_bool("2", NS_XSD "integer", false, SERD_NOTHING, false); + check_get_bool("1.5", NS_XSD "double", false, SERD_NOTHING, false); + + check_get_bool("2", NS_XSD "integer", true, SERD_BOOL, true); + check_get_bool("1.5", NS_XSD "double", true, SERD_BOOL, true); + + check_get_bool("unknown", NS_XSD "string", true, SERD_NOTHING, false); + check_get_bool("!invalid", NS_XSD "long", true, SERD_NOTHING, false); } static void @@ -134,8 +236,8 @@ test_decimal(void) assert(datatype); assert(!strcmp(serd_node_string(datatype), NS_XSD "decimal")); - const double value = serd_get_double(node); - assert(!memcmp(&value, &test_values[i], sizeof(value))); + const SerdValue value = serd_get_value(node); + assert(!memcmp(&value.data.as_double, &test_values[i], sizeof(double))); serd_node_free(NULL, node); } } @@ -148,7 +250,7 @@ test_double(void) "0.0E0", "-0.0E0", "1.2E0", "-2.3E0", "4.56789E6"}; for (size_t i = 0; i < sizeof(test_values) / sizeof(double); ++i) { - SerdNode* node = serd_new_double(NULL, test_values[i]); + SerdNode* node = serd_new_value(NULL, serd_double(test_values[i])); const char* node_str = serd_node_string(node); assert(!strcmp(node_str, test_strings[i])); @@ -159,24 +261,35 @@ test_double(void) assert(datatype); assert(!strcmp(serd_node_string(datatype), NS_XSD "double")); - const double value = serd_get_double(node); - assert(!memcmp(&value, &test_values[i], sizeof(value))); + const SerdValue value = serd_get_value(node); + assert(!memcmp(&value.data.as_double, &test_values[i], sizeof(double))); serd_node_free(NULL, node); } } static void -check_get_double(const char* string, - const char* datatype_uri, - const double expected) +check_get_double(const char* string, + const char* datatype_uri, + const bool lossy, + const SerdValueType value_type, + const double expected) { SerdNode* const node = serd_new_literal( NULL, SERD_STRING(string), SERD_HAS_DATATYPE, SERD_STRING(datatype_uri)); assert(node); - const double value = serd_get_double(node); - assert(!memcmp(&value, &expected, sizeof(value))); + const SerdValue value = serd_get_value_as(node, SERD_DOUBLE, lossy); + + assert(value.type == value_type); + + SERD_DISABLE_CONVERSION_WARNINGS + + assert(value_type == SERD_NOTHING || + ((isnan(value.data.as_double) && isnan(expected)) || + !memcmp(&value.data.as_double, &expected, sizeof(double)))); + + SERD_RESTORE_WARNINGS serd_node_free(NULL, node); } @@ -184,34 +297,19 @@ check_get_double(const char* string, static void test_get_double(void) { - check_get_double("1.2", NS_XSD "double", 1.2); - check_get_double("-.5", NS_XSD "float", -0.5); - check_get_double("-67", NS_XSD "long", -67.0); - check_get_double("8.9", NS_XSD "decimal", 8.9); - check_get_double("false", NS_XSD "boolean", 0.0); - check_get_double("true", NS_XSD "boolean", 1.0); - - static const uint8_t blob[] = {1u, 2u, 3u, 4u}; + check_get_double("1.2", NS_XSD "double", false, SERD_DOUBLE, 1.2); + check_get_double("-.5", NS_XSD "float", false, SERD_DOUBLE, -0.5); + check_get_double("-67", NS_XSD "long", false, SERD_DOUBLE, -67.0); + check_get_double("67", NS_XSD "unsignedLong", false, SERD_DOUBLE, 67.0); + check_get_double("8.9", NS_XSD "decimal", false, SERD_DOUBLE, 8.9); + check_get_double("false", NS_XSD "boolean", false, SERD_DOUBLE, 0.0); + check_get_double("true", NS_XSD "boolean", false, SERD_DOUBLE, 1.0); SERD_DISABLE_CONVERSION_WARNINGS - - SerdNode* const nan = serd_new_string(NULL, SERD_STRING("unknown")); - assert(isnan(serd_get_double(nan))); - serd_node_free(NULL, nan); - - SerdNode* const invalid = serd_new_literal(NULL, - SERD_STRING("!invalid"), - SERD_HAS_DATATYPE, - SERD_STRING(NS_XSD "long")); - - assert(isnan(serd_get_double(invalid))); - serd_node_free(NULL, invalid); - - SerdNode* const base64 = serd_new_base64(NULL, blob, sizeof(blob)); - - assert(isnan(serd_get_double(base64))); - serd_node_free(NULL, base64); - + check_get_double("str", NS_XSD "string", true, SERD_NOTHING, NAN); + check_get_double("!invalid", NS_XSD "long", true, SERD_NOTHING, NAN); + check_get_double("D3AD", NS_XSD "hexBinary", true, SERD_NOTHING, NAN); + check_get_double("Zm9v", NS_XSD "base64Binary", true, SERD_NOTHING, NAN); SERD_RESTORE_WARNINGS } @@ -223,7 +321,7 @@ test_float(void) "0.0E0", "-0.0E0", "1.5E0", "-2.5E0", "4.56789E6"}; for (size_t i = 0; i < sizeof(test_values) / sizeof(float); ++i) { - SerdNode* node = serd_new_float(NULL, test_values[i]); + SerdNode* node = serd_new_value(NULL, serd_float(test_values[i])); const char* node_str = serd_node_string(node); assert(!strcmp(node_str, test_strings[i])); @@ -234,24 +332,35 @@ test_float(void) assert(datatype); assert(!strcmp(serd_node_string(datatype), NS_XSD "float")); - const float value = serd_get_float(node); - assert(!memcmp(&value, &test_values[i], sizeof(value))); + const SerdValue value = serd_get_value(node); + assert(!memcmp(&value.data.as_float, &test_values[i], sizeof(float))); serd_node_free(NULL, node); } } static void -check_get_float(const char* string, - const char* datatype_uri, - const float expected) +check_get_float(const char* string, + const char* datatype_uri, + const bool lossy, + const SerdValueType value_type, + const float expected) { SerdNode* const node = serd_new_literal( NULL, SERD_STRING(string), SERD_HAS_DATATYPE, SERD_STRING(datatype_uri)); assert(node); - const float value = serd_get_float(node); - assert(!memcmp(&value, &expected, sizeof(value))); + const SerdValue value = serd_get_value_as(node, SERD_FLOAT, lossy); + + assert(value.type == value_type); + + SERD_DISABLE_CONVERSION_WARNINGS + + assert(value_type == SERD_NOTHING || + ((isnan(value.data.as_float) && isnan(expected)) || + !memcmp(&value.data.as_float, &expected, sizeof(float)))); + + SERD_RESTORE_WARNINGS serd_node_free(NULL, node); } @@ -259,29 +368,20 @@ check_get_float(const char* string, static void test_get_float(void) { - check_get_float("1.2", NS_XSD "float", 1.2f); - check_get_float("-.5", NS_XSD "float", -0.5f); - check_get_float("-67", NS_XSD "long", -67.0f); - check_get_float("1.5", NS_XSD "decimal", 1.5f); - check_get_float("false", NS_XSD "boolean", 0.0f); - check_get_float("true", NS_XSD "boolean", 1.0f); - - SERD_DISABLE_CONVERSION_WARNINGS + check_get_float("1.2", NS_XSD "float", false, SERD_FLOAT, 1.2f); + check_get_float("-.5", NS_XSD "float", false, SERD_FLOAT, -0.5f); + check_get_float("-67", NS_XSD "long", false, SERD_FLOAT, -67.0f); + check_get_float("false", NS_XSD "boolean", false, SERD_FLOAT, 0.0f); + check_get_float("true", NS_XSD "boolean", false, SERD_FLOAT, 1.0f); - SerdNode* const nan = serd_new_string(NULL, SERD_STRING("unknown")); - assert(isnan(serd_get_float(nan))); - serd_node_free(NULL, nan); - - SerdNode* const invalid = serd_new_literal(NULL, - SERD_STRING("!invalid"), - SERD_HAS_DATATYPE, - SERD_STRING(NS_XSD "long")); - - assert(isnan(serd_get_double(invalid))); + check_get_float("1.5", NS_XSD "decimal", true, SERD_FLOAT, 1.5f); + SERD_DISABLE_CONVERSION_WARNINGS + check_get_float("str", NS_XSD "string", true, SERD_NOTHING, NAN); + check_get_float("!invalid", NS_XSD "long", true, SERD_NOTHING, NAN); + check_get_float("D3AD", NS_XSD "hexBinary", true, SERD_NOTHING, NAN); + check_get_float("Zm9v", NS_XSD "base64Binary", true, SERD_NOTHING, NAN); SERD_RESTORE_WARNINGS - - serd_node_free(NULL, invalid); } static void @@ -302,21 +402,27 @@ test_integer(void) assert(datatype); assert(!strcmp(serd_node_string(datatype), NS_XSD "integer")); - assert(serd_get_integer(node) == test_values[i]); + assert(serd_get_value(node).data.as_long == test_values[i]); serd_node_free(NULL, node); } } static void -check_get_integer(const char* string, - const char* datatype_uri, - const int64_t expected) +check_get_integer(const char* string, + const char* datatype_uri, + const bool lossy, + const SerdValueType value_type, + const int64_t expected) { SerdNode* const node = serd_new_literal( NULL, SERD_STRING(string), SERD_HAS_DATATYPE, SERD_STRING(datatype_uri)); assert(node); - assert(serd_get_integer(node) == expected); + + const SerdValue value = serd_get_value_as(node, SERD_LONG, lossy); + + assert(value.type == value_type); + assert(value_type == SERD_NOTHING || value.data.as_long == expected); serd_node_free(NULL, node); } @@ -324,14 +430,23 @@ check_get_integer(const char* string, static void test_get_integer(void) { - check_get_integer("12", NS_XSD "long", 12); - check_get_integer("-34", NS_XSD "long", -34); - check_get_integer("56", NS_XSD "integer", 56); - check_get_integer("false", NS_XSD "boolean", 0); - check_get_integer("true", NS_XSD "boolean", 1); - check_get_integer("78.0", NS_XSD "decimal", 78); - check_get_integer("unknown", NS_XSD "string", 0); - check_get_integer("!invalid", NS_XSD "long", 0); + check_get_integer("12", NS_XSD "long", false, SERD_LONG, 12); + check_get_integer("-34", NS_XSD "long", false, SERD_LONG, -34); + check_get_integer("56", NS_XSD "integer", false, SERD_LONG, 56); + check_get_integer("false", NS_XSD "boolean", false, SERD_LONG, 0); + check_get_integer("true", NS_XSD "boolean", false, SERD_LONG, 1); + check_get_integer("78.0", NS_XSD "decimal", false, SERD_LONG, 78); + + check_get_integer("0", NS_XSD "nonPositiveInteger", false, SERD_LONG, 0); + check_get_integer("-1", NS_XSD "negativeInteger", false, SERD_LONG, -1); + check_get_integer("2", NS_XSD "nonNegativeInteger", false, SERD_LONG, 2); + check_get_integer("3", NS_XSD "positiveInteger", false, SERD_LONG, 3); + + check_get_integer("78.5", NS_XSD "decimal", false, SERD_NOTHING, 0); + check_get_integer("78.5", NS_XSD "decimal", true, SERD_LONG, 78); + + check_get_integer("unknown", NS_XSD "string", true, SERD_NOTHING, 0); + check_get_integer("!invalid", NS_XSD "long", true, SERD_NOTHING, 0); } static void @@ -592,10 +707,11 @@ test_compare(void) SerdNode* hallo = serd_new_literal( NULL, SERD_STRING("Hallo"), SERD_HAS_LANGUAGE, SERD_STRING("de")); - SerdNode* hello = serd_new_string(NULL, SERD_STRING("Hello")); - SerdNode* universe = serd_new_string(NULL, SERD_STRING("Universe")); - SerdNode* integer = serd_new_integer(NULL, 4); - SerdNode* blank = serd_new_token(NULL, SERD_BLANK, SERD_STRING("b1")); + SerdNode* hello = serd_new_string(NULL, SERD_STRING("Hello")); + SerdNode* universe = serd_new_string(NULL, SERD_STRING("Universe")); + SerdNode* integer = serd_new_integer(NULL, 4); + SerdNode* short_integer = serd_new_value(NULL, serd_short(4)); + SerdNode* blank = serd_new_token(NULL, SERD_BLANK, SERD_STRING("b1")); SerdNode* uri = serd_new_uri(NULL, SERD_STRING("http://example.org/")); @@ -621,12 +737,14 @@ test_compare(void) assert(serd_node_compare(angst, angst_de) < 0); assert(serd_node_compare(angst_de, angst_en) < 0); assert(serd_node_compare(aardvark, badger) < 0); + assert(serd_node_compare(integer, short_integer) < 0); + serd_node_free(NULL, badger); + serd_node_free(NULL, aardvark); serd_node_free(NULL, uri); serd_node_free(NULL, blank); + serd_node_free(NULL, short_integer); serd_node_free(NULL, integer); - serd_node_free(NULL, badger); - serd_node_free(NULL, aardvark); serd_node_free(NULL, universe); serd_node_free(NULL, hello); serd_node_free(NULL, hallo); @@ -639,8 +757,9 @@ test_compare(void) int main(void) { + test_value(); test_boolean(); - test_get_boolean(); + test_get_bool(); test_decimal(); test_double(); test_get_double(); diff --git a/test/test_node_syntax.c b/test/test_node_syntax.c index 09037363..a8e0a163 100644 --- a/test/test_node_syntax.c +++ b/test/test_node_syntax.c @@ -130,12 +130,12 @@ test_common(SerdWorld* const world, const SerdSyntax syntax) assert(check(world, syntax, - serd_new_double(NULL, 1.25), + serd_new_value(NULL, serd_double(1.25)), "\"1.25E0\"^^<http://www.w3.org/2001/XMLSchema#double>")); assert(check(world, syntax, - serd_new_float(NULL, 1.25), + serd_new_value(NULL, serd_float(1.25f)), "\"1.25E0\"^^<http://www.w3.org/2001/XMLSchema#float>")); assert( @@ -186,12 +186,12 @@ test_ntriples(void) assert(check(world, SERD_NTRIPLES, - serd_new_boolean(NULL, true), + serd_new_value(NULL, serd_bool(true)), "\"true\"^^<http://www.w3.org/2001/XMLSchema#boolean>")); assert(check(world, SERD_NTRIPLES, - serd_new_boolean(NULL, false), + serd_new_value(NULL, serd_bool(false)), "\"false\"^^<http://www.w3.org/2001/XMLSchema#boolean>")); serd_world_free(world); @@ -212,8 +212,11 @@ test_turtle(void) assert(check(world, SERD_TURTLE, serd_new_decimal(NULL, 1.25), "1.25")); assert(check(world, SERD_TURTLE, serd_new_integer(NULL, 1234), "1234")); - assert(check(world, SERD_TURTLE, serd_new_boolean(NULL, true), "true")); - assert(check(world, SERD_TURTLE, serd_new_boolean(NULL, false), "false")); + assert( + check(world, SERD_TURTLE, serd_new_value(NULL, serd_bool(true)), "true")); + + assert( + check(world, SERD_TURTLE, serd_new_value(NULL, serd_bool(false)), "false")); serd_world_free(world); } diff --git a/test/test_nodes.c b/test/test_nodes.c index 19dcee01..482c7727 100644 --- a/test/test_nodes.c +++ b/test/test_nodes.c @@ -232,10 +232,10 @@ test_boolean(void) SerdNodes* const nodes = serd_nodes_new(allocator); - const SerdNode* const false1 = serd_nodes_boolean(nodes, false); - const SerdNode* const false2 = serd_nodes_boolean(nodes, false); - const SerdNode* const true1 = serd_nodes_boolean(nodes, true); - const SerdNode* const true2 = serd_nodes_boolean(nodes, true); + const SerdNode* const false1 = serd_nodes_value(nodes, serd_bool(false)); + const SerdNode* const false2 = serd_nodes_value(nodes, serd_bool(false)); + const SerdNode* const true1 = serd_nodes_value(nodes, serd_bool(true)); + const SerdNode* const true2 = serd_nodes_value(nodes, serd_bool(true)); assert(false1 == false2); assert(true1 == true2); @@ -285,8 +285,8 @@ test_double(void) SerdNodes* const nodes = serd_nodes_new(allocator); - const SerdNode* const a = serd_nodes_double(nodes, -1.2E3); - const SerdNode* const b = serd_nodes_double(nodes, -1.2E3); + const SerdNode* const a = serd_nodes_value(nodes, serd_double(-1.2E3)); + const SerdNode* const b = serd_nodes_value(nodes, serd_double(-1.2E3)); assert(a == b); assert(!strcmp(serd_node_string(a), "-1.2E3")); @@ -303,8 +303,8 @@ test_float(void) SerdNodes* const nodes = serd_nodes_new(allocator); - const SerdNode* const a = serd_nodes_float(nodes, -1.2E3f); - const SerdNode* const b = serd_nodes_float(nodes, -1.2E3f); + const SerdNode* const a = serd_nodes_value(nodes, serd_float(-1.2E3f)); + const SerdNode* const b = serd_nodes_value(nodes, serd_float(-1.2E3f)); assert(a == b); assert(!strcmp(serd_node_string(a), "-1.2E3")); |