Update in-tree libosmium dependency to 2.5.4
The latest releases have some critical fixes, see the changelog: https://github.com/osmcode/libosmium/blob/v2.5.4/CHANGELOG.md Merge commit 'afdf8e7b21fbaf597e91d9d8a7542635e60ee9a1' into use_libosmium_2_5_4
This commit is contained in:
+8
-2
@@ -106,6 +106,7 @@ add_unit_test(basic test_timestamp)
|
||||
add_unit_test(basic test_types_from_string)
|
||||
add_unit_test(basic test_way)
|
||||
|
||||
add_unit_test(buffer test_buffer_basics)
|
||||
add_unit_test(buffer test_buffer_node)
|
||||
add_unit_test(buffer test_buffer_purge)
|
||||
|
||||
@@ -133,9 +134,15 @@ add_unit_test(index test_id_to_location ENABLE_IF ${SPARSEHASH_FOUND})
|
||||
|
||||
add_unit_test(io test_bzip2 ENABLE_IF ${BZIP2_FOUND} LIBS ${BZIP2_LIBRARIES})
|
||||
add_unit_test(io test_file_formats)
|
||||
add_unit_test(io test_reader LIBS "${OSMIUM_XML_LIBRARIES}")
|
||||
add_unit_test(io test_reader LIBS "${OSMIUM_XML_LIBRARIES};${OSMIUM_PBF_LIBRARIES}")
|
||||
add_unit_test(io test_reader_with_mock_decompression ENABLE_IF ${Threads_FOUND} LIBS ${OSMIUM_XML_LIBRARIES})
|
||||
add_unit_test(io test_reader_with_mock_parser ENABLE_IF ${Threads_FOUND} LIBS ${CMAKE_THREAD_LIBS_INIT})
|
||||
add_unit_test(io test_output_utils)
|
||||
add_unit_test(io test_output_iterator ENABLE_IF ${Threads_FOUND} LIBS ${CMAKE_THREAD_LIBS_INIT})
|
||||
add_unit_test(io test_string_table)
|
||||
add_unit_test(io test_writer ENABLE_IF ${Threads_FOUND} LIBS ${OSMIUM_XML_LIBRARIES})
|
||||
add_unit_test(io test_writer_with_mock_compression ENABLE_IF ${Threads_FOUND} LIBS ${OSMIUM_XML_LIBRARIES})
|
||||
add_unit_test(io test_writer_with_mock_encoder ENABLE_IF ${Threads_FOUND} LIBS ${OSMIUM_XML_LIBRARIES})
|
||||
|
||||
add_unit_test(tags test_filter)
|
||||
add_unit_test(tags test_operators)
|
||||
@@ -144,7 +151,6 @@ add_unit_test(tags test_tag_list)
|
||||
add_unit_test(thread test_pool ENABLE_IF ${Threads_FOUND} LIBS ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
add_unit_test(util test_cast_with_assert)
|
||||
add_unit_test(util test_data_file)
|
||||
add_unit_test(util test_delta)
|
||||
add_unit_test(util test_double)
|
||||
add_unit_test(util test_file)
|
||||
|
||||
+3
-3
@@ -88,11 +88,11 @@ set_tests_properties(testdata-overview PROPERTIES
|
||||
#
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
find_package(Ruby 1.9)
|
||||
find_program(RUBY ruby)
|
||||
find_package(Gem COMPONENTS json)
|
||||
find_program(SPATIALITE spatialite)
|
||||
|
||||
if(RUBY_FOUND AND GEM_json_FOUND AND SPATIALITE)
|
||||
if(RUBY AND GEM_json_FOUND AND SPATIALITE)
|
||||
add_executable(testdata-multipolygon testdata-multipolygon.cpp)
|
||||
target_link_libraries(testdata-multipolygon
|
||||
${OSMIUM_XML_LIBRARIES}
|
||||
@@ -102,7 +102,7 @@ if(RUBY_FOUND AND GEM_json_FOUND AND SPATIALITE)
|
||||
add_test(NAME testdata-multipolygon
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-D OSM_TESTDATA=${OSM_TESTDATA}
|
||||
-D RUBY=${RUBY_EXECUTABLE}
|
||||
-D RUBY=${RUBY}
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/run-testdata-multipolygon.cmake)
|
||||
|
||||
set_tests_properties(testdata-multipolygon PROPERTIES LABELS "data;slow")
|
||||
|
||||
+31
-140
@@ -3,6 +3,8 @@
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
|
||||
#include <gdalcpp.hpp>
|
||||
|
||||
#include <osmium/index/map/sparse_mem_array.hpp>
|
||||
|
||||
#include <osmium/area/assembler.hpp>
|
||||
@@ -41,10 +43,9 @@ inline tagmap_type create_map(const osmium::TagList& taglist) {
|
||||
|
||||
class TestHandler : public osmium::handler::Handler {
|
||||
|
||||
OGRDataSource* m_data_source;
|
||||
OGRLayer* m_layer_point;
|
||||
OGRLayer* m_layer_linestring;
|
||||
OGRLayer* m_layer_polygon;
|
||||
gdalcpp::Layer m_layer_point;
|
||||
gdalcpp::Layer m_layer_lines;
|
||||
gdalcpp::Layer m_layer_mpoly;
|
||||
|
||||
osmium::geom::OGRFactory<> m_ogr_factory;
|
||||
osmium::geom::WKTFactory<> m_wkt_factory;
|
||||
@@ -55,84 +56,20 @@ class TestHandler : public osmium::handler::Handler {
|
||||
|
||||
public:
|
||||
|
||||
TestHandler(OGRDataSource* data_source) :
|
||||
m_data_source(data_source),
|
||||
explicit TestHandler(gdalcpp::Dataset& dataset) :
|
||||
m_layer_point(dataset, "points", wkbPoint),
|
||||
m_layer_lines(dataset, "lines", wkbLineString),
|
||||
m_layer_mpoly(dataset, "multipolygons", wkbMultiPolygon),
|
||||
m_out("multipolygon-tests.json") {
|
||||
|
||||
OGRSpatialReference sparef;
|
||||
sparef.SetWellKnownGeogCS("WGS84");
|
||||
m_layer_point.add_field("id", OFTReal, 10);
|
||||
m_layer_point.add_field("type", OFTString, 30);
|
||||
|
||||
/**************/
|
||||
m_layer_lines.add_field("id", OFTReal, 10);
|
||||
m_layer_lines.add_field("type", OFTString, 30);
|
||||
|
||||
m_layer_point = m_data_source->CreateLayer("points", &sparef, wkbPoint, nullptr);
|
||||
if (!m_layer_point) {
|
||||
std::cerr << "Layer creation failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRFieldDefn layer_point_field_id("id", OFTReal);
|
||||
layer_point_field_id.SetWidth(10);
|
||||
|
||||
if (m_layer_point->CreateField(&layer_point_field_id) != OGRERR_NONE) {
|
||||
std::cerr << "Creating id field failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRFieldDefn layer_point_field_type("type", OFTString);
|
||||
layer_point_field_type.SetWidth(30);
|
||||
|
||||
if (m_layer_point->CreateField(&layer_point_field_type) != OGRERR_NONE) {
|
||||
std::cerr << "Creating type field failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**************/
|
||||
|
||||
m_layer_linestring = m_data_source->CreateLayer("lines", &sparef, wkbLineString, nullptr);
|
||||
if (!m_layer_linestring) {
|
||||
std::cerr << "Layer creation failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRFieldDefn layer_linestring_field_id("id", OFTReal);
|
||||
layer_linestring_field_id.SetWidth(10);
|
||||
|
||||
if (m_layer_linestring->CreateField(&layer_linestring_field_id) != OGRERR_NONE) {
|
||||
std::cerr << "Creating id field failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRFieldDefn layer_linestring_field_type("type", OFTString);
|
||||
layer_linestring_field_type.SetWidth(30);
|
||||
|
||||
if (m_layer_linestring->CreateField(&layer_linestring_field_type) != OGRERR_NONE) {
|
||||
std::cerr << "Creating type field failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**************/
|
||||
|
||||
m_layer_polygon = m_data_source->CreateLayer("multipolygons", &sparef, wkbMultiPolygon, nullptr);
|
||||
if (!m_layer_polygon) {
|
||||
std::cerr << "Layer creation failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRFieldDefn layer_polygon_field_id("id", OFTInteger);
|
||||
layer_polygon_field_id.SetWidth(10);
|
||||
|
||||
if (m_layer_polygon->CreateField(&layer_polygon_field_id) != OGRERR_NONE) {
|
||||
std::cerr << "Creating id field failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRFieldDefn layer_polygon_field_from_type("from_type", OFTString);
|
||||
layer_polygon_field_from_type.SetWidth(1);
|
||||
|
||||
if (m_layer_polygon->CreateField(&layer_polygon_field_from_type) != OGRERR_NONE) {
|
||||
std::cerr << "Creating from_type field failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
m_layer_mpoly.add_field("id", OFTReal, 10);
|
||||
m_layer_mpoly.add_field("from_type", OFTString, 1);
|
||||
}
|
||||
|
||||
~TestHandler() {
|
||||
@@ -140,34 +77,18 @@ public:
|
||||
}
|
||||
|
||||
void node(const osmium::Node& node) {
|
||||
OGRFeature* feature = OGRFeature::CreateFeature(m_layer_point->GetLayerDefn());
|
||||
std::unique_ptr<OGRPoint> ogr_point = m_ogr_factory.create_point(node);
|
||||
feature->SetGeometry(ogr_point.get());
|
||||
feature->SetField("id", static_cast<double>(node.id()));
|
||||
feature->SetField("type", node.tags().get_value_by_key("type"));
|
||||
|
||||
if (m_layer_point->CreateFeature(feature) != OGRERR_NONE) {
|
||||
std::cerr << "Failed to create feature.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRFeature::DestroyFeature(feature);
|
||||
gdalcpp::Feature feature(m_layer_point, m_ogr_factory.create_point(node));
|
||||
feature.set_field("id", static_cast<double>(node.id()));
|
||||
feature.set_field("type", node.tags().get_value_by_key("type"));
|
||||
feature.add_to_layer();
|
||||
}
|
||||
|
||||
void way(const osmium::Way& way) {
|
||||
try {
|
||||
std::unique_ptr<OGRLineString> ogr_linestring = m_ogr_factory.create_linestring(way);
|
||||
OGRFeature* feature = OGRFeature::CreateFeature(m_layer_linestring->GetLayerDefn());
|
||||
feature->SetGeometry(ogr_linestring.get());
|
||||
feature->SetField("id", static_cast<double>(way.id()));
|
||||
feature->SetField("type", way.tags().get_value_by_key("type"));
|
||||
|
||||
if (m_layer_linestring->CreateFeature(feature) != OGRERR_NONE) {
|
||||
std::cerr << "Failed to create feature.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRFeature::DestroyFeature(feature);
|
||||
gdalcpp::Feature feature(m_layer_lines, m_ogr_factory.create_linestring(way));
|
||||
feature.set_field("id", static_cast<double>(way.id()));
|
||||
feature.set_field("type", way.tags().get_value_by_key("type"));
|
||||
feature.add_to_layer();
|
||||
} catch (osmium::geometry_error&) {
|
||||
std::cerr << "Ignoring illegal geometry for way " << way.id() << ".\n";
|
||||
}
|
||||
@@ -200,10 +121,8 @@ public:
|
||||
m_out << "INVALID\"\n}";
|
||||
}
|
||||
try {
|
||||
std::unique_ptr<OGRMultiPolygon> ogr_polygon = m_ogr_factory.create_multipolygon(area);
|
||||
OGRFeature* feature = OGRFeature::CreateFeature(m_layer_polygon->GetLayerDefn());
|
||||
feature->SetGeometry(ogr_polygon.get());
|
||||
feature->SetField("id", static_cast<int>(area.orig_id()));
|
||||
gdalcpp::Feature feature(m_layer_mpoly, m_ogr_factory.create_multipolygon(area));
|
||||
feature.set_field("id", static_cast<double>(area.orig_id()));
|
||||
|
||||
std::string from_type;
|
||||
if (area.from_way()) {
|
||||
@@ -211,14 +130,8 @@ public:
|
||||
} else {
|
||||
from_type = "r";
|
||||
}
|
||||
feature->SetField("from_type", from_type.c_str());
|
||||
|
||||
if (m_layer_polygon->CreateFeature(feature) != OGRERR_NONE) {
|
||||
std::cerr << "Failed to create feature.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRFeature::DestroyFeature(feature);
|
||||
feature.set_field("from_type", from_type.c_str());
|
||||
feature.add_to_layer();
|
||||
} catch (osmium::geometry_error&) {
|
||||
std::cerr << "Ignoring illegal geometry for area " << area.id() << " created from " << (area.from_way() ? "way" : "relation") << " with id=" << area.orig_id() << ".\n";
|
||||
}
|
||||
@@ -228,26 +141,6 @@ public:
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
OGRDataSource* initialize_database(const std::string& output_format, const std::string& output_filename) {
|
||||
OGRRegisterAll();
|
||||
|
||||
OGRSFDriver* driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(output_format.c_str());
|
||||
if (!driver) {
|
||||
std::cerr << output_format << " driver not available.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE");
|
||||
const char* options[] = { "SPATIALITE=TRUE", nullptr };
|
||||
OGRDataSource* data_source = driver->CreateDataSource(output_filename.c_str(), const_cast<char**>(options));
|
||||
if (!data_source) {
|
||||
std::cerr << "Creation of output file failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return data_source;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
std::cerr << "Usage: " << argv[0] << " INFILE\n";
|
||||
@@ -258,9 +151,10 @@ int main(int argc, char* argv[]) {
|
||||
std::string input_filename(argv[1]);
|
||||
std::string output_filename("multipolygon.db");
|
||||
|
||||
OGRDataSource* data_source = initialize_database(output_format, output_filename);
|
||||
CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE");
|
||||
gdalcpp::Dataset dataset{output_format, output_filename, gdalcpp::SRS{}, { "SPATIALITE=TRUE" }};
|
||||
|
||||
osmium::area::ProblemReporterOGR problem_reporter(data_source);
|
||||
osmium::area::ProblemReporterOGR problem_reporter(dataset);
|
||||
osmium::area::Assembler::config_type assembler_config(&problem_reporter);
|
||||
assembler_config.enable_debug_output();
|
||||
osmium::area::MultipolygonCollector<osmium::area::Assembler> collector(assembler_config);
|
||||
@@ -275,7 +169,7 @@ int main(int argc, char* argv[]) {
|
||||
location_handler_type location_handler(index);
|
||||
location_handler.ignore_errors();
|
||||
|
||||
TestHandler test_handler(data_source);
|
||||
TestHandler test_handler(dataset);
|
||||
|
||||
std::cerr << "Pass 2...\n";
|
||||
osmium::io::Reader reader2(input_filename);
|
||||
@@ -284,8 +178,5 @@ int main(int argc, char* argv[]) {
|
||||
}));
|
||||
reader2.close();
|
||||
std::cerr << "Pass 2 done\n";
|
||||
|
||||
OGRDataSource::DestroyDataSource(data_source);
|
||||
OGRCleanupAll();
|
||||
}
|
||||
|
||||
|
||||
+29
-125
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <gdalcpp.hpp>
|
||||
|
||||
#include <osmium/index/map/sparse_mem_array.hpp>
|
||||
|
||||
#include <osmium/geom/ogr.hpp>
|
||||
@@ -15,154 +17,53 @@ typedef osmium::handler::NodeLocationsForWays<index_type> location_handler_type;
|
||||
|
||||
class TestOverviewHandler : public osmium::handler::Handler {
|
||||
|
||||
OGRDataSource* m_data_source;
|
||||
|
||||
OGRLayer* m_layer_nodes;
|
||||
OGRLayer* m_layer_labels;
|
||||
OGRLayer* m_layer_ways;
|
||||
gdalcpp::Layer m_layer_nodes;
|
||||
gdalcpp::Layer m_layer_labels;
|
||||
gdalcpp::Layer m_layer_ways;
|
||||
|
||||
osmium::geom::OGRFactory<> m_factory;
|
||||
|
||||
public:
|
||||
|
||||
TestOverviewHandler(const std::string& driver_name, const std::string& filename) {
|
||||
explicit TestOverviewHandler(gdalcpp::Dataset& dataset) :
|
||||
m_layer_nodes(dataset, "nodes", wkbPoint),
|
||||
m_layer_labels(dataset, "labels", wkbPoint),
|
||||
m_layer_ways(dataset, "ways", wkbLineString) {
|
||||
|
||||
OGRRegisterAll();
|
||||
m_layer_nodes.add_field("id", OFTReal, 10);
|
||||
|
||||
OGRSFDriver* driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver_name.c_str());
|
||||
if (!driver) {
|
||||
std::cerr << driver_name << " driver not available.\n";
|
||||
exit(1);
|
||||
}
|
||||
m_layer_labels.add_field("id", OFTReal, 10);
|
||||
m_layer_labels.add_field("label", OFTString, 30);
|
||||
|
||||
CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE");
|
||||
const char* options[] = { "SPATIALITE=TRUE", nullptr };
|
||||
m_data_source = driver->CreateDataSource(filename.c_str(), const_cast<char**>(options));
|
||||
if (!m_data_source) {
|
||||
std::cerr << "Creation of output file failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRSpatialReference sparef;
|
||||
sparef.SetWellKnownGeogCS("WGS84");
|
||||
|
||||
// nodes layer
|
||||
|
||||
m_layer_nodes = m_data_source->CreateLayer("nodes", &sparef, wkbPoint, nullptr);
|
||||
if (!m_layer_nodes) {
|
||||
std::cerr << "Layer creation failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRFieldDefn layer_nodes_field_id("id", OFTReal);
|
||||
layer_nodes_field_id.SetWidth(10);
|
||||
|
||||
if (m_layer_nodes->CreateField(&layer_nodes_field_id) != OGRERR_NONE) {
|
||||
std::cerr << "Creating id field failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// labels layer
|
||||
|
||||
m_layer_labels = m_data_source->CreateLayer("labels", &sparef, wkbPoint, nullptr);
|
||||
if (!m_layer_labels) {
|
||||
std::cerr << "Layer creation failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRFieldDefn layer_labels_field_id("id", OFTReal);
|
||||
layer_labels_field_id.SetWidth(10);
|
||||
|
||||
if (m_layer_labels->CreateField(&layer_labels_field_id) != OGRERR_NONE) {
|
||||
std::cerr << "Creating id field failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRFieldDefn layer_labels_field_label("label", OFTString);
|
||||
layer_labels_field_label.SetWidth(30);
|
||||
|
||||
if (m_layer_labels->CreateField(&layer_labels_field_label) != OGRERR_NONE) {
|
||||
std::cerr << "Creating label field failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// ways layer
|
||||
|
||||
m_layer_ways = m_data_source->CreateLayer("ways", &sparef, wkbLineString, nullptr);
|
||||
if (!m_layer_ways) {
|
||||
std::cerr << "Layer creation failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRFieldDefn layer_way_field_id("id", OFTReal);
|
||||
layer_way_field_id.SetWidth(10);
|
||||
|
||||
if (m_layer_ways->CreateField(&layer_way_field_id) != OGRERR_NONE) {
|
||||
std::cerr << "Creating id field failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRFieldDefn layer_way_field_test("test", OFTInteger);
|
||||
layer_way_field_test.SetWidth(3);
|
||||
|
||||
if (m_layer_ways->CreateField(&layer_way_field_test) != OGRERR_NONE) {
|
||||
std::cerr << "Creating test field failed.\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
~TestOverviewHandler() {
|
||||
OGRDataSource::DestroyDataSource(m_data_source);
|
||||
OGRCleanupAll();
|
||||
m_layer_ways.add_field("id", OFTReal, 10);
|
||||
m_layer_ways.add_field("test", OFTInteger, 3);
|
||||
}
|
||||
|
||||
void node(const osmium::Node& node) {
|
||||
const char* label = node.tags().get_value_by_key("label");
|
||||
if (label) {
|
||||
OGRFeature* feature = OGRFeature::CreateFeature(m_layer_labels->GetLayerDefn());
|
||||
std::unique_ptr<OGRPoint> ogr_point = m_factory.create_point(node);
|
||||
feature->SetGeometry(ogr_point.get());
|
||||
feature->SetField("id", static_cast<double>(node.id()));
|
||||
feature->SetField("label", label);
|
||||
|
||||
if (m_layer_labels->CreateFeature(feature) != OGRERR_NONE) {
|
||||
std::cerr << "Failed to create feature.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRFeature::DestroyFeature(feature);
|
||||
gdalcpp::Feature feature(m_layer_labels, m_factory.create_point(node));
|
||||
feature.set_field("id", static_cast<double>(node.id()));
|
||||
feature.set_field("label", label);
|
||||
feature.add_to_layer();
|
||||
} else {
|
||||
OGRFeature* feature = OGRFeature::CreateFeature(m_layer_nodes->GetLayerDefn());
|
||||
std::unique_ptr<OGRPoint> ogr_point = m_factory.create_point(node);
|
||||
feature->SetGeometry(ogr_point.get());
|
||||
feature->SetField("id", static_cast<double>(node.id()));
|
||||
|
||||
if (m_layer_nodes->CreateFeature(feature) != OGRERR_NONE) {
|
||||
std::cerr << "Failed to create feature.\n";
|
||||
exit(1);
|
||||
}
|
||||
OGRFeature::DestroyFeature(feature);
|
||||
gdalcpp::Feature feature(m_layer_nodes, m_factory.create_point(node));
|
||||
feature.set_field("id", static_cast<double>(node.id()));
|
||||
feature.add_to_layer();
|
||||
}
|
||||
}
|
||||
|
||||
void way(const osmium::Way& way) {
|
||||
try {
|
||||
std::unique_ptr<OGRLineString> ogr_linestring = m_factory.create_linestring(way);
|
||||
OGRFeature* feature = OGRFeature::CreateFeature(m_layer_ways->GetLayerDefn());
|
||||
feature->SetGeometry(ogr_linestring.get());
|
||||
feature->SetField("id", static_cast<double>(way.id()));
|
||||
gdalcpp::Feature feature(m_layer_ways, m_factory.create_linestring(way));
|
||||
feature.set_field("id", static_cast<double>(way.id()));
|
||||
|
||||
const char* test = way.tags().get_value_by_key("test");
|
||||
if (test) {
|
||||
feature->SetField("test", test);
|
||||
feature.set_field("test", test);
|
||||
}
|
||||
|
||||
if (m_layer_ways->CreateFeature(feature) != OGRERR_NONE) {
|
||||
std::cerr << "Failed to create feature.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OGRFeature::DestroyFeature(feature);
|
||||
feature.add_to_layer();
|
||||
} catch (osmium::geometry_error&) {
|
||||
std::cerr << "Ignoring illegal geometry for way " << way.id() << ".\n";
|
||||
}
|
||||
@@ -183,13 +84,16 @@ int main(int argc, char* argv[]) {
|
||||
std::string output_filename("testdata-overview.db");
|
||||
::unlink(output_filename.c_str());
|
||||
|
||||
CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE");
|
||||
gdalcpp::Dataset dataset(output_format, output_filename, gdalcpp::SRS{}, { "SPATIALITE=TRUE" });
|
||||
|
||||
osmium::io::Reader reader(input_filename);
|
||||
|
||||
index_type index;
|
||||
location_handler_type location_handler(index);
|
||||
location_handler.ignore_errors();
|
||||
|
||||
TestOverviewHandler handler(output_format, output_filename);
|
||||
TestOverviewHandler handler(dataset);
|
||||
|
||||
osmium::apply(reader, location_handler, handler);
|
||||
reader.close();
|
||||
|
||||
+20
-15
@@ -8,6 +8,7 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <osmium/io/detail/queue_util.hpp>
|
||||
#include <osmium/io/xml_input.hpp>
|
||||
#include <osmium/io/gzip_compression.hpp>
|
||||
#include <osmium/visitor.hpp>
|
||||
@@ -72,24 +73,27 @@ std::string read_gz_file(const char* test_id, const char* suffix) {
|
||||
|
||||
|
||||
header_buffer_type parse_xml(std::string input) {
|
||||
osmium::thread::Queue<std::string> input_queue;
|
||||
osmium::thread::Queue<osmium::memory::Buffer> output_queue;
|
||||
osmium::io::detail::future_string_queue_type input_queue;
|
||||
osmium::io::detail::future_buffer_queue_type output_queue;
|
||||
std::promise<osmium::io::Header> header_promise;
|
||||
std::atomic<bool> done {false};
|
||||
input_queue.push(input);
|
||||
input_queue.push(std::string()); // EOF marker
|
||||
std::future<osmium::io::Header> header_future = header_promise.get_future();
|
||||
|
||||
osmium::io::detail::XMLParser parser(input_queue, output_queue, header_promise, osmium::osm_entity_bits::all, done);
|
||||
parser();
|
||||
osmium::io::detail::add_to_queue(input_queue, std::move(input));
|
||||
osmium::io::detail::add_to_queue(input_queue, std::string{});
|
||||
|
||||
osmium::io::detail::XMLParser parser(input_queue, output_queue, header_promise, osmium::osm_entity_bits::all);
|
||||
parser.parse();
|
||||
|
||||
header_buffer_type result;
|
||||
result.header = header_promise.get_future().get();
|
||||
output_queue.wait_and_pop(result.buffer);
|
||||
result.header = header_future.get();
|
||||
std::future<osmium::memory::Buffer> future_buffer;
|
||||
output_queue.wait_and_pop(future_buffer);
|
||||
result.buffer = future_buffer.get();
|
||||
|
||||
if (result.buffer) {
|
||||
osmium::memory::Buffer buffer;
|
||||
output_queue.wait_and_pop(buffer);
|
||||
assert(!buffer);
|
||||
std::future<osmium::memory::Buffer> future_buffer2;
|
||||
output_queue.wait_and_pop(future_buffer2);
|
||||
assert(!future_buffer2.get());
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -534,9 +538,10 @@ TEST_CASE("Reading OSM XML 200") {
|
||||
osmium::io::Header header = reader.header();
|
||||
REQUIRE(header.get("generator") == "testdata");
|
||||
|
||||
osmium::memory::Buffer buffer = reader.read();
|
||||
REQUIRE(0 == buffer.committed());
|
||||
REQUIRE(! buffer);
|
||||
REQUIRE_THROWS({
|
||||
reader.read();
|
||||
});
|
||||
|
||||
reader.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,20 @@ TEST_CASE("NodeRefSegmentClass") {
|
||||
REQUIRE(calculate_intersection(s1, s7) == osmium::Location());
|
||||
}
|
||||
|
||||
SECTION("intersection of very long segments") {
|
||||
NodeRefSegment s1({ 1, {90.0, 90.0}}, { 2, {-90.0, -90.0}}, nullptr, nullptr);
|
||||
NodeRefSegment s2({ 1, {-90.0, 90.0}}, { 2, {90.0, -90.0}}, nullptr, nullptr);
|
||||
REQUIRE(calculate_intersection(s1, s2) == osmium::Location(0.0, 0.0));
|
||||
|
||||
NodeRefSegment s3({ 1, {-90.0, -90.0}}, { 2, {90.0, 90.0}}, nullptr, nullptr);
|
||||
NodeRefSegment s4({ 1, {-90.0, 90.0}}, { 2, {90.0, -90.0}}, nullptr, nullptr);
|
||||
REQUIRE(calculate_intersection(s3, s4) == osmium::Location(0.0, 0.0));
|
||||
|
||||
NodeRefSegment s5({ 1, {-90.0000001, -90.0}}, { 2, {90.0, 90.0}}, nullptr, nullptr);
|
||||
NodeRefSegment s6({ 1, {-90.0, 90.0}}, { 2, {90.0, -90.0}}, nullptr, nullptr);
|
||||
REQUIRE(calculate_intersection(s5, s6) == osmium::Location(0.0, 0.0));
|
||||
}
|
||||
|
||||
SECTION("to_left_of") {
|
||||
osmium::Location loc { 2.0, 2.0 };
|
||||
|
||||
|
||||
+61
-1
@@ -21,11 +21,13 @@ TEST_CASE("Basic Changeset") {
|
||||
.set_created_at(100)
|
||||
.set_closed_at(200)
|
||||
.set_num_changes(7)
|
||||
.set_num_comments(3)
|
||||
.set_uid(9);
|
||||
|
||||
REQUIRE(42 == cs1.id());
|
||||
REQUIRE(9 == cs1.uid());
|
||||
REQUIRE(7 == cs1.num_changes());
|
||||
REQUIRE(3 == cs1.num_comments());
|
||||
REQUIRE(true == cs1.closed());
|
||||
REQUIRE(osmium::Timestamp(100) == cs1.created_at());
|
||||
REQUIRE(osmium::Timestamp(200) == cs1.closed_at());
|
||||
@@ -33,7 +35,7 @@ TEST_CASE("Basic Changeset") {
|
||||
REQUIRE(std::string("user") == cs1.user());
|
||||
|
||||
crc32.update(cs1);
|
||||
REQUIRE(crc32().checksum() == 0xf44aff25);
|
||||
REQUIRE(crc32().checksum() == 0x502e8c0e);
|
||||
|
||||
osmium::Changeset& cs2 = buffer_add_changeset(buffer,
|
||||
"user",
|
||||
@@ -42,11 +44,13 @@ TEST_CASE("Basic Changeset") {
|
||||
cs2.set_id(43)
|
||||
.set_created_at(120)
|
||||
.set_num_changes(21)
|
||||
.set_num_comments(osmium::num_comments_type(0))
|
||||
.set_uid(9);
|
||||
|
||||
REQUIRE(43 == cs2.id());
|
||||
REQUIRE(9 == cs2.uid());
|
||||
REQUIRE(21 == cs2.num_changes());
|
||||
REQUIRE(0 == cs2.num_comments());
|
||||
REQUIRE(false == cs2.closed());
|
||||
REQUIRE(osmium::Timestamp(120) == cs2.created_at());
|
||||
REQUIRE(osmium::Timestamp() == cs2.closed_at());
|
||||
@@ -61,3 +65,59 @@ TEST_CASE("Basic Changeset") {
|
||||
REQUIRE(false == (cs1 >= cs2));
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Create changeset without helper") {
|
||||
osmium::memory::Buffer buffer(10 * 1000);
|
||||
osmium::builder::ChangesetBuilder builder(buffer);
|
||||
|
||||
osmium::Changeset& cs1 = builder.object();
|
||||
cs1.set_id(42)
|
||||
.set_created_at(100)
|
||||
.set_closed_at(200)
|
||||
.set_num_changes(7)
|
||||
.set_num_comments(2)
|
||||
.set_uid(9);
|
||||
|
||||
builder.add_user("user");
|
||||
add_tags(buffer, builder, {
|
||||
{"key1", "val1"},
|
||||
{"key2", "val2"}
|
||||
});
|
||||
|
||||
{
|
||||
osmium::builder::ChangesetDiscussionBuilder disc_builder(buffer, &builder);
|
||||
disc_builder.add_comment(osmium::Timestamp(300), 10, "user2");
|
||||
disc_builder.add_comment_text("foo");
|
||||
disc_builder.add_comment(osmium::Timestamp(400), 9, "user");
|
||||
disc_builder.add_comment_text("bar");
|
||||
}
|
||||
|
||||
buffer.commit();
|
||||
|
||||
REQUIRE(42 == cs1.id());
|
||||
REQUIRE(9 == cs1.uid());
|
||||
REQUIRE(7 == cs1.num_changes());
|
||||
REQUIRE(2 == cs1.num_comments());
|
||||
REQUIRE(true == cs1.closed());
|
||||
REQUIRE(osmium::Timestamp(100) == cs1.created_at());
|
||||
REQUIRE(osmium::Timestamp(200) == cs1.closed_at());
|
||||
REQUIRE(2 == cs1.tags().size());
|
||||
REQUIRE(std::string("user") == cs1.user());
|
||||
|
||||
auto cit = cs1.discussion().begin();
|
||||
|
||||
REQUIRE(cit != cs1.discussion().end());
|
||||
REQUIRE(cit->date() == osmium::Timestamp(300));
|
||||
REQUIRE(cit->uid() == 10);
|
||||
REQUIRE(std::string("user2") == cit->user());
|
||||
REQUIRE(std::string("foo") == cit->text());
|
||||
|
||||
REQUIRE(++cit != cs1.discussion().end());
|
||||
REQUIRE(cit->date() == osmium::Timestamp(400));
|
||||
REQUIRE(cit->uid() == 9);
|
||||
REQUIRE(std::string("user") == cit->user());
|
||||
REQUIRE(std::string("bar") == cit->text());
|
||||
|
||||
REQUIRE(++cit == cs1.discussion().end());
|
||||
}
|
||||
|
||||
|
||||
+21
@@ -24,6 +24,27 @@ TEST_CASE("CRC of basic datatypes") {
|
||||
REQUIRE(crc32().checksum() == 0x8fe62899);
|
||||
}
|
||||
|
||||
SECTION("Int16") {
|
||||
crc32.update_int16(0x0123U);
|
||||
crc32.update_int16(0x1234U);
|
||||
|
||||
REQUIRE(crc32().checksum() == 0xda923744);
|
||||
}
|
||||
|
||||
SECTION("Int32") {
|
||||
crc32.update_int32(0x01234567UL);
|
||||
crc32.update_int32(0x12345678UL);
|
||||
|
||||
REQUIRE(crc32().checksum() == 0x9b4e2af3);
|
||||
}
|
||||
|
||||
SECTION("Int64") {
|
||||
crc32.update_int64(0x0123456789abcdefULL);
|
||||
crc32.update_int64(0x123456789abcdef0ULL);
|
||||
|
||||
REQUIRE(crc32().checksum() == 0x6d8b7267);
|
||||
}
|
||||
|
||||
SECTION("String") {
|
||||
const char* str = "foobar";
|
||||
crc32.update_string(str);
|
||||
|
||||
+3
-3
@@ -37,12 +37,12 @@ SECTION("node_builder") {
|
||||
REQUIRE(333 == node.changeset());
|
||||
REQUIRE(21 == node.uid());
|
||||
REQUIRE(std::string("foo") == node.user());
|
||||
REQUIRE(123 == node.timestamp());
|
||||
REQUIRE(123 == uint32_t(node.timestamp()));
|
||||
REQUIRE(osmium::Location(3.5, 4.7) == node.location());
|
||||
REQUIRE(2 == node.tags().size());
|
||||
|
||||
crc32.update(node);
|
||||
REQUIRE(crc32().checksum() == 0xc696802f);
|
||||
REQUIRE(crc32().checksum() == 0x7dc553f9);
|
||||
|
||||
node.set_visible(false);
|
||||
REQUIRE(false == node.visible());
|
||||
@@ -61,7 +61,7 @@ SECTION("node_default_attributes") {
|
||||
REQUIRE(0 == node.changeset());
|
||||
REQUIRE(0 == node.uid());
|
||||
REQUIRE(std::string("") == node.user());
|
||||
REQUIRE(0 == node.timestamp());
|
||||
REQUIRE(0 == uint32_t(node.timestamp()));
|
||||
REQUIRE(osmium::Location() == node.location());
|
||||
REQUIRE(0 == node.tags().size());
|
||||
}
|
||||
|
||||
+22
-22
@@ -31,20 +31,20 @@ TEST_CASE("Object_Comparisons") {
|
||||
node1.set_version(1);
|
||||
node2.set_id(15);
|
||||
node2.set_version(2);
|
||||
REQUIRE(true == (node1 < node2));
|
||||
REQUIRE(false == (node1 > node2));
|
||||
REQUIRE(node1 < node2);
|
||||
REQUIRE_FALSE(node1 > node2);
|
||||
node1.set_id(20);
|
||||
node1.set_version(1);
|
||||
node2.set_id(20);
|
||||
node2.set_version(2);
|
||||
REQUIRE(true == (node1 < node2));
|
||||
REQUIRE(false == (node1 > node2));
|
||||
REQUIRE(node1 < node2);
|
||||
REQUIRE_FALSE(node1 > node2);
|
||||
node1.set_id(-10);
|
||||
node1.set_version(2);
|
||||
node2.set_id(-15);
|
||||
node2.set_version(1);
|
||||
REQUIRE(true == (node1 < node2));
|
||||
REQUIRE(false == (node1 > node2));
|
||||
REQUIRE(node1 < node2);
|
||||
REQUIRE_FALSE(node1 > node2);
|
||||
}
|
||||
|
||||
SECTION("order_types") {
|
||||
@@ -122,26 +122,26 @@ TEST_CASE("Object_Comparisons") {
|
||||
const osmium::Way& way = static_cast<const osmium::Way&>(*(++it));
|
||||
const osmium::Relation& relation = static_cast<const osmium::Relation&>(*(++it));
|
||||
|
||||
REQUIRE(true == (node1 < node2));
|
||||
REQUIRE(true == (node2 < way));
|
||||
REQUIRE(false == (node2 > way));
|
||||
REQUIRE(true == (way < relation));
|
||||
REQUIRE(true == (node1 < relation));
|
||||
REQUIRE(node1 < node2);
|
||||
REQUIRE(node2 < way);
|
||||
REQUIRE_FALSE(node2 > way);
|
||||
REQUIRE(way < relation);
|
||||
REQUIRE(node1 < relation);
|
||||
|
||||
REQUIRE(true == osmium::object_order_type_id_version()(node1, node2));
|
||||
REQUIRE(true == osmium::object_order_type_id_reverse_version()(node2, node1));
|
||||
REQUIRE(true == osmium::object_order_type_id_version()(node1, way));
|
||||
REQUIRE(true == osmium::object_order_type_id_reverse_version()(node1, way));
|
||||
REQUIRE(osmium::object_order_type_id_version()(node1, node2));
|
||||
REQUIRE(osmium::object_order_type_id_reverse_version()(node2, node1));
|
||||
REQUIRE(osmium::object_order_type_id_version()(node1, way));
|
||||
REQUIRE(osmium::object_order_type_id_reverse_version()(node1, way));
|
||||
|
||||
REQUIRE(false == osmium::object_equal_type_id_version()(node1, node2));
|
||||
REQUIRE(true == osmium::object_equal_type_id_version()(node2, node3));
|
||||
REQUIRE_FALSE(osmium::object_equal_type_id_version()(node1, node2));
|
||||
REQUIRE(osmium::object_equal_type_id_version()(node2, node3));
|
||||
|
||||
REQUIRE(true == osmium::object_equal_type_id()(node1, node2));
|
||||
REQUIRE(true == osmium::object_equal_type_id()(node2, node3));
|
||||
REQUIRE(osmium::object_equal_type_id()(node1, node2));
|
||||
REQUIRE(osmium::object_equal_type_id()(node2, node3));
|
||||
|
||||
REQUIRE(false == osmium::object_equal_type_id_version()(node1, way));
|
||||
REQUIRE(false == osmium::object_equal_type_id_version()(node1, relation));
|
||||
REQUIRE(false == osmium::object_equal_type_id()(node1, relation));
|
||||
REQUIRE_FALSE(osmium::object_equal_type_id_version()(node1, way));
|
||||
REQUIRE_FALSE(osmium::object_equal_type_id_version()(node1, relation));
|
||||
REQUIRE_FALSE(osmium::object_equal_type_id()(node1, relation));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+13
-2
@@ -36,7 +36,7 @@ TEST_CASE("Build relation") {
|
||||
REQUIRE(333 == relation.changeset());
|
||||
REQUIRE(21 == relation.uid());
|
||||
REQUIRE(std::string("foo") == relation.user());
|
||||
REQUIRE(123 == relation.timestamp());
|
||||
REQUIRE(123 == uint32_t(relation.timestamp()));
|
||||
REQUIRE(2 == relation.tags().size());
|
||||
REQUIRE(3 == relation.members().size());
|
||||
|
||||
@@ -61,5 +61,16 @@ TEST_CASE("Build relation") {
|
||||
}
|
||||
|
||||
crc32.update(relation);
|
||||
REQUIRE(crc32().checksum() == 0xebcd836d);
|
||||
REQUIRE(crc32().checksum() == 0x2c2352e);
|
||||
}
|
||||
|
||||
TEST_CASE("Member role too long") {
|
||||
osmium::memory::Buffer buffer(10000);
|
||||
|
||||
osmium::builder::RelationMemberListBuilder builder(buffer);
|
||||
|
||||
const char role[2000] = "";
|
||||
builder.add_member(osmium::item_type::node, 1, role, 1024);
|
||||
REQUIRE_THROWS(builder.add_member(osmium::item_type::node, 1, role, 1025));
|
||||
}
|
||||
|
||||
|
||||
+21
-6
@@ -8,34 +8,45 @@ TEST_CASE("Timestamp") {
|
||||
|
||||
SECTION("can be default initialized to invalid value") {
|
||||
osmium::Timestamp t;
|
||||
REQUIRE(0 == t);
|
||||
REQUIRE(0 == uint32_t(t));
|
||||
REQUIRE("" == t.to_iso());
|
||||
REQUIRE_FALSE(t.valid());
|
||||
}
|
||||
|
||||
SECTION("invalid value is zero") {
|
||||
osmium::Timestamp t(static_cast<time_t>(0));
|
||||
REQUIRE(0 == t);
|
||||
REQUIRE(0 == uint32_t(t));
|
||||
REQUIRE("" == t.to_iso());
|
||||
REQUIRE_FALSE(t.valid());
|
||||
}
|
||||
|
||||
SECTION("can be initialized from time_t") {
|
||||
osmium::Timestamp t(static_cast<time_t>(1));
|
||||
REQUIRE(1 == t);
|
||||
REQUIRE(1 == uint32_t(t));
|
||||
REQUIRE("1970-01-01T00:00:01Z" == t.to_iso());
|
||||
REQUIRE(t.valid());
|
||||
}
|
||||
|
||||
SECTION("can be initialized from const char*") {
|
||||
osmium::Timestamp t("2000-01-01T00:00:00Z");
|
||||
REQUIRE("2000-01-01T00:00:00Z" == t.to_iso());
|
||||
REQUIRE(t.valid());
|
||||
}
|
||||
|
||||
SECTION("can be initialized from string") {
|
||||
osmium::Timestamp t("2000-01-01T00:00:00Z");
|
||||
std::string s = "2000-01-01T00:00:00Z";
|
||||
osmium::Timestamp t(s);
|
||||
REQUIRE("2000-01-01T00:00:00Z" == t.to_iso());
|
||||
REQUIRE(t.valid());
|
||||
}
|
||||
|
||||
SECTION("throws if initialized from bad string") {
|
||||
REQUIRE_THROWS_AS(osmium::Timestamp("x"), std::invalid_argument);
|
||||
}
|
||||
|
||||
SECTION("can be implicitly cast to time_t") {
|
||||
SECTION("can be explicitly cast to time_t") {
|
||||
osmium::Timestamp t(4242);
|
||||
time_t x = t;
|
||||
time_t x = t.seconds_since_epoch();
|
||||
REQUIRE(x == 4242);
|
||||
}
|
||||
|
||||
@@ -50,6 +61,10 @@ TEST_CASE("Timestamp") {
|
||||
osmium::Timestamp t1(10);
|
||||
osmium::Timestamp t2(50);
|
||||
REQUIRE(t1 < t2);
|
||||
REQUIRE(t1 > osmium::start_of_time());
|
||||
REQUIRE(t2 > osmium::start_of_time());
|
||||
REQUIRE(t1 < osmium::end_of_time());
|
||||
REQUIRE(t2 < osmium::end_of_time());
|
||||
}
|
||||
|
||||
SECTION("can be written to stream") {
|
||||
|
||||
+2
-2
@@ -36,7 +36,7 @@ SECTION("way_builder") {
|
||||
REQUIRE(333 == way.changeset());
|
||||
REQUIRE(21 == way.uid());
|
||||
REQUIRE(std::string("foo") == way.user());
|
||||
REQUIRE(123 == way.timestamp());
|
||||
REQUIRE(123 == uint32_t(way.timestamp()));
|
||||
REQUIRE(2 == way.tags().size());
|
||||
REQUIRE(3 == way.nodes().size());
|
||||
REQUIRE(1 == way.nodes()[0].ref());
|
||||
@@ -45,7 +45,7 @@ SECTION("way_builder") {
|
||||
REQUIRE(! way.is_closed());
|
||||
|
||||
crc32.update(way);
|
||||
REQUIRE(crc32().checksum() == 0x20fe7a30);
|
||||
REQUIRE(crc32().checksum() == 0x7676d0c2);
|
||||
}
|
||||
|
||||
SECTION("closed_way") {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <osmium/memory/buffer.hpp>
|
||||
|
||||
TEST_CASE("Buffer basics") {
|
||||
|
||||
osmium::memory::Buffer invalid_buffer1;
|
||||
osmium::memory::Buffer invalid_buffer2;
|
||||
osmium::memory::Buffer empty_buffer1(1024);
|
||||
osmium::memory::Buffer empty_buffer2(2048);
|
||||
|
||||
REQUIRE(!invalid_buffer1);
|
||||
REQUIRE(!invalid_buffer2);
|
||||
REQUIRE(empty_buffer1);
|
||||
REQUIRE(empty_buffer2);
|
||||
|
||||
REQUIRE(invalid_buffer1 == invalid_buffer2);
|
||||
REQUIRE(invalid_buffer1 != empty_buffer1);
|
||||
REQUIRE(empty_buffer1 != empty_buffer2);
|
||||
|
||||
REQUIRE(invalid_buffer1.capacity() == 0);
|
||||
REQUIRE(invalid_buffer1.written() == 0);
|
||||
REQUIRE(invalid_buffer1.committed() == 0);
|
||||
|
||||
REQUIRE(empty_buffer1.capacity() == 1024);
|
||||
REQUIRE(empty_buffer1.written() == 0);
|
||||
REQUIRE(empty_buffer1.committed() == 0);
|
||||
|
||||
REQUIRE(empty_buffer2.capacity() == 2048);
|
||||
REQUIRE(empty_buffer2.written() == 0);
|
||||
REQUIRE(empty_buffer2.committed() == 0);
|
||||
|
||||
}
|
||||
|
||||
+71
-7
@@ -9,7 +9,7 @@ void check_node_1(osmium::Node& node) {
|
||||
REQUIRE(true == node.visible());
|
||||
REQUIRE(333 == node.changeset());
|
||||
REQUIRE(21 == node.uid());
|
||||
REQUIRE(123 == node.timestamp());
|
||||
REQUIRE(123 == uint32_t(node.timestamp()));
|
||||
REQUIRE(osmium::Location(3.5, 4.7) == node.location());
|
||||
REQUIRE(std::string("testuser") == node.user());
|
||||
|
||||
@@ -28,7 +28,7 @@ void check_node_2(osmium::Node& node) {
|
||||
REQUIRE(true == node.visible());
|
||||
REQUIRE(333 == node.changeset());
|
||||
REQUIRE(21 == node.uid());
|
||||
REQUIRE(123 == node.timestamp());
|
||||
REQUIRE(123 == uint32_t(node.timestamp()));
|
||||
REQUIRE(osmium::Location(3.5, 4.7) == node.location());
|
||||
REQUIRE(std::string("testuser") == node.user());
|
||||
|
||||
@@ -56,13 +56,14 @@ void check_node_2(osmium::Node& node) {
|
||||
REQUIRE(2 == n);
|
||||
}
|
||||
|
||||
TEST_CASE("Buffer_Node") {
|
||||
TEST_CASE("Node in Buffer") {
|
||||
|
||||
SECTION("buffer_node") {
|
||||
constexpr size_t buffer_size = 10000;
|
||||
unsigned char data[buffer_size];
|
||||
constexpr size_t buffer_size = 10000;
|
||||
unsigned char data[buffer_size];
|
||||
|
||||
osmium::memory::Buffer buffer(data, buffer_size, 0);
|
||||
osmium::memory::Buffer buffer(data, buffer_size, 0);
|
||||
|
||||
SECTION("Add node to buffer") {
|
||||
|
||||
{
|
||||
// add node 1
|
||||
@@ -132,4 +133,67 @@ TEST_CASE("Buffer_Node") {
|
||||
|
||||
}
|
||||
|
||||
SECTION("Add buffer to another one") {
|
||||
|
||||
{
|
||||
// add node 1
|
||||
osmium::builder::NodeBuilder node_builder(buffer);
|
||||
osmium::Node& node = node_builder.object();
|
||||
REQUIRE(osmium::item_type::node == node.type());
|
||||
|
||||
node.set_id(1);
|
||||
node.set_version(3);
|
||||
node.set_visible(true);
|
||||
node.set_changeset(333);
|
||||
node.set_uid(21);
|
||||
node.set_timestamp(123);
|
||||
node.set_location(osmium::Location(3.5, 4.7));
|
||||
|
||||
node_builder.add_user("testuser");
|
||||
|
||||
buffer.commit();
|
||||
}
|
||||
|
||||
osmium::memory::Buffer buffer2(buffer_size, osmium::memory::Buffer::auto_grow::yes);
|
||||
|
||||
buffer2.add_buffer(buffer);
|
||||
buffer2.commit();
|
||||
|
||||
REQUIRE(buffer.committed() == buffer2.committed());
|
||||
const osmium::Node& node = buffer2.get<osmium::Node>(0);
|
||||
REQUIRE(node.id() == 1);
|
||||
REQUIRE(123 == uint32_t(node.timestamp()));
|
||||
}
|
||||
|
||||
SECTION("Use back_inserter on buffer") {
|
||||
|
||||
{
|
||||
// add node 1
|
||||
osmium::builder::NodeBuilder node_builder(buffer);
|
||||
osmium::Node& node = node_builder.object();
|
||||
REQUIRE(osmium::item_type::node == node.type());
|
||||
|
||||
node.set_id(1);
|
||||
node.set_version(3);
|
||||
node.set_visible(true);
|
||||
node.set_changeset(333);
|
||||
node.set_uid(21);
|
||||
node.set_timestamp(123);
|
||||
node.set_location(osmium::Location(3.5, 4.7));
|
||||
|
||||
node_builder.add_user("testuser");
|
||||
|
||||
buffer.commit();
|
||||
}
|
||||
|
||||
osmium::memory::Buffer buffer2(buffer_size, osmium::memory::Buffer::auto_grow::yes);
|
||||
|
||||
std::copy(buffer.begin(), buffer.end(), std::back_inserter(buffer2));
|
||||
|
||||
REQUIRE(buffer.committed() == buffer2.committed());
|
||||
const osmium::Node& node = buffer2.get<osmium::Node>(0);
|
||||
REQUIRE(node.id() == 1);
|
||||
REQUIRE(123 == uint32_t(node.timestamp()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -1,5 +1,7 @@
|
||||
|
||||
std::string s = R"(127.4864358 16.8380041 223904 118630 18
|
||||
#include <string>
|
||||
|
||||
static std::string s = R"(127.4864358 16.8380041 223904 118630 18
|
||||
163.1103174 39.4760232 121 48 7
|
||||
-4.1372725 -22.5105386 31 36 6
|
||||
98.7193066 -36.2312406 1 1 1
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<osm version="0.6" generator="osmium/1.2.1">
|
||||
<node id="1" version="1" timestamp="2015-09-17T11:52:00Z" uid="1" user="user_1" changeset="1" visible="false"/>
|
||||
<node id="2" version="1" timestamp="2015-09-17T11:52:00Z" uid="1" user="user_1" changeset="1" visible="true" lat="1" lon="1"/>
|
||||
</osm>
|
||||
Binary file not shown.
@@ -0,0 +1,153 @@
|
||||
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <locale>
|
||||
|
||||
#include <osmium/io/detail/string_util.hpp>
|
||||
|
||||
TEST_CASE("output formatted") {
|
||||
|
||||
std::string out;
|
||||
|
||||
SECTION("small results") {
|
||||
osmium::io::detail::append_printf_formatted_string(out, "%d", 17);
|
||||
REQUIRE(out == "17");
|
||||
}
|
||||
|
||||
SECTION("several parameters") {
|
||||
osmium::io::detail::append_printf_formatted_string(out, "%d %s", 17, "foo");
|
||||
REQUIRE(out == "17 foo");
|
||||
|
||||
}
|
||||
|
||||
SECTION("string already containing something") {
|
||||
out += "foo";
|
||||
osmium::io::detail::append_printf_formatted_string(out, " %d", 23);
|
||||
REQUIRE(out == "foo 23");
|
||||
}
|
||||
|
||||
SECTION("large results") {
|
||||
const char* str =
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
|
||||
|
||||
osmium::io::detail::append_printf_formatted_string(out, "%s", str);
|
||||
|
||||
REQUIRE(out == str);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("UTF8 encoding") {
|
||||
|
||||
std::string out;
|
||||
|
||||
SECTION("append to string") {
|
||||
out += "1234";
|
||||
osmium::io::detail::append_utf8_encoded_string(out, "abc");
|
||||
REQUIRE(out == "1234abc");
|
||||
}
|
||||
|
||||
SECTION("don't encode alphabetic characters") {
|
||||
const char* s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
osmium::io::detail::append_utf8_encoded_string(out, s);
|
||||
REQUIRE(out == s);
|
||||
}
|
||||
|
||||
SECTION("don't encode numeric characters") {
|
||||
const char* s = "0123456789";
|
||||
osmium::io::detail::append_utf8_encoded_string(out, s);
|
||||
REQUIRE(out == s);
|
||||
}
|
||||
|
||||
SECTION("don't encode lots of often used characters characters") {
|
||||
const char* s = ".-;:_#+";
|
||||
osmium::io::detail::append_utf8_encoded_string(out, s);
|
||||
REQUIRE(out == s);
|
||||
}
|
||||
|
||||
SECTION("encode characters that are special in OPL") {
|
||||
osmium::io::detail::append_utf8_encoded_string(out, " \n,=@");
|
||||
REQUIRE(out == "%20%%0a%%2c%%3d%%40%");
|
||||
}
|
||||
|
||||
// workaround for missing support for u8 string literals on Windows
|
||||
#if !defined(_MSC_VER)
|
||||
|
||||
SECTION("encode multibyte character") {
|
||||
osmium::io::detail::append_utf8_encoded_string(out, u8"\u30dc_\U0001d11e_\U0001f6eb");
|
||||
REQUIRE(out == "%30dc%_%1d11e%_%1f6eb%");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("html encoding") {
|
||||
|
||||
std::string out;
|
||||
|
||||
SECTION("do not encode normal characters") {
|
||||
const char* s = "abc123,.-";
|
||||
osmium::io::detail::append_xml_encoded_string(out, s);
|
||||
REQUIRE(out == s);
|
||||
}
|
||||
|
||||
SECTION("encode special XML characters") {
|
||||
const char* s = "& \" \' < > \n \r \t";
|
||||
osmium::io::detail::append_xml_encoded_string(out, s);
|
||||
REQUIRE(out == "& " ' < > 
 
 	");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("debug encoding") {
|
||||
|
||||
std::string out;
|
||||
|
||||
SECTION("do not encode normal characters") {
|
||||
const char* s = "abc123,.-";
|
||||
osmium::io::detail::append_debug_encoded_string(out, s, "[", "]");
|
||||
REQUIRE(out == s);
|
||||
}
|
||||
|
||||
SECTION("encode some unicode characters") {
|
||||
const char* s = u8"\n_\u30dc_\U0001d11e_\U0001f6eb";
|
||||
osmium::io::detail::append_debug_encoded_string(out, s, "[", "]");
|
||||
REQUIRE(out == "[<U+000A>]_[<U+30DC>]_[<U+1D11E>]_[<U+1F6EB>]");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("encoding of non-printable characters in the first 127 characters") {
|
||||
|
||||
std::locale cloc("C");
|
||||
char s[] = "a\0";
|
||||
|
||||
for (char c = 1; c < 0x7f; ++c) {
|
||||
std::string out;
|
||||
s[0] = c;
|
||||
|
||||
SECTION("utf8 encode") {
|
||||
osmium::io::detail::append_utf8_encoded_string(out, s);
|
||||
|
||||
if (!std::isprint(c, cloc)) {
|
||||
REQUIRE(out[0] == '%');
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("debug encode") {
|
||||
osmium::io::detail::append_debug_encoded_string(out, s, "", "");
|
||||
|
||||
if (!std::isprint(c, cloc)) {
|
||||
REQUIRE(out[0] == '<');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+100
-5
@@ -4,6 +4,7 @@
|
||||
#include <osmium/handler.hpp>
|
||||
#include <osmium/io/any_compression.hpp>
|
||||
#include <osmium/io/xml_input.hpp>
|
||||
#include <osmium/io/pbf_input.hpp>
|
||||
#include <osmium/visitor.hpp>
|
||||
#include <osmium/memory/buffer.hpp>
|
||||
|
||||
@@ -17,6 +18,27 @@ struct CountHandler : public osmium::handler::Handler {
|
||||
|
||||
}; // class CountHandler
|
||||
|
||||
struct ZeroPositionNodeCountHandler : public osmium::handler::Handler {
|
||||
|
||||
// number of nodes seen at zero position, or visible with undefined
|
||||
// location.
|
||||
int count = 0;
|
||||
int total_count = 0; // total number of nodes seen
|
||||
const osmium::Location zero = osmium::Location(int32_t(0), int32_t(0));
|
||||
|
||||
void node(osmium::Node &n) {
|
||||
// no nodes in the history file have a zero location, and
|
||||
// no visible nodes should have an undefined location.
|
||||
if ((n.location() == zero) ||
|
||||
(n.visible() && !n.location())) {
|
||||
++count;
|
||||
}
|
||||
++total_count;
|
||||
}
|
||||
|
||||
}; // class ZeroPositionNodeCountHandler
|
||||
|
||||
|
||||
TEST_CASE("Reader") {
|
||||
|
||||
SECTION("reader can be initialized with file") {
|
||||
@@ -34,7 +56,7 @@ TEST_CASE("Reader") {
|
||||
osmium::apply(reader, handler);
|
||||
}
|
||||
|
||||
SECTION("should return invalid buffer after eof") {
|
||||
SECTION("should throw after eof") {
|
||||
osmium::io::File file(with_data_dir("t/io/data.osm"));
|
||||
osmium::io::Reader reader(file);
|
||||
|
||||
@@ -45,9 +67,9 @@ TEST_CASE("Reader") {
|
||||
|
||||
REQUIRE(reader.eof());
|
||||
|
||||
// extra read always returns invalid buffer
|
||||
osmium::memory::Buffer buffer = reader.read();
|
||||
REQUIRE(!buffer);
|
||||
REQUIRE_THROWS_AS({
|
||||
reader.read();
|
||||
}, osmium::io_error);
|
||||
}
|
||||
|
||||
SECTION("should not hang when apply() is called twice on reader") {
|
||||
@@ -56,7 +78,9 @@ TEST_CASE("Reader") {
|
||||
osmium::handler::Handler handler;
|
||||
|
||||
osmium::apply(reader, handler);
|
||||
osmium::apply(reader, handler);
|
||||
REQUIRE_THROWS_AS({
|
||||
osmium::apply(reader, handler);
|
||||
}, osmium::io_error);
|
||||
}
|
||||
|
||||
SECTION("should work with a buffer with uncompressed data") {
|
||||
@@ -113,5 +137,76 @@ TEST_CASE("Reader") {
|
||||
REQUIRE(handler.count == 1);
|
||||
}
|
||||
|
||||
SECTION("should decode zero node positions in history (XML)") {
|
||||
osmium::io::Reader reader(with_data_dir("t/io/deleted_nodes.osh"),
|
||||
osmium::osm_entity_bits::node);
|
||||
ZeroPositionNodeCountHandler handler;
|
||||
|
||||
REQUIRE(handler.count == 0);
|
||||
REQUIRE(handler.total_count == 0);
|
||||
|
||||
osmium::apply(reader, handler);
|
||||
|
||||
REQUIRE(handler.count == 0);
|
||||
REQUIRE(handler.total_count == 2);
|
||||
}
|
||||
|
||||
SECTION("should decode zero node positions in history (PBF)") {
|
||||
osmium::io::Reader reader(with_data_dir("t/io/deleted_nodes.osh.pbf"),
|
||||
osmium::osm_entity_bits::node);
|
||||
ZeroPositionNodeCountHandler handler;
|
||||
|
||||
REQUIRE(handler.count == 0);
|
||||
REQUIRE(handler.total_count == 0);
|
||||
|
||||
osmium::apply(reader, handler);
|
||||
|
||||
REQUIRE(handler.count == 0);
|
||||
REQUIRE(handler.total_count == 2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Reader failure modes") {
|
||||
|
||||
SECTION("should fail with nonexistent file") {
|
||||
REQUIRE_THROWS({
|
||||
osmium::io::Reader reader(with_data_dir("t/io/nonexistent-file.osm"));
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("should fail with nonexistent file (gz)") {
|
||||
REQUIRE_THROWS({
|
||||
osmium::io::Reader reader(with_data_dir("t/io/nonexistent-file.osm.gz"));
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("should fail with nonexistent file (pbf)") {
|
||||
REQUIRE_THROWS({
|
||||
osmium::io::Reader reader(with_data_dir("t/io/nonexistent-file.osm.pbf"));
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("should work when there is an exception in main thread before getting header") {
|
||||
try {
|
||||
osmium::io::Reader reader(with_data_dir("t/io/data.osm"));
|
||||
REQUIRE(!reader.eof());
|
||||
throw std::runtime_error("foo");
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SECTION("should work when there is an exception in main thread while reading") {
|
||||
try {
|
||||
osmium::io::Reader reader(with_data_dir("t/io/data.osm"));
|
||||
REQUIRE(!reader.eof());
|
||||
auto header = reader.header();
|
||||
throw std::runtime_error("foo");
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
|
||||
#include "catch.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <osmium/io/compression.hpp>
|
||||
#include <osmium/io/xml_input.hpp>
|
||||
|
||||
// The MockDecompressor behaves like other Decompressor classes, but "invents"
|
||||
// OSM data in XML format that can be read. Through a parameter to the
|
||||
// constructor it can be instructed to throw an exception in specific parts
|
||||
// of its code. This is then used to test the internals of the Reader.
|
||||
|
||||
class MockDecompressor : public osmium::io::Decompressor {
|
||||
|
||||
std::string m_fail_in;
|
||||
int m_read_count = 0;
|
||||
|
||||
public:
|
||||
|
||||
MockDecompressor(const std::string& fail_in) :
|
||||
Decompressor(),
|
||||
m_fail_in(fail_in) {
|
||||
if (m_fail_in == "constructor") {
|
||||
throw std::runtime_error("error constructor");
|
||||
}
|
||||
}
|
||||
|
||||
~MockDecompressor() noexcept final = default;
|
||||
|
||||
void add_node(std::string& s, int i) {
|
||||
s += "<node id='";
|
||||
s += std::to_string(i);
|
||||
s += "' version='1' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' changeset='1' lon='1.02' lat='1.02'/>\n";
|
||||
}
|
||||
|
||||
std::string read() final {
|
||||
std::string buffer;
|
||||
++m_read_count;
|
||||
|
||||
if (m_read_count == 1) {
|
||||
if (m_fail_in == "first read") {
|
||||
throw std::runtime_error("error first read");
|
||||
} else {
|
||||
buffer += "<?xml version='1.0' encoding='UTF-8'?>\n<osm version='0.6' generator='testdata'>\n";
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
add_node(buffer, i);
|
||||
}
|
||||
}
|
||||
} else if (m_read_count == 2) {
|
||||
if (m_fail_in == "second read") {
|
||||
throw std::runtime_error("error second read");
|
||||
} else {
|
||||
for (int i = 1000; i < 2000; ++i) {
|
||||
add_node(buffer, i);
|
||||
}
|
||||
}
|
||||
} else if (m_read_count == 3) {
|
||||
buffer += "</osm>";
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void close() final {
|
||||
if (m_fail_in == "close") {
|
||||
throw std::runtime_error("error close");
|
||||
}
|
||||
}
|
||||
|
||||
}; // class MockDecompressor
|
||||
|
||||
TEST_CASE("Test Reader using MockDecompressor") {
|
||||
|
||||
std::string fail_in;
|
||||
|
||||
osmium::io::CompressionFactory::instance().register_compression(osmium::io::file_compression::gzip,
|
||||
[](int, osmium::io::fsync) { return nullptr; },
|
||||
[&](int) { return new MockDecompressor(fail_in); },
|
||||
[](const char*, size_t) { return nullptr; }
|
||||
);
|
||||
|
||||
SECTION("fail in constructor") {
|
||||
fail_in = "constructor";
|
||||
|
||||
try {
|
||||
osmium::io::Reader reader(with_data_dir("t/io/data.osm.gz"));
|
||||
REQUIRE(false);
|
||||
} catch (std::runtime_error& e) {
|
||||
REQUIRE(std::string{e.what()} == "error constructor");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("fail in first read") {
|
||||
fail_in = "first read";
|
||||
|
||||
try {
|
||||
osmium::io::Reader reader(with_data_dir("t/io/data.osm.gz"));
|
||||
reader.read();
|
||||
REQUIRE(false);
|
||||
} catch (std::runtime_error& e) {
|
||||
REQUIRE(std::string{e.what()} == "error first read");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("fail in second read") {
|
||||
fail_in = "second read";
|
||||
|
||||
try {
|
||||
osmium::io::Reader reader(with_data_dir("t/io/data.osm.gz"));
|
||||
reader.read();
|
||||
reader.read();
|
||||
REQUIRE(false);
|
||||
} catch (std::runtime_error& e) {
|
||||
REQUIRE(std::string{e.what()} == "error second read");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("fail in close") {
|
||||
fail_in = "close";
|
||||
|
||||
try {
|
||||
osmium::io::Reader reader(with_data_dir("t/io/data.osm.gz"));
|
||||
reader.read();
|
||||
reader.read();
|
||||
reader.read();
|
||||
reader.close();
|
||||
REQUIRE(false);
|
||||
} catch (std::runtime_error& e) {
|
||||
REQUIRE(std::string{e.what()} == "error close");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("not failing") {
|
||||
fail_in = "not";
|
||||
|
||||
osmium::io::Reader reader(with_data_dir("t/io/data.osm.gz"));
|
||||
reader.read();
|
||||
reader.close();
|
||||
REQUIRE(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
|
||||
#include "catch.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <osmium/builder/osm_object_builder.hpp>
|
||||
#include <osmium/io/compression.hpp>
|
||||
#include <osmium/io/detail/input_format.hpp>
|
||||
#include <osmium/io/detail/queue_util.hpp>
|
||||
#include <osmium/io/file_format.hpp>
|
||||
#include <osmium/io/header.hpp>
|
||||
#include <osmium/io/reader.hpp>
|
||||
#include <osmium/thread/queue.hpp>
|
||||
#include <osmium/thread/util.hpp>
|
||||
|
||||
class MockParser : public osmium::io::detail::Parser {
|
||||
|
||||
std::string m_fail_in;
|
||||
|
||||
public:
|
||||
|
||||
MockParser(osmium::io::detail::future_string_queue_type& input_queue,
|
||||
osmium::io::detail::future_buffer_queue_type& output_queue,
|
||||
std::promise<osmium::io::Header>& header_promise,
|
||||
osmium::osm_entity_bits::type read_types,
|
||||
const std::string& fail_in) :
|
||||
Parser(input_queue, output_queue, header_promise, read_types),
|
||||
m_fail_in(fail_in) {
|
||||
}
|
||||
|
||||
osmium::memory::Buffer create_testdata() {
|
||||
osmium::memory::Buffer buffer(1000);
|
||||
|
||||
{
|
||||
osmium::builder::NodeBuilder nb(buffer);
|
||||
nb.add_user("foo");
|
||||
}
|
||||
buffer.commit();
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void run() final {
|
||||
osmium::thread::set_thread_name("_osmium_mock_in");
|
||||
|
||||
if (m_fail_in == "header") {
|
||||
throw std::runtime_error("error in header");
|
||||
}
|
||||
|
||||
set_header_value(osmium::io::Header{});
|
||||
|
||||
send_to_output_queue(create_testdata());
|
||||
|
||||
if (m_fail_in == "read") {
|
||||
throw std::runtime_error("error in read");
|
||||
}
|
||||
}
|
||||
|
||||
}; // class MockParser
|
||||
|
||||
TEST_CASE("Test Reader using MockParser") {
|
||||
|
||||
std::string fail_in;
|
||||
|
||||
osmium::io::detail::ParserFactory::instance().register_parser(
|
||||
osmium::io::file_format::xml,
|
||||
[&](osmium::io::detail::future_string_queue_type& input_queue,
|
||||
osmium::io::detail::future_buffer_queue_type& output_queue,
|
||||
std::promise<osmium::io::Header>& header_promise,
|
||||
osmium::osm_entity_bits::type read_which_entities) {
|
||||
return std::unique_ptr<osmium::io::detail::Parser>(new MockParser(input_queue, output_queue, header_promise, read_which_entities, fail_in));
|
||||
});
|
||||
|
||||
SECTION("no failure") {
|
||||
fail_in = "";
|
||||
osmium::io::Reader reader(with_data_dir("t/io/data.osm"));
|
||||
auto header = reader.header();
|
||||
REQUIRE(reader.read());
|
||||
REQUIRE(!reader.read());
|
||||
REQUIRE(reader.eof());
|
||||
reader.close();
|
||||
}
|
||||
|
||||
SECTION("throw in header") {
|
||||
fail_in = "header";
|
||||
try {
|
||||
osmium::io::Reader reader(with_data_dir("t/io/data.osm"));
|
||||
reader.header();
|
||||
} catch (std::runtime_error& e) {
|
||||
REQUIRE(std::string{e.what()} == "error in header");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("throw in read") {
|
||||
fail_in = "read";
|
||||
osmium::io::Reader reader(with_data_dir("t/io/data.osm"));
|
||||
reader.header();
|
||||
try {
|
||||
reader.read();
|
||||
} catch (std::runtime_error& e) {
|
||||
REQUIRE(std::string{e.what()} == "error in read");
|
||||
}
|
||||
reader.close();
|
||||
}
|
||||
|
||||
SECTION("throw in user code") {
|
||||
fail_in = "";
|
||||
osmium::io::Reader reader(with_data_dir("t/io/data.osm"));
|
||||
reader.header();
|
||||
try {
|
||||
throw std::runtime_error("error in user code");
|
||||
} catch (std::runtime_error& e) {
|
||||
REQUIRE(std::string{e.what()} == "error in user code");
|
||||
}
|
||||
REQUIRE(reader.read());
|
||||
REQUIRE(!reader.read());
|
||||
REQUIRE(reader.eof());
|
||||
reader.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -33,9 +33,9 @@ TEST_CASE("String store") {
|
||||
}
|
||||
|
||||
SECTION("add zero-length string and longer strings") {
|
||||
const char* s1 = ss.add("");
|
||||
const char* s2 = ss.add("xxx");
|
||||
const char* s3 = ss.add("yyyyy");
|
||||
ss.add("");
|
||||
ss.add("xxx");
|
||||
ss.add("yyyyy");
|
||||
|
||||
auto it = ss.begin();
|
||||
REQUIRE(std::string(*it++) == "");
|
||||
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
#include "catch.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <osmium/io/any_compression.hpp>
|
||||
#include <osmium/io/xml_input.hpp>
|
||||
#include <osmium/io/xml_output.hpp>
|
||||
#include <osmium/io/output_iterator.hpp>
|
||||
#include <osmium/memory/buffer.hpp>
|
||||
|
||||
TEST_CASE("Writer") {
|
||||
|
||||
osmium::io::Header header;
|
||||
header.set("generator", "test_writer.cpp");
|
||||
|
||||
osmium::io::Reader reader(with_data_dir("t/io/data.osm"));
|
||||
osmium::memory::Buffer buffer = reader.read();
|
||||
REQUIRE(buffer);
|
||||
REQUIRE(buffer.committed() > 0);
|
||||
auto num = std::distance(buffer.cbegin<osmium::OSMObject>(), buffer.cend<osmium::OSMObject>());
|
||||
REQUIRE(num > 0);
|
||||
REQUIRE(buffer.cbegin<osmium::OSMObject>()->id() == 1);
|
||||
|
||||
std::string filename;
|
||||
|
||||
SECTION("Empty writes") {
|
||||
|
||||
SECTION("Empty buffer") {
|
||||
filename = "test-writer-out-empty-buffer.osm";
|
||||
osmium::io::Writer writer(filename, header, osmium::io::overwrite::allow);
|
||||
osmium::memory::Buffer empty_buffer(1024);
|
||||
writer(std::move(empty_buffer));
|
||||
writer.close();
|
||||
}
|
||||
|
||||
SECTION("Invalid buffer") {
|
||||
filename = "test-writer-out-invalid-buffer.osm";
|
||||
osmium::io::Writer writer(filename, header, osmium::io::overwrite::allow);
|
||||
osmium::memory::Buffer invalid_buffer;
|
||||
writer(std::move(invalid_buffer));
|
||||
writer.close();
|
||||
}
|
||||
|
||||
osmium::io::Reader reader_check(filename);
|
||||
osmium::memory::Buffer buffer_check = reader_check.read();
|
||||
REQUIRE(!buffer_check);
|
||||
}
|
||||
|
||||
SECTION("Successfull writes") {
|
||||
|
||||
SECTION("Writer buffer") {
|
||||
filename = "test-writer-out-buffer.osm";
|
||||
osmium::io::Writer writer(filename, header, osmium::io::overwrite::allow);
|
||||
writer(std::move(buffer));
|
||||
writer.close();
|
||||
|
||||
REQUIRE_THROWS_AS({
|
||||
writer(osmium::memory::Buffer{});
|
||||
}, osmium::io_error);
|
||||
}
|
||||
|
||||
SECTION("Writer item") {
|
||||
filename = "test-writer-out-item.osm";
|
||||
osmium::io::Writer writer(filename, header, osmium::io::overwrite::allow);
|
||||
for (const auto& item : buffer) {
|
||||
writer(item);
|
||||
}
|
||||
writer.close();
|
||||
}
|
||||
|
||||
SECTION("Writer output iterator") {
|
||||
filename = "test-writer-out-iterator.osm";
|
||||
osmium::io::Writer writer(filename, header, osmium::io::overwrite::allow);
|
||||
auto it = osmium::io::make_output_iterator(writer);
|
||||
std::copy(buffer.cbegin(), buffer.cend(), it);
|
||||
writer.close();
|
||||
}
|
||||
|
||||
osmium::io::Reader reader_check(filename);
|
||||
osmium::memory::Buffer buffer_check = reader_check.read();
|
||||
REQUIRE(buffer_check);
|
||||
REQUIRE(buffer_check.committed() > 0);
|
||||
REQUIRE(std::distance(buffer_check.cbegin<osmium::OSMObject>(), buffer_check.cend<osmium::OSMObject>()) == num);
|
||||
REQUIRE(buffer_check.cbegin<osmium::OSMObject>()->id() == 1);
|
||||
|
||||
}
|
||||
|
||||
SECTION("Interrupted write") {
|
||||
|
||||
int error = 0;
|
||||
try {
|
||||
|
||||
SECTION("fail after open") {
|
||||
filename = "test-writer-out-fail1.osm";
|
||||
osmium::io::Writer writer(filename, header, osmium::io::overwrite::allow);
|
||||
throw 1;
|
||||
}
|
||||
|
||||
SECTION("fail after write") {
|
||||
filename = "test-writer-out-fail2.osm";
|
||||
osmium::io::Writer writer(filename, header, osmium::io::overwrite::allow);
|
||||
writer(std::move(buffer));
|
||||
throw 2;
|
||||
}
|
||||
|
||||
} catch (int e) {
|
||||
error = e;
|
||||
}
|
||||
|
||||
REQUIRE(error > 0);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
|
||||
#include "catch.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include <osmium/io/compression.hpp>
|
||||
#include <osmium/io/xml_input.hpp>
|
||||
#include <osmium/io/xml_output.hpp>
|
||||
|
||||
class MockCompressor : public osmium::io::Compressor {
|
||||
|
||||
std::string m_fail_in;
|
||||
|
||||
public:
|
||||
|
||||
MockCompressor(const std::string& fail_in) :
|
||||
Compressor(osmium::io::fsync::no),
|
||||
m_fail_in(fail_in) {
|
||||
if (m_fail_in == "constructor") {
|
||||
throw std::logic_error("constructor");
|
||||
}
|
||||
}
|
||||
|
||||
~MockCompressor() noexcept final = default;
|
||||
|
||||
void write(const std::string&) final {
|
||||
if (m_fail_in == "write") {
|
||||
throw std::logic_error("write");
|
||||
}
|
||||
}
|
||||
|
||||
void close() final {
|
||||
if (m_fail_in == "close") {
|
||||
throw std::logic_error("close");
|
||||
}
|
||||
}
|
||||
|
||||
}; // class MockCompressor
|
||||
|
||||
TEST_CASE("Write with mock compressor") {
|
||||
|
||||
std::string fail_in;
|
||||
|
||||
osmium::io::CompressionFactory::instance().register_compression(osmium::io::file_compression::gzip,
|
||||
[&](int, osmium::io::fsync) { return new MockCompressor(fail_in); },
|
||||
[](int) { return nullptr; },
|
||||
[](const char*, size_t) { return nullptr; }
|
||||
);
|
||||
|
||||
osmium::io::Header header;
|
||||
header.set("generator", "test_writer_with_mock_compression.cpp");
|
||||
|
||||
osmium::io::Reader reader(with_data_dir("t/io/data.osm"));
|
||||
osmium::memory::Buffer buffer = reader.read();
|
||||
REQUIRE(buffer);
|
||||
REQUIRE(buffer.committed() > 0);
|
||||
auto num = std::distance(buffer.cbegin<osmium::OSMObject>(), buffer.cend<osmium::OSMObject>());
|
||||
REQUIRE(num > 0);
|
||||
|
||||
SECTION("fail on construction") {
|
||||
|
||||
fail_in = "constructor";
|
||||
|
||||
REQUIRE_THROWS_AS({
|
||||
osmium::io::Writer writer("test-writer-mock-fail-on-construction.osm.gz", header, osmium::io::overwrite::allow);
|
||||
writer(std::move(buffer));
|
||||
writer.close();
|
||||
}, std::logic_error);
|
||||
|
||||
}
|
||||
|
||||
SECTION("fail on write") {
|
||||
|
||||
fail_in = "write";
|
||||
|
||||
REQUIRE_THROWS_AS({
|
||||
osmium::io::Writer writer("test-writer-mock-fail-on-write.osm.gz", header, osmium::io::overwrite::allow);
|
||||
writer(std::move(buffer));
|
||||
writer.close();
|
||||
}, std::logic_error);
|
||||
|
||||
}
|
||||
|
||||
SECTION("fail on close") {
|
||||
|
||||
fail_in = "close";
|
||||
|
||||
REQUIRE_THROWS_AS({
|
||||
osmium::io::Writer writer("test-writer-mock-fail-on-close.osm.gz", header, osmium::io::overwrite::allow);
|
||||
writer(std::move(buffer));
|
||||
writer.close();
|
||||
}, std::logic_error);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
|
||||
#include "catch.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include <osmium/io/compression.hpp>
|
||||
#include <osmium/io/detail/output_format.hpp>
|
||||
#include <osmium/io/detail/queue_util.hpp>
|
||||
#include <osmium/io/xml_input.hpp>
|
||||
#include <osmium/io/writer.hpp>
|
||||
|
||||
class MockOutputFormat : public osmium::io::detail::OutputFormat {
|
||||
|
||||
std::string m_fail_in;
|
||||
|
||||
public:
|
||||
|
||||
MockOutputFormat(const osmium::io::File&, osmium::io::detail::future_string_queue_type& output_queue, const std::string& fail_in) :
|
||||
OutputFormat(output_queue),
|
||||
m_fail_in(fail_in) {
|
||||
}
|
||||
|
||||
void write_header(const osmium::io::Header&) final {
|
||||
if (m_fail_in == "header") {
|
||||
throw std::logic_error("header");
|
||||
}
|
||||
send_to_output_queue(std::string{"header"});
|
||||
}
|
||||
|
||||
void write_buffer(osmium::memory::Buffer&&) final {
|
||||
if (m_fail_in == "write") {
|
||||
throw std::logic_error("write");
|
||||
}
|
||||
send_to_output_queue(std::string{"write"});
|
||||
}
|
||||
|
||||
void write_end() final {
|
||||
if (m_fail_in == "write_end") {
|
||||
throw std::logic_error("write_end");
|
||||
}
|
||||
send_to_output_queue(std::string{"end"});
|
||||
}
|
||||
|
||||
}; // class MockOutputFormat
|
||||
|
||||
TEST_CASE("Test Writer with MockOutputFormat") {
|
||||
|
||||
std::string fail_in;
|
||||
|
||||
osmium::io::detail::OutputFormatFactory::instance().register_output_format(
|
||||
osmium::io::file_format::xml,
|
||||
[&](const osmium::io::File& file, osmium::io::detail::future_string_queue_type& output_queue) {
|
||||
return new MockOutputFormat(file, output_queue, fail_in);
|
||||
});
|
||||
|
||||
osmium::io::Header header;
|
||||
header.set("generator", "test_writer_with_mock_encoder.cpp");
|
||||
|
||||
osmium::io::Reader reader(with_data_dir("t/io/data.osm"));
|
||||
osmium::memory::Buffer buffer = reader.read();
|
||||
REQUIRE(buffer);
|
||||
REQUIRE(buffer.committed() > 0);
|
||||
auto num = std::distance(buffer.cbegin<osmium::OSMObject>(), buffer.cend<osmium::OSMObject>());
|
||||
REQUIRE(num > 0);
|
||||
|
||||
SECTION("error in header") {
|
||||
|
||||
fail_in = "header";
|
||||
|
||||
REQUIRE_THROWS_AS({
|
||||
osmium::io::Writer writer("test-writer-mock-fail-on-construction.osm", header, osmium::io::overwrite::allow);
|
||||
writer(std::move(buffer));
|
||||
writer.close();
|
||||
}, std::logic_error);
|
||||
|
||||
}
|
||||
|
||||
SECTION("error in write") {
|
||||
|
||||
fail_in = "write";
|
||||
|
||||
REQUIRE_THROWS_AS({
|
||||
osmium::io::Writer writer("test-writer-mock-fail-on-construction.osm", header, osmium::io::overwrite::allow);
|
||||
writer(std::move(buffer));
|
||||
writer.close();
|
||||
}, std::logic_error);
|
||||
|
||||
}
|
||||
|
||||
SECTION("error in write_end") {
|
||||
|
||||
fail_in = "write_end";
|
||||
|
||||
REQUIRE_THROWS_AS({
|
||||
osmium::io::Writer writer("test-writer-mock-fail-on-construction.osm", header, osmium::io::overwrite::allow);
|
||||
writer(std::move(buffer));
|
||||
writer.close();
|
||||
}, std::logic_error);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -100,3 +100,14 @@ TEST_CASE("empty keys and values are okay") {
|
||||
REQUIRE(std::string("") == tl.get_value_by_key("empty value"));
|
||||
REQUIRE(std::string("empty key") == tl.get_value_by_key(""));
|
||||
}
|
||||
|
||||
TEST_CASE("tag key or value is too long") {
|
||||
osmium::memory::Buffer buffer(10240);
|
||||
osmium::builder::TagListBuilder builder(buffer);
|
||||
|
||||
const char kv[2000] = "";
|
||||
builder.add_tag(kv, 1, kv, 1000);
|
||||
REQUIRE_THROWS(builder.add_tag(kv, 1500, kv, 1));
|
||||
REQUIRE_THROWS(builder.add_tag(kv, 1, kv, 1500));
|
||||
}
|
||||
|
||||
|
||||
+33
-29
@@ -5,14 +5,7 @@
|
||||
#include <thread>
|
||||
|
||||
#include <osmium/thread/pool.hpp>
|
||||
|
||||
static std::atomic<int> result;
|
||||
|
||||
struct test_job_ok {
|
||||
void operator()() const {
|
||||
result = 1;
|
||||
}
|
||||
};
|
||||
#include <osmium/util/compatibility.hpp>
|
||||
|
||||
struct test_job_with_result {
|
||||
int operator()() const {
|
||||
@@ -21,44 +14,55 @@ struct test_job_with_result {
|
||||
};
|
||||
|
||||
struct test_job_throw {
|
||||
void operator()() const {
|
||||
OSMIUM_NORETURN void operator()() const {
|
||||
throw std::runtime_error("exception in pool thread");
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE("number of threads in pool") {
|
||||
|
||||
// hardcoded setting
|
||||
REQUIRE(osmium::thread::detail::get_pool_size( 1, 0, 2) == 1);
|
||||
REQUIRE(osmium::thread::detail::get_pool_size( 4, 0, 2) == 4);
|
||||
REQUIRE(osmium::thread::detail::get_pool_size( 4, 0, 4) == 4);
|
||||
REQUIRE(osmium::thread::detail::get_pool_size(16, 0, 4) == 16);
|
||||
REQUIRE(osmium::thread::detail::get_pool_size(16, 0, 16) == 16);
|
||||
REQUIRE(osmium::thread::detail::get_pool_size( 8, 4, 2) == 8);
|
||||
REQUIRE(osmium::thread::detail::get_pool_size( 8, 16, 2) == 8);
|
||||
REQUIRE(osmium::thread::detail::get_pool_size(-2, 16, 2) == 1);
|
||||
REQUIRE(osmium::thread::detail::get_pool_size(-2, 16, 8) == 6);
|
||||
|
||||
// user decides through OSMIUM_POOL_THREADS env variable
|
||||
REQUIRE(osmium::thread::detail::get_pool_size( 0, 0, 2) == 1);
|
||||
REQUIRE(osmium::thread::detail::get_pool_size( 0, -2, 4) == 2);
|
||||
REQUIRE(osmium::thread::detail::get_pool_size( 0, -1, 8) == 7);
|
||||
REQUIRE(osmium::thread::detail::get_pool_size( 0, 0, 16) == 14);
|
||||
REQUIRE(osmium::thread::detail::get_pool_size( 0, 1, 16) == 1);
|
||||
REQUIRE(osmium::thread::detail::get_pool_size( 0, 2, 16) == 2);
|
||||
REQUIRE(osmium::thread::detail::get_pool_size( 0, 4, 16) == 4);
|
||||
REQUIRE(osmium::thread::detail::get_pool_size( 0, 8, 16) == 8);
|
||||
|
||||
// outliers
|
||||
REQUIRE(osmium::thread::detail::get_pool_size(-100, 0, 16) == 1);
|
||||
REQUIRE(osmium::thread::detail::get_pool_size(1000, 0, 16) == 256);
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("thread") {
|
||||
|
||||
auto& pool = osmium::thread::Pool::instance();
|
||||
|
||||
SECTION("can get access to thread pool") {
|
||||
auto& pool = osmium::thread::Pool::instance();
|
||||
REQUIRE(pool.queue_empty());
|
||||
}
|
||||
|
||||
SECTION("can send job to thread pool") {
|
||||
auto& pool = osmium::thread::Pool::instance();
|
||||
result = 0;
|
||||
auto future = pool.submit(test_job_ok {});
|
||||
|
||||
// wait a bit for the other thread to get a chance to run
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
|
||||
REQUIRE(result == 1);
|
||||
|
||||
future.get();
|
||||
|
||||
REQUIRE(true);
|
||||
}
|
||||
|
||||
SECTION("can send job to thread pool") {
|
||||
auto& pool = osmium::thread::Pool::instance();
|
||||
auto future = pool.submit(test_job_with_result {});
|
||||
|
||||
REQUIRE(future.get() == 42);
|
||||
}
|
||||
|
||||
SECTION("can throw from job in thread pool") {
|
||||
auto& pool = osmium::thread::Pool::instance();
|
||||
result = 0;
|
||||
|
||||
auto future = pool.submit(test_job_throw {});
|
||||
|
||||
REQUIRE_THROWS_AS(future.get(), std::runtime_error);
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <osmium/util/data_file.hpp>
|
||||
|
||||
TEST_CASE("temporary file") {
|
||||
|
||||
SECTION("create/open") {
|
||||
osmium::util::DataFile file;
|
||||
|
||||
REQUIRE(!!file);
|
||||
int fd = file.fd();
|
||||
|
||||
REQUIRE(fd > 0);
|
||||
|
||||
const char buf[] = "foobar";
|
||||
REQUIRE(::write(fd, buf, sizeof(buf)) == sizeof(buf));
|
||||
|
||||
file.close();
|
||||
|
||||
REQUIRE(!file);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("named file") {
|
||||
|
||||
SECTION("create/open") {
|
||||
{
|
||||
osmium::util::DataFile file("test.data", true);
|
||||
|
||||
REQUIRE(!!file);
|
||||
int fd = file.fd();
|
||||
|
||||
REQUIRE(fd > 0);
|
||||
|
||||
REQUIRE(file.size() == 0);
|
||||
|
||||
const char buf[] = "foobar";
|
||||
REQUIRE(::write(fd, buf, sizeof(buf) - 1) == sizeof(buf) - 1);
|
||||
|
||||
file.close();
|
||||
|
||||
REQUIRE(!file);
|
||||
}
|
||||
{
|
||||
osmium::util::DataFile file("test.data", false);
|
||||
|
||||
REQUIRE(!!file);
|
||||
int fd = file.fd();
|
||||
|
||||
REQUIRE(fd > 0);
|
||||
|
||||
REQUIRE(file.size() == 6);
|
||||
|
||||
char buf[10];
|
||||
int len = ::read(fd, buf, sizeof(buf));
|
||||
|
||||
REQUIRE(len == 6);
|
||||
REQUIRE(!strncmp(buf, "foobar", 6));
|
||||
|
||||
file.close();
|
||||
|
||||
REQUIRE(!file);
|
||||
REQUIRE(unlink("test.data") == 0);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("grow file") {
|
||||
osmium::util::DataFile file("test.data", true);
|
||||
|
||||
REQUIRE(!!file);
|
||||
|
||||
REQUIRE(file.size() == 0);
|
||||
file.grow(10);
|
||||
REQUIRE(file.size() == 10);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+30
-4
@@ -4,24 +4,50 @@
|
||||
|
||||
#include <osmium/util/delta.hpp>
|
||||
|
||||
TEST_CASE("delta encode") {
|
||||
TEST_CASE("delta encode int") {
|
||||
|
||||
osmium::util::DeltaEncode<int> x;
|
||||
|
||||
SECTION("int") {
|
||||
REQUIRE(x.update(17) == 17);
|
||||
REQUIRE(x.update(10) == -7);
|
||||
REQUIRE(x.update(-10) == -20);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("delta decode") {
|
||||
TEST_CASE("delta decode int") {
|
||||
|
||||
osmium::util::DeltaDecode<int> x;
|
||||
|
||||
SECTION("int") {
|
||||
REQUIRE(x.update(17) == 17);
|
||||
REQUIRE(x.update(10) == 27);
|
||||
REQUIRE(x.update(-40) == -13);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("delta encode unsigned int") {
|
||||
|
||||
osmium::util::DeltaEncode<unsigned int> x;
|
||||
|
||||
SECTION("int") {
|
||||
REQUIRE(x.update(17) == 17);
|
||||
REQUIRE(x.update(10) == -7);
|
||||
REQUIRE(x.update(0) == -10);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("delta decode unsigned int") {
|
||||
|
||||
osmium::util::DeltaDecode<unsigned int> x;
|
||||
|
||||
SECTION("int") {
|
||||
REQUIRE(x.update(17) == 17);
|
||||
REQUIRE(x.update(10) == 27);
|
||||
REQUIRE(x.update(-15) == 12);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,13 +56,13 @@ TEST_CASE("delta encode and decode") {
|
||||
|
||||
std::vector<int> a = { 5, -9, 22, 13, 0, 23 };
|
||||
|
||||
osmium::util::DeltaEncode<int> de;
|
||||
osmium::util::DeltaEncode<int, int> de;
|
||||
std::vector<int> b;
|
||||
for (int x : a) {
|
||||
b.push_back(de.update(x));
|
||||
}
|
||||
|
||||
osmium::util::DeltaDecode<int> dd;
|
||||
osmium::util::DeltaDecode<int, int> dd;
|
||||
std::vector<int> c;
|
||||
for (int x : b) {
|
||||
c.push_back(dd.update(x));
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <osmium/util/file.hpp>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <crtdbg.h>
|
||||
// https://msdn.microsoft.com/en-us/library/ksazx244.aspx
|
||||
// https://msdn.microsoft.com/en-us/library/a9yf33zb.aspx
|
||||
class DoNothingInvalidParameterHandler {
|
||||
@@ -23,6 +24,7 @@ public:
|
||||
|
||||
DoNothingInvalidParameterHandler() :
|
||||
old_handler(_set_invalid_parameter_handler(invalid_parameter_handler)) {
|
||||
_CrtSetReportMode(_CRT_ASSERT, 0);
|
||||
}
|
||||
|
||||
~DoNothingInvalidParameterHandler() {
|
||||
|
||||
+41
-8
@@ -6,43 +6,76 @@
|
||||
|
||||
TEST_CASE("Options") {
|
||||
|
||||
SECTION("set_simple") {
|
||||
osmium::util::Options o;
|
||||
osmium::util::Options o;
|
||||
|
||||
SECTION("set a single value from string") {
|
||||
o.set("foo", "bar");
|
||||
REQUIRE("bar" == o.get("foo"));
|
||||
REQUIRE("" == o.get("empty"));
|
||||
REQUIRE("default" == o.get("empty", "default"));
|
||||
|
||||
REQUIRE(!o.is_true("foo"));
|
||||
REQUIRE(!o.is_true("empty"));
|
||||
|
||||
REQUIRE(o.is_not_false("foo"));
|
||||
REQUIRE(o.is_not_false("empty"));
|
||||
|
||||
REQUIRE(1 == o.size());
|
||||
}
|
||||
|
||||
SECTION("set_from_bool") {
|
||||
osmium::util::Options o;
|
||||
SECTION("set values from booleans") {
|
||||
o.set("t", true);
|
||||
o.set("f", false);
|
||||
REQUIRE("true" == o.get("t"));
|
||||
REQUIRE("false" == o.get("f"));
|
||||
REQUIRE("" == o.get("empty"));
|
||||
|
||||
REQUIRE(o.is_true("t"));
|
||||
REQUIRE(!o.is_true("f"));
|
||||
|
||||
REQUIRE(o.is_not_false("t"));
|
||||
REQUIRE(!o.is_not_false("f"));
|
||||
|
||||
REQUIRE(2 == o.size());
|
||||
}
|
||||
|
||||
SECTION("set_from_single_string_with_equals") {
|
||||
osmium::util::Options o;
|
||||
SECTION("set value from string with equal sign") {
|
||||
o.set("foo=bar");
|
||||
REQUIRE("bar" == o.get("foo"));
|
||||
REQUIRE(1 == o.size());
|
||||
}
|
||||
|
||||
SECTION("set_from_single_string_without_equals") {
|
||||
osmium::util::Options o;
|
||||
SECTION("set value from string without equal sign") {
|
||||
o.set("foo");
|
||||
REQUIRE("true" == o.get("foo"));
|
||||
|
||||
REQUIRE(o.is_true("foo"));
|
||||
REQUIRE(o.is_not_false("foo"));
|
||||
|
||||
REQUIRE(1 == o.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Options with initializer list") {
|
||||
|
||||
osmium::util::Options o{ { "foo", "true" }, { "bar", "17" } };
|
||||
|
||||
REQUIRE(o.get("foo") == "true");
|
||||
REQUIRE(o.get("bar") == "17");
|
||||
REQUIRE(o.is_true("foo"));
|
||||
REQUIRE_FALSE(o.is_true("bar"));
|
||||
REQUIRE(o.size() == 2);
|
||||
|
||||
SECTION("Change existing value") {
|
||||
o.set("foo", "false");
|
||||
REQUIRE_FALSE(o.is_true("foo"));
|
||||
}
|
||||
|
||||
SECTION("Add new value") {
|
||||
o.set("new", "something");
|
||||
REQUIRE_FALSE(o.is_true("new"));
|
||||
REQUIRE(o.get("new") == "something");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user