From 4c5dbc41602a01f9c7f79d0fe8bd49a8c2d92862 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 26 Nov 2019 18:52:59 +0300 Subject: [PATCH] Add support for scheduled message_id. GitOrigin-RevId: 1e56677062f8b59501fe64760ede980b9cb9bceb --- td/telegram/MessageId.h | 58 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/td/telegram/MessageId.h b/td/telegram/MessageId.h index 321cdf43..6c0f657e 100644 --- a/td/telegram/MessageId.h +++ b/td/telegram/MessageId.h @@ -9,6 +9,7 @@ #include "td/telegram/DialogId.h" #include "td/utils/common.h" +#include "td/utils/logging.h" #include "td/utils/misc.h" #include "td/utils/StringBuilder.h" #include "td/utils/tl_helpers.h" @@ -63,13 +64,23 @@ class MessageId { int64 id = 0; static constexpr int32 SERVER_ID_SHIFT = 20; + static constexpr int32 SHORT_TYPE_MASK = (1 << 2) - 1; static constexpr int32 TYPE_MASK = (1 << 3) - 1; static constexpr int32 FULL_TYPE_MASK = (1 << SERVER_ID_SHIFT) - 1; + static constexpr int32 SCHEDULED_MASK = 4; static constexpr int32 TYPE_YET_UNSENT = 1; static constexpr int32 TYPE_LOCAL = 2; friend StringBuilder &operator<<(StringBuilder &string_builder, MessageId message_id); + // ordinary message ID layout + // |-------31--------|---17---|1|--2-| + // |server_message_id|local_id|0|type| + + // scheduled message ID layout + // |-------30-------|----18---|1|--2-| + // |send_date-2**30 |server_id|1|type| + public: MessageId() = default; @@ -77,6 +88,22 @@ class MessageId { : id(static_cast(server_message_id.get()) << SERVER_ID_SHIFT) { } + static MessageId get_scheduled_message_id(int32 server_message_id, int32 send_date) { + if (send_date <= (1 << 30)) { + LOG(ERROR) << "Scheduled message send date " << send_date << " is in the past"; + return MessageId(); + } + if (server_message_id <= 0) { + LOG(ERROR) << "Scheduled message ID " << server_message_id << " is non-positive"; + return MessageId(); + } + if (server_message_id >= (1 << 18)) { + LOG(ERROR) << "Scheduled message ID " << server_message_id << " is too big"; + return MessageId(); + } + return MessageId((static_cast(send_date - (1 << 30)) << 21) | (server_message_id << 3) | SCHEDULED_MASK); + } + explicit constexpr MessageId(int64 message_id) : id(message_id) { } template ::value>> @@ -100,6 +127,15 @@ class MessageId { return type == TYPE_YET_UNSENT || type == TYPE_LOCAL; } + bool is_valid_scheduled() const { + if (id <= 0 || id > max().get()) { + return false; + } + int32 type = (id & TYPE_MASK); + return type == SCHEDULED_MASK || type == (SCHEDULED_MASK | TYPE_YET_UNSENT) || + type == (SCHEDULED_MASK | TYPE_LOCAL); + } + int64 get() const { return id; } @@ -121,14 +157,18 @@ class MessageId { } } + bool is_scheduled() const { + return (id & SCHEDULED_MASK) != 0; + } + bool is_yet_unsent() const { - CHECK(is_valid()); - return (id & TYPE_MASK) == TYPE_YET_UNSENT; + CHECK(is_valid() || is_scheduled()); + return (id & SHORT_TYPE_MASK) == TYPE_YET_UNSENT; } bool is_local() const { - CHECK(is_valid()); - return (id & TYPE_MASK) == TYPE_LOCAL; + CHECK(is_valid() || is_scheduled()); + return (id & SHORT_TYPE_MASK) == TYPE_LOCAL; } bool is_server() const { @@ -136,6 +176,11 @@ class MessageId { return (id & FULL_TYPE_MASK) == 0; } + bool is_scheduled_server() const { + CHECK(is_valid_scheduled()); + return (id & SHORT_TYPE_MASK) == 0; + } + ServerMessageId get_server_message_id() const { CHECK(id == 0 || is_server()); return ServerMessageId(narrow_cast(id >> SERVER_ID_SHIFT)); @@ -166,6 +211,11 @@ class MessageId { } } + int32 get_scheduled_server_message_id() const { + CHECK(is_scheduled_server()); + return static_cast((id >> 3) & ((1 << 18) - 1)); + } + bool operator==(const MessageId &other) const { return id == other.id; }