Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Boost Json #1129

Draft
wants to merge 19 commits into
base: master
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion .github/workflows/vroom.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install libasio-dev libglpk-dev jq
sudo apt-get install libasio-dev libglpk-dev libboost-json1.83-dev jq
- name: Build vroom
run: make -j
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/vroom_libosrm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install libasio-dev libglpk-dev
sudo apt-get install libasio-dev libglpk-dev libboost-json1.83-dev
- name: Cache OSRM
id: cache
uses: actions/cache@v4
Expand Down
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,3 @@
[submodule "include/polylineencoder"]
path = include/polylineencoder
url = https://github.com/vahancho/polylineencoder
[submodule "include/rapidjson"]
path = include/rapidjson
url = https://github.com/Tencent/rapidjson
1 change: 0 additions & 1 deletion include/rapidjson
Submodule rapidjson deleted from 973dc9
4 changes: 2 additions & 2 deletions libvroom_examples/makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CXX ?= g++
CXXFLAGS = -I../src -std=c++20 -Wextra -Wpedantic -Wall -O3
LDLIBS = -L../lib/ -lvroom -lpthread -lssl -lcrypto
CXXFLAGS = -I../src -std=c++20 -Wextra -Wpedantic -Wall -O3 -DBOOST_JSON_STANDALONE -DBOOST_JSON_NO_LIB
LDLIBS = -L../lib/ -lvroom -lpthread -lssl -lcrypto -lboost_json

# Checking for libglpk based on whether the header file is found as
# glpk does not provide a pkg-config setup.
Expand Down
4 changes: 2 additions & 2 deletions src/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
# Variables.
CXX ?= g++
USE_ROUTING ?= true
CXXFLAGS = -MMD -MP -I. -std=c++20 -Wextra -Wpedantic -Wall -O3 -DASIO_STANDALONE -DUSE_ROUTING=$(USE_ROUTING)
LDLIBS = -lpthread
CXXFLAGS = -MMD -MP -I. -std=c++20 -Wextra -Wpedantic -Wall -O3 -DASIO_STANDALONE -DBOOST_JSON_STANDALONE -DBOOST_JSON_NO_LIB -DUSE_ROUTING=$(USE_ROUTING)
LDLIBS = -lpthread -lboost_json

# Using all cpp files in current directory.
MAIN = ../bin/vroom
Expand Down
42 changes: 23 additions & 19 deletions src/routing/http_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,16 @@ std::string HttpWrapper::run_query(const std::string& query) const {
: send_then_receive(query);
}

void HttpWrapper::parse_response(rapidjson::Document& json_result,
void HttpWrapper::parse_response(boost::json::object& json_result,
const std::string& json_content) {
#ifdef NDEBUG
json_result.Parse(json_content.c_str());
json_result = boost::json::parse(json_content).as_object();
#else
assert(!json_result.Parse(json_content.c_str()).HasParseError());
boost::json::error_code ec;
auto content = boost::json::parse(json_content, ec);
boost::json::object* ptr = content.if_object();
assert(!ec && ptr);
json_result = content.get_object();
#endif
}

Expand All @@ -155,19 +159,19 @@ Matrices HttpWrapper::get_matrices(const std::vector<Location>& locs) const {
// Expected matrix size.
std::size_t m_size = locs.size();

rapidjson::Document json_result;
boost::json::object json_result;
this->parse_response(json_result, json_string);
this->check_response(json_result, locs, _matrix_service);

if (!json_result.HasMember(_matrix_durations_key.c_str())) {
if (!json_result.contains(_matrix_durations_key)) {
throw RoutingException("Missing " + _matrix_durations_key + ".");
}
assert(json_result[_matrix_durations_key.c_str()].Size() == m_size);
assert(json_result.at(_matrix_durations_key).get_array().size() == m_size);

if (!json_result.HasMember(_matrix_distances_key.c_str())) {
if (!json_result.contains(_matrix_distances_key)) {
throw RoutingException("Missing " + _matrix_distances_key + ".");
}
assert(json_result[_matrix_distances_key.c_str()].Size() == m_size);
assert(json_result.at(_matrix_distances_key).get_array().size() == m_size);

// Build matrices while checking for unfound routes ('null' values)
// to avoid unexpected behavior.
Expand All @@ -176,22 +180,22 @@ Matrices HttpWrapper::get_matrices(const std::vector<Location>& locs) const {
std::vector<unsigned> nb_unfound_from_loc(m_size, 0);
std::vector<unsigned> nb_unfound_to_loc(m_size, 0);

for (rapidjson::SizeType i = 0; i < m_size; ++i) {
const auto& duration_line = json_result[_matrix_durations_key.c_str()][i];
const auto& distance_line = json_result[_matrix_distances_key.c_str()][i];
assert(duration_line.Size() == m_size);
assert(distance_line.Size() == m_size);
for (rapidjson::SizeType j = 0; j < m_size; ++j) {
if (duration_value_is_null(duration_line[j]) ||
distance_value_is_null(distance_line[j])) {
for (size_t i = 0; i < m_size; ++i) {
const auto& duration_line = json_result.at(_matrix_durations_key).at(i);
const auto& distance_line = json_result.at(_matrix_distances_key).at(i);
assert(duration_line.get_array().size() == m_size);
assert(distance_line.get_array().size() == m_size);
for (size_t j = 0; j < m_size; ++j) {
if (duration_value_is_null(duration_line.at(j)) ||
distance_value_is_null(distance_line.at(j))) {
// No route found between i and j. Just storing info as we
// don't know yet which location is responsible between i
// and j.
++nb_unfound_from_loc[i];
++nb_unfound_to_loc[j];
} else {
m.durations[i][j] = get_duration_value(duration_line[j]);
m.distances[i][j] = get_distance_value(distance_line[j]);
m.durations[i][j] = get_duration_value(duration_line.at(j));
m.distances[i][j] = get_distance_value(distance_line.at(j));
}
}
}
Expand Down Expand Up @@ -219,7 +223,7 @@ void HttpWrapper::add_geometry(Route& route) const {

std::string json_string = this->run_query(query);

rapidjson::Document json_result;
boost::json::object json_result;
parse_response(json_result, json_string);
this->check_response(json_result,
non_break_locations, // not supposed to be used
Expand Down
18 changes: 9 additions & 9 deletions src/routing/http_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Copyright (c) 2015-2024, Julien Coupey.
All rights reserved (see LICENSE).

*/
#include "../include/rapidjson/include/rapidjson/document.h"
#include <boost/json.hpp>

#include "routing/wrapper.h"
#include "structures/typedefs.h"
Expand Down Expand Up @@ -42,33 +42,33 @@ class HttpWrapper : public Wrapper {

std::string run_query(const std::string& query) const;

static void parse_response(rapidjson::Document& json_result,
static void parse_response(boost::json::object& json_result,
const std::string& json_content);

virtual std::string build_query(const std::vector<Location>& locations,
const std::string& service) const = 0;

virtual void check_response(const rapidjson::Document& json_result,
virtual void check_response(const boost::json::object& json_result,
const std::vector<Location>& locs,
const std::string& service) const = 0;

Matrices get_matrices(const std::vector<Location>& locs) const override;

virtual bool
duration_value_is_null(const rapidjson::Value& matrix_entry) const = 0;
duration_value_is_null(const boost::json::value& matrix_entry) const = 0;

virtual bool
distance_value_is_null(const rapidjson::Value& matrix_entry) const = 0;
distance_value_is_null(const boost::json::value& matrix_entry) const = 0;

virtual UserDuration
get_duration_value(const rapidjson::Value& matrix_entry) const = 0;
get_duration_value(const boost::json::value& matrix_entry) const = 0;

virtual UserDistance
get_distance_value(const rapidjson::Value& matrix_entry) const = 0;
get_distance_value(const boost::json::value& matrix_entry) const = 0;

virtual unsigned get_legs_number(const rapidjson::Value& result) const = 0;
virtual unsigned get_legs_number(const boost::json::object& result) const = 0;

virtual std::string get_geometry(rapidjson::Value& result) const = 0;
virtual std::string get_geometry(boost::json::object& result) const = 0;

void add_geometry(Route& route) const override;
};
Expand Down
32 changes: 17 additions & 15 deletions src/routing/ors_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ All rights reserved (see LICENSE).
#include "routing/ors_wrapper.h"
#include "utils/helpers.h"

#include <iostream>

namespace vroom::routing {

OrsWrapper::OrsWrapper(const std::string& profile, const Server& server)
Expand Down Expand Up @@ -60,41 +62,41 @@ std::string OrsWrapper::build_query(const std::vector<Location>& locations,
return query;
}

void OrsWrapper::check_response(const rapidjson::Document& json_result,
void OrsWrapper::check_response(const boost::json::object& json_result,
const std::vector<Location>&,
const std::string&) const {
if (json_result.HasMember("error")) {
if (json_result.contains("error")) {
throw RoutingException(
std::string(json_result["error"]["message"].GetString()));
json_result.at("error").at("message").get_string().subview());
}
}

bool OrsWrapper::duration_value_is_null(
const rapidjson::Value& matrix_entry) const {
return matrix_entry.IsNull();
const boost::json::value& matrix_entry) const {
return matrix_entry.is_null();
}

bool OrsWrapper::distance_value_is_null(
const rapidjson::Value& matrix_entry) const {
return matrix_entry.IsNull();
const boost::json::value& matrix_entry) const {
return matrix_entry.is_null();
}

UserDuration
OrsWrapper::get_duration_value(const rapidjson::Value& matrix_entry) const {
return utils::round<UserDuration>(matrix_entry.GetDouble());
OrsWrapper::get_duration_value(const boost::json::value& matrix_entry) const {
return utils::round<UserDuration>(matrix_entry.to_number<double>());
}

UserDistance
OrsWrapper::get_distance_value(const rapidjson::Value& matrix_entry) const {
return utils::round<UserDistance>(matrix_entry.GetDouble());
OrsWrapper::get_distance_value(const boost::json::value& matrix_entry) const {
return utils::round<UserDuration>(matrix_entry.to_number<double>());
}

unsigned OrsWrapper::get_legs_number(const rapidjson::Value& result) const {
return result["routes"][0]["segments"].Size();
unsigned OrsWrapper::get_legs_number(const boost::json::object& result) const {
return result.at("routes").at(0).at("segments").get_array().size();
}

std::string OrsWrapper::get_geometry(rapidjson::Value& result) const {
return result["routes"][0]["geometry"].GetString();
std::string OrsWrapper::get_geometry(boost::json::object& result) const {
return result.at("routes").at(0).at("geometry").get_string().subview();
}

} // namespace vroom::routing
14 changes: 7 additions & 7 deletions src/routing/ors_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,25 @@ class OrsWrapper : public HttpWrapper {
std::string build_query(const std::vector<Location>& locations,
const std::string& service) const override;

void check_response(const rapidjson::Document& json_result,
void check_response(const boost::json::object& json_result,
const std::vector<Location>& locs,
const std::string& service) const override;

bool
duration_value_is_null(const rapidjson::Value& matrix_entry) const override;
duration_value_is_null(const boost::json::value& matrix_entry) const override;

bool
distance_value_is_null(const rapidjson::Value& matrix_entry) const override;
distance_value_is_null(const boost::json::value& matrix_entry) const override;

UserDuration
get_duration_value(const rapidjson::Value& matrix_entry) const override;
get_duration_value(const boost::json::value& matrix_entry) const override;

UserDistance
get_distance_value(const rapidjson::Value& matrix_entry) const override;
get_distance_value(const boost::json::value& matrix_entry) const override;

unsigned get_legs_number(const rapidjson::Value& result) const override;
unsigned get_legs_number(const boost::json::object& result) const override;

std::string get_geometry(rapidjson::Value& result) const override;
std::string get_geometry(boost::json::object& result) const override;

public:
OrsWrapper(const std::string& profile, const Server& server);
Expand Down
33 changes: 17 additions & 16 deletions src/routing/osrm_routed_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,14 @@ OsrmRoutedWrapper::build_query(const std::vector<Location>& locations,
return query;
}

void OsrmRoutedWrapper::check_response(const rapidjson::Document& json_result,
void OsrmRoutedWrapper::check_response(const boost::json::object& json_result,
const std::vector<Location>& locs,
const std::string&) const {
assert(json_result.HasMember("code"));
const std::string code = json_result["code"].GetString();
assert(json_result.contains("code"));
const std::string code = json_result.at("code").get_string().subview();
if (code != "Ok") {
const std::string message = json_result["message"].GetString();
const std::string message =
json_result.at("message").get_string().subview();
if (const std::string snapping_error_base =
"Could not find a matching segment for coordinate ";
code == "NoSegment" && message.starts_with(snapping_error_base)) {
Expand All @@ -87,32 +88,32 @@ void OsrmRoutedWrapper::check_response(const rapidjson::Document& json_result,
}

bool OsrmRoutedWrapper::duration_value_is_null(
const rapidjson::Value& matrix_entry) const {
return matrix_entry.IsNull();
const boost::json::value& matrix_entry) const {
return matrix_entry.is_null();
}

bool OsrmRoutedWrapper::distance_value_is_null(
const rapidjson::Value& matrix_entry) const {
return matrix_entry.IsNull();
const boost::json::value& matrix_entry) const {
return matrix_entry.is_null();
}

UserDuration OsrmRoutedWrapper::get_duration_value(
const rapidjson::Value& matrix_entry) const {
return utils::round<UserDuration>(matrix_entry.GetDouble());
const boost::json::value& matrix_entry) const {
return utils::round<UserDuration>(matrix_entry.to_number<double>());
}

UserDistance OsrmRoutedWrapper::get_distance_value(
const rapidjson::Value& matrix_entry) const {
return utils::round<UserDistance>(matrix_entry.GetDouble());
const boost::json::value& matrix_entry) const {
return utils::round<UserDuration>(matrix_entry.to_number<double>());
}

unsigned
OsrmRoutedWrapper::get_legs_number(const rapidjson::Value& result) const {
return result["routes"][0]["legs"].Size();
OsrmRoutedWrapper::get_legs_number(const boost::json::object& result) const {
return result.at("routes").at(0).at("legs").get_array().size();
}

std::string OsrmRoutedWrapper::get_geometry(rapidjson::Value& result) const {
return result["routes"][0]["geometry"].GetString();
std::string OsrmRoutedWrapper::get_geometry(boost::json::object& result) const {
return result.at("routes").at(0).at("geometry").get_string().subview();
}

} // namespace vroom::routing
14 changes: 7 additions & 7 deletions src/routing/osrm_routed_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,25 @@ class OsrmRoutedWrapper : public HttpWrapper {
std::string build_query(const std::vector<Location>& locations,
const std::string& service) const override;

void check_response(const rapidjson::Document& json_result,
void check_response(const boost::json::object& json_result,
const std::vector<Location>& locs,
const std::string& service) const override;

bool
duration_value_is_null(const rapidjson::Value& matrix_entry) const override;
duration_value_is_null(const boost::json::value& matrix_entry) const override;

bool
distance_value_is_null(const rapidjson::Value& matrix_entry) const override;
distance_value_is_null(const boost::json::value& matrix_entry) const override;

UserDuration
get_duration_value(const rapidjson::Value& matrix_entry) const override;
get_duration_value(const boost::json::value& matrix_entry) const override;

UserDistance
get_distance_value(const rapidjson::Value& matrix_entry) const override;
get_distance_value(const boost::json::value& matrix_entry) const override;

unsigned get_legs_number(const rapidjson::Value& result) const override;
unsigned get_legs_number(const boost::json::object& result) const override;

std::string get_geometry(rapidjson::Value& result) const override;
std::string get_geometry(boost::json::object& result) const override;

public:
OsrmRoutedWrapper(const std::string& profile, const Server& server);
Expand Down
Loading