Mercurial > hg > sv-dependency-builds
changeset 93:5fcdb63f4cc6
Add sord, serd
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Wed, 20 Mar 2013 15:23:43 +0000 |
parents | 182a858dbd4f |
children | d278df1123f9 |
files | script/win32/configure-command-x-mingw src/sord-0.12.0/wscript win32-mingw/include/serd-0/serd/serd.h win32-mingw/include/sord-0/sord/sord.h win32-mingw/include/sord-0/sord/sordmm.hpp win32-mingw/lib/libserd-0.a win32-mingw/lib/libsord-0.a win32-mingw/lib/pkgconfig/serd-0.pc win32-mingw/lib/pkgconfig/sord-0.pc |
diffstat | 9 files changed, 2267 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/script/win32/configure-command-x-mingw Wed Mar 20 15:18:57 2013 +0000 +++ b/script/win32/configure-command-x-mingw Wed Mar 20 15:23:43 2013 +0000 @@ -2,4 +2,5 @@ mypath=`pwd`/`dirname $0` deproot="$mypath"/../../ prefix="$deproot"/win32-mingw -CXX="i486-mingw32-g++ -I$prefix/include -L$prefix/lib" CC="i486-mingw32-gcc -I$prefix/include -L$prefix/lib" ./configure --prefix=$prefix/ --host=i486-unknown-windows +CXX="i486-mingw32-g++ -I$prefix/include -L$prefix/lib" CC="i486-mingw32-gcc -I$prefix/include -L$prefix/lib" ./configure --prefix=$prefix/ --host=i486-unknown-windows "$@" +
--- a/src/sord-0.12.0/wscript Wed Mar 20 15:18:57 2013 +0000 +++ b/src/sord-0.12.0/wscript Wed Mar 20 15:23:43 2013 +0000 @@ -63,7 +63,7 @@ autowaf.check_pkg(conf, 'serd-0', uselib_store='SERD', atleast_version='0.18.0', mandatory=True) - autowaf.check_pkg(conf, 'libpcre', uselib_store='PCRE', mandatory=False) +# autowaf.check_pkg(conf, 'libpcre', uselib_store='PCRE', mandatory=False) # Parse dump options and define things accordingly dump = Options.options.dump.split(',')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/serd-0/serd/serd.h Wed Mar 20 15:23:43 2013 +0000 @@ -0,0 +1,963 @@ +/* + Copyright 2011-2012 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. +*/ + +/** + @file serd.h API for Serd, a lightweight RDF syntax library. +*/ + +#ifndef SERD_SERD_H +#define SERD_SERD_H + +#include <stdarg.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> + +#ifdef SERD_SHARED +# ifdef _WIN32 +# define SERD_LIB_IMPORT __declspec(dllimport) +# define SERD_LIB_EXPORT __declspec(dllexport) +# else +# define SERD_LIB_IMPORT __attribute__((visibility("default"))) +# define SERD_LIB_EXPORT __attribute__((visibility("default"))) +# endif +# ifdef SERD_INTERNAL +# define SERD_API SERD_LIB_EXPORT +# else +# define SERD_API SERD_LIB_IMPORT +# endif +#else +# define SERD_API +#endif + +#ifdef __cplusplus +extern "C" { +#else +# include <stdbool.h> +#endif + +/** + @defgroup serd Serd + A lightweight RDF syntax library. + @{ +*/ + +/** + Environment. + + Represents the state required to resolve a CURIE or relative URI, e.g. the + base URI and set of namespace prefixes at a particular point. +*/ +typedef struct SerdEnvImpl SerdEnv; + +/** + RDF reader. + + Parses RDF by calling user-provided sink functions as input is consumed + (much like an XML SAX parser). +*/ +typedef struct SerdReaderImpl SerdReader; + +/** + RDF writer. + + Provides a number of functions to allow writing RDF syntax out to some + stream. These functions are deliberately compatible with the sink functions + used by SerdReader, so a reader can be directly connected to a writer to + re-serialise a document with minimal overhead. +*/ +typedef struct SerdWriterImpl SerdWriter; + +/** + Return status code. +*/ +typedef enum { + SERD_SUCCESS, /**< No error */ + SERD_FAILURE, /**< Non-fatal failure */ + SERD_ERR_UNKNOWN, /**< Unknown error */ + SERD_ERR_BAD_SYNTAX, /**< Invalid syntax */ + SERD_ERR_BAD_ARG, /**< Invalid argument */ + SERD_ERR_NOT_FOUND, /**< Not found */ + SERD_ERR_ID_CLASH, /**< Encountered clashing blank node IDs */ + SERD_ERR_BAD_CURIE, /**< Invalid CURIE (e.g. prefix does not exist) */ + SERD_ERR_INTERNAL /**< Unexpected internal error (should not happen) */ +} SerdStatus; + +/** + RDF syntax type. +*/ +typedef enum { + /** + Turtle - Terse RDF Triple Language (UTF-8). + @see <a href="http://www.w3.org/TeamSubmission/turtle/">Turtle</a> + */ + SERD_TURTLE = 1, + + /** + NTriples - Line-based RDF triples (ASCII). + @see <a href="http://www.w3.org/TR/rdf-testcases#ntriples">NTriples</a> + */ + SERD_NTRIPLES = 2 +} SerdSyntax; + +/** + Flags indication inline abbreviation information for a statement. +*/ +typedef enum { + SERD_EMPTY_S = 1 << 1, /**< Empty blank node subject */ + SERD_EMPTY_O = 1 << 2, /**< Empty blank node object */ + SERD_ANON_S_BEGIN = 1 << 3, /**< Start of anonymous subject */ + SERD_ANON_O_BEGIN = 1 << 4, /**< Start of anonymous object */ + SERD_ANON_CONT = 1 << 5, /**< Continuation of anonymous node */ + SERD_LIST_S_BEGIN = 1 << 6, /**< Start of list subject */ + SERD_LIST_O_BEGIN = 1 << 7, /**< Start of list object */ + SERD_LIST_CONT = 1 << 8 /**< Continuation of list */ +} SerdStatementFlag; + +/** + Bitwise OR of SerdNodeFlag values. +*/ +typedef uint32_t SerdStatementFlags; + +/** + Type of a syntactic RDF node. + + This is more precise than the type of an abstract RDF node. An abstract + node is either a resource, literal, or blank. In syntax there are two ways + to refer to a resource (by URI or CURIE) and two ways to refer to a blank + (by ID or anonymously). Anonymous (inline) blank nodes are expressed using + SerdStatementFlags rather than this type. +*/ +typedef enum { + /** + The type of a nonexistent node. + + This type is useful as a sentinel, but is never emitted by the reader. + */ + SERD_NOTHING = 0, + + /** + Literal value. + + A literal optionally has either a language, or a datatype (not both). + */ + SERD_LITERAL = 1, + + /** + URI (absolute or relative). + + Value is an unquoted URI string, which is either a relative reference + with respect to the current base URI (e.g. "foo/bar"), or an absolute + URI (e.g. "http://example.org/foo"). + @see <a href="http://tools.ietf.org/html/rfc3986">RFC3986</a>. + */ + SERD_URI = 2, + + /** + CURIE, a shortened URI. + + Value is an unquoted CURIE string relative to the current environment, + e.g. "rdf:type". + @see <a href="http://www.w3.org/TR/curie">CURIE Syntax 1.0</a> + */ + SERD_CURIE = 3, + + /** + A blank node. + + Value is a blank node ID, e.g. "id3", which is meaningful only within + this serialisation. + @see <a href="http://www.w3.org/TeamSubmission/turtle#nodeID">Turtle + <tt>nodeID</tt></a> + */ + SERD_BLANK = 4, + +} SerdType; + +/** + Flags indicating certain string properties relevant to serialisation. +*/ +typedef enum { + SERD_HAS_NEWLINE = 1, /**< Contains line breaks ('\\n' or '\\r') */ + SERD_HAS_QUOTE = 1 << 1 /**< Contains quotes ('"') */ +} SerdNodeFlag; + +/** + Bitwise OR of SerdNodeFlag values. +*/ +typedef uint32_t SerdNodeFlags; + +/** + A syntactic RDF node. +*/ +typedef struct { + const uint8_t* buf; /**< Value string */ + size_t n_bytes; /**< Size in bytes (not including null) */ + size_t n_chars; /**< Length in characters (not including null)*/ + SerdNodeFlags flags; /**< Node flags (e.g. string properties) */ + SerdType type; /**< Node type */ +} SerdNode; + +/** + An unterminated string fragment. +*/ +typedef struct { + const uint8_t* buf; /**< Start of chunk */ + size_t len; /**< Length of chunk in bytes */ +} SerdChunk; + +/** + An error description. +*/ +typedef struct { + SerdStatus status; /**< Error code */ + const uint8_t* filename; /**< File where error was encountered, or NULL */ + unsigned line; /**< Line where error was encountered, or 0 */ + unsigned col; /**< Column where error was encountered */ + const char* fmt; /**< Message format string (printf style) */ + va_list* args; /**< Arguments for fmt */ +} SerdError; + +/** + A parsed URI. + + This struct directly refers to chunks in other strings, it does not own any + memory itself. Thus, URIs can be parsed and/or resolved against a base URI + in-place without allocating memory. +*/ +typedef struct { + SerdChunk scheme; /**< Scheme */ + SerdChunk authority; /**< Authority */ + SerdChunk path_base; /**< Path prefix if relative */ + SerdChunk path; /**< Path suffix */ + SerdChunk query; /**< Query */ + SerdChunk fragment; /**< Fragment */ +} SerdURI; + +/** + Syntax style options. + + The style of the writer output can be controlled by ORing together + values from this enumeration. Note that some options are only supported + for some syntaxes (e.g. NTriples does not support abbreviation and is + always ASCII). +*/ +typedef enum { + SERD_STYLE_ABBREVIATED = 1, /**< Abbreviate triples when possible. */ + SERD_STYLE_ASCII = 1 << 1, /**< Escape all non-ASCII characters. */ + SERD_STYLE_RESOLVED = 1 << 2, /**< Resolve URIs against base URI. */ + SERD_STYLE_CURIED = 1 << 3, /**< Shorten URIs into CURIEs. */ + SERD_STYLE_BULK = 1 << 4 /**< Write output in pages. */ +} SerdStyle; + +/** + @name String Utilities + @{ +*/ + +/** + Return a string describing a status code. +*/ +SERD_API +const uint8_t* +serd_strerror(SerdStatus status); + +/** + Measure a UTF-8 string. + @return Length of @c str in characters (except NULL). + @param str A null-terminated UTF-8 string. + @param n_bytes (Output) Set to the size of @c str in bytes (except NULL). + @param flags (Output) Set to the applicable flags. +*/ +SERD_API +size_t +serd_strlen(const uint8_t* str, size_t* n_bytes, SerdNodeFlags* flags); + +/** + Parse a string to a double. + + The API of this function is identical to the standard C strtod function, + except this function is locale-independent and always matches the lexical + format used in the Turtle grammar (the decimal point is always "."). +*/ +SERD_API +double +serd_strtod(const char* str, char** endptr); + +/** + Decode a base64 string. + This function can be used to deserialise a blob node created with + serd_node_new_blob(). + + @param str Base64 string to decode. + @param len The length of @c str. + @param size Set to the size of the returned blob in bytes. + @return A newly allocated blob which must be freed with free(). +*/ +SERD_API +void* +serd_base64_decode(const uint8_t* str, size_t len, size_t* size); + +/** + @} + @name URI + @{ +*/ + +static const SerdURI SERD_URI_NULL = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}; + +/** + Return the local path for @c uri, or NULL if @c uri is not a file URI. + Note this (inappropriately named) function only removes the file scheme if + necessary, and returns @c uri unmodified if it is an absolute path. Percent + encoding and other issues are not handled, to properly convert a file URI to + a path, use serd_file_uri_parse(). +*/ +SERD_API +const uint8_t* +serd_uri_to_path(const uint8_t* uri); + +/** + Get the unescaped path and hostname from a file URI. + @param uri A file URI. + @param hostname If non-NULL, set to the hostname, if present. + @return The path component of the URI. + + Both the returned path and @c hostname (if applicable) are owned by the + caller and must be freed with free(). +*/ +SERD_API +uint8_t* +serd_file_uri_parse(const uint8_t* uri, uint8_t** hostname); + +/** + Return true iff @c utf8 starts with a valid URI scheme. +*/ +SERD_API +bool +serd_uri_string_has_scheme(const uint8_t* utf8); + +/** + Parse @c utf8, writing result to @c out. +*/ +SERD_API +SerdStatus +serd_uri_parse(const uint8_t* utf8, SerdURI* out); + +/** + Set @c out to @c uri resolved against @c base. +*/ +SERD_API +void +serd_uri_resolve(const SerdURI* uri, const SerdURI* base, SerdURI* out); + +/** + Sink function for raw string output. +*/ +typedef size_t (*SerdSink)(const void* buf, size_t len, void* stream); + +/** + Serialise @c uri with a series of calls to @c sink. +*/ +SERD_API +size_t +serd_uri_serialise(const SerdURI* uri, SerdSink sink, void* stream); + +/** + Serialise @c uri relative to @c base with a series of calls to @c sink. + + The @c uri is written as a relative URI iff if it a child of @c base and @c + root. The optional @c root parameter must be a prefix of @c base and can be + used keep up-references ("../") within a certain namespace. +*/ +SERD_API +size_t +serd_uri_serialise_relative(const SerdURI* uri, + const SerdURI* base, + const SerdURI* root, + SerdSink sink, + void* stream); + +/** + @} + @name Node + @{ +*/ + +static const SerdNode SERD_NODE_NULL = { 0, 0, 0, 0, SERD_NOTHING }; + +/** + Make a (shallow) node from @c str. + + This measures, but does not copy, @c str. No memory is allocated. +*/ +SERD_API +SerdNode +serd_node_from_string(SerdType type, const uint8_t* str); + +/** + Make a deep copy of @c node. + + @return a node that the caller must free with @ref serd_node_free. +*/ +SERD_API +SerdNode +serd_node_copy(const SerdNode* node); + +/** + Return true iff @c a is equal to @c b. +*/ +SERD_API +bool +serd_node_equals(const SerdNode* a, const SerdNode* b); + +/** + Simple wrapper for serd_node_new_uri to resolve a URI node. +*/ +SERD_API +SerdNode +serd_node_new_uri_from_node(const SerdNode* uri_node, + const SerdURI* base, + SerdURI* out); + +/** + Simple wrapper for serd_node_new_uri to resolve a URI string. +*/ +SERD_API +SerdNode +serd_node_new_uri_from_string(const uint8_t* str, + const SerdURI* base, + SerdURI* out); + +/** + Create a new file URI node from a file system path and optional hostname. + + Backslashes in Windows paths will be converted and '%' will always be + percent encoded. If @c escape is true, all other invalid characters will be + percent encoded as well. + + If @c path is relative, @c hostname is ignored. + If @c out is not NULL, it will be set to the parsed URI. +*/ +SERD_API +SerdNode +serd_node_new_file_uri(const uint8_t* path, + const uint8_t* hostname, + SerdURI* out, + bool escape); + +/** + Create a new node by serialising @c uri into a new string. + + @param uri The URI to parse and serialise. + + @param base Base URI to resolve @c uri against (or NULL for no resolution). + + @param out Set to the parsing of the new URI (i.e. points only to + memory owned by the new returned node). +*/ +SERD_API +SerdNode +serd_node_new_uri(const SerdURI* uri, const SerdURI* base, SerdURI* out); + +/** + Create a new node by serialising @c d into an xsd:decimal string. + + The resulting node will always contain a `.', start with a digit, and end + with a digit (i.e. will have a leading and/or trailing `0' if necessary). + It will never be in scientific notation. A maximum of @c frac_digits digits + will be written after the decimal point, but trailing zeros will + automatically be omitted (except one if @c d is a round integer). + + Note that about 16 and 8 fractional digits are required to precisely + represent a double and float, respectively. + + @param d The value for the new node. + @param frac_digits The maximum number of digits after the decimal place. +*/ +SERD_API +SerdNode +serd_node_new_decimal(double d, unsigned frac_digits); + +/** + Create a new node by serialising @c i into an xsd:integer string. +*/ +SERD_API +SerdNode +serd_node_new_integer(int64_t i); + +/** + Create a node by serialising @c buf into an xsd:base64Binary string. + This function can be used to make a serialisable node out of arbitrary + binary data, which can be decoded using serd_base64_decode(). + + @param buf Raw binary input data. + @param size Size of @c buf. + @param wrap_lines Wrap lines at 76 characters to conform to RFC 2045. +*/ +SERD_API +SerdNode +serd_node_new_blob(const void* buf, size_t size, bool wrap_lines); + +/** + Free any data owned by @c node. + + Note that if @c node is itself dynamically allocated (which is not the case + for nodes created internally by serd), it will not be freed. +*/ +SERD_API +void +serd_node_free(SerdNode* node); + +/** + @} + @name Event Handlers + @{ +*/ + +/** + Sink (callback) for errors. + + @param handle Handle for user data. + @param error Error description. +*/ +typedef SerdStatus (*SerdErrorSink)(void* handle, + const SerdError* error); + +/** + Sink (callback) for base URI changes. + + Called whenever the base URI of the serialisation changes. +*/ +typedef SerdStatus (*SerdBaseSink)(void* handle, + const SerdNode* uri); + +/** + Sink (callback) for namespace definitions. + + Called whenever a prefix is defined in the serialisation. +*/ +typedef SerdStatus (*SerdPrefixSink)(void* handle, + const SerdNode* name, + const SerdNode* uri); + +/** + Sink (callback) for statements. + + Called for every RDF statement in the serialisation. +*/ +typedef SerdStatus (*SerdStatementSink)(void* handle, + SerdStatementFlags flags, + const SerdNode* graph, + const SerdNode* subject, + const SerdNode* predicate, + const SerdNode* object, + const SerdNode* object_datatype, + const SerdNode* object_lang); + +/** + Sink (callback) for anonymous node end markers. + + This is called to indicate that the anonymous node with the given + @c value will no longer be referred to by any future statements + (i.e. the anonymous serialisation of the node is finished). +*/ +typedef SerdStatus (*SerdEndSink)(void* handle, + const SerdNode* node); + +/** + @} + @name Environment + @{ +*/ + +/** + Create a new environment. +*/ +SERD_API +SerdEnv* +serd_env_new(const SerdNode* base_uri); + +/** + Free @c ns. +*/ +SERD_API +void +serd_env_free(SerdEnv* env); + +/** + Get the current base URI. +*/ +SERD_API +const SerdNode* +serd_env_get_base_uri(const SerdEnv* env, + SerdURI* out); + +/** + Set the current base URI. +*/ +SERD_API +SerdStatus +serd_env_set_base_uri(SerdEnv* env, + const SerdNode* uri); + +/** + Set a namespace prefix. +*/ +SERD_API +SerdStatus +serd_env_set_prefix(SerdEnv* env, + const SerdNode* name, + const SerdNode* uri); + +/** + Set a namespace prefix. +*/ +SERD_API +SerdStatus +serd_env_set_prefix_from_strings(SerdEnv* env, + const uint8_t* name, + const uint8_t* uri); + +/** + Qualify @c uri into a CURIE if possible. +*/ +SERD_API +bool +serd_env_qualify(const SerdEnv* env, + const SerdNode* uri, + SerdNode* prefix, + SerdChunk* suffix); + +/** + Expand @c curie. +*/ +SERD_API +SerdStatus +serd_env_expand(const SerdEnv* env, + const SerdNode* curie, + SerdChunk* uri_prefix, + SerdChunk* uri_suffix); + +/** + Expand @c node, which must be a CURIE or URI, to a full URI. +*/ +SERD_API +SerdNode +serd_env_expand_node(const SerdEnv* env, + const SerdNode* node); + +/** + Call @c func for each prefix defined in @c env. +*/ +SERD_API +void +serd_env_foreach(const SerdEnv* env, + SerdPrefixSink func, + void* handle); + +/** + @} + @name Reader + @{ +*/ + +/** + Create a new RDF reader. +*/ +SERD_API +SerdReader* +serd_reader_new(SerdSyntax syntax, + void* handle, + void (*free_handle)(void*), + SerdBaseSink base_sink, + SerdPrefixSink prefix_sink, + SerdStatementSink statement_sink, + SerdEndSink end_sink); + +/** + Set a function to be called when errors occur during reading. + + The @p error_sink will be called with @p handle as its first argument. If + no error function is set, errors are printed to stderr in GCC style. +*/ +SERD_API +void +serd_reader_set_error_sink(SerdReader* reader, + SerdErrorSink error_sink, + void* handle); + +/** + Return the @c handle passed to @ref serd_reader_new. +*/ +SERD_API +void* +serd_reader_get_handle(const SerdReader* reader); + +/** + Set a prefix to be added to all blank node identifiers. + + This is useful when multiple files are to be parsed into the same output + (e.g. a store, or other files). Since Serd preserves blank node IDs, this + could cause conflicts where two non-equivalent blank nodes are merged, + resulting in corrupt data. By setting a unique blank node prefix for each + parsed file, this can be avoided, while preserving blank node names. +*/ +SERD_API +void +serd_reader_add_blank_prefix(SerdReader* reader, + const uint8_t* prefix); + +/** + Set the URI of the default graph. + + If this is set, the reader will emit quads with the graph set to the given + node for any statements that are not in a named graph (which is currently + all of them since Serd currently does not support any graph syntaxes). +*/ +SERD_API +void +serd_reader_set_default_graph(SerdReader* reader, + const SerdNode* graph); + +/** + Read a file at a given @c uri. +*/ +SERD_API +SerdStatus +serd_reader_read_file(SerdReader* reader, + const uint8_t* uri); + +/** + Start an incremental read from a file handle. + + Iff @p bulk is true, @p file will be read a page at a time. This is more + efficient, but uses a page of memory and means that an entire page of input + must be ready before any callbacks will fire. To react as soon as input + arrives, set @p bulk to false. +*/ +SERD_API +SerdStatus +serd_reader_start_stream(SerdReader* me, + FILE* file, + const uint8_t* name, + bool bulk); + +/** + Read a single "chunk" of data during an incremental read. + + This function will read a single top level description, and return. This + may be a directive, statement, or several statements; essentially it reads + until a '.' is encountered. This is particularly useful for reading + directly from a pipe or socket. +*/ +SERD_API +SerdStatus +serd_reader_read_chunk(SerdReader* me); + +/** + Finish an incremental read from a file handle. +*/ +SERD_API +SerdStatus +serd_reader_end_stream(SerdReader* me); + +/** + Read @c file. +*/ +SERD_API +SerdStatus +serd_reader_read_file_handle(SerdReader* reader, + FILE* file, + const uint8_t* name); + +/** + Read @c utf8. +*/ +SERD_API +SerdStatus +serd_reader_read_string(SerdReader* me, const uint8_t* utf8); + +/** + Free @c reader. +*/ +SERD_API +void +serd_reader_free(SerdReader* reader); + +/** + @} + @name Writer + @{ +*/ + +/** + Create a new RDF writer. +*/ +SERD_API +SerdWriter* +serd_writer_new(SerdSyntax syntax, + SerdStyle style, + SerdEnv* env, + const SerdURI* base_uri, + SerdSink sink, + void* stream); + +/** + Free @c writer. +*/ +SERD_API +void +serd_writer_free(SerdWriter* writer); + +/** + Return the env used by @c writer. +*/ +SERD_API +SerdEnv* +serd_writer_get_env(SerdWriter* writer); + +/** + A convenience sink function for writing to a FILE*. + + This function can be used as a SerdSink when writing to a FILE*. The + @c stream parameter must be a FILE* opened for writing. +*/ +SERD_API +size_t +serd_file_sink(const void* buf, size_t len, void* stream); + +/** + A convenience sink function for writing to a string. + + This function can be used as a SerdSink to write to a SerdChunk which is + resized as necessary with realloc(). The @c stream parameter must point to + an initialized SerdChunk. When the write is finished, the string should be + retrieved with serd_chunk_sink_finish(). +*/ +SERD_API +size_t +serd_chunk_sink(const void* buf, size_t len, void* stream); + +/** + Finish a serialisation to a chunk with serd_chunk_sink(). + + The returned string is the result of the serialisation, which is NULL + terminated (by this function) and owned by the caller. +*/ +SERD_API +uint8_t* +serd_chunk_sink_finish(SerdChunk* stream); + +/** + Set a function to be called when errors occur during writing. + + The @p error_sink will be called with @p handle as its first argument. If + no error function is set, errors are printed to stderr. +*/ +SERD_API +void +serd_writer_set_error_sink(SerdWriter* writer, + SerdErrorSink error_sink, + void* handle); + +/** + Set a prefix to be removed from matching blank node identifiers. +*/ +SERD_API +void +serd_writer_chop_blank_prefix(SerdWriter* writer, + const uint8_t* prefix); + +/** + Set the current output base URI (and emit directive if applicable). + + Note this function can be safely casted to SerdBaseSink. +*/ +SERD_API +SerdStatus +serd_writer_set_base_uri(SerdWriter* writer, + const SerdNode* uri); + +/** + Set the current root URI. + + The root URI should be a prefix of the base URI. The path of the root URI + is the highest path any relative up-reference can refer to. For example, + with root <file:///foo/root> and base <file:///foo/root/base>, + <file:///foo/root> will be written as <../>, but <file:///foo> will be + written non-relatively as <file:///foo>. If the root is not explicitly set, + it defaults to the base URI, so no up-references will be created at all. +*/ +SERD_API +SerdStatus +serd_writer_set_root_uri(SerdWriter* writer, + const SerdNode* uri); + +/** + Set a namespace prefix (and emit directive if applicable). + + Note this function can be safely casted to SerdPrefixSink. +*/ +SERD_API +SerdStatus +serd_writer_set_prefix(SerdWriter* writer, + const SerdNode* name, + const SerdNode* uri); + +/** + Write a statement. + + Note this function can be safely casted to SerdStatementSink. +*/ +SERD_API +SerdStatus +serd_writer_write_statement(SerdWriter* writer, + SerdStatementFlags flags, + const SerdNode* graph, + const SerdNode* subject, + const SerdNode* predicate, + const SerdNode* object, + const SerdNode* object_datatype, + const SerdNode* object_lang); + +/** + Mark the end of an anonymous node's description. + + Note this function can be safely casted to SerdEndSink. +*/ +SERD_API +SerdStatus +serd_writer_end_anon(SerdWriter* writer, + const SerdNode* node); + +/** + Finish a write. +*/ +SERD_API +SerdStatus +serd_writer_finish(SerdWriter* writer); + +/** + @} + @} +*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SERD_SERD_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/sord-0/sord/sord.h Wed Mar 20 15:23:43 2013 +0000 @@ -0,0 +1,627 @@ +/* + Copyright 2011-2013 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. +*/ + +/** + @file sord.h API for Sord, a lightweight RDF model library. +*/ + +#ifndef SORD_SORD_H +#define SORD_SORD_H + +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> + +#include "serd/serd.h" + +#ifdef SORD_SHARED +# ifdef _WIN32 +# define SORD_LIB_IMPORT __declspec(dllimport) +# define SORD_LIB_EXPORT __declspec(dllexport) +# else +# define SORD_LIB_IMPORT __attribute__((visibility("default"))) +# define SORD_LIB_EXPORT __attribute__((visibility("default"))) +# endif +# ifdef SORD_INTERNAL +# define SORD_API SORD_LIB_EXPORT +# else +# define SORD_API SORD_LIB_IMPORT +# endif +#else +# define SORD_API +#endif + +#ifdef __cplusplus +extern "C" { +#else +# include <stdbool.h> +#endif + +/** + @defgroup sord Sord + A lightweight RDF model library. + + Sord stores RDF (subject object predicate context) quads, where the context + may be omitted (to represent triples in the default graph). + @{ +*/ + +/** + Sord World. + The World represents all library state, including interned strings. +*/ +typedef struct SordWorldImpl SordWorld; + +/** + Sord Model. + + A model is an indexed set of Quads (i.e. it can contain several RDF + graphs). It may be searched using various patterns depending on which + indices are enabled. +*/ +typedef struct SordModelImpl SordModel; + +/** + Model Inserter. + + An inserter is used for writing statements to a model using the Serd sink + interface. This makes it simple to write to a model directly using a + SerdReader, or any other code that writes statements to a SerdStatementSink. +*/ +typedef struct SordInserterImpl SordInserter; + +/** + Model Iterator. +*/ +typedef struct SordIterImpl SordIter; + +/** + RDF Node. + A Node is a component of a Quad. Nodes may be URIs, blank nodes, or + (in the case of quad objects only) string literals. Literal nodes may + have an associate language or datatype (but not both). +*/ +typedef struct SordNodeImpl SordNode; + +/** + Quad of nodes (a statement), or a quad pattern. + + Nodes are ordered (S P O G). The ID of the default graph is 0. +*/ +typedef const SordNode* SordQuad[4]; + +/** + Index into a SordQuad. +*/ +typedef enum { + SORD_SUBJECT = 0, /**< Subject */ + SORD_PREDICATE = 1, /**< Predicate (a.k.a. "key") */ + SORD_OBJECT = 2, /**< Object (a.k.a. "value") */ + SORD_GRAPH = 3 /**< Graph (a.k.a. "context") */ +} SordQuadIndex; + +/** + Type of a node. +*/ +typedef enum { + SORD_URI = 1, /**< URI */ + SORD_BLANK = 2, /**< Blank node identifier */ + SORD_LITERAL = 3 /**< Literal (string with optional lang or datatype) */ +} SordNodeType; + +/** + Indexing option. +*/ +typedef enum { + SORD_SPO = 1, /**< Subject, Predicate, Object */ + SORD_SOP = 1 << 1, /**< Subject, Object, Predicate */ + SORD_OPS = 1 << 2, /**< Object, Predicate, Subject */ + SORD_OSP = 1 << 3, /**< Object, Subject, Predicate */ + SORD_PSO = 1 << 4, /**< Predicate, Subject, Object */ + SORD_POS = 1 << 5 /**< Predicate, Object, Subject */ +} SordIndexOption; + +/** + @name World + @{ +*/ + +/** + Create a new Sord World. + It is safe to use multiple worlds in one process, though no data + (e.g. nodes) can be shared between worlds, and this should be avoided if + possible for performance reasons. +*/ +SORD_API +SordWorld* +sord_world_new(void); + +/** + Free @c world. +*/ +SORD_API +void +sord_world_free(SordWorld* world); + +/** + Set a function to be called when errors occur. + + The @p error_sink will be called with @p handle as its first argument. If + no error function is set, errors are printed to stderr. +*/ +SORD_API +void +sord_world_set_error_sink(SordWorld* world, + SerdErrorSink error_sink, + void* handle); + +/** + @} + @name Node + @{ +*/ + +/** + Get a URI node from a string. + + Note this function measures @c str, which is a common bottleneck. + Use sord_node_from_serd_node instead if @c str is already measured. +*/ +SORD_API +SordNode* +sord_new_uri(SordWorld* world, const uint8_t* uri); + +/** + Get a URI node from a relative URI string. +*/ +SORD_API +SordNode* +sord_new_relative_uri(SordWorld* world, + const uint8_t* str, + const uint8_t* base_uri); + +/** + Get a blank node from a string. + + Note this function measures @c str, which is a common bottleneck. + Use sord_node_from_serd_node instead if @c str is already measured. +*/ +SORD_API +SordNode* +sord_new_blank(SordWorld* world, const uint8_t* str); + +/** + Get a literal node from a string. + + Note this function measures @c str, which is a common bottleneck. + Use sord_node_from_serd_node instead if @c str is already measured. +*/ +SORD_API +SordNode* +sord_new_literal(SordWorld* world, + SordNode* datatype, + const uint8_t* str, + const char* lang); + +/** + Copy a node (obtain a reference). + + Node that since nodes are interned and reference counted, this does not + actually create a deep copy of @c node. +*/ +SORD_API +SordNode* +sord_node_copy(const SordNode* node); + +/** + Free a node (drop a reference). +*/ +SORD_API +void +sord_node_free(SordWorld* world, SordNode* node); + +/** + Return the type of a node (SORD_URI, SORD_BLANK, or SORD_LITERAL). +*/ +SORD_API +SordNodeType +sord_node_get_type(const SordNode* node); + +/** + Return the string value of a node. +*/ +SORD_API +const uint8_t* +sord_node_get_string(const SordNode* node); + +/** + Return the string value of a node, and set @c len to its length. +*/ +SORD_API +const uint8_t* +sord_node_get_string_counted(const SordNode* node, size_t* len); + +/** + Return the language of a literal node (or NULL). +*/ +SORD_API +const char* +sord_node_get_language(const SordNode* node); + +/** + Return the datatype URI of a literal node (or NULL). +*/ +SORD_API +SordNode* +sord_node_get_datatype(const SordNode* node); + +/** + Return the flags (string attributes) of a node. +*/ +SORD_API +SerdNodeFlags +sord_node_get_flags(const SordNode* node); + +/** + Return true iff node can be serialised as an inline object. + + More specifically, this returns true iff the node is the object field + of exactly one statement, and therefore can be inlined since it needn't + be referred to by name. +*/ +SORD_API +bool +sord_node_is_inline_object(const SordNode* node); + +/** + Return true iff @c a is equal to @c b. + + Note this is much faster than comparing the node's strings. +*/ +SORD_API +bool +sord_node_equals(const SordNode* a, + const SordNode* b); + +/** + Return a SordNode as a SerdNode. + + The returned node is shared and must not be freed or modified. +*/ +SORD_API +const SerdNode* +sord_node_to_serd_node(const SordNode* node); + +/** + Create a new SordNode from a SerdNode. + + The returned node must be freed using sord_node_free. +*/ +SORD_API +SordNode* +sord_node_from_serd_node(SordWorld* world, + SerdEnv* env, + const SerdNode* node, + const SerdNode* datatype, + const SerdNode* lang); + +/** + @} + @name Model + @{ +*/ + +/** + Create a new model. + + @param world The world in which to make this model. + + @param indices SordIndexOption flags (e.g. SORD_SPO|SORD_OPS). Be sure to + enable an index where the most significant node(s) are not variables in your + queries (e.g. to make (? P O) queries, enable either SORD_OPS or SORD_POS). + + @param graphs If true, store (and index) graph contexts. +*/ +SORD_API +SordModel* +sord_new(SordWorld* world, + unsigned indices, + bool graphs); + +/** + Close and free @c model. +*/ +SORD_API +void +sord_free(SordModel* model); + +/** + Get the world associated with @c model. +*/ +SORD_API +SordWorld* +sord_get_world(SordModel* model); + +/** + Return the number of nodes stored in @c world. + + Nodes are included in this count iff they are a part of a quad in @c world. +*/ +SORD_API +size_t +sord_num_nodes(const SordWorld* world); + +/** + Return the number of quads stored in @c model. +*/ +SORD_API +size_t +sord_num_quads(const SordModel* model); + +/** + Return an iterator to the start of @c model. +*/ +SORD_API +SordIter* +sord_begin(const SordModel* model); + +/** + Search for statements by a quad pattern. + @return an iterator to the first match, or NULL if no matches found. +*/ +SORD_API +SordIter* +sord_find(SordModel* model, const SordQuad pat); + +/** + Search for statements by nodes. + @return an iterator to the first match, or NULL if no matches found. +*/ +SORD_API +SordIter* +sord_search(SordModel* model, + const SordNode* s, + const SordNode* p, + const SordNode* o, + const SordNode* g); +/** + Search for a single node that matches a pattern. + Exactly one of @p s, @p p, @p o must be NULL. + This function is mainly useful for predicates that only have one value. + The returned node must be freed using sord_node_free. + @return the first matching node, or NULL if no matches are found. +*/ +SORD_API +SordNode* +sord_get(SordModel* model, + const SordNode* s, + const SordNode* p, + const SordNode* o, + const SordNode* g); + +/** + Return true iff a statement exists. +*/ +SORD_API +bool +sord_ask(SordModel* model, + const SordNode* s, + const SordNode* p, + const SordNode* o, + const SordNode* g); + +/** + Return the number of matching statements. +*/ +SORD_API +uint64_t +sord_count(SordModel* model, + const SordNode* s, + const SordNode* p, + const SordNode* o, + const SordNode* g); + +/** + Check if @a model contains a triple pattern. +*/ +SORD_API +bool +sord_contains(SordModel* model, const SordQuad pat); + +/** + Add a quad to a model. +*/ +SORD_API +bool +sord_add(SordModel* model, const SordQuad quad); + +/** + Remove a quad from a model. + + Note that is it illegal to remove while iterating over @c model. +*/ +SORD_API +void +sord_remove(SordModel* model, const SordQuad quad); + +/** + @} + @name Inserter + @{ +*/ + +/** + Create an inserter for writing statements to a model. +*/ +SORD_API +SordInserter* +sord_inserter_new(SordModel* model, + SerdEnv* env); + +/** + Free an inserter. +*/ +SORD_API +void +sord_inserter_free(SordInserter* inserter); + +/** + Set the current base URI for writing to the model. + + Note this function can be safely casted to SerdBaseSink. +*/ +SORD_API +SerdStatus +sord_inserter_set_base_uri(SordInserter* inserter, + const SerdNode* uri); + +/** + Set a namespace prefix for writing to the model. + + Note this function can be safely casted to SerdPrefixSink. +*/ +SORD_API +SerdStatus +sord_inserter_set_prefix(SordInserter* inserter, + const SerdNode* name, + const SerdNode* uri); + +/** + Write a statement to the model. + + Note this function can be safely casted to SerdStatementSink. +*/ +SORD_API +SerdStatus +sord_inserter_write_statement(SordInserter* inserter, + SerdStatementFlags flags, + const SerdNode* graph, + const SerdNode* subject, + const SerdNode* predicate, + const SerdNode* object, + const SerdNode* object_datatype, + const SerdNode* object_lang); + +/** + @} + @name Iteration + @{ +*/ + +/** + Set @c quad to the quad pointed to by @c iter. +*/ +SORD_API +void +sord_iter_get(const SordIter* iter, SordQuad quad); + +/** + Return a field of the quad pointed to by @c iter. +*/ +SORD_API +const SordNode* +sord_iter_get_node(const SordIter* iter, SordQuadIndex index); + +/** + Return the store pointed to by @c iter. +*/ +SORD_API +const SordModel* +sord_iter_get_model(SordIter* iter); + +/** + Increment @c iter to point to the next statement. +*/ +SORD_API +bool +sord_iter_next(SordIter* iter); + +/** + Return true iff @c iter is at the end of its range. +*/ +SORD_API +bool +sord_iter_end(const SordIter* iter); + +/** + Free @c iter. +*/ +SORD_API +void +sord_iter_free(SordIter* iter); + +/** + @} + @name Utilities + @{ +*/ + +/** + Match two quads (using ID comparison only). + + This function is a straightforward and fast equivalence match with wildcard + support (ID 0 is a wildcard). It does not actually read node data. + @return true iff @c x and @c y match. +*/ +SORD_API +bool +sord_quad_match(const SordQuad x, const SordQuad y); + +/** + @} + @name Serialisation + @{ +*/ + +/** + Return a reader that will read into @c model. +*/ +SORD_API +SerdReader* +sord_new_reader(SordModel* model, + SerdEnv* env, + SerdSyntax syntax, + SordNode* graph); + +/** + Write a model to a writer. +*/ +SORD_API +bool +sord_write(SordModel* model, + SerdWriter* writer, + SordNode* graph); + +/** + Write a range to a writer. + + This increments @c iter to its end, then frees it. +*/ +SORD_API +bool +sord_write_iter(SordIter* iter, + SerdWriter* writer); + +/** + @} + @} +*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SORD_SORD_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/include/sord-0/sord/sordmm.hpp Wed Mar 20 15:23:43 2013 +0000 @@ -0,0 +1,653 @@ +/* + Copyright 2011-2013 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. +*/ + +/** + @file sordmm.hpp + Public Sord C++ API. +*/ + +#ifndef SORD_SORDMM_HPP +#define SORD_SORDMM_HPP + +#include <cassert> +#include <cstring> +#include <cstdlib> +#include <iostream> +#include <set> +#include <string> +#include <sstream> + +#include "serd/serd.h" +#include "sord/sord.h" + +#define SORD_NS_XSD "http://www.w3.org/2001/XMLSchema#" + +namespace Sord { + +/** Utility base class to prevent copying. */ +class Noncopyable { +protected: + Noncopyable() {} + ~Noncopyable() {} +private: + Noncopyable(const Noncopyable&); + const Noncopyable& operator=(const Noncopyable&); +}; + +/** C++ wrapper for a Sord object. */ +template <typename T> +class Wrapper { +public: + inline Wrapper(T c_obj = NULL) : _c_obj(c_obj) {} + + inline T c_obj() { return _c_obj; } + inline const T c_obj() const { return _c_obj; } + +protected: + T _c_obj; +}; + +/** Collection of RDF namespaces with prefixes. */ +class Namespaces : public Wrapper<SerdEnv*> { +public: + Namespaces() : Wrapper<SerdEnv*>(serd_env_new(NULL)) {} + ~Namespaces() { serd_env_free(_c_obj); } + + static inline SerdNode string_to_node(SerdType type, const std::string& s) { + SerdNode ret = { + (const uint8_t*)s.c_str(), s.length(), s.length(), 0, type }; + return ret; + } + + inline void add(const std::string& name, + const std::string& uri) { + const SerdNode name_node = string_to_node(SERD_LITERAL, name); + const SerdNode uri_node = string_to_node(SERD_URI, uri); + serd_env_set_prefix(_c_obj, &name_node, &uri_node); + } + + inline std::string qualify(std::string uri) const { + const SerdNode uri_node = string_to_node(SERD_URI, uri); + SerdNode prefix; + SerdChunk suffix; + if (serd_env_qualify(_c_obj, &uri_node, &prefix, &suffix)) { + std::string ret((const char*)prefix.buf, prefix.n_bytes); + ret.append(":").append((const char*)suffix.buf, suffix.len); + return ret; + } + return uri; + } + + inline std::string expand(const std::string& curie) const { + assert(curie.find(":") != std::string::npos); + SerdNode curie_node = string_to_node(SERD_CURIE, curie); + SerdChunk uri_prefix; + SerdChunk uri_suffix; + if (!serd_env_expand(_c_obj, &curie_node, &uri_prefix, &uri_suffix)) { + std::string ret((const char*)uri_prefix.buf, uri_prefix.len); + ret.append((const char*)uri_suffix.buf, uri_suffix.len); + return ret; + } + std::cerr << "CURIE `" << curie << "' has unknown prefix." << std::endl; + return curie; + } +}; + +/** Sord library state. */ +class World : public Noncopyable, public Wrapper<SordWorld*> { +public: + inline World() + : _next_blank_id(0) + { + _c_obj = sord_world_new(); + } + + inline ~World() { + sord_world_free(_c_obj); + } + + inline uint64_t blank_id() { return _next_blank_id++; } + + inline void add_prefix(const std::string& prefix, const std::string& uri) { + _prefixes.add(prefix, uri); + } + + inline const Namespaces& prefixes() const { return _prefixes; } + inline SordWorld* world() { return _c_obj; } + +private: + Namespaces _prefixes; + std::set<std::string> _blank_ids; + uint64_t _next_blank_id; +}; + +/** An RDF Node (resource, literal, etc) + */ +class Node : public Wrapper<SordNode*> { +public: + enum Type { + UNKNOWN = 0, + URI = SORD_URI, + BLANK = SORD_BLANK, + LITERAL = SORD_LITERAL + }; + + inline Node() : Wrapper<SordNode*>(NULL), _world(NULL) {} + + inline Node(World& world, Type t, const std::string& s); + inline Node(World& world); + inline Node(World& world, const SordNode* node); + inline Node(World& world, SordNode* node, bool copy=false); + inline Node(const Node& other); + inline ~Node(); + + inline Type type() const { + return _c_obj ? (Type)sord_node_get_type(_c_obj) : UNKNOWN; + } + + inline const SordNode* get_node() const { return _c_obj; } + inline SordNode* get_node() { return _c_obj; } + + const SerdNode* to_serd_node() { + return sord_node_to_serd_node(_c_obj); + } + + inline bool is_valid() const { return type() != UNKNOWN; } + + inline bool operator<(const Node& other) const { + if (type() != other.type()) { + return type() < other.type(); + } else { + return to_string() < other.to_string(); + } + } + + Node& operator=(const Node& other) { + if (&other != this) { + if (_c_obj) { + sord_node_free(_world->c_obj(), _c_obj); + } + _world = other._world; + _c_obj = other._c_obj ? sord_node_copy(other._c_obj) : NULL; + } + return *this; + } + + inline bool operator==(const Node& other) const { + return sord_node_equals(_c_obj, other._c_obj); + } + + inline const uint8_t* to_u_string() const; + inline const char* to_c_string() const; + inline std::string to_string() const; + + inline bool is_literal_type(const char* type_uri) const; + + inline bool is_uri() const { return _c_obj && type() == URI; } + inline bool is_blank() const { return _c_obj && type() == BLANK; } + inline bool is_int() const { return is_literal_type(SORD_NS_XSD "integer"); } + inline bool is_float() const { return is_literal_type(SORD_NS_XSD "decimal"); } + inline bool is_bool() const { return is_literal_type(SORD_NS_XSD "boolean"); } + + inline int to_int() const; + inline float to_float() const; + inline bool to_bool() const; + + inline static Node blank_id(World& world, const std::string base="b") { + const uint64_t num = world.blank_id(); + std::ostringstream ss; + ss << base << num; + return Node(world, Node::BLANK, ss.str()); + } + +private: + World* _world; +}; + +inline std::ostream& +operator<<(std::ostream& os, const Node& node) +{ + return os << node.to_string(); +} + +class URI : public Node { +public: + inline URI(World& world, const std::string& s) + : Node(world, Node::URI, s) {} + inline URI(World& world, const std::string& s, const std::string& base) + : Node(world, sord_new_relative_uri(world.world(), + (const uint8_t*)s.c_str(), + (const uint8_t*)base.c_str())) + {} +}; + +class Curie : public Node { +public: + inline Curie(World& world, const std::string& s) + : Node(world, Node::URI, world.prefixes().expand(s)) {} +}; + +class Literal : public Node { +public: + inline Literal(World& world, const std::string& s) + : Node(world, Node::LITERAL, s) {} + + static inline Node decimal(World& world, double d, unsigned frac_digits) { + const SerdNode val = serd_node_new_decimal(d, 7); + const SerdNode type = serd_node_from_string( + SERD_URI, (const uint8_t*)SORD_NS_XSD "decimal"); + + return Node( + world, + sord_node_from_serd_node( + world.c_obj(), world.prefixes().c_obj(), &val, &type, NULL), + false); + } + + static inline Node integer(World& world, int64_t i) { + const SerdNode val = serd_node_new_integer(i); + const SerdNode type = serd_node_from_string( + SERD_URI, (const uint8_t*)SORD_NS_XSD "integer"); + + return Node( + world, + sord_node_from_serd_node( + world.c_obj(), world.prefixes().c_obj(), &val, &type, NULL), + false); + } +}; + +inline +Node::Node(World& world, Type type, const std::string& s) + : _world(&world) +{ + switch (type) { + case URI: + _c_obj = sord_new_uri( + world.world(), (const unsigned char*)s.c_str()); + break; + case LITERAL: + _c_obj = sord_new_literal( + world.world(), NULL, (const unsigned char*)s.c_str(), NULL); + break; + case BLANK: + _c_obj = sord_new_blank( + world.world(), (const unsigned char*)s.c_str()); + break; + default: + _c_obj = NULL; + } + + assert(this->type() == type); +} + +inline +Node::Node(World& world) + : _world(&world) +{ + Node me = blank_id(world); + *this = me; +} + +inline +Node::Node(World& world, const SordNode* node) + : _world(&world) +{ + _c_obj = sord_node_copy(node); +} + +inline +Node::Node(World& world, SordNode* node, bool copy) + : _world(&world) +{ + _c_obj = copy ? sord_node_copy(node) : node; +} + +inline +Node::Node(const Node& other) + : Wrapper<SordNode*>() + , _world(other._world) +{ + if (_world) { + _c_obj = other._c_obj ? sord_node_copy(other._c_obj) : NULL; + } + + assert((!_c_obj && !other._c_obj) || to_string() == other.to_string()); +} + +inline +Node::~Node() +{ + if (_world) { + sord_node_free(_world->c_obj(), _c_obj); + } +} + +inline std::string +Node::to_string() const +{ + return _c_obj ? (const char*)sord_node_get_string(_c_obj) : ""; +} + +inline const char* +Node::to_c_string() const +{ + return (const char*)sord_node_get_string(_c_obj); +} + +inline const uint8_t* +Node::to_u_string() const +{ + return sord_node_get_string(_c_obj); +} + +inline bool +Node::is_literal_type(const char* type_uri) const +{ + if (_c_obj && sord_node_get_type(_c_obj) == SORD_LITERAL) { + const SordNode* datatype = sord_node_get_datatype(_c_obj); + if (datatype && !strcmp((const char*)sord_node_get_string(datatype), + type_uri)) + return true; + } + return false; +} + +inline int +Node::to_int() const +{ + assert(is_int()); + char* endptr; + return strtol((const char*)sord_node_get_string(_c_obj), &endptr, 10); +} + +inline float +Node::to_float() const +{ + assert(is_float()); + char* endptr; + return serd_strtod((const char*)sord_node_get_string(_c_obj), &endptr); +} + +inline bool +Node::to_bool() const +{ + assert(is_bool()); + return !strcmp((const char*)sord_node_get_string(_c_obj), "true"); +} + +struct Iter : public Wrapper<SordIter*> { + inline Iter(World& world, SordIter* c_obj) + : Wrapper<SordIter*>(c_obj), _world(world) {} + inline ~Iter() { sord_iter_free(_c_obj); } + inline bool end() const { return sord_iter_end(_c_obj); } + inline bool next() const { return sord_iter_next(_c_obj); } + inline Iter& operator++() { + assert(!end()); + next(); + return *this; + } + inline const Node get_subject() const { + SordQuad quad; + sord_iter_get(_c_obj, quad); + return Node(_world, quad[SORD_SUBJECT]); + } + inline const Node get_predicate() const { + SordQuad quad; + sord_iter_get(_c_obj, quad); + return Node(_world, quad[SORD_PREDICATE]); + } + inline const Node get_object() const { + SordQuad quad; + sord_iter_get(_c_obj, quad); + return Node(_world, quad[SORD_OBJECT]); + } + World& _world; +}; + +/** An RDF Model (collection of triples). + */ +class Model : public Noncopyable, public Wrapper<SordModel*> { +public: + inline Model(World& world, + const std::string& base_uri, + unsigned indices = (SORD_SPO | SORD_OPS), + bool graphs = true); + + inline ~Model(); + + inline const Node& base_uri() const { return _base; } + + size_t num_quads() const { return sord_num_quads(_c_obj); } + + inline void load_file(SerdEnv* env, + SerdSyntax syntax, + const std::string& uri, + const std::string& base_uri=""); + + inline void load_string(SerdEnv* env, + SerdSyntax syntax, + const char* str, + size_t len, + const std::string& base_uri); + + inline SerdStatus write_to_file( + const std::string& uri, + SerdSyntax syntax = SERD_TURTLE, + SerdStyle style = (SerdStyle)(SERD_STYLE_ABBREVIATED + |SERD_STYLE_CURIED + |SERD_STYLE_RESOLVED)); + + inline std::string write_to_string( + const std::string& base_uri, + SerdSyntax syntax = SERD_TURTLE, + SerdStyle style = (SerdStyle)(SERD_STYLE_ABBREVIATED + |SERD_STYLE_CURIED + |SERD_STYLE_RESOLVED)); + + inline void add_statement(const Node& subject, + const Node& predicate, + const Node& object); + + inline Iter find(const Node& subject, + const Node& predicate, + const Node& object); + + inline Node get(const Node& subject, + const Node& predicate, + const Node& object); + + inline World& world() const { return _world; } + +private: + World& _world; + Node _base; + SerdWriter* _writer; + size_t _next_blank_id; +}; + +/** Create an empty in-memory RDF model. + */ +inline +Model::Model(World& world, + const std::string& base_uri, + unsigned indices, + bool graphs) + : _world(world) + , _base(world, Node::URI, base_uri) + , _writer(NULL) +{ + _c_obj = sord_new(_world.world(), indices, graphs); +} + +inline void +Model::load_string(SerdEnv* env, + SerdSyntax syntax, + const char* str, + size_t len, + const std::string& base_uri) +{ + SerdReader* reader = sord_new_reader(_c_obj, env, syntax, NULL); + serd_reader_read_string(reader, (const uint8_t*)str); + serd_reader_free(reader); +} + +inline Model::~Model() +{ + sord_free(_c_obj); +} + +inline void +Model::load_file(SerdEnv* env, + SerdSyntax syntax, + const std::string& data_uri, + const std::string& base_uri) +{ + uint8_t* path = serd_file_uri_parse((const uint8_t*)data_uri.c_str(), NULL); + if (!path) { + fprintf(stderr, "Failed to parse file URI <%s>\n", data_uri.c_str()); + return; + } + + // FIXME: blank prefix parameter? + SerdReader* reader = sord_new_reader(_c_obj, env, syntax, NULL); + serd_reader_read_file(reader, path); + serd_reader_free(reader); + free(path); +} + +inline SerdStatus +Model::write_to_file(const std::string& uri, SerdSyntax syntax, SerdStyle style) +{ + uint8_t* path = serd_file_uri_parse((const uint8_t*)uri.c_str(), NULL); + if (!path) { + fprintf(stderr, "Failed to parse file URI <%s>\n", uri.c_str()); + return SERD_ERR_BAD_ARG; + } + + FILE* const fd = fopen((const char*)path, "w"); + if (!fd) { + fprintf(stderr, "Failed to open file %s\n", path); + free(path); + return SERD_ERR_UNKNOWN; + } + free(path); + + SerdURI base_uri = SERD_URI_NULL; + if (serd_uri_parse((const uint8_t*)uri.c_str(), &base_uri)) { + fprintf(stderr, "Invalid base URI <%s>\n", uri.c_str()); + fclose(fd); + return SERD_ERR_BAD_ARG; + } + + SerdWriter* writer = serd_writer_new(syntax, + style, + _world.prefixes().c_obj(), + &base_uri, + serd_file_sink, + fd); + + serd_env_foreach(_world.prefixes().c_obj(), + (SerdPrefixSink)serd_writer_set_prefix, + writer); + + sord_write(_c_obj, writer, 0); + serd_writer_free(writer); + fclose(fd); + + return SERD_SUCCESS; +} + +static size_t +string_sink(const void* buf, size_t len, void* stream) +{ + std::string* str = (std::string*)stream; + str->append((const char*)buf, len); + return len; +} + +inline std::string +Model::write_to_string(const std::string& base_uri_str, + SerdSyntax syntax, + SerdStyle style) +{ + SerdURI base_uri = SERD_URI_NULL; + if (serd_uri_parse((const uint8_t*)base_uri_str.c_str(), &base_uri)) { + fprintf(stderr, "Invalid base URI <%s>\n", base_uri_str.c_str()); + return ""; + } + + std::string ret; + + SerdWriter* writer = serd_writer_new(syntax, + style, + _world.prefixes().c_obj(), + &base_uri, + string_sink, + &ret); + + serd_env_foreach(_world.prefixes().c_obj(), + (SerdPrefixSink)serd_writer_set_prefix, + writer); + + sord_write(_c_obj, writer, 0); + + serd_writer_free(writer); + return ret; +} + +inline void +Model::add_statement(const Node& subject, + const Node& predicate, + const Node& object) +{ + SordQuad quad = { subject.c_obj(), + predicate.c_obj(), + object.c_obj(), + NULL }; + + sord_add(_c_obj, quad); +} + +inline Iter +Model::find(const Node& subject, + const Node& predicate, + const Node& object) +{ + SordQuad quad = { subject.c_obj(), + predicate.c_obj(), + object.c_obj(), + NULL }; + + return Iter(_world, sord_find(_c_obj, quad)); +} + +inline Node +Model::get(const Node& subject, + const Node& predicate, + const Node& object) +{ + SordNode* c_node = sord_get( + _c_obj, subject.c_obj(), predicate.c_obj(), object.c_obj(), NULL); + Node node(_world, c_node); + sord_node_free(_world.c_obj(), c_node); + return node; +} + +} // namespace Sord + +#endif // SORD_SORDMM_HPP +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/lib/pkgconfig/serd-0.pc Wed Mar 20 15:23:43 2013 +0000 @@ -0,0 +1,10 @@ +prefix=/work/sonic-visualiser/sv-dependency-builds/win32-mingw +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: Serd +Version: 0.18.2 +Description: Lightweight RDF syntax library +Libs: -L${libdir} -lserd-0 +Cflags: -I${includedir}/serd-0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32-mingw/lib/pkgconfig/sord-0.pc Wed Mar 20 15:23:43 2013 +0000 @@ -0,0 +1,11 @@ +prefix=/work/sonic-visualiser/sv-dependency-builds/win32-mingw +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: Sord +Version: 0.12.0 +Description: A lightweight C library for storing RDF statements in memory. +Requires: serd-0 +Libs: -L${libdir} -lsord-0 +Cflags: -I${includedir}/sord-0