summaryrefslogtreecommitdiffstats
path: root/librdfa/lists.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:40:05 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:40:05 +0000
commit4038ab95a094b363f1748f3dcb51511a1217475d (patch)
tree7f393d66a783f91ddd263c78d681e485cf4f45ca /librdfa/lists.c
parentInitial commit. (diff)
downloadraptor2-8a74621eb7909f43a549b042a496e042ad12fdcb.tar.xz
raptor2-8a74621eb7909f43a549b042a496e042ad12fdcb.zip
Adding upstream version 2.0.16.upstream/2.0.16upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'librdfa/lists.c')
-rw-r--r--librdfa/lists.c243
1 files changed, 243 insertions, 0 deletions
diff --git a/librdfa/lists.c b/librdfa/lists.c
new file mode 100644
index 0000000..d399979
--- /dev/null
+++ b/librdfa/lists.c
@@ -0,0 +1,243 @@
+/**
+ * Copyright 2012 Digital Bazaar, Inc.
+ *
+ * This file is part of librdfa.
+ *
+ * librdfa is Free Software, and can be licensed under any of the
+ * following three licenses:
+ *
+ * 1. GNU Lesser General Public License (LGPL) V2.1 or any
+ * newer version
+ * 2. GNU General Public License (GPL) V2 or any newer version
+ * 3. Apache License, V2.0 or any newer version
+ *
+ * You may not use this file except in compliance with at least one of
+ * the above three licenses.
+ *
+ * See LICENSE-* at the top of this software distribution for more
+ * information regarding the details of each license.
+ *
+ * Handles all triple functionality including all incomplete triple
+ * functionality.
+ *
+ * @author Manu Sporny
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "rdfa_utils.h"
+#include "rdfa.h"
+
+void rdfa_establish_new_inlist_triples(rdfacontext* context,
+ rdfalist* predicates, const char* object, rdfresource_t object_type)
+{
+ int i = 0;
+ for(i = 0; i < (int)predicates->num_items; i++)
+ {
+ const char* predicate = (const char*)predicates->items[i]->data;
+ char* resolved_predicate = rdfa_resolve_relrev_curie(context, predicate);
+ rdftriple* triple;
+ /* ensure the list mapping exists */
+ rdfa_create_list_mapping(
+ context, context->local_list_mappings,
+ context->new_subject, resolved_predicate);
+
+ /* add an incomplete triple for each list mapping */
+ triple = rdfa_create_triple(context->new_subject, resolved_predicate,
+ object, object_type, context->datatype, context->language);
+ rdfa_append_to_list_mapping(context->local_list_mappings,
+ context->new_subject, resolved_predicate, triple);
+
+ free(resolved_predicate);
+ }
+
+#if defined(DEBUG) && DEBUG > 0
+ printf("LOCAL LIST MAPPINGS: ");
+ rdfa_print_mapping(context->local_list_mappings,
+ (print_mapping_value_fp)rdfa_print_triple_list);
+#endif
+}
+
+void rdfa_save_incomplete_list_triples(
+ rdfacontext* context, const rdfalist* rel)
+{
+ unsigned int i;
+ for(i = 0; i < rel->num_items; i++)
+ {
+ const char* curie = (const char*)rel->items[i]->data;
+ char* resolved_curie = rdfa_resolve_relrev_curie(context, curie);
+
+ /* ensure the list mapping exists */
+ rdfa_create_list_mapping(
+ context, context->local_list_mappings,
+ context->new_subject, resolved_curie);
+
+ /* get the list name */
+ rdfa_add_item(
+ context->local_incomplete_triples, resolved_curie,
+ (liflag_t)(RDFALIST_FLAG_DIR_NONE | RDFALIST_FLAG_TEXT));
+
+ free(resolved_curie);
+ }
+
+#if defined(DEBUG) && DEBUG > 0
+ printf("LOCAL INCOMPLETE TRIPLES: ");
+ rdfa_print_list(context->local_incomplete_triples);
+#endif
+}
+
+void rdfa_complete_list_triples(rdfacontext* context)
+{
+ /* For each IRI in the local list mapping, if the equivalent list does
+ * not exist in the evaluation context, indicating that the list was
+ * originally instantiated on the current element, use the list as follows: */
+ int i;
+ rdfalist* list;
+ rdftriple* triple;
+ void** mptr = context->local_list_mappings;
+ char* key = NULL;
+ void** kptr = NULL;
+ void* value = NULL;
+ unsigned int list_depth = 0;
+
+#if defined(DEBUG) && DEBUG > 0
+ printf("local_list_mappings: ");
+ rdfa_print_mapping(context->local_list_mappings,
+ (print_mapping_value_fp)rdfa_print_triple_list);
+#endif
+
+ while(*mptr != NULL)
+ {
+ kptr = mptr;
+ rdfa_next_mapping(mptr++, &key, &value);
+ list = (rdfalist*)value;
+ list_depth = list->user_data;
+ mptr++;
+#if defined(DEBUG) && DEBUG > 0
+ printf("LIST TRIPLES for key (%u/%u): KEY(%s)\n",
+ context->depth, list_depth, key);
+#endif
+
+ if((context->depth < (int)list_depth) &&
+ (rdfa_get_list_mapping(
+ context->list_mappings, context->new_subject, key) == NULL) &&
+ (strcmp(key, RDFA_MAPPING_DELETED_KEY) != 0))
+ {
+ char* predicate = strstr(key, " ") + 1;
+ triple = (rdftriple*)list->items[0]->data;
+ if(list->num_items == 1)
+ {
+ /* Free unused list triple */
+ rdfa_free_triple(triple);
+
+ /* the list is empty, generate an empty list triple */
+ triple = rdfa_create_triple(context->new_subject, predicate,
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#nil",
+ RDF_TYPE_IRI, NULL, NULL);
+ context->default_graph_triple_callback(
+ triple, context->callback_data);
+ }
+ else
+ {
+ char* bnode = NULL;
+ char* subject;
+ char* tmp = NULL;
+ bnode = rdfa_replace_string(bnode, triple->subject);
+ for(i = 1; i < (int)list->num_items; i++)
+ {
+ char* next = NULL;
+ triple = (rdftriple*)list->items[i]->data;
+ /* Create a new 'bnode' array containing newly created bnodes,
+ * one for each item in the list
+ * For each bnode-(IRI or literal) pair from the list the
+ * following triple is generated:
+ *
+ * subject
+ * bnode
+ * predicate
+ * http://www.w3.org/1999/02/22-rdf-syntax-ns#first
+ * object
+ * full IRI or literal */
+ triple->subject =
+ rdfa_replace_string(triple->subject, bnode);
+ triple->predicate =
+ rdfa_replace_string(triple->predicate,
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#first");
+ context->default_graph_triple_callback(
+ triple, context->callback_data);
+
+ /* Free the list item */
+ free(list->items[i]);
+ list->items[i] = NULL;
+
+ /* For each item in the 'bnode' array the following triple is
+ * generated:
+ *
+ * subject
+ * bnode
+ * predicate
+ * http://www.w3.org/1999/02/22-rdf-syntax-ns#rest
+ * object
+ * next item in the 'bnode' array or, if that does not exist,
+ * http://www.w3.org/1999/02/22-rdf-syntax-ns#nil */
+ if(i < (int)list->num_items - 1)
+ {
+ next = rdfa_create_bnode(context);
+ }
+ else
+ {
+ next = rdfa_strdup((char*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#nil");
+ }
+
+ triple = rdfa_create_triple(bnode,
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest",
+ next, RDF_TYPE_IRI, NULL, NULL);
+ context->default_graph_triple_callback(
+ triple, context->callback_data);
+
+ /* Free the bnode, setting 'next' appropriately */
+ free(bnode);
+ bnode = next;
+ }
+
+ /* A single additional triple is generated:
+ * subject
+ * current subject
+ * predicate
+ * full IRI of the local list mapping associated with this list
+ * object
+ * first item of the 'bnode' array */
+ subject = rdfa_strdup(key);
+ if(subject)
+ tmp = strstr(subject, " ");
+
+ if(tmp) {
+ tmp[0] = '\0';
+ triple = (rdftriple*)list->items[0]->data;
+ triple->subject =
+ rdfa_replace_string(triple->subject, subject);
+ triple->predicate =
+ rdfa_replace_string(triple->predicate, predicate);
+ context->default_graph_triple_callback(
+ triple, context->callback_data);
+ }
+ if(subject)
+ free(subject);
+ if(bnode)
+ free(bnode);
+ }
+
+ /* Free the first list item and empty the list */
+ free(list->items[0]);
+ list->items[0] = NULL;
+ list->num_items = 0;
+
+ /* clear the entry from the mapping */
+ *kptr = rdfa_replace_string((char*)*kptr, RDFA_MAPPING_DELETED_KEY);
+ }
+ }
+}