aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-05-12 18:03:13 +0200
committerDavid Robillard <d@drobilla.net>2020-06-21 18:12:04 +0200
commitbc0e185a469018ea70f32abb50c4b4a1073b0249 (patch)
tree58adee5b431ac8168c6f032e173c649d0e7bd112 /src
parente9418d9ff3416cfd6cf558cea36af0582d8567a6 (diff)
downloadserd-bc0e185a469018ea70f32abb50c4b4a1073b0249.tar.gz
serd-bc0e185a469018ea70f32abb50c4b4a1073b0249.tar.bz2
serd-bc0e185a469018ea70f32abb50c4b4a1073b0249.zip
Set datatypes on integer, decimal, and base64 nodes
Diffstat (limited to 'src')
-rw-r--r--src/node.c79
-rw-r--r--src/static_nodes.h36
2 files changed, 89 insertions, 26 deletions
diff --git a/src/node.c b/src/node.c
index 0a28be65..4246e3cd 100644
--- a/src/node.c
+++ b/src/node.c
@@ -18,6 +18,7 @@
#include "base64.h"
#include "serd_internal.h"
+#include "static_nodes.h"
#include "string_utils.h"
#include <assert.h>
@@ -47,7 +48,21 @@ static size_t
serd_node_pad_size(const size_t n_bytes)
{
const size_t pad = serd_node_align - (n_bytes + 2) % serd_node_align;
- return n_bytes + 2 + pad;
+ const size_t size = n_bytes + 2 + pad;
+ assert(size % serd_node_align == 0);
+ return size;
+}
+
+static const SerdNode*
+serd_node_get_meta_c(const SerdNode* node)
+{
+ return node + 1 + (serd_node_pad_size(node->n_bytes) / serd_node_align);
+}
+
+static SerdNode*
+serd_node_get_meta(SerdNode* node)
+{
+ return node + 1 + (serd_node_pad_size(node->n_bytes) / serd_node_align);
}
static const SerdNode*
@@ -408,21 +423,26 @@ serd_digits(double abs)
}
SerdNode*
-serd_node_new_decimal(double d, unsigned frac_digits)
+serd_node_new_decimal(double d, unsigned frac_digits, const SerdNode* datatype)
{
if (isnan(d) || isinf(d)) {
return NULL;
}
+ const SerdNode* type = datatype ? datatype : &serd_xsd_decimal.node;
const double abs_d = fabs(d);
const unsigned int_digits = serd_digits(abs_d);
const size_t len = int_digits + frac_digits + 3;
- SerdNode* const node = serd_node_malloc(len, 0, SERD_LITERAL);
- char* const buf = serd_node_buffer(node);
- const double int_part = floor(abs_d);
+ const size_t type_len = serd_node_total_size(type);
+ const size_t total_len = len + type_len;
+
+ SerdNode* const node =
+ serd_node_malloc(total_len, SERD_HAS_DATATYPE, SERD_LITERAL);
// Point s to decimal point location
- char* s = buf + int_digits;
+ char* const buf = serd_node_buffer(node);
+ const double int_part = floor(abs_d);
+ char* s = buf + int_digits;
if (d < 0.0) {
*buf = '-';
++s;
@@ -460,19 +480,25 @@ serd_node_new_decimal(double d, unsigned frac_digits)
}
}
+ memcpy(serd_node_get_meta(node), type, type_len);
return node;
}
SerdNode*
-serd_node_new_integer(int64_t i)
+serd_node_new_integer(int64_t i, const SerdNode* datatype)
{
- int64_t abs_i = (i < 0) ? -i : i;
- const unsigned digits = serd_digits((double)abs_i);
- SerdNode* node = serd_node_malloc(digits + 2, 0, SERD_LITERAL);
- char* buf = serd_node_buffer(node);
+ const SerdNode* type = datatype ? datatype : &serd_xsd_integer.node;
+ int64_t abs_i = (i < 0) ? -i : i;
+ const unsigned digits = serd_digits((double)abs_i);
+ const size_t type_len = serd_node_total_size(type);
+ const size_t total_len = digits + 2 + type_len;
+
+ SerdNode* node =
+ serd_node_malloc(total_len, SERD_HAS_DATATYPE, SERD_LITERAL);
// Point s to the end
- char* s = buf + digits - 1;
+ char* buf = serd_node_buffer(node);
+ char* s = buf + digits - 1;
if (i < 0) {
*buf = '-';
++s;
@@ -485,24 +511,34 @@ serd_node_new_integer(int64_t i)
*s-- = (char)('0' + (abs_i % 10));
} while ((abs_i /= 10) > 0);
+ memcpy(serd_node_get_meta(node), type, type_len);
return node;
}
SerdNode*
-serd_node_new_blob(const void* buf, size_t size, bool wrap_lines)
+serd_node_new_blob(const void* buf,
+ size_t size,
+ bool wrap_lines,
+ const SerdNode* datatype)
{
if (!buf || !size) {
return NULL;
}
- const size_t len = serd_base64_get_length(size, wrap_lines);
- SerdNode* const node = serd_node_malloc(len + 1, 0, SERD_LITERAL);
+ const SerdNode* type = datatype ? datatype : &serd_xsd_base64Binary.node;
+ const size_t len = serd_base64_get_length(size, wrap_lines);
+ const size_t type_len = serd_node_total_size(type);
+ const size_t total_len = len + 1 + type_len;
+
+ SerdNode* const node =
+ serd_node_malloc(total_len, SERD_HAS_DATATYPE, SERD_LITERAL);
if (serd_base64_encode(serd_node_buffer(node), buf, size, wrap_lines)) {
node->flags |= SERD_HAS_NEWLINE;
}
node->n_bytes = len;
+ memcpy(serd_node_get_meta(node), type, type_len);
return node;
}
@@ -524,15 +560,6 @@ serd_node_get_length(const SerdNode* node)
return node ? node->n_bytes : 0;
}
-static const SerdNode*
-serd_node_get_meta_node(const SerdNode* node)
-{
- const size_t len = serd_node_pad_size(node->n_bytes);
- assert((intptr_t)node % serd_node_align == 0);
- assert(len % serd_node_align == 0);
- return node + 1 + (len / serd_node_align);
-}
-
const SerdNode*
serd_node_get_datatype(const SerdNode* node)
{
@@ -540,7 +567,7 @@ serd_node_get_datatype(const SerdNode* node)
return NULL;
}
- const SerdNode* const datatype = serd_node_get_meta_node(node);
+ const SerdNode* const datatype = serd_node_get_meta_c(node);
assert(datatype->type == SERD_URI || datatype->type == SERD_CURIE);
return datatype;
}
@@ -552,7 +579,7 @@ serd_node_get_language(const SerdNode* node)
return NULL;
}
- const SerdNode* const lang = serd_node_get_meta_node(node);
+ const SerdNode* const lang = serd_node_get_meta_c(node);
assert(lang->type == SERD_LITERAL);
return lang;
}
diff --git a/src/static_nodes.h b/src/static_nodes.h
new file mode 100644
index 00000000..62e38c91
--- /dev/null
+++ b/src/static_nodes.h
@@ -0,0 +1,36 @@
+/*
+ Copyright 2019-2020 David Robillard <http://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.
+*/
+
+#ifndef SERD_STATIC_NODES_H
+#define SERD_STATIC_NODES_H
+
+#include "node.h"
+#include "serd_internal.h"
+
+typedef struct StaticNode {
+ SerdNode node;
+ char buf[sizeof(NS_XSD "base64Binary")];
+} StaticNode;
+
+#define DEFINE_XSD_NODE(name) \
+ static const StaticNode serd_xsd_##name = { \
+ {sizeof(NS_XSD #name) - 1, 0, SERD_URI}, NS_XSD #name};
+
+DEFINE_XSD_NODE(base64Binary)
+DEFINE_XSD_NODE(decimal)
+DEFINE_XSD_NODE(integer)
+
+#endif // SERD_STATIC_NODES_H