aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--include/serd/serd.h32
-rw-r--r--meson.build1
-rw-r--r--src/node.c26
-rw-r--r--src/static_nodes.h2
-rw-r--r--src/string.c2
6 files changed, 63 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index d900e544..2b792055 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
serd (1.0.1) unstable;
* Add SerdBuffer for mutable buffers to keep SerdChunk const-correct
+ * Add support for xsd:float and xsd:double literals
* Bring read/write interface closer to C standard
* Make nodes opaque
* Remove serd_uri_to_path()
diff --git a/include/serd/serd.h b/include/serd/serd.h
index fdae8ac7..e1a28fdf 100644
--- a/include/serd/serd.h
+++ b/include/serd/serd.h
@@ -627,7 +627,37 @@ SerdNode* SERD_ALLOCATED
serd_new_decimal(double d, const SerdNode* SERD_NULLABLE datatype);
/**
- Create a new node by serialising `i` into an xsd:integer string.
+ Create a new node by serialising `d` into a normalised xsd:double string.
+
+ The returned node will always be in normalised scientific notation, like
+ "1.23E4", except for NaN and negative/positive infinity, which are "NaN",
+ "-INF", and "INF", respectively.
+
+ Uses the shortest possible representation that precisely describes `d`,
+ which has at most 17 significant digits (under 24 characters total).
+
+ @param d Double value to serialise.
+ @return A literal node with datatype xsd:double.
+*/
+SERD_API
+SerdNode* SERD_ALLOCATED
+serd_new_double(double d);
+
+/**
+ Create a new node by serialising `f` into a normalised xsd:float string.
+
+ Uses identical formatting to serd_new_double(), except with at most 9
+ significant digits (under 14 characters total).
+
+ @param f Float value to serialise.
+ @return A literal node with datatype xsd:float.
+*/
+SERD_API
+SerdNode* SERD_ALLOCATED
+serd_new_float(float f);
+
+/**
+ Create a new node by serialising `i` into an xsd:integer string
@param i Integer value to serialise.
@param datatype Datatype of node, or NULL for xsd:integer.
diff --git a/meson.build b/meson.build
index 98ae0d5e..4dd4b6e5 100644
--- a/meson.build
+++ b/meson.build
@@ -33,6 +33,7 @@ if get_option('strict')
'-Wno-covered-switch-default',
'-Wno-disabled-macro-expansion',
'-Wno-double-promotion',
+ '-Wno-float-equal',
'-Wno-format-nonliteral',
'-Wno-implicit-fallthrough',
'-Wno-nullability-extension',
diff --git a/src/node.c b/src/node.c
index 0d6eb19a..db183fc0 100644
--- a/src/node.c
+++ b/src/node.c
@@ -507,6 +507,32 @@ 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_STRING_VIEW(buf, r.count),
+ SERD_STATIC_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_STRING_VIEW(buf, r.count),
+ SERD_STATIC_STRING(EXESS_XSD_URI "float"));
+}
+
static size_t
write_variant_literal(const void* const user_data,
const size_t buf_size,
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 00b1e91a..6e28778b 100644
--- a/src/string.c
+++ b/src/string.c
@@ -21,6 +21,8 @@
#include <assert.h>
#include <math.h>
+#include <stdbool.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>