Skip to content
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Build
run-name: ${{github.actor}} build
on:
push:
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install -y build-essential cmake clang clang-tidy libexpat1-dev zlib1g-dev
- name: Configure
run: cmake -Bbuild -S. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
- name: Build
run: cmake --build build -- -j$(nproc)

3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# artifacts
build
install
/.cache

# ide
.vscode
*.user
*.user
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

this is an error

# Toggle integration tests
option(INPUTOSM_INTEGRATION_TESTS "Build integration tests" ON)
option(WARNINGS_AS_ERRORS "Treat warnings as errors" ON)
Expand Down
1 change: 1 addition & 0 deletions src/inputosmlog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <cstdarg>
#include <cstdio>
#include <cstring>
#include <cstdlib>

constexpr const char* kError = "err";
constexpr const char* kInfo = "inf";
Expand Down
2 changes: 1 addition & 1 deletion src/inputosmpbf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct field_t

struct string_table_t
{
std::vector<uint32_t> st_index;
std::vector<std::size_t> st_index;
std::vector<uint8_t> st_buffer;

void clear()
Expand Down
62 changes: 50 additions & 12 deletions src/inputosmxml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "inputosmlog.h"
#include "timeutil.h"

#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
Expand Down Expand Up @@ -46,9 +47,13 @@ enum class current_tag_t
};
current_tag_t current_tag;
std::vector<std::string> current_strings;
std::vector<tag_t> current_tags;
std::vector<std::pair<int, int>> current_tags;
std::vector<int64_t> current_refs;
std::vector<relation_member_t> current_members;
struct ext_relation_member_t : relation_member_t
{
int role_index = -1;
};
std::vector<ext_relation_member_t> current_members;

static void xml_start_node(const char **attr)
{
Expand Down Expand Up @@ -80,7 +85,14 @@ static void xml_end_node()
{
// node end
current_tag = current_tag_t::none;
current_node.tags = {current_tags.data(), current_tags.size()};
// assemble tags
std::vector<tag_t> tags;
for (std::size_t i = 0; i < current_tags.size(); i++)
{
tags.emplace_back(
tag_t{current_strings[current_tags[i].first].c_str(), current_strings[current_tags[i].second].c_str()});
}
current_node.tags = {tags.data(), tags.size()};
if (parser_enabled && node_handler) parser_enabled = node_handler({&current_node, 1});
current_tags.clear();
current_strings.clear();
Expand All @@ -104,7 +116,14 @@ static void xml_end_way()
{
// way end
current_tag = current_tag_t::none;
current_way.tags = {current_tags.data(), current_tags.size()};
// assemble tags
std::vector<tag_t> tags;
for (std::size_t i = 0; i < current_tags.size(); i++)
{
tags.emplace_back(
tag_t{current_strings[current_tags[i].first].c_str(), current_strings[current_tags[i].second].c_str()});
}
current_way.tags = {tags.data(), tags.size()};
current_way.node_refs = {current_refs.data(), current_refs.size()};
if (parser_enabled && way_handler) parser_enabled = way_handler({&current_way, 1});
current_tags.clear();
Expand All @@ -130,8 +149,22 @@ static void xml_end_relation()
{
// end relation
current_tag = current_tag_t::none;
current_relation.tags = {current_tags.data(), current_tags.size()};
current_relation.members = {current_members.data(), current_members.size()};
// assemble tags
std::vector<tag_t> tags;
for (std::size_t i = 0; i < current_tags.size(); i++)
{
tags.emplace_back(
tag_t{current_strings[current_tags[i].first].c_str(), current_strings[current_tags[i].second].c_str()});
}
current_relation.tags = {tags.data(), tags.size()};
// assemble members
std::vector<relation_member_t> members;
for (const auto &m : current_members)
{
members.emplace_back(
relation_member_t{m.type, m.id, m.role_index >= 0 ? current_strings[m.role_index].c_str() : nullptr});
}
current_relation.members = {members.data(), members.size()};
if (parser_enabled && relation_handler) parser_enabled = relation_handler({&current_relation, 1});
current_tags.clear();
current_strings.clear();
Expand All @@ -150,7 +183,7 @@ static void xml_start_xtag(const char **attr)
if (strcmp(attr[i], "v") == 0) current_strings.emplace_back(attr[i + 1]);
}
for (auto i = istart; i < current_strings.size(); i += 2)
current_tags.emplace_back(tag_t{current_strings[i].c_str(), current_strings[i + 1].c_str()});
current_tags.emplace_back(std::pair<int, int>{i, i + 1});
}
}

Expand All @@ -171,27 +204,32 @@ static void xml_start_member(const char **attr)
// member start
if (current_tag == current_tag_t::relation)
{
relation_member_t member;
ext_relation_member_t member;
for (int i = 0; attr[i]; i += 2)
{
if (strcmp(attr[i], "ref") == 0) member.id = atoll(attr[i + 1]);
if (strcmp(attr[i], "type") == 0)
{
if (strcmp(attr[i + 1], "node") == 0) member.type = 0;
if (strcmp(attr[i + 1], "way") == 0) member.type = 2;
if (strcmp(attr[i + 1], "way") == 0) member.type = 1;
if (strcmp(attr[i + 1], "relation") == 0) member.type = 2;
}
if (strcmp(attr[i], "role") == 0)
{
current_strings.emplace_back(attr[i + 1]);
member.role = current_strings.back().c_str();
member.role_index = current_strings.size() - 1;
}
}
if (member.role_index < 0)
{
current_strings.emplace_back();
member.role_index = current_strings.size() - 1;
}
current_members.emplace_back(member);
}
}

static void xml_start_tag(void */*data*/, const char *el, const char **attr)
static void xml_start_tag(void * /*data*/, const char *el, const char **attr)
{
// XML tag start
if (strcmp(el, "node") == 0) xml_start_node(attr);
Expand All @@ -207,7 +245,7 @@ static void xml_start_tag(void */*data*/, const char *el, const char **attr)
if (strcmp(el, "delete") == 0) osc_mode = mode_t::destroy;
}

static void xml_end_tag(void */*data*/, const char *el)
static void xml_end_tag(void * /*data*/, const char *el)
{
// XML tag end
if (strcmp(el, "node") == 0) xml_end_node();
Expand Down
23 changes: 16 additions & 7 deletions src/timeutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@

#include "timeutil.h"
#include <chrono>
#include <inttypes.h>
#include <ctime>
#include <cinttypes>

int64_t now_ms()
{
Expand All @@ -29,16 +30,24 @@ int64_t now_us()

time_t str_to_timestamp(const char* str)
{
struct tm timeinfo;
strptime(str, "%FT%TZ", &timeinfo);
return mktime(&timeinfo);
struct tm timeinfo{};
if (strptime(str, "%FT%TZ", &timeinfo) == nullptr)
{
return 0;
}
return timegm(&timeinfo);
}

time_t str_to_timestamp_osmstate(const char* str)
{
struct tm timeinfo;
strptime(str, "%FT%H\\:%M\\:%SZ", &timeinfo);
return mktime(&timeinfo);
struct tm timeinfo{};
if (strptime(str, "%FT%H\\:%M\\:%SZ", &timeinfo) == nullptr)
{
return 0;
}
return timegm(&timeinfo);
}

std::string timestamp_to_str(const time_t rawtime)
{
struct tm* dt;
Expand Down
Loading