aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/connection.cpp30
-rw-r--r--lib/events/event.h29
2 files changed, 44 insertions, 15 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp
index 81151135..6e04883e 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -977,22 +977,22 @@ void Connection::Private::consumeToDeviceEvents(Events&& toDeviceEvents)
if (!toDeviceEvents.empty()) {
qCDebug(E2EE) << "Consuming" << toDeviceEvents.size()
<< "to-device events";
- visitEach(toDeviceEvents, [this](const EncryptedEvent& event) {
- if (event.algorithm() != OlmV1Curve25519AesSha2AlgoKey) {
- qCDebug(E2EE) << "Unsupported algorithm" << event.id()
- << "for event" << event.algorithm();
- return;
- }
- if (isKnownCurveKey(event.senderId(), event.senderKey())) {
- handleEncryptedToDeviceEvent(event);
- return;
+ for (auto&& tdEvt : toDeviceEvents)
+ if (auto&& event = eventCast<EncryptedEvent>(std::move(tdEvt))) {
+ if (event->algorithm() != OlmV1Curve25519AesSha2AlgoKey) {
+ qCDebug(E2EE) << "Unsupported algorithm" << event->id()
+ << "for event" << event->algorithm();
+ return;
+ }
+ if (isKnownCurveKey(event->senderId(), event->senderKey())) {
+ handleEncryptedToDeviceEvent(*event);
+ return;
+ }
+ trackedUsers += event->senderId();
+ outdatedUsers += event->senderId();
+ encryptionUpdateRequired = true;
+ pendingEncryptedEvents.push_back(std::move(event));
}
- trackedUsers += event.senderId();
- outdatedUsers += event.senderId();
- encryptionUpdateRequired = true;
- pendingEncryptedEvents.push_back(
- makeEvent<EncryptedEvent>(event.fullJson()));
- });
}
#endif
}
diff --git a/lib/events/event.h b/lib/events/event.h
index da6cf3c7..043d4f54 100644
--- a/lib/events/event.h
+++ b/lib/events/event.h
@@ -332,6 +332,13 @@ inline bool isUnknown(const Event& e)
return e.type() == UnknownEventTypeId;
}
+//! \brief Cast the event pointer down in a type-safe way
+//!
+//! Checks that the event \p eptr points to actually is of the requested type
+//! and returns a (plain) pointer to the event downcast to that type. \p eptr
+//! can be either "dumb" (BaseEventT*) or "smart" (`event_ptr_tt<>`). This
+//! overload doesn't affect the event ownership - if the original pointer owns
+//! the event it must outlive the downcast pointer to keep it from dangling.
template <class EventT, typename BasePtrT>
inline auto eventCast(const BasePtrT& eptr)
-> decltype(static_cast<EventT*>(&*eptr))
@@ -341,6 +348,28 @@ inline auto eventCast(const BasePtrT& eptr)
: nullptr;
}
+//! \brief Cast the event pointer down in a type-safe way, with moving
+//!
+//! Checks that the event \p eptr points to actually is of the requested type;
+//! if (and only if) it is, releases the pointer, downcasts it to the requested
+//! event type and returns a new smart pointer wrapping the downcast one.
+//! Unlike the non-moving eventCast() overload, this one only accepts a smart
+//! pointer, and that smart pointer should be an rvalue (either a temporary,
+//! or as a result of std::move()). The ownership, respectively, is transferred
+//! to the new pointer; the original smart pointer is reset to nullptr, as is
+//! normal for `unique_ptr<>::release()`.
+//! \note If \p eptr's event type does not match \p EventT it retains ownership
+//! after calling this overload; if it is a temporary, this normally
+//! leads to the event getting deleted along with the end of
+//! the temporary's lifetime.
+template <class EventT, typename BaseEventT>
+inline auto eventCast(event_ptr_tt<BaseEventT>&& eptr)
+{
+ return eptr && is<std::decay_t<EventT>>(*eptr)
+ ? event_ptr_tt<EventT>(static_cast<EventT*>(eptr.release()))
+ : nullptr;
+}
+
namespace _impl {
template <typename FnT, class BaseT>
concept Invocable_With_Downcast =