Merge pull request #1462

07b9138c support importing unportable outputs (kenshi84)
2ac80075 also use portable serializer for boost_serialization_helper.h and net_node.inl, completely adandon boost/archive/binary_oarchive.hpp (kenshi84)
d1d6e27a moved boost cpp into hpp since they're supposed to be header only (kenshi84)
66e6af89 added experimental boost::archive::portable_binary_{i|o}archive (kenshi84)
This commit is contained in:
Riccardo Spagni 2016-12-20 17:40:11 +02:00
commit b9b9028e50
No known key found for this signature in database
GPG key ID: 55432DF31CCD4FCD
12 changed files with 783 additions and 34 deletions

View file

@ -0,0 +1,52 @@
#ifndef PORTABLE_BINARY_ARCHIVE_HPP
#define PORTABLE_BINARY_ARCHIVE_HPP
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
#include <climits>
#if CHAR_BIT != 8
#error This code assumes an eight-bit byte.
#endif
#include <boost/archive/basic_archive.hpp>
#include <boost/detail/endian.hpp>
#include <boost/archive/impl/archive_serializer_map.ipp>
namespace boost { namespace archive {
enum portable_binary_archive_flags {
endian_big = 0x4000,
endian_little = 0x8000
};
//#if ( endian_big <= boost::archive::flags_last )
//#error archive flags conflict
//#endif
inline void
reverse_bytes(char size, char *address){
char * first = address;
char * last = first + size - 1;
for(;first < last;++first, --last){
char x = *last;
*last = *first;
*first = x;
}
}
} }
#endif // PORTABLE_BINARY_ARCHIVE_HPP

View file

@ -0,0 +1,340 @@
#ifndef PORTABLE_BINARY_IARCHIVE_HPP
#define PORTABLE_BINARY_IARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
#if defined(_MSC_VER)
#pragma warning( push )
#pragma warning( disable : 4244 )
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// portable_binary_iarchive.hpp
// (C) Copyright 2002-7 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <istream>
#include <boost/serialization/string.hpp>
#include <boost/serialization/item_version_type.hpp>
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/basic_binary_iprimitive.hpp>
#include <boost/archive/detail/common_iarchive.hpp>
#include <boost/archive/detail/register_archive.hpp>
#include <boost/archive/portable_binary_archive.hpp>
#include <boost/archive/impl/basic_binary_iprimitive.ipp>
namespace boost { namespace archive {
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// exception to be thrown if integer read from archive doesn't fit
// variable being loaded
class portable_binary_iarchive_exception :
public boost::archive::archive_exception
{
public:
enum exception_code {
incompatible_integer_size
} m_exception_code ;
portable_binary_iarchive_exception(exception_code c = incompatible_integer_size ) :
boost::archive::archive_exception(boost::archive::archive_exception::other_exception),
m_exception_code(c)
{}
virtual const char *what( ) const throw( )
{
const char *msg = "programmer error";
switch(m_exception_code){
case incompatible_integer_size:
msg = "integer cannot be represented";
break;
default:
msg = boost::archive::archive_exception::what();
assert(false);
break;
}
return msg;
}
};
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// "Portable" input binary archive. It addresses integer size and endienness so
// that binary archives can be passed across systems. Note:floating point types
// not addressed here
class portable_binary_iarchive :
public boost::archive::basic_binary_iprimitive<
portable_binary_iarchive,
std::istream::char_type,
std::istream::traits_type
>,
public boost::archive::detail::common_iarchive<
portable_binary_iarchive
>
{
typedef boost::archive::basic_binary_iprimitive<
portable_binary_iarchive,
std::istream::char_type,
std::istream::traits_type
> primitive_base_t;
typedef boost::archive::detail::common_iarchive<
portable_binary_iarchive
> archive_base_t;
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
#else
friend archive_base_t;
friend primitive_base_t; // since with override load below
friend class boost::archive::detail::interface_iarchive<
portable_binary_iarchive
>;
friend class boost::archive::load_access;
protected:
#endif
unsigned int m_flags;
void load_impl(boost::intmax_t & l, char maxsize);
// default fall through for any types not specified here
template<class T>
void load(T & t){
boost::intmax_t l;
load_impl(l, sizeof(T));
// use cast to avoid compile time warning
//t = static_cast< T >(l);
t = T(l);
}
void load(boost::serialization::item_version_type & t){
boost::intmax_t l;
load_impl(l, sizeof(boost::serialization::item_version_type));
// use cast to avoid compile time warning
t = boost::serialization::item_version_type(l);
}
void load(boost::archive::version_type & t){
boost::intmax_t l;
load_impl(l, sizeof(boost::archive::version_type));
// use cast to avoid compile time warning
t = boost::archive::version_type(l);
}
void load(boost::archive::class_id_type & t){
boost::intmax_t l;
load_impl(l, sizeof(boost::archive::class_id_type));
// use cast to avoid compile time warning
t = boost::archive::class_id_type(static_cast<int>(l));
}
void load(std::string & t){
this->primitive_base_t::load(t);
}
#ifndef BOOST_NO_STD_WSTRING
void load(std::wstring & t){
this->primitive_base_t::load(t);
}
#endif
void load(float & t){
this->primitive_base_t::load(t);
// floats not supported
//BOOST_STATIC_ASSERT(false);
}
void load(double & t){
this->primitive_base_t::load(t);
// doubles not supported
//BOOST_STATIC_ASSERT(false);
}
void load(char & t){
this->primitive_base_t::load(t);
}
void load(unsigned char & t){
this->primitive_base_t::load(t);
}
typedef boost::archive::detail::common_iarchive<portable_binary_iarchive>
detail_common_iarchive;
template<class T>
void load_override(T & t){
this->detail_common_iarchive::load_override(t);
}
void load_override(boost::archive::class_name_type & t);
// binary files don't include the optional information
void load_override(boost::archive::class_id_optional_type &){}
void init(unsigned int flags);
public:
portable_binary_iarchive(std::istream & is, unsigned flags = 0) :
primitive_base_t(
* is.rdbuf(),
0 != (flags & boost::archive::no_codecvt)
),
archive_base_t(flags),
m_flags(0)
{
init(flags);
}
portable_binary_iarchive(
std::basic_streambuf<
std::istream::char_type,
std::istream::traits_type
> & bsb,
unsigned int flags
) :
primitive_base_t(
bsb,
0 != (flags & boost::archive::no_codecvt)
),
archive_base_t(flags),
m_flags(0)
{
init(flags);
}
};
} }
// required by export in boost version > 1.34
#ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE
BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_iarchive)
#endif
// required by export in boost <= 1.34
#define BOOST_ARCHIVE_CUSTOM_IARCHIVE_TYPES portable_binary_iarchive
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// portable_binary_iarchive.cpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <istream>
#include <string>
#include <boost/detail/endian.hpp>
#include <boost/serialization/throw_exception.hpp>
#include <boost/archive/archive_exception.hpp>
namespace boost { namespace archive {
inline void
portable_binary_iarchive::load_impl(boost::intmax_t & l, char maxsize){
char size;
l = 0;
this->primitive_base_t::load(size);
if(0 == size){
return;
}
bool negative = (size < 0);
if(negative)
size = -size;
if(size > maxsize)
boost::serialization::throw_exception(
portable_binary_iarchive_exception()
);
char * cptr = reinterpret_cast<char *>(& l);
#ifdef BOOST_BIG_ENDIAN
cptr += (sizeof(boost::intmax_t) - size);
#endif
this->primitive_base_t::load_binary(cptr, size);
#ifdef BOOST_BIG_ENDIAN
if(m_flags & endian_little)
#else
if(m_flags & endian_big)
#endif
reverse_bytes(size, cptr);
if(negative)
l = -l;
}
inline void
portable_binary_iarchive::load_override(
boost::archive::class_name_type & t
){
std::string cn;
cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE);
load_override(cn);
if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1))
boost::serialization::throw_exception(
boost::archive::archive_exception(
boost::archive::archive_exception::invalid_class_name)
);
std::memcpy(t, cn.data(), cn.size());
// borland tweak
t.t[cn.size()] = '\0';
}
inline void
portable_binary_iarchive::init(unsigned int flags){
if(0 == (flags & boost::archive::no_header)){
// read signature in an archive version independent manner
std::string file_signature;
* this >> file_signature;
if(file_signature != boost::archive::BOOST_ARCHIVE_SIGNATURE())
boost::serialization::throw_exception(
boost::archive::archive_exception(
boost::archive::archive_exception::invalid_signature
)
);
// make sure the version of the reading archive library can
// support the format of the archive being read
boost::archive::library_version_type input_library_version;
* this >> input_library_version;
// extra little .t is to get around borland quirk
if(boost::archive::BOOST_ARCHIVE_VERSION() < input_library_version)
boost::serialization::throw_exception(
boost::archive::archive_exception(
boost::archive::archive_exception::unsupported_version
)
);
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
this->set_library_version(input_library_version);
//#else
//#if ! BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
//detail::
//#endif
boost::archive::detail::basic_iarchive::set_library_version(
input_library_version
);
#endif
}
unsigned char x;
load(x);
m_flags = x << CHAR_BIT;
}
} }
namespace boost {
namespace archive {
namespace detail {
template class archive_serializer_map<portable_binary_iarchive>;
}
template class basic_binary_iprimitive<
portable_binary_iarchive,
std::istream::char_type,
std::istream::traits_type
> ;
} // namespace archive
} // namespace boost
#if defined(_MSC_VER)
#pragma warning( pop )
#endif
#endif // PORTABLE_BINARY_IARCHIVE_HPP

View file

@ -0,0 +1,294 @@
#ifndef PORTABLE_BINARY_OARCHIVE_HPP
#define PORTABLE_BINARY_OARCHIVE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
#if defined(_MSC_VER)
#pragma warning( push )
#pragma warning( disable : 4244 )
#endif
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// portable_binary_oarchive.hpp
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <ostream>
#include <boost/serialization/string.hpp>
#include <boost/archive/archive_exception.hpp>
#include <boost/archive/basic_binary_oprimitive.hpp>
#include <boost/archive/detail/common_oarchive.hpp>
#include <boost/archive/detail/register_archive.hpp>
#include <boost/archive/portable_binary_archive.hpp>
#include <boost/archive/impl/basic_binary_oprimitive.ipp>
namespace boost { namespace archive {
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// exception to be thrown if integer read from archive doesn't fit
// variable being loaded
class portable_binary_oarchive_exception :
public boost::archive::archive_exception
{
public:
typedef enum {
invalid_flags
} exception_code;
portable_binary_oarchive_exception(exception_code c = invalid_flags )
{}
virtual const char *what( ) const throw( )
{
const char *msg = "programmer error";
switch(code){
case invalid_flags:
msg = "cannot be both big and little endian";
default:
boost::archive::archive_exception::what();
}
return msg;
}
};
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// "Portable" output binary archive. This is a variation of the native binary
// archive. it addresses integer size and endienness so that binary archives can
// be passed across systems. Note:floating point types not addressed here
class portable_binary_oarchive :
public boost::archive::basic_binary_oprimitive<
portable_binary_oarchive,
std::ostream::char_type,
std::ostream::traits_type
>,
public boost::archive::detail::common_oarchive<
portable_binary_oarchive
>
{
typedef boost::archive::basic_binary_oprimitive<
portable_binary_oarchive,
std::ostream::char_type,
std::ostream::traits_type
> primitive_base_t;
typedef boost::archive::detail::common_oarchive<
portable_binary_oarchive
> archive_base_t;
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
#else
friend archive_base_t;
friend primitive_base_t; // since with override save below
friend class boost::archive::detail::interface_oarchive<
portable_binary_oarchive
>;
friend class boost::archive::save_access;
protected:
#endif
unsigned int m_flags;
void save_impl(const boost::intmax_t l, const char maxsize);
// add base class to the places considered when matching
// save function to a specific set of arguments. Note, this didn't
// work on my MSVC 7.0 system so we use the sure-fire method below
// using archive_base_t::save;
// default fall through for any types not specified here
template<class T>
void save(const T & t){
save_impl(t, sizeof(T));
}
void save(const std::string & t){
this->primitive_base_t::save(t);
}
#ifndef BOOST_NO_STD_WSTRING
void save(const std::wstring & t){
this->primitive_base_t::save(t);
}
#endif
void save(const float & t){
this->primitive_base_t::save(t);
// floats not supported
//BOOST_STATIC_ASSERT(false);
}
void save(const double & t){
this->primitive_base_t::save(t);
// doubles not supported
//BOOST_STATIC_ASSERT(false);
}
void save(const char & t){
this->primitive_base_t::save(t);
}
void save(const unsigned char & t){
this->primitive_base_t::save(t);
}
// default processing - kick back to base class. Note the
// extra stuff to get it passed borland compilers
typedef boost::archive::detail::common_oarchive<portable_binary_oarchive>
detail_common_oarchive;
template<class T>
void save_override(T & t){
this->detail_common_oarchive::save_override(t);
}
// explicitly convert to char * to avoid compile ambiguities
void save_override(const boost::archive::class_name_type & t){
const std::string s(t);
* this << s;
}
// binary files don't include the optional information
void save_override(
const boost::archive::class_id_optional_type & /* t */
){}
void init(unsigned int flags);
public:
portable_binary_oarchive(std::ostream & os, unsigned flags = 0) :
primitive_base_t(
* os.rdbuf(),
0 != (flags & boost::archive::no_codecvt)
),
archive_base_t(flags),
m_flags(flags & (endian_big | endian_little))
{
init(flags);
}
portable_binary_oarchive(
std::basic_streambuf<
std::ostream::char_type,
std::ostream::traits_type
> & bsb,
unsigned int flags
) :
primitive_base_t(
bsb,
0 != (flags & boost::archive::no_codecvt)
),
archive_base_t(flags),
m_flags(0)
{
init(flags);
}
};
} }
// required by export in boost version > 1.34
#ifdef BOOST_SERIALIZATION_REGISTER_ARCHIVE
BOOST_SERIALIZATION_REGISTER_ARCHIVE(portable_binary_oarchive)
#endif
// required by export in boost <= 1.34
#define BOOST_ARCHIVE_CUSTOM_OARCHIVE_TYPES portable_binary_oarchive
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// portable_binary_oarchive.cpp
// (C) Copyright 2002-7 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for updates, documentation, and revision history.
#include <ostream>
#include <boost/detail/endian.hpp>
namespace boost { namespace archive {
inline void
portable_binary_oarchive::save_impl(
const boost::intmax_t l,
const char maxsize
){
char size = 0;
if(l == 0){
this->primitive_base_t::save(size);
return;
}
boost::intmax_t ll;
bool negative = (l < 0);
if(negative)
ll = -l;
else
ll = l;
do{
ll >>= CHAR_BIT;
++size;
}while(ll != 0);
this->primitive_base_t::save(
static_cast<char>(negative ? -size : size)
);
if(negative)
ll = -l;
else
ll = l;
char * cptr = reinterpret_cast<char *>(& ll);
#ifdef BOOST_BIG_ENDIAN
cptr += (sizeof(boost::intmax_t) - size);
if(m_flags & endian_little)
reverse_bytes(size, cptr);
#else
if(m_flags & endian_big)
reverse_bytes(size, cptr);
#endif
this->primitive_base_t::save_binary(cptr, size);
}
inline void
portable_binary_oarchive::init(unsigned int flags) {
if(m_flags == (endian_big | endian_little)){
boost::serialization::throw_exception(
portable_binary_oarchive_exception()
);
}
if(0 == (flags & boost::archive::no_header)){
// write signature in an archive version independent manner
const std::string file_signature(
boost::archive::BOOST_ARCHIVE_SIGNATURE()
);
* this << file_signature;
// write library version
const boost::archive::library_version_type v(
boost::archive::BOOST_ARCHIVE_VERSION()
);
* this << v;
}
save(static_cast<unsigned char>(m_flags >> CHAR_BIT));
}
} }
namespace boost {
namespace archive {
namespace detail {
template class archive_serializer_map<portable_binary_oarchive>;
}
template class basic_binary_oprimitive<
portable_binary_oarchive,
std::ostream::char_type,
std::ostream::traits_type
> ;
} // namespace archive
} // namespace boost
#if defined(_MSC_VER)
#pragma warning( pop )
#endif
#endif // PORTABLE_BINARY_OARCHIVE_HPP

View file

@ -30,8 +30,9 @@
#pragma once
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/portable_binary_oarchive.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
namespace tools
@ -75,7 +76,7 @@ namespace tools
return false;
#endif
boost::archive::binary_oarchive a(data_file);
boost::archive::portable_binary_oarchive a(data_file);
a << obj;
if (data_file.fail())
return false;
@ -99,9 +100,23 @@ namespace tools
data_file.open( file_path, std::ios_base::binary | std::ios_base::in);
if(data_file.fail())
return false;
boost::archive::binary_iarchive a(data_file);
a >> obj;
try
{
// first try reading in portable mode
boost::archive::portable_binary_iarchive a(data_file);
a >> obj;
}
catch(...)
{
// if failed, try reading in unportable mode
boost::filesystem::copy_file(file_path, file_path + ".unportable", boost::filesystem::copy_option::overwrite_if_exists);
data_file.close();
data_file.open( file_path, std::ios_base::binary | std::ios_base::in);
if(data_file.fail())
return false;
boost::archive::binary_iarchive a(data_file);
a >> obj;
}
return !data_file.fail();
CATCH_ENTRY_L0("unserialize_obj_from_file", false);
}

View file

@ -28,8 +28,6 @@
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <fstream>
#include "include_base_utils.h"

View file

@ -30,8 +30,6 @@
#include <algorithm>
#include <cstdio>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/filesystem.hpp>
#include "include_base_utils.h"

View file

@ -38,7 +38,8 @@
#include <boost/foreach.hpp>
#include <boost/serialization/is_bitwise_serializable.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
#include <boost/archive/portable_binary_oarchive.hpp>
#include "cryptonote_basic.h"
#include "common/unordered_containers_boost_serialization.h"
#include "crypto/crypto.h"
@ -230,7 +231,8 @@ namespace boost
// a & x.senderPk; // not serialized, as we do not use it in monero currently
}
inline void serializeOutPk(boost::archive::binary_iarchive &a, rct::ctkeyV &outPk_, const boost::serialization::version_type ver)
template <class Archive>
inline typename std::enable_if<Archive::is_loading::value, void>::type serializeOutPk(Archive &a, rct::ctkeyV &outPk_, const boost::serialization::version_type ver)
{
rct::keyV outPk;
a & outPk;
@ -242,7 +244,8 @@ namespace boost
}
}
inline void serializeOutPk(boost::archive::binary_oarchive &a, rct::ctkeyV &outPk_, const boost::serialization::version_type ver)
template <class Archive>
inline typename std::enable_if<Archive::is_saving::value, void>::type serializeOutPk(Archive &a, rct::ctkeyV &outPk_, const boost::serialization::version_type ver)
{
rct::keyV outPk(outPk_.size());
for (size_t n = 0; n < outPk_.size(); ++n)

View file

@ -137,14 +137,34 @@ namespace nodetool
{
try
{
boost::archive::binary_iarchive a(p2p_data);
// first try reading in portable mode
boost::archive::portable_binary_iarchive a(p2p_data);
a >> *this;
}
catch (const std::exception &e)
catch (...)
{
LOG_ERROR("Failed to load p2p config file, falling back to default config");
m_peerlist = peerlist_manager(); // it was probably half clobbered by the failed load
make_default_config();
// if failed, try reading in unportable mode
boost::filesystem::copy_file(state_file_path, state_file_path + ".unportable", boost::filesystem::copy_option::overwrite_if_exists);
p2p_data.close();
p2p_data.open( state_file_path , std::ios_base::binary | std::ios_base::in);
if(!p2p_data.fail())
{
try
{
boost::archive::binary_iarchive a(p2p_data);
a >> *this;
}
catch (const std::exception &e)
{
LOG_ERROR("Failed to load p2p config file, falling back to default config");
m_peerlist = peerlist_manager(); // it was probably half clobbered by the failed load
make_default_config();
}
}
else
{
make_default_config();
}
}
}else
{
@ -645,7 +665,7 @@ namespace nodetool
return false;
};
boost::archive::binary_oarchive a(p2p_data);
boost::archive::portable_binary_oarchive a(p2p_data);
a << *this;
return true;
CATCH_ENTRY_L0("blockchain_storage::save", false);

View file

@ -36,8 +36,9 @@
#include <boost/foreach.hpp>
//#include <boost/bimap.hpp>
//#include <boost/bimap/multiset_of.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/portable_binary_oarchive.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
#include <boost/serialization/version.hpp>
#include <boost/multi_index_container.hpp>

View file

@ -3882,7 +3882,7 @@ bool simple_wallet::export_outputs(const std::vector<std::string> &args)
std::vector<tools::wallet2::transfer_details> outs = m_wallet->export_outputs();
std::stringstream oss;
boost::archive::binary_oarchive ar(oss);
boost::archive::portable_binary_oarchive ar(oss);
ar << outs;
std::string magic(OUTPUT_EXPORT_FILE_MAGIC, strlen(OUTPUT_EXPORT_FILE_MAGIC));
@ -3962,10 +3962,19 @@ bool simple_wallet::import_outputs(const std::vector<std::string> &args)
std::string body(data, headerlen);
std::stringstream iss;
iss << body;
boost::archive::binary_iarchive ar(iss);
std::vector<tools::wallet2::transfer_details> outputs;
ar >> outputs;
try
{
boost::archive::portable_binary_iarchive ar(iss);
ar >> outputs;
}
catch (...)
{
iss.str("");
iss << body;
boost::archive::binary_iarchive ar(iss);
ar >> outputs;
}
size_t n_outputs = m_wallet->import_outputs(outputs);
success_msg_writer() << boost::lexical_cast<std::string>(n_outputs) << " outputs imported";
}

View file

@ -30,8 +30,6 @@
#include <random>
#include <tuple>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/format.hpp>
#include <boost/optional/optional.hpp>
#include <boost/utility/value_init.hpp>
@ -2313,16 +2311,38 @@ void wallet2::load(const std::string& wallet_, const std::string& password)
std::stringstream iss;
iss << cache_data;
boost::archive::binary_iarchive ar(iss);
ar >> *this;
try {
boost::archive::portable_binary_iarchive ar(iss);
ar >> *this;
}
catch (...)
{
LOG_PRINT_L0("Failed to open portable binary, trying unportable");
boost::filesystem::copy_file(m_wallet_file, m_wallet_file + ".unportable", boost::filesystem::copy_option::overwrite_if_exists);
iss.str("");
iss << cache_data;
boost::archive::binary_iarchive ar(iss);
ar >> *this;
}
}
catch (...)
{
LOG_PRINT_L1("Failed to load encrypted cache, trying unencrypted");
std::stringstream iss;
iss << buf;
boost::archive::binary_iarchive ar(iss);
ar >> *this;
try {
boost::archive::portable_binary_iarchive ar(iss);
ar >> *this;
}
catch (...)
{
LOG_PRINT_L0("Failed to open portable binary, trying unportable");
boost::filesystem::copy_file(m_wallet_file, m_wallet_file + ".unportable", boost::filesystem::copy_option::overwrite_if_exists);
iss.str("");
iss << buf;
boost::archive::binary_iarchive ar(iss);
ar >> *this;
}
}
THROW_WALLET_EXCEPTION_IF(
m_account_public_address.m_spend_public_key != m_account.get_keys().m_account_address.m_spend_public_key ||
@ -2396,7 +2416,7 @@ void wallet2::store_to(const std::string &path, const std::string &password)
}
// preparing wallet data
std::stringstream oss;
boost::archive::binary_oarchive ar(oss);
boost::archive::portable_binary_oarchive ar(oss);
ar << *this;
wallet2::cache_file_data cache_file_data = boost::value_initialized<wallet2::cache_file_data>();

View file

@ -31,7 +31,6 @@
#pragma once
#include <memory>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
@ -676,11 +675,11 @@ namespace boost
namespace serialization
{
template <class Archive>
inline void initialize_transfer_details(Archive &a, tools::wallet2::transfer_details &x, const boost::serialization::version_type ver)
inline typename std::enable_if<!Archive::is_loading::value, void>::type initialize_transfer_details(Archive &a, tools::wallet2::transfer_details &x, const boost::serialization::version_type ver)
{
}
template<>
inline void initialize_transfer_details(boost::archive::binary_iarchive &a, tools::wallet2::transfer_details &x, const boost::serialization::version_type ver)
template <class Archive>
inline typename std::enable_if<Archive::is_loading::value, void>::type initialize_transfer_details(Archive &a, tools::wallet2::transfer_details &x, const boost::serialization::version_type ver)
{
if (ver < 1)
{