Browse Source

Format all code with clang-format

zrythm_meson
David Robillard 2 years ago
parent
commit
d101d92694
  1. 24
      .clang-format
  2. 281
      include/serd/serd.h
  3. 4
      src/attributes.h
  4. 94
      src/base64.c
  5. 2
      src/base64.h
  6. 95
      src/byte_sink.h
  7. 107
      src/byte_source.c
  8. 108
      src/byte_source.h
  9. 333
      src/env.c
  10. 2668
      src/n3.c
  11. 493
      src/node.c
  12. 19
      src/node.h
  13. 429
      src/reader.c
  14. 186
      src/reader.h
  15. 16
      src/serd_internal.h
  16. 552
      src/serdi.c
  17. 86
      src/stack.h
  18. 223
      src/string.c
  19. 109
      src/string_utils.h
  20. 41
      src/system.c
  21. 12
      src/system.h
  22. 766
      src/uri.c
  23. 81
      src/uri_utils.h
  24. 1565
      src/writer.c
  25. 94
      test/test_env.c
  26. 12
      test/test_free_null.c
  27. 239
      test/test_node.c
  28. 117
      test/test_read_chunk.c
  29. 529
      test/test_reader_writer.c
  30. 42
      test/test_string.c
  31. 216
      test/test_uri.c

24
.clang-format

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
---
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignEscapedNewlinesLeft: true
BasedOnStyle: Mozilla
BraceWrapping:
AfterNamespace: false
AfterClass: true
AfterEnum: false
AfterExternBlock: false
AfterFunction: true
AfterStruct: false
SplitEmptyFunction: false
SplitEmptyRecord: false
BreakBeforeBraces: Custom
Cpp11BracedListStyle: true
IndentCaseLabels: false
IndentPPDirectives: AfterHash
KeepEmptyLinesAtTheStartOfBlocks: false
SpacesInContainerLiterals: false
StatementMacros:
- SERD_API
- SERD_DEPRECATED_BY
...

281
include/serd/serd.h

@ -26,54 +26,59 @@ @@ -26,54 +26,59 @@
#include <stdio.h>
#if defined(SERD_SHARED) && defined(SERD_INTERNAL) && defined(_WIN32)
# define SERD_API __declspec(dllexport)
# define SERD_API __declspec(dllexport)
#elif defined(SERD_SHARED) && defined(_WIN32)
# define SERD_API __declspec(dllimport)
# define SERD_API __declspec(dllimport)
#elif defined(SERD_SHARED) && defined(__GNUC__)
# define SERD_API __attribute__((visibility("default")))
# define SERD_API __attribute__((visibility("default")))
#else
# define SERD_API
# define SERD_API
#endif
#ifdef __GNUC__
# define SERD_PURE_FUNC __attribute__((pure))
# define SERD_CONST_FUNC __attribute__((const))
# define SERD_PURE_FUNC __attribute__((pure))
# define SERD_CONST_FUNC __attribute__((const))
#else
# define SERD_PURE_FUNC
# define SERD_CONST_FUNC
# define SERD_PURE_FUNC
# define SERD_CONST_FUNC
#endif
#ifdef __clang__
# define SERD_NONNULL _Nonnull
# define SERD_NULLABLE _Nullable
# define SERD_ALLOCATED _Null_unspecified
# define SERD_NONNULL _Nonnull
# define SERD_NULLABLE _Nullable
# define SERD_ALLOCATED _Null_unspecified
#else
# define SERD_NONNULL
# define SERD_NULLABLE
# define SERD_ALLOCATED
# define SERD_NONNULL
# define SERD_NULLABLE
# define SERD_ALLOCATED
#endif
#define SERD_PURE_API SERD_API SERD_PURE_FUNC
#define SERD_CONST_API SERD_API SERD_CONST_FUNC
#define SERD_PURE_API \
SERD_API \
SERD_PURE_FUNC
#define SERD_CONST_API \
SERD_API \
SERD_CONST_FUNC
#ifndef SERD_DISABLE_DEPRECATED
# if defined(__clang__)
# define SERD_DEPRECATED_BY(rep) __attribute__((deprecated("", rep)))
# elif defined(__GNUC__) && __GNUC__ > 4
# define SERD_DEPRECATED_BY(rep) __attribute__((deprecated("Use " rep)))
# elif defined(__GNUC__)
# define SERD_DEPRECATED_BY(rep) __attribute__((deprecated))
# else
# define SERD_DEPRECATED_BY(rep)
# endif
# if defined(__clang__)
# define SERD_DEPRECATED_BY(rep) __attribute__((deprecated("", rep)))
# elif defined(__GNUC__) && __GNUC__ > 4
# define SERD_DEPRECATED_BY(rep) __attribute__((deprecated("Use " rep)))
# elif defined(__GNUC__)
# define SERD_DEPRECATED_BY(rep) __attribute__((deprecated))
# else
# define SERD_DEPRECATED_BY(rep)
# endif
#endif
#ifdef __cplusplus
extern "C" {
# if defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
# endif
# if defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
# endif
#endif
/**
@ -93,35 +98,35 @@ typedef struct SerdWriterImpl SerdWriter; @@ -93,35 +98,35 @@ 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)
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 {
SERD_TURTLE = 1, ///< Terse triples http://www.w3.org/TR/turtle
SERD_NTRIPLES = 2, ///< Line-based triples http://www.w3.org/TR/n-triples/
SERD_NQUADS = 3, ///< Line-based quads http://www.w3.org/TR/n-quads/
SERD_TRIG = 4 ///< Terse quads http://www.w3.org/TR/trig/
SERD_TURTLE = 1, ///< Terse triples http://www.w3.org/TR/turtle
SERD_NTRIPLES = 2, ///< Line-based triples http://www.w3.org/TR/n-triples/
SERD_NQUADS = 3, ///< Line-based quads http://www.w3.org/TR/n-quads/
SERD_TRIG = 4 ///< Terse quads http://www.w3.org/TR/trig/
} SerdSyntax;
/// Flags indicating inline abbreviation information for a statement
typedef enum {
SERD_EMPTY_S = 1u << 1u, ///< Empty blank node subject
SERD_EMPTY_O = 1u << 2u, ///< Empty blank node object
SERD_ANON_S_BEGIN = 1u << 3u, ///< Start of anonymous subject
SERD_ANON_O_BEGIN = 1u << 4u, ///< Start of anonymous object
SERD_ANON_CONT = 1u << 5u, ///< Continuation of anonymous node
SERD_LIST_S_BEGIN = 1u << 6u, ///< Start of list subject
SERD_LIST_O_BEGIN = 1u << 7u, ///< Start of list object
SERD_LIST_CONT = 1u << 8u ///< Continuation of list
SERD_EMPTY_S = 1u << 1u, ///< Empty blank node subject
SERD_EMPTY_O = 1u << 2u, ///< Empty blank node object
SERD_ANON_S_BEGIN = 1u << 3u, ///< Start of anonymous subject
SERD_ANON_O_BEGIN = 1u << 4u, ///< Start of anonymous object
SERD_ANON_CONT = 1u << 5u, ///< Continuation of anonymous node
SERD_LIST_S_BEGIN = 1u << 6u, ///< Start of list subject
SERD_LIST_O_BEGIN = 1u << 7u, ///< Start of list object
SERD_LIST_CONT = 1u << 8u ///< Continuation of list
} SerdStatementFlag;
/// Bitwise OR of SerdStatementFlag values
@ -139,52 +144,52 @@ typedef uint32_t SerdStatementFlags; @@ -139,52 +144,52 @@ typedef uint32_t SerdStatementFlags;
node types.
*/
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 [RFC3986](http://tools.ietf.org/html/rfc3986)
*/
SERD_URI = 2,
/**
CURIE, a shortened URI.
Value is an unquoted CURIE string relative to the current environment,
e.g. "rdf:type". @see [CURIE Syntax 1.0](http://www.w3.org/TR/curie)
*/
SERD_CURIE = 3,
/**
A blank node.
Value is a blank node ID without any syntactic prefix, like "id3", which
is meaningful only within this serialisation. @see [RDF 1.1
Turtle](http://www.w3.org/TR/turtle/#grammar-production-BLANK_NODE_LABEL)
*/
SERD_BLANK = 4
/**
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 [RFC3986](http://tools.ietf.org/html/rfc3986)
*/
SERD_URI = 2,
/**
CURIE, a shortened URI.
Value is an unquoted CURIE string relative to the current environment,
e.g. "rdf:type". @see [CURIE Syntax 1.0](http://www.w3.org/TR/curie)
*/
SERD_CURIE = 3,
/**
A blank node.
Value is a blank node ID without any syntactic prefix, like "id3", which
is meaningful only within this serialisation. @see [RDF 1.1
Turtle](http://www.w3.org/TR/turtle/#grammar-production-BLANK_NODE_LABEL)
*/
SERD_BLANK = 4
} SerdType;
/// Flags indicating certain string properties relevant to serialisation
typedef enum {
SERD_HAS_NEWLINE = 1u << 0u, ///< Contains line breaks ('\\n' or '\\r')
SERD_HAS_QUOTE = 1u << 1u ///< Contains quotes ('"')
SERD_HAS_NEWLINE = 1u << 0u, ///< Contains line breaks ('\\n' or '\\r')
SERD_HAS_QUOTE = 1u << 1u ///< Contains quotes ('"')
} SerdNodeFlag;
/// Bitwise OR of SerdNodeFlag values
@ -192,27 +197,27 @@ typedef uint32_t SerdNodeFlags; @@ -192,27 +197,27 @@ typedef uint32_t SerdNodeFlags;
/// A syntactic RDF node
typedef struct {
const uint8_t* SERD_NULLABLE buf; ///< Value string
size_t n_bytes; ///< Size in bytes (excluding null)
size_t n_chars; ///< String length (excluding null)
SerdNodeFlags flags; ///< Node flags (string properties)
SerdType type; ///< Node type
const uint8_t* SERD_NULLABLE buf; ///< Value string
size_t n_bytes; ///< Size in bytes (excluding null)
size_t n_chars; ///< String length (excluding null)
SerdNodeFlags flags; ///< Node flags (string properties)
SerdType type; ///< Node type
} SerdNode;
/// An unterminated string fragment
typedef struct {
const uint8_t* SERD_NULLABLE buf; ///< Start of chunk
size_t len; ///< Length of chunk in bytes
const uint8_t* SERD_NULLABLE 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* SERD_NULLABLE filename; ///< File with error
unsigned line; ///< Line in file with error or 0
unsigned col; ///< Column in file with error
const char* SERD_NONNULL fmt; ///< Printf-style format string
va_list* SERD_NONNULL args; ///< Arguments for fmt
SerdStatus status; ///< Error code
const uint8_t* SERD_NULLABLE filename; ///< File with error
unsigned line; ///< Line in file with error or 0
unsigned col; ///< Column in file with error
const char* SERD_NONNULL fmt; ///< Printf-style format string
va_list* SERD_NONNULL args; ///< Arguments for fmt
} SerdError;
/**
@ -223,12 +228,12 @@ typedef struct { @@ -223,12 +228,12 @@ typedef struct {
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
SerdChunk scheme; ///< Scheme
SerdChunk authority; ///< Authority
SerdChunk path_base; ///< Path prefix if relative
SerdChunk path; ///< Path suffix
SerdChunk query; ///< Query
SerdChunk fragment; ///< Fragment
} SerdURI;
/**
@ -239,11 +244,11 @@ typedef struct { @@ -239,11 +244,11 @@ typedef struct {
does not support abbreviation and is always ASCII.
*/
typedef enum {
SERD_STYLE_ABBREVIATED = 1u << 0u, ///< Abbreviate triples when possible.
SERD_STYLE_ASCII = 1u << 1u, ///< Escape all non-ASCII characters.
SERD_STYLE_RESOLVED = 1u << 2u, ///< Resolve URIs against base URI.
SERD_STYLE_CURIED = 1u << 3u, ///< Shorten URIs into CURIEs.
SERD_STYLE_BULK = 1u << 4u, ///< Write output in pages.
SERD_STYLE_ABBREVIATED = 1u << 0u, ///< Abbreviate triples when possible.
SERD_STYLE_ASCII = 1u << 1u, ///< Escape all non-ASCII characters.
SERD_STYLE_RESOLVED = 1u << 2u, ///< Resolve URIs against base URI.
SERD_STYLE_CURIED = 1u << 3u, ///< Shorten URIs into CURIEs.
SERD_STYLE_BULK = 1u << 4u, ///< Write output in pages.
} SerdStyle;
/**
@ -353,9 +358,8 @@ typedef size_t (*SerdSink)(const void* SERD_NONNULL buf, @@ -353,9 +358,8 @@ typedef size_t (*SerdSink)(const void* SERD_NONNULL buf,
@{
*/
static const SerdURI SERD_URI_NULL = {
{NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}
};
static const SerdURI SERD_URI_NULL =
{{NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}};
/**
Return the local path for `uri`, or NULL if `uri` is not a file URI.
@ -364,7 +368,8 @@ static const SerdURI SERD_URI_NULL = { @@ -364,7 +368,8 @@ static const SerdURI SERD_URI_NULL = {
encoding and other issues are not handled, to properly convert a file URI to
a path, use serd_file_uri_parse().
*/
SERD_API SERD_DEPRECATED_BY("serd_file_uri_parse")
SERD_API
SERD_DEPRECATED_BY("serd_file_uri_parse")
const uint8_t* SERD_NULLABLE
serd_uri_to_path(const uint8_t* SERD_NONNULL uri);
@ -431,7 +436,7 @@ serd_uri_serialise_relative(const SerdURI* SERD_NONNULL uri, @@ -431,7 +436,7 @@ serd_uri_serialise_relative(const SerdURI* SERD_NONNULL uri,
@{
*/
static const SerdNode SERD_NODE_NULL = { NULL, 0, 0, 0, SERD_NOTHING };
static const SerdNode SERD_NODE_NULL = {NULL, 0, 0, 0, SERD_NOTHING};
/**
Make a (shallow) node from `str`.
@ -450,16 +455,16 @@ serd_node_from_string(SerdType type, const uint8_t* SERD_NULLABLE str); @@ -450,16 +455,16 @@ serd_node_from_string(SerdType type, const uint8_t* SERD_NULLABLE str);
*/
SERD_API
SerdNode
serd_node_from_substring(SerdType type,
serd_node_from_substring(SerdType type,
const uint8_t* SERD_NULLABLE str,
size_t len);
size_t len);
/// Simple wrapper for serd_node_new_uri() to resolve a URI node
SERD_API
SerdNode
serd_node_new_uri_from_node(const SerdNode* SERD_NONNULL uri_node,
const SerdURI* SERD_NULLABLE base,
SerdURI* SERD_NULLABLE out);
const SerdURI* SERD_NULLABLE base,
SerdURI* SERD_NULLABLE out);
/// Simple wrapper for serd_node_new_uri() to resolve a URI string
SERD_API
@ -621,14 +626,14 @@ typedef SerdStatus (*SerdPrefixSink)(void* SERD_NULLABLE handle, @@ -621,14 +626,14 @@ typedef SerdStatus (*SerdPrefixSink)(void* SERD_NULLABLE handle,
Called for every RDF statement in the serialisation.
*/
typedef SerdStatus (*SerdStatementSink)(
void* SERD_NULLABLE handle,
SerdStatementFlags flags,
const SerdNode* SERD_NULLABLE graph,
const SerdNode* SERD_NONNULL subject,
const SerdNode* SERD_NONNULL predicate,
const SerdNode* SERD_NONNULL object,
const SerdNode* SERD_NULLABLE object_datatype,
const SerdNode* SERD_NULLABLE object_lang);
void* SERD_NULLABLE handle,
SerdStatementFlags flags,
const SerdNode* SERD_NULLABLE graph,
const SerdNode* SERD_NONNULL subject,
const SerdNode* SERD_NONNULL predicate,
const SerdNode* SERD_NONNULL object,
const SerdNode* SERD_NULLABLE object_datatype,
const SerdNode* SERD_NULLABLE object_lang);
/**
Sink (callback) for anonymous node end markers
@ -1041,10 +1046,10 @@ serd_writer_finish(SerdWriter* SERD_NONNULL writer); @@ -1041,10 +1046,10 @@ serd_writer_finish(SerdWriter* SERD_NONNULL writer);
*/
#ifdef __cplusplus
# if defined(__GNUC__)
# pragma GCC diagnostic pop
# endif
} /* extern "C" */
# if defined(__GNUC__)
# pragma GCC diagnostic pop
# endif
} /* extern "C" */
#endif
#endif /* SERD_SERD_H */
#endif /* SERD_SERD_H */

4
src/attributes.h

@ -18,9 +18,9 @@ @@ -18,9 +18,9 @@
#define SERD_ATTRIBUTES_H
#ifdef __GNUC__
# define SERD_MALLOC_FUNC __attribute__((malloc))
# define SERD_MALLOC_FUNC __attribute__((malloc))
#else
# define SERD_MALLOC_FUNC
# define SERD_MALLOC_FUNC
#endif
#endif // SERD_ATTRIBUTES_H

94
src/base64.c

@ -32,7 +32,7 @@ @@ -32,7 +32,7 @@
@see <a href="http://tools.ietf.org/html/rfc3548#section-3">RFC3548 S3</a>.
*/
static const uint8_t b64_map[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/**
Base64 decoding table.
@ -42,27 +42,28 @@ static const uint8_t b64_map[] = @@ -42,27 +42,28 @@ static const uint8_t b64_map[] =
A '$' is a placeholder for characters not in the base64 alphabet.
*/
static const char b64_unmap[] =
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$m$$$ncdefghijkl$$$$$$"
"$/0123456789:;<=>?@ABCDEFGH$$$$$$IJKLMNOPQRSTUVWXYZ[\\]^_`ab$$$$"
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$";
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$m$$$ncdefghijkl$$$$$$"
"$/0123456789:;<=>?@ABCDEFGH$$$$$$IJKLMNOPQRSTUVWXYZ[\\]^_`ab$$$$"
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"
"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$";
/** Encode 3 raw bytes to 4 base64 characters. */
static inline void
encode_chunk(uint8_t out[4], const uint8_t in[3], size_t n_in)
{
out[0] = b64_map[in[0] >> 2];
out[1] = b64_map[((in[0] & 0x03) << 4) | ((in[1] & 0xF0) >> 4)];
out[2] = ((n_in > 1)
? (b64_map[((in[1] & 0x0F) << 2) | ((in[2] & 0xC0) >> 6)])
: (uint8_t)'=');
out[3] = ((n_in > 2) ? b64_map[in[2] & 0x3F] : (uint8_t)'=');
out[0] = b64_map[in[0] >> 2];
out[1] = b64_map[((in[0] & 0x03) << 4) | ((in[1] & 0xF0) >> 4)];
out[2] = (n_in > 1) ? (b64_map[((in[1] & 0x0F) << 2) | ((in[2] & 0xC0) >> 6)])
: (uint8_t)'=';
out[3] = ((n_in > 2) ? b64_map[in[2] & 0x3F] : (uint8_t)'=');
}
size_t
serd_base64_get_length(const size_t size, const bool wrap_lines)
{
return (size + 2) / 3 * 4 + (wrap_lines * ((size - 1) / 57));
return (size + 2) / 3 * 4 + (wrap_lines * ((size - 1) / 57));
}
bool
@ -71,54 +72,61 @@ serd_base64_encode(uint8_t* const str, @@ -71,54 +72,61 @@ serd_base64_encode(uint8_t* const str,
const size_t size,
const bool wrap_lines)
{
bool has_newline = false;
for (size_t i = 0, j = 0; i < size; i += 3, j += 4) {
uint8_t in[4] = { 0, 0, 0, 0 };
size_t n_in = MIN(3, size - i);
memcpy(in, (const uint8_t*)buf + i, n_in);
bool has_newline = false;
for (size_t i = 0, j = 0; i < size; i += 3, j += 4) {
uint8_t in[4] = {0, 0, 0, 0};
size_t n_in = MIN(3, size - i);
memcpy(in, (const uint8_t*)buf + i, n_in);
if (wrap_lines && i > 0 && (i % 57) == 0) {
str[j++] = '\n';
has_newline = true;
}
if (wrap_lines && i > 0 && (i % 57) == 0) {
str[j++] = '\n';
has_newline = true;
}
encode_chunk(str + j, in, n_in);
}
encode_chunk(str + j, in, n_in);
}
return has_newline;
return has_newline;
}
static inline uint8_t
unmap(const uint8_t in)
{
return (uint8_t)(b64_unmap[in] - 47);
return (uint8_t)(b64_unmap[in] - 47);
}
/** Decode 4 base64 characters to 3 raw bytes. */
static inline size_t
decode_chunk(const uint8_t in[4], uint8_t out[3])
{
out[0] = (uint8_t)(((unmap(in[0]) << 2)) | unmap(in[1]) >> 4);
out[1] = (uint8_t)(((unmap(in[1]) << 4) & 0xF0) | unmap(in[2]) >> 2);
out[2] = (uint8_t)(((unmap(in[2]) << 6) & 0xC0) | unmap(in[3]));
return 1 + (in[2] != '=') + ((in[2] != '=') && (in[3] != '='));
out[0] = (uint8_t)(((unmap(in[0]) << 2)) | unmap(in[1]) >> 4);
out[1] = (uint8_t)(((unmap(in[1]) << 4) & 0xF0) | unmap(in[2]) >> 2);
out[2] = (uint8_t)(((unmap(in[2]) << 6) & 0xC0) | unmap(in[3]));
return 1 + (in[2] != '=') + ((in[2] != '=') && (in[3] != '='));
}
void*
serd_base64_decode(const uint8_t* str, size_t len, size_t* size)
{
void* buf = malloc((len * 3) / 4 + 2);
*size = 0;
for (size_t i = 0, j = 0; i < len; j += 3) {
uint8_t in[] = "====";
size_t n_in = 0;
for (; i < len && n_in < 4; ++n_in) {
for (; i < len && !is_base64(str[i]); ++i) {} // Skip junk
in[n_in] = str[i++];
}
if (n_in > 1) {
*size += decode_chunk(in, (uint8_t*)buf + j);
}
}
return buf;
void* buf = malloc((len * 3) / 4 + 2);
*size = 0;
for (size_t i = 0, j = 0; i < len; j += 3) {
uint8_t in[] = "====";
size_t n_in = 0;
for (; i < len && n_in < 4; ++n_in) {
for (; i < len && !is_base64(str[i]); ++i) {
// Skip junk
}
in[n_in] = str[i++];
}
if (n_in > 1) {
*size += decode_chunk(in, (uint8_t*)buf + j);
}
}
return buf;
}

2
src/base64.h

@ -45,4 +45,4 @@ serd_base64_get_length(size_t size, bool wrap_lines); @@ -45,4 +45,4 @@ serd_base64_get_length(size_t size, bool wrap_lines);
bool
serd_base64_encode(uint8_t* str, const void* buf, size_t size, bool wrap_lines);
#endif // SERD_BASE64_H
#endif // SERD_BASE64_H

95
src/byte_sink.h

@ -27,73 +27,72 @@ @@ -27,73 +27,72 @@
#include <string.h>
typedef struct SerdByteSinkImpl {
SerdSink sink;
void* stream;
uint8_t* buf;
size_t size;
size_t block_size;
SerdSink sink;
void* stream;
uint8_t* buf;
size_t size;
size_t block_size;
} SerdByteSink;
static inline SerdByteSink
serd_byte_sink_new(SerdSink sink, void* stream, size_t block_size)
{
SerdByteSink bsink;
bsink.sink = sink;
bsink.stream = stream;
bsink.size = 0;
bsink.block_size = block_size;
bsink.buf = ((block_size > 1)
? (uint8_t*)serd_allocate_buffer(block_size)
: NULL);
return bsink;
SerdByteSink bsink = {sink, stream, NULL, 0, block_size};
if (block_size > 1) {
bsink.buf = (uint8_t*)serd_allocate_buffer(block_size);
}
return bsink;
}
static inline void
serd_byte_sink_flush(SerdByteSink* bsink)
{
if (bsink->block_size > 1 && bsink->size > 0) {
bsink->sink(bsink->buf, bsink->size, bsink->stream);
bsink->size = 0;
}
if (bsink->block_size > 1 && bsink->size > 0) {
bsink->sink(bsink->buf, bsink->size, bsink->stream);
bsink->size = 0;
}
}
static inline void
serd_byte_sink_free(SerdByteSink* bsink)
{
serd_byte_sink_flush(bsink);
serd_free_aligned(bsink->buf);
bsink->buf = NULL;
serd_byte_sink_flush(bsink);
serd_free_aligned(bsink->buf);
bsink->buf = NULL;
}
static inline size_t
serd_byte_sink_write(const void* buf, size_t len, SerdByteSink* bsink)
{
if (len == 0) {
return 0;
}
if (bsink->block_size == 1) {
return bsink->sink(buf, len, bsink->stream);
}
const size_t orig_len = len;
while (len) {
const size_t space = bsink->block_size - bsink->size;
const size_t n = MIN(space, len);
// Write as much as possible into the remaining buffer space
memcpy(bsink->buf + bsink->size, buf, n);
bsink->size += n;
buf = (const uint8_t*)buf + n;
len -= n;
// Flush page if buffer is full
if (bsink->size == bsink->block_size) {
bsink->sink(bsink->buf, bsink->block_size, bsink->stream);
bsink->size = 0;
}
}
return orig_len;
if (len == 0) {
return 0;
}
if (bsink->block_size == 1) {
return bsink->sink(buf, len, bsink->stream);
}
const size_t orig_len = len;
while (len) {
const size_t space = bsink->block_size - bsink->size;
const size_t n = MIN(space, len);
// Write as much as possible into the remaining buffer space
memcpy(bsink->buf + bsink->size, buf, n);
bsink->size += n;
buf = (const uint8_t*)buf + n;
len -= n;
// Flush page if buffer is full
if (bsink->size == bsink->block_size) {
bsink->sink(bsink->buf, bsink->block_size, bsink->stream);
bsink->size = 0;
}
}
return orig_len;
}
#endif // SERD_BYTE_SINK_H
#endif // SERD_BYTE_SINK_H

107
src/byte_source.c

@ -27,23 +27,23 @@ @@ -27,23 +27,23 @@
SerdStatus
serd_byte_source_page(SerdByteSource* source)
{
source->read_head = 0;
const size_t n_read = source->read_func(
source->file_buf, 1, source->page_size, source->stream);
if (n_read == 0) {
source->file_buf[0] = '\0';
source->eof = true;
return (source->error_func(source->stream)
? SERD_ERR_UNKNOWN : SERD_FAILURE);
}
if (n_read < source->page_size) {
source->file_buf[n_read] = '\0';
source->buf_size = n_read;
}
return SERD_SUCCESS;
source->read_head = 0;
const size_t n_read =
source->read_func(source->file_buf, 1, source->page_size, source->stream);
if (n_read == 0) {
source->file_buf[0] = '\0';
source->eof = true;
return (source->error_func(source->stream) ? SERD_ERR_UNKNOWN
: SERD_FAILURE);
}
if (n_read < source->page_size) {
source->file_buf[n_read] = '\0';
source->buf_size = n_read;
}
return SERD_SUCCESS;
}
SerdStatus
@ -54,58 +54,59 @@ serd_byte_source_open_source(SerdByteSource* source, @@ -54,58 +54,59 @@ serd_byte_source_open_source(SerdByteSource* source,
const uint8_t* name,
size_t page_size)
{
const Cursor cur = { name, 1, 1 };
memset(source, '\0', sizeof(*source));
source->stream = stream;
source->from_stream = true;
source->page_size = page_size;
source->buf_size = page_size;
source->cur = cur;
source->error_func = error_func;
source->read_func = read_func;
if (page_size > 1) {
source->file_buf = (uint8_t*)serd_allocate_buffer(page_size);
source->read_buf = source->file_buf;
memset(source->file_buf, '\0', page_size);
} else {
source->read_buf = &source->read_byte;
}
return SERD_SUCCESS;
const Cursor cur = {name, 1, 1};
memset(source, '\0', sizeof(*source));
source->stream = stream;
source->from_stream = true;
source->page_size = page_size;
source->buf_size = page_size;
source->cur = cur;
source->error_func = error_func;
source->read_func = read_func;
if (page_size > 1) {
source->file_buf = (uint8_t*)serd_allocate_buffer(page_size);
source->read_buf = source->file_buf;
memset(source->file_buf, '\0', page_size);
} else {
source->read_buf = &source->read_byte;
}
return SERD_SUCCESS;
}
SerdStatus
serd_byte_source_prepare(SerdByteSource* source)
{
source->prepared = true;
source->prepared = true;
if (source->from_stream) {
return (source->page_size > 1 ? serd_byte_source_page(source)
: serd_byte_source_advance(source));
}
if (source->from_stream) {
return (source->page_size > 1 ? serd_byte_source_page(source)
: serd_byte_source_advance(source));
}
return SERD_SUCCESS;
return SERD_SUCCESS;
}
SerdStatus
serd_byte_source_open_string(SerdByteSource* source, const uint8_t* utf8)
{
const Cursor cur = { (const uint8_t*)"(string)", 1, 1 };
const Cursor cur = {(const uint8_t*)"(string)", 1, 1};
memset(source, '\0', sizeof(*source));
source->cur = cur;
source->read_buf = utf8;
return SERD_SUCCESS;
memset(source, '\0', sizeof(*source));
source->cur = cur;
source->read_buf = utf8;
return SERD_SUCCESS;
}
SerdStatus
serd_byte_source_close(SerdByteSource* source)
{
if (source->page_size > 1) {
serd_free_aligned(source->file_buf);
}
memset(source, '\0', sizeof(*source));
return SERD_SUCCESS;
if (source->page_size > 1) {
serd_free_aligned(source->file_buf);
}
memset(source, '\0', sizeof(*source));
return SERD_SUCCESS;
}

108
src/byte_source.h

@ -26,31 +26,29 @@ @@ -26,31 +26,29 @@
#include <stdio.h>
typedef struct {
const uint8_t* filename;
unsigned line;
unsigned col;
const uint8_t* filename;
unsigned line;
unsigned col;
} Cursor;
typedef struct {
SerdSource read_func; ///< Read function (e.g. fread)
SerdStreamErrorFunc error_func; ///< Error function (e.g. ferror)
void* stream; ///< Stream (e.g. FILE)
size_t page_size; ///< Number of bytes to read at a time
size_t buf_size; ///< Number of bytes in file_buf
Cursor cur; ///< Cursor for error reporting
uint8_t* file_buf; ///< Buffer iff reading pages from a file
const uint8_t* read_buf; ///< Pointer to file_buf or read_byte
size_t read_head; ///< Offset into read_buf
uint8_t read_byte; ///< 1-byte 'buffer' used when not paging
bool from_stream; ///< True iff reading from `stream`
bool prepared; ///< True iff prepared for reading
bool eof; ///< True iff end of file reached
SerdSource read_func; ///< Read function (e.g. fread)
SerdStreamErrorFunc error_func; ///< Error function (e.g. ferror)
void* stream; ///< Stream (e.g. FILE)
size_t page_size; ///< Number of bytes to read at a time
size_t buf_size; ///< Number of bytes in file_buf
Cursor cur; ///< Cursor for error reporting
uint8_t* file_buf; ///< Buffer iff reading pages from a file
const uint8_t* read_buf; ///< Pointer to file_buf or read_byte
size_t read_head; ///< Offset into read_buf
uint8_t read_byte; ///< 1-byte 'buffer' used when not paging
bool from_stream; ///< True iff reading from `stream`
bool prepared; ///< True iff prepared for reading
bool eof; ///< True iff end of file reached
} SerdByteSource;
SerdStatus
serd_byte_source_open_file(SerdByteSource* source,
FILE* file,
bool bulk);
serd_byte_source_open_file(SerdByteSource* source, FILE* file, bool bulk);
SerdStatus
serd_byte_source_open_string(SerdByteSource* source, const uint8_t* utf8);
@ -75,44 +73,48 @@ serd_byte_source_page(SerdByteSource* source); @@ -75,44 +73,48 @@ serd_byte_source_page(SerdByteSource* source);
static inline uint8_t
serd_byte_source_peek(SerdByteSource* source)
{
assert(source->prepared);
return source->read_buf[source->read_head];
assert(source->prepared);
return source->read_buf[source->read_head];
}
static inline SerdStatus
serd_byte_source_advance(SerdByteSource* source)
{
SerdStatus st = SERD_SUCCESS;
switch (serd_byte_source_peek(source)) {
case '\n': ++source->cur.line; source->cur.col = 0; break;
default: ++source->cur.col;
}
const bool was_eof = source->eof;
if (source->from_stream) {
source->eof = false;
if (source->page_size > 1) {
if (++source->read_head == source->page_size) {
st = serd_byte_source_page(source);
} else if (source->read_head == source->buf_size) {
source->eof = true;
}
} else {
if (!source->read_func(&source->read_byte, 1, 1, source->stream)) {
source->eof = true;
st = source->error_func(source->stream) ? SERD_ERR_UNKNOWN
: SERD_FAILURE;
}
}
} else if (!source->eof) {
++source->read_head; // Move to next character in string
if (source->read_buf[source->read_head] == '\0') {
source->eof = true;
}
}
return (was_eof && source->eof) ? SERD_FAILURE : st;
SerdStatus st = SERD_SUCCESS;
switch (serd_byte_source_peek(source)) {
case '\n':
++source->cur.line;
source->cur.col = 0;
break;
default:
++source->cur.col;
}
const bool was_eof = source->eof;
if (source->from_stream) {
source->eof = false;
if (source->page_size > 1) {
if (++source->read_head == source->page_size) {
st = serd_byte_source_page(source);
} else if (source->read_head == source->buf_size) {
source->eof = true;
}
} else {
if (!source->read_func(&source->read_byte, 1, 1, source->stream)) {
source->eof = true;
st =
source->error_func(source->stream) ? SERD_ERR_UNKNOWN : SERD_FAILURE;
}
}
} else if (!source->eof) {
++source->read_head; // Move to next character in string
if (source->read_buf[source->read_head] == '\0') {
source->eof = true;
}
}
return (was_eof && source->eof) ? SERD_FAILURE : st;
}
#endif // SERD_BYTE_SOURCE_H
#endif // SERD_BYTE_SOURCE_H

333
src/env.c

@ -23,141 +23,137 @@ @@ -23,141 +23,137 @@
#include <string.h>
typedef struct {
SerdNode name;
SerdNode uri;
SerdNode name;
SerdNode uri;
} SerdPrefix;
struct SerdEnvImpl {
SerdPrefix* prefixes;
size_t n_prefixes;
SerdNode base_uri_node;
SerdURI base_uri;
SerdPrefix* prefixes;
size_t n_prefixes;
SerdNode base_uri_node;
SerdURI base_uri;
};
SerdEnv*
serd_env_new(const SerdNode* base_uri)
{
SerdEnv* env = (SerdEnv*)calloc(1, sizeof(struct SerdEnvImpl));
if (env && base_uri) {
serd_env_set_base_uri(env, base_uri);
}
return env;
SerdEnv* env = (SerdEnv*)calloc(1, sizeof(struct SerdEnvImpl));
if (env && base_uri) {
serd_env_set_base_uri(env, base_uri);
}
return env;
}
void
serd_env_free(SerdEnv* env)
{
if (!env) {
return;
}
for (size_t i = 0; i < env->n_prefixes; ++i) {
serd_node_free(&env->prefixes[i].name);
serd_node_free(&env->prefixes[i].uri);
}
free(env->prefixes);
serd_node_free(&env->base_uri_node);
free(env);
if (!env) {
return;
}
for (size_t i = 0; i < env->n_prefixes; ++i) {
serd_node_free(&env->prefixes[i].name);
serd_node_free(&env->prefixes[i].uri);
}
free(env->prefixes);
serd_node_free(&env->base_uri_node);
free(env);
}
const SerdNode*
serd_env_get_base_uri(const SerdEnv* env,
SerdURI* out)
serd_env_get_base_uri(const SerdEnv* env, SerdURI* out)
{
if (out) {
*out = env->base_uri;
}
return &env->base_uri_node;
if (out) {
*out = env->base_uri;
}
return &env->base_uri_node;
}
SerdStatus
serd_env_set_base_uri(SerdEnv* env,
const SerdNode* uri)
serd_env_set_base_uri(SerdEnv* env, const SerdNode* uri)
{
if (!env || (uri && uri->type != SERD_URI)) {
return SERD_ERR_BAD_ARG;
}
if (!uri || !uri->buf) {
serd_node_free(&env->base_uri_node);
env->base_uri_node = SERD_NODE_NULL;
env->base_uri = SERD_URI_NULL;
return SERD_SUCCESS;
}
// Resolve base URI and create a new node and URI for it
SerdURI base_uri;
SerdNode base_uri_node = serd_node_new_uri_from_node(
uri, &env->base_uri, &base_uri);
// Replace the current base URI
serd_node_free(&env->base_uri_node);
env->base_uri_node = base_uri_node;
env->base_uri = base_uri;
return SERD_SUCCESS;
if (!env || (uri && uri->type != SERD_URI)) {
return SERD_ERR_BAD_ARG;
}
if (!uri || !uri->buf) {
serd_node_free(&env->base_uri_node);
env->base_uri_node = SERD_NODE_NULL;
env->base_uri = SERD_URI_NULL;
return SERD_SUCCESS;
}
// Resolve base URI and create a new node and URI for it
SerdURI base_uri;
SerdNode base_uri_node =
serd_node_new_uri_from_node(uri, &env->base_uri, &base_uri);
// Replace the current base URI
serd_node_free(&env->base_uri_node);
env->base_uri_node = base_uri_node;
env->base_uri = base_uri;
return SERD_SUCCESS;
}
static inline SERD_PURE_FUNC SerdPrefix*
serd_env_find(const SerdEnv* env,
const uint8_t* name,
size_t name_len)
serd_env_find(const SerdEnv* env, const uint8_t* name, size_t name_len)
{
for (size_t i = 0; i < env->n_prefixes; ++i) {
const SerdNode* const prefix_name = &env->prefixes[i].name;
if (prefix_name->n_bytes == name_len) {
if (!memcmp(prefix_name->buf, name, name_len)) {
return &env->prefixes[i];
}
}
}
return NULL;
for (size_t i = 0; i < env->n_prefixes; ++i) {
const SerdNode* const prefix_name = &env->prefixes[i].name;
if (prefix_name->n_bytes == name_len) {
if (!memcmp(prefix_name->buf, name, name_len)) {
return &env->prefixes[i];
}
}
}
return NULL;
}
static void
serd_env_add(SerdEnv* env,
const SerdNode* name,
const SerdNode* uri)
serd_env_add(SerdEnv* env, const SerdNode* name, const SerdNode* uri)
{
SerdPrefix* const prefix = serd_env_find(env, name->buf, name->n_bytes);
if (prefix) {
if (!serd_node_equals(&prefix->uri, uri)) {
SerdNode old_prefix_uri = prefix->uri;
prefix->uri = serd_node_copy(uri);
serd_node_free(&old_prefix_uri);
}
} else {
env->prefixes = (SerdPrefix*)realloc(
env->prefixes, (++env->n_prefixes) * sizeof(SerdPrefix));
env->prefixes[env->n_prefixes - 1].name = serd_node_copy(name);
env->prefixes[env->n_prefixes - 1].uri = serd_node_copy(uri);
}
SerdPrefix* const prefix = serd_env_find(env, name->buf, name->n_bytes);
if (prefix) {
if (!serd_node_equals(&prefix->uri, uri)) {
SerdNode old_prefix_uri = prefix->uri;
prefix->uri = serd_node_copy(uri);
serd_node_free(&old_prefix_uri);
}
} else {
env->prefixes = (SerdPrefix*)realloc(
env->prefixes, (++env->n_prefixes) * sizeof(SerdPrefix));
env->prefixes[env->n_prefixes - 1].name = serd_node_copy(name);
env->prefixes[env->n_prefixes - 1].uri = serd_node_copy(uri);
}
}
SerdStatus
serd_env_set_prefix(SerdEnv* env,
const SerdNode* name,
const SerdNode* uri)
serd_env_set_prefix(SerdEnv* env, const SerdNode* name, const SerdNode* uri)
{
if (!name->buf || uri->type != SERD_URI) {
return SERD_ERR_BAD_ARG;
}
if (serd_uri_string_has_scheme(uri->buf)) {
// Set prefix to absolute URI
serd_env_add(env, name, uri);
} else {
// Resolve relative URI and create a new node and URI for it
SerdURI abs_uri;
SerdNode abs_uri_node = serd_node_new_uri_from_node(
uri, &env->base_uri, &abs_uri);
// Set prefix to resolved (absolute) URI
serd_env_add(env, name, &abs_uri_node);
serd_node_free(&abs_uri_node);
}
return SERD_SUCCESS;
if (!name->buf || uri->type != SERD_URI) {
return SERD_ERR_BAD_ARG;
}
if (serd_uri_string_has_scheme(uri->buf)) {
// Set prefix to absolute URI
serd_env_add(env, name, uri);
} else {
// Resolve relative URI and create a new node and URI for it
SerdURI abs_uri;
SerdNode abs_uri_node =
serd_node_new_uri_from_node(uri, &env->base_uri, &abs_uri);
// Set prefix to resolved (absolute) URI
serd_env_add(env, name, &abs_uri_node);
serd_node_free(&abs_uri_node);
}
return SERD_SUCCESS;
}
SerdStatus
@ -165,10 +161,10 @@ serd_env_set_prefix_from_strings(SerdEnv* env, @@ -165,10 +161,10 @@ serd_env_set_prefix_from_strings(SerdEnv* env,
const uint8_t* name,
const uint8_t* uri)
{
const SerdNode name_node = serd_node_from_string(SERD_LITERAL, name);
const SerdNode uri_node = serd_node_from_string(SERD_URI, uri);
const SerdNode name_node = serd_node_from_string(SERD_LITERAL, name);
const SerdNode uri_node = serd_node_from_string(SERD_URI, uri);
return serd_env_set_prefix(env, &name_node, &uri_node);
return serd_env_set_prefix(env, &name_node, &uri_node);
}
bool
@ -177,20 +173,20 @@ serd_env_qualify(const SerdEnv* env, @@ -177,20 +173,20 @@ serd_env_qualify(const SerdEnv* env,
SerdNode* prefix,
SerdChunk* suffix)
{
for (size_t i = 0; i < env->n_prefixes; ++i) {
const SerdNode* const prefix_uri = &env->prefixes[i].uri;
if (uri->n_bytes >= prefix_uri->n_bytes) {
if (!strncmp((const char*)uri->buf,
(const char*)prefix_uri->buf,
prefix_uri->n_bytes)) {
*prefix = env->prefixes[i].name;
suffix->buf = uri->buf + prefix_uri->n_bytes;
suffix->len = uri->n_bytes - prefix_uri->n_bytes;
return true;
}
}
}
return false;
for (size_t i = 0; i < env->n_prefixes; ++i) {
const SerdNode* const prefix_uri = &env->prefixes[i].uri;
if (uri->n_bytes >= prefix_uri->n_bytes) {
if (!strncmp((const char*)uri->buf,
(const char*)prefix_uri->buf,
prefix_uri->n_bytes)) {
*prefix = env->prefixes[i].name;
suffix->buf = uri->buf + prefix_uri->n_bytes;
suffix->len = uri->n_bytes - prefix_uri->n_bytes;
return true;
}
}
}
return false;
}
SerdStatus
@ -199,61 +195,62 @@ serd_env_expand(const SerdEnv* env, @@ -199,61 +195,62 @@ serd_env_expand(const SerdEnv* env,
SerdChunk* uri_prefix,
SerdChunk* uri_suffix)
{
const uint8_t* const colon = (const uint8_t*)memchr(
curie->buf, ':', curie->n_bytes + 1);
if (curie->type != SERD_CURIE || !colon) {
return SERD_ERR_BAD_ARG;
}
const size_t name_len = (size_t)(colon - curie->buf);
const SerdPrefix* const prefix = serd_env_find(env, curie->buf, name_len);
if (prefix) {
uri_prefix->buf = prefix->uri.buf;
uri_prefix->len = prefix->uri.n_bytes;
uri_suffix->buf = colon + 1;
uri_suffix->len = curie->n_bytes - name_len - 1;
return SERD_SUCCESS;
}
return SERD_ERR_BAD_CURIE;
const uint8_t* const colon =
(const uint8_t*)memchr(curie->buf, ':', curie->n_bytes + 1);
if (curie->type != SERD_CURIE || !colon) {
return SERD_ERR_BAD_ARG;
}
const size_t name_len = (size_t)(colon - curie->buf);
const SerdPrefix* const prefix = serd_env_find(env, curie->buf, name_len);
if (prefix) {
uri_prefix->buf = prefix->uri.buf;
uri_prefix->len = prefix->uri.n_bytes;
uri_suffix->buf = colon + 1;
uri_suffix->len = curie->n_bytes - name_len - 1;
return SERD_SUCCESS;
}
return SERD_ERR_BAD_CURIE;
}
SerdNode
serd_env_expand_node(const SerdEnv* env,
const SerdNode* node)
serd_env_expand_node(const SerdEnv* env, const SerdNode* node)
{
switch (node->type) {
case SERD_NOTHING:
case SERD_LITERAL:
break;
case SERD_URI: {
SerdURI ignored;
return serd_node_new_uri_from_node(node, &env->base_uri, &ignored);
}
case SERD_CURIE: {
SerdChunk prefix;
SerdChunk suffix;
if (serd_env_expand(env, node, &prefix, &suffix)) {
return SERD_NODE_NULL;
}
const size_t len = prefix.len + suffix.len;
uint8_t* buf = (uint8_t*)malloc(len + 1);
SerdNode ret = { buf, len, 0, 0, SERD_URI };
snprintf((char*)buf, len + 1, "%s%s", prefix.buf, suffix.buf);
ret.n_chars = serd_strlen(buf, NULL, NULL);
return ret;
}
case SERD_BLANK:
break;
}
return SERD_NODE_NULL;
switch (node->type) {
case SERD_NOTHING:
case SERD_LITERAL:
break;
case SERD_URI: {
SerdURI ignored;
return serd_node_new_uri_from_node(node, &env->base_uri, &ignored);
}
case SERD_CURIE: {
SerdChunk prefix;
SerdChunk suffix;
if (serd_env_expand(env, node, &prefix, &suffix)) {
return SERD_NODE_NULL;
}
const size_t len = prefix.len + suffix.len;
uint8_t* buf = (uint8_t*)malloc(len + 1);
SerdNode ret = {buf, len, 0, 0, SERD_URI};
snprintf((char*)buf, len + 1, "%s%s", prefix.buf, suffix.buf);
ret.n_chars = serd_strlen(buf, NULL, NULL);
return ret;
}
case SERD_BLANK:
break;
}