24 Ağustos 2017 Perşembe

serialization binary_oarchive Sınıfı

Giriş
Şu satırı dahil ederiz.
#include <boost/archive/binary_oarchive.hpp>
EOS Portable Archives kütüphanesini ilk burada gördüm. binary_oarchive sınıfı farklı platformlar arasında portable olmayabliir. Açıklaması şöyle
The thing about the binary archive is that it was designed for optimal speed and not for portability across different platforms. This is where the EOS portable archive fills the gap, bringing both execution speed and a platform independent space-efficient binary packing.
Constructor - ofstream
Şöyle yaparız. Dosyayı std::ios::binary olarak açıp açmama konusunda emin değilim.
std::ofstream ofs("saved.bin");
boost::archive::binary_oarchive oa (ofs);
Constructor - ostringstream
Örnek
Şöyle yaparız.
std::ostringstream oss;
boost::archive::binary_oarchive oa (oss);
Örnek
Şöyle yaparız.
template<class Archive, class Object>
std::string serialise_to_string(Object const& o)
{
  auto os = std::ostringstream(std::ios::binary);
  Archive arch { os, boost::archive::no_header };
  arch << BOOST_SERIALIZATION_NVP(o);
  return os.str();
};

std::ostream& dump(std::ostream& os, std::string const& s)
{
  const char *sep = "";
  for (uint8_t ch : s) {
    std::cout << sep << std::hex << std::setw(2) << std::setfill('0')
              << static_cast<int>(ch);
    sep = " ";
  }
  return os;
}

Foo foo;

auto s1 = serialise_to_string<boost::archive::binary_oarchive>(foo);
dump(std::cout, s1) << std::endl << std::endl;
Constructor - ostringstream + flags
Şöyle yaparız.
static auto const flags = boost::archive::no_header | boost::archive::no_tracking;

std::ostringstream oss;
boost::archive::binary_oarchive oa(oss, flags);
Constructor - stringstream
Şöyle yaparız.
stringstream oss(ios_base::out|ios_base::binary);
boost::archive::binary_oarchive oa(oss);
oa << boost::serialization::make_nvp("Connections", conn);
operator << metodu - primitive
Şöyle yaparız.  Sanırım sadece lvalue değişkenler ile çalışıyor.
int i = 1
oa << i;
operator << metodu - class
Şöyle yaparız.
Foo foo;
oa << foo;
operator << metodu - STL
Şöyle yaparız.
vector<ObjectDTO> objects = ...;
oa << objects;
Diğer
Sıkıştırma için şöyle yaparız. Burada archive önce stringstream'e yazar. Daha sonra bu stream filtering_ostream nesnesine kopyalanır. filtering_ostream de sonucu vector'e yazar. Yani bir sürü kopyalama olduğu için çok verimli değil.
static auto const flags = boost::archive::no_header | boost::archive::no_tracking;

std::stringstream ss;
{
  boost::archive::binary_oarchive oa(ss, flags);
  oa << foo;
}

std::vector<char> compressed;
{
  boost::iostreams::filtering_ostream fos;
  fos.push(boost::iostreams::bzip2_compressor());
  fos.push(boost::iostreams::back_inserter(compressed));

  boost::iostreams::copy(ss, fos);
}

serialization make_array metodu

Giriş
Belirtilen belleği stream'e yazar.
Örnek
boost serialization normalde std::vector nesnesini yazıp okuyabilir. Sadece örnek olsun diye ekliyorum. Elimizde bir vector olsun
std::vector<int> v(100);
Şöyle yaparız.
std::ostringstream oss;

boost::archive::binary_oarchive oa(oss, flags);
oa << v.size() << boost::serialization::make_array(v.data(), v.size());

Örnek
Şöyle yaparız.
template <class Archive>
inline void save(Archive &ar, icu_55::UnicodeString const &s,const unsigned int) {
  auto sz = s.getCapacity();
  auto len = s.length();
  auto buf = s.getBuffer();

  if (!buf) throw std::invalid_argument("str");

  ar & sz & len & boost::serialization::make_array(buf, sz);
}

template <class Archive>
inline void load(Archive &ar, icu_55::UnicodeString &s, const unsigned int)
{
  size_t sz, len;
  ar & sz & len;
  auto buf = s.getBuffer(sz);
  if (!buf) throw std::invalid_argument("s");

  try {
    ar & boost::serialization::make_array(buf, sz);
  } 
  catch(...) {
    s.releaseBuffer(len);
    throw;
  }
  s.releaseBuffer(len);
}