Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 2 additions & 8 deletions src/db-copy-mgr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include <string>

#include "db-copy.hpp"
#include "util.hpp"
#include "hex.hpp"

/**
* Management class that fills and manages copy buffers.
Expand Down Expand Up @@ -237,13 +237,7 @@ class db_copy_mgr_t
*/
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';
}

Expand Down
17 changes: 1 addition & 16 deletions src/gen/canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "canvas.hpp"

#include "hex.hpp"
#include "raster.hpp"
#include "tile.hpp"

Expand Down Expand Up @@ -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;
}
2 changes: 0 additions & 2 deletions src/gen/canvas.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,4 @@ class canvas_t
image_type m_rast;
}; // class canvas_t

std::string to_hex(std::string const &in);

#endif // OSM2PGSQL_CANVAS_HPP
3 changes: 2 additions & 1 deletion src/gen/gen-rivers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "gen-rivers.hpp"

#include "geom-functions.hpp"
#include "hex.hpp"
#include "logging.hpp"
#include "params.hpp"
#include "pgsql.hpp"
Expand Down Expand Up @@ -264,7 +265,7 @@ SELECT "{id_column}", "{width_column}", "{name_column}", "{geom_column}"
if (!name.empty()) {
names.emplace(id, name);
}
auto const geom = ewkb_to_geom(decode_hex(result.get(i, 3)));
auto const geom = ewkb_to_geom(util::decode_hex(result.get(i, 3)));

if (geom.is_linestring()) {
auto const &ls = geom.get<geom::linestring_t>();
Expand Down
7 changes: 4 additions & 3 deletions src/gen/gen-tile-builtup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "canvas.hpp"
#include "geom-functions.hpp"
#include "hex.hpp"
#include "logging.hpp"
#include "params.hpp"
#include "pgsql.hpp"
Expand All @@ -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 ({}, {}, {}, '{}')",
Expand Down Expand Up @@ -61,7 +62,7 @@ void draw_from_db(double margin, canvas_list_t *canvas_list, pg_conn_t *conn,
box.max_x(), box.max_y());

for (int n = 0; n < result.num_tuples(); ++n) {
auto const geom = ewkb_to_geom(decode_hex(result.get(n, 0)));
auto const geom = ewkb_to_geom(util::decode_hex(result.get(n, 0)));
cc.canvas.draw(geom, tile);
}
}
Expand Down Expand Up @@ -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));
Expand Down
5 changes: 3 additions & 2 deletions src/gen/gen-tile-raster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "gen-tile-raster.hpp"

#include "canvas.hpp"
#include "hex.hpp"
#include "logging.hpp"
#include "params.hpp"
#include "pgsql.hpp"
Expand Down Expand Up @@ -49,7 +50,7 @@ void draw_from_db(double margin, unsigned int image_extent,

for (int n = 0; n < result.num_tuples(); ++n) {
std::string param = result.get_value(n, 1);
auto const geom = ewkb_to_geom(decode_hex(result.get(n, 0)));
auto const geom = ewkb_to_geom(util::decode_hex(result.get(n, 0)));

auto const [it, success] = canvas_list->try_emplace(
std::move(param), image_extent, image_buffer);
Expand All @@ -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 ('{}', {}, {}, {}, '{}')",
Expand Down
78 changes: 78 additions & 0 deletions src/hex.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* 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 <array>
#include <cassert>
#include <stdexcept>

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 {

constexpr std::array<char, 256> const 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<std::size_t>(static_cast<unsigned char>(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.begin(); hex != hex_string.end();) {
unsigned int const c = decode_hex_char(*hex++);
wkb += static_cast<char>((c << 4U) | decode_hex_char(*hex++));
}

return wkb;
}

} // namespace util
47 changes: 47 additions & 0 deletions src/hex.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#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.
*/
[[nodiscard]] std::string encode_hex(std::string const &in);

/**
* Decode one hex character (0-9A-F or 0-9a-f) and return its value.
* Returns 0 for characters that are not hex characters.
*/
[[nodiscard]] unsigned char decode_hex_char(char c) noexcept;

/**
* Decode a string of hex characters. Throws an exception if the input is not
* a valid hex encoding.
*/
[[nodiscard]] std::string decode_hex(std::string_view hex);

} // namespace util

#endif // OSM2PGSQL_HEX_HPP
3 changes: 2 additions & 1 deletion src/locator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "geom-boost-adaptor.hpp"
#include "geom-box.hpp"
#include "geom-functions.hpp"
#include "hex.hpp"
#include "overloaded.hpp"
#include "pgsql-capabilities.hpp"
#include "pgsql.hpp"
Expand Down Expand Up @@ -60,7 +61,7 @@ void locator_t::add_regions(pg_conn_t const &db_connection,

for (int n = 0; n < result.num_tuples(); ++n) {
std::string const name = result.get_value(n, 0);
auto geometry = ewkb_to_geom(decode_hex(result.get(n, 1)));
auto geometry = ewkb_to_geom(util::decode_hex(result.get(n, 1)));

if (geometry.srid() == 4326) {
add_region(name, geometry);
Expand Down
39 changes: 0 additions & 39 deletions src/wkb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,42 +575,3 @@ geom::geometry_t ewkb_to_geom(std::string_view wkb)

return geom;
}

namespace {

constexpr std::array<char, 256> const 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<std::size_t>(static_cast<unsigned char>(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.begin(); hex != hex_string.end();) {
unsigned int const c = decode_hex_char(*hex++);
wkb += static_cast<char>((c << 4U) | decode_hex_char(*hex++));
}

return wkb;
}
12 changes: 0 additions & 12 deletions src/wkb.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,4 @@
*/
[[nodiscard]] geom::geometry_t ewkb_to_geom(std::string_view wkb);

/**
* Decode one hex character (0-9A-F or 0-9a-f) and return its value.
* Returns 0 for characters that are not hex characters.
*/
[[nodiscard]] unsigned char decode_hex_char(char c) noexcept;

/**
* Decode a string of hex characters. Throws an exception if the input is not
* a valid hex encoding.
*/
[[nodiscard]] std::string decode_hex(std::string_view hex);

#endif // OSM2PGSQL_WKB_HPP
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading