summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2023-06-17 21:58:32 +0200
committerRoman Smrž <roman.smrz@seznam.cz>2023-06-18 22:41:23 +0200
commite7d6aafd3c9353d9e6169ca775cf1dae618238cd (patch)
tree6df8f296d7db8dd9e7d23f5774009ccc5ee269a7 /src
parent2130d07cbf91e016fd21a730a8449dd4bd34a093 (diff)
Storage: iterable type for record item list
Diffstat (limited to 'src')
-rw-r--r--src/attach.cpp7
-rw-r--r--src/channel.cpp7
-rw-r--r--src/contact.cpp14
-rw-r--r--src/identity.cpp7
-rw-r--r--src/message.cpp7
-rw-r--r--src/pubkey.h7
-rw-r--r--src/set.cpp14
-rw-r--r--src/state.cpp14
-rw-r--r--src/storage.cpp165
9 files changed, 147 insertions, 95 deletions
diff --git a/src/attach.cpp b/src/attach.cpp
index 4bf06b1..74bc875 100644
--- a/src/attach.cpp
+++ b/src/attach.cpp
@@ -105,14 +105,9 @@ AttachIdentity AttachIdentity::load(const Ref & ref)
.keys = {},
};
- vector<vector<uint8_t>> keys;
- for (auto s : rec->items("skey"))
- if (const auto & b = s.asBinary())
- keys.push_back(*b);
-
return AttachIdentity {
.identity = *rec->item("identity").as<Signed<IdentityData>>(),
- .keys = keys,
+ .keys = rec->items("skey").asBinary(),
};
}
diff --git a/src/channel.cpp b/src/channel.cpp
index 08db911..b317f3d 100644
--- a/src/channel.cpp
+++ b/src/channel.cpp
@@ -26,15 +26,10 @@ Ref ChannelRequestData::store(const Storage & st) const
ChannelRequestData ChannelRequestData::load(const Ref & ref)
{
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),
+ .peers = rec->items("peer").as<Signed<IdentityData>>(),
.key = *key,
};
}
diff --git a/src/contact.cpp b/src/contact.cpp
index 0050f95..01aa710 100644
--- a/src/contact.cpp
+++ b/src/contact.cpp
@@ -111,19 +111,9 @@ ContactData ContactData::load(const Ref & ref)
if (!rec)
return ContactData();
- vector<Stored<ContactData>> prev;
- for (const auto & x : rec->items("PREV"))
- if (const auto & p = x.as<ContactData>())
- prev.push_back(*p);
-
- vector<Stored<Signed<IdentityData>>> identity;
- for (const auto & x : rec->items("identity"))
- if (const auto & i = x.asRef())
- identity.push_back(*i);
-
return ContactData {
- .prev = std::move(prev),
- .identity = std::move(identity),
+ .prev = rec->items("PREV").as<ContactData>(),
+ .identity = rec->items("identity").as<Signed<IdentityData>>(),
.name = rec->item("name").asText(),
};
}
diff --git a/src/identity.cpp b/src/identity.cpp
index 9077db2..3b8d3bf 100644
--- a/src/identity.cpp
+++ b/src/identity.cpp
@@ -239,14 +239,9 @@ void Identity::Builder::owner(const Identity & val)
IdentityData IdentityData::load(const Ref & ref)
{
if (auto rec = ref->asRecord()) {
- vector<Stored<Signed<IdentityData>>> prev;
- for (auto p : rec->items("SPREV"))
- if (const auto & x = p.as<Signed<IdentityData>>())
- prev.push_back(x.value());
-
if (auto keyIdentity = rec->item("key-id").as<PublicKey>())
return IdentityData {
- .prev = std::move(prev),
+ .prev = rec->items("SPREV").as<Signed<IdentityData>>(),
.name = rec->item("name").asText(),
.owner = rec->item("owner").as<Signed<IdentityData>>(),
.keyIdentity = keyIdentity.value(),
diff --git a/src/message.cpp b/src/message.cpp
index ff8e05b..06ee8ad 100644
--- a/src/message.cpp
+++ b/src/message.cpp
@@ -55,15 +55,10 @@ DirectMessageData DirectMessageData::load(const Ref & ref)
if (!rec)
return DirectMessageData();
- vector<Stored<DirectMessageData>> prev;
- for (auto p : rec->items("PREV"))
- if (const auto & x = p.as<DirectMessageData>())
- prev.push_back(*x);
-
auto fref = rec->item("from").asRef();
return DirectMessageData {
- .prev = std::move(prev),
+ .prev = rec->items("PREV").as<DirectMessageData>(),
.from = fref ? Identity::load(*fref) : nullopt,
.time = *rec->item("time").asDate(),
.text = rec->item("text").asText().value(),
diff --git a/src/pubkey.h b/src/pubkey.h
index 5cb693b..ca662ba 100644
--- a/src/pubkey.h
+++ b/src/pubkey.h
@@ -110,10 +110,9 @@ Signed<T> Signed<T>::load(const Ref & ref)
if (auto rec = ref->asRecord())
if (auto data = rec->item("SDATA").as<T>()) {
vector<Stored<Signature>> sigs;
- for (auto item : rec->items("sig"))
- if (auto sig = item.as<Signature>())
- if (sig.value()->verify(data.value().ref()))
- sigs.push_back(sig.value());
+ for (const auto & sig : rec->items("sig").as<Signature>())
+ if (sig->verify(data.value().ref()))
+ sigs.push_back(sig);
return Signed(*data, sigs);
}
diff --git a/src/set.cpp b/src/set.cpp
index d224af3..ce343d8 100644
--- a/src/set.cpp
+++ b/src/set.cpp
@@ -153,19 +153,9 @@ vector<Ref> SetBase::store() const
SetItem SetItem::load(const Ref & ref)
{
if (auto rec = ref->asRecord()) {
- vector<Stored<SetItem>> prev;
- for (auto p : rec->items("PREV"))
- if (const auto & x = p.as<SetItem>())
- prev.push_back(*x);
-
- vector<Ref> item;
- for (auto i : rec->items("item"))
- if (const auto & x = i.asRef())
- item.push_back(*x);
-
return SetItem {
- .prev = std::move(prev),
- .item = std::move(item),
+ .prev = rec->items("PREV").as<SetItem>(),
+ .item = rec->items("item").asRef(),
};
}
diff --git a/src/state.cpp b/src/state.cpp
index 6ad9f89..8e5dcad 100644
--- a/src/state.cpp
+++ b/src/state.cpp
@@ -22,9 +22,7 @@ LocalState::LocalState(const Ref & ref):
if (auto x = rec->item("id").asRef())
p->identity = Identity::load(*x);
- for (auto i : rec->items("shared"))
- if (const auto & x = i.as<SharedData>())
- p->shared.tip.push_back(*x);
+ p->shared.tip = rec->items("shared").as<SharedData>();
if (p->identity) {
vector<Stored<Signed<IdentityData>>> updates;
@@ -158,16 +156,10 @@ SharedData::SharedData(const Ref & ref)
if (!rec)
return;
- for (auto i : rec->items("PREV"))
- if (const auto & x = i.as<SharedData>())
- prev.push_back(*x);
-
+ prev = rec->items("PREV").as<SharedData>();
if (auto x = rec->item("type").asUUID())
type = *x;
-
- for (auto i : rec->items("value"))
- if (const auto & x = i.asRef())
- value.push_back(*x);
+ value = rec->items("value").asRef();
}
Ref SharedData::store(const Storage & st) const
diff --git a/src/storage.cpp b/src/storage.cpp
index fb3698c..4e56b2e 100644
--- a/src/storage.cpp
+++ b/src/storage.cpp
@@ -789,10 +789,9 @@ optional<Digest> Storage::Priv::copy(const ObjectT<S> & pobj, vector<Digest> * m
{
bool fail = false;
if (auto rec = pobj.asRecord())
- for (const auto & item : rec->items())
- if (auto r = item.asRef())
- if (!copy<S>(*r, missing))
- fail = true;
+ for (const auto & r : rec->items().asRef())
+ if (!copy<S>(r, missing))
+ fail = true;
if (fail)
return nullopt;
@@ -1032,24 +1031,13 @@ vector<Ref> Ref::previous() const
if (!rec)
return {};
- vector<Ref> res;
-
- auto sdata = rec->item("SDATA").asRef();
- if (sdata) {
- auto drec = sdata.value()->asRecord();
- if (!drec)
- return {};
-
- for (const Record::Item & i : drec->items("SPREV"))
- if (auto x = i.asRef())
- res.push_back(*x);
- return res;
+ if (auto sdata = rec->item("SDATA").asRef()) {
+ if (auto drec = sdata.value()->asRecord())
+ return drec->items("SPREV").asRef();
+ return {};
}
- for (const Record::Item & i : rec->items("PREV"))
- if (auto x = i.asRef())
- res.push_back(*x);
- return res;
+ return rec->items("PREV").asRef();
}
Generation Ref::generation() const
@@ -1177,6 +1165,125 @@ optional<typename RecordT<S>::Item::UnknownType> RecordT<S>::Item::asUnknown() c
return nullopt;
}
+template<class S>
+RecordT<S>::Items::Items(shared_ptr<const vector<Item>> items):
+ items(move(items)), filter(nullopt)
+{}
+
+template<class S>
+RecordT<S>::Items::Items(shared_ptr<const vector<Item>> items, string filter):
+ items(move(items)), filter(move(filter))
+{}
+
+template<class S>
+RecordT<S>::Items::Iterator::Iterator(const Items & source, size_t idx):
+ source(source), idx(idx)
+{}
+
+template<class S>
+typename RecordT<S>::Items::Iterator & RecordT<S>::Items::Iterator::operator++()
+{
+ const auto & items = *source.items;
+ do {
+ idx++;
+ } while (idx < items.size() &&
+ source.filter &&
+ items[idx].name != *source.filter);
+ return *this;
+}
+
+template<class S>
+typename RecordT<S>::Items::Iterator RecordT<S>::Items::begin() const
+{
+ return ++Iterator(*this, -1);
+}
+
+template<class S>
+typename RecordT<S>::Items::Iterator RecordT<S>::Items::end() const
+{
+ return Iterator(*this, items->size());
+}
+
+template<class S>
+vector<typename RecordT<S>::Item::Empty> RecordT<S>::Items::asEmpty() const
+{
+ vector<Empty> res;
+ for (const auto & item : *this)
+ if (holds_alternative<Empty>(item.value))
+ res.push_back(std::get<Empty>(item.value));
+ return res;
+}
+
+template<class S>
+vector<typename RecordT<S>::Item::Integer> RecordT<S>::Items::asInteger() const
+{
+ vector<Integer> res;
+ for (const auto & item : *this)
+ if (holds_alternative<Integer>(item.value))
+ res.push_back(std::get<Integer>(item.value));
+ return res;
+}
+
+template<class S>
+vector<typename RecordT<S>::Item::Text> RecordT<S>::Items::asText() const
+{
+ vector<Text> res;
+ for (const auto & item : *this)
+ if (holds_alternative<Text>(item.value))
+ res.push_back(std::get<Text>(item.value));
+ return res;
+}
+
+template<class S>
+vector<typename RecordT<S>::Item::Binary> RecordT<S>::Items::asBinary() const
+{
+ vector<Binary> res;
+ for (const auto & item : *this)
+ if (holds_alternative<Binary>(item.value))
+ res.push_back(std::get<Binary>(item.value));
+ return res;
+}
+
+template<class S>
+vector<typename RecordT<S>::Item::Date> RecordT<S>::Items::asDate() const
+{
+ vector<Date> res;
+ for (const auto & item : *this)
+ if (holds_alternative<Date>(item.value))
+ res.push_back(std::get<Date>(item.value));
+ return res;
+}
+
+template<class S>
+vector<typename RecordT<S>::Item::UUID> RecordT<S>::Items::asUUID() const
+{
+ vector<UUID> res;
+ for (const auto & item : *this)
+ if (holds_alternative<UUID>(item.value))
+ res.push_back(std::get<UUID>(item.value));
+ return res;
+}
+
+template<class S>
+vector<typename RecordT<S>::Item::Ref> RecordT<S>::Items::asRef() const
+{
+ vector<Ref> res;
+ for (const auto & item : *this)
+ if (holds_alternative<Ref>(item.value))
+ res.push_back(std::get<Ref>(item.value));
+ return res;
+}
+
+template<class S>
+vector<typename RecordT<S>::Item::UnknownType> RecordT<S>::Items::asUnknown() const
+{
+ vector<UnknownType> res;
+ for (const auto & item : *this)
+ if (holds_alternative<UnknownType>(item.value))
+ res.push_back(std::get<UnknownType>(item.value));
+ return res;
+}
+
template<class S>
RecordT<S>::RecordT(const vector<Item> & from):
@@ -1274,9 +1381,9 @@ vector<uint8_t> RecordT<S>::encode() const
}
template<class S>
-const vector<typename RecordT<S>::Item> & RecordT<S>::items() const
+typename RecordT<S>::Items RecordT<S>::items() const
{
- return *ptr;
+ return Items(ptr);
}
template<class S>
@@ -1296,14 +1403,9 @@ typename RecordT<S>::Item RecordT<S>::operator[](const string & name) const
}
template<class S>
-vector<typename RecordT<S>::Item> RecordT<S>::items(const string & name) const
+typename RecordT<S>::Items RecordT<S>::items(const string & name) const
{
- vector<Item> res;
- for (auto item : *ptr) {
- if (item.name == name)
- res.push_back(item);
- }
- return res;
+ return Items(ptr, name);
}
template<class S>
@@ -1544,9 +1646,8 @@ vector<Stored<Object>> erebos::collectStoredObjects(const Stored<Object> & from)
res.push_back(cur);
if (auto rec = cur->asRecord())
- for (const auto & item : rec->items())
- if (auto ref = item.asRef())
- queue.push_back(Stored<Object>::load(*ref));
+ for (const auto & ref : rec->items().asRef())
+ queue.push_back(Stored<Object>::load(ref));
}
return res;