From b09e73f0abcc386719a2235cc3ae61fb1cbfc5ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Wed, 16 Aug 2023 20:53:58 +0200 Subject: Move network header definitions to protocol module --- src/network/protocol.cpp | 150 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) (limited to 'src/network/protocol.cpp') diff --git a/src/network/protocol.cpp b/src/network/protocol.cpp index c247bf0..c2c6c5d 100644 --- a/src/network/protocol.cpp +++ b/src/network/protocol.cpp @@ -7,7 +7,10 @@ #include #include +using std::holds_alternative; using std::move; +using std::nullopt; +using std::runtime_error; using std::scoped_lock; namespace erebos { @@ -122,6 +125,10 @@ void NetworkProtocol::shutdown() } +/******************************************************************************/ +/* Connection */ +/******************************************************************************/ + NetworkProtocol::Connection::Id NetworkProtocol::ConnectionPriv::id() const { return reinterpret_cast(this); @@ -195,4 +202,147 @@ void NetworkProtocol::Connection::close() p = nullptr; } + +/******************************************************************************/ +/* Header */ +/******************************************************************************/ + +bool NetworkProtocol::Header::Item::operator==(const Item & other) const +{ + if (type != other.type) + return false; + + if (value.index() != other.value.index()) + return false; + + if (holds_alternative(value)) + return std::get(value).digest() == + std::get(other.value).digest(); + + if (holds_alternative(value)) + return std::get(value) == std::get(other.value); + + throw runtime_error("unhandled network header item type"); +} + +optional NetworkProtocol::Header::load(const PartialRef & ref) +{ + return load(*ref); +} + +optional NetworkProtocol::Header::load(const PartialObject & obj) +{ + auto rec = obj.asRecord(); + if (!rec) + return nullopt; + + vector items; + for (const auto & item : rec->items()) { + if (item.name == "ACK") { + if (auto ref = item.asRef()) + items.emplace_back(Item { + .type = Type::Acknowledged, + .value = *ref, + }); + } else if (item.name == "REQ") { + if (auto ref = item.asRef()) + items.emplace_back(Item { + .type = Type::DataRequest, + .value = *ref, + }); + } else if (item.name == "RSP") { + if (auto ref = item.asRef()) + items.emplace_back(Item { + .type = Type::DataResponse, + .value = *ref, + }); + } else if (item.name == "ANN") { + if (auto ref = item.asRef()) + items.emplace_back(Item { + .type = Type::AnnounceSelf, + .value = *ref, + }); + } else if (item.name == "ANU") { + if (auto ref = item.asRef()) + items.emplace_back(Item { + .type = Type::AnnounceUpdate, + .value = *ref, + }); + } else if (item.name == "CRQ") { + if (auto ref = item.asRef()) + items.emplace_back(Item { + .type = Type::ChannelRequest, + .value = *ref, + }); + } else if (item.name == "CAC") { + if (auto ref = item.asRef()) + items.emplace_back(Item { + .type = Type::ChannelAccept, + .value = *ref, + }); + } else if (item.name == "STP") { + if (auto val = item.asUUID()) + items.emplace_back(Item { + .type = Type::ServiceType, + .value = *val, + }); + } else if (item.name == "SRF") { + if (auto ref = item.asRef()) + items.emplace_back(Item { + .type = Type::ServiceRef, + .value = *ref, + }); + } + } + + return NetworkProtocol::Header(items); +} + +PartialObject NetworkProtocol::Header::toObject() const +{ + vector ritems; + + for (const auto & item : items) { + switch (item.type) { + case Type::Acknowledged: + ritems.emplace_back("ACK", std::get(item.value)); + break; + + case Type::DataRequest: + ritems.emplace_back("REQ", std::get(item.value)); + break; + + case Type::DataResponse: + ritems.emplace_back("RSP", std::get(item.value)); + break; + + case Type::AnnounceSelf: + ritems.emplace_back("ANN", std::get(item.value)); + break; + + case Type::AnnounceUpdate: + ritems.emplace_back("ANU", std::get(item.value)); + break; + + case Type::ChannelRequest: + ritems.emplace_back("CRQ", std::get(item.value)); + break; + + case Type::ChannelAccept: + ritems.emplace_back("CAC", std::get(item.value)); + break; + + case Type::ServiceType: + ritems.emplace_back("STP", std::get(item.value)); + break; + + case Type::ServiceRef: + ritems.emplace_back("SRF", std::get(item.value)); + break; + } + } + + return PartialObject(PartialRecord(std::move(ritems))); +} + } -- cgit v1.2.3