1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-05-05 06:09:47 +02:00
audacity/lib-src/redland/librdf/rdf_query_triples.c
2010-01-24 09:19:39 +00:00

304 lines
8.2 KiB
C

/* -*- Mode: c; c-basic-offset: 2 -*-
*
* rdf_query_triples.c - RDF Query simple triple query language
*
* Copyright (C) 2002-2008, David Beckett http://www.dajobe.org/
* Copyright (C) 2002-2004, University of Bristol, UK http://www.bristol.ac.uk/
*
* This package is Free Software and part of Redland http://librdf.org/
*
* It is licensed under the following three licenses as alternatives:
* 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.html or LICENSE.txt at the top of this package for the
* complete terms and further detail along with the license texts for
* the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
*
*
*/
#ifdef HAVE_CONFIG_H
#include <rdf_config.h>
#endif
#ifdef WIN32
#include <win32_rdf_config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <redland.h>
typedef struct
{
librdf_statement statement; /* statement to match */
librdf_model *model;
} librdf_query_triples_context;
/* prototypes for local functions */
static int librdf_query_triples_init(librdf_query* query, const char *name, librdf_uri* uri, const unsigned char *query_string, librdf_uri* base_uri);
static librdf_query_results* librdf_query_triples_query_execute(librdf_query* query, librdf_model* model);
static librdf_stream* librdf_query_triples_results_as_stream(librdf_query_results* query_results);
static void librdf_query_triples_register_factory(librdf_query_factory *factory);
/*
* librdf_query_triples_find_next_term - Locate end of triples query term
* @string: the string to search
*
* Find the character after a term like '[...]' or '"..."' or NULL
* if not found, end of string
*
* Return value: pointer to the character in the string or NULL
**/
static unsigned char *
librdf_query_triples_find_next_term(unsigned char *string)
{
unsigned char c;
unsigned char delim='\0';
if(!string)
return NULL;
switch(*string++) {
case '"':
delim='"';
break;
case '[':
delim=']';
break;
case '-':
return string;
default:
/* Bad value - includes '\0' */
return NULL;
}
while((c=*string++)) {
if(c == delim)
break;
}
if(!c)
string=NULL;
return string;
}
/* functions implementing query api */
/**
* librdf_query_triples_init:
* @query: the #librdf_query
* @name: the query language name
* @uri: the query language URI or NULL
* @query_string: the query string
*
* Initialise a triples query from the string.
*
* Parses the query string in the triples form to create an internal
* representation, suitable for use in querying.
*
* The syntax of the query format is as follows:
* query := subject ' ' predicate ' ' object
* subject := null | uri
* predicate := null | uri
* object := null | uri | literal
* null : '-'
* uri : '[' URI-string ']'
* literal : ''' string '''
*
* Return value:
**/
static int
librdf_query_triples_init(librdf_query* query,
const char *name, librdf_uri* uri,
const unsigned char* query_string,
librdf_uri* base_uri)
{
librdf_query_triples_context *context=(librdf_query_triples_context*)query->context;
int len;
unsigned char *query_string_copy;
unsigned char *cur, *p;
librdf_node *subject, *predicate, *object;
librdf_statement_init(query->world, &context->statement);
len=strlen((const char*)query_string);
query_string_copy=(unsigned char*)LIBRDF_MALLOC(cstring, len+1);
if(!query_string_copy)
return 0;
strcpy((char*)query_string_copy, (const char*)query_string);
cur=query_string_copy;
/* subject - NULL or URI */
p=librdf_query_triples_find_next_term(cur);
if(!p) {
librdf_log(query->world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_QUERY, NULL,
"Bad triples query language syntax - bad subject in '%s'", cur);
LIBRDF_FREE(cstring, query_string_copy);
return 0;
}
*p='\0';
p++;
if(strcmp((const char*)cur, "-")) {
/* Expecting query_string='[URI]' */
cur++; /* Move past '[' */
p[-2]='\0'; /* Zap ']' */
subject=librdf_new_node_from_uri_string(query->world, cur);
if(!subject) {
LIBRDF_FREE(cstring, query_string_copy);
return 0;
}
librdf_statement_set_subject(&context->statement, subject);
} else
subject=NULL;
cur=p;
/* predicate - NULL or URI */
p=(unsigned char*)librdf_query_triples_find_next_term(cur);
if(!p) {
librdf_log(query->world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_QUERY, NULL,
"Bad triples query language syntax - bad predicate in '%s'", cur);
LIBRDF_FREE(cstring, query_string_copy);
librdf_free_node(subject);
return 0;
}
*p='\0';
p++;
if(strcmp((const char*)cur, "-")) {
/* Expecting cur='[URI]' */
cur++; /* Move past '[' */
p[-2]='\0'; /* Zap ']' */
predicate=librdf_new_node_from_uri_string(query->world, cur);
if(!predicate) {
LIBRDF_FREE(cstring, query_string_copy);
librdf_free_node(subject);
return 0;
}
librdf_statement_set_predicate(&context->statement, predicate);
} else
predicate=NULL;
cur=p;
/* object - NULL, literal or URI */
p=librdf_query_triples_find_next_term(cur);
if(!p) {
librdf_log(query->world, 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_QUERY, NULL,
"Bad triples query language syntax - bad object in '%s'", cur);
LIBRDF_FREE(cstring, query_string_copy);
if(subject)
librdf_free_node(subject);
if(predicate)
librdf_free_node(predicate);
return 0;
}
*p='\0';
p++;
if(strcmp((const char*)cur, "-")) {
/* Expecting cur='[URI]' or '"string"' */
cur++; /* Move past '[' or '"' */
p[-2]='\0'; /* Zap ']' or '"' */
if(cur[-1] == '"')
object=librdf_new_node_from_literal(query->world, cur, NULL, 0);
else
object=librdf_new_node_from_uri_string(query->world, cur);
if(!object) {
LIBRDF_FREE(cstring, query_string_copy);
if(subject)
librdf_free_node(subject);
if(predicate)
librdf_free_node(predicate);
return 0;
}
librdf_statement_set_object(&context->statement, object);
}
LIBRDF_FREE(cstring, query_string_copy);
return 0;
}
static void
librdf_query_triples_terminate(librdf_query* query)
{
librdf_query_triples_context *context=(librdf_query_triples_context*)query->context;
librdf_node *node;
node=librdf_statement_get_subject(&context->statement);
if(node)
librdf_free_node(node);
node=librdf_statement_get_predicate(&context->statement);
if(node)
librdf_free_node(node);
node=librdf_statement_get_object(&context->statement);
if(node)
librdf_free_node(node);
}
static librdf_query_results*
librdf_query_triples_query_execute(librdf_query* query, librdf_model* model)
{
librdf_query_triples_context* context=(librdf_query_triples_context*)query->context;
librdf_query_results* results;
results=(librdf_query_results*)LIBRDF_MALLOC(librdf_query_results, sizeof(librdf_query_results));
results->query=query;
context->model=model;
return results;
}
static librdf_stream*
librdf_query_triples_results_as_stream(librdf_query_results* query_results)
{
librdf_query_triples_context* context=(librdf_query_triples_context*)query_results->query->context;
return librdf_model_find_statements(context->model, &context->statement);
}
/* local function to register list query functions */
static void
librdf_query_triples_register_factory(librdf_query_factory *factory)
{
factory->context_length = sizeof(librdf_query_triples_context);
factory->init = librdf_query_triples_init;
factory->terminate = librdf_query_triples_terminate;
factory->execute = librdf_query_triples_query_execute;
factory->results_as_stream = librdf_query_triples_results_as_stream;
}
void
librdf_query_triples_constructor(librdf_world *world)
{
librdf_query_register_factory(world, "triples", NULL,
&librdf_query_triples_register_factory);
}