1
0
mirror of https://github.com/Rogiel/PacketBuffer synced 2025-12-06 00:13:04 +00:00

Initial commit

This commit is contained in:
2017-05-30 14:44:14 -03:00
commit dff846799a
28 changed files with 3203 additions and 0 deletions

View File

@@ -0,0 +1,185 @@
/*
* Copyright (c) 2017, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Rogiel Sulzbach nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PACKETBUFFER_OBJECTSERIALIZER_H
#define PACKETBUFFER_OBJECTSERIALIZER_H
namespace PacketBuffer {
template<typename Packer, typename T>
struct HasIntrusivePackMethod {
template<typename U, void (U::*)(Packer&) const>
struct SFINAE;
template<typename U>
static char test(SFINAE<U, &U::pack>*);
template<typename U>
static int test(...);
static const bool value = sizeof(test<T>(0)) == sizeof(char);
};
template<typename Unpacker, typename T>
struct HasIntrusiveUnpackMethod {
template<typename U, void (U::*)(Unpacker&)>
struct SFINAE;
template<typename U>
static char test(SFINAE<U, &U::unpack>*);
template<typename U>
static int test(...);
static const bool value = sizeof(test<T>(0)) == sizeof(char);
};
/**
* The ObjectSerializer class template is responsible for implementing the serialization logic
* for non-primitive types.
*
* A user can provide a specialization for any type it wishes to add custom serialization code.
*
* By default, the ObjectSerializer will call the intrusive pack() and unpack() methods on the
* user given object. If these methods are not available, compilation will fail with a error
* message describing which of the required methods are missing.
*
* A custom ObjectSerialization specialization can be provided as follows:
*
* @code
* struct UserDefinedType {
* uint64_t id;
* std::string name;
* }
*
* namespace PacketBuffer {
* template<>
* class ObjectSerializer<UserDefinedType> {
* public:
* template<typename Packer>
* static void pack(Packer& packer, const T& object) {
* packer(object.id, object.name);
* }
*
* template<typename Unpacker>
* static void unpack(Unpacker& unpacker, T& object) {
* unpacker(object.id, object.name);
* }
* }
* }
* @endcode
*
* If more convenient, a user can also provide a set of **intrusive** methods that allow
* packing and unpacking objects:
*
* @code
* struct UserDefinedType {
* uint64_t id;
* std::string name;
*
* template<typename Packer>
* void pack(Packer& packer) const {
* packer(id, name);
* }
*
* template<typename Unpacker>
* void unpack(Unpacker& unpacker) {
* unpacker(id, name);
* }
* }
* @endcode
*
* @tparam T the type of the object to be packed and/or unpacked
*/
template<typename T, typename = void>
class ObjectSerializer {
public:
/**
* Packs a object to its packed representation.
*
* This is a default implementation whose only job is to forward to the intrusive implementation,
* and if this is not available, fail at compile time.
*
* @tparam Packer the packer type
* @param packer the packer to write data from
* @param object the object to be packed
*/
template<typename Packer>
static inline void pack(Packer& packer, const T& object) {
/*
* If you are getting an error here, this means that one of your objects being serialized does not implement
* a pack() method. A pack method can be implemented as follows:
*
* template<typename Packer>
* void pack(Packer& packer) const {
* packer(
* a, b, c
* );
* }
*/
static_assert(HasIntrusivePackMethod<Packer, T>::value,
"The object of type T does not have a ObjectSerializer<T> "
"specialization and does not implement a intrusive pack(Packer&) method.");
object.pack(packer);
}
/**
* Unpacks a object from its packet representation.
*
* This is a default implementation whose only job is to forward to the intrusive implementation,
* and if this is not available, fail at compile time.
*
* @tparam Unpacker the unpacker type
* @param unpacker the unpacker to read data from
* @param object the object to unpack to
*/
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, T& object) {
/*
* If you are getting an error here, this means that one of your objects being serialized does not implement
* a unpack() method. A unpack method can be implemented as follows:
*
* template<typename Unpacker>
* void unpack(Unpacker& unpacker) {
* unpacker(
* a, b, c
* );
* }
*/
static_assert(HasIntrusiveUnpackMethod<Unpacker, T>::value,
"The object of type T does not have a ObjectSerializer<T> "
"specialization and does not implement a intrusive unpack(Unpacker&) method.");
object.unpack(unpacker);
}
};
}
#endif //PACKETBUFFER_OBJECTSERIALIZER_H

View File

@@ -0,0 +1,321 @@
/*
* Copyright (c) 2017, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Rogiel Sulzbach nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PACKETBUFFER_PACKER_H
#define PACKETBUFFER_PACKER_H
#include <boost/endian/conversion.hpp>
#include "ObjectSerializer.h"
namespace PacketBuffer {
/**
* The Packer template class is responsible for converting C++ primitive types like integers and raw buffers
* into a platform independent raw buffer.
*
* By default, all integers are encoded as little endian, this, however can be changed by setting "Endianess"
* template parameter to something else.
*
* The <tt>Buffer</tt> class must implement a <tt>write</tt> with the following signature:
* @code
* void write(const char* data, size_t length);
* @endcode
*
* @tparam Buffer the buffer type to write data to
* @tparam Endianess the endianess used to encode integer types
*/
template<typename Buffer, boost::endian::order Endianess = boost::endian::order::little>
class Packer {
private:
/**
* A reference to the buffer in which packed data is written to
*/
Buffer& buffer;
public:
/**
* Creates a new Packer instance with the given buffer reference. Packed data will be written
* into the given buffer object.
*
* @param buffer the buffer object to write data to
*/
explicit Packer(Buffer& buffer) : buffer(buffer) {};
/**
* Deleted copy constructor.
*/
Packer(const Packer& other) = delete;
/**
* Deleted copy assignment operator.
*/
Packer& operator=(const Packer& other) = delete;
/**
* Deleted move constructor.
*/
Packer(Packer&& other) = delete;
/**
* Deleted move assignment operator.
*/
Packer& operator=(Packer&& other) = delete;
/**
* Default destructor.
*/
~Packer() = default;
public: // Helper methods
/**
* A helper <tt>&</tt> operator overload. Calls the pack() method for the given type.
*
* @tparam T the data type to pack
* @param v the value to be packed
*
* @return this
*/
template<typename T>
inline Packer& operator&(const T& v) {
return pack(v);
}
/**
* A helper <tt><<</tt> operator overload that behaves similarly to ostreams operator. Calls the
* pack() method for given type.
*
* @tparam T the data type to pack
* @param v the value to be packed
*
* @return this
*/
template<typename T>
inline Packer& operator<<(const T& v) {
return pack(v);
}
/**
* A helper call operator overload. Calls pack() method for the given types.
*
* @tparam Ts the types to be packed
* @param vs the values to be packed. The values will be packed in the given order.
*
* @return this
*/
template<typename... Ts>
inline Packer& operator()(const Ts& ... vs) {
return pack(vs...);
}
public: // Object serialization
/**
* Packs a sequence of objects of types <tt>T</tt> and <tt>Ts...</tt>.
*
* The objects will be packed in the given order.
*
* @tparam T the type of the first object to be packed
* @tparam Ts the type of the remaining objects to be packed
* @param v the value of the first object to be packed
* @param vs the value of the remaining objects to be packed
*
* @return this
*/
template<typename T, typename... Ts>
inline Packer& pack(const T& v, const Ts& ... vs) {
pack(v);
pack(vs...);
return *this;
}
/**
* Packs a single object of type <tt>T</tt>.
*
* @tparam T the type of the object to be packed
* @param object the value of the object to be packed
*
* @return this
*/
template<typename T>
inline Packer& pack(const T& object) {
ObjectSerializer<T>::pack(*this, object);
return *this;
}
public: // Integer types
/**
* Packs a uint8_t integer value.
*
* @param i the integer value to pack
*
* @return this
*/
inline Packer& pack(uint8_t i) {
static_assert(sizeof(i) == 1, "uint8_t size must be 1 byte");
boost::endian::conditional_reverse_inplace<boost::endian::order::native, Endianess>(i);
return pack(reinterpret_cast<const char*>(&i), sizeof(i));
}
/**
* Packs a int8_t integer value.
*
* @param i the integer value to pack
*
* @return this
*/
inline Packer& pack(int8_t i) {
static_assert(sizeof(i) == 1, "int8_t size must be 1 byte");
boost::endian::conditional_reverse_inplace<boost::endian::order::native, Endianess>(i);
return pack(reinterpret_cast<const char*>(&i), sizeof(i));
}
/**
* Packs a uint16_t integer value.
*
* @param i the integer value to pack
*
* @return this
*/
inline Packer& pack(uint16_t i) {
static_assert(sizeof(i) == 2, "uint16_t size must be 2 byte2");
boost::endian::conditional_reverse_inplace<boost::endian::order::native, Endianess>(i);
return pack(reinterpret_cast<const char*>(&i), sizeof(i));
}
/**
* Packs a int16_t integer value.
*
* @param i the integer value to pack
*
* @return this
*/
inline Packer& pack(int16_t i) {
static_assert(sizeof(i) == 2, "int16_t size must be 2 byte2");
boost::endian::conditional_reverse_inplace<boost::endian::order::native, Endianess>(i);
return pack(reinterpret_cast<const char*>(&i), sizeof(i));
}
/**
* Packs a uint32_t integer value.
*
* @param i the integer value to pack
*
* @return this
*/
inline Packer& pack(uint32_t i) {
static_assert(sizeof(i) == 4, "uint32_t size must be 4 bytes");
boost::endian::conditional_reverse_inplace<boost::endian::order::native, Endianess>(i);
return pack(reinterpret_cast<const char*>(&i), sizeof(i));
}
/**
* Packs a int32_t integer value.
*
* @param i the integer value to pack
*
* @return this
*/
inline Packer& pack(int32_t i) {
static_assert(sizeof(i) == 4, "int32_t size must be 4 bytes");
boost::endian::conditional_reverse_inplace<boost::endian::order::native, Endianess>(i);
return pack(reinterpret_cast<const char*>(&i), sizeof(i));
}
/**
* Packs a uint64_t integer value.
*
* @param i the integer value to pack
*
* @return this
*/
inline Packer& pack(uint64_t i) {
static_assert(sizeof(i) == 8, "uint64_t size must be 8 bytes");
boost::endian::conditional_reverse_inplace<boost::endian::order::native, Endianess>(i);
return pack(reinterpret_cast<const char*>(&i), sizeof(i));
}
/**
* Packs a int64_t integer value.
*
* @param i the integer value to pack
*
* @return this
*/
inline Packer& pack(int64_t i) {
static_assert(sizeof(i) == 8, "int64_t size must be 8 bytes");
boost::endian::conditional_reverse_inplace<boost::endian::order::native, Endianess>(i);
return pack(reinterpret_cast<const char*>(&i), sizeof(i));
}
/**
* Packs a boolean value.
*
* @param b the boolean value to pack
*
* @return this
*/
inline Packer& pack(bool b) {
static_assert(sizeof(b) == 1, "bool size must be 1 byte");
boost::endian::conditional_reverse_inplace<boost::endian::order::native, Endianess>(b);
return pack(reinterpret_cast<const char*>(&b), sizeof(b));
}
public: // write operation
/**
* Packs a char-pointer gives by <tt>ptr</tt> with length given by <tt>size</tt>.
*
* @param ptr the char pointer to be packed
* @param size the char pointer length
*
* @return this
*/
inline Packer& pack(const char* ptr, size_t size) {
buffer.write(ptr, size);
return *this;
}
/**
* Packs a char-pointer givem by <tt>ptr</tt> with length given by <tt>size</tt>.
*
* @param ptr the char pointer to be packed
* @param size the char pointer length
*
* @return this
*/
inline Packer& pack(const unsigned char* ptr, size_t size) {
buffer.write(ptr, size);
return *this;
}
};
}
#endif //PACKETBUFFER_PACKER_H

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2017, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Rogiel Sulzbach nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "Packer.h"
#include "Unpacker.h"
#include "ObjectSerializer.h"
#include "Serializer/Std.h"

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2017, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Rogiel Sulzbach nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PACKETBUFFER_SERIALIZER_STD_H
#define PACKETBUFFER_SERIALIZER_STD_H
#include "Std/Array.h"
#include "Std/Chrono.h"
#include "Std/List.h"
#include "Std/Map.h"
#include "Std/Pair.h"
#include "Std/Set.h"
#include "Std/String.h"
#include "Std/Tuple.h"
#include "Std/Vector.h"
#endif //PACKETBUFFER_SERIALIZER_STD_H

View File

@@ -0,0 +1,127 @@
/*
* Copyright (c) 2017, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Rogiel Sulzbach nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PACKETBUFFER_SERIALIZER_STD_ARRAY_H
#define PACKETBUFFER_SERIALIZER_STD_ARRAY_H
#include "PacketBuffer/ObjectSerializer.h"
#include <array>
namespace PacketBuffer {
/**
* A ObjectSerializer for a statically sized array of type <tt>T</tt>
* with size of <tt>S</tt>.
*
* @note This serializer does not include the size of the original array
* when serialized. Further changing the size of the array will cause a
* change in the binary format of the packet.
*
* @tparam T the array type
* @tparam S the array fixed size
*/
template<typename T, size_t S>
class ObjectSerializer<T[S], typename std::enable_if<sizeof(T) != 1>::type> {
public:
template<typename Packer>
static inline void pack(Packer& packer, T const array[S]) {
for(int i = 0; i < S; i++) {
packer(array[i]);
}
}
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, T array[S]) {
for(int i = 0; i < S; i++) {
unpacker(array[i]);
}
}
};
/**
* A ObjectSerializer for a statically sized array of type <tt>T</tt>
* with size of <tt>S</tt>.
*
* This implementation is specialized for object whose size is 1 byte.
*
* @note This serializer does not include the size of the original array
* when serialized. Further changing the size of the array will cause a
* change in the binary format of the packet.
*
* @tparam T the array type
* @tparam S the array fixed size
*/
template<typename T, size_t S>
class ObjectSerializer<T[S], typename std::enable_if<sizeof(T) == 1>::type> {
public:
template<typename Packer>
static inline void pack(Packer& packer, T const array[S]) {
packer.pack(reinterpret_cast<const char*>(array), S);
}
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, T array[S]) {
unpacker.unpack(reinterpret_cast<char*>(array), S);
}
};
/**
* A ObjectSerializer for a statically sized array of type <tt>T</tt>
* with size of <tt>S</tt>.
*
* @note This serializer does not include the size of the original array
* when serialized. Further changing the size of the array will cause a
* change in the binary format of the packet.
*
* @tparam T the array type
* @tparam S the array fixed size
*/
template<typename T, size_t S>
class ObjectSerializer<std::array<T, S>> {
public:
template<typename Packer>
static inline void pack(Packer& packer, const std::array<T, S>& array) {
for(int i = 0; i < S; i++) {
packer(array[i]);
}
}
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, std::array<T, S>& array) {
for(int i = 0; i < S; i++) {
unpacker(array[i]);
}
}
};
}
#endif //PACKETBUFFER_SERIALIZER_STD_ARRAY_H

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) 2017, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Rogiel Sulzbach nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PACKETBUFFER_SERIALIZER_STD_CHRONO_H
#define PACKETBUFFER_SERIALIZER_STD_CHRONO_H
#include "PacketBuffer/ObjectSerializer.h"
#include <chrono>
namespace PacketBuffer {
/**
* A ObjectSerializer for std::chrono::duration values with representation
* of type <tt>R</tt> and period type of <tt>P</tt>.
*
* @tparam R the duration representation type
* @tparam P the duration period type
*/
template<typename R, typename P>
class ObjectSerializer<std::chrono::duration<R, P>> {
public:
template<typename Packer>
static inline void pack(Packer& packer, const std::chrono::duration<R, P>& duration) {
packer((int64_t) duration.count());
}
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, std::chrono::duration<R, P>& duration) {
int64_t r;
unpacker(r);
duration = std::chrono::duration<R, P>(r);
}
};
/**
* A ObjectSerializer for std::chrono::time_point values with clock
* of type <tt>Clock</tt> and duration type of <tt>Duration</tt>.
*
* @tparam Clock the time_point clock type
* @tparam Duration the time_point duration type
*/
template<typename Clock, typename Duration>
class ObjectSerializer<std::chrono::time_point<Clock, Duration>> {
public:
template<typename Packer>
static inline void pack(Packer& packer, const std::chrono::time_point<Clock, Duration>& point) {
packer(point.time_since_epoch());
}
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, std::chrono::time_point<Clock, Duration>& point) {
Duration d;
unpacker(d);
point = std::chrono::time_point<Clock, Duration>(d);
}
};
}
#endif //PACKETBUFFER_SERIALIZER_STD_CHRONO_H

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2017, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Rogiel Sulzbach nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PACKETBUFFER_SERIALIZER_STD_EXPERIMENTAL_H
#define PACKETBUFFER_SERIALIZER_STD_EXPERIMENTAL_H
#include "Experimental/Optional.h"
#endif //PACKETBUFFER_SERIALIZER_STD_EXPERIMENTAL_H

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) 2017, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Rogiel Sulzbach nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PACKETBUFFER_SERIALIZER_STD_EXPERIMENTAL_OPTIONAL_H
#define PACKETBUFFER_SERIALIZER_STD_EXPERIMENTAL_OPTIONAL_H
#include "PacketBuffer/ObjectSerializer.h"
#if __has_include(<experimental/optional>)
#include <experimental/optional>
namespace PacketBuffer {
/**
* A ObjectSerializer for std::optional of type <tt>T</tt>.
*
* @tparam T the optional type
*/
template<typename T>
class ObjectSerializer<std::experimental::optional<T>> {
public:
template<typename Packer>
static inline void pack(Packer& packer, const std::experimental::optional<T>& optional) {
if(optional) {
packer(true);
packer(*optional);
} else {
packer(false);
}
}
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, std::experimental::optional<T>& optional) {
bool hasValue;
unpacker(hasValue);
if(hasValue) {
unpacker(*optional);
}
}
};
}
#endif
#endif //PACKETBUFFER_SERIALIZER_STD_EXPERIMENTAL_OPTIONAL_H

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2017, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Rogiel Sulzbach nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PACKETBUFFER_SERIALIZER_STD_LIST_H
#define PACKETBUFFER_SERIALIZER_STD_LIST_H
#include "PacketBuffer/ObjectSerializer.h"
#include <list>
#include <forward_list>
namespace PacketBuffer {
/**
* A ObjectSerializer for std::list with elements of type <tt>R</tt>
* using an allocator of type <tt>Allocator</tt>.
*
* @tparam T the list element type
* @tparam Allocator the list allocator type
*/
template<typename T, typename Allocator>
class ObjectSerializer<std::list<T, Allocator>> {
public:
template<typename Packer>
static inline void pack(Packer& packer, const std::list<T, Allocator>& list) {
auto items = static_cast<uint64_t>(list.size());
packer(items);
for(auto& entry : list) {
packer(entry);
}
}
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, std::list<T, Allocator>& list) {
uint64_t items;
unpacker(items);
for(int i = 0; i < items; i++) {
T v;
unpacker(v);
list.push_back(v);
}
}
};
}
#endif //PACKETBUFFER_SERIALIZER_STD_LIST_H

View File

@@ -0,0 +1,113 @@
/*
* Copyright (c) 2017, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Rogiel Sulzbach nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PACKETBUFFER_SERIALIZER_STD_MAP_H
#define PACKETBUFFER_SERIALIZER_STD_MAP_H
#include "PacketBuffer/ObjectSerializer.h"
#include "PacketBuffer/Serializer/Std/Pair.h"
#include <map>
#include <unordered_map>
namespace PacketBuffer {
/**
* A ObjectSerializer for std::map with keys of type <tt>K</tt>,
* values of type <tt>T</tt>, comparison functor of type
* <tt>Compare</tt> and using an allocator of type <tt>Allocator</tt>.
*
* @tparam K the map element key
* @tparam V the map element value
* @tparam Compare the map comparison functor
* @tparam Allocator the map allocator type
*/
template<typename K, typename V, typename Compare, typename Allocator>
class ObjectSerializer<std::map<K, V, Compare, Allocator>> {
public:
template<typename Packer>
static inline void pack(Packer& packer, const std::map<K, V, Compare, Allocator>& map) {
auto items = static_cast<uint64_t>(map.size());
packer(items);
for(const std::pair<K, V>& entry : map) {
packer(entry);
}
}
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, std::map<K, V, Compare, Allocator>& map) {
uint64_t items;
unpacker(items);
for(int i = 0; i < items; i++) {
std::pair<K, V> entry;
unpacker(entry);
map.insert(std::move(entry));
}
}
};
/**
* A ObjectSerializer for std::unordered_map with keys of type <tt>K</tt>,
* values of type <tt>T</tt>, comparison functor of type <tt>Compare</tt>
* and using an allocator of type <tt>Allocator</tt>.
*
* @tparam K the map element key
* @tparam V the map element value
* @tparam Compare the map comparison functor
* @tparam Allocator the map allocator type
*/
template<typename K, typename V, class Hash, class Predicate, typename Allocator>
class ObjectSerializer<std::unordered_map<K, V, Hash, Predicate, Allocator>> {
public:
template<typename Packer>
static inline void pack(Packer& packer, const std::unordered_map<K, V, Hash, Predicate, Allocator>& map) {
auto items = static_cast<uint64_t>(map.size());
packer(items);
for(const std::pair<K, V>& entry : map) {
packer(entry);
}
}
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, std::unordered_map<K, V, Hash, Predicate, Allocator>& map) {
uint64_t items;
unpacker(items);
for(int i = 0; i < items; i++) {
std::pair<K, V> entry;
unpacker(entry);
map.insert(std::move(entry));
}
}
};
}
#endif //PACKETBUFFER_SERIALIZER_STD_MAP_H

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2017, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Rogiel Sulzbach nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PACKETBUFFER_SERIALIZER_STD_PAIR_H
#define PACKETBUFFER_SERIALIZER_STD_PAIR_H
#include "PacketBuffer/ObjectSerializer.h"
#include <utility>
namespace PacketBuffer {
/**
* A ObjectSerializer for std::pair of types <tt>T1</tt> and <tt>T2</tt>.
*
* @tparam T1 the pair first type
* @tparam T2 the pair second type
*/
template<typename T1, typename T2>
class ObjectSerializer<std::pair<T1, T2>> {
public:
template<typename Packer>
static inline void pack(Packer& packer, const std::pair<T1, T2>& pair) {
packer(pair.first, pair.second);
}
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, std::pair<T1, T2>& pair) {
unpacker(pair.first, pair.second);
}
};
}
#endif //PACKETBUFFER_SERIALIZER_STD_PAIR_H

View File

@@ -0,0 +1,112 @@
/*
* Copyright (c) 2017, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Rogiel Sulzbach nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PACKETBUFFER_SERIALIZER_STD_SET_H
#define PACKETBUFFER_SERIALIZER_STD_SET_H
#include "PacketBuffer/ObjectSerializer.h"
#include <set>
#include <unordered_set>
namespace PacketBuffer {
/**
* A ObjectSerializer for std::set with elements of type <tt>T</tt>,
* comparison functor of type <tt>Compare</tt> and using an allocator
* of type <tt>Allocator</tt>.
*
* @tparam T the set element key
* @tparam Compare the set comparison functor
* @tparam Allocator the set allocator type
*/
template<typename T, typename Compare, typename Allocator>
class ObjectSerializer<std::set<T, Compare, Allocator>> {
public:
template<typename Packer>
static inline void pack(Packer& packer, const std::set<T, Compare, Allocator>& set) {
auto items = static_cast<uint64_t>(set.size());
packer(items);
for(auto& entry : set) {
packer(entry);
}
}
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, std::set<T, Compare, Allocator>& set) {
uint64_t items;
unpacker(items);
for(int i = 0; i < items; i++) {
T v;
unpacker(v);
set.insert(v);
}
}
};
/**
* A ObjectSerializer for std::unordered_set with elements of type
* <tt>T</tt>, hash functor of type <tt>Hash</tt>, predicate of type
* <tt>Predicate</tt> and using an allocator of type <tt>Allocator</tt>.
*
* @tparam T the set element key
* @tparam Hash the set hash functor
* @tparam Predicate the set predicate functor
* @tparam Allocator the set allocator type
*/
template<typename T, typename Hash, typename Predicate, typename Allocator>
class ObjectSerializer<std::unordered_set<T, Hash, Predicate, Allocator>> {
public:
template<typename Packer>
static inline void pack(Packer& packer, const std::unordered_set<T, Hash, Predicate, Allocator>& set) {
auto items = static_cast<uint64_t>(set.size());
packer(items);
for(auto& entry : set) {
packer(entry);
}
}
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, std::unordered_set<T, Hash, Predicate, Allocator>& set) {
uint64_t items;
unpacker(items);
set.reserve(items);
for(int i = 0; i < items; i++) {
T v;
unpacker(v);
set.insert(v);
}
}
};
}
#endif //PACKETBUFFER_SERIALIZER_STD_SET_H

View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) 2017, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Rogiel Sulzbach nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PACKETBUFFER_SERIALIZER_STD_STRING_H
#define PACKETBUFFER_SERIALIZER_STD_STRING_H
#include "PacketBuffer/ObjectSerializer.h"
#include <string>
namespace PacketBuffer {
/**
* A ObjectSerializer for std::basic_string with character of type
* <tt>T</tt>, traits of type <tt>Traits</tt> and using an allocator
* of type <tt>Allocator</tt>.
*
* @tparam T the string character type
* @tparam Traits the string traits
* @tparam Allocator the string character allocator
*/
template<typename T, typename Traits, typename Allocator>
class ObjectSerializer<std::basic_string<T, Traits, Allocator>> {
public:
template<typename Packer>
static inline void pack(Packer& packer, const std::basic_string<T, Traits, Allocator>& string) {
auto length = static_cast<uint64_t>(string.size());
packer(length);
for(int i = 0; i < length; i++) {
packer(string[i]);
}
}
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, std::basic_string<T, Traits, Allocator>& string) {
uint64_t length;
unpacker(length);
string.resize(length);
for(int i = 0; i < length; i++) {
unpacker(string[i]);
}
}
};
/**
* A ObjectSerializer for std::string.
*/
template<>
class ObjectSerializer<std::string> {
public:
template<typename Packer>
static inline void pack(Packer& packer, const std::string& string) {
auto length = static_cast<uint64_t>(string.size());
packer(length);
packer.pack(string.data(), string.size());
}
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, std::string& string) {
uint64_t length;
unpacker(length);
string.resize(length);
unpacker.unpack(&string[0], string.size());
}
};
}
#endif //PACKETBUFFER_SERIALIZER_STD_STRING_H

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 2017, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Rogiel Sulzbach nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PACKETBUFFER_SERIALIZER_STD_TUPLE_H
#define PACKETBUFFER_SERIALIZER_STD_TUPLE_H
#include "PacketBuffer/ObjectSerializer.h"
#include <tuple>
namespace PacketBuffer {
/**
* A ObjectSerializer for std::tuple with elements of type <tt>Ts</tt>.
*
* @tparam Ts the tuple element types
*/
template<typename... Ts>
class ObjectSerializer<std::tuple<Ts...>> {
public:
template<typename Packer>
static inline void pack(Packer& packer, const std::tuple<Ts...>& tuple) {
packImpl<Packer, 0, Ts...>(packer, tuple);
}
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, std::tuple<Ts...>& tuple) {
unpackImpl<Unpacker, 0, Ts...>(unpacker, tuple);
}
private:
template<typename Packer, size_t I, typename T, typename... OTs>
static inline void packImpl(Packer& packer, const std::tuple<Ts...>& tuple) {
packer(std::get<I>(tuple));
packImpl<Packer, I + 1, OTs...>(packer, tuple);
}
template<typename Packer, size_t I>
static inline void packImpl(Packer& packer, const std::tuple<Ts...>& tuple) {}
template<typename Unpacker, size_t I, typename T, typename... OTs>
static inline void unpackImpl(Unpacker& unpacker, std::tuple<Ts...>& tuple) {
unpacker(std::get<I>(tuple));
unpackImpl<Unpacker, I + 1, OTs...>(unpacker, tuple);
}
template<typename Unpacker, size_t I>
static inline void unpackImpl(Unpacker& unpacker, std::tuple<Ts...>& tuple) {}
};
}
#endif //PACKETBUFFER_SERIALIZER_STD_TUPLE_H

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) 2017, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Rogiel Sulzbach nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PACKETBUFFER_SERIALIZER_STD_VECTOR_H
#define PACKETBUFFER_SERIALIZER_STD_VECTOR_H
#include "PacketBuffer/ObjectSerializer.h"
#include <vector>
namespace PacketBuffer {
/**
* A ObjectSerializer for std::vector with elements of type <tt>R</tt>
* using an allocator of type <tt>Allocator</tt>.
*
* @tparam T the vector element type
* @tparam Allocator the vector allocator type
*/
template<typename T, typename Allocator>
class ObjectSerializer<std::vector<T, Allocator>> {
public:
template<typename Packer>
static inline void pack(Packer& packer, const std::vector<T, Allocator>& vector) {
auto items = static_cast<uint64_t>(vector.size());
packer(items);
for(int i = 0; i < items; i++) {
packer(vector[i]);
}
}
template<typename Unpacker>
static inline void unpack(Unpacker& unpacker, std::vector<T, Allocator>& vector) {
uint64_t items;
unpacker(items);
vector.resize(items);
for(int i = 0; i < items; i++) {
unpacker(vector[i]);
}
}
};
}
#endif //PACKETBUFFER_SERIALIZER_STD_VECTOR_H

View File

@@ -0,0 +1,320 @@
/*
* Copyright (c) 2017, Rogiel Sulzbach
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Rogiel Sulzbach nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PACKETBUFFER_UNPACKER_H
#define PACKETBUFFER_UNPACKER_H
#include <boost/endian/conversion.hpp>
#include "ObjectSerializer.h"
namespace PacketBuffer {
template<typename Buffer, boost::endian::order Endianess = boost::endian::order::little>
class Unpacker {
private:
Buffer& buffer;
public:
Unpacker(Buffer& buffer) : buffer(buffer) {};
/**
* Deleted copy constructor.
*/
Unpacker(const Unpacker& other) = delete;
/**
* Deleted copy assignment operator.
*/
Unpacker& operator=(const Unpacker& other) = delete;
/**
* Deleted move constructor.
*/
Unpacker(Unpacker&& other) = delete;
/**
* Deleted move assignment operator.
*/
Unpacker& operator=(Unpacker&& other) = delete;
/**
* Default destructor.
*/
~Unpacker() = default;
public: // Helper methods
/**
* A helper <tt>&</tt> operator overload. Calls the unpack() method for the given type.
*
* @tparam T the data type to unpack
* @param v the value to unpack to
*
* @return this
*/
template<typename T>
Unpacker& operator&(T& v) {
return unpack(v);
}
/**
* A helper <tt>>></tt> operator overload that behaves similarly to ostreams operator. Calls the
* unpack() method for given type.
*
* @tparam T the data type to unpack
* @param v the value to unpack to
*
* @return this
*/
template<typename T>
Unpacker& operator>>(T& v) {
return unpack(v);
}
/**
* A helper call operator overload. Calls unpack() method for the given types.
*
* @tparam Ts the types to be unpacked
* @param vs the values to be unpacked. The values will be unpacked in the given order.
*
* @return this
*/
template<typename... Ts>
Unpacker& operator()(Ts& ... vs) {
return unpack(vs...);
}
/**
* Creates a default constructible object of type T and unpacks the data into it.
*
* @tparam T the type to be unpacked
*
* @return the unpacked object
*/
template<typename T>
T unpack() {
T v;
unpack(v);
return v;
}
public: // Object serialization
/**
* Unpacks a sequence of objects of types <tt>T</tt> and <tt>Ts...</tt>.
*
* The objects will be unpacked in the given order.
*
* @tparam T the type of the first object to be unpacked
* @tparam Ts the type of the remaining objects to be unpacked
* @param v the value of the first object to be unpacked
* @param vs the value of the remaining objects to be unpacked
*
* @return this
*/
template<typename T, typename... Ts>
Unpacker& unpack(T& v, Ts& ... vs) {
unpack(v);
unpack(vs...);
return *this;
}
/**
* Unpacks a single object of type <tt>T</tt>.
*
* @tparam T the type of the object to be unpacked
* @param object the value of the object to be unpacked
*
* @return this
*/
template<typename T>
Unpacker& unpack(T& object) {
ObjectSerializer<T>::unpack(*this, object);
return *this;
}
public: // Integer types
/**
* Unpacks a uint8_t integer value.
*
* @param i the integer value to unpack
*
* @return this
*/
Unpacker& unpack(uint8_t& i) {
static_assert(sizeof(i) == 1, "uint8_t size must be 1 byte");
unpack(reinterpret_cast<char*>(&i), sizeof(i));
boost::endian::conditional_reverse_inplace<Endianess, boost::endian::order::native>(i);
return *this;
}
/**
* Unpacks a int8_t integer value.
*
* @param i the integer value to unpack
*
* @return this
*/
Unpacker& unpack(int8_t& i) {
static_assert(sizeof(i) == 1, "int8_t size must be 1 byte");
unpack(reinterpret_cast<char*>(&i), sizeof(i));
boost::endian::conditional_reverse_inplace<Endianess, boost::endian::order::native>(i);
return *this;
}
/**
* Unpacks a uint16_t integer value.
*
* @param i the integer value to unpack
*
* @return this
*/
Unpacker& unpack(uint16_t& i) {
static_assert(sizeof(i) == 2, "uint16_t size must be 2 byte2");
unpack(reinterpret_cast<char*>(&i), sizeof(i));
boost::endian::conditional_reverse_inplace<Endianess, boost::endian::order::native>(i);
return *this;
}
/**
* Unpacks a int16_t integer value.
*
* @param i the integer value to unpack
*
* @return this
*/
Unpacker& unpack(int16_t& i) {
static_assert(sizeof(i) == 2, "int16_t size must be 2 byte2");
unpack(reinterpret_cast<char*>(&i), sizeof(i));
boost::endian::conditional_reverse_inplace<Endianess, boost::endian::order::native>(i);
return *this;
}
/**
* Unpacks a uint32_t integer value.
*
* @param i the integer value to unpack
*
* @return this
*/
Unpacker& unpack(uint32_t& i) {
static_assert(sizeof(i) == 4, "uint32_t size must be 4 bytes");
unpack(reinterpret_cast<char*>(&i), sizeof(i));
boost::endian::conditional_reverse_inplace<Endianess, boost::endian::order::native>(i);
return *this;
}
/**
* Unpacks a int32_t integer value.
*
* @param i the integer value to unpack
*
* @return this
*/
Unpacker& unpack(int32_t& i) {
static_assert(sizeof(i) == 4, "int32_t size must be 4 bytes");
unpack(reinterpret_cast<char*>(&i), sizeof(i));
boost::endian::conditional_reverse_inplace<Endianess, boost::endian::order::native>(i);
return *this;
}
/**
* Unpacks a uint64_t integer value.
*
* @param i the integer value to unpack
*
* @return this
*/
Unpacker& unpack(uint64_t& i) {
static_assert(sizeof(i) == 8, "uint64_t size must be 8 bytes");
unpack(reinterpret_cast<char*>(&i), sizeof(i));
boost::endian::conditional_reverse_inplace<Endianess, boost::endian::order::native>(i);
return *this;
}
/**
* Unpacks a int64_t integer value.
*
* @param i the integer value to unpack
*
* @return this
*/
Unpacker& unpack(int64_t& i) {
static_assert(sizeof(i) == 8, "int64_t size must be 8 bytes");
unpack(reinterpret_cast<char*>(&i), sizeof(i));
boost::endian::conditional_reverse_inplace<Endianess, boost::endian::order::native>(i);
return *this;
}
/**
* Unpacks a boolean value.
*
* @param b the boolean value to unpack
*
* @return this
*/
Unpacker& unpack(bool& b) {
static_assert(sizeof(b) == 1, "bool size must be 1 byte");
unpack(reinterpret_cast<char*>(&b), sizeof(b));
boost::endian::conditional_reverse_inplace<Endianess, boost::endian::order::native>(b);
return *this;
}
public: // write operation
/**
* Unpacks a char-pointer given by <tt>ptr</tt> with length given by <tt>size</tt>.
*
* @param ptr the char pointer to be unpacked
* @param size the char pointer length
*
* @return this
*/
Unpacker& unpack(char* ptr, size_t size) {
buffer.read(ptr, size);
return *this;
}
/**
* Unpacks a char-pointer given by <tt>ptr</tt> with length given by <tt>size</tt>.
*
* @param ptr the char pointer to be unpacked
* @param size the char pointer length
*
* @return this
*/
Unpacker& unpack(unsigned char* ptr, size_t size) {
buffer.read(ptr, size);
return *this;
}
};
}
#endif //PACKETBUFFER_UNPACKER_H