2014-11-28 04:07:06 -05:00
|
|
|
#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>
|
2015-09-02 14:09:53 -04:00
|
|
|
#include <iterator>
|
2014-11-28 04:07:06 -05:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
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>;
|
|
|
|
|
2015-01-27 11:44:46 -05:00
|
|
|
template <class ObjectT> static void EncodeToBase64(const ObjectT &object, std::string &encoded)
|
2014-11-28 04:07:06 -05:00
|
|
|
{
|
2015-02-10 06:02:13 -05:00
|
|
|
const char *char_ptr_to_object = reinterpret_cast<const char *>(&object);
|
2014-11-28 04:07:06 -05:00
|
|
|
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)));
|
2015-09-02 14:09:53 -04:00
|
|
|
std::replace(begin(encoded), end(encoded), '+', '-');
|
|
|
|
std::replace(begin(encoded), end(encoded), '/', '_');
|
2014-11-28 04:07:06 -05:00
|
|
|
}
|
|
|
|
|
2015-01-27 11:44:46 -05:00
|
|
|
template <class ObjectT> static void DecodeFromBase64(const std::string &input, ObjectT &object)
|
2014-11-28 04:07:06 -05:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::string encoded(input);
|
2015-09-02 14:09:53 -04:00
|
|
|
std::replace(begin(encoded), end(encoded), '-', '+');
|
|
|
|
std::replace(begin(encoded), end(encoded), '_', '/');
|
2014-11-28 04:07:06 -05:00
|
|
|
|
2015-09-14 17:01:38 -04:00
|
|
|
std::copy(binary_t(encoded.begin()), binary_t(encoded.begin() + encoded.length()),
|
2015-02-10 06:02:13 -05:00
|
|
|
reinterpret_cast<char *>(&object));
|
2014-11-28 04:07:06 -05:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* OBJECT_ENCODER_HPP */
|