#ifndef OBJECT_ENCODER_HPP #define OBJECT_ENCODER_HPP #include <boost/assert.hpp> #include <boost/archive/iterators/base64_from_binary.hpp> #include <boost/archive/iterators/binary_from_base64.hpp> #include <boost/archive/iterators/transform_width.hpp> #include <algorithm> #include <iterator> #include <string> #include <vector> namespace osrm { namespace engine { struct ObjectEncoder { using base64_t = boost::archive::iterators::base64_from_binary< boost::archive::iterators::transform_width<const char *, 6, 8>>; using binary_t = boost::archive::iterators::transform_width< boost::archive::iterators::binary_from_base64<std::string::const_iterator>, 8, 6>; template <class ObjectT> static void EncodeToBase64(const ObjectT &object, std::string &encoded) { const char *char_ptr_to_object = reinterpret_cast<const char *>(&object); std::vector<unsigned char> data(sizeof(object)); std::copy(char_ptr_to_object, char_ptr_to_object + sizeof(ObjectT), data.begin()); unsigned char number_of_padded_chars = 0; // is in {0,1,2}; while (data.size() % 3 != 0) { ++number_of_padded_chars; data.push_back(0x00); } BOOST_ASSERT_MSG(0 == data.size() % 3, "base64 input data size is not a multiple of 3!"); encoded.resize(sizeof(ObjectT)); encoded.assign(base64_t(&data[0]), base64_t(&data[0] + (data.size() - number_of_padded_chars))); std::replace(begin(encoded), end(encoded), '+', '-'); std::replace(begin(encoded), end(encoded), '/', '_'); } template <class ObjectT> static void DecodeFromBase64(const std::string &input, ObjectT &object) { try { std::string encoded(input); std::replace(begin(encoded), end(encoded), '-', '+'); std::replace(begin(encoded), end(encoded), '_', '/'); std::copy(binary_t(encoded.begin()), binary_t(encoded.begin() + encoded.length()), reinterpret_cast<char *>(&object)); } catch (...) { } } }; } } #endif /* OBJECT_ENCODER_HPP */