diff options
author | David Robillard <d@drobilla.net> | 2017-07-09 14:59:05 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2017-07-09 14:59:05 +0200 |
commit | 4d535bbe0390ed4f03c611e433145c9e49cbf3ad (patch) | |
tree | 3ec86327944909c214dabe419ef67c3400fb1aec /src/string.c | |
parent | 4270fbbc761e4d36e9fc28a361b7e8d7c21166d2 (diff) | |
download | serd-4d535bbe0390ed4f03c611e433145c9e49cbf3ad.tar.gz serd-4d535bbe0390ed4f03c611e433145c9e49cbf3ad.tar.bz2 serd-4d535bbe0390ed4f03c611e433145c9e49cbf3ad.zip |
Add serd_node_from_substring()
This allows creating nodes in-place from substrings of other strings to allow
zero-copy serialization from existing delimited buffers.
Diffstat (limited to 'src/string.c')
-rw-r--r-- | src/string.c | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/src/string.c b/src/string.c index 9381015d..dedd0713 100644 --- a/src/string.c +++ b/src/string.c @@ -36,6 +36,42 @@ serd_strerror(SerdStatus status) return (const uint8_t*)"Unknown error"; // never reached } +static inline void +serd_update_flags(const uint8_t c, SerdNodeFlags* const flags) +{ + switch (c) { + case '\r': case '\n': + *flags |= SERD_HAS_NEWLINE; + break; + case '"': + *flags |= SERD_HAS_QUOTE; + } +} + +size_t +serd_substrlen(const uint8_t* const str, + const size_t len, + size_t* const n_bytes, + SerdNodeFlags* const flags) +{ + size_t n_chars = 0; + size_t i = 0; + SerdNodeFlags f = 0; + for (; i < len && str[i]; ++i) { + if ((str[i] & 0xC0) != 0x80) { // Start of new character + ++n_chars; + serd_update_flags(str[i], &f); + } + } + if (n_bytes) { + *n_bytes = i; + } + if (flags) { + *flags = f; + } + return n_chars; +} + SERD_API size_t serd_strlen(const uint8_t* str, size_t* n_bytes, SerdNodeFlags* flags) @@ -44,16 +80,9 @@ serd_strlen(const uint8_t* str, size_t* n_bytes, SerdNodeFlags* flags) size_t i = 0; SerdNodeFlags f = 0; for (; str[i]; ++i) { - if ((str[i] & 0xC0) != 0x80) { - // Does not start with `10', start of a new character + if ((str[i] & 0xC0) != 0x80) { // Start of new character ++n_chars; - switch (str[i]) { - case '\r': case '\n': - f |= SERD_HAS_NEWLINE; - break; - case '"': - f |= SERD_HAS_QUOTE; - } + serd_update_flags(str[i], &f); } } if (n_bytes) { |