Merge branch 'serial-new' of https://gforge.inria.fr/git/paradiseo/paradiseo
This commit is contained in:
commit
c424e9a123
12 changed files with 412 additions and 33 deletions
|
|
@ -13,10 +13,10 @@ set(EOSERIAL_LIB_OUTPUT_PATH ${EO_BIN_DIR}/lib)
|
|||
set(LIBRARY_OUTPUT_PATH ${EOSERIAL_LIB_OUTPUT_PATH})
|
||||
|
||||
set(EOSERIAL_SOURCES
|
||||
Array.cpp
|
||||
Object.cpp
|
||||
SerialArray.cpp
|
||||
SerialObject.cpp
|
||||
Parser.cpp
|
||||
String.cpp
|
||||
SerialString.cpp
|
||||
)
|
||||
|
||||
add_library(eoserial STATIC ${EOSERIAL_SOURCES})
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ Authors:
|
|||
|
||||
# include "Parser.h"
|
||||
|
||||
# include "Array.h"
|
||||
# include "Object.h"
|
||||
# include "String.h"
|
||||
# include "SerialArray.h"
|
||||
# include "SerialObject.h"
|
||||
# include "SerialString.h"
|
||||
|
||||
// in debug mode only
|
||||
// # define DEBUG(x) std::cout << x << std::endl;
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ Authors:
|
|||
# define __EOSERIAL_PARSER_H__
|
||||
|
||||
# include "Entity.h"
|
||||
# include "String.h"
|
||||
# include "Object.h"
|
||||
# include "SerialString.h"
|
||||
# include "SerialObject.h"
|
||||
|
||||
/**
|
||||
* @file Parser.h
|
||||
|
|
|
|||
58
eo/src/serial/SerialArray.cpp
Normal file
58
eo/src/serial/SerialArray.cpp
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
(c) Thales group, 2012
|
||||
|
||||
This library 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;
|
||||
version 2 of the License.
|
||||
|
||||
This library 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 this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Contact: http://eodev.sourceforge.net
|
||||
|
||||
Authors:
|
||||
Benjamin Bouvier <benjamin.bouvier@gmail.com>
|
||||
*/
|
||||
# include "SerialArray.h"
|
||||
|
||||
namespace eoserial
|
||||
{
|
||||
std::ostream& Array::print( std::ostream& out ) const
|
||||
{
|
||||
out << "[";
|
||||
bool first = true;
|
||||
for (ArrayChildren::const_iterator it = begin(),
|
||||
end = this->end();
|
||||
it != end;
|
||||
++it)
|
||||
{
|
||||
if ( first )
|
||||
{
|
||||
first = false;
|
||||
} else {
|
||||
out << ", ";
|
||||
}
|
||||
(*it)->print( out );
|
||||
}
|
||||
out << "]\n";
|
||||
return out;
|
||||
}
|
||||
|
||||
Array::~Array()
|
||||
{
|
||||
for (ArrayChildren::iterator it = begin(),
|
||||
end = this->end();
|
||||
it != end;
|
||||
++it)
|
||||
{
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace eoserial
|
||||
170
eo/src/serial/SerialArray.h
Normal file
170
eo/src/serial/SerialArray.h
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
(c) Thales group, 2012
|
||||
|
||||
This library 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;
|
||||
version 2 of the License.
|
||||
|
||||
This library 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 this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Contact: http://eodev.sourceforge.net
|
||||
|
||||
Authors:
|
||||
Benjamin Bouvier <benjamin.bouvier@gmail.com>
|
||||
*/
|
||||
# ifndef __EOSERIAL_ARRAY_H__
|
||||
# define __EOSERIAL_ARRAY_H__
|
||||
|
||||
# include <vector>
|
||||
|
||||
# include "Entity.h"
|
||||
# include "Serializable.h"
|
||||
# include "SerialObject.h"
|
||||
|
||||
namespace eoserial
|
||||
{
|
||||
|
||||
// Forward declaration for below declarations.
|
||||
class Array;
|
||||
|
||||
/*
|
||||
* Declarations of functions present in Utils.h
|
||||
* These are put here to avoid instead of including the file Utils.h, which would
|
||||
* cause a circular inclusion.
|
||||
*/
|
||||
|
||||
template< class T >
|
||||
void unpack( const Array & array, unsigned int index, T & value );
|
||||
|
||||
void unpackObject( const Array & array, unsigned int index, Persistent & value );
|
||||
|
||||
template< class Container, template<class> class UnpackAlgorithm >
|
||||
void unpackArray( const Array & array, unsigned int index, Container & container );
|
||||
|
||||
/**
|
||||
* @brief Represents a JSON array.
|
||||
*
|
||||
* Wrapper for an array, so as to be used as a JSON object.
|
||||
*
|
||||
* @ingroup Serialization
|
||||
*/
|
||||
class Array : public eoserial::Entity, public std::vector< eoserial::Entity* >
|
||||
{
|
||||
protected:
|
||||
typedef std::vector< eoserial::Entity* > ArrayChildren;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Adds the serializable object as a JSON object.
|
||||
* @param obj Object which implemnets JsonSerializable.
|
||||
*/
|
||||
void push_back( const eoserial::Printable* obj )
|
||||
{
|
||||
ArrayChildren::push_back( obj->pack() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Proxy for vector::push_back.
|
||||
*/
|
||||
void push_back( eoserial::Entity* json )
|
||||
{
|
||||
ArrayChildren::push_back( json );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prints the JSON array into the given stream.
|
||||
* @param out The stream
|
||||
*/
|
||||
virtual std::ostream& print( std::ostream& out ) const;
|
||||
|
||||
/**
|
||||
* @brief Dtor
|
||||
*/
|
||||
~Array();
|
||||
|
||||
/*
|
||||
* The following parts allows the user to automatically deserialize an eoserial::Array into a
|
||||
* standard container, by giving the algorithm which will be used to deserialize contained entities.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Functor which determines how to retrieve the real value contained in a eoserial::Entity at
|
||||
* a given place.
|
||||
*
|
||||
* It will be applied for each contained variable in the array.
|
||||
*/
|
||||
template<class Container>
|
||||
struct BaseAlgorithm
|
||||
{
|
||||
/**
|
||||
* @brief Main operator.
|
||||
*
|
||||
* @param array The eoserial::Array from which we're reading.
|
||||
* @param i The index of the contained value.
|
||||
* @param container The standard (STL) container in which we'll push back the read value.
|
||||
*/
|
||||
virtual void operator()( const eoserial::Array& array, unsigned int i, Container & container ) const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief BaseAlgorithm for retrieving primitive variables.
|
||||
*
|
||||
* This one should be used to retrieve primitive (and types which implement operator>>) variables, for instance
|
||||
* int, double, std::string, etc...
|
||||
*/
|
||||
template<typename C>
|
||||
struct UnpackAlgorithm : public BaseAlgorithm<C>
|
||||
{
|
||||
void operator()( const eoserial::Array& array, unsigned int i, C & container ) const
|
||||
{
|
||||
typename C::value_type t;
|
||||
unpack( array, i, t );
|
||||
container.push_back( t );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief BaseAlgorithm for retrieving eoserial::Persistent objects.
|
||||
*
|
||||
* This one should be used to retrieve objects which implement eoserial::Persistent.
|
||||
*/
|
||||
template<typename C>
|
||||
struct UnpackObjectAlgorithm : public BaseAlgorithm<C>
|
||||
{
|
||||
void operator()( const eoserial::Array& array, unsigned int i, C & container ) const
|
||||
{
|
||||
typename C::value_type t;
|
||||
unpackObject( array, i, t );
|
||||
container.push_back( t );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief General algorithm for array deserialization.
|
||||
*
|
||||
* Applies the BaseAlgorithm to each contained variable in the eoserial::Array.
|
||||
*/
|
||||
template<class Container, template<class T> class UnpackAlgorithm>
|
||||
inline void deserialize( Container & array )
|
||||
{
|
||||
UnpackAlgorithm< Container > algo;
|
||||
for( unsigned int i = 0, size = this->size();
|
||||
i < size;
|
||||
++i)
|
||||
{
|
||||
algo( *this, i, array );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace eoserial
|
||||
|
||||
# endif // __EOSERIAL_ARRAY_H__
|
||||
|
||||
60
eo/src/serial/SerialObject.cpp
Normal file
60
eo/src/serial/SerialObject.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
(c) Thales group, 2012
|
||||
|
||||
This library 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;
|
||||
version 2 of the License.
|
||||
|
||||
This library 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 this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Contact: http://eodev.sourceforge.net
|
||||
|
||||
Authors:
|
||||
Benjamin Bouvier <benjamin.bouvier@gmail.com>
|
||||
*/
|
||||
# include "SerialObject.h"
|
||||
|
||||
using namespace eoserial;
|
||||
|
||||
namespace eoserial
|
||||
{
|
||||
std::ostream& Object::print( std::ostream& out ) const
|
||||
{
|
||||
out << '{';
|
||||
bool first = true;
|
||||
for(JsonValues::const_iterator it = begin(), end = this->end();
|
||||
it != end;
|
||||
++it)
|
||||
{
|
||||
if ( first )
|
||||
{
|
||||
first = false;
|
||||
} else {
|
||||
out << ", ";
|
||||
}
|
||||
|
||||
out << '"' << it->first << "\":"; // key
|
||||
it->second->print( out ); // value
|
||||
}
|
||||
out << "}\n";
|
||||
return out;
|
||||
}
|
||||
|
||||
Object::~Object()
|
||||
{
|
||||
for(JsonValues::iterator it = begin(), end = this->end();
|
||||
it != end;
|
||||
++it)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace eoserial
|
||||
88
eo/src/serial/SerialObject.h
Normal file
88
eo/src/serial/SerialObject.h
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
(c) Thales group, 2012
|
||||
|
||||
This library 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;
|
||||
version 2 of the License.
|
||||
|
||||
This library 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 this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Contact: http://eodev.sourceforge.net
|
||||
|
||||
Authors:
|
||||
Benjamin Bouvier <benjamin.bouvier@gmail.com>
|
||||
*/
|
||||
# ifndef __EOSERIAL_OBJECT_H__
|
||||
# define __EOSERIAL_OBJECT_H__
|
||||
|
||||
# include <map>
|
||||
# include <string>
|
||||
|
||||
# include "Entity.h"
|
||||
# include "Serializable.h"
|
||||
|
||||
namespace eoserial
|
||||
{
|
||||
/**
|
||||
* @brief JSON Object
|
||||
*
|
||||
* This class represents a JSON object, which is basically a dictionnary
|
||||
* of keys (strings) and values (JSON entities).
|
||||
*
|
||||
* @ingroup Serialization
|
||||
*/
|
||||
class Object : public eoserial::Entity, public std::map< std::string, eoserial::Entity* >
|
||||
{
|
||||
public:
|
||||
typedef std::map<std::string, eoserial::Entity*> JsonValues;
|
||||
|
||||
/**
|
||||
* @brief Adds a pair into the JSON object.
|
||||
* @param key The key associated with the eoserial object
|
||||
* @param json The JSON object as created with framework.
|
||||
*/
|
||||
void add( const std::string& key, eoserial::Entity* json )
|
||||
{
|
||||
(*this)[ key ] = json;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a pair into the JSON object.
|
||||
* @param key The key associated with the eoserial object
|
||||
* @param obj A JSON-serializable object
|
||||
*/
|
||||
void add( const std::string& key, const eoserial::Printable* obj )
|
||||
{
|
||||
(*this)[ key ] = obj->pack();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deserializes a Serializable class instance from this JSON object.
|
||||
* @param obj The object we want to rebuild.
|
||||
*/
|
||||
void deserialize( eoserial::Persistent & obj )
|
||||
{
|
||||
obj.unpack( this );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Dtor
|
||||
*/
|
||||
~Object();
|
||||
|
||||
/**
|
||||
* @brief Prints the content of a JSON object into a stream.
|
||||
*/
|
||||
virtual std::ostream& print( std::ostream& out ) const;
|
||||
};
|
||||
|
||||
} // namespace eoserial
|
||||
# endif // __EOSERIAL_OBJECT_H__
|
||||
|
||||
32
eo/src/serial/SerialString.cpp
Normal file
32
eo/src/serial/SerialString.cpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
(c) Thales group, 2012
|
||||
|
||||
This library 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;
|
||||
version 2 of the License.
|
||||
|
||||
This library 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 this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Contact: http://eodev.sourceforge.net
|
||||
|
||||
Authors:
|
||||
Benjamin Bouvier <benjamin.bouvier@gmail.com>
|
||||
*/
|
||||
# include "SerialString.h"
|
||||
|
||||
namespace eoserial
|
||||
{
|
||||
std::ostream& String::print( std::ostream& out ) const
|
||||
{
|
||||
out << '"' << *this << '"';
|
||||
return out;
|
||||
}
|
||||
} // namespace eoserial
|
||||
|
||||
103
eo/src/serial/SerialString.h
Normal file
103
eo/src/serial/SerialString.h
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
(c) Thales group, 2012
|
||||
|
||||
This library 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;
|
||||
version 2 of the License.
|
||||
|
||||
This library 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 this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Contact: http://eodev.sourceforge.net
|
||||
|
||||
Authors:
|
||||
Benjamin Bouvier <benjamin.bouvier@gmail.com>
|
||||
*/
|
||||
# ifndef __EOSERIAL_STRING_H__
|
||||
# define __EOSERIAL_STRING_H__
|
||||
|
||||
# include <string>
|
||||
# include <sstream>
|
||||
# include <limits>
|
||||
|
||||
# include "Entity.h"
|
||||
|
||||
namespace eoserial
|
||||
{
|
||||
/**
|
||||
* @brief JSON String
|
||||
*
|
||||
* Wrapper for string, so as to be used as a JSON object.
|
||||
*
|
||||
* @ingroup Serialization
|
||||
*/
|
||||
class String : public eoserial::Entity, public std::string
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Default ctor.
|
||||
* @param str The string we want to wrap.
|
||||
*/
|
||||
String( const std::string& str ) : std::string( str ) {}
|
||||
|
||||
/**
|
||||
* @brief Ctor used only when parsing.
|
||||
*/
|
||||
String( ) {}
|
||||
|
||||
/**
|
||||
* @brief Prints out the string.
|
||||
*/
|
||||
virtual std::ostream& print( std::ostream& out ) const;
|
||||
|
||||
/**
|
||||
* @brief Deserializes the current String into a given primitive type value.
|
||||
* @param value The value in which we're writing.
|
||||
*/
|
||||
template<class T>
|
||||
inline void deserialize( T & value ) const;
|
||||
|
||||
protected:
|
||||
// Copy and reaffectation are forbidden
|
||||
explicit String( const String& _ );
|
||||
String& operator=( const String& _ );
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Casts a eoserial::String into a primitive value, or in a type which at
|
||||
* least overload operator>>.
|
||||
*
|
||||
* @param value A reference to the variable we're writing into.
|
||||
*
|
||||
* It's not necessary to specify the variable type, which can be infered by compiler when
|
||||
* invoking.
|
||||
*/
|
||||
template<class T>
|
||||
inline void String::deserialize( T & value ) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss.precision(std::numeric_limits<double>::digits10 + 1);
|
||||
ss << *this;
|
||||
ss >> value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Specialization for strings, which don't need to be converted through
|
||||
* a stringstream.
|
||||
*/
|
||||
template<>
|
||||
inline void String::deserialize( std::string & value ) const
|
||||
{
|
||||
value = *this;
|
||||
}
|
||||
|
||||
} // namespace eoserial
|
||||
|
||||
# endif // __EOSERIAL_STRING_H__
|
||||
58
eo/src/serial/Traits.h
Normal file
58
eo/src/serial/Traits.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
(c) Benjamin Bouvier, 2013
|
||||
|
||||
This library 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;
|
||||
version 2 of the License.
|
||||
|
||||
This library 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 this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Contact: http://eodev.sourceforge.net
|
||||
|
||||
Authors:
|
||||
Benjamin Bouvier <benjamin.bouvier@gmail.com>
|
||||
*/
|
||||
# ifndef __EOSERIAL_TRAITS_H__
|
||||
# define __EOSERIAL_TRAITS_H__
|
||||
|
||||
/**
|
||||
* @file Traits.h
|
||||
*
|
||||
* Traits used for serialization purposes.
|
||||
*
|
||||
* @author Benjamin Bouvier <benjamin.bouvier@gmail.com>
|
||||
*/
|
||||
|
||||
namespace eoserial
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Trait to know whether Derived is derived from Base or not.
|
||||
*
|
||||
* To know whether A is derived from B, just test the boolean IsDerivedFrom<A, B>::value.
|
||||
*
|
||||
* @see http://www.gotw.ca/publications/mxc++-item-4.htm
|
||||
*/
|
||||
template<class Derived, class Base>
|
||||
class IsDerivedFrom
|
||||
{
|
||||
struct no{};
|
||||
struct yes{ no _[2]; };
|
||||
|
||||
static yes Test( Base* something );
|
||||
static no Test( ... );
|
||||
|
||||
public:
|
||||
enum { value = sizeof( Test( static_cast<Derived*>(0) ) ) == sizeof(yes) };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
# endif // __EOSERIAL_TRAITS_H__
|
||||
|
|
@ -22,31 +22,353 @@ Authors:
|
|||
# ifndef __EOSERIAL_UTILS_H__
|
||||
# define __EOSERIAL_UTILS_H__
|
||||
|
||||
# include "Array.h"
|
||||
# include "Object.h"
|
||||
# include "String.h"
|
||||
# include "SerialArray.h"
|
||||
# include "SerialObject.h"
|
||||
# include "SerialString.h"
|
||||
|
||||
# include "Traits.h"
|
||||
|
||||
# include <list>
|
||||
# include <map>
|
||||
|
||||
/**
|
||||
* @file Utils.h
|
||||
*
|
||||
* @brief Contains utilities for simple serialization and deserialization.
|
||||
*
|
||||
* @todo encapsulate implementations.
|
||||
*
|
||||
* Example
|
||||
*
|
||||
* @code
|
||||
# include <vector>
|
||||
# include <string>
|
||||
# include <iostream>
|
||||
|
||||
# include "eoSerial.h"
|
||||
|
||||
struct SimpleObject: public eoserial::Persistent
|
||||
{
|
||||
public:
|
||||
|
||||
SimpleObject( int v ) : value(v)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
eoserial::Object* pack() const
|
||||
{
|
||||
eoserial::Object* obj = new eoserial::Object;
|
||||
(*obj)["value"] = eoserial::pack( value );
|
||||
return obj;
|
||||
}
|
||||
|
||||
void unpack( const eoserial::Object* json )
|
||||
{
|
||||
eoserial::unpack( *json, "value", value );
|
||||
}
|
||||
|
||||
int value;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
eoserial::Object o;
|
||||
|
||||
std::cout << "packing..." << std::endl;
|
||||
// directly pack raw types
|
||||
o["long"] = eoserial::pack(123456L);
|
||||
o["bool"] = eoserial::pack(true);
|
||||
o["double"] = eoserial::pack(3.141592653);
|
||||
o["float"] = eoserial::pack(3.141592653f);
|
||||
|
||||
std::string str = "Hello, world!";
|
||||
o["str"] = eoserial::pack( str );
|
||||
|
||||
// pack objects the same way
|
||||
SimpleObject obj(42);
|
||||
o["obj"] = eoserial::pack( obj );
|
||||
|
||||
// pack vector and list the same way
|
||||
std::vector<int> vec;
|
||||
vec.push_back(1);
|
||||
vec.push_back(3);
|
||||
vec.push_back(3);
|
||||
vec.push_back(7);
|
||||
o["vec"] = eoserial::pack( vec );
|
||||
|
||||
std::map<std::string, int> str2int;
|
||||
str2int["one"] = 1;
|
||||
str2int["two"] = 2;
|
||||
str2int["answer"] = 42;
|
||||
o["map"] = eoserial::pack( str2int );
|
||||
|
||||
// print it
|
||||
o.print( std::cout );
|
||||
|
||||
std::cout << "unpacking..." << std::endl;
|
||||
|
||||
// unpack as easily raw types
|
||||
long oneTwoThreeFourFiveSix = 0L;
|
||||
eoserial::unpack( o, "long", oneTwoThreeFourFiveSix);
|
||||
std::cout << "the long: " << oneTwoThreeFourFiveSix << std::endl;
|
||||
|
||||
// since vec is encoded as an internal eoserial::Array, it can be
|
||||
// decoded into a std::vector or a std::list without difference.
|
||||
std::list<int> lis;
|
||||
eoserial::unpack( o, "vec", lis );
|
||||
|
||||
std::cout << "the list: ";
|
||||
for( auto it = lis.begin(), end = lis.end(); it != end; ++it)
|
||||
{
|
||||
std::cout << *it << ';';
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
std::map< std::string, int > readMap;
|
||||
eoserial::unpack( o, "map", readMap );
|
||||
std::cout << "The answer is " << readMap["answer"] << std::endl;
|
||||
|
||||
obj.value = -1;
|
||||
// unpack object the same way
|
||||
eoserial::unpack( o, "obj", obj );
|
||||
std::cout << "obj.value = " << obj.value << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@endcode
|
||||
*
|
||||
* @author Benjamin Bouvier <benjamin.bouvier@gmail.com>
|
||||
*/
|
||||
|
||||
namespace eoserial
|
||||
{
|
||||
/* ***************************
|
||||
* DESERIALIZATION FUNCTIONS *
|
||||
*****************************
|
||||
/* *****************
|
||||
* DESERIALIZATION *
|
||||
******************/
|
||||
|
||||
/**
|
||||
* @brief Recursively unpack elements of an object which implements push_back.
|
||||
*/
|
||||
template< class T >
|
||||
inline void unpackBasePushBack( const Entity* obj, T& container )
|
||||
{
|
||||
const Array* arr = static_cast<const Array*>( obj );
|
||||
for( auto it = arr->begin(), end = arr->end();
|
||||
it != end;
|
||||
++it )
|
||||
{
|
||||
typename T::value_type item;
|
||||
unpackBase( *it, item );
|
||||
container.push_back( item );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unpack method for std::vector
|
||||
*/
|
||||
template< class T >
|
||||
inline void unpackBase( const Entity* obj, std::vector<T>& v )
|
||||
{
|
||||
unpackBasePushBack( obj, v );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unpack method for std::list
|
||||
*/
|
||||
template< class T >
|
||||
inline void unpackBase( const Entity* obj, std::list<T>& l )
|
||||
{
|
||||
unpackBasePushBack( obj, l );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unpack method for std::map< std::string, T >
|
||||
*/
|
||||
template< class T >
|
||||
inline void unpackBase( const Entity* entity, std::map<std::string, T> & m )
|
||||
{
|
||||
const Object* obj = static_cast< const Object* >( entity );
|
||||
for( auto it = obj->begin(), end = obj->end();
|
||||
it != end;
|
||||
++it )
|
||||
{
|
||||
unpackBase( it->second, m[ it->first ] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unpack implementation for non eoserial::Persistent objects.
|
||||
*
|
||||
* This implementation is being used for every objects that can be transmitted
|
||||
* to a std::ostream (i.e. which implements the operator <<)
|
||||
*/
|
||||
template<class T, int n>
|
||||
struct UnpackImpl
|
||||
{
|
||||
void operator()( const Entity* obj, T& value )
|
||||
{
|
||||
static_cast<const String*>( obj )->deserialize( value );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Unpack implementation for eoserial::Persistent objects.
|
||||
*/
|
||||
template<class T>
|
||||
struct UnpackImpl<T, 1>
|
||||
{
|
||||
void operator()( const Entity* obj, T& value )
|
||||
{
|
||||
value.unpack( static_cast<const Object*>(obj) );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Unpack helper for determining which implementation to use.
|
||||
*
|
||||
* The trick comes from Herb Sutter: IsDerivedFrom<T, Persistent>::value is
|
||||
* true if and only if T inherits from Persistent. In this case, it's equal
|
||||
* to 1, thus the partial specialization of UnpackImpl is used. In the other
|
||||
* case, it's equal to 0 and the generic implementation is used.
|
||||
*/
|
||||
template<class T>
|
||||
inline void unpackBase( const Entity* obj, T& value )
|
||||
{
|
||||
UnpackImpl< T, IsDerivedFrom< T, Persistent >::value > impl;
|
||||
impl( obj, value );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Universal unpack method.
|
||||
*
|
||||
* @param obj The eoserial::object containing the value to deserialize.
|
||||
* @param key Name of the field to deserialize
|
||||
* @param value The object in which we'll store the deserialized value.
|
||||
*/
|
||||
template<class T>
|
||||
inline void unpack( const Object& obj, const std::string& key, T& value )
|
||||
{
|
||||
unpackBase( obj.find(key)->second, value );
|
||||
}
|
||||
|
||||
/* *******************
|
||||
* SERIALIZATION *****
|
||||
********************/
|
||||
|
||||
/**
|
||||
* @brief Pack implementation for non eoserial::Printable objects.
|
||||
*
|
||||
* This implementation is being used for every objects that can be transmitted
|
||||
* to a std::istream (i.e. which implements the operator >>)
|
||||
*/
|
||||
template<class T, int n>
|
||||
struct PackImpl
|
||||
{
|
||||
Entity* operator()( const T& value )
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss.precision(std::numeric_limits<double>::digits10 + 1);
|
||||
ss << value;
|
||||
return new String(ss.str());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Pack implementation for eoserial::Printable objects.
|
||||
*/
|
||||
template<class T>
|
||||
struct PackImpl<T, 1>
|
||||
{
|
||||
Entity* operator()( const T& value )
|
||||
{
|
||||
return value.pack();
|
||||
}
|
||||
};
|
||||
|
||||
// Pre declaration for being usable in packIterable.
|
||||
template<class T>
|
||||
inline Entity* pack( const T& value );
|
||||
|
||||
/**
|
||||
* @brief Pack method for iterable (begin, end) objects.
|
||||
*/
|
||||
template<class T>
|
||||
inline Entity* packIterable( const T& container )
|
||||
{
|
||||
Array* arr = new Array;
|
||||
for( auto it = container.begin(), end = container.end();
|
||||
it != end;
|
||||
++it )
|
||||
{
|
||||
arr->push_back( pack(*it) );
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pack method for std::vector
|
||||
*/
|
||||
template<class T>
|
||||
inline Entity* pack( const std::vector<T>& v )
|
||||
{
|
||||
return packIterable( v );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pack method for std::list
|
||||
*/
|
||||
template<class T>
|
||||
inline Entity* pack( const std::list<T>& l )
|
||||
{
|
||||
return packIterable( l );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pack method for std::map< std::string, T >
|
||||
*/
|
||||
template<class T>
|
||||
inline Entity* pack( const std::map<std::string, T>& map )
|
||||
{
|
||||
Object* obj = new Object;
|
||||
for( auto it = map.begin(), end = map.end();
|
||||
it != end;
|
||||
++it )
|
||||
{
|
||||
(*obj)[ it->first ] = pack( it->second );
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Universal pack method.
|
||||
*
|
||||
* @see unpackBase to understand the trick with the implementation.
|
||||
*
|
||||
* @param value Variable to store into an entity.
|
||||
* @return An entity to store into an object.
|
||||
*/
|
||||
template<class T>
|
||||
inline Entity* pack( const T& value )
|
||||
{
|
||||
PackImpl<T, IsDerivedFrom< T, Printable >::value> impl;
|
||||
return impl( value );
|
||||
}
|
||||
|
||||
/** **************
|
||||
* OLD FUNCTIONS *
|
||||
****************
|
||||
These functions are useful for casting eoserial::objects into simple, primitive
|
||||
variables or into class instance which implement eoserial::Persistent.
|
||||
|
||||
The model is always quite the same :
|
||||
The model is always quite the same :
|
||||
- the first argument is the containing object (which is a eoserial::Entity,
|
||||
an object or an array)
|
||||
- the second argument is the key or index,
|
||||
- the last argument is the value in which we're writing.
|
||||
|
||||
*/
|
||||
|
||||
template< class T >
|
||||
inline void unpack( const Object & obj, const std::string & key, T & value )
|
||||
{
|
||||
static_cast<String*>( obj.find( key )->second )->deserialize( value );
|
||||
}
|
||||
|
||||
inline void unpackObject( const Object & obj, const std::string & key, Persistent & value )
|
||||
{
|
||||
static_cast<Object*>( obj.find( key )->second )->deserialize( value );
|
||||
|
|
|
|||
|
|
@ -22,11 +22,10 @@ Authors:
|
|||
# ifndef __EOSERIAL_HEADERS__
|
||||
# define __EOSERIAL_HEADERS__
|
||||
|
||||
# include "Object.h"
|
||||
# include "Serializable.h"
|
||||
# include "Array.h"
|
||||
# include "Object.h"
|
||||
# include "String.h"
|
||||
# include "SerialArray.h"
|
||||
# include "SerialObject.h"
|
||||
# include "SerialString.h"
|
||||
# include "Parser.h"
|
||||
# include "Utils.h"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue