mirror of
https://github.com/Rogiel/PacketBuffer
synced 2025-12-06 00:13:04 +00:00
Initial commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
cmake-build-*
|
||||
/.idea
|
||||
32
.gitmodules
vendored
Normal file
32
.gitmodules
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
[submodule "Catch"]
|
||||
path = Catch
|
||||
url = https://github.com/philsquared/Catch.git
|
||||
50
CMakeLists.txt
Normal file
50
CMakeLists.txt
Normal file
@@ -0,0 +1,50 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
project(PacketBuffer)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
|
||||
add_library(PacketBuffer INTERFACE)
|
||||
target_include_directories(PacketBuffer INTERFACE include)
|
||||
|
||||
option(PACKET_BUFFER_EXAMPLES "Enable to build examples" OFF)
|
||||
if(PACKET_BUFFER_EXAMPLES)
|
||||
add_executable(PacketBuffer.Example example/main.cpp)
|
||||
target_link_libraries(PacketBuffer.Example PacketBuffer)
|
||||
endif()
|
||||
|
||||
option(PACKET_BUFFER_TESTS "Enable to build tests" OFF)
|
||||
if(PACKET_BUFFER_TESTS)
|
||||
file(GLOB_RECURSE TESTS_SRC tests/*.cpp)
|
||||
add_executable(PacketBuffer.Tests ${TESTS_SRC})
|
||||
target_link_libraries(PacketBuffer.Tests PacketBuffer)
|
||||
target_include_directories(PacketBuffer.Tests PRIVATE Catch/include)
|
||||
endif()
|
||||
1
Catch
Submodule
1
Catch
Submodule
Submodule Catch added at 3e328f55fc
30
LICENSE
Normal file
30
LICENSE
Normal file
@@ -0,0 +1,30 @@
|
||||
The BSD 3-Clause ("BSD New" or "BSD Simplified") License
|
||||
========================================================
|
||||
|
||||
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 the Rogiel Sulzbach nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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.
|
||||
63
README.md
Normal file
63
README.md
Normal file
@@ -0,0 +1,63 @@
|
||||
PacketBuffer - Lightning fast packet parsing library
|
||||
========================================================
|
||||
|
||||
PacketBuffer is a C++14 header-only library designed specifically to be really fast at processing binary network packets. It supports many of the C++ standard containers, including:
|
||||
|
||||
* [`std::array`](include/PacketBuffer/Serializer/Std/Array.h)
|
||||
* [`T[S]` (statically sized arrays)](include/PacketBuffer/Serializer/Std/Array.h)
|
||||
* [`std::chrono::duration`](include/PacketBuffer/Serializer/Std/Chrono.h)
|
||||
* [`std::chrono::time_point`](include/PacketBuffer/Serializer/Std/Chrono.h)
|
||||
* [`std::vector`](include/PacketBuffer/Serializer/Std/Vector.h)
|
||||
* [`std::map`](include/PacketBuffer/Serializer/Std/Map.h)
|
||||
* [`std::unordered_map`](include/PacketBuffer/Serializer/Std/Map.h)
|
||||
* [`std::list`](include/PacketBuffer/Serializer/Std/List.h)
|
||||
* [`std::set`](include/PacketBuffer/Serializer/Std/Set.h)
|
||||
* [`std::unoredered_set`](include/PacketBuffer/Serializer/Std/Set.h)
|
||||
* [`std::string`](include/PacketBuffer/Serializer/Std/String.h)
|
||||
* [`std::tuple`](include/PacketBuffer/Serializer/Std/Tuple.h)
|
||||
* [`std::pair`](include/PacketBuffer/Serializer/Std/Pair.h)
|
||||
* [`std::experimental::optional`](include/PacketBuffer/Serializer/Std/Experimental/Optional.h)
|
||||
|
||||
It also supports endian swapping the following types:
|
||||
`uint8_t`, `int8_t`,
|
||||
`uint16_t`, `int16_t`,
|
||||
`uint32_t`, `int32_t`,
|
||||
`uint64_t`, `int64_t`.
|
||||
|
||||
## Getting Started
|
||||
````````
|
||||
using namespace PacketBuffer;
|
||||
|
||||
std::stringstream ss;
|
||||
Packer<std::stringstream> packer(ss);
|
||||
packer.pack(uint8_t(100));
|
||||
````````
|
||||
|
||||
That's it!
|
||||
|
||||
But wait, you probably want something more than just packing a `uint8_t`, right? What about some custom structs?
|
||||
|
||||
### Packing structs
|
||||
``` c++
|
||||
using namespace PacketBuffer;
|
||||
|
||||
struct MyPacket {
|
||||
uint8_t id;
|
||||
std::string name;
|
||||
uint8_t age;
|
||||
|
||||
template<typename Packer>
|
||||
void pack(Packer& packer) const { packer(id, name, age); }
|
||||
|
||||
template<typename Unpacker>
|
||||
void unpack(Unpacker& unpacker) { unpacker(id, name, age); }
|
||||
};
|
||||
|
||||
std::stringstream ss;
|
||||
Packer<std::stringstream> packer(ss);
|
||||
|
||||
MyPacket packet;
|
||||
packer.pack(packet);
|
||||
```
|
||||
|
||||
Seriously, that is it! You can now serialize and deserialize your structure on any machine with whatever byte order it has!
|
||||
125
example/main.cpp
Normal file
125
example/main.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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 <PacketBuffer/PacketBuffer.h>
|
||||
#include <PacketBuffer/Serializer/Std/Experimental.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace PacketBuffer;
|
||||
|
||||
struct HELLO_MESSAGE {
|
||||
uint8_t id;
|
||||
uint8_t kind;
|
||||
|
||||
unsigned char payload[64];
|
||||
std::array<uint8_t, 16> test;
|
||||
|
||||
std::vector<int> vec;
|
||||
|
||||
std::tuple<uint8_t, uint32_t, uint64_t> tuple;
|
||||
std::pair<uint8_t, uint32_t> pair;
|
||||
|
||||
std::map<uint8_t, uint64_t> mapping;
|
||||
std::unordered_map<uint8_t, uint64_t> umapping;
|
||||
|
||||
std::list<uint8_t> list;
|
||||
std::list<uint8_t> flist;
|
||||
std::set<uint8_t> set;
|
||||
std::unordered_set<uint8_t> uset;
|
||||
|
||||
std::chrono::seconds durationSec;
|
||||
std::chrono::hours durationHour;
|
||||
|
||||
std::chrono::system_clock::time_point time;
|
||||
|
||||
std::experimental::optional<std::string> oName;
|
||||
|
||||
std::string name;
|
||||
|
||||
template<typename Packer>
|
||||
void pack(Packer& packer) const {
|
||||
packer(
|
||||
id, kind, payload, test, vec, tuple, pair, mapping, umapping, list, flist, set, uset, name, durationSec,
|
||||
durationHour, time, oName
|
||||
);
|
||||
}
|
||||
|
||||
template<typename Unpacker>
|
||||
void unpack(Unpacker& unpacker) {
|
||||
unpacker(
|
||||
id, kind, payload, test, vec, tuple, pair, mapping, umapping, list, flist, set, uset, name, durationSec,
|
||||
durationHour, time, oName
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, const char** argv) {
|
||||
std::stringstream ss;
|
||||
Packer<std::ostream> packer(ss);
|
||||
|
||||
{
|
||||
HELLO_MESSAGE hello;
|
||||
hello.id = 20;
|
||||
hello.kind = 2;
|
||||
memset(hello.payload, 'A', sizeof(hello.payload));
|
||||
|
||||
hello.vec = {1, 2, 3};
|
||||
hello.mapping[1] = 200;
|
||||
hello.mapping[2] = 300;
|
||||
|
||||
hello.name = "It Works!";
|
||||
// hello.wname = L"Teste";
|
||||
hello.oName = std::string(";)");
|
||||
|
||||
packer.pack(hello);
|
||||
}
|
||||
|
||||
std::cout << "Serialized message has " << ss.str().size() << std::endl;
|
||||
|
||||
{
|
||||
Unpacker<std::istream> unpacker(ss);
|
||||
HELLO_MESSAGE unpacked;
|
||||
|
||||
unpacker.unpack(unpacked);
|
||||
|
||||
std::cout << "id: " << (int) unpacked.id << std::endl;
|
||||
std::cout << "kind: " << (int) unpacked.kind << std::endl;
|
||||
std::cout << "payload: " << std::string((char*) unpacked.payload, 64) << std::endl;
|
||||
std::cout << "vec: " << unpacked.vec.size() << std::endl;
|
||||
std::cout << "name: " << unpacked.name << std::endl;
|
||||
|
||||
std::cout << "mapping: " << std::endl;
|
||||
for(auto& entry : unpacked.mapping) {
|
||||
std::cout << " " << (int) entry.first << " = " << entry.second << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
185
include/PacketBuffer/ObjectSerializer.h
Normal file
185
include/PacketBuffer/ObjectSerializer.h
Normal 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
|
||||
321
include/PacketBuffer/Packer.h
Normal file
321
include/PacketBuffer/Packer.h
Normal 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
|
||||
34
include/PacketBuffer/PacketBuffer.h
Normal file
34
include/PacketBuffer/PacketBuffer.h
Normal 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"
|
||||
43
include/PacketBuffer/Serializer/Std.h
Normal file
43
include/PacketBuffer/Serializer/Std.h
Normal 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
|
||||
127
include/PacketBuffer/Serializer/Std/Array.h
Normal file
127
include/PacketBuffer/Serializer/Std/Array.h
Normal 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
|
||||
87
include/PacketBuffer/Serializer/Std/Chrono.h
Normal file
87
include/PacketBuffer/Serializer/Std/Chrono.h
Normal 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
|
||||
35
include/PacketBuffer/Serializer/Std/Experimental.h
Normal file
35
include/PacketBuffer/Serializer/Std/Experimental.h
Normal 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
|
||||
73
include/PacketBuffer/Serializer/Std/Experimental/Optional.h
Normal file
73
include/PacketBuffer/Serializer/Std/Experimental/Optional.h
Normal 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
|
||||
74
include/PacketBuffer/Serializer/Std/List.h
Normal file
74
include/PacketBuffer/Serializer/Std/List.h
Normal 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
|
||||
113
include/PacketBuffer/Serializer/Std/Map.h
Normal file
113
include/PacketBuffer/Serializer/Std/Map.h
Normal 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
|
||||
62
include/PacketBuffer/Serializer/Std/Pair.h
Normal file
62
include/PacketBuffer/Serializer/Std/Pair.h
Normal 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
|
||||
112
include/PacketBuffer/Serializer/Std/Set.h
Normal file
112
include/PacketBuffer/Serializer/Std/Set.h
Normal 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
|
||||
97
include/PacketBuffer/Serializer/Std/String.h
Normal file
97
include/PacketBuffer/Serializer/Std/String.h
Normal 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
|
||||
80
include/PacketBuffer/Serializer/Std/Tuple.h
Normal file
80
include/PacketBuffer/Serializer/Std/Tuple.h
Normal 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
|
||||
73
include/PacketBuffer/Serializer/Std/Vector.h
Normal file
73
include/PacketBuffer/Serializer/Std/Vector.h
Normal 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
|
||||
320
include/PacketBuffer/Unpacker.h
Normal file
320
include/PacketBuffer/Unpacker.h
Normal 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
|
||||
397
tests/Packer.cpp
Normal file
397
tests/Packer.cpp
Normal file
@@ -0,0 +1,397 @@
|
||||
/*
|
||||
* 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 <catch.hpp>
|
||||
#include <sstream>
|
||||
|
||||
#include <PacketBuffer/PacketBuffer.h>
|
||||
|
||||
std::string string_to_hex(const std::string& input) {
|
||||
static const char* const lut = "0123456789ABCDEF";
|
||||
size_t len = input.length();
|
||||
|
||||
std::string output;
|
||||
output.reserve(2 * len);
|
||||
for(size_t i = 0; i < len; ++i) {
|
||||
const unsigned char c = input[i];
|
||||
output.push_back(lut[c >> 4]);
|
||||
output.push_back(lut[c & 15]);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
TEST_CASE("Packer", "[packer]") {
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
SECTION("little endian") {
|
||||
PacketBuffer::Packer<std::ostream, boost::endian::order::little> packer(ss);
|
||||
|
||||
SECTION("uint8_t") {
|
||||
SECTION("min") {
|
||||
packer.pack(std::numeric_limits<uint8_t>::min());
|
||||
CHECK(string_to_hex(ss.str()) == "00");
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
packer.pack(uint8_t(1));
|
||||
CHECK(string_to_hex(ss.str()) == "01");
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
packer.pack(std::numeric_limits<uint8_t>::max());
|
||||
CHECK(string_to_hex(ss.str()) == "FF");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("int8_t") {
|
||||
SECTION("min") {
|
||||
packer.pack(std::numeric_limits<int8_t>::min());
|
||||
CHECK(string_to_hex(ss.str()) == "80");
|
||||
}
|
||||
|
||||
SECTION("zero") {
|
||||
packer.pack(int8_t(0));
|
||||
CHECK(string_to_hex(ss.str()) == "00");
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
packer.pack(int8_t(1));
|
||||
CHECK(string_to_hex(ss.str()) == "01");
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
packer.pack(std::numeric_limits<int8_t>::max());
|
||||
CHECK(string_to_hex(ss.str()) == "7F");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("uint16_t") {
|
||||
SECTION("min") {
|
||||
packer.pack(std::numeric_limits<uint16_t>::min());
|
||||
CHECK(string_to_hex(ss.str()) == "0000");
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
packer.pack(uint16_t(1));
|
||||
CHECK(string_to_hex(ss.str()) == "0100");
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
packer.pack(std::numeric_limits<uint16_t>::max());
|
||||
CHECK(string_to_hex(ss.str()) == "FFFF");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("int16_t") {
|
||||
SECTION("min") {
|
||||
packer.pack(std::numeric_limits<int16_t>::min());
|
||||
CHECK(string_to_hex(ss.str()) == "0080");
|
||||
}
|
||||
|
||||
SECTION("zero") {
|
||||
packer.pack(int16_t(0));
|
||||
CHECK(string_to_hex(ss.str()) == "0000");
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
packer.pack(int16_t(1));
|
||||
CHECK(string_to_hex(ss.str()) == "0100");
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
packer.pack(std::numeric_limits<int16_t>::max());
|
||||
CHECK(string_to_hex(ss.str()) == "FF7F");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("uint32_t") {
|
||||
SECTION("min") {
|
||||
packer.pack(std::numeric_limits<uint32_t>::min());
|
||||
CHECK(string_to_hex(ss.str()) == "00000000");
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
packer.pack(uint32_t(1));
|
||||
CHECK(string_to_hex(ss.str()) == "01000000");
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
packer.pack(std::numeric_limits<uint32_t>::max());
|
||||
CHECK(string_to_hex(ss.str()) == "FFFFFFFF");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("int32_t") {
|
||||
SECTION("min") {
|
||||
packer.pack(std::numeric_limits<int32_t>::min());
|
||||
CHECK(string_to_hex(ss.str()) == "00000080");
|
||||
}
|
||||
|
||||
SECTION("zero") {
|
||||
packer.pack(int32_t(0));
|
||||
CHECK(string_to_hex(ss.str()) == "00000000");
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
packer.pack(int32_t(1));
|
||||
CHECK(string_to_hex(ss.str()) == "01000000");
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
packer.pack(std::numeric_limits<int32_t>::max());
|
||||
CHECK(string_to_hex(ss.str()) == "FFFFFF7F");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("uint64_t") {
|
||||
SECTION("min") {
|
||||
packer.pack(std::numeric_limits<uint64_t>::min());
|
||||
CHECK(string_to_hex(ss.str()) == "0000000000000000");
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
packer.pack(uint64_t(1));
|
||||
CHECK(string_to_hex(ss.str()) == "0100000000000000");
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
packer.pack(std::numeric_limits<uint64_t>::max());
|
||||
CHECK(string_to_hex(ss.str()) == "FFFFFFFFFFFFFFFF");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("int64_t") {
|
||||
SECTION("min") {
|
||||
packer.pack(std::numeric_limits<int64_t>::min());
|
||||
CHECK(string_to_hex(ss.str()) == "0000000000000080");
|
||||
}
|
||||
|
||||
SECTION("zero") {
|
||||
packer.pack(int64_t(0));
|
||||
CHECK(string_to_hex(ss.str()) == "0000000000000000");
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
packer.pack(int64_t(1));
|
||||
CHECK(string_to_hex(ss.str()) == "0100000000000000");
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
packer.pack(std::numeric_limits<int64_t>::max());
|
||||
CHECK(string_to_hex(ss.str()) == "FFFFFFFFFFFFFF7F");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("bool") {
|
||||
SECTION("true") {
|
||||
packer.pack(true);
|
||||
CHECK(string_to_hex(ss.str()) == "01");
|
||||
}
|
||||
|
||||
SECTION("false") {
|
||||
packer.pack(false);
|
||||
CHECK(string_to_hex(ss.str()) == "00");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("big endian") {
|
||||
PacketBuffer::Packer<std::ostream, boost::endian::order::big> packer(ss);
|
||||
|
||||
SECTION("uint8_t") {
|
||||
SECTION("min") {
|
||||
packer.pack(std::numeric_limits<uint8_t>::min());
|
||||
CHECK(string_to_hex(ss.str()) == "00");
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
packer.pack(uint8_t(1));
|
||||
CHECK(string_to_hex(ss.str()) == "01");
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
packer.pack(std::numeric_limits<uint8_t>::max());
|
||||
CHECK(string_to_hex(ss.str()) == "FF");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("int8_t") {
|
||||
SECTION("min") {
|
||||
packer.pack(std::numeric_limits<int8_t>::min());
|
||||
CHECK(string_to_hex(ss.str()) == "80");
|
||||
}
|
||||
|
||||
SECTION("zero") {
|
||||
packer.pack(int8_t(0));
|
||||
CHECK(string_to_hex(ss.str()) == "00");
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
packer.pack(int8_t(1));
|
||||
CHECK(string_to_hex(ss.str()) == "01");
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
packer.pack(std::numeric_limits<int8_t>::max());
|
||||
CHECK(string_to_hex(ss.str()) == "7F");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("uint16_t") {
|
||||
SECTION("min") {
|
||||
packer.pack(std::numeric_limits<uint16_t>::min());
|
||||
CHECK(string_to_hex(ss.str()) == "0000");
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
packer.pack(uint16_t(1));
|
||||
CHECK(string_to_hex(ss.str()) == "0001");
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
packer.pack(std::numeric_limits<uint16_t>::max());
|
||||
CHECK(string_to_hex(ss.str()) == "FFFF");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("int16_t") {
|
||||
SECTION("min") {
|
||||
packer.pack(std::numeric_limits<int16_t>::min());
|
||||
CHECK(string_to_hex(ss.str()) == "8000");
|
||||
}
|
||||
|
||||
SECTION("zero") {
|
||||
packer.pack(int16_t(0));
|
||||
CHECK(string_to_hex(ss.str()) == "0000");
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
packer.pack(int16_t(1));
|
||||
CHECK(string_to_hex(ss.str()) == "0001");
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
packer.pack(std::numeric_limits<int16_t>::max());
|
||||
CHECK(string_to_hex(ss.str()) == "7FFF");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("uint32_t") {
|
||||
SECTION("min") {
|
||||
packer.pack(std::numeric_limits<uint32_t>::min());
|
||||
CHECK(string_to_hex(ss.str()) == "00000000");
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
packer.pack(uint32_t(1));
|
||||
CHECK(string_to_hex(ss.str()) == "00000001");
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
packer.pack(std::numeric_limits<uint32_t>::max());
|
||||
CHECK(string_to_hex(ss.str()) == "FFFFFFFF");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("int32_t") {
|
||||
SECTION("min") {
|
||||
packer.pack(std::numeric_limits<int32_t>::min());
|
||||
CHECK(string_to_hex(ss.str()) == "80000000");
|
||||
}
|
||||
|
||||
SECTION("zero") {
|
||||
packer.pack(int32_t(0));
|
||||
CHECK(string_to_hex(ss.str()) == "00000000");
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
packer.pack(int32_t(1));
|
||||
CHECK(string_to_hex(ss.str()) == "00000001");
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
packer.pack(std::numeric_limits<int32_t>::max());
|
||||
CHECK(string_to_hex(ss.str()) == "7FFFFFFF");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("uint64_t") {
|
||||
SECTION("min") {
|
||||
packer.pack(std::numeric_limits<uint64_t>::min());
|
||||
CHECK(string_to_hex(ss.str()) == "0000000000000000");
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
packer.pack(uint64_t(1));
|
||||
CHECK(string_to_hex(ss.str()) == "0000000000000001");
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
packer.pack(std::numeric_limits<uint64_t>::max());
|
||||
CHECK(string_to_hex(ss.str()) == "FFFFFFFFFFFFFFFF");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("int64_t") {
|
||||
SECTION("min") {
|
||||
packer.pack(std::numeric_limits<int64_t>::min());
|
||||
CHECK(string_to_hex(ss.str()) == "8000000000000000");
|
||||
}
|
||||
|
||||
SECTION("zero") {
|
||||
packer.pack(int64_t(0));
|
||||
CHECK(string_to_hex(ss.str()) == "0000000000000000");
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
packer.pack(int64_t(1));
|
||||
CHECK(string_to_hex(ss.str()) == "0000000000000001");
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
packer.pack(std::numeric_limits<int64_t>::max());
|
||||
CHECK(string_to_hex(ss.str()) == "7FFFFFFFFFFFFFFF");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("bool") {
|
||||
SECTION("true") {
|
||||
packer.pack(true);
|
||||
CHECK(string_to_hex(ss.str()) == "01");
|
||||
}
|
||||
|
||||
SECTION("false") {
|
||||
packer.pack(false);
|
||||
CHECK(string_to_hex(ss.str()) == "00");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
113
tests/Serializer/Std/Array.cpp
Normal file
113
tests/Serializer/Std/Array.cpp
Normal 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.
|
||||
*/
|
||||
|
||||
#include <catch.hpp>
|
||||
#include <sstream>
|
||||
|
||||
#include <PacketBuffer/PacketBuffer.h>
|
||||
|
||||
namespace {
|
||||
std::string string_to_hex(const std::string& input) {
|
||||
static const char* const lut = "0123456789ABCDEF";
|
||||
size_t len = input.length();
|
||||
|
||||
std::string output;
|
||||
output.reserve(2 * len);
|
||||
for(size_t i = 0; i < len; ++i) {
|
||||
const unsigned char c = input[i];
|
||||
output.push_back(lut[c >> 4]);
|
||||
output.push_back(lut[c & 15]);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Serializer/Std/Array", "[serializer][std][array]") {
|
||||
|
||||
std::stringstream ss;
|
||||
PacketBuffer::Packer<std::ostream> packer(ss);
|
||||
PacketBuffer::Unpacker<std::istream> unpacker(ss);
|
||||
|
||||
SECTION("empty array") {
|
||||
SECTION("should be correctly packed") {
|
||||
std::array<uint8_t, 0> array;
|
||||
packer.pack(array);
|
||||
|
||||
CHECK(string_to_hex(ss.str()) == "");
|
||||
|
||||
SECTION("and should unpack back") {
|
||||
std::array<uint8_t, 0> unpacked;
|
||||
unpacker.unpack(unpacked);
|
||||
|
||||
CHECK(unpacked.size() == 0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("should be correctly packed") {
|
||||
std::array<uint8_t, 2> array = {100, 200};
|
||||
packer.pack(array);
|
||||
|
||||
CHECK(string_to_hex(ss.str()) == "64C8");
|
||||
|
||||
SECTION("and should unpack back") {
|
||||
std::array<uint8_t, 2> unpacked;
|
||||
unpacker.unpack(unpacked);
|
||||
|
||||
REQUIRE(unpacked.size() == 2);
|
||||
CHECK(unpacked == array);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Serializer/Std/CArray", "[serializer][std][c-array]") {
|
||||
std::stringstream ss;
|
||||
PacketBuffer::Packer<std::ostream> packer(ss);
|
||||
PacketBuffer::Unpacker<std::istream> unpacker(ss);
|
||||
|
||||
SECTION("should be correctly packed") {
|
||||
uint8_t array[4] = {1, 2, 3, 4};
|
||||
packer.pack(array);
|
||||
|
||||
CHECK(string_to_hex(ss.str()) == "01020304");
|
||||
|
||||
SECTION("and should unpack back") {
|
||||
uint8_t unpacked[4];
|
||||
unpacker.unpack(unpacked);
|
||||
|
||||
CHECK(unpacked[0] == array[0]);
|
||||
CHECK(unpacked[1] == array[1]);
|
||||
CHECK(unpacked[2] == array[2]);
|
||||
CHECK(unpacked[3] == array[3]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
109
tests/Serializer/Std/String.cpp
Normal file
109
tests/Serializer/Std/String.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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 <catch.hpp>
|
||||
#include <sstream>
|
||||
|
||||
#include <PacketBuffer/PacketBuffer.h>
|
||||
|
||||
namespace {
|
||||
std::string string_to_hex(const std::string& input) {
|
||||
static const char* const lut = "0123456789ABCDEF";
|
||||
size_t len = input.length();
|
||||
|
||||
std::string output;
|
||||
output.reserve(2 * len);
|
||||
for(size_t i = 0; i < len; ++i) {
|
||||
const unsigned char c = input[i];
|
||||
output.push_back(lut[c >> 4]);
|
||||
output.push_back(lut[c & 15]);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Serializer/Std/String", "[serializer][std][string]") {
|
||||
|
||||
std::stringstream ss;
|
||||
PacketBuffer::Packer<std::ostream> packer(ss);
|
||||
PacketBuffer::Unpacker<std::istream> unpacker(ss);
|
||||
|
||||
SECTION("empty string") {
|
||||
SECTION("should be correctly packed") {
|
||||
std::string string = "";
|
||||
packer.pack(string);
|
||||
|
||||
CHECK(string_to_hex(ss.str()) == "0000000000000000");
|
||||
|
||||
SECTION("and should unpack back") {
|
||||
std::string unpacked;
|
||||
unpacker.unpack(unpacked);
|
||||
|
||||
CHECK(unpacked.size() == 0);
|
||||
CHECK(unpacked == string);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("should be correctly packed") {
|
||||
std::string string = "Hello Testing World";
|
||||
packer.pack(string);
|
||||
|
||||
CHECK(string_to_hex(ss.str()) == "130000000000000048656C6C6F2054657374696E6720576F726C64");
|
||||
|
||||
SECTION("and should unpack back") {
|
||||
std::string unpacked;
|
||||
unpacker.unpack(unpacked);
|
||||
|
||||
REQUIRE(unpacked.size() == 19);
|
||||
CHECK(unpacked == string);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("with NULL character") {
|
||||
SECTION("should be correctly packed") {
|
||||
std::string string = "Hey";
|
||||
string.resize(4);
|
||||
string[3] = 0x00;
|
||||
packer.pack(string);
|
||||
|
||||
CHECK(string_to_hex(ss.str()) == "040000000000000048657900");
|
||||
|
||||
SECTION("and should unpack back") {
|
||||
std::string unpacked;
|
||||
unpacker.unpack(unpacked);
|
||||
|
||||
REQUIRE(unpacked.size() == 4);
|
||||
CHECK(unpacked == string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
413
tests/Unpacker.cpp
Normal file
413
tests/Unpacker.cpp
Normal file
@@ -0,0 +1,413 @@
|
||||
/*
|
||||
* 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 <catch.hpp>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <PacketBuffer/PacketBuffer.h>
|
||||
|
||||
std::string hex_to_string(const std::string& input) {
|
||||
static const char* const lut = "0123456789ABCDEF";
|
||||
size_t len = input.length();
|
||||
if(len & 1) throw std::invalid_argument("odd length");
|
||||
|
||||
std::string output;
|
||||
output.reserve(len / 2);
|
||||
for(size_t i = 0; i < len; i += 2) {
|
||||
char a = input[i];
|
||||
const char* p = std::lower_bound(lut, lut + 16, a);
|
||||
if(*p != a) throw std::invalid_argument("not a hex digit");
|
||||
|
||||
char b = input[i + 1];
|
||||
const char* q = std::lower_bound(lut, lut + 16, b);
|
||||
if(*q != b) throw std::invalid_argument("not a hex digit");
|
||||
|
||||
output.push_back(((p - lut) << 4) | (q - lut));
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
TEST_CASE("Unpacker", "[unpacker]") {
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
SECTION("little endian") {
|
||||
PacketBuffer::Unpacker<std::istream, boost::endian::order::little> unpacker(ss);
|
||||
|
||||
SECTION("uint8_t") {
|
||||
SECTION("min") {
|
||||
ss.str(hex_to_string("00"));
|
||||
CHECK(unpacker.unpack<uint8_t>() == 0);
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
ss.str(hex_to_string("01"));
|
||||
CHECK(unpacker.unpack<uint8_t>() == 1);
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
ss.str(hex_to_string("FF"));
|
||||
CHECK(unpacker.unpack<uint8_t>() == 255);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("int8_t") {
|
||||
SECTION("min") {
|
||||
ss.str(hex_to_string("80"));
|
||||
CHECK(unpacker.unpack<int8_t>() == -128);
|
||||
}
|
||||
|
||||
SECTION("zero") {
|
||||
ss.str(hex_to_string("00"));
|
||||
CHECK(unpacker.unpack<int8_t>() == 0);
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
ss.str(hex_to_string("01"));
|
||||
CHECK(unpacker.unpack<int8_t>() == 1);
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
ss.str(hex_to_string("7F"));
|
||||
CHECK(unpacker.unpack<int8_t>() == 127);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("uint16_t") {
|
||||
SECTION("min") {
|
||||
ss.str(hex_to_string("0000"));
|
||||
CHECK(unpacker.unpack<uint16_t>() == 0);
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
ss.str(hex_to_string("0100"));
|
||||
CHECK(unpacker.unpack<uint16_t>() == 1);
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
ss.str(hex_to_string("FFFF"));
|
||||
CHECK(unpacker.unpack<uint16_t>() == 65535);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("int16_t") {
|
||||
SECTION("min") {
|
||||
ss.str(hex_to_string("0080"));
|
||||
CHECK(unpacker.unpack<int16_t>() == -32768);
|
||||
}
|
||||
|
||||
SECTION("zero") {
|
||||
ss.str(hex_to_string("0000"));
|
||||
CHECK(unpacker.unpack<int16_t>() == 0);
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
ss.str(hex_to_string("0100"));
|
||||
CHECK(unpacker.unpack<int16_t>() == 1);
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
ss.str(hex_to_string("FF7F"));
|
||||
CHECK(unpacker.unpack<int16_t>() == 32767);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("uint32_t") {
|
||||
SECTION("min") {
|
||||
ss.str(hex_to_string("00000000"));
|
||||
CHECK(unpacker.unpack<uint32_t>() == 0);
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
ss.str(hex_to_string("01000000"));
|
||||
CHECK(unpacker.unpack<uint32_t>() == 1);
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
ss.str(hex_to_string("FFFFFFFF"));
|
||||
CHECK(unpacker.unpack<uint32_t>() == 4294967295);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("int32_t") {
|
||||
SECTION("min") {
|
||||
ss.str(hex_to_string("00000080"));
|
||||
CHECK(unpacker.unpack<int32_t>() == -2147483648);
|
||||
}
|
||||
|
||||
SECTION("zero") {
|
||||
ss.str(hex_to_string("00000000"));
|
||||
CHECK(unpacker.unpack<int32_t>() == 0);
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
ss.str(hex_to_string("01000000"));
|
||||
CHECK(unpacker.unpack<int32_t>() == 1);
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
ss.str(hex_to_string("FFFFFF7F"));
|
||||
CHECK(unpacker.unpack<int32_t>() == 2147483647);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("uint64_t") {
|
||||
SECTION("min") {
|
||||
ss.str(hex_to_string("0000000000000000"));
|
||||
CHECK(unpacker.unpack<uint64_t>() == 0);
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
ss.str(hex_to_string("0100000000000000"));
|
||||
CHECK(unpacker.unpack<uint64_t>() == 1);
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
ss.str(hex_to_string("FFFFFFFFFFFFFFFF"));
|
||||
CHECK(unpacker.unpack<uint64_t>() == 18446744073709551615UL);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("int64_t") {
|
||||
SECTION("min") {
|
||||
ss.str(hex_to_string("0000000000000080"));
|
||||
CHECK(unpacker.unpack<int64_t>() == -9223372036854775808L);
|
||||
}
|
||||
|
||||
SECTION("zero") {
|
||||
ss.str(hex_to_string("0000000000000000"));
|
||||
CHECK(unpacker.unpack<int64_t>() == 0);
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
ss.str(hex_to_string("0100000000000000"));
|
||||
CHECK(unpacker.unpack<int64_t>() == 1);
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
ss.str(hex_to_string("FFFFFFFFFFFFFF7F"));
|
||||
CHECK(unpacker.unpack<int64_t>() == 9223372036854775807L);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("bool") {
|
||||
SECTION("true") {
|
||||
ss.str(hex_to_string("01"));
|
||||
CHECK(unpacker.unpack<bool>() == true);
|
||||
}
|
||||
|
||||
SECTION("false") {
|
||||
ss.str(hex_to_string("00"));
|
||||
CHECK(unpacker.unpack<bool>() == false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("big endian") {
|
||||
PacketBuffer::Unpacker<std::istream, boost::endian::order::big> unpacker(ss);
|
||||
|
||||
SECTION("uint8_t") {
|
||||
SECTION("min") {
|
||||
ss.str(hex_to_string("00"));
|
||||
CHECK(unpacker.unpack<uint8_t>() == 0);
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
ss.str(hex_to_string("01"));
|
||||
CHECK(unpacker.unpack<uint8_t>() == 1);
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
ss.str(hex_to_string("FF"));
|
||||
CHECK(unpacker.unpack<uint8_t>() == 255);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("int8_t") {
|
||||
SECTION("min") {
|
||||
ss.str(hex_to_string("80"));
|
||||
CHECK(unpacker.unpack<int8_t>() == -128);
|
||||
}
|
||||
|
||||
SECTION("zero") {
|
||||
ss.str(hex_to_string("00"));
|
||||
CHECK(unpacker.unpack<int8_t>() == 0);
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
ss.str(hex_to_string("01"));
|
||||
CHECK(unpacker.unpack<int8_t>() == 1);
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
ss.str(hex_to_string("7F"));
|
||||
CHECK(unpacker.unpack<int8_t>() == 127);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("uint16_t") {
|
||||
SECTION("min") {
|
||||
ss.str(hex_to_string("0000"));
|
||||
CHECK(unpacker.unpack<uint16_t>() == 0);
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
ss.str(hex_to_string("0001"));
|
||||
CHECK(unpacker.unpack<uint16_t>() == 1);
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
ss.str(hex_to_string("FFFF"));
|
||||
CHECK(unpacker.unpack<uint16_t>() == 65535);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("int16_t") {
|
||||
SECTION("min") {
|
||||
ss.str(hex_to_string("8000"));
|
||||
CHECK(unpacker.unpack<int16_t>() == -32768);
|
||||
}
|
||||
|
||||
SECTION("zero") {
|
||||
ss.str(hex_to_string("0000"));
|
||||
CHECK(unpacker.unpack<int16_t>() == 0);
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
ss.str(hex_to_string("0001"));
|
||||
CHECK(unpacker.unpack<int16_t>() == 1);
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
ss.str(hex_to_string("7FFF"));
|
||||
CHECK(unpacker.unpack<int16_t>() == 32767);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("uint32_t") {
|
||||
SECTION("min") {
|
||||
ss.str(hex_to_string("00000000"));
|
||||
CHECK(unpacker.unpack<uint32_t>() == 0);
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
ss.str(hex_to_string("00000001"));
|
||||
CHECK(unpacker.unpack<uint32_t>() == 1);
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
ss.str(hex_to_string("FFFFFFFF"));
|
||||
CHECK(unpacker.unpack<uint32_t>() == 4294967295);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("int32_t") {
|
||||
SECTION("min") {
|
||||
ss.str(hex_to_string("80000000"));
|
||||
CHECK(unpacker.unpack<int32_t>() == -2147483648);
|
||||
}
|
||||
|
||||
SECTION("zero") {
|
||||
ss.str(hex_to_string("00000000"));
|
||||
CHECK(unpacker.unpack<int32_t>() == 0);
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
ss.str(hex_to_string("00000001"));
|
||||
CHECK(unpacker.unpack<int32_t>() == 1);
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
ss.str(hex_to_string("7FFFFFFF"));
|
||||
CHECK(unpacker.unpack<int32_t>() == 2147483647);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("uint64_t") {
|
||||
SECTION("min") {
|
||||
ss.str(hex_to_string("0000000000000000"));
|
||||
CHECK(unpacker.unpack<uint64_t>() == 0);
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
ss.str(hex_to_string("0000000000000001"));
|
||||
CHECK(unpacker.unpack<uint64_t>() == 1);
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
ss.str(hex_to_string("FFFFFFFFFFFFFFFF"));
|
||||
CHECK(unpacker.unpack<uint64_t>() == 18446744073709551615UL);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("int64_t") {
|
||||
SECTION("min") {
|
||||
ss.str(hex_to_string("8000000000000000"));
|
||||
CHECK(unpacker.unpack<int64_t>() == -9223372036854775808L);
|
||||
}
|
||||
|
||||
SECTION("zero") {
|
||||
ss.str(hex_to_string("0000000000000000"));
|
||||
CHECK(unpacker.unpack<int64_t>() == 0);
|
||||
}
|
||||
|
||||
SECTION("one") {
|
||||
ss.str(hex_to_string("0000000000000001"));
|
||||
CHECK(unpacker.unpack<int64_t>() == 1);
|
||||
}
|
||||
|
||||
SECTION("max") {
|
||||
ss.str(hex_to_string("7FFFFFFFFFFFFFFF"));
|
||||
CHECK(unpacker.unpack<int64_t>() == 9223372036854775807L);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("bool") {
|
||||
SECTION("true") {
|
||||
ss.str(hex_to_string("01"));
|
||||
CHECK(unpacker.unpack<bool>() == true);
|
||||
}
|
||||
|
||||
SECTION("false") {
|
||||
ss.str(hex_to_string("00"));
|
||||
CHECK(unpacker.unpack<bool>() == false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("should throw an error on overflow") {
|
||||
PacketBuffer::Unpacker<std::istream> unpacker(ss);
|
||||
|
||||
// REQUIRE_THROWS(unpacker.unpack<uint32_t>());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
32
tests/main.cpp
Normal file
32
tests/main.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define CATCH_CONFIG_MAIN
|
||||
|
||||
#include "catch.hpp"
|
||||
Reference in New Issue
Block a user