changeset 115:1609fb751561

sord-0 -> sord and serd-0 -> serd
author Chris Cannam <cannam@all-day-breakfast.com>
date Thu, 09 Jan 2014 21:21:48 +0000
parents 241db1b1eff2
children e448888319fc
files osx/include/serd-0/serd/serd.h osx/include/serd/serd.h osx/include/sord-0/sord/sord.h osx/include/sord-0/sord/sordmm.hpp osx/include/sord/sord.h osx/include/sord/sordmm.hpp
diffstat 6 files changed, 2243 insertions(+), 2243 deletions(-) [+]
line wrap: on
line diff
--- a/osx/include/serd-0/serd/serd.h	Thu Jan 09 13:23:08 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,963 +0,0 @@
-/*
-  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/osx/include/serd/serd.h	Thu Jan 09 21:21:48 2014 +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 */
--- a/osx/include/sord-0/sord/sord.h	Thu Jan 09 13:23:08 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,627 +0,0 @@
-/*
-  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 */
--- a/osx/include/sord-0/sord/sordmm.hpp	Thu Jan 09 13:23:08 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,653 +0,0 @@
-/*
-  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/osx/include/sord/sord.h	Thu Jan 09 21:21:48 2014 +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/osx/include/sord/sordmm.hpp	Thu Jan 09 21:21:48 2014 +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
+