diff --git a/include/opendht/default_types.h b/include/opendht/default_types.h index db8f4395d25ce76ac886dd43f030544a6b5da445..33a2a3021b8de870445c08f175fdf5b88b67d5b1 100644 --- a/include/opendht/default_types.h +++ b/include/opendht/default_types.h @@ -23,18 +23,17 @@ namespace dht { -struct DhtMessage : public Value::Serializable<DhtMessage> +class DhtMessage : public Value::Serializable<DhtMessage> { +public: + static const ValueType TYPE; + DhtMessage(std::string s = {}, Blob msg = {}) : service(s), data(msg) {} std::string getService() const { return service; } - static const ValueType TYPE; - virtual const ValueType& getType() const override { - return TYPE; - } static Value::Filter getFilter() { return {}; } static bool storePolicy(InfoHash key, std::shared_ptr<Value>& value, InfoHash from, const sockaddr* from_addr, socklen_t from_len); @@ -44,57 +43,64 @@ struct DhtMessage : public Value::Serializable<DhtMessage> /** print value for debugging */ friend std::ostream& operator<< (std::ostream&, const DhtMessage&); -public: std::string service; Blob data; MSGPACK_DEFINE(service, data); }; -template <typename Type> -struct SignedValue : public Value::Serializable<Type> +template <typename T> +class SignedValue : public Value::Serializable<T> { +private: + using BaseClass = Value::Serializable<T>; + +public: virtual void unpackValue(const Value& v) override { from = v.owner.getId(); - Value::Serializable<Type>::unpackValue(v); + BaseClass::unpackValue(v); } + static Value::Filter getFilter() { return [](const Value& v){ return v.isSigned(); }; } -public: + dht::InfoHash from; }; -template <typename Type> -struct EncryptedValue : public SignedValue<Type> +template <typename T> +class EncryptedValue : public SignedValue<T> { +public: + using BaseClass = SignedValue<T>; + +public: virtual void unpackValue(const Value& v) override { to = v.recipient; - SignedValue<Type>::unpackValue(v); + BaseClass::unpackValue(v); } + static Value::Filter getFilter() { return Value::Filter::chain( - SignedValue<Type>::getFilter(), + BaseClass::getFilter(), [](const Value& v){ return v.recipient != InfoHash(); } ); } -public: dht::InfoHash to; }; -struct ImMessage : public SignedValue<ImMessage> +class ImMessage : public SignedValue<ImMessage> { +private: + using BaseClass = SignedValue<ImMessage>; + +public: + static const ValueType TYPE; + ImMessage() {} ImMessage(dht::Value::Id id, std::string&& m, long d = 0) - : id(id), msg(std::move(m)), date(d) {} + : id(id), msg(std::move(m)), date(d) {} - static const ValueType TYPE; - virtual const ValueType& getType() const override { - return TYPE; - } - static Value::Filter getFilter() { - return SignedValue::getFilter(); - } virtual void unpackValue(const Value& v) override { to = v.recipient; SignedValue::unpackValue(v); @@ -103,20 +109,22 @@ struct ImMessage : public SignedValue<ImMessage> dht::InfoHash to; dht::Value::Id id; std::string msg; - long date; + long date {0}; MSGPACK_DEFINE_MAP(id, msg, date); }; -struct TrustRequest : public EncryptedValue<TrustRequest> +class TrustRequest : public EncryptedValue<TrustRequest> { +private: + using BaseClass = EncryptedValue<TrustRequest>; + +public: + static const ValueType TYPE; + TrustRequest() {} TrustRequest(std::string s) : service(s) {} TrustRequest(std::string s, const Blob& d) : service(s), payload(d) {} - static const ValueType TYPE; - virtual const ValueType& getType() const override { - return TYPE; - } static Value::Filter getFilter() { return EncryptedValue::getFilter(); } @@ -126,15 +134,17 @@ struct TrustRequest : public EncryptedValue<TrustRequest> MSGPACK_DEFINE(service, payload); }; -struct IceCandidates : public EncryptedValue<IceCandidates> +class IceCandidates : public EncryptedValue<IceCandidates> { +private: + using BaseClass = EncryptedValue<IceCandidates>; + +public: + static const ValueType TYPE; + IceCandidates() {} IceCandidates(Value::Id msg_id, Blob ice) : id(msg_id), ice_data(ice) {} - static const ValueType TYPE; - virtual const ValueType& getType() const override { - return TYPE; - } static Value::Filter getFilter() { return EncryptedValue::getFilter(); } @@ -168,11 +178,16 @@ struct IceCandidates : public EncryptedValue<IceCandidates> Blob ice_data; }; - /* "Peer" announcement */ -struct IpServiceAnnouncement : public Value::Serializable<IpServiceAnnouncement> +class IpServiceAnnouncement : public Value::Serializable<IpServiceAnnouncement> { +private: + using BaseClass = Value::Serializable<IpServiceAnnouncement>; + +public: + static const ValueType TYPE; + IpServiceAnnouncement(in_port_t p = 0) { ss.ss_family = 0; setPort(p); @@ -226,7 +241,6 @@ struct IpServiceAnnouncement : public Value::Serializable<IpServiceAnnouncement> return ss; } - static const ValueType TYPE; virtual const ValueType& getType() const { return TYPE; } diff --git a/include/opendht/value.h b/include/opendht/value.h index 4be12f1790b4b919647da5b9cc99dffb9681f1a7..693014bc268f82d1cbdc1782ea4b9ede12d44169 100644 --- a/include/opendht/value.h +++ b/include/opendht/value.h @@ -175,38 +175,52 @@ struct Value }; } - template <typename T> - struct Serializable + class SerializableBase { + public: + SerializableBase() {} + virtual ~SerializableBase() {}; virtual const ValueType& getType() const = 0; + virtual void unpackValue(const Value& v) = 0; + virtual Value packValue() const = 0; + }; + + template <typename Derived, typename Base=SerializableBase> + class Serializable : public Base + { + public: + using Base::Base; + + virtual const ValueType& getType() const { + return Derived::TYPE; + } + virtual void unpackValue(const Value& v) { auto msg = msgpack::unpack((const char*)v.data.data(), v.data.size()); - msgpack::object obj = msg.get(); - obj.convert(static_cast<T*>(this)); + msg.get().convert(static_cast<Derived*>(this)); } virtual Value packValue() const { - return Value {getType(), static_cast<const T&>(*this)}; + return Value {getType(), static_cast<const Derived&>(*this)}; } - virtual ~Serializable() = default; }; template <typename T, - typename std::enable_if<std::is_base_of<Serializable<T>, T>::value, T>::type* = nullptr> + typename std::enable_if<std::is_base_of<SerializableBase, T>::value, T>::type* = nullptr> static Value pack(const T& obj) { return obj.packValue(); } template <typename T, - typename std::enable_if<!std::is_base_of<Serializable<T>, T>::value, T>::type* = nullptr> + typename std::enable_if<!std::is_base_of<SerializableBase, T>::value, T>::type* = nullptr> static Value pack(const T& obj) { return {ValueType::USER_DATA.id, packMsg<T>(obj)}; } template <typename T, - typename std::enable_if<std::is_base_of<Serializable<T>, T>::value, T>::type* = nullptr> + typename std::enable_if<std::is_base_of<SerializableBase, T>::value, T>::type* = nullptr> static T unpack(const Value& v) { T msg; @@ -215,7 +229,7 @@ struct Value } template <typename T, - typename std::enable_if<!std::is_base_of<Serializable<T>, T>::value, T>::type* = nullptr> + typename std::enable_if<!std::is_base_of<SerializableBase, T>::value, T>::type* = nullptr> static T unpack(const Value& v) { return unpackMsg<T>(v.data); @@ -245,7 +259,7 @@ struct Value : id(id), type(t), data(std::move(data)) {} Value(ValueType::Id t, const uint8_t* dat_ptr, size_t dat_len, Id id = INVALID_ID) : id(id), type(t), data(dat_ptr, dat_ptr+dat_len) {} - + template <typename Type> Value(ValueType::Id t, const Type& d, Id id = INVALID_ID) : id(id), type(t), data(packMsg(d)) {} @@ -405,7 +419,7 @@ struct Value }; template <typename T, - typename std::enable_if<std::is_base_of<Value::Serializable<T>, T>::value, T>::type* = nullptr> + typename std::enable_if<std::is_base_of<Value::SerializableBase, T>::value, T>::type* = nullptr> Value::Filter getFilterSet(Value::Filter f) { @@ -417,7 +431,7 @@ getFilterSet(Value::Filter f) } template <typename T, - typename std::enable_if<!std::is_base_of<Value::Serializable<T>, T>::value, T>::type* = nullptr> + typename std::enable_if<!std::is_base_of<Value::SerializableBase, T>::value, T>::type* = nullptr> Value::Filter getFilterSet(Value::Filter f) { @@ -425,7 +439,7 @@ getFilterSet(Value::Filter f) } template <typename T, - typename std::enable_if<std::is_base_of<Value::Serializable<T>, T>::value, T>::type* = nullptr> + typename std::enable_if<std::is_base_of<Value::SerializableBase, T>::value, T>::type* = nullptr> Value::Filter getFilterSet() { @@ -436,7 +450,7 @@ getFilterSet() } template <typename T, - typename std::enable_if<!std::is_base_of<Value::Serializable<T>, T>::value, T>::type* = nullptr> + typename std::enable_if<!std::is_base_of<Value::SerializableBase, T>::value, T>::type* = nullptr> Value::Filter getFilterSet() {