diff --git a/servus/CMakeLists.txt b/servus/CMakeLists.txt index 90c25fb..fd54a1c 100644 --- a/servus/CMakeLists.txt +++ b/servus/CMakeLists.txt @@ -19,6 +19,7 @@ set(SERVUS_PUBLIC_HEADERS listener.h result.h + serializable.h servus.h types.h uint128_t.h @@ -33,6 +34,7 @@ set(SERVUS_HEADERS set(SERVUS_SOURCES md5/md5.cc + serializable.cpp servus.cpp uint128_t.cpp uri.cpp diff --git a/servus/serializable.cpp b/servus/serializable.cpp new file mode 100644 index 0000000..1139aaa --- /dev/null +++ b/servus/serializable.cpp @@ -0,0 +1,52 @@ +/* Copyright (c) 2016, Human Brain Project + * Stefan.Eilemann@epfl.ch + * + * This file is part of Servus + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3.0 as published + * by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "serializable.h" + +namespace servus +{ +Serializable::ChangeFunc Serializable::setUpdatedFunction( + const ChangeFunc& func ) +{ + const ChangeFunc old = _updated; + _updated = func; + return old; +} + +Serializable::ChangeFunc Serializable::setRequestedFunction( + const ChangeFunc& func ) +{ + const ChangeFunc old = _requested; + _requested = func; + return old; +} + +void Serializable::notifyUpdated() const +{ + if( _updated ) + _updated(); +} + +void Serializable::notifyRequested() const +{ + if( _requested ) + _requested(); +} + +} diff --git a/servus/serializable.h b/servus/serializable.h new file mode 100644 index 0000000..dd957de --- /dev/null +++ b/servus/serializable.h @@ -0,0 +1,120 @@ +/* Copyright (c) 2016, Human Brain Project + * Stefan.Eilemann@epfl.ch + * + * This file is part of Servus + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 3.0 as published + * by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef SERVUS_SERIALIZABLE_H +#define SERVUS_SERIALIZABLE_H + +#include +#include +#include // function +#include // shared_ptr + +namespace servus +{ + +/** Interface for serializable objects */ +class Serializable +{ +public: + virtual ~Serializable() {} + + /** Pointer + size wrapper for binary serialization. */ + struct Data + { + Data() : size ( 0 ) {} + std::shared_ptr< const void > ptr; //!< ptr to the binary serialization + size_t size; //!< The size of the binary serialization + }; + + /** @return the universally unique identifier of this serializable. */ + virtual uint128_t getTypeIdentifier() const = 0; + + /** + * Update this serializable from its binary representation. + * @return true on success, false on error. + */ + bool fromBinary( const Data& data ) + { return _fromBinary( data.ptr.get(), data.size ); } + bool fromBinary( const void* data, const size_t size ) + { return _fromBinary( data, size ); } + + /** + * Get a binary representation of this object. + * + * The returned data is not thread safe, that is, it should not be modified + * until the caller of this method has completed its execution. + * + * @return the binary representation of this object. + */ + Data toBinary() const { return _toBinary(); } + + /** + * Update this serializable from its JSON representation. + * @return true on success, false on error. + */ + bool fromJSON( const std::string& json ) { return _fromJSON( json ); } + + /** @return the JSON representation of this object. */ + std::string toJSON() const { return _toJSON(); } + + /** Function for change notification. */ + typedef std::function< void() > ChangeFunc; + + /** + * Set a new function called after the object has been updated. + * + * @return the previously set function. + */ + SERVUS_API ChangeFunc setUpdatedFunction( const ChangeFunc& func ); + + /** + * Set a new function called when a request has been received. + * + * Invoked before the object is published. + * @return the previously set function. + */ + SERVUS_API ChangeFunc setRequestedFunction( const ChangeFunc& func ); + + /** @internal used by ZeroEQ to invoke updated function */ + SERVUS_API void notifyUpdated() const; + /** @internal used by ZeroEQ to invoke updated function */ + SERVUS_API void notifyRequested() const; + +protected: + /** @name API for serializable sub classes. */ + //@{ + virtual bool _fromBinary( const void* /*data*/, const size_t /*size*/ ) + { throw std::runtime_error( "Binary deserialization not implemented" );} + virtual Data _toBinary() const + { throw std::runtime_error( "Binary serialization not implemented" ); } + + virtual bool _fromJSON( const std::string& /*json*/ ) + { throw std::runtime_error( "JSON deserialization not implemented" ); } + virtual std::string _toJSON() const + { throw std::runtime_error( "JSON serialization not implemented" ); } + //@} + +private: + ChangeFunc _updated; + ChangeFunc _requested; +}; + +} + +#endif // SERVUS_SERIALIZABLE_H diff --git a/servus/types.h b/servus/types.h index e08b7fc..f0e2158 100644 --- a/servus/types.h +++ b/servus/types.h @@ -1,6 +1,6 @@ -/* Copyright (c) 2015, Human Brain Project - * Stefan.Eilemann@epfl.ch - * Juan Hernando +/* Copyright (c) 2015-2016, Human Brain Project + * Stefan.Eilemann@epfl.ch + * Juan Hernando * * This file is part of Servus * @@ -60,6 +60,7 @@ namespace servus { class Listener; +class Serializable; class Servus; class URI; class uint128_t;