diff options
author | Roman Smrž <roman.smrz@seznam.cz> | 2023-08-16 20:53:58 +0200 |
---|---|---|
committer | Roman Smrž <roman.smrz@seznam.cz> | 2023-08-16 21:49:39 +0200 |
commit | b09e73f0abcc386719a2235cc3ae61fb1cbfc5ca (patch) | |
tree | 462085ac8fb592f4a2c07446058a7e761b51dfac /src/network/protocol.cpp | |
parent | 2ed8103ff1c0fca7372b3c3888f590ba41c525e6 (diff) |
Move network header definitions to protocol module
Diffstat (limited to 'src/network/protocol.cpp')
-rw-r--r-- | src/network/protocol.cpp | 150 |
1 files changed, 150 insertions, 0 deletions
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 <mutex> #include <system_error> +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<uintptr_t>(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<PartialRef>(value)) + return std::get<PartialRef>(value).digest() == + std::get<PartialRef>(other.value).digest(); + + if (holds_alternative<UUID>(value)) + return std::get<UUID>(value) == std::get<UUID>(other.value); + + throw runtime_error("unhandled network header item type"); +} + +optional<NetworkProtocol::Header> NetworkProtocol::Header::load(const PartialRef & ref) +{ + return load(*ref); +} + +optional<NetworkProtocol::Header> NetworkProtocol::Header::load(const PartialObject & obj) +{ + auto rec = obj.asRecord(); + if (!rec) + return nullopt; + + vector<Item> 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<PartialRecord::Item> ritems; + + for (const auto & item : items) { + switch (item.type) { + case Type::Acknowledged: + ritems.emplace_back("ACK", std::get<PartialRef>(item.value)); + break; + + case Type::DataRequest: + ritems.emplace_back("REQ", std::get<PartialRef>(item.value)); + break; + + case Type::DataResponse: + ritems.emplace_back("RSP", std::get<PartialRef>(item.value)); + break; + + case Type::AnnounceSelf: + ritems.emplace_back("ANN", std::get<PartialRef>(item.value)); + break; + + case Type::AnnounceUpdate: + ritems.emplace_back("ANU", std::get<PartialRef>(item.value)); + break; + + case Type::ChannelRequest: + ritems.emplace_back("CRQ", std::get<PartialRef>(item.value)); + break; + + case Type::ChannelAccept: + ritems.emplace_back("CAC", std::get<PartialRef>(item.value)); + break; + + case Type::ServiceType: + ritems.emplace_back("STP", std::get<UUID>(item.value)); + break; + + case Type::ServiceRef: + ritems.emplace_back("SRF", std::get<PartialRef>(item.value)); + break; + } + } + + return PartialObject(PartialRecord(std::move(ritems))); +} + } |