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
+
Binary file win32-mingw/lib/libserd-0.a has changed
Binary file win32-mingw/lib/libsord-0.a has changed
--- /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