Skip to content

Commit f9873fb

Browse files
authored
Merge pull request #1881 from joto/wkb-string-view
Refactor ewkb parser to use string_views instead of iterators
2 parents 8b9eedc + 4e5c5d3 commit f9873fb

File tree

2 files changed

+22
-24
lines changed

2 files changed

+22
-24
lines changed

src/wkb.cpp

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <cstring>
1818
#include <stdexcept>
1919
#include <string>
20+
#include <string_view>
2021
#include <utility>
2122

2223
namespace ewkb {
@@ -298,26 +299,23 @@ class make_ewkb_visitor
298299
* Empty Multi* geometries and Geometry Collections will return a NULL
299300
* geometry object.
300301
*
301-
* Call next() to get a pointer to the next character that is not part of the
302-
* geometry any more. If this is not the same as the end pointer given to
303-
* the constructor, this means that there is extra data available in the
304-
* input data.
302+
* Call is_done() to check whether the parser read all available data.
305303
*
306304
* Can only parse (E)WKB in native byte order.
307305
*/
308306
class ewkb_parser_t
309307
{
310308
public:
311-
ewkb_parser_t(char const *it, char const *end)
312-
: m_it(it), m_end(end),
313-
m_max_length(static_cast<uint32_t>(end - it) / (sizeof(double) * 2))
309+
ewkb_parser_t(std::string_view input)
310+
: m_data(input),
311+
m_max_length(static_cast<uint32_t>(input.size()) / (sizeof(double) * 2))
314312
{}
315313

316314
geom::geometry_t operator()()
317315
{
318316
geom::geometry_t geom;
319317

320-
if (m_it == m_end) {
318+
if (m_data.empty()) {
321319
return geom;
322320
}
323321

@@ -353,12 +351,12 @@ class ewkb_parser_t
353351
return geom;
354352
}
355353

356-
char const *next() const noexcept { return m_it; }
354+
bool is_done() const noexcept { return m_data.empty(); }
357355

358356
private:
359357
void check_bytes(uint32_t bytes) const
360358
{
361-
if (static_cast<std::size_t>(m_end - m_it) < bytes) {
359+
if (m_data.size() < bytes) {
362360
throw std::runtime_error{"Invalid WKB geometry: Incomplete"};
363361
}
364362
}
@@ -368,8 +366,8 @@ class ewkb_parser_t
368366
check_bytes(sizeof(uint32_t));
369367

370368
uint32_t data = 0;
371-
std::memcpy(&data, m_it, sizeof(uint32_t));
372-
m_it += sizeof(uint32_t);
369+
std::memcpy(&data, m_data.data(), sizeof(uint32_t));
370+
m_data.remove_prefix(sizeof(uint32_t));
373371

374372
return data;
375373
}
@@ -393,7 +391,7 @@ class ewkb_parser_t
393391

394392
uint32_t parse_header(geom::geometry_t *geom = nullptr)
395393
{
396-
if (static_cast<uint8_t>(*m_it++) !=
394+
if (static_cast<uint8_t>(m_data.front()) !=
397395
ewkb::wkb_byte_order_type_t::Endian) {
398396
throw std::runtime_error
399397
{
@@ -407,6 +405,7 @@ class ewkb_parser_t
407405
"osm2pgsql can only process geometries in native byte order."
408406
};
409407
}
408+
m_data.remove_prefix(1);
410409

411410
auto type = parse_uint32();
412411
if (type & ewkb::geometry_type::wkb_srid) {
@@ -429,8 +428,8 @@ class ewkb_parser_t
429428
check_bytes(sizeof(double) * 2);
430429

431430
std::array<double, 2> data{};
432-
std::memcpy(data.data(), m_it, sizeof(double) * 2);
433-
m_it += sizeof(double) * 2;
431+
std::memcpy(data.data(), m_data.data(), sizeof(double) * 2);
432+
m_data.remove_prefix(sizeof(double) * 2);
434433

435434
point->set_x(data[0]);
436435
point->set_y(data[1]);
@@ -543,14 +542,13 @@ class ewkb_parser_t
543542

544543
collection.reserve(num_geoms);
545544
for (uint32_t i = 0; i < num_geoms; ++i) {
546-
ewkb_parser_t parser{m_it, m_end};
545+
ewkb_parser_t parser{m_data};
547546
collection.add_geometry(parser());
548-
m_it = parser.next();
547+
m_data = parser.m_data;
549548
}
550549
}
551550

552-
char const *m_it;
553-
char const *m_end;
551+
std::string_view m_data;
554552
uint32_t m_max_length;
555553

556554
}; // class ewkb_parser_t
@@ -565,13 +563,12 @@ std::string geom_to_ewkb(geom::geometry_t const &geom, bool ensure_multi)
565563
static_cast<uint32_t>(geom.srid()), ensure_multi});
566564
}
567565

568-
geom::geometry_t ewkb_to_geom(std::string const &wkb)
566+
geom::geometry_t ewkb_to_geom(std::string_view wkb)
569567
{
570-
char const *const end = wkb.data() + wkb.size();
571-
ewkb::ewkb_parser_t parser{wkb.data(), end};
568+
ewkb::ewkb_parser_t parser{wkb};
572569
auto geom = parser();
573570

574-
if (parser.next() != end) {
571+
if (!parser.is_done()) {
575572
throw std::runtime_error{"Invalid WKB geometry: Extra data at end"};
576573
}
577574

src/wkb.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "geom.hpp"
1414

1515
#include <string>
16+
#include <string_view>
1617

1718
/**
1819
* \file
@@ -37,7 +38,7 @@
3738
* \param wkb Input EWKB geometry in binary format
3839
* \returns Geometry
3940
*/
40-
[[nodiscard]] geom::geometry_t ewkb_to_geom(std::string const &wkb);
41+
[[nodiscard]] geom::geometry_t ewkb_to_geom(std::string_view wkb);
4142

4243
/**
4344
* Decode one hex character (0-9A-F or 0-9a-f) and return its value. Throw

0 commit comments

Comments
 (0)