summaryrefslogtreecommitdiffstats
path: root/src/node.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/node.c')
-rw-r--r--src/node.c320
1 files changed, 69 insertions, 251 deletions
diff --git a/src/node.c b/src/node.c
index ac47e80..f10ed91 100644
--- a/src/node.c
+++ b/src/node.c
@@ -19,283 +19,103 @@
#include "lilv/lilv.h"
#include "serd/serd.h"
-#include "sord/sord.h"
#include <math.h>
#include <stdbool.h>
-#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-static void
-lilv_node_set_numerics_from_string(LilvNode* val)
-{
- const char* str = (const char*)sord_node_get_string(val->node);
-
- switch (val->type) {
- case LILV_VALUE_URI:
- case LILV_VALUE_BLANK:
- case LILV_VALUE_STRING:
- case LILV_VALUE_BLOB:
- break;
- case LILV_VALUE_INT:
- val->val.int_val = strtol(str, NULL, 10);
- break;
- case LILV_VALUE_FLOAT:
- val->val.float_val = serd_strtod(str, NULL);
- break;
- case LILV_VALUE_BOOL:
- val->val.bool_val = !strcmp(str, "true");
- break;
- }
-}
-
-/** Note that if `type` is numeric or boolean, the returned value is corrupt
- * until lilv_node_set_numerics_from_string is called. It is not
- * automatically called from here to avoid overhead and imprecision when the
- * exact string value is known.
- */
-LilvNode*
-lilv_node_new(LilvWorld* world, LilvNodeType type, const char* str)
-{
- LilvNode* val = (LilvNode*)malloc(sizeof(LilvNode));
- val->world = world;
- val->type = type;
-
- const uint8_t* ustr = (const uint8_t*)str;
- switch (type) {
- case LILV_VALUE_URI:
- val->node = sord_new_uri(world->world, ustr);
- break;
- case LILV_VALUE_BLANK:
- val->node = sord_new_blank(world->world, ustr);
- break;
- case LILV_VALUE_STRING:
- val->node = sord_new_literal(world->world, NULL, ustr, NULL);
- break;
- case LILV_VALUE_INT:
- val->node =
- sord_new_literal(world->world, world->uris.xsd_integer, ustr, NULL);
- break;
- case LILV_VALUE_FLOAT:
- val->node =
- sord_new_literal(world->world, world->uris.xsd_decimal, ustr, NULL);
- break;
- case LILV_VALUE_BOOL:
- val->node =
- sord_new_literal(world->world, world->uris.xsd_boolean, ustr, NULL);
- break;
- case LILV_VALUE_BLOB:
- val->node =
- sord_new_literal(world->world, world->uris.xsd_base64Binary, ustr, NULL);
- break;
- }
-
- if (!val->node) {
- free(val);
- return NULL;
- }
-
- return val;
-}
-
-/** Create a new LilvNode from `node`, or return NULL if impossible */
-LilvNode*
-lilv_node_new_from_node(LilvWorld* world, const SordNode* node)
-{
- if (!node) {
- return NULL;
- }
-
- LilvNode* result = NULL;
- SordNode* datatype_uri = NULL;
- LilvNodeType type = LILV_VALUE_STRING;
-
- switch (sord_node_get_type(node)) {
- case SORD_URI:
- result = (LilvNode*)malloc(sizeof(LilvNode));
- result->world = world;
- result->type = LILV_VALUE_URI;
- result->node = sord_node_copy(node);
- break;
- case SORD_BLANK:
- result = (LilvNode*)malloc(sizeof(LilvNode));
- result->world = world;
- result->type = LILV_VALUE_BLANK;
- result->node = sord_node_copy(node);
- break;
- case SORD_LITERAL:
- datatype_uri = sord_node_get_datatype(node);
- if (datatype_uri) {
- if (sord_node_equals(datatype_uri, world->uris.xsd_boolean)) {
- type = LILV_VALUE_BOOL;
- } else if (sord_node_equals(datatype_uri, world->uris.xsd_decimal) ||
- sord_node_equals(datatype_uri, world->uris.xsd_double)) {
- type = LILV_VALUE_FLOAT;
- } else if (sord_node_equals(datatype_uri, world->uris.xsd_integer)) {
- type = LILV_VALUE_INT;
- } else if (sord_node_equals(datatype_uri, world->uris.xsd_base64Binary)) {
- type = LILV_VALUE_BLOB;
- } else {
- LILV_ERRORF("Unknown datatype `%s'\n",
- sord_node_get_string(datatype_uri));
- }
- }
- result =
- lilv_node_new(world, type, (const char*)sord_node_get_string(node));
- lilv_node_set_numerics_from_string(result);
- break;
- }
-
- return result;
-}
-
+LILV_API
LilvNode*
lilv_new_uri(LilvWorld* world, const char* uri)
{
- return lilv_node_new(world, LILV_VALUE_URI, uri);
+ (void)world;
+ return serd_new_uri(SERD_MEASURE_STRING(uri));
}
LilvNode*
lilv_new_file_uri(LilvWorld* world, const char* host, const char* path)
{
- char* abs_path = lilv_path_absolute(path);
- SerdNode s = serd_node_new_file_uri(
- (const uint8_t*)abs_path, (const uint8_t*)host, NULL, true);
+ (void)world;
+
+ char* abs_path = lilv_path_absolute(path);
+ SerdNode* s =
+ serd_new_file_uri(SERD_MEASURE_STRING(abs_path), SERD_MEASURE_STRING(host));
- LilvNode* ret = lilv_node_new(world, LILV_VALUE_URI, (const char*)s.buf);
- serd_node_free(&s);
free(abs_path);
- return ret;
+ return s;
}
LilvNode*
lilv_new_string(LilvWorld* world, const char* str)
{
- return lilv_node_new(world, LILV_VALUE_STRING, str);
+ (void)world;
+
+ return serd_new_string(SERD_MEASURE_STRING(str));
}
LilvNode*
lilv_new_int(LilvWorld* world, int val)
{
- char str[32];
- snprintf(str, sizeof(str), "%d", val);
- LilvNode* ret = lilv_node_new(world, LILV_VALUE_INT, str);
- if (ret) {
- ret->val.int_val = val;
- }
- return ret;
+ (void)world;
+
+ return serd_new_integer(val, world->uris.xsd_int);
}
LilvNode*
lilv_new_float(LilvWorld* world, float val)
{
- char str[32];
- snprintf(str, sizeof(str), "%f", val);
- LilvNode* ret = lilv_node_new(world, LILV_VALUE_FLOAT, str);
- if (ret) {
- ret->val.float_val = val;
- }
- return ret;
+ (void)world;
+
+ return serd_new_float(val);
}
LilvNode*
lilv_new_bool(LilvWorld* world, bool val)
{
- LilvNode* ret = lilv_node_new(world, LILV_VALUE_BOOL, val ? "true" : "false");
- if (ret) {
- ret->val.bool_val = val;
- }
- return ret;
+ (void)world;
+
+ return serd_new_typed_literal(val ? SERD_STATIC_STRING("true")
+ : SERD_STATIC_STRING("false"),
+ serd_node_string_view(world->uris.xsd_boolean));
}
LilvNode*
lilv_node_duplicate(const LilvNode* val)
{
- if (!val) {
- return NULL;
- }
-
- LilvNode* result = (LilvNode*)malloc(sizeof(LilvNode));
- result->world = val->world;
- result->node = sord_node_copy(val->node);
- result->val = val->val;
- result->type = val->type;
- return result;
+ return serd_node_copy(val);
}
void
lilv_node_free(LilvNode* val)
{
- if (val) {
- sord_node_free(val->world->world, val->node);
- free(val);
- }
+ serd_node_free(val);
}
bool
lilv_node_equals(const LilvNode* value, const LilvNode* other)
{
- if (value == NULL && other == NULL) {
- return true;
- }
-
- if (value == NULL || other == NULL || value->type != other->type) {
- return false;
- }
-
- switch (value->type) {
- case LILV_VALUE_URI:
- case LILV_VALUE_BLANK:
- case LILV_VALUE_STRING:
- case LILV_VALUE_BLOB:
- return sord_node_equals(value->node, other->node);
- case LILV_VALUE_INT:
- return (value->val.int_val == other->val.int_val);
- case LILV_VALUE_FLOAT:
- return (value->val.float_val == other->val.float_val);
- case LILV_VALUE_BOOL:
- return (value->val.bool_val == other->val.bool_val);
- }
-
- return false; /* shouldn't get here */
+ return serd_node_equals(value, other);
}
char*
lilv_node_get_turtle_token(const LilvNode* value)
{
- const char* str = (const char*)sord_node_get_string(value->node);
+ const char* str = serd_node_string(value);
size_t len = 0;
char* result = NULL;
- SerdNode node;
- switch (value->type) {
- case LILV_VALUE_URI:
+ if (lilv_node_is_uri(value)) {
len = strlen(str) + 3;
result = (char*)calloc(len, 1);
snprintf(result, len, "<%s>", str);
- break;
- case LILV_VALUE_BLANK:
+ } else if (lilv_node_is_blank(value)) {
len = strlen(str) + 3;
result = (char*)calloc(len, 1);
snprintf(result, len, "_:%s", str);
- break;
- case LILV_VALUE_STRING:
- case LILV_VALUE_BOOL:
- case LILV_VALUE_BLOB:
+ } else {
result = lilv_strdup(str);
- break;
- case LILV_VALUE_INT:
- node = serd_node_new_integer(value->val.int_val);
- result = lilv_strdup((char*)node.buf);
- serd_node_free(&node);
- break;
- case LILV_VALUE_FLOAT:
- node = serd_node_new_decimal(value->val.float_val, 8);
- result = lilv_strdup((char*)node.buf);
- serd_node_free(&node);
- break;
}
return result;
@@ -304,110 +124,108 @@ lilv_node_get_turtle_token(const LilvNode* value)
bool
lilv_node_is_uri(const LilvNode* value)
{
- return (value && value->type == LILV_VALUE_URI);
+ return value && serd_node_type(value) == SERD_URI;
}
const char*
lilv_node_as_uri(const LilvNode* value)
{
- return (lilv_node_is_uri(value)
- ? (const char*)sord_node_get_string(value->node)
- : NULL);
+ return (lilv_node_is_uri(value) ? serd_node_string(value) : NULL);
}
bool
lilv_node_is_blank(const LilvNode* value)
{
- return (value && value->type == LILV_VALUE_BLANK);
+ return value && serd_node_type(value) == SERD_BLANK;
}
const char*
lilv_node_as_blank(const LilvNode* value)
{
- return (lilv_node_is_blank(value)
- ? (const char*)sord_node_get_string(value->node)
- : NULL);
+ return (lilv_node_is_blank(value) ? serd_node_string(value) : NULL);
}
bool
lilv_node_is_literal(const LilvNode* value)
{
- if (!value) {
- return false;
- }
-
- switch (value->type) {
- case LILV_VALUE_STRING:
- case LILV_VALUE_INT:
- case LILV_VALUE_FLOAT:
- case LILV_VALUE_BLOB:
- return true;
- default:
- return false;
- }
+ return value && serd_node_type(value) == SERD_LITERAL;
}
bool
lilv_node_is_string(const LilvNode* value)
{
- return (value && value->type == LILV_VALUE_STRING);
+ return value &&
+ (serd_node_type(value) == SERD_LITERAL && !serd_node_datatype(value));
}
const char*
lilv_node_as_string(const LilvNode* value)
{
- return value ? (const char*)sord_node_get_string(value->node) : NULL;
+ return value ? serd_node_string(value) : NULL;
}
bool
lilv_node_is_int(const LilvNode* value)
{
- return (value && value->type == LILV_VALUE_INT);
+ if (!value) {
+ return false;
+ }
+
+ const SerdNode* const datatype = serd_node_datatype(value);
+ return (serd_node_type(value) == SERD_LITERAL && datatype &&
+ (!strcmp(serd_node_string(datatype), LILV_NS_XSD "integer") ||
+ !strcmp(serd_node_string(datatype), LILV_NS_XSD "int")));
}
int
lilv_node_as_int(const LilvNode* value)
{
- return lilv_node_is_int(value) ? value->val.int_val : 0;
+ return lilv_node_is_int(value) ? strtoll(serd_node_string(value), NULL, 10)
+ : 0;
}
bool
lilv_node_is_float(const LilvNode* value)
{
- return (value && value->type == LILV_VALUE_FLOAT);
+ if (!value) {
+ return false;
+ }
+
+ const SerdNode* const datatype = serd_node_datatype(value);
+ return (serd_node_type(value) == SERD_LITERAL && datatype &&
+ (!strcmp(serd_node_string(datatype), LILV_NS_XSD "decimal") ||
+ !strcmp(serd_node_string(datatype), LILV_NS_XSD "float") ||
+ !strcmp(serd_node_string(datatype), LILV_NS_XSD "double")));
}
float
lilv_node_as_float(const LilvNode* value)
{
- if (lilv_node_is_float(value)) {
- return value->val.float_val;
- }
-
- if (lilv_node_is_int(value)) {
- return (float)value->val.int_val;
- }
-
- return NAN;
+ return serd_get_float(value);
}
bool
lilv_node_is_bool(const LilvNode* value)
{
- return (value && value->type == LILV_VALUE_BOOL);
+ if (!value) {
+ return false;
+ }
+
+ const SerdNode* const datatype = serd_node_datatype(value);
+ return (serd_node_type(value) == SERD_LITERAL && datatype &&
+ (!strcmp(serd_node_string(datatype), LILV_NS_XSD "boolean")));
}
bool
lilv_node_as_bool(const LilvNode* value)
{
- return lilv_node_is_bool(value) ? value->val.bool_val : false;
+ return (lilv_node_is_bool(value) && !strcmp(serd_node_string(value), "true"));
}
char*
lilv_node_get_path(const LilvNode* value, char** hostname)
{
- if (lilv_node_is_uri(value)) {
- return lilv_file_uri_parse(lilv_node_as_uri(value), hostname);
- }
- return NULL;
+ return lilv_node_is_uri(value)
+ ? serd_parse_file_uri(lilv_node_as_uri(value), hostname)
+ : NULL;
}