aboutsummaryrefslogtreecommitdiffstats
path: root/src/string.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2017-07-09 14:59:05 +0200
committerDavid Robillard <d@drobilla.net>2017-07-09 14:59:05 +0200
commit4d535bbe0390ed4f03c611e433145c9e49cbf3ad (patch)
tree3ec86327944909c214dabe419ef67c3400fb1aec /src/string.c
parent4270fbbc761e4d36e9fc28a361b7e8d7c21166d2 (diff)
downloadserd-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.c47
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) {