Skip to content
Snippets Groups Projects
Commit f3530e05 authored by Federico's avatar Federico
Browse files

Incomplete implementation of serialization to std streams

parent f0715e67
Branches
Tags
No related merge requests found
#include <iostream>
#include <sstream>
#include <cassert>
#include <tscpp.h>
#include "types.h"
using namespace std;
using namespace tscpp;
int main()
{
//Serialize to buffer
Point3d p1(1,2,3);
stringstream ss;
OutputArchive oa(ss);
oa<<p1;
//Unserialize from buffer
Point3d p2;
InputArchive ia(ss);
ia>>p2;
assert(p1==p2);
cout<<"Test passed"<<endl;
}
......@@ -3,10 +3,12 @@ CXX = g++
CXXFLAGS = -std=c++11 -O2 -Wall -I..
all:
$(CXX) $(CXXFLAGS) 1_stream_known.cpp ../tscpp.cpp -o 1_stream_known
$(CXX) $(CXXFLAGS) 3_buffer_known.cpp ../tscpp.cpp -o 3_buffer_known
$(CXX) $(CXXFLAGS) 4_buffer_unknown.cpp ../tscpp.cpp -o 4_buffer_unknown
./1_stream_known
./3_buffer_known
./4_buffer_unknown
clean:
rm -f 3_buffer_known 4_buffer_unknown
rm -f 1_stream_known 3_buffer_known 4_buffer_unknown
......@@ -26,6 +26,7 @@
***************************************************************************/
#include "tscpp.h"
#include <memory>
#if defined(__GNUC__) && !defined(_MIOSIX)
#include <cxxabi.h>
#endif
......@@ -107,4 +108,40 @@ string demangle(const string& name)
#endif
}
void OutputArchive::serializeImpl(const char *name, const void *data, int size)
{
int nameSize=strlen(name);
os.write(name,nameSize+1);
os.write(reinterpret_cast<const char*>(data),size);
}
void InputArchive::unserializeImpl(const char *name, void *data, int size)
{
auto pos=is.tellg();
int nameSize=strlen(name);
unique_ptr<char[]> unserializedName(new char[nameSize+1]);
is.read(unserializedName.get(),nameSize+1);
if(is.eof())
{
is.seekg(pos);
throw 1; //FIXME
}
if(memcmp(unserializedName.get(),name,nameSize+1))
{
is.seekg(pos);
throw 2; //FIXME
}
//NOTE: we are writing on top of a constructed type without calling its
//destructor. However, since it is trivially copyable, we at least aren't
//overwriting pointers to allocated memory.
is.read(reinterpret_cast<char*>(data),size);
if(is.eof())
{
is.seekg(pos);
throw 3; //FIXME
}
}
} //namespace tscpp
......@@ -29,6 +29,8 @@
#include <type_traits>
#include <functional>
#include <ostream>
#include <istream>
#include <cstring>
#include <string>
#include <map>
......@@ -186,4 +188,88 @@ std::string peekTypeName(const void *buffer, int bufSize);
*/
std::string demangle(const std::string& name);
/**
* The output archive.
* This class allows to serialize objects to any ostream using the familiar
* << syntax
*/
class OutputArchive
{
public:
/**
* Constructor
* \param os ostream where srialized types will be written
*/
OutputArchive(std::ostream& os) : os(os) {}
/**
* \internal
*/
void serializeImpl(const char *name, const void *data, int size);
private:
OutputArchive(const OutputArchive&)=delete;
OutputArchive& operator=(const OutputArchive&)=delete;
std::ostream& os;
};
/**
* Serialize a type
* \param oa archive where the type will be serialized
* \param t type to serialize
*/
template<typename T>
OutputArchive& operator<<(OutputArchive& oa, const T& t)
{
#ifndef _MIOSIX
static_assert(std::is_trivially_copyable<T>::value,"Type is not trivially copyable");
#endif
oa.serializeImpl(typeid(t).name(),&t,sizeof(t));
return oa;
}
/**
* The input archive.
* This class allows to unserialize types from a stream, as long as you know
* what types have been serialized in which order. Otherwise have a look at
* UnknownInputArchive.
* To unserialize, use the familiar >> syntax.
*/
class InputArchive
{
public:
/**
* Constructor
* \param os ostream where srialized types will be written
*/
InputArchive(std::istream& is) : is(is) {}
/**
* \internal
*/
void unserializeImpl(const char *name, void *data, int size);
private:
InputArchive(const InputArchive&)=delete;
InputArchive& operator=(const InputArchive&)=delete;
std::istream& is;
};
/**
* Unserialize a type
* \param ia archive where the type has been serialized
* \param t type to unserialize
*/
template<typename T>
InputArchive& operator>>(InputArchive& ia, T& t)
{
#ifndef _MIOSIX
static_assert(std::is_trivially_copyable<T>::value,"Type is not trivially copyable");
#endif
ia.unserializeImpl(typeid(t).name(),&t,sizeof(t));
return ia;
}
} // namespace tscpp
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment