diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..626ea89 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,23 @@ +version: 2 + +jobs: + build: + docker: + - image: "serega753/cpp_project:actual" + working_directory: /app/TP_CPP_PROJECT + steps: + - checkout + - setup_remote_docker: + docker_layer_caching: true + - run: + name: cd + command: 'cd /app/TP_CPP_PROJECT' + - run: + name: cp cmake + command: 'cp /app/net_cmake/CMakeLists.txt /app/TP_CPP_PROJECT/Net/' + - run: + name: Creating Build Files + command: 'cmake Net/CMakeLists.txt && cd Net/ && make' + - run: + name: testing + command: '/app/TP_CPP_PROJECT/Net/net_tests' \ No newline at end of file diff --git a/.gitignore b/.gitignore index 259148f..9c6671d 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,6 @@ *.exe *.out *.app +Net/CMakeLists.txt +Net/cmake-build-debug* +Net/.idea* diff --git a/Net/include/AbstractClientNetObject.h b/Net/include/AbstractClientNetObject.h new file mode 100644 index 0000000..1b63366 --- /dev/null +++ b/Net/include/AbstractClientNetObject.h @@ -0,0 +1,16 @@ +// +// Created by alex on 17.12.18. +// + +#ifndef NET_ABSTRACTCLIENTNETOBJECT_H +#define NET_ABSTRACTCLIENTNETOBJECT_H + +#include "AbstractNetObject.h" + +class AbstractClientNetObject : public AbstractNetObject +{ + +}; + + +#endif //NET_ABSTRACTCLIENTNETOBJECT_H diff --git a/Net/include/AbstractNetObject.h b/Net/include/AbstractNetObject.h new file mode 100644 index 0000000..a8c4d40 --- /dev/null +++ b/Net/include/AbstractNetObject.h @@ -0,0 +1,19 @@ +// +// Created by alex on 17.12.18. +// + +#ifndef NET_ABSTRACTNETOBJECT_H +#define NET_ABSTRACTNETOBJECT_H + +#include "Serializable.h" + +class AbstractNetObject +{ +public: + virtual void send(Serializable* serializable) = 0; + virtual std::vector> receive() = 0; + virtual void work() = 0; +}; + + +#endif //NET_ABSTRACTNETOBJECT_H diff --git a/Net/include/AbstractServerNetObject.h b/Net/include/AbstractServerNetObject.h new file mode 100644 index 0000000..3786091 --- /dev/null +++ b/Net/include/AbstractServerNetObject.h @@ -0,0 +1,18 @@ +// +// Created by alex on 17.12.18. +// + +#ifndef NET_ABSTRACTSERVERNETOBJECT_H +#define NET_ABSTRACTSERVERNETOBJECT_H + + +#include "AbstractNetObject.h" + +class AbstractServerNetObject :public AbstractNetObject +{ +public: + virtual void send(Serializable* serializable, int player_number) = 0; +}; + + +#endif //NET_ABSTRACTSERVERNETOBJECT_H diff --git a/Net/include/ClientNetObject.h b/Net/include/ClientNetObject.h new file mode 100644 index 0000000..a1ae774 --- /dev/null +++ b/Net/include/ClientNetObject.h @@ -0,0 +1,33 @@ +// +// Created by alex on 17.12.18. +// + +#ifndef NET_CLIENTNETOBJECT_H +#define NET_CLIENTNETOBJECT_H + +#include +#include "AbstractClientNetObject.h" +#include "DefaultAbstractFactory.h" +#include "noncopyable.h" + +class ClientNetObjectImpl; + +class ClientNetObject : public AbstractClientNetObject, public noncopyable +{ +public: + ClientNetObject(std::string ip, uint port, std::map _map, + std::string startobj_string, + std::string endobj_string, + size_t type_length, int wait_time); + ~ClientNetObject(); + + void send(Serializable *serializable) override; + std::vector> receive() override; + void work() override; + +private: + ClientNetObjectImpl *impl; +}; + + +#endif //NET_CLIENTNETOBJECT_H diff --git a/Net/include/DefaultAbstractFactory.h b/Net/include/DefaultAbstractFactory.h new file mode 100644 index 0000000..26c2448 --- /dev/null +++ b/Net/include/DefaultAbstractFactory.h @@ -0,0 +1,18 @@ +// +// Created by alex on 23.11.18. +// + +#ifndef NET_DEFAULTABSTRACTFACTORY_H +#define NET_DEFAULTABSTRACTFACTORY_H + +#include "Serializable.h" + +class DefaultAbstractFactory +{ +public: + virtual std::shared_ptr create() = 0; + virtual ~DefaultAbstractFactory() = default; +}; + + +#endif //NET_DEFAULTABSTRACTFACTORY_H diff --git a/Net/include/Serializable.h b/Net/include/Serializable.h new file mode 100644 index 0000000..9e7bb54 --- /dev/null +++ b/Net/include/Serializable.h @@ -0,0 +1,24 @@ +// +// Created by alex on 12.11.18. +// + +#ifndef NET_SERIALIZABLE_H +#define NET_SERIALIZABLE_H + +#include +#include +#include + +struct Serializable +{ +public: + virtual void serialize(boost::archive::text_oarchive& ar) = 0; + + virtual void deserialize(boost::archive::text_iarchive& ar) = 0; +// virtual void serialize(boost::archive::text_iarchive& ar, const unsigned int version) = 0; +// virtual void serialize(boost::archive::text_oarchive& ar, const unsigned int version) = 0; + virtual ~Serializable() = default; +}; + + +#endif //NET_SERIALIZABLE_H diff --git a/Net/include/ServerNetObject.h b/Net/include/ServerNetObject.h new file mode 100644 index 0000000..38ce79d --- /dev/null +++ b/Net/include/ServerNetObject.h @@ -0,0 +1,34 @@ +// +// Created by alex on 17.12.18. +// + +#ifndef NET_SERVERNETOBJECT_H +#define NET_SERVERNETOBJECT_H + + +#include +#include "AbstractServerNetObject.h" +#include "DefaultAbstractFactory.h" +#include "noncopyable.h" + +class ServerNetObjectImpl; + +class ServerNetObject : public AbstractServerNetObject, public noncopyable +{ +public: + ServerNetObject(std::string ip, uint port, int player_num, std::map _map, + std::string startobj_string, + std::string endobj_string, + size_t type_length, int wait_time); + ~ServerNetObject(); + + void send(Serializable *serializable) override; + std::vector> receive() override; + void work() override; + void send(Serializable *serializable, int player_number) override; +private: + ServerNetObjectImpl* impl; +}; + + +#endif //NET_SERVERNETOBJECT_H diff --git a/Net/include/noncopyable.h b/Net/include/noncopyable.h new file mode 100644 index 0000000..f7f13de --- /dev/null +++ b/Net/include/noncopyable.h @@ -0,0 +1,22 @@ +// +// Created by alex on 17.12.18. +// + +#ifndef NET_NONCOPYABLE_H +#define NET_NONCOPYABLE_H + + +class noncopyable +{ +protected: + noncopyable() = default; + ~noncopyable() = default; +public: + noncopyable(noncopyable&) = delete; + noncopyable(noncopyable&&) = delete; + noncopyable& operator=(noncopyable&) = delete; + noncopyable&& operator=(noncopyable&&) = delete; +}; + + +#endif //NET_NONCOPYABLE_H diff --git a/Net/non_public_include/SerializationOperation.h b/Net/non_public_include/SerializationOperation.h new file mode 100644 index 0000000..9a9123f --- /dev/null +++ b/Net/non_public_include/SerializationOperation.h @@ -0,0 +1,34 @@ +// +// Created by alex on 23.12.18. +// + +#ifndef NET_SERIALIZATIONOPERATION_H +#define NET_SERIALIZATIONOPERATION_H + +#include +#include +#include + +#include "DefaultAbstractFactory.h" + +class SerializationOperation +{ +public: + SerializationOperation(std::map _map, + std::string startobj_string, + std::string endobj_string, + size_t type_length); + + std::string serialize(Serializable* serializable) const; + std::shared_ptr deserialize(std::string& wrong_data_recv_buf, std::string& temp_recv_buf) const; + std::string get_endobj() const; + +private: + std::map map; + const std::string STARTOBJ; + const std::string ENDOBJ; + const size_t TYPE_LENGTH; +}; + + +#endif //NET_SERIALIZATIONOPERATION_H diff --git a/Net/src/ClientNetObject.cpp b/Net/src/ClientNetObject.cpp new file mode 100644 index 0000000..5a508e7 --- /dev/null +++ b/Net/src/ClientNetObject.cpp @@ -0,0 +1,40 @@ +// +// Created by alex on 17.12.18. +// + +#include "../include/ClientNetObject.h" +#include "ClientNetObjectImpl.cpp" + +ClientNetObject::ClientNetObject( + std::string ip, + uint port, + std::map _map, + std::string startobj_string = "STARTOBJ", + std::string endobj_string = "ENDOBJ", + size_t type_length = 3, int wait_time = 1) +{ + impl = new ClientNetObjectImpl(ip, port, _map, + startobj_string, + endobj_string, + type_length, wait_time); +} + +ClientNetObject::~ClientNetObject() +{ + delete impl; +} + +void ClientNetObject::send(Serializable *serializable) +{ + impl->send(serializable); +} + +std::vector> ClientNetObject::receive() +{ + return impl->receive(); +} + +void ClientNetObject::work() +{ + impl->work(); +} diff --git a/Net/src/ClientNetObjectImpl.cpp b/Net/src/ClientNetObjectImpl.cpp new file mode 100644 index 0000000..b148668 --- /dev/null +++ b/Net/src/ClientNetObjectImpl.cpp @@ -0,0 +1,155 @@ +// +// Created by alex on 17.12.18. +// + +#include +#include "../include/AbstractClientNetObject.h" +#include "SubSock.cpp" +#include "../non_public_include/SerializationOperation.h" + + +class ClientNetObjectImpl : public AbstractClientNetObject +{ +public: + ClientNetObjectImpl(std::string _ip, uint _port, std::map _map, + std::string startobj_string, + std::string endobj_string, + size_t type_length, int wait_time) + : + serializer(_map, + startobj_string, + endobj_string, + type_length), + ip(_ip), + port(_port), + WAIT_TIME_BETWEEN_SEND(wait_time) + { + sock = nullptr; + } + + ~ClientNetObjectImpl() + { + delete sock; + } + + void send(Serializable *serializable) override + { + std::string send_buf = serializer.serialize(serializable); + + static std::chrono::steady_clock::time_point send_time = std::chrono::steady_clock::now(); + while(std::chrono::steady_clock::now() < send_time + std::chrono::milliseconds(WAIT_TIME_BETWEEN_SEND)) + ; + send_time = std::chrono::steady_clock::now(); + + sock_mutex.lock(); + boost::asio::write(*(sock->socket),boost::asio::buffer(send_buf)); // send + sock_mutex.unlock(); + } + + std::vector> receive() override + { + buf_mutex.lock(); + auto temp = std::move(buf); + buf.clear(); + buf_mutex.unlock(); + return temp; + } + + void work() override + { + sock = new SubSock(context); + connect(); + tcp::no_delay option(true); + sock->socket->set_option(option); + sock->thread = new std::thread(std::bind(&ClientNetObjectImpl::read_sock, this)); + } + + void connect() + { + try + { + while(true) + { + tcp::resolver resolver(context); + boost::system::error_code ec; + boost::asio::connect(*(sock->socket), resolver.resolve(ip, std::to_string(port)), ec); + if(!ec) + break; + } + } + catch(std::exception& e) + { + std::cerr << e.what() << std::endl; + } + } + + void read_sock(); +private: + const SerializationOperation serializer; + + const std::string ip; + const uint port; + + const int WAIT_TIME_BETWEEN_SEND; + + std::vector> buf; + + boost::asio::io_context context; + std::mutex sock_mutex; + std::mutex buf_mutex; + + SubSock* sock; +}; + + +void ClientNetObjectImpl::read_sock() +{ + std::string wrong_data_recv_buf; // in case of unsuccessful parse this will be used as a buf to prevent data loss + while(!(sock->stop)) + { + std::string temp_recv_buf; + static std::string ENDOBJ = serializer.get_endobj(); + + sock_mutex.lock(); // lock socket mutex + + if(sock->socket->available()) + { + boost::asio::read_until(*(sock->socket), boost::asio::dynamic_buffer(temp_recv_buf), ENDOBJ); // read from socket + sock_mutex.unlock(); // unlock socket mutex + try + { + auto serializable = serializer.deserialize(wrong_data_recv_buf,temp_recv_buf); + + buf_mutex.lock(); // lock buf mutex + buf.push_back(serializable); // write to the buf + buf_mutex.unlock(); // unlock buf mutex + + } + catch(std::invalid_argument& e) + { + std::cerr << e.what() << std::endl; + } + } + else + { + sock_mutex.unlock(); + if(!wrong_data_recv_buf.empty()) + { + try + { + auto serializable = serializer.deserialize(wrong_data_recv_buf,temp_recv_buf); + + buf_mutex.lock(); // lock buf mutex + buf.push_back(serializable); // write to the buf + buf_mutex.unlock(); // unlock buf mutex + + } + catch(std::invalid_argument& e) + { + std::cerr << e.what() << std::endl; + } + } + } + } + sock->socket->close(); +} diff --git a/Net/src/SerializationOperation.cpp b/Net/src/SerializationOperation.cpp new file mode 100644 index 0000000..db096a7 --- /dev/null +++ b/Net/src/SerializationOperation.cpp @@ -0,0 +1,95 @@ +// +// Created by alex on 17.12.18. +// + +#include +#include +#include + +#include "DefaultAbstractFactory.h" +#include "../non_public_include/SerializationOperation.h" + +SerializationOperation::SerializationOperation(std::map _map, + std::string startobj_string, + std::string endobj_string, + size_t type_length) + : + map(_map), + STARTOBJ(startobj_string), + ENDOBJ(endobj_string), + TYPE_LENGTH(type_length) +{ + +} + +std::string SerializationOperation::serialize(Serializable* serializable) const +{ + std::stringstream stream; + boost::archive::text_oarchive archive(stream); + serializable->serialize(archive); + + std::string send_buf, temp_buf; + + temp_buf = stream.str(); + send_buf.append(STARTOBJ); + + send_buf.append(temp_buf); // write buf + send_buf.append(std::string(typeid(*serializable).name()).substr(0,TYPE_LENGTH)); // write object type + send_buf.append(ENDOBJ); + return send_buf; +} + +std::shared_ptr SerializationOperation::deserialize(std::string& wrong_data_recv_buf, std::string& temp_recv_buf) const +{ + std::shared_ptr serializable; // create pointer + try + { + std::string recv_buf; + if(!wrong_data_recv_buf.empty()) + recv_buf.append(wrong_data_recv_buf); + + recv_buf.append(temp_recv_buf); + + size_t object_start; + if((object_start = recv_buf.find(STARTOBJ)) == std::string::npos) + throw std::invalid_argument("BAD INET MESSAGE: NO OBJECT START"); + + size_t object_end; + if((object_end = recv_buf.find(ENDOBJ, object_start)) == std::string::npos) + throw std::invalid_argument("BAD INET MESSAGE: NO OBJECT END"); + + std::string type = recv_buf.substr( + object_end - TYPE_LENGTH, TYPE_LENGTH); // read first N bytes to check which class object was sent + + if(object_end + ENDOBJ.size() != recv_buf.size()) + wrong_data_recv_buf = recv_buf.substr(object_end); + else + wrong_data_recv_buf.clear(); + + recv_buf.erase(object_end - TYPE_LENGTH); // clear TYPE and ENDOBJ from message + recv_buf.erase(0, object_start + STARTOBJ.size()); // clear STARTOBJ + + + + + serializable = map.at(type)->create(); // create empty object + + // deserialize + std::stringstream stream; + stream << recv_buf; + boost::archive::text_iarchive archive(stream); + serializable->deserialize(archive); + } + catch(std::invalid_argument& e) + { + wrong_data_recv_buf.append(temp_recv_buf); + std::cerr << "RECV_BUF IS " << temp_recv_buf << std::endl; + throw; + } + return serializable; +} + +std::string SerializationOperation::get_endobj() const +{ + return ENDOBJ; +} diff --git a/Net/src/ServerNetObject.cpp b/Net/src/ServerNetObject.cpp new file mode 100644 index 0000000..43abe68 --- /dev/null +++ b/Net/src/ServerNetObject.cpp @@ -0,0 +1,46 @@ +// +// Created by alex on 17.12.18. +// + +#include "../include/ServerNetObject.h" +#include "ServerNetObjectImpl.cpp" + +ServerNetObject::ServerNetObject(std::string ip, + uint port, + int player_num, + std::map _map, + std::string startobj_string = "STARTOBJ", + std::string endobj_string = "ENDOBJ", + size_t type_length = 3, + int wait_time = 1) +{ + impl = new ServerNetObjectImpl(ip, port, + player_num, _map, + startobj_string, endobj_string, + type_length, wait_time); +} + +ServerNetObject::~ServerNetObject() +{ + delete impl; +} + +void ServerNetObject::send(Serializable *serializable, int player_number) +{ + impl->send(serializable, player_number); +} + +void ServerNetObject::send(Serializable *serializable) +{ + impl->send(serializable); +} + +std::vector> ServerNetObject::receive() +{ + return impl->receive(); +} + +void ServerNetObject::work() +{ + impl->work(); +} diff --git a/Net/src/ServerNetObjectImpl.cpp b/Net/src/ServerNetObjectImpl.cpp new file mode 100644 index 0000000..9549494 --- /dev/null +++ b/Net/src/ServerNetObjectImpl.cpp @@ -0,0 +1,166 @@ +// +// Created by alex on 17.12.18. +// + +#include +#include "../include/AbstractServerNetObject.h" +#include "SubSock.cpp" +#include "../non_public_include/SerializationOperation.h" + + +class ServerNetObjectImpl : public AbstractServerNetObject +{ +public: +// friend void read_client_socks(ServerNetObjectImpl* impl, int socks_index); + + ServerNetObjectImpl(std::string _ip, uint _port, int player_number, std::map _map, + std::string startobj_string, + std::string endobj_string, + size_t type_length, int wait_time) + : + serializer(_map, + startobj_string, + endobj_string, + type_length), + player_num(player_number), + ip(_ip), + port(_port), + WAIT_TIME_BETWEEN_SEND(wait_time) + { + socks = nullptr; + } + + ~ServerNetObjectImpl() + { + delete[] socks; + } + + void send(Serializable *serializable) override + { + std::string send_buf = serializer.serialize(serializable); + + static std::chrono::steady_clock::time_point send_time = std::chrono::steady_clock::now(); + while(std::chrono::steady_clock::now() < send_time + std::chrono::milliseconds(WAIT_TIME_BETWEEN_SEND)) + ; + send_time = std::chrono::steady_clock::now(); + + sock_mutex.lock(); + for(int i = 0; i < player_num; ++i) + { + boost::asio::write(*(socks[i].socket), boost::asio::buffer(send_buf)); // send + } + sock_mutex.unlock(); + } + + void read_client_socks(int socks_index); + + void send(Serializable *serializable, int player_number) override + { + std::string send_buf = serializer.serialize(serializable); + + sock_mutex.lock(); + boost::asio::write(*(socks[player_number].socket), boost::asio::buffer(send_buf)); // send + sock_mutex.unlock(); + } + + std::vector> receive() override + { + buf_mutex.lock(); + auto temp=std::move(buf); + buf.clear(); + buf_mutex.unlock(); + return temp; + } + + void work() override + { + socks = new SubSock[player_num]; + for(size_t i = 0; i < player_num; ++i) + { + socks[i].socket = new tcp::socket(context); + connect(i); + tcp::no_delay option(true); + socks[i].socket->set_option(option); + socks[i].thread = new std::thread(std::bind(&ServerNetObjectImpl::read_client_socks, this, i)); + } + } + + void connect(size_t socks_index) + { + static tcp::acceptor acceptor(context,tcp::endpoint(tcp::v4(),port)); + tcp::endpoint endpoint; + acceptor.accept(*(socks[socks_index].socket), endpoint); + std::cerr << endpoint.address() << ' ' << endpoint.port() << std::endl; + } + +private: + + + const SerializationOperation serializer; + + const int player_num; + + const std::string ip; + const uint port; + + const int WAIT_TIME_BETWEEN_SEND; + + boost::asio::io_context context; + std::mutex sock_mutex; + std::mutex buf_mutex; + SubSock* socks; // TODO(Me): unordered_map + + + std::vector> buf; +}; + +void ServerNetObjectImpl::read_client_socks(int socks_index) +{ + std::string wrong_data_recv_buf; // in case of unsuccessful parse this will be used as a buf to prevent data loss + while(!(socks[socks_index].stop)) + { + std::string temp_recv_buf; + static std::string ENDOBJ = serializer.get_endobj(); + sock_mutex.lock(); // lock socket mutex + + if(socks[socks_index].socket->available()) + { + boost::asio::read_until(*(socks[socks_index].socket), boost::asio::dynamic_buffer(temp_recv_buf), ENDOBJ); // read from socket + sock_mutex.unlock(); // unlock socket mutex + try + { + auto serializable = serializer.deserialize(wrong_data_recv_buf,temp_recv_buf); + + buf_mutex.lock(); // lock buf mutex + buf.push_back(serializable); // write to the buf + buf_mutex.unlock(); // unlock buf mutex + + } + catch(std::invalid_argument& e) + { + std::cerr << e.what() << std::endl; + } + } + else + { + sock_mutex.unlock(); // unlock socket mutex + if(!wrong_data_recv_buf.empty()) + { + try + { + auto serializable = serializer.deserialize(wrong_data_recv_buf,temp_recv_buf); + + buf_mutex.lock(); // lock buf mutex + buf.push_back(serializable); // write to the buf + buf_mutex.unlock(); // unlock buf mutex + + } + catch(std::invalid_argument& e) + { + std::cerr << e.what() << std::endl; + } + } + } + } + socks[socks_index].socket->close(); +} diff --git a/Net/src/SubSock.cpp b/Net/src/SubSock.cpp new file mode 100644 index 0000000..075de23 --- /dev/null +++ b/Net/src/SubSock.cpp @@ -0,0 +1,39 @@ +// +// Created by alex on 17.12.18. +// + +#include +#include + +using boost::asio::ip::tcp; + +struct SubSock +{ + SubSock(); + explicit SubSock(boost::asio::io_context& context); + std::thread* thread; + tcp::socket* socket; + bool stop; + ~SubSock(); +}; + +SubSock::SubSock() +{ + thread = nullptr; + stop = false; +} + +SubSock::SubSock(boost::asio::io_context& context) +{ + socket = new tcp::socket(context); + thread = nullptr; + stop = false; +} + +SubSock::~SubSock() +{ + stop = true; + thread->join(); + delete socket; + delete thread; +} \ No newline at end of file diff --git a/Net/test/gtest.cpp b/Net/test/gtest.cpp new file mode 100644 index 0000000..813c37c --- /dev/null +++ b/Net/test/gtest.cpp @@ -0,0 +1,12 @@ +// +// Created by alex on 29.10.18. +// + +#include + + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/Net/test/serialization_operation_test.cpp b/Net/test/serialization_operation_test.cpp new file mode 100644 index 0000000..cb851ca --- /dev/null +++ b/Net/test/serialization_operation_test.cpp @@ -0,0 +1,36 @@ +// +// Created by alex on 23.12.18. +// +#include +#include "serialized_stub.h" +#include "../non_public_include/SerializationOperation.h" +#include + + +TEST(SerializationOperation, serialize_deserialize_stuff) +{ + const int TYPE_LENGTH = 3; + std::map map; + map = { + { + {std::string(typeid(Stuff).name()).substr(0, 3), new StuffFactory()} + } + }; + SerializationOperation serializer(map, "startobj", "endobj", TYPE_LENGTH); + Stuff stuff; + stuff.int_field = 4; + stuff.bool_field = true; + stuff.char_field = 'f'; + stuff.string_field = "abcd"; + stuff.vector_field.push_back(1); + stuff.vector_field.push_back(2); + stuff.vector_field.push_back(3); + stuff.vector_field.push_back(5); + std::string data = serializer.serialize(&stuff); + std::string empty_string; + empty_string.clear(); + auto deserialized_data = serializer.deserialize(empty_string, data); + std::shared_ptr ptr = std::dynamic_pointer_cast(deserialized_data); + EXPECT_EQ(stuff, *(ptr.get())); + map.clear(); +} diff --git a/Net/test/serialized_stub.h b/Net/test/serialized_stub.h new file mode 100644 index 0000000..9745b1d --- /dev/null +++ b/Net/test/serialized_stub.h @@ -0,0 +1,60 @@ +// +// Created by alex on 23.12.18. +// + +#ifndef NET_SERIALIZED_STUB_H +#define NET_SERIALIZED_STUB_H + +#include "DefaultAbstractFactory.h" +#include +#include + + +struct Stuff : public Serializable +{ + int int_field; + char char_field; + bool bool_field; + std::string string_field; + std::vector vector_field; + + void serialize(boost::archive::text_oarchive& ar) + { + ar & int_field; + ar & char_field; + ar & bool_field; + ar & string_field; + ar & vector_field; + } + + void deserialize(boost::archive::text_iarchive& ar) + { + ar & int_field; + ar & char_field; + ar & bool_field; + ar & string_field; + ar & vector_field; + } + bool operator==(const Stuff other) const + { + return + other.int_field == int_field && + other.char_field == char_field && + other.bool_field == bool_field && + other.string_field == string_field && + other.vector_field == vector_field; + } +}; + +class StuffFactory : public DefaultAbstractFactory +{ +public: + std::shared_ptr create() + { + return std::make_shared(); + } + ~StuffFactory() = default; +}; + + +#endif //NET_SERIALIZED_STUB_H