summaryrefslogtreecommitdiff
path: root/src/channel.cpp
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2020-04-16 21:42:45 +0200
committerRoman Smrž <roman.smrz@seznam.cz>2020-04-16 21:42:45 +0200
commit6cf5244bc514042fe419fffe1cd26a7f5e3c778f (patch)
tree4a72abf80980c3d10656bd82606a69329867d057 /src/channel.cpp
parenta76a9ad65fa549d2c1650bb5a7d9a657186edc43 (diff)
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.
Diffstat (limited to 'src/channel.cpp')
-rw-r--r--src/channel.cpp102
1 files changed, 42 insertions, 60 deletions
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> ChannelRequestData::load(const Ref & ref)
+ChannelRequestData ChannelRequestData::load(const Ref & ref)
{
- auto rec = ref->asRecord();
- if (!rec)
- return nullopt;
-
- remove_const<decltype(peers)>::type peers;
- for (const auto & i : rec->items("peer"))
- if (auto p = i.as<Signed<IdentityData>>())
- peers.push_back(*p);
-
- auto enc = rec->item("enc").asText();
- if (!enc || enc != "aes-128-gcm")
- return nullopt;
-
- auto key = rec->item("key").as<PublicKexKey>();
- if (!key)
- return nullopt;
+ if (auto rec = ref->asRecord()) {
+ remove_const<decltype(peers)>::type peers;
+ for (const auto & i : rec->items("peer"))
+ if (auto p = i.as<Signed<IdentityData>>())
+ peers.push_back(*p);
+
+ if (rec->item("enc").asText() == "aes-128-gcm")
+ if (auto key = rec->item("key").as<PublicKexKey>())
+ return ChannelRequestData {
+ .peers = std::move(peers),
+ .key = *key,
+ };
+ }
return ChannelRequestData {
- .peers = std::move(peers),
- .key = *key,
+ .peers = {},
+ .key = Stored<PublicKexKey>::load(ref.storage().zref()),
};
}
@@ -58,27 +55,18 @@ Ref ChannelAcceptData::store(const Storage & st) const
return st.storeObject(Record(std::move(items)));
}
-optional<ChannelAcceptData> 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<ChannelRequest>();
- if (!request)
- return nullopt;
-
- auto enc = rec->item("enc").asText();
- if (!enc || enc != "aes-128-gcm")
- return nullopt;
-
- auto key = rec->item("key").as<PublicKexKey>();
- if (!key)
- return nullopt;
+ if (auto rec = ref->asRecord())
+ if (rec->item("enc").asText() == "aes-128-gcm")
+ return ChannelAcceptData {
+ .request = *rec->item("req").as<ChannelRequest>(),
+ .key = *rec->item("key").as<PublicKexKey>(),
+ };
return ChannelAcceptData {
- .request = *request,
- .key = *key,
+ .request = Stored<ChannelRequest>::load(ref.storage().zref()),
+ .key = Stored<PublicKexKey>::load(ref.storage().zref()),
};
}
@@ -114,26 +102,20 @@ Ref Channel::store(const Storage & st) const
return st.storeObject(Record(std::move(items)));
}
-optional<Channel> Channel::load(const Ref & ref)
+Channel Channel::load(const Ref & ref)
{
- auto rec = ref->asRecord();
- if (!rec)
- return nullopt;
-
- remove_const<decltype(peers)>::type peers;
- for (const auto & i : rec->items("peer"))
- if (auto p = i.as<Signed<IdentityData>>())
- 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<decltype(peers)>::type peers;
+ for (const auto & i : rec->items("peer"))
+ if (auto p = i.as<Signed<IdentityData>>())
+ 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<ChannelRequest> Channel::generateRequest(const Storage & st,
@@ -146,12 +128,12 @@ Stored<ChannelRequest> Channel::generateRequest(const Storage & st,
return signKey->sign(st.store(ChannelRequestData {
.peers = self.ref()->digest() < peer.ref()->digest() ?
vector<Stored<Signed<IdentityData>>> {
- *Stored<Signed<IdentityData>>::load(*self.ref()),
- *Stored<Signed<IdentityData>>::load(*peer.ref()),
+ Stored<Signed<IdentityData>>::load(*self.ref()),
+ Stored<Signed<IdentityData>>::load(*peer.ref()),
} :
vector<Stored<Signed<IdentityData>>> {
- *Stored<Signed<IdentityData>>::load(*peer.ref()),
- *Stored<Signed<IdentityData>>::load(*self.ref()),
+ Stored<Signed<IdentityData>>::load(*peer.ref()),
+ Stored<Signed<IdentityData>>::load(*self.ref()),
},
.key = SecretKexKey::generate(st).pub(),
}));