From: Joel Rosdahl Date: Fri, 7 Jul 2023 09:17:43 +0000 (+0200) Subject: refactor: Improve format_base16/format_base32hex implementations X-Git-Tag: v4.9~149 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=677b6e66de3b29165aeb808f09399b719478d1f1;p=thirdparty%2Fccache.git refactor: Improve format_base16/format_base32hex implementations --- diff --git a/src/storage/remote/RedisStorage.cpp b/src/storage/remote/RedisStorage.cpp index 34a57484b..2422bb0b8 100644 --- a/src/storage/remote/RedisStorage.cpp +++ b/src/storage/remote/RedisStorage.cpp @@ -22,11 +22,14 @@ #include #include #include +#include // for timeval #include #include #include -#include +#ifdef HAVE_SYS_UTIME_H +# include // for timeval +#endif // Ignore "ISO C++ forbids flexible array member ‘buf’" warning from -Wpedantic. #ifdef __GNUC__ diff --git a/src/third_party/CMakeLists.txt b/src/third_party/CMakeLists.txt index 0d6ffb3e2..549f51e46 100644 --- a/src/third_party/CMakeLists.txt +++ b/src/third_party/CMakeLists.txt @@ -1,4 +1,4 @@ -add_library(third_party STATIC base32hex.c format.cpp httplib.cpp url.cpp xxhash.c) +add_library(third_party STATIC format.cpp httplib.cpp url.cpp xxhash.c) if(NOT MSVC) target_sources(third_party PRIVATE getopt_long.c) else() diff --git a/src/third_party/base32hex.c b/src/third_party/base32hex.c deleted file mode 100644 index 4c2275d03..000000000 --- a/src/third_party/base32hex.c +++ /dev/null @@ -1,79 +0,0 @@ -/* (C) 2012 Peter Conrad - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "base32hex.h" - -#define to_32hex(c) ((c) < 10 ? (c) + '0' : (c) + 'a' - 10) - -/* out must point to a buffer of at least (len * 8 / 5) + 1 bytes. - * Encoded string is *not* padded. - * See RFC-4648. This implementation produces lowercase hex characters. - * Returns length of encoded string. - */ -unsigned int base32hex(char *out, const uint8_t *in, unsigned int len) { -unsigned int buf = 0, bits = 0; -char *x = out; - - while (len-- > 0) { - buf <<= 8; - buf |= *in++; - bits += 8; - while (bits >= 5) { - char c = (buf >> (bits - 5)) & 0x1f; - *x++ = to_32hex(c); - bits -= 5; - } - } - if (bits > 0) { - char c = (buf << (5 - bits)) & 0x1f; - *x++ = to_32hex(c); - } - return x - out; -} - -#ifdef TEST -#include -#include -#include - -static void test(char *in, char *expected, int explen) { -char buf[255]; -int r; - - if ((r = base32hex(buf, in, strlen(in))) != explen) { - printf("Failed: b32h('%s') yields %d chars (expected %d)\n", - in, r, explen); - exit(1); - } - if (strncmp(buf, expected, r)) { - buf[r] = 0; - printf("Failed: b32h('%s') = '%s' (expected %s)\n", - in, buf, expected); - exit(1); - } -} - -int main(int argc, char **argv) { - test("", "", 0); - test("f", "co", 2); - test("fo", "cpng", 4); - test("foo", "cpnmu", 5); - test("foob", "cpnmuog", 7); - test("fooba", "cpnmuoj1", 8); - test("foobar", "cpnmuoj1e8", 10); - printf("Success!\n"); -} - -#endif diff --git a/src/third_party/base32hex.h b/src/third_party/base32hex.h deleted file mode 100644 index 838671973..000000000 --- a/src/third_party/base32hex.h +++ /dev/null @@ -1,23 +0,0 @@ -/* (C) 2012 Peter Conrad - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef BASE32_HEX_H -#define BASE32_HEX_H - -#include - -extern unsigned int base32hex(char *out, const uint8_t *in, unsigned int len); - -#endif diff --git a/src/util/string.cpp b/src/util/string.cpp index 1f90934d4..3fe7d2e49 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -21,10 +21,6 @@ #include #include -extern "C" { -#include -} - #include #include #include @@ -36,10 +32,10 @@ format_base16(nonstd::span data) { static const char digits[] = "0123456789abcdef"; std::string result; - result.resize(2 * data.size()); - for (size_t i = 0; i < data.size(); ++i) { - result[i * 2] = digits[data[i] >> 4]; - result[i * 2 + 1] = digits[data[i] & 0xF]; + result.reserve(2 * data.size()); + for (uint8_t b : data) { + result += digits[b >> 4]; + result += digits[b & 0xF]; } return result; } @@ -47,10 +43,24 @@ format_base16(nonstd::span data) std::string format_base32hex(nonstd::span data) { - const size_t bytes_to_reserve = data.size() * 8 / 5 + 1; - std::string result(bytes_to_reserve, 0); - const size_t actual_size = base32hex(&result[0], data.data(), data.size()); - result.resize(actual_size); + static const char digits[] = "0123456789abcdefghijklmnopqrstuv"; + std::string result; + result.reserve(data.size() * 8 / 5 + 1); + uint8_t i = 0; + uint16_t bits = 0; + for (uint8_t b : data) { + bits <<= 8; + bits |= b; + i += 8; + while (i >= 5) { + result += digits[(bits >> (i - 5)) & 0x1f]; + i -= 5; + } + } + if (i > 0) { + DEBUG_ASSERT(i < 5); + result += digits[(bits << (5 - i)) & 0x1f]; + } return result; }