Skip to content
Permalink
Browse files

Initial work on a new serialization framework.

  • Loading branch information...
antialize authored and Mortal committed Jan 7, 2013
1 parent 2261d31 commit f1df45e695da744cfef5007c73ab84ca313cf331
Showing with 284 additions and 2 deletions.
  1. +58 −2 test/unit/test_serialization.cpp
  2. +1 −0 tpie/CMakeLists.txt
  3. +54 −0 tpie/is_simple_iterator.h
  4. +171 −0 tpie/serialization2.h
@@ -19,6 +19,7 @@

#include "common.h"
#include <tpie/serialization.h>
#include <tpie/serialization2.h>
#include <map>
#include <boost/random/linear_congruential.hpp>
#include <boost/unordered_map.hpp>
@@ -27,8 +28,62 @@
using namespace tpie;
using namespace std;

struct write_container {
ostream & o;
write_container(ostream & o): o(o) {}
void write(const char * x, size_t t) {
log_info() << "Write " << t << std::endl;
o.write(x, t);
}
};

struct read_container {
istream & o;
read_container(istream & o): o(o) {}
void read(char * x, size_t t) {
log_info() << "Read " << t << std::endl;
o.read(x, t);
}
};

bool testSer2() {
std::stringstream ss;
std::vector<int> v;
v.push_back(88);
v.push_back(74);

write_container wc(ss);
serialize(wc, (int)454);
serialize(wc, (float)4.5);
serialize(wc, true);
serialize(wc, v);
serialize(wc, std::string("Abekat"));

int a;
float b;
bool c;
std::vector<int> d;
std::string e;

read_container rc(ss);
unserialize(rc, a);
unserialize(rc, b);
unserialize(rc, c);
unserialize(rc, d);
unserialize(rc, e);
std::cout << a << " " << b << " " << c << " " << d[0] << " " << d[1] << " " << e << std::endl;
if (a != 454) return false;
if (b != 4.5) return false;
if (c != true) return false;
std::cout << "Here" << std::endl;
if (d != v) return false;
std::cout << "Here" << std::endl;
if (e != "Abekat") return false;
return true;
}


bool testSer(bool safe) {
boost::filesystem::remove("temp.ser");
std::stringstream ss;
std::vector<int> v;
v.push_back(88);
@@ -74,5 +129,6 @@ bool unsafe_test() { return testSer(false); }
int main(int argc, char ** argv) {
return tpie::tests(argc, argv)
.test(safe_test, "safe")
.test(unsafe_test, "unsafe");
.test(unsafe_test, "unsafe")
.test(testSer2, "serialization2");
}
@@ -58,6 +58,7 @@ set (HEADERS
progress_indicator_terminal.h
queue.h
serialization.h
serialization2.h
sort.h
sort_deprecated.h
sort_manager.h
@@ -0,0 +1,54 @@
// -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
// vi:set ts=4 sts=4 sw=4 noet :
// Copyright 2013, The TPIE development team
//
// This file is part of TPIE.
//
// TPIE is free software: you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// TPIE is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
// License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with TPIE. If not, see <http://www.gnu.org/licenses/>

#include <vector>
#include <string>

namespace tpie {

template <bool> struct is_simple_iterator_enable_if { };
template <> struct is_simple_iterator_enable_if<true> {typedef void type;};

/**
* \brief Checks if an iterator is simple
*
* An iterator is simple if it is a random access iterator
* and all elements in a range from a to b
* are located from &(*a) to &(*b)
*/
template <typename T>
class is_simple_iterator {
private:
template <typename TT>
static char magic(typename std::vector<typename TT::value_type>::iterator*);
template <typename TT>
static char magic(typename std::vector<typename TT::value_type>::const_iterator*);
template <typename TT>
static char magic(typename std::basic_string<char>::iterator*);
template <typename TT>
static char magic(typename std::basic_string<char>::const_iterator*);
template <typename TT>
static char magic(TT *, typename is_simple_iterator_enable_if<TT::is_simple_iterator>::type *_=0);
template <typename TT>
static long magic(...);
public:
static bool const value=sizeof(magic<T>((T*)0))==sizeof(char);
};

} //namespace tpie
@@ -0,0 +1,171 @@
// -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
// vi:set ts=4 sts=4 sw=4 noet :
// Copyright 2010, The TPIE development team
//
// This file is part of TPIE.
//
// TPIE is free software: you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// TPIE is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
// License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with TPIE. If not, see <http://www.gnu.org/licenses/>

#ifndef TPIE_SERIALIZATION2_H
#define TPIE_SERIALIZATION2_H

///////////////////////////////////////////////////////////////////////////
/// \file tpie/serialization.h Binary serialization and unserialization.
///////////////////////////////////////////////////////////////////////////

#include <tpie/config.h>
#include <tpie/portability.h>
#include <typeinfo>
#include <boost/type_traits/is_pod.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/utility/enable_if.hpp>
#include <tpie/is_simple_iterator.h>

namespace tpie_serialize {}

namespace tpie {

namespace bits {
using namespace tpie_serialize;

template <typename D, typename T,
bool is_simple_itr=tpie::is_simple_iterator<T>::value,
bool is_pod=boost::is_pod<typename std::iterator_traits<T>::value_type>::value,
bool is_pointer=boost::is_pointer<typename std::iterator_traits<T>::value_type>::value>
struct array_encode_magic {
//using namespace tpie_serialize;
void operator()(D & dst, T start, T end) {
for (T i=start; i != end; ++i) tp_serialize(dst, *i);
}
};

template <typename D, typename T>
struct array_encode_magic<D, T, true, true, false> {
void operator()(D & d, T start, T end) {
d.write((const char*)(&(*start)), (end-start)*sizeof(T));
}
};

template <typename D, typename T,
bool is_simple_itr=tpie::is_simple_iterator<T>::value,
bool is_pod=boost::is_pod<typename std::iterator_traits<T>::value_type>::value,
bool is_pointer=boost::is_pointer<typename std::iterator_traits<T>::value_type>::value>
struct array_decode_magic {
//using namespace tpie_serialize;
void operator()(D & dst, T start, T end) {
for (T i=start; i != end; ++i) tp_unserialize(dst, *i);
}
};

template <typename D, typename T>
struct array_decode_magic<D, T, true, true, false> {
void operator()(D & d, T start, T end) {
d.read((char *)(&(*start)), (end-start)*sizeof(T));
}
};

struct counter {
size_t size;
counter(): size(0) {}
void write(void *, size_t s) {size += s;}
};

};

template <class D, typename T>
void serialize(D & dst, const T & v) {
using namespace tpie_serialize;
tp_serialize(dst, v);
}
template <class D, typename T>
void serialize(D & dst, T start, T end) {
using namespace tpie_serialize;
bits::array_encode_magic<D, T> magic;
magic(dst, start, end);
}

template <class S, typename T>
void unserialize(S & src, T & v) {
using namespace tpie_serialize;
tp_unserialize(src, v);
}

template <class D, typename T>
void unserialize(D & dst, T start, T end) {
using namespace tpie_serialize;
bits::array_decode_magic<D, T> magic;
magic(dst, start, end);
}

template <typename T>
size_t serialized_size(const T & v) {
bits::counter c;
serialize(c, v);
return c.size;
}


};

namespace tpie_serialize {

template <class D, typename T>
void tp_serialize(D & dst, const T & v,
typename boost::enable_if<boost::is_pod<T> >::type *_=0,
typename boost::disable_if<boost::is_pointer<T> >::type *__=0) {
tpie::unused(_);
tpie::unused(__);
dst.write((const char *)&v, sizeof(T));
}

template <class S, typename T>
void tp_unserialize(S & src, T & v,
typename boost::enable_if<boost::is_pod<T> >::type *_=0,
typename boost::disable_if<boost::is_pointer<T> >::type *__=0) {
tpie::unused(_);
tpie::unused(__);
src.read((char *)&v, sizeof(T));
}

template <class D, typename T, typename alloc_t>
void tp_serialize(D & dst, const std::vector<T, alloc_t> & v) {
tpie::serialize(dst, v.size());
tpie::serialize(dst, v.begin(), v.end());
}

template <class S, typename T, typename alloc_t>
void tp_unserialize(S & src, std::vector<T, alloc_t> & v) {
typename std::vector<T>::size_type s;
tpie::unserialize(src, s);
v.resize(s);
tpie::unserialize(src, v.begin(), v.end());
}

template <class D, typename T>
void tp_serialize(D & dst, const std::basic_string<T> & v) {
tpie::serialize(dst, v.size());
tpie::serialize(dst, v.begin(), v.end());
}

template <class S, typename T>
void tp_unserialize(S & src, std::basic_string<T> & v) {
typename std::basic_string<T>::size_type s;
tpie::unserialize(src, s);
v.resize(s);
tpie::unserialize(src, v.begin(), v.end());
}

} //namespace tpie_serialize

#endif // TPIE_SERIALIZATION2_H

0 comments on commit f1df45e

Please sign in to comment.
You can’t perform that action at this time.