1 /*
2   Copyright 2011-2017 David Robillard <http://drobilla.net>
3 
4   Permission to use, copy, modify, and/or distribute this software for any
5   purpose with or without fee is hereby granted, provided that the above
6   copyright notice and this permission notice appear in all copies.
7 
8   THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16 
17 /**
18    @file serd.h API for Serd, a lightweight RDF syntax library.
19 */
20 
21 #ifndef SERD_SERD_H
22 #define SERD_SERD_H
23 
24 #include <stdarg.h>
25 #include <stdbool.h>
26 #include <stddef.h>
27 #include <stdint.h>
28 #include <stdio.h>
29 
30 #ifdef SERD_SHARED
31 #    ifdef _WIN32
32 #        define SERD_LIB_IMPORT __declspec(dllimport)
33 #        define SERD_LIB_EXPORT __declspec(dllexport)
34 #    else
35 #        define SERD_LIB_IMPORT __attribute__((visibility("default")))
36 #        define SERD_LIB_EXPORT __attribute__((visibility("default")))
37 #    endif
38 #    ifdef SERD_INTERNAL
39 #        define SERD_API SERD_LIB_EXPORT
40 #    else
41 #        define SERD_API SERD_LIB_IMPORT
42 #    endif
43 #else
44 #    define SERD_API
45 #endif
46 
47 #ifdef __cplusplus
48 extern "C" {
49 #endif
50 
51 /**
52    @defgroup serd Serd
53    A lightweight RDF syntax library.
54    @{
55 */
56 
57 /**
58    Environment.
59 
60    Represents the state required to resolve a CURIE or relative URI, e.g. the
61    base URI and set of namespace prefixes at a particular point.
62 */
63 typedef struct SerdEnvImpl SerdEnv;
64 
65 /**
66    RDF reader.
67 
68    Parses RDF by calling user-provided sink functions as input is consumed
69    (much like an XML SAX parser).
70 */
71 typedef struct SerdReaderImpl SerdReader;
72 
73 /**
74    RDF writer.
75 
76    Provides a number of functions to allow writing RDF syntax out to some
77    stream.  These functions are deliberately compatible with the sink functions
78    used by SerdReader, so a reader can be directly connected to a writer to
79    re-serialise a document with minimal overhead.
80 */
81 typedef struct SerdWriterImpl SerdWriter;
82 
83 /**
84    Return status code.
85 */
86 typedef enum {
87 	SERD_SUCCESS,         /**< No error */
88 	SERD_FAILURE,         /**< Non-fatal failure */
89 	SERD_ERR_UNKNOWN,     /**< Unknown error */
90 	SERD_ERR_BAD_SYNTAX,  /**< Invalid syntax */
91 	SERD_ERR_BAD_ARG,     /**< Invalid argument */
92 	SERD_ERR_NOT_FOUND,   /**< Not found */
93 	SERD_ERR_ID_CLASH,    /**< Encountered clashing blank node IDs */
94 	SERD_ERR_BAD_CURIE,   /**< Invalid CURIE (e.g. prefix does not exist) */
95 	SERD_ERR_INTERNAL     /**< Unexpected internal error (should not happen) */
96 } SerdStatus;
97 
98 /**
99    RDF syntax type.
100 */
101 typedef enum {
102 	/**
103 	   Turtle - Terse RDF Triple Language (UTF-8).
104 	   @see <a href="http://www.w3.org/TeamSubmission/turtle/">Turtle</a>
105 	*/
106 	SERD_TURTLE = 1,
107 
108 	/**
109 	   NTriples - Line-based RDF triples (ASCII).
110 	   @see <a href="http://www.w3.org/TR/rdf-testcases#ntriples">NTriples</a>
111 	*/
112 	SERD_NTRIPLES = 2,
113 
114 	/**
115 	   NQuads - Line-based RDF quads (UTF-8).
116 	   @see <a href="https://www.w3.org/TR/n-quads/">NQuads</a>
117 	*/
118 	SERD_NQUADS = 3,
119 
120 	/**
121 	   TriG - Terse RDF quads (UTF-8).
122 	   @see <a href="https://www.w3.org/TR/trig/">Trig</a>
123 	*/
124 	SERD_TRIG = 4
125 } SerdSyntax;
126 
127 /**
128    Flags indicating inline abbreviation information for a statement.
129 */
130 typedef enum {
131 	SERD_EMPTY_S      = 1 << 1,  /**< Empty blank node subject */
132 	SERD_EMPTY_O      = 1 << 2,  /**< Empty blank node object */
133 	SERD_ANON_S_BEGIN = 1 << 3,  /**< Start of anonymous subject */
134 	SERD_ANON_O_BEGIN = 1 << 4,  /**< Start of anonymous object */
135 	SERD_ANON_CONT    = 1 << 5,  /**< Continuation of anonymous node */
136 	SERD_LIST_S_BEGIN = 1 << 6,  /**< Start of list subject */
137 	SERD_LIST_O_BEGIN = 1 << 7,  /**< Start of list object */
138 	SERD_LIST_CONT    = 1 << 8   /**< Continuation of list */
139 } SerdStatementFlag;
140 
141 /**
142    Bitwise OR of SerdStatementFlag values.
143 */
144 typedef uint32_t SerdStatementFlags;
145 
146 /**
147    Type of a syntactic RDF node.
148 
149    This is more precise than the type of an abstract RDF node.  An abstract
150    node is either a resource, literal, or blank.  In syntax there are two ways
151    to refer to a resource (by URI or CURIE) and two ways to refer to a blank
152    (by ID or anonymously).  Anonymous (inline) blank nodes are expressed using
153    SerdStatementFlags rather than this type.
154 */
155 typedef enum {
156 	/**
157 	   The type of a nonexistent node.
158 
159 	   This type is useful as a sentinel, but is never emitted by the reader.
160 	*/
161 	SERD_NOTHING = 0,
162 
163 	/**
164 	   Literal value.
165 
166 	   A literal optionally has either a language, or a datatype (not both).
167 	*/
168 	SERD_LITERAL = 1,
169 
170 	/**
171 	   URI (absolute or relative).
172 
173 	   Value is an unquoted URI string, which is either a relative reference
174 	   with respect to the current base URI (e.g. "foo/bar"), or an absolute
175 	   URI (e.g. "http://example.org/foo").
176 	   @see <a href="http://tools.ietf.org/html/rfc3986">RFC3986</a>.
177 	*/
178 	SERD_URI = 2,
179 
180 	/**
181 	   CURIE, a shortened URI.
182 
183 	   Value is an unquoted CURIE string relative to the current environment,
184 	   e.g. "rdf:type".
185 	   @see <a href="http://www.w3.org/TR/curie">CURIE Syntax 1.0</a>
186 	*/
187 	SERD_CURIE = 3,
188 
189 	/**
190 	   A blank node.
191 
192 	   Value is a blank node ID, e.g. "id3", which is meaningful only within
193 	   this serialisation.
194 	   @see <a href="http://www.w3.org/TeamSubmission/turtle#nodeID">Turtle
195 	   <tt>nodeID</tt></a>
196 	*/
197 	SERD_BLANK = 4
198 } SerdType;
199 
200 /**
201    Flags indicating certain string properties relevant to serialisation.
202 */
203 typedef enum {
204 	SERD_HAS_NEWLINE = 1,      /**< Contains line breaks ('\\n' or '\\r') */
205 	SERD_HAS_QUOTE   = 1 << 1  /**< Contains quotes ('"') */
206 } SerdNodeFlag;
207 
208 /**
209    Bitwise OR of SerdNodeFlag values.
210 */
211 typedef uint32_t SerdNodeFlags;
212 
213 /**
214    A syntactic RDF node.
215 */
216 typedef struct {
217 	const uint8_t* buf;      /**< Value string */
218 	size_t         n_bytes;  /**< Size in bytes (not including null) */
219 	size_t         n_chars;  /**< Length in characters (not including null)*/
220 	SerdNodeFlags  flags;    /**< Node flags (e.g. string properties) */
221 	SerdType       type;     /**< Node type */
222 } SerdNode;
223 
224 /**
225    An unterminated string fragment.
226 */
227 typedef struct {
228 	const uint8_t* buf;  /**< Start of chunk */
229 	size_t         len;  /**< Length of chunk in bytes */
230 } SerdChunk;
231 
232 /**
233    An error description.
234 */
235 typedef struct {
236 	SerdStatus     status;    /**< Error code */
237 	const uint8_t* filename;  /**< File where error was encountered, or NULL */
238 	unsigned       line;      /**< Line where error was encountered, or 0 */
239 	unsigned       col;       /**< Column where error was encountered */
240 	const char*    fmt;       /**< Message format string (printf style) */
241 	va_list*       args;      /**< Arguments for fmt */
242 } SerdError;
243 
244 /**
245    A parsed URI.
246 
247    This struct directly refers to chunks in other strings, it does not own any
248    memory itself.  Thus, URIs can be parsed and/or resolved against a base URI
249    in-place without allocating memory.
250 */
251 typedef struct {
252 	SerdChunk scheme;     /**< Scheme */
253 	SerdChunk authority;  /**< Authority */
254 	SerdChunk path_base;  /**< Path prefix if relative */
255 	SerdChunk path;       /**< Path suffix */
256 	SerdChunk query;      /**< Query */
257 	SerdChunk fragment;   /**< Fragment */
258 } SerdURI;
259 
260 /**
261    Syntax style options.
262 
263    The style of the writer output can be controlled by ORing together
264    values from this enumeration.  Note that some options are only supported
265    for some syntaxes (e.g. NTriples does not support abbreviation and is
266    always ASCII).
267 */
268 typedef enum {
269 	SERD_STYLE_ABBREVIATED = 1,       /**< Abbreviate triples when possible. */
270 	SERD_STYLE_ASCII       = 1 << 1,  /**< Escape all non-ASCII characters. */
271 	SERD_STYLE_RESOLVED    = 1 << 2,  /**< Resolve URIs against base URI. */
272 	SERD_STYLE_CURIED      = 1 << 3,  /**< Shorten URIs into CURIEs. */
273 	SERD_STYLE_BULK        = 1 << 4   /**< Write output in pages. */
274 } SerdStyle;
275 
276 /**
277    Free memory allocated by Serd.
278 
279    This function exists because some systems require memory allocated by a
280    library to be freed by code in the same library.  It is otherwise equivalent
281    to the standard C free() function.
282 */
283 SERD_API
284 void
285 serd_free(void* ptr);
286 
287 /**
288    @name String Utilities
289    @{
290 */
291 
292 /**
293    Return a string describing a status code.
294 */
295 SERD_API
296 const uint8_t*
297 serd_strerror(SerdStatus status);
298 
299 /**
300    Measure a UTF-8 string.
301    @return Length of `str` in characters (except NULL).
302    @param str A null-terminated UTF-8 string.
303    @param n_bytes (Output) Set to the size of `str` in bytes (except NULL).
304    @param flags (Output) Set to the applicable flags.
305 */
306 SERD_API
307 size_t
308 serd_strlen(const uint8_t* str, size_t* n_bytes, SerdNodeFlags* flags);
309 
310 /**
311    Parse a string to a double.
312 
313    The API of this function is identical to the standard C strtod function,
314    except this function is locale-independent and always matches the lexical
315    format used in the Turtle grammar (the decimal point is always ".").
316 */
317 SERD_API
318 double
319 serd_strtod(const char* str, char** endptr);
320 
321 /**
322    Decode a base64 string.
323    This function can be used to deserialise a blob node created with
324    serd_node_new_blob().
325 
326    @param str Base64 string to decode.
327    @param len The length of `str`.
328    @param size Set to the size of the returned blob in bytes.
329    @return A newly allocated blob which must be freed with serd_free().
330 */
331 SERD_API
332 void*
333 serd_base64_decode(const uint8_t* str, size_t len, size_t* size);
334 
335 /**
336    @}
337    @name Byte Streams
338    @{
339 */
340 
341 /**
342    Function to detect I/O stream errors.
343 
344    Identical semantics to `ferror`.
345 
346    @return Non-zero if `stream` has encountered an error.
347 */
348 typedef int (*SerdStreamErrorFunc)(void* stream);
349 
350 /**
351    Source function for raw string input.
352 
353    Identical semantics to `fread`, but may set errno for more informative error
354    reporting than supported by SerdStreamErrorFunc.
355 
356    @param buf Output buffer.
357    @param size Size of a single element of data in bytes (always 1).
358    @param nmemb Number of elements to read.
359    @param stream Stream to read from (FILE* for fread).
360    @return Number of elements (bytes) read.
361 */
362 typedef size_t (*SerdSource)(void*  buf,
363                              size_t size,
364                              size_t nmemb,
365                              void*  stream);
366 
367 /**
368    Sink function for raw string output.
369 */
370 typedef size_t (*SerdSink)(const void* buf, size_t len, void* stream);
371 
372 /**
373    @}
374    @name URI
375    @{
376 */
377 
378 static const SerdURI SERD_URI_NULL = {
379 	{NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}
380 };
381 
382 /**
383    Return the local path for `uri`, or NULL if `uri` is not a file URI.
384    Note this (inappropriately named) function only removes the file scheme if
385    necessary, and returns `uri` unmodified if it is an absolute path.  Percent
386    encoding and other issues are not handled, to properly convert a file URI to
387    a path, use serd_file_uri_parse().
388 */
389 SERD_API
390 const uint8_t*
391 serd_uri_to_path(const uint8_t* uri);
392 
393 /**
394    Get the unescaped path and hostname from a file URI.
395    @param uri A file URI.
396    @param hostname If non-NULL, set to the hostname, if present.
397    @return The path component of the URI.
398 
399    The returned path and `*hostname` must be freed with serd_free().
400 */
401 SERD_API
402 uint8_t*
403 serd_file_uri_parse(const uint8_t* uri, uint8_t** hostname);
404 
405 /**
406    Return true iff `utf8` starts with a valid URI scheme.
407 */
408 SERD_API
409 bool
410 serd_uri_string_has_scheme(const uint8_t* utf8);
411 
412 /**
413    Parse `utf8`, writing result to `out`.
414 */
415 SERD_API
416 SerdStatus
417 serd_uri_parse(const uint8_t* utf8, SerdURI* out);
418 
419 /**
420    Set target `t` to reference `r` resolved against `base`.
421 
422    @see http://tools.ietf.org/html/rfc3986#section-5.2.2
423 */
424 SERD_API
425 void
426 serd_uri_resolve(const SerdURI* r, const SerdURI* base, SerdURI* t);
427 
428 /**
429    Serialise `uri` with a series of calls to `sink`.
430 */
431 SERD_API
432 size_t
433 serd_uri_serialise(const SerdURI* uri, SerdSink sink, void* stream);
434 
435 /**
436    Serialise `uri` relative to `base` with a series of calls to `sink`.
437 
438    The `uri` is written as a relative URI iff if it a child of `base` and @c
439    root.  The optional `root` parameter must be a prefix of `base` and can be
440    used keep up-references ("../") within a certain namespace.
441 */
442 SERD_API
443 size_t
444 serd_uri_serialise_relative(const SerdURI* uri,
445                             const SerdURI* base,
446                             const SerdURI* root,
447                             SerdSink       sink,
448                             void*          stream);
449 
450 /**
451    @}
452    @name Node
453    @{
454 */
455 
456 static const SerdNode SERD_NODE_NULL = { NULL, 0, 0, 0, SERD_NOTHING };
457 
458 /**
459    Make a (shallow) node from `str`.
460 
461    This measures, but does not copy, `str`.  No memory is allocated.
462 */
463 SERD_API
464 SerdNode
465 serd_node_from_string(SerdType type, const uint8_t* str);
466 
467 /**
468    Make a (shallow) node from a prefix of `str`.
469 
470    This measures, but does not copy, `str`.  No memory is allocated.
471    Note that the returned node may not be null terminated.
472 */
473 SERD_API
474 SerdNode
475 serd_node_from_substring(SerdType type, const uint8_t* str, size_t len);
476 
477 /**
478    Make a deep copy of `node`.
479 
480    @return a node that the caller must free with serd_node_free().
481 */
482 SERD_API
483 SerdNode
484 serd_node_copy(const SerdNode* node);
485 
486 /**
487    Return true iff `a` is equal to `b`.
488 */
489 SERD_API
490 bool
491 serd_node_equals(const SerdNode* a, const SerdNode* b);
492 
493 /**
494    Simple wrapper for serd_node_new_uri() to resolve a URI node.
495 */
496 SERD_API
497 SerdNode
498 serd_node_new_uri_from_node(const SerdNode* uri_node,
499                             const SerdURI*  base,
500                             SerdURI*        out);
501 
502 /**
503    Simple wrapper for serd_node_new_uri() to resolve a URI string.
504 */
505 SERD_API
506 SerdNode
507 serd_node_new_uri_from_string(const uint8_t* str,
508                               const SerdURI* base,
509                               SerdURI*       out);
510 
511 /**
512    Create a new file URI node from a file system path and optional hostname.
513 
514    Backslashes in Windows paths will be converted and '%' will always be
515    percent encoded.  If `escape` is true, all other invalid characters will be
516    percent encoded as well.
517 
518    If `path` is relative, `hostname` is ignored.
519    If `out` is not NULL, it will be set to the parsed URI.
520 */
521 SERD_API
522 SerdNode
523 serd_node_new_file_uri(const uint8_t* path,
524                        const uint8_t* hostname,
525                        SerdURI*       out,
526                        bool           escape);
527 
528 /**
529    Create a new node by serialising `uri` into a new string.
530 
531    @param uri The URI to serialise.
532 
533    @param base Base URI to resolve `uri` against (or NULL for no resolution).
534 
535    @param out Set to the parsing of the new URI (i.e. points only to
536    memory owned by the new returned node).
537 */
538 SERD_API
539 SerdNode
540 serd_node_new_uri(const SerdURI* uri, const SerdURI* base, SerdURI* out);
541 
542 /**
543    Create a new node by serialising `uri` into a new relative URI.
544 
545    @param uri The URI to serialise.
546 
547    @param base Base URI to make `uri` relative to, if possible.
548 
549    @param root Root URI for resolution (see serd_uri_serialise_relative()).
550 
551    @param out Set to the parsing of the new URI (i.e. points only to
552    memory owned by the new returned node).
553 */
554 SERD_API
555 SerdNode
556 serd_node_new_relative_uri(const SerdURI* uri,
557                            const SerdURI* base,
558                            const SerdURI* root,
559                            SerdURI*       out);
560 
561 /**
562    Create a new node by serialising `d` into an xsd:decimal string.
563 
564    The resulting node will always contain a `.', start with a digit, and end
565    with a digit (i.e. will have a leading and/or trailing `0' if necessary).
566    It will never be in scientific notation.  A maximum of `frac_digits` digits
567    will be written after the decimal point, but trailing zeros will
568    automatically be omitted (except one if `d` is a round integer).
569 
570    Note that about 16 and 8 fractional digits are required to precisely
571    represent a double and float, respectively.
572 
573    @param d The value for the new node.
574    @param frac_digits The maximum number of digits after the decimal place.
575 */
576 SERD_API
577 SerdNode
578 serd_node_new_decimal(double d, unsigned frac_digits);
579 
580 /**
581    Create a new node by serialising `i` into an xsd:integer string.
582 */
583 SERD_API
584 SerdNode
585 serd_node_new_integer(int64_t i);
586 
587 /**
588    Create a node by serialising `buf` into an xsd:base64Binary string.
589    This function can be used to make a serialisable node out of arbitrary
590    binary data, which can be decoded using serd_base64_decode().
591 
592    @param buf Raw binary input data.
593    @param size Size of `buf`.
594    @param wrap_lines Wrap lines at 76 characters to conform to RFC 2045.
595 */
596 SERD_API
597 SerdNode
598 serd_node_new_blob(const void* buf, size_t size, bool wrap_lines);
599 
600 /**
601    Free any data owned by `node`.
602 
603    Note that if `node` is itself dynamically allocated (which is not the case
604    for nodes created internally by serd), it will not be freed.
605 */
606 SERD_API
607 void
608 serd_node_free(SerdNode* node);
609 
610 /**
611    @}
612    @name Event Handlers
613    @{
614 */
615 
616 /**
617    Sink (callback) for errors.
618 
619    @param handle Handle for user data.
620    @param error Error description.
621 */
622 typedef SerdStatus (*SerdErrorSink)(void*            handle,
623                                     const SerdError* error);
624 
625 /**
626    Sink (callback) for base URI changes.
627 
628    Called whenever the base URI of the serialisation changes.
629 */
630 typedef SerdStatus (*SerdBaseSink)(void*           handle,
631                                    const SerdNode* uri);
632 
633 /**
634    Sink (callback) for namespace definitions.
635 
636    Called whenever a prefix is defined in the serialisation.
637 */
638 typedef SerdStatus (*SerdPrefixSink)(void*           handle,
639                                      const SerdNode* name,
640                                      const SerdNode* uri);
641 
642 /**
643    Sink (callback) for statements.
644 
645    Called for every RDF statement in the serialisation.
646 */
647 typedef SerdStatus (*SerdStatementSink)(void*              handle,
648                                         SerdStatementFlags flags,
649                                         const SerdNode*    graph,
650                                         const SerdNode*    subject,
651                                         const SerdNode*    predicate,
652                                         const SerdNode*    object,
653                                         const SerdNode*    object_datatype,
654                                         const SerdNode*    object_lang);
655 
656 /**
657    Sink (callback) for anonymous node end markers.
658 
659    This is called to indicate that the anonymous node with the given
660    `value` will no longer be referred to by any future statements
661    (i.e. the anonymous serialisation of the node is finished).
662 */
663 typedef SerdStatus (*SerdEndSink)(void*           handle,
664                                   const SerdNode* node);
665 
666 /**
667    @}
668    @name Environment
669    @{
670 */
671 
672 /**
673    Create a new environment.
674 */
675 SERD_API
676 SerdEnv*
677 serd_env_new(const SerdNode* base_uri);
678 
679 /**
680    Free `ns`.
681 */
682 SERD_API
683 void
684 serd_env_free(SerdEnv* env);
685 
686 /**
687    Get the current base URI.
688 */
689 SERD_API
690 const SerdNode*
691 serd_env_get_base_uri(const SerdEnv* env,
692                       SerdURI*       out);
693 
694 /**
695    Set the current base URI.
696 */
697 SERD_API
698 SerdStatus
699 serd_env_set_base_uri(SerdEnv*        env,
700                       const SerdNode* uri);
701 
702 /**
703    Set a namespace prefix.
704 */
705 SERD_API
706 SerdStatus
707 serd_env_set_prefix(SerdEnv*        env,
708                     const SerdNode* name,
709                     const SerdNode* uri);
710 
711 /**
712    Set a namespace prefix.
713 */
714 SERD_API
715 SerdStatus
716 serd_env_set_prefix_from_strings(SerdEnv*       env,
717                                  const uint8_t* name,
718                                  const uint8_t* uri);
719 
720 /**
721    Qualify `uri` into a CURIE if possible.
722 */
723 SERD_API
724 bool
725 serd_env_qualify(const SerdEnv*  env,
726                  const SerdNode* uri,
727                  SerdNode*       prefix,
728                  SerdChunk*      suffix);
729 
730 /**
731    Expand `curie`.
732 
733    Errors: SERD_ERR_BAD_ARG if `curie` is not valid, or SERD_ERR_BAD_CURIE if
734    prefix is not defined in `env`.
735 */
736 SERD_API
737 SerdStatus
738 serd_env_expand(const SerdEnv*  env,
739                 const SerdNode* curie,
740                 SerdChunk*      uri_prefix,
741                 SerdChunk*      uri_suffix);
742 
743 /**
744    Expand `node`, which must be a CURIE or URI, to a full URI.
745 
746    Returns null if `node` can not be expanded.
747 */
748 SERD_API
749 SerdNode
750 serd_env_expand_node(const SerdEnv*  env,
751                      const SerdNode* node);
752 
753 /**
754    Call `func` for each prefix defined in `env`.
755 */
756 SERD_API
757 void
758 serd_env_foreach(const SerdEnv* env,
759                  SerdPrefixSink func,
760                  void*          handle);
761 
762 /**
763    @}
764    @name Reader
765    @{
766 */
767 
768 /**
769    Create a new RDF reader.
770 */
771 SERD_API
772 SerdReader*
773 serd_reader_new(SerdSyntax        syntax,
774                 void*             handle,
775                 void              (*free_handle)(void*),
776                 SerdBaseSink      base_sink,
777                 SerdPrefixSink    prefix_sink,
778                 SerdStatementSink statement_sink,
779                 SerdEndSink       end_sink);
780 
781 /**
782    Enable or disable strict parsing.
783 
784    The reader is non-strict (lax) by default, which will tolerate URIs with
785    invalid characters.  Setting strict will fail when parsing such files.  An
786    error is printed for invalid input in either case.
787 */
788 SERD_API
789 void
790 serd_reader_set_strict(SerdReader* reader, bool strict);
791 
792 /**
793    Set a function to be called when errors occur during reading.
794 
795    The `error_sink` will be called with `handle` as its first argument.  If
796    no error function is set, errors are printed to stderr in GCC style.
797 */
798 SERD_API
799 void
800 serd_reader_set_error_sink(SerdReader*   reader,
801                            SerdErrorSink error_sink,
802                            void*         error_handle);
803 
804 /**
805    Return the `handle` passed to serd_reader_new().
806 */
807 SERD_API
808 void*
809 serd_reader_get_handle(const SerdReader* reader);
810 
811 /**
812    Set a prefix to be added to all blank node identifiers.
813 
814    This is useful when multiple files are to be parsed into the same output
815    (e.g. a store, or other files).  Since Serd preserves blank node IDs, this
816    could cause conflicts where two non-equivalent blank nodes are merged,
817    resulting in corrupt data.  By setting a unique blank node prefix for each
818    parsed file, this can be avoided, while preserving blank node names.
819 */
820 SERD_API
821 void
822 serd_reader_add_blank_prefix(SerdReader*    reader,
823                              const uint8_t* prefix);
824 
825 /**
826    Set the URI of the default graph.
827 
828    If this is set, the reader will emit quads with the graph set to the given
829    node for any statements that are not in a named graph (which is currently
830    all of them since Serd currently does not support any graph syntaxes).
831 */
832 SERD_API
833 void
834 serd_reader_set_default_graph(SerdReader*     reader,
835                               const SerdNode* graph);
836 
837 /**
838    Read a file at a given `uri`.
839 */
840 SERD_API
841 SerdStatus
842 serd_reader_read_file(SerdReader*    reader,
843                       const uint8_t* uri);
844 
845 /**
846    Start an incremental read from a file handle.
847 
848    Iff `bulk` is true, `file` will be read a page at a time.  This is more
849    efficient, but uses a page of memory and means that an entire page of input
850    must be ready before any callbacks will fire.  To react as soon as input
851    arrives, set `bulk` to false.
852 */
853 SERD_API
854 SerdStatus
855 serd_reader_start_stream(SerdReader*    reader,
856                          FILE*          file,
857                          const uint8_t* name,
858                          bool           bulk);
859 
860 /**
861    Start an incremental read from a user-specified source.
862 
863    The `read_func` is guaranteed to only be called for `page_size` elements
864    with size 1 (i.e. `page_size` bytes).
865 */
866 SERD_API
867 SerdStatus
868 serd_reader_start_source_stream(SerdReader*         reader,
869                                 SerdSource          read_func,
870                                 SerdStreamErrorFunc error_func,
871                                 void*               stream,
872                                 const uint8_t*      name,
873                                 size_t              page_size);
874 
875 /**
876    Read a single "chunk" of data during an incremental read.
877 
878    This function will read a single top level description, and return.  This
879    may be a directive, statement, or several statements; essentially it reads
880    until a '.' is encountered.  This is particularly useful for reading
881    directly from a pipe or socket.
882 */
883 SERD_API
884 SerdStatus
885 serd_reader_read_chunk(SerdReader* reader);
886 
887 /**
888    Finish an incremental read from a file handle.
889 */
890 SERD_API
891 SerdStatus
892 serd_reader_end_stream(SerdReader* reader);
893 
894 /**
895    Read `file`.
896 */
897 SERD_API
898 SerdStatus
899 serd_reader_read_file_handle(SerdReader*    reader,
900                              FILE*          file,
901                              const uint8_t* name);
902 
903 /**
904    Read a user-specified byte source.
905 */
906 SERD_API
907 SerdStatus
908 serd_reader_read_source(SerdReader*         reader,
909                         SerdSource          source,
910                         SerdStreamErrorFunc error,
911                         void*               stream,
912                         const uint8_t*      name,
913                         size_t              page_size);
914 
915 /**
916    Read `utf8`.
917 */
918 SERD_API
919 SerdStatus
920 serd_reader_read_string(SerdReader* reader, const uint8_t* utf8);
921 
922 /**
923    Free `reader`.
924 */
925 SERD_API
926 void
927 serd_reader_free(SerdReader* reader);
928 
929 /**
930    @}
931    @name Writer
932    @{
933 */
934 
935 /**
936    Create a new RDF writer.
937 */
938 SERD_API
939 SerdWriter*
940 serd_writer_new(SerdSyntax     syntax,
941                 SerdStyle      style,
942                 SerdEnv*       env,
943                 const SerdURI* base_uri,
944                 SerdSink       ssink,
945                 void*          stream);
946 
947 /**
948    Free `writer`.
949 */
950 SERD_API
951 void
952 serd_writer_free(SerdWriter* writer);
953 
954 /**
955    Return the env used by `writer`.
956 */
957 SERD_API
958 SerdEnv*
959 serd_writer_get_env(SerdWriter* writer);
960 
961 /**
962    A convenience sink function for writing to a FILE*.
963 
964    This function can be used as a SerdSink when writing to a FILE*.  The
965    `stream` parameter must be a FILE* opened for writing.
966 */
967 SERD_API
968 size_t
969 serd_file_sink(const void* buf, size_t len, void* stream);
970 
971 /**
972    A convenience sink function for writing to a string.
973 
974    This function can be used as a SerdSink to write to a SerdChunk which is
975    resized as necessary with realloc().  The `stream` parameter must point to
976    an initialized SerdChunk.  When the write is finished, the string should be
977    retrieved with serd_chunk_sink_finish().
978 */
979 SERD_API
980 size_t
981 serd_chunk_sink(const void* buf, size_t len, void* stream);
982 
983 /**
984    Finish a serialisation to a chunk with serd_chunk_sink().
985 
986    The returned string is the result of the serialisation, which is NULL
987    terminated (by this function) and owned by the caller.
988 */
989 SERD_API
990 uint8_t*
991 serd_chunk_sink_finish(SerdChunk* stream);
992 
993 /**
994    Set a function to be called when errors occur during writing.
995 
996    The `error_sink` will be called with `handle` as its first argument.  If
997    no error function is set, errors are printed to stderr.
998 */
999 SERD_API
1000 void
1001 serd_writer_set_error_sink(SerdWriter*   writer,
1002                            SerdErrorSink error_sink,
1003                            void*         error_handle);
1004 
1005 /**
1006    Set a prefix to be removed from matching blank node identifiers.
1007 */
1008 SERD_API
1009 void
1010 serd_writer_chop_blank_prefix(SerdWriter*    writer,
1011                               const uint8_t* prefix);
1012 
1013 /**
1014    Set the current output base URI (and emit directive if applicable).
1015 
1016    Note this function can be safely casted to SerdBaseSink.
1017 */
1018 SERD_API
1019 SerdStatus
1020 serd_writer_set_base_uri(SerdWriter*     writer,
1021                          const SerdNode* uri);
1022 
1023 /**
1024    Set the current root URI.
1025 
1026    The root URI should be a prefix of the base URI.  The path of the root URI
1027    is the highest path any relative up-reference can refer to.  For example,
1028    with root <file:///foo/root> and base <file:///foo/root/base>,
1029    <file:///foo/root> will be written as <../>, but <file:///foo> will be
1030    written non-relatively as <file:///foo>.  If the root is not explicitly set,
1031    it defaults to the base URI, so no up-references will be created at all.
1032 */
1033 SERD_API
1034 SerdStatus
1035 serd_writer_set_root_uri(SerdWriter*     writer,
1036                          const SerdNode* uri);
1037 
1038 /**
1039    Set a namespace prefix (and emit directive if applicable).
1040 
1041    Note this function can be safely casted to SerdPrefixSink.
1042 */
1043 SERD_API
1044 SerdStatus
1045 serd_writer_set_prefix(SerdWriter*     writer,
1046                        const SerdNode* name,
1047                        const SerdNode* uri);
1048 
1049 /**
1050    Write a statement.
1051 
1052    Note this function can be safely casted to SerdStatementSink.
1053 */
1054 SERD_API
1055 SerdStatus
1056 serd_writer_write_statement(SerdWriter*        writer,
1057                             SerdStatementFlags flags,
1058                             const SerdNode*    graph,
1059                             const SerdNode*    subject,
1060                             const SerdNode*    predicate,
1061                             const SerdNode*    object,
1062                             const SerdNode*    datatype,
1063                             const SerdNode*    lang);
1064 
1065 /**
1066    Mark the end of an anonymous node's description.
1067 
1068    Note this function can be safely casted to SerdEndSink.
1069 */
1070 SERD_API
1071 SerdStatus
1072 serd_writer_end_anon(SerdWriter*     writer,
1073                      const SerdNode* node);
1074 
1075 /**
1076    Finish a write.
1077 */
1078 SERD_API
1079 SerdStatus
1080 serd_writer_finish(SerdWriter* writer);
1081 
1082 /**
1083    @}
1084    @}
1085 */
1086 
1087 #ifdef __cplusplus
1088 }  /* extern "C" */
1089 #endif
1090 
1091 #endif  /* SERD_SERD_H */
1092