From 9cc2493cd87e2419d3cfb432844a2bf45ec3178f Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 10 Dec 2022 19:51:56 +0200 Subject: [PATCH] Simplify the inner workings of Protocol The CompoundDef hierarchy was basically just a polymorphic wrapper for Serializer. Might as well make Serializer itself polymorphic. --- source/net/protocol.cpp | 2 +- source/net/protocol.h | 129 +++++++++++++++------------------------- 2 files changed, 48 insertions(+), 83 deletions(-) diff --git a/source/net/protocol.cpp b/source/net/protocol.cpp index bcad032..cee1836 100644 --- a/source/net/protocol.cpp +++ b/source/net/protocol.cpp @@ -14,7 +14,7 @@ Protocol::Protocol(unsigned npi): header_def(0), next_packet_id(npi) { - PacketDefBuilder >(*this, header_def, NullSerializer()) + PacketDefBuilder>(*this, header_def, Serializer()) (&PacketHeader::type)(&PacketHeader::length); } diff --git a/source/net/protocol.h b/source/net/protocol.h index 6d15a33..f9a2f37 100644 --- a/source/net/protocol.h +++ b/source/net/protocol.h @@ -35,26 +35,7 @@ private: struct Traits; template - struct CompoundTypeDef - { - virtual ~CompoundTypeDef() = default; - - virtual std::uint64_t get_hash() const = 0; - virtual char *serialize(const C &, char *, char *) const = 0; - virtual const char *deserialize(C &, const char *, const char *) const = 0; - }; - - template - struct CompoundDef: public CompoundTypeDef - { - S serializer; - - CompoundDef(const S &); - - std::uint64_t get_hash() const override; - char *serialize(const C &, char *, char *) const override; - const char *deserialize(C &, const char *, const char *) const override; - }; + class Serializer; template class BasicSerializer @@ -110,52 +91,55 @@ private: typedef C ValueType; private: - const CompoundTypeDef &def; + const Serializer &serializer; public: CompoundSerializer(const Protocol &); + std::uint64_t get_hash() const; char *serialize(const C &, char *, char *) const; const char *deserialize(C &, const char *, const char *) const; }; - template - class Serializer: public Head + template + class FieldSerializer: public Head { public: template struct Next { - typedef Serializer, typename Traits::Serializer> Type; + typedef FieldSerializer, typename Traits::Serializer> Type; }; private: - typedef typename S::ValueType P::*Pointer; + typedef typename S::ValueType C::*Pointer; Pointer ptr; S ser; public: - Serializer(const Head &, Pointer, const Protocol &); + FieldSerializer(const Head &, Pointer, const Protocol &); std::uint64_t get_hash() const; - char *serialize(const P &, char *, char *) const; - const char *deserialize(P &, const char *, const char *) const; + char *serialize(const C &, char *, char *) const; + const char *deserialize(C &, const char *, const char *) const; }; - template - class NullSerializer + template + class Serializer { public: template struct Next { - typedef Serializer::Serializer> Type; + typedef FieldSerializer, typename Traits::Serializer> Type; }; - std::uint64_t get_hash() const { return 0; } - char *serialize(const P &, char *b, char *) const { return b; } - const char *deserialize(P &, const char *b, const char *) const { return b; } + virtual ~Serializer() = default; + + virtual std::uint64_t get_hash() const { return 0; } + virtual char *serialize(const C &, char *b, char *) const { return b; } + virtual const char *deserialize(C &, const char *b, const char *) const { return b; } }; class PacketDefBase @@ -177,7 +161,7 @@ private: class PacketTypeDef: public PacketDefBase { private: - CompoundTypeDef

*compound; + Serializer

*serializer; public: PacketTypeDef(unsigned); @@ -188,9 +172,9 @@ private: template void set_serializer(const S &); - const CompoundTypeDef

&get_compound() const { return *compound; } + const Serializer

&get_serializer() const { return *serializer; } - std::uint64_t get_hash() const override { return compound->get_hash(); } + std::uint64_t get_hash() const override { return serializer->get_hash(); } char *serialize(const P &, char *, char *) const; const char *deserialize(P &, const char *, const char *) const; const char *dispatch(ReceiverBase &, const char *, const char *) const override; @@ -242,10 +226,10 @@ private: protected: template - PacketDefBuilder > add(unsigned); + PacketDefBuilder> add(unsigned); template - PacketDefBuilder > add(); + PacketDefBuilder> add(); const PacketDefBase &get_packet_by_class_id(unsigned) const; const PacketDefBase &get_packet_by_id(unsigned) const; @@ -272,15 +256,15 @@ unsigned Protocol::get_packet_class_id() } template -Protocol::PacketDefBuilder > Protocol::add(unsigned id) +Protocol::PacketDefBuilder> Protocol::add(unsigned id) { PacketTypeDef

*pdef = new PacketTypeDef

(id); add_packet(pdef); - return PacketDefBuilder >(*this, *pdef, NullSerializer

()); + return PacketDefBuilder>(*this, *pdef, Serializer

()); } template -Protocol::PacketDefBuilder > Protocol::add() +Protocol::PacketDefBuilder> Protocol::add() { return add

(next_packet_id++); } @@ -338,38 +322,13 @@ template<> struct Protocol::Traits }; template -struct Protocol::Traits > +struct Protocol::Traits> { static const std::uint16_t signature = 'A'; - typedef ArraySerializer > Serializer; + typedef ArraySerializer> Serializer; }; - -template -Protocol::CompoundDef::CompoundDef(const S &s): - serializer(s) -{ } - -template -std::uint64_t Protocol::CompoundDef::get_hash() const -{ - return hash_round<64>(serializer.get_hash(), 'C'); -} - -template -char *Protocol::CompoundDef::serialize(const C &com, char *buf, char *end) const -{ - return serializer.serialize(com, buf, end); -} - -template -const char *Protocol::CompoundDef::deserialize(C &com, const char *buf, const char *end) const -{ - return serializer.deserialize(com, buf, end); -} - - inline std::uint64_t Protocol::StringSerializer::get_hash() const { return Traits::signature; @@ -411,44 +370,50 @@ const char *Protocol::ArraySerializer::deserialize(A &array, const char *buf, template Protocol::CompoundSerializer::CompoundSerializer(const Protocol &proto): - def(proto.get_packet_by_class().get_compound()) + serializer(proto.get_packet_by_class().get_serializer()) { } +template +std::uint64_t Protocol::CompoundSerializer::get_hash() const +{ + return hash_round<64>(serializer.get_hash(), 'C'); +} + template char *Protocol::CompoundSerializer::serialize(const C &com, char *buf, char *end) const { - return def.serialize(com, buf, end); + return serializer.serialize(com, buf, end); } template const char *Protocol::CompoundSerializer::deserialize(C &com, const char *buf, const char *end) const { - return def.deserialize(com, buf, end); + return serializer.deserialize(com, buf, end); } template -Protocol::Serializer::Serializer(const Head &h, Pointer p, const Protocol &proto): +Protocol::FieldSerializer::FieldSerializer(const Head &h, Pointer p, const Protocol &proto): Head(h), ptr(p), ser(proto) { } template -std::uint64_t Protocol::Serializer::get_hash() const +std::uint64_t Protocol::FieldSerializer::get_hash() const { return hash_update<64>(Head::get_hash(), ser.get_hash()); } template -char *Protocol::Serializer::serialize(const P &pkt, char *buf, char *end) const +char *Protocol::FieldSerializer::serialize(const P &pkt, char *buf, char *end) const { buf = Head::serialize(pkt, buf, end); return ser.serialize(pkt.*ptr, buf, end); } template -const char *Protocol::Serializer::deserialize(P &pkt, const char *buf, const char *end) const +const char *Protocol::FieldSerializer::deserialize(P &pkt, const char *buf, const char *end) const { buf = Head::deserialize(pkt, buf, end); return ser.deserialize(pkt.*ptr, buf, end); @@ -458,33 +423,33 @@ const char *Protocol::Serializer::deserialize(P &pkt, const char *bu template Protocol::PacketTypeDef

::PacketTypeDef(unsigned i): PacketDefBase(i), - compound(new CompoundDef >(NullSerializer

())) + serializer(new Serializer

) { } template Protocol::PacketTypeDef

::~PacketTypeDef() { - delete compound; + delete serializer; } template template void Protocol::PacketTypeDef

::set_serializer(const S &ser) { - delete compound; - compound = new CompoundDef(ser); + delete serializer; + serializer = new S(ser); } template char *Protocol::PacketTypeDef

::serialize(const P &pkt, char *buf, char *end) const { - return compound->serialize(pkt, buf, end); + return serializer->serialize(pkt, buf, end); } template const char *Protocol::PacketTypeDef

::deserialize(P &pkt, const char *buf, const char *end) const { - return compound->deserialize(pkt, buf, end); + return serializer->deserialize(pkt, buf, end); } template -- 2.43.0