From 6cf5244bc514042fe419fffe1cd26a7f5e3c778f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Thu, 16 Apr 2020 21:42:45 +0200 Subject: Remove optional from load result Makes loading of data well-defined for arbitrary object contents. Introduce zero reference and object to represent missing or mismatched parts. --- src/channel.cpp | 102 +++++++++++++++++++++++--------------------------------- 1 file changed, 42 insertions(+), 60 deletions(-) (limited to 'src/channel.cpp') diff --git a/src/channel.cpp b/src/channel.cpp index 50c5f97..b13a71e 100644 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -22,28 +22,25 @@ Ref ChannelRequestData::store(const Storage & st) const return st.storeObject(Record(std::move(items))); } -optional ChannelRequestData::load(const Ref & ref) +ChannelRequestData ChannelRequestData::load(const Ref & ref) { - auto rec = ref->asRecord(); - if (!rec) - return nullopt; - - remove_const::type peers; - for (const auto & i : rec->items("peer")) - if (auto p = i.as>()) - peers.push_back(*p); - - auto enc = rec->item("enc").asText(); - if (!enc || enc != "aes-128-gcm") - return nullopt; - - auto key = rec->item("key").as(); - if (!key) - return nullopt; + if (auto rec = ref->asRecord()) { + remove_const::type peers; + for (const auto & i : rec->items("peer")) + if (auto p = i.as>()) + peers.push_back(*p); + + if (rec->item("enc").asText() == "aes-128-gcm") + if (auto key = rec->item("key").as()) + return ChannelRequestData { + .peers = std::move(peers), + .key = *key, + }; + } return ChannelRequestData { - .peers = std::move(peers), - .key = *key, + .peers = {}, + .key = Stored::load(ref.storage().zref()), }; } @@ -58,27 +55,18 @@ Ref ChannelAcceptData::store(const Storage & st) const return st.storeObject(Record(std::move(items))); } -optional ChannelAcceptData::load(const Ref & ref) +ChannelAcceptData ChannelAcceptData::load(const Ref & ref) { - auto rec = ref->asRecord(); - if (!rec) - return nullopt; - - auto request = rec->item("req").as(); - if (!request) - return nullopt; - - auto enc = rec->item("enc").asText(); - if (!enc || enc != "aes-128-gcm") - return nullopt; - - auto key = rec->item("key").as(); - if (!key) - return nullopt; + if (auto rec = ref->asRecord()) + if (rec->item("enc").asText() == "aes-128-gcm") + return ChannelAcceptData { + .request = *rec->item("req").as(), + .key = *rec->item("key").as(), + }; return ChannelAcceptData { - .request = *request, - .key = *key, + .request = Stored::load(ref.storage().zref()), + .key = Stored::load(ref.storage().zref()), }; } @@ -114,26 +102,20 @@ Ref Channel::store(const Storage & st) const return st.storeObject(Record(std::move(items))); } -optional Channel::load(const Ref & ref) +Channel Channel::load(const Ref & ref) { - auto rec = ref->asRecord(); - if (!rec) - return nullopt; - - remove_const::type peers; - for (const auto & i : rec->items("peer")) - if (auto p = i.as>()) - peers.push_back(*p); - - auto enc = rec->item("enc").asText(); - if (!enc || enc != "aes-128-gcm") - return nullopt; - - auto key = rec->item("key").asBinary(); - if (!key) - return nullopt; - - return Channel(peers, std::move(*key)); + if (auto rec = ref->asRecord()) { + remove_const::type peers; + for (const auto & i : rec->items("peer")) + if (auto p = i.as>()) + peers.push_back(*p); + + if (rec->item("enc").asText() == "aes-128-gcm") + if (auto key = rec->item("key").asBinary()) + return Channel(peers, std::move(*key)); + } + + return Channel({}, {}); } Stored Channel::generateRequest(const Storage & st, @@ -146,12 +128,12 @@ Stored Channel::generateRequest(const Storage & st, return signKey->sign(st.store(ChannelRequestData { .peers = self.ref()->digest() < peer.ref()->digest() ? vector>> { - *Stored>::load(*self.ref()), - *Stored>::load(*peer.ref()), + Stored>::load(*self.ref()), + Stored>::load(*peer.ref()), } : vector>> { - *Stored>::load(*peer.ref()), - *Stored>::load(*self.ref()), + Stored>::load(*peer.ref()), + Stored>::load(*self.ref()), }, .key = SecretKexKey::generate(st).pub(), })); -- cgit v1.2.3