aboutsummaryrefslogtreecommitdiffstats
path: root/include/serd/serd.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/serd/serd.h')
-rw-r--r--include/serd/serd.h267
1 files changed, 143 insertions, 124 deletions
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