/** * SPDX-License-Identifier: GPL-2.0-or-later * * This file is part of osm2pgsql (https://osm2pgsql.org/). * * Copyright (C) 2006-2026 by the osm2pgsql developer community. * For a full list of authors see the git log. */ #include "hex.hpp" #include #include #include namespace util { void encode_hex(std::string const &input, std::string *output) { assert(output); constexpr char const *const LOOKUP_HEX = "0123456789ABCDEF"; for (auto const c : input) { unsigned int const num = static_cast(c); (*output) += LOOKUP_HEX[(num >> 4U) & 0xfU]; (*output) += LOOKUP_HEX[num & 0xfU]; } } std::string encode_hex(std::string const &input) { std::string result; result.reserve(input.size() * 2); encode_hex(input, &result); return result; } namespace { constexpr std::array HEX_TABLE = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; } // anonymous namespace unsigned char decode_hex_char(char c) noexcept { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index) return HEX_TABLE[static_cast(static_cast(c))]; } std::string decode_hex(std::string_view hex_string) { if (hex_string.size() % 2 != 0) { throw std::runtime_error{"Invalid wkb: Not a valid hex string"}; } std::string wkb; wkb.reserve(hex_string.size() / 2); // NOLINTNEXTLINE(llvm-qualified-auto, readability-qualified-auto) for (auto hex = hex_string.cbegin(); hex != hex_string.cend();) { unsigned int const c = decode_hex_char(*hex++); wkb += static_cast((c << 4U) | decode_hex_char(*hex++)); } return wkb; } } // namespace util