Consolidate hex encoding functions into their own file

Consolidate multiple functions doing basically the same hex encoding
and add some tests.
This commit is contained in:
Jochen Topf
2025-06-01 21:55:41 +02:00
parent 771baaa45b
commit 993bc74c24
10 changed files with 119 additions and 29 deletions

View File

@ -32,6 +32,7 @@ target_sources(osm2pgsql_lib PRIVATE
geom-functions.cpp
geom-pole-of-inaccessibility.cpp
geom.cpp
hex.cpp
idlist.cpp
input.cpp
locator.cpp

View File

@ -15,7 +15,7 @@
#include <string>
#include "db-copy.hpp"
#include "util.hpp"
#include "hex.hpp"
/**
* Management class that fills and manages copy buffers.
@ -237,13 +237,7 @@ public:
*/
void add_hex_geom(std::string const &wkb)
{
char const *const lookup_hex = "0123456789ABCDEF";
for (auto c : wkb) {
unsigned int const num = static_cast<unsigned char>(c);
m_current.buffer += lookup_hex[(num >> 4U) & 0xfU];
m_current.buffer += lookup_hex[num & 0xfU];
}
util::encode_hex(wkb, &m_current.buffer);
m_current.buffer += '\t';
}

View File

@ -9,6 +9,7 @@
#include "canvas.hpp"
#include "hex.hpp"
#include "raster.hpp"
#include "tile.hpp"
@ -139,19 +140,3 @@ void canvas_t::merge(canvas_t const &other)
{
cv::bitwise_or(m_rast, other.m_rast, m_rast);
}
std::string to_hex(std::string const &in)
{
std::string result;
result.reserve(in.size() * 2);
char const *const lookup_hex = "0123456789ABCDEF";
for (const auto c : in) {
unsigned int const num = static_cast<unsigned char>(c);
result += lookup_hex[(num >> 4U) & 0xfU];
result += lookup_hex[num & 0xfU];
}
return result;
}

View File

@ -77,6 +77,4 @@ private:
image_type m_rast;
}; // class canvas_t
std::string to_hex(std::string const &in);
#endif // OSM2PGSQL_CANVAS_HPP

View File

@ -11,6 +11,7 @@
#include "canvas.hpp"
#include "geom-functions.hpp"
#include "hex.hpp"
#include "logging.hpp"
#include "params.hpp"
#include "pgsql.hpp"
@ -33,7 +34,7 @@ void save_image_to_table(pg_conn_t *connection, canvas_t const &canvas,
std::string const &table, char const *variant,
std::string const &table_prefix)
{
auto const wkb = to_hex(canvas.to_wkb(tile, margin));
auto const wkb = util::encode_hex(canvas.to_wkb(tile, margin));
connection->exec("INSERT INTO \"{}_{}_{}\" (zoom, x, y, rast)"
" VALUES ({}, {}, {}, '{}')",
@ -251,7 +252,7 @@ void gen_tile_builtup_t::process(tile_t const &tile)
log_gen("Write geometries to destination table...");
timer(m_timer_write).start();
for (auto const &geom : geometries) {
auto const wkb = to_hex(geom_to_ewkb(geom));
auto const wkb = util::encode_hex(geom_to_ewkb(geom));
if (m_has_area_column) {
connection().exec_prepared("insert_geoms", wkb, tile.x(), tile.y(),
geom::area(geom));

View File

@ -10,6 +10,7 @@
#include "gen-tile-raster.hpp"
#include "canvas.hpp"
#include "hex.hpp"
#include "logging.hpp"
#include "params.hpp"
#include "pgsql.hpp"
@ -63,7 +64,7 @@ void save_image_to_table(pg_conn_t *connection, canvas_t const &canvas,
std::string const &param, char const *variant,
std::string const &table_prefix)
{
auto const wkb = to_hex(canvas.to_wkb(tile, margin));
auto const wkb = util::encode_hex(canvas.to_wkb(tile, margin));
connection->exec("INSERT INTO \"{}_{}\" (type, zoom, x, y, rast)"
" VALUES ('{}', {}, {}, {}, '{}')",

37
src/hex.cpp Normal file
View File

@ -0,0 +1,37 @@
/**
* SPDX-License-Identifier: GPL-2.0-or-later
*
* This file is part of osm2pgsql (https://osm2pgsql.org/).
*
* Copyright (C) 2006-2025 by the osm2pgsql developer community.
* For a full list of authors see the git log.
*/
#include "hex.hpp"
#include <cassert>
namespace util {
void encode_hex(std::string const &in, std::string *out)
{
assert(out);
constexpr char const *const LOOKUP_HEX = "0123456789ABCDEF";
for (auto const c : in) {
unsigned int const num = static_cast<unsigned char>(c);
(*out) += LOOKUP_HEX[(num >> 4U) & 0xfU];
(*out) += LOOKUP_HEX[num & 0xfU];
}
}
std::string encode_hex(std::string const &in)
{
std::string result;
result.reserve(in.size() * 2);
encode_hex(in, &result);
return result;
}
} // namespace util

35
src/hex.hpp Normal file
View File

@ -0,0 +1,35 @@
#ifndef OSM2PGSQL_HEX_HPP
#define OSM2PGSQL_HEX_HPP
/**
* SPDX-License-Identifier: GPL-2.0-or-later
*
* This file is part of osm2pgsql (https://osm2pgsql.org/).
*
* Copyright (C) 2006-2025 by the osm2pgsql developer community.
* For a full list of authors see the git log.
*/
#include <string>
namespace util {
/**
* Convert content of input string to hex and append to output.
*
* \param in The input data.
* \param out Pointer to output string.
*/
void encode_hex(std::string const &in, std::string *out);
/**
* Convert content of input string to hex and return it.
*
* \param in The input data.
* \returns Hex encoded string.
*/
std::string encode_hex(std::string const &in);
} // namespace util
#endif // OSM2PGSQL_HEX_HPP

View File

@ -57,6 +57,7 @@ set_test(test-geom-points LABELS NoDB)
set_test(test-geom-pole-of-inaccessibility LABELS NoDB)
set_test(test-geom-polygons LABELS NoDB)
set_test(test-geom-transform LABELS NoDB)
set_test(test-hex LABELS NoDB)
set_test(test-json-writer LABELS NoDB)
set_test(test-locator LABELS NoDB)
set_test(test-lua-utils LABELS NoDB)

37
tests/test-hex.cpp Normal file
View File

@ -0,0 +1,37 @@
/**
* SPDX-License-Identifier: GPL-2.0-or-later
*
* This file is part of osm2pgsql (https://osm2pgsql.org/).
*
* Copyright (C) 2006-2025 by the osm2pgsql developer community.
* For a full list of authors see the git log.
*/
#include <catch.hpp>
#include "hex.hpp"
#include <string>
TEST_CASE("hex encode a string", "[NoDB]")
{
std::string result;
util::encode_hex("ab~", &result);
REQUIRE(result.size() == 6);
REQUIRE(result == "61627E");
}
TEST_CASE("hex encode a string adding to existing string", "[NoDB]")
{
std::string result{"0x"};
util::encode_hex("\xca\xfe", &result);
REQUIRE(result.size() == 6);
REQUIRE(result == "0xCAFE");
}
TEST_CASE("hex encoding an empty string doesn't change output string", "[NoDB]")
{
std::string result{"foo"};
util::encode_hex("", &result);
REQUIRE(result == "foo");
}