diff options
author | David Robillard <d@drobilla.net> | 2011-01-23 20:18:20 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2011-01-23 20:18:20 +0000 |
commit | 0993d312cb18131de8aa5a73eda65305f8f7899b (patch) | |
tree | b3f15437587d5e4414318bda832a3f37b81c33f4 /src/uri.c | |
parent | 2c45a0e0d3e89946726c76f0e68b12048fb48785 (diff) | |
download | serd-0993d312cb18131de8aa5a73eda65305f8f7899b.tar.gz serd-0993d312cb18131de8aa5a73eda65305f8f7899b.tar.bz2 serd-0993d312cb18131de8aa5a73eda65305f8f7899b.zip |
Faster serd_uri_serialise.
git-svn-id: http://svn.drobilla.net/serd/trunk@50 490d8e77-9747-427b-9fa3-0b8f29cee8a0
Diffstat (limited to 'src/uri.c')
-rw-r--r-- | src/uri.c | 51 |
1 files changed, 32 insertions, 19 deletions
@@ -269,27 +269,40 @@ serd_uri_serialise(const SerdURI* uri, SerdSink sink, void* stream) /* Merge paths, removing dot components. See http://tools.ietf.org/html/rfc3986#section-5.2.3 */ - const uint8_t* uri_first = uri->path.buf; - const uint8_t* uri_end = uri_first; + const uint8_t* begin = uri->path.buf; + const uint8_t* end = begin; size_t up = 1; - if (uri_first) { + if (begin) { // Count and skip leading dot components - uri_end = uri->path.buf + uri->path.len; - while (uri_first < uri_end) { - if (!memcmp((const char*)uri_first, "./", 2)) { - uri_first += 2; - } else if (!memcmp((const char*)uri_first, "../", 3)) { - ++up; - uri_first += 3; - } else if (!memcmp((const char*)uri_first, "..", 2)) { - ++up; - uri_first += 2; - } else if (!memcmp((const char*)uri_first, ".", 1)) { - ++uri_first; - } else if (!memcmp((const char*)uri_first, "//", 1)) { - ++uri_first; - } else { + end = uri->path.buf + uri->path.len; + for (bool done = false; !done && (begin < end);) { + switch (begin[0]) { + case '.': + switch (begin[1]) { + case '/': + begin += 2; // Chop leading "./" + break; + case '.': + ++up; + switch (begin[2]) { + case '/': + begin += 3; // Chop lading "../" + break; + default: + begin += 2; // Chop leading ".." + } + break; + default: + ++begin; // Chop leading "." + } break; + case '/': + if (begin[1] == '/') { + ++begin; // Replace leading "//" with "/" + break; + } // else fall through + default: + done = true; // Finished chopping dot components } } @@ -312,7 +325,7 @@ serd_uri_serialise(const SerdURI* uri, SerdSink sink, void* stream) } // Write URI suffix - WRITE(uri_first, uri_end - uri_first); + WRITE(begin, end - begin); } } } else { |