diff options
| author | Roman Smrž <roman.smrz@seznam.cz> | 2023-08-26 21:38:36 +0200 | 
|---|---|---|
| committer | Roman Smrž <roman.smrz@seznam.cz> | 2023-08-27 16:32:21 +0200 | 
| commit | 09c1e987f6ddfdefb26b6a5f359363303720d5fb (patch) | |
| tree | d87d0ef934b740a124333105053f561a9f4eca33 /src/network | |
| parent | c44b82faaf309c916a1aecf4ec939510e6384ae5 (diff) | |
Network: header item as variant of per-header-type structs
Diffstat (limited to 'src/network')
| -rw-r--r-- | src/network/protocol.cpp | 130 | ||||
| -rw-r--r-- | src/network/protocol.h | 28 | 
2 files changed, 61 insertions, 97 deletions
| diff --git a/src/network/protocol.cpp b/src/network/protocol.cpp index f38267f..ede7023 100644 --- a/src/network/protocol.cpp +++ b/src/network/protocol.cpp @@ -9,11 +9,12 @@  #include <mutex>  #include <system_error> +using std::get_if;  using std::holds_alternative;  using std::move;  using std::nullopt; -using std::runtime_error;  using std::scoped_lock; +using std::visit;  namespace erebos { @@ -327,21 +328,16 @@ void NetworkProtocol::Connection::trySendOutQueue()  /* Header                                                                     */  /******************************************************************************/ -bool NetworkProtocol::Header::Item::operator==(const Item & other) const +bool operator==(const NetworkProtocol::Header::Item & left, +		const NetworkProtocol::Header::Item & right)  { -	if (type != other.type) +	if (left.index() != right.index())  		return false; -	if (value.index() != other.value.index()) -		return false; - -	if (holds_alternative<Digest>(value)) -		return std::get<Digest>(value) == std::get<Digest>(other.value); - -	if (holds_alternative<UUID>(value)) -		return std::get<UUID>(value) == std::get<UUID>(other.value); - -	throw runtime_error("unhandled network header item type"); +	return visit([&](auto && arg) { +            using T = std::decay_t<decltype(arg)>; +	    return arg.value == std::get<T>(right).value; +	}, left);  }  optional<NetworkProtocol::Header> NetworkProtocol::Header::load(const PartialRef & ref) @@ -359,58 +355,31 @@ optional<NetworkProtocol::Header> NetworkProtocol::Header::load(const PartialObj  	for (const auto & item : rec->items()) {  		if (item.name == "ACK") {  			if (auto ref = item.asRef()) -				items.emplace_back(Item { -					.type = Type::Acknowledged, -					.value = ref->digest(), -				}); +				items.emplace_back(Acknowledged { ref->digest() });  		} else if (item.name == "REQ") {  			if (auto ref = item.asRef()) -				items.emplace_back(Item { -					.type = Type::DataRequest, -					.value = ref->digest(), -				}); +				items.emplace_back(DataRequest { ref->digest() });  		} else if (item.name == "RSP") {  			if (auto ref = item.asRef()) -				items.emplace_back(Item { -					.type = Type::DataResponse, -					.value = ref->digest(), -				}); +				items.emplace_back(DataResponse { ref->digest() });  		} else if (item.name == "ANN") {  			if (auto ref = item.asRef()) -				items.emplace_back(Item { -					.type = Type::AnnounceSelf, -					.value = ref->digest(), -				}); +				items.emplace_back(AnnounceSelf { ref->digest() });  		} else if (item.name == "ANU") {  			if (auto ref = item.asRef()) -				items.emplace_back(Item { -					.type = Type::AnnounceUpdate, -					.value = ref->digest(), -				}); +				items.emplace_back(AnnounceUpdate { ref->digest() });  		} else if (item.name == "CRQ") {  			if (auto ref = item.asRef()) -				items.emplace_back(Item { -					.type = Type::ChannelRequest, -					.value = ref->digest(), -				}); +				items.emplace_back(ChannelRequest { ref->digest() });  		} else if (item.name == "CAC") {  			if (auto ref = item.asRef()) -				items.emplace_back(Item { -					.type = Type::ChannelAccept, -					.value = ref->digest(), -				}); +				items.emplace_back(ChannelAccept { ref->digest() });  		} else if (item.name == "STP") {  			if (auto val = item.asUUID()) -				items.emplace_back(Item { -					.type = Type::ServiceType, -					.value = *val, -				}); +				items.emplace_back(ServiceType { *val });  		} else if (item.name == "SRF") {  			if (auto ref = item.asRef()) -				items.emplace_back(Item { -					.type = Type::ServiceRef, -					.value = ref->digest(), -				}); +				items.emplace_back(ServiceRef { ref->digest() });  		}  	} @@ -422,43 +391,32 @@ PartialObject NetworkProtocol::Header::toObject(const PartialStorage & st) const  	vector<PartialRecord::Item> ritems;  	for (const auto & item : items) { -		switch (item.type) { -		case Type::Acknowledged: -			ritems.emplace_back("ACK", st.ref(std::get<Digest>(item.value))); -			break; - -		case Type::DataRequest: -			ritems.emplace_back("REQ", st.ref(std::get<Digest>(item.value))); -			break; - -		case Type::DataResponse: -			ritems.emplace_back("RSP", st.ref(std::get<Digest>(item.value))); -			break; - -		case Type::AnnounceSelf: -			ritems.emplace_back("ANN", st.ref(std::get<Digest>(item.value))); -			break; - -		case Type::AnnounceUpdate: -			ritems.emplace_back("ANU", st.ref(std::get<Digest>(item.value))); -			break; - -		case Type::ChannelRequest: -			ritems.emplace_back("CRQ", st.ref(std::get<Digest>(item.value))); -			break; - -		case Type::ChannelAccept: -			ritems.emplace_back("CAC", st.ref(std::get<Digest>(item.value))); -			break; - -		case Type::ServiceType: -			ritems.emplace_back("STP", std::get<UUID>(item.value)); -			break; - -		case Type::ServiceRef: -			ritems.emplace_back("SRF", st.ref(std::get<Digest>(item.value))); -			break; -		} +		if (const auto * ptr = get_if<Acknowledged>(&item)) +			ritems.emplace_back("ACK", st.ref(ptr->value)); + +		else if (const auto * ptr = get_if<DataRequest>(&item)) +			ritems.emplace_back("REQ", st.ref(ptr->value)); + +		else if (const auto * ptr = get_if<DataResponse>(&item)) +			ritems.emplace_back("RSP", st.ref(ptr->value)); + +		else if (const auto * ptr = get_if<AnnounceSelf>(&item)) +			ritems.emplace_back("ANN", st.ref(ptr->value)); + +		else if (const auto * ptr = get_if<AnnounceUpdate>(&item)) +			ritems.emplace_back("ANU", st.ref(ptr->value)); + +		else if (const auto * ptr = get_if<ChannelRequest>(&item)) +			ritems.emplace_back("CRQ", st.ref(ptr->value)); + +		else if (const auto * ptr = get_if<ChannelAccept>(&item)) +			ritems.emplace_back("CAC", st.ref(ptr->value)); + +		else if (const auto * ptr = get_if<ServiceType>(&item)) +			ritems.emplace_back("STP", ptr->value); + +		else if (const auto * ptr = get_if<ServiceRef>(&item)) +			ritems.emplace_back("SRF", st.ref(ptr->value));  	}  	return PartialObject(PartialRecord(std::move(ritems))); diff --git a/src/network/protocol.h b/src/network/protocol.h index c5803ce..df29c05 100644 --- a/src/network/protocol.h +++ b/src/network/protocol.h @@ -106,7 +106,17 @@ struct NetworkProtocol::ConnectionReadReady { Connection::Id id; };  struct NetworkProtocol::Header  { -	enum class Type { +	struct Acknowledged { Digest value; }; +	struct DataRequest { Digest value; }; +	struct DataResponse { Digest value; }; +	struct AnnounceSelf { Digest value; }; +	struct AnnounceUpdate { Digest value; }; +	struct ChannelRequest { Digest value; }; +	struct ChannelAccept { Digest value; }; +	struct ServiceType { UUID value; }; +	struct ServiceRef { Digest value; }; + +	using Item = variant<  		Acknowledged,  		DataRequest,  		DataResponse, @@ -115,16 +125,7 @@ struct NetworkProtocol::Header  		ChannelRequest,  		ChannelAccept,  		ServiceType, -		ServiceRef, -	}; - -	struct Item { -		const Type type; -		const variant<Digest, UUID> value; - -		bool operator==(const Item &) const; -		bool operator!=(const Item & other) const { return !(*this == other); } -	}; +		ServiceRef>;  	Header(const vector<Item> & items): items(items) {}  	static optional<Header> load(const PartialRef &); @@ -134,6 +135,11 @@ struct NetworkProtocol::Header  	const vector<Item> items;  }; +bool operator==(const NetworkProtocol::Header::Item &, const NetworkProtocol::Header::Item &); +inline bool operator!=(const NetworkProtocol::Header::Item & left, +		const NetworkProtocol::Header::Item & right) +{ return not (left == right); } +  class ReplyBuilder  {  public: |