-// Copyright (C) 2020-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2020-2023 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
#pragma once
-#include "Util.hpp"
+#include <util/string.hpp>
#include "third_party/fmt/core.h"
// allow for up to four uniform cache levels. The rest are encoded as
// lowercase base32hex digits without padding characters.
const size_t base16_bytes = 2;
- return Util::format_base16(m_bytes, base16_bytes)
- + Util::format_base32hex(m_bytes + base16_bytes,
- size() - base16_bytes);
+ return util::format_base16({m_bytes, base16_bytes})
+ + util::format_base32hex(
+ {m_bytes + base16_bytes, size() - base16_bytes});
}
inline bool
-// Copyright (C) 2020-2022 Joel Rosdahl and other contributors
+// Copyright (C) 2020-2023 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
#include <core/wincompat.hpp>
#include <util/file.hpp>
+#include <util/string.hpp>
#include <fcntl.h>
#include <sys/stat.h>
switch (hash_type) {
case HashType::binary:
add_debug_text(
- Util::format_base16(static_cast<const uint8_t*>(data), size));
+ util::format_base16({static_cast<const uint8_t*>(data), size}));
break;
case HashType::text:
#include <limits.h> // NOLINT: PATH_MAX is defined in limits.h
-extern "C" {
-#include "third_party/base32hex.h"
-}
-
#ifdef HAVE_DIRENT_H
# include <dirent.h>
#endif
return result;
}
-std::string
-format_base16(const uint8_t* data, size_t size)
-{
- static const char digits[] = "0123456789abcdef";
- std::string result;
- result.resize(2 * size);
- for (size_t i = 0; i < size; ++i) {
- result[i * 2] = digits[data[i] >> 4];
- result[i * 2 + 1] = digits[data[i] & 0xF];
- }
- return result;
-}
-
-std::string
-format_base32hex(const uint8_t* data, size_t size)
-{
- const size_t bytes_to_reserve = size * 8 / 5 + 1;
- std::string result(bytes_to_reserve, 0);
- const size_t actual_size = base32hex(&result[0], data, size);
- result.resize(actual_size);
- return result;
-}
-
void
ensure_dir_exists(std::string_view dir)
{
// not intended to be machine parsable. `argv` must be terminated by a nullptr.
std::string format_argv_for_logging(const char* const* argv);
-// Format a hexadecimal string representing `size` bytes of `data`. The returned
-// string will be `2 * size` long.
-std::string format_base16(const uint8_t* data, size_t size);
-
-// Format a lowercase base32hex string representing `size` bytes of `data`. No
-// padding characters will be added.
-std::string format_base32hex(const uint8_t* data, size_t size);
-
// Return current working directory (CWD) as returned from getcwd(3) (i.e.,
// normalized path without symlink parts). Returns the empty string on error.
std::string get_actual_cwd();
const auto actual = checksum.digest();
if (actual != m_checksum) {
- throw core::Error(
- FMT("Incorrect checksum (actual {}, expected {})",
- Util::format_base16(actual.data(), actual.size()),
- Util::format_base16(m_checksum.data(), m_checksum.size())));
+ throw core::Error(FMT("Incorrect checksum (actual {}, expected {})",
+ util::format_base16(actual),
+ util::format_base16(m_checksum)));
}
}
checksum.update({data, size});
});
const auto digest = checksum.digest();
- PRINT(
- stdout, "{}\n", Util::format_base16(digest.data(), digest.size()));
+ PRINT(stdout, "{}\n", util::format_base16(digest));
} else {
PRINT(stderr, "Error: Failed to checksum {}\n", arg);
}
// Mimic hex representation of a SHA256 hash value.
const auto sha256_hex_size = 64;
static_assert(Digest::size() == 20, "Update below if digest size changes");
- std::string hex_digits = Util::format_base16(key.bytes(), key.size());
+ std::string hex_digits = util::format_base16({key.bytes(), key.size()});
hex_digits.append(hex_digits.data(), sha256_hex_size - hex_digits.size());
LOG("Translated key {} to Bazel layout ac/{}", key.to_string(), hex_digits);
return FMT("{}ac/{}", m_url_path, hex_digits);
#include <util/expected.hpp>
#include <util/string.hpp>
+#include <sys/time.h>
+
// Ignore "ISO C++ forbids flexible array member ‘buf’" warning from -Wpedantic.
#ifdef __GNUC__
# pragma GCC diagnostic push
#include <assertions.hpp>
#include <fmtmacros.hpp>
+extern "C" {
+#include <third_party/base32hex.h>
+}
+
#include <algorithm>
#include <cctype>
#include <iostream>
namespace util {
+std::string
+format_base16(nonstd::span<const uint8_t> 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];
+ }
+ return result;
+}
+
+std::string
+format_base32hex(nonstd::span<const uint8_t> 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);
+ return result;
+}
+
std::string
format_human_readable_diff(int64_t diff, SizeUnitPrefixType prefix_type)
{
// Return true if `suffix` is a suffix of `string`.
bool ends_with(std::string_view string, std::string_view suffix);
+// Format a hexadecimal string representing `data`. The returned string will be
+// `2 * data.size()` long.
+std::string format_base16(nonstd::span<const uint8_t> data);
+
+// Format a lowercase base32hex string representing `data`. No padding
+// characters will be added.
+std::string format_base32hex(nonstd::span<const uint8_t> data);
+
// Format `diff` as a human-readable string.
std::string format_human_readable_diff(int64_t diff,
SizeUnitPrefixType prefix_type);
CHECK(Util::format_argv_for_logging(argv_2) == "foo bar");
}
-TEST_CASE("Util::format_base16")
-{
- uint8_t none[] = "";
- uint8_t text[4] = "foo"; // incl. NUL
- uint8_t data[4] = {0, 1, 2, 3};
-
- CHECK(Util::format_base16(none, 0) == "");
- CHECK(Util::format_base16(text, sizeof(text)) == "666f6f00");
- CHECK(Util::format_base16(data, sizeof(data)) == "00010203");
-}
-
-TEST_CASE("Util::format_base32hex")
-{
- // Test vectors (without padding) from RFC 4648.
- const uint8_t input[] = {'f', 'o', 'o', 'b', 'a', 'r'};
- CHECK(Util::format_base32hex(input, 0) == "");
- CHECK(Util::format_base32hex(input, 1) == "co");
- CHECK(Util::format_base32hex(input, 2) == "cpng");
- CHECK(Util::format_base32hex(input, 3) == "cpnmu");
- CHECK(Util::format_base32hex(input, 4) == "cpnmuog");
- CHECK(Util::format_base32hex(input, 5) == "cpnmuoj1");
- CHECK(Util::format_base32hex(input, 6) == "cpnmuoj1e8");
-}
-
TEST_CASE("Util::get_extension")
{
CHECK(Util::get_extension("") == "");
-// Copyright (C) 2011-2022 Joel Rosdahl and other contributors
+// Copyright (C) 2011-2023 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
{
util::XXH3_128 checksum;
auto digest = checksum.digest();
- CHECK(Util::format_base16(digest.data(), 16)
+ CHECK(util::format_base16({digest.data(), 16})
== "99aa06d3014798d86001c324468d497f");
checksum.update(util::to_span("foo"));
digest = checksum.digest();
- CHECK(Util::format_base16(digest.data(), 16)
+ CHECK(util::format_base16({digest.data(), 16})
== "79aef92e83454121ab6e5f64077e7d8a");
checksum.update(util::to_span("t"));
digest = checksum.digest();
- CHECK(Util::format_base16(digest.data(), 16)
+ CHECK(util::format_base16({digest.data(), 16})
== "e6045075b5bf1ae7a3e4c87775e6c97f");
checksum.reset();
digest = checksum.digest();
- CHECK(Util::format_base16(digest.data(), 16)
+ CHECK(util::format_base16({digest.data(), 16})
== "99aa06d3014798d86001c324468d497f");
}
TEST_SUITE_BEGIN("util");
+TEST_CASE("util::format_base16")
+{
+ uint8_t none[] = "";
+ uint8_t text[4] = "foo"; // incl. NUL
+ uint8_t data[4] = {0, 1, 2, 3};
+
+ CHECK(util::format_base16({none, 0}) == "");
+ CHECK(util::format_base16({text, sizeof(text)}) == "666f6f00");
+ CHECK(util::format_base16({data, sizeof(data)}) == "00010203");
+}
+
+TEST_CASE("util::format_base32hex")
+{
+ // Test vectors (without padding) from RFC 4648.
+ const uint8_t input[] = {'f', 'o', 'o', 'b', 'a', 'r'};
+ CHECK(util::format_base32hex({input, 0}) == "");
+ CHECK(util::format_base32hex({input, 1}) == "co");
+ CHECK(util::format_base32hex({input, 2}) == "cpng");
+ CHECK(util::format_base32hex({input, 3}) == "cpnmu");
+ CHECK(util::format_base32hex({input, 4}) == "cpnmuog");
+ CHECK(util::format_base32hex({input, 5}) == "cpnmuoj1");
+ CHECK(util::format_base32hex({input, 6}) == "cpnmuoj1e8");
+}
+
TEST_CASE("util::ends_with")
{
CHECK(util::ends_with("", ""));