Merge remote-tracking branch 'td/master'

This commit is contained in:
Andrea Cavalli 2021-07-17 11:15:40 +02:00
commit 3dde04b17f
261 changed files with 4201 additions and 3984 deletions

View File

@ -419,6 +419,7 @@ set(TDLIB_SOURCE
td/mtproto/AuthData.h
td/mtproto/AuthKey.h
td/mtproto/CryptoStorer.h
td/mtproto/DhCallback.h
td/mtproto/DhHandshake.h
td/mtproto/Handshake.h
td/mtproto/HandshakeActor.h
@ -598,6 +599,7 @@ set(TDLIB_SOURCE
td/telegram/SecretChatActor.h
td/telegram/SecretChatId.h
td/telegram/SecretChatDb.h
td/telegram/SecretChatLayer.h
td/telegram/SecretChatsManager.h
td/telegram/SecretInputMedia.h
td/telegram/SecureManager.h

View File

@ -166,7 +166,7 @@ function split_file($file, $chunks, $undo) {
$parents = array();
foreach ($functions as $i => $f) {
if (preg_match_all('/(?J)(create_handler|create_net_actor)<(?<name>[A-Z][A-Za-z]*)>|'.
'(?<name>[A-Z][A-Za-z]*) : public (Td::ResultHandler|NetActor|Request)|'.
'(?<name>[A-Z][A-Za-z]*) (final )?: public (Td::ResultHandler|NetActor|Request)|'.
'(CREATE_REQUEST|CREATE_NO_ARGS_REQUEST)[(](?<name>[A-Z][A-Za-z]*)|'.
'(?<name>complete_pending_preauthentication_requests)|'.
'(?<name>get_message_history_slice)|'.

View File

@ -20,7 +20,7 @@
#endif
template <int type>
class RingBench : public td::Benchmark {
class RingBench final : public td::Benchmark {
public:
struct PassActor;
@ -31,13 +31,13 @@ class RingBench : public td::Benchmark {
td::ConcurrentScheduler *scheduler_ = nullptr;
public:
std::string get_description() const override {
std::string get_description() const final {
static const char *types[] = {"later", "immediate", "raw", "tail", "lambda"};
static_assert(0 <= type && type < 5, "");
return PSTRING() << "Ring (send_" << types[type] << ") (threads_n = " << thread_n_ << ")";
}
struct PassActor : public td::Actor {
struct PassActor final : public td::Actor {
int id = -1;
td::ActorId<PassActor> next_actor;
int start_n = 0;
@ -68,14 +68,14 @@ class RingBench : public td::Benchmark {
}
}
void raw_event(const td::Event::Raw &raw) override {
void raw_event(const td::Event::Raw &raw) final {
pass(static_cast<int>(raw.u32));
}
void start_up() override {
void start_up() final {
yield();
}
void wakeup() override {
void wakeup() final {
if (start_n != 0) {
int n = start_n;
start_n = 0;
@ -87,7 +87,7 @@ class RingBench : public td::Benchmark {
RingBench(int actor_n, int thread_n) : actor_n_(actor_n), thread_n_(thread_n) {
}
void start_up() override {
void start_up() final {
scheduler_ = new td::ConcurrentScheduler();
scheduler_->init(thread_n_);
@ -103,7 +103,7 @@ class RingBench : public td::Benchmark {
scheduler_->start();
}
void run(int n) override {
void run(int n) final {
// first actor is on main_thread
actor_array_[0].get_actor_unsafe()->start_n = td::max(n, 100);
while (scheduler_->run_main(10)) {
@ -111,22 +111,22 @@ class RingBench : public td::Benchmark {
}
}
void tear_down() override {
void tear_down() final {
scheduler_->finish();
delete scheduler_;
}
};
template <int type>
class QueryBench : public td::Benchmark {
class QueryBench final : public td::Benchmark {
public:
std::string get_description() const override {
std::string get_description() const final {
static const char *types[] = {"callback", "immediate future", "delayed future", "dummy", "lambda", "lambda_future"};
static_assert(0 <= type && type < 6, "");
return PSTRING() << "QueryBench: " << types[type];
}
class ClientActor : public td::Actor {
class ClientActor final : public td::Actor {
public:
class Callback {
public:
@ -157,20 +157,20 @@ class QueryBench : public td::Benchmark {
td::unique_ptr<Callback> callback_;
};
class ServerActor : public td::Actor {
class ServerActor final : public td::Actor {
public:
class ClientCallback : public ClientActor::Callback {
class ClientCallback final : public ClientActor::Callback {
public:
explicit ClientCallback(td::ActorId<ServerActor> server) : server_(server) {
}
void on_result(int x) override {
void on_result(int x) final {
send_closure(server_, &ServerActor::on_result, x);
}
private:
td::ActorId<ServerActor> server_;
};
void start_up() override {
void start_up() final {
client_ = td::create_actor<ClientActor>("Client", td::make_unique<ClientCallback>(actor_id(this))).release();
}
@ -179,7 +179,7 @@ class QueryBench : public td::Benchmark {
wakeup();
}
void wakeup() override {
void wakeup() final {
while (true) {
if (n_ < 0) {
td::Scheduler::instance()->finish();
@ -222,7 +222,7 @@ class QueryBench : public td::Benchmark {
wakeup();
}
void raw_event(const td::Event::Raw &event) override {
void raw_event(const td::Event::Raw &event) final {
int val = future_.move_as_ok();
CHECK(val == n_ * n_);
wakeup();
@ -238,7 +238,7 @@ class QueryBench : public td::Benchmark {
td::FutureActor<int> future_;
};
void start_up() override {
void start_up() final {
scheduler_ = new td::ConcurrentScheduler();
scheduler_->init(0);
@ -246,7 +246,7 @@ class QueryBench : public td::Benchmark {
scheduler_->start();
}
void run(int n) override {
void run(int n) final {
// first actor is on main_thread
{
auto guard = scheduler_->get_main_guard();
@ -257,7 +257,7 @@ class QueryBench : public td::Benchmark {
}
}
void tear_down() override {
void tear_down() final {
server_.release();
scheduler_->finish();
delete scheduler_;

View File

@ -29,22 +29,22 @@ static constexpr int DATA_SIZE = 8 << 10;
static constexpr int SHORT_DATA_SIZE = 64;
#if OPENSSL_VERSION_NUMBER <= 0x10100000L
class SHA1Bench : public td::Benchmark {
class SHA1Bench final : public td::Benchmark {
public:
alignas(64) unsigned char data[DATA_SIZE];
std::string get_description() const override {
std::string get_description() const final {
return PSTRING() << "SHA1 OpenSSL [" << (DATA_SIZE >> 10) << "KB]";
}
void start_up() override {
void start_up() final {
for (int i = 0; i < DATA_SIZE; i++) {
data[i] = 123;
data[i] = 0;
}
}
void run(int n) override {
void run(int n) final {
for (int i = 0; i < n; i++) {
unsigned char md[20];
SHA1(data, DATA_SIZE, md);
@ -53,17 +53,17 @@ class SHA1Bench : public td::Benchmark {
};
#endif
class AesEcbBench : public td::Benchmark {
class AesEcbBench final : public td::Benchmark {
public:
alignas(64) unsigned char data[DATA_SIZE];
td::UInt256 key;
td::UInt256 iv;
std::string get_description() const override {
std::string get_description() const final {
return PSTRING() << "AES ECB OpenSSL [" << (DATA_SIZE >> 10) << "KB]";
}
void start_up() override {
void start_up() final {
for (int i = 0; i < DATA_SIZE; i++) {
data[i] = 123;
}
@ -71,7 +71,7 @@ class AesEcbBench : public td::Benchmark {
td::Random::secure_bytes(iv.raw, sizeof(iv));
}
void run(int n) override {
void run(int n) final {
td::AesState state;
state.init(td::as_slice(key), true);
td::MutableSlice data_slice(data, DATA_SIZE);
@ -84,17 +84,17 @@ class AesEcbBench : public td::Benchmark {
}
};
class AesIgeEncryptBench : public td::Benchmark {
class AesIgeEncryptBench final : public td::Benchmark {
public:
alignas(64) unsigned char data[DATA_SIZE];
td::UInt256 key;
td::UInt256 iv;
std::string get_description() const override {
std::string get_description() const final {
return PSTRING() << "AES IGE OpenSSL encrypt [" << (DATA_SIZE >> 10) << "KB]";
}
void start_up() override {
void start_up() final {
for (int i = 0; i < DATA_SIZE; i++) {
data[i] = 123;
}
@ -102,7 +102,7 @@ class AesIgeEncryptBench : public td::Benchmark {
td::Random::secure_bytes(iv.raw, sizeof(iv));
}
void run(int n) override {
void run(int n) final {
td::MutableSlice data_slice(data, DATA_SIZE);
td::AesIgeState state;
state.init(as_slice(key), as_slice(iv), true);
@ -112,17 +112,17 @@ class AesIgeEncryptBench : public td::Benchmark {
}
};
class AesIgeDecryptBench : public td::Benchmark {
class AesIgeDecryptBench final : public td::Benchmark {
public:
alignas(64) unsigned char data[DATA_SIZE];
td::UInt256 key;
td::UInt256 iv;
std::string get_description() const override {
std::string get_description() const final {
return PSTRING() << "AES IGE OpenSSL decrypt [" << (DATA_SIZE >> 10) << "KB]";
}
void start_up() override {
void start_up() final {
for (int i = 0; i < DATA_SIZE; i++) {
data[i] = 123;
}
@ -130,7 +130,7 @@ class AesIgeDecryptBench : public td::Benchmark {
td::Random::secure_bytes(iv.raw, sizeof(iv));
}
void run(int n) override {
void run(int n) final {
td::MutableSlice data_slice(data, DATA_SIZE);
td::AesIgeState state;
state.init(as_slice(key), as_slice(iv), false);
@ -140,17 +140,17 @@ class AesIgeDecryptBench : public td::Benchmark {
}
};
class AesCtrBench : public td::Benchmark {
class AesCtrBench final : public td::Benchmark {
public:
alignas(64) unsigned char data[DATA_SIZE];
td::UInt256 key;
td::UInt128 iv;
std::string get_description() const override {
std::string get_description() const final {
return PSTRING() << "AES CTR OpenSSL [" << (DATA_SIZE >> 10) << "KB]";
}
void start_up() override {
void start_up() final {
for (int i = 0; i < DATA_SIZE; i++) {
data[i] = 123;
}
@ -158,7 +158,7 @@ class AesCtrBench : public td::Benchmark {
td::Random::secure_bytes(iv.raw, sizeof(iv));
}
void run(int n) override {
void run(int n) final {
td::MutableSlice data_slice(data, DATA_SIZE);
td::AesCtrState state;
state.init(as_slice(key), as_slice(iv));
@ -169,17 +169,17 @@ class AesCtrBench : public td::Benchmark {
};
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
class AesCtrOpenSSLBench : public td::Benchmark {
class AesCtrOpenSSLBench final : public td::Benchmark {
public:
alignas(64) unsigned char data[DATA_SIZE];
td::UInt256 key;
td::UInt128 iv;
std::string get_description() const override {
std::string get_description() const final {
return PSTRING() << "AES CTR RAW OpenSSL [" << (DATA_SIZE >> 10) << "KB]";
}
void start_up() override {
void start_up() final {
for (int i = 0; i < DATA_SIZE; i++) {
data[i] = 123;
}
@ -187,7 +187,7 @@ class AesCtrOpenSSLBench : public td::Benchmark {
td::Random::secure_bytes(iv.raw, sizeof(iv));
}
void run(int n) override {
void run(int n) final {
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), nullptr, key.raw, iv.raw);
@ -205,17 +205,17 @@ class AesCtrOpenSSLBench : public td::Benchmark {
};
#endif
class AesCbcDecryptBench : public td::Benchmark {
class AesCbcDecryptBench final : public td::Benchmark {
public:
alignas(64) unsigned char data[DATA_SIZE];
td::UInt256 key;
td::UInt128 iv;
std::string get_description() const override {
std::string get_description() const final {
return PSTRING() << "AES CBC Decrypt OpenSSL [" << (DATA_SIZE >> 10) << "KB]";
}
void start_up() override {
void start_up() final {
for (int i = 0; i < DATA_SIZE; i++) {
data[i] = 123;
}
@ -223,7 +223,7 @@ class AesCbcDecryptBench : public td::Benchmark {
td::Random::secure_bytes(as_slice(iv));
}
void run(int n) override {
void run(int n) final {
td::MutableSlice data_slice(data, DATA_SIZE);
for (int i = 0; i < n; i++) {
td::aes_cbc_decrypt(as_slice(key), as_slice(iv), data_slice, data_slice);
@ -231,17 +231,17 @@ class AesCbcDecryptBench : public td::Benchmark {
}
};
class AesCbcEncryptBench : public td::Benchmark {
class AesCbcEncryptBench final : public td::Benchmark {
public:
alignas(64) unsigned char data[DATA_SIZE];
td::UInt256 key;
td::UInt128 iv;
std::string get_description() const override {
std::string get_description() const final {
return PSTRING() << "AES CBC Encrypt OpenSSL [" << (DATA_SIZE >> 10) << "KB]";
}
void start_up() override {
void start_up() final {
for (int i = 0; i < DATA_SIZE; i++) {
data[i] = 123;
}
@ -249,7 +249,7 @@ class AesCbcEncryptBench : public td::Benchmark {
td::Random::secure_bytes(as_slice(iv));
}
void run(int n) override {
void run(int n) final {
td::MutableSlice data_slice(data, DATA_SIZE);
for (int i = 0; i < n; i++) {
td::aes_cbc_encrypt(as_slice(key), as_slice(iv), data_slice, data_slice);
@ -258,17 +258,17 @@ class AesCbcEncryptBench : public td::Benchmark {
};
template <bool use_state>
class AesIgeShortBench : public td::Benchmark {
class AesIgeShortBench final : public td::Benchmark {
public:
alignas(64) unsigned char data[SHORT_DATA_SIZE];
td::UInt256 key;
td::UInt256 iv;
std::string get_description() const override {
std::string get_description() const final {
return PSTRING() << "AES IGE OpenSSL " << (use_state ? "EVP" : "C ") << "[" << SHORT_DATA_SIZE << "B]";
}
void start_up() override {
void start_up() final {
for (int i = 0; i < SHORT_DATA_SIZE; i++) {
data[i] = 123;
}
@ -276,7 +276,7 @@ class AesIgeShortBench : public td::Benchmark {
td::Random::secure_bytes(as_slice(iv));
}
void run(int n) override {
void run(int n) final {
td::MutableSlice data_slice(data, SHORT_DATA_SIZE);
for (int i = 0; i < n; i++) {
if (use_state) {
@ -363,22 +363,22 @@ BENCH(Pbkdf2, "pbkdf2") {
td::pbkdf2_sha256(password, salt, n, key);
}
class Crc32Bench : public td::Benchmark {
class Crc32Bench final : public td::Benchmark {
public:
alignas(64) unsigned char data[DATA_SIZE];
std::string get_description() const override {
std::string get_description() const final {
return PSTRING() << "Crc32 zlib [" << (DATA_SIZE >> 10) << "KB]";
}
void start_up() override {
void start_up() final {
for (int i = 0; i < DATA_SIZE; i++) {
data[i] = 123;
data[i] = 0;
}
}
void run(int n) override {
void run(int n) final {
td::uint64 res = 0;
for (int i = 0; i < n; i++) {
res += td::crc32(td::Slice(data, DATA_SIZE));
@ -387,22 +387,22 @@ class Crc32Bench : public td::Benchmark {
}
};
class Crc64Bench : public td::Benchmark {
class Crc64Bench final : public td::Benchmark {
public:
alignas(64) unsigned char data[DATA_SIZE];
std::string get_description() const override {
std::string get_description() const final {
return PSTRING() << "Crc64 Anton [" << (DATA_SIZE >> 10) << "KB]";
}
void start_up() override {
void start_up() final {
for (int i = 0; i < DATA_SIZE; i++) {
data[i] = 123;
data[i] = 0;
}
}
void run(int n) override {
void run(int n) final {
td::uint64 res = 0;
for (int i = 0; i < n; i++) {
res += td::crc64(td::Slice(data, DATA_SIZE));

View File

@ -28,7 +28,7 @@
#include <memory>
template <class KeyValueT>
class TdKvBench : public td::Benchmark {
class TdKvBench final : public td::Benchmark {
td::ConcurrentScheduler sched;
td::string name_;
@ -37,27 +37,27 @@ class TdKvBench : public td::Benchmark {
name_ = std::move(name);
}
td::string get_description() const override {
td::string get_description() const final {
return name_;
}
class Main : public td::Actor {
class Main final : public td::Actor {
public:
explicit Main(int n) : n_(n) {
}
private:
void loop() override {
void loop() final {
KeyValueT::destroy("test_tddb").ignore();
class Worker : public Actor {
class Worker final : public Actor {
public:
Worker(int n, td::string db_name) : n_(n) {
kv_.init(db_name).ensure();
}
private:
void loop() override {
void loop() final {
for (int i = 0; i < n_; i++) {
kv_.set(td::to_string(i % 10), td::to_string(i));
}
@ -71,12 +71,12 @@ class TdKvBench : public td::Benchmark {
int n_;
};
void start_up_n(int n) override {
void start_up_n(int n) final {
sched.init(1);
sched.create_actor_unsafe<Main>(1, "Main", n).release();
}
void run(int n) override {
void run(int n) final {
sched.start();
while (sched.run_main(10)) {
// empty
@ -84,17 +84,17 @@ class TdKvBench : public td::Benchmark {
sched.finish();
}
void tear_down() override {
void tear_down() final {
}
};
template <bool is_encrypted = false>
class SqliteKVBench : public td::Benchmark {
class SqliteKVBench final : public td::Benchmark {
td::SqliteDb db;
td::string get_description() const override {
td::string get_description() const final {
return PSTRING() << "SqliteKV " << td::tag("is_encrypted", is_encrypted);
}
void start_up() override {
void start_up() final {
td::string path = "testdb.sqlite";
td::SqliteDb::destroy(path).ignore();
if (is_encrypted) {
@ -110,7 +110,7 @@ class SqliteKVBench : public td::Benchmark {
db.exec("DROP TABLE IF EXISTS KV").ensure();
db.exec("CREATE TABLE IF NOT EXISTS KV (k BLOB PRIMARY KEY, v BLOB)").ensure();
}
void run(int n) override {
void run(int n) final {
auto stmt = db.get_statement("REPLACE INTO KV (k, v) VALUES(?1, ?2)").move_as_ok();
db.exec("BEGIN TRANSACTION").ensure();
for (int i = 0; i < n; i++) {
@ -142,16 +142,16 @@ static td::Status init_db(td::SqliteDb &db) {
return td::Status::OK();
}
class SqliteKeyValueAsyncBench : public td::Benchmark {
class SqliteKeyValueAsyncBench final : public td::Benchmark {
public:
td::string get_description() const override {
td::string get_description() const final {
return "SqliteKeyValueAsync";
}
void start_up() override {
void start_up() final {
do_start_up().ensure();
scheduler_->start();
}
void run(int n) override {
void run(int n) final {
auto guard = scheduler_->get_main_guard();
for (int i = 0; i < n; i++) {
@ -160,7 +160,7 @@ class SqliteKeyValueAsyncBench : public td::Benchmark {
sqlite_kv_async_->set(key, value, td::Auto());
}
}
void tear_down() override {
void tear_down() final {
scheduler_->run_main(0.1);
{
auto guard = scheduler_->get_main_guard();
@ -199,13 +199,13 @@ class SqliteKeyValueAsyncBench : public td::Benchmark {
}
};
class SeqKvBench : public td::Benchmark {
td::string get_description() const override {
class SeqKvBench final : public td::Benchmark {
td::string get_description() const final {
return "SeqKvBench";
}
td::SeqKeyValue kv;
void run(int n) override {
void run(int n) final {
for (int i = 0; i < n; i++) {
kv.set(PSLICE() << i % 10, PSLICE() << i);
}
@ -213,17 +213,17 @@ class SeqKvBench : public td::Benchmark {
};
template <bool is_encrypted = false>
class BinlogKeyValueBench : public td::Benchmark {
td::string get_description() const override {
class BinlogKeyValueBench final : public td::Benchmark {
td::string get_description() const final {
return PSTRING() << "BinlogKeyValue " << td::tag("is_encrypted", is_encrypted);
}
td::BinlogKeyValue<td::Binlog> kv;
void start_up() override {
void start_up() final {
td::SqliteDb::destroy("test_binlog").ignore();
kv.init("test_binlog", is_encrypted ? td::DbKey::password("cucumber") : td::DbKey::empty()).ensure();
}
void run(int n) override {
void run(int n) final {
for (int i = 0; i < n; i++) {
kv.set(td::to_string(i % 10), td::to_string(i));
}

View File

@ -6,6 +6,7 @@
//
#include "td/utils/benchmark.h"
#include "td/mtproto/DhCallback.h"
#include "td/mtproto/DhHandshake.h"
#include "td/utils/base64.h"
@ -28,34 +29,34 @@ static string prime_base64 =
"WC2xF40WnGvEZbDW_5yjko_vW5rk5Bj8Feg-vqD4f6n_Xu1wBQ3tKEn0e_lZ2VaFDOkphR8NgRX2NbEF7i5OFdBLJFS_b0-t8DSxBAMRnNjjuS_MW"
"w";
class HandshakeBench : public Benchmark {
std::string get_description() const override {
class HandshakeBench final : public Benchmark {
std::string get_description() const final {
return "Handshake";
}
class FakeDhCallback : public DhCallback {
class FakeDhCallback final : public mtproto::DhCallback {
public:
int is_good_prime(Slice prime_str) const override {
int is_good_prime(Slice prime_str) const final {
auto it = cache.find(prime_str.str());
if (it == cache.end()) {
return -1;
}
return it->second;
}
void add_good_prime(Slice prime_str) const override {
void add_good_prime(Slice prime_str) const final {
cache[prime_str.str()] = 1;
}
void add_bad_prime(Slice prime_str) const override {
void add_bad_prime(Slice prime_str) const final {
cache[prime_str.str()] = 0;
}
mutable std::map<string, int> cache;
} dh_callback;
void run(int n) override {
DhHandshake a;
DhHandshake b;
void run(int n) final {
mtproto::DhHandshake a;
mtproto::DhHandshake b;
auto prime = base64url_decode(prime_base64).move_as_ok();
DhHandshake::check_config(g, prime, &dh_callback).ensure();
mtproto::DhHandshake::check_config(g, prime, &dh_callback).ensure();
for (int i = 0; i < n; i += 2) {
a.set_config(g, prime);
b.set_config(g, prime);

View File

@ -24,8 +24,8 @@ namespace td {
std::atomic<int> counter;
class HttpClient : public HttpOutboundConnection::Callback {
void start_up() override {
class HttpClient final : public HttpOutboundConnection::Callback {
void start_up() final {
IPAddress addr;
addr.init_ipv4_port("127.0.0.1", 8082).ensure();
auto fd = SocketFd::open(addr);
@ -37,12 +37,12 @@ class HttpClient : public HttpOutboundConnection::Callback {
cnt_ = 100000;
counter++;
}
void tear_down() override {
void tear_down() final {
if (--counter == 0) {
Scheduler::instance()->finish();
}
}
void loop() override {
void loop() final {
if (cnt_-- < 0) {
return stop();
}
@ -50,10 +50,10 @@ class HttpClient : public HttpOutboundConnection::Callback {
send_closure(connection_, &HttpOutboundConnection::write_ok);
LOG(INFO) << "SEND";
}
void handle(unique_ptr<HttpQuery> result) override {
void handle(unique_ptr<HttpQuery> result) final {
loop();
}
void on_connection_error(Status error) override {
void on_connection_error(Status error) final {
LOG(ERROR) << "ERROR: " << error;
}

View File

@ -16,12 +16,12 @@
static std::string http_query = "GET / HTTP/1.1\r\nConnection:keep-alive\r\nhost:127.0.0.1:8080\r\n\r\n";
static const size_t block_size = 2500;
class HttpReaderBench : public td::Benchmark {
std::string get_description() const override {
class HttpReaderBench final : public td::Benchmark {
std::string get_description() const final {
return "HttpReaderBench";
}
void run(int n) override {
void run(int n) final {
int cnt = static_cast<int>(block_size / http_query.size());
td::HttpQuery q;
int parsed = 0;
@ -46,18 +46,18 @@ class HttpReaderBench : public td::Benchmark {
td::ChainBufferReader reader_;
td::HttpReader http_reader_;
void start_up() override {
void start_up() final {
reader_ = writer_.extract_reader();
http_reader_.init(&reader_, 10000, 0);
}
};
class BufferBench : public td::Benchmark {
std::string get_description() const override {
class BufferBench final : public td::Benchmark {
std::string get_description() const final {
return "BufferBench";
}
void run(int n) override {
void run(int n) final {
int cnt = static_cast<int>(block_size / http_query.size());
for (int i = 0; i < n; i += cnt) {
for (int j = 0; j < cnt; j++) {
@ -73,17 +73,17 @@ class BufferBench : public td::Benchmark {
td::ChainBufferReader reader_;
td::HttpReader http_reader_;
void start_up() override {
void start_up() final {
reader_ = writer_.extract_reader();
}
};
class FindBoundaryBench : public td::Benchmark {
std::string get_description() const override {
class FindBoundaryBench final : public td::Benchmark {
std::string get_description() const final {
return "FindBoundaryBench";
}
void run(int n) override {
void run(int n) final {
int cnt = static_cast<int>(block_size / http_query.size());
for (int i = 0; i < n; i += cnt) {
for (int j = 0; j < cnt; j++) {
@ -103,7 +103,7 @@ class FindBoundaryBench : public td::Benchmark {
td::ChainBufferReader reader_;
td::HttpReader http_reader_;
void start_up() override {
void start_up() final {
reader_ = writer_.extract_reader();
}
};

View File

@ -21,9 +21,9 @@ namespace td {
static int cnt = 0;
class HelloWorld : public HttpInboundConnection::Callback {
class HelloWorld final : public HttpInboundConnection::Callback {
public:
void handle(unique_ptr<HttpQuery> query, ActorOwn<HttpInboundConnection> connection) override {
void handle(unique_ptr<HttpQuery> query, ActorOwn<HttpInboundConnection> connection) final {
// LOG(ERROR) << *query;
HttpHeaderCreator hc;
Slice content = "hello world";
@ -40,19 +40,19 @@ class HelloWorld : public HttpInboundConnection::Callback {
send_closure(connection, &HttpInboundConnection::write_next, BufferSlice(res.ok()));
send_closure(connection.release(), &HttpInboundConnection::write_ok);
}
void hangup() override {
void hangup() final {
LOG(ERROR) << "CLOSE " << cnt--;
stop();
}
};
const int N = 0;
class Server : public TcpListener::Callback {
class Server final : public TcpListener::Callback {
public:
void start_up() override {
void start_up() final {
listener_ = create_actor<TcpListener>("Listener", 8082, ActorOwn<TcpListener::Callback>(actor_id(this)));
}
void accept(SocketFd fd) override {
void accept(SocketFd fd) final {
LOG(ERROR) << "ACCEPT " << cnt++;
pos_++;
auto scheduler_id = pos_ % (N != 0 ? N : 1) + (N != 0);
@ -61,7 +61,7 @@ class Server : public TcpListener::Callback {
create_actor_on_scheduler<HelloWorld>("HelloWorld", scheduler_id))
.release();
}
void hangup() override {
void hangup() final {
// may be it should be default?..
LOG(ERROR) << "Hanging up..";
stop();

View File

@ -24,7 +24,7 @@ namespace td {
// HttpInboundConnection header
static int cnt = 0;
class HelloWorld : public Actor {
class HelloWorld final : public Actor {
public:
explicit HelloWorld(SocketFd socket_fd) : socket_fd_(std::move(socket_fd)) {
}
@ -39,7 +39,7 @@ class HelloWorld : public Actor {
std::string write_buf_;
size_t write_pos_{0};
void start_up() override {
void start_up() final {
Scheduler::subscribe(socket_fd_.get_poll_info().extract_pollable_fd(this));
HttpHeaderCreator hc;
Slice content = "hello world";
@ -53,7 +53,7 @@ class HelloWorld : public Actor {
hello_ = hc.finish(content).ok().str();
}
void loop() override {
void loop() final {
auto status = do_loop();
if (status.is_error()) {
Scheduler::unsubscribe(socket_fd_.get_poll_info().get_pollable_fd_ref());
@ -98,18 +98,18 @@ class HelloWorld : public Actor {
}
};
const int N = 0;
class Server : public TcpListener::Callback {
class Server final : public TcpListener::Callback {
public:
void start_up() override {
void start_up() final {
listener_ = create_actor<TcpListener>("Listener", 8082, ActorOwn<TcpListener::Callback>(actor_id(this)));
}
void accept(SocketFd fd) override {
void accept(SocketFd fd) final {
LOG(ERROR) << "ACCEPT " << cnt++;
pos_++;
auto scheduler_id = pos_ % (N != 0 ? N : 1) + (N != 0);
create_actor_on_scheduler<HelloWorld>("HttpInboundConnection", scheduler_id, std::move(fd)).release();
}
void hangup() override {
void hangup() final {
// may be it should be default?..
LOG(ERROR) << "Hanging up..";
stop();

View File

@ -22,7 +22,7 @@
namespace td {
class HttpEchoConnection : public Actor {
class HttpEchoConnection final : public Actor {
public:
explicit HttpEchoConnection(SocketFd fd) : fd_(std::move(fd)) {
}
@ -31,11 +31,11 @@ class HttpEchoConnection : public Actor {
BufferedFd<SocketFd> fd_;
HttpReader reader_;
HttpQuery query_;
void start_up() override {
void start_up() final {
Scheduler::subscribe(fd_.get_poll_info().extract_pollable_fd(this));
reader_.init(&fd_.input_buffer(), 1024 * 1024, 0);
}
void tear_down() override {
void tear_down() final {
Scheduler::unsubscribe_before_close(fd_.get_poll_info().get_pollable_fd_ref());
fd_.close();
}
@ -55,7 +55,7 @@ class HttpEchoConnection : public Actor {
fd_.output_buffer().append(res.ok());
}
void loop() override {
void loop() final {
sync_with_poll(fd_);
auto status = [&] {
TRY_STATUS(loop_read());
@ -85,17 +85,17 @@ class HttpEchoConnection : public Actor {
};
const int N = 8;
class Server : public TcpListener::Callback {
class Server final : public TcpListener::Callback {
public:
void start_up() override {
void start_up() final {
listener_ = create_actor<TcpListener>("Listener", 8082, ActorOwn<TcpListener::Callback>(actor_id(this)));
}
void accept(SocketFd fd) override {
void accept(SocketFd fd) final {
pos_++;
auto scheduler_id = pos_ % (N != 0 ? N : 1) + (N != 0);
create_actor_on_scheduler<HttpEchoConnection>("HttpInboundConnection", scheduler_id, std::move(fd)).release();
}
void hangup() override {
void hangup() final {
LOG(ERROR) << "Hanging up..";
stop();
}

View File

@ -36,7 +36,7 @@ std::string create_tmp_file() {
#endif
}
class IostreamWriteBench : public td::Benchmark {
class IostreamWriteBench final : public td::Benchmark {
protected:
std::string file_name_;
std::ofstream stream;
@ -44,30 +44,30 @@ class IostreamWriteBench : public td::Benchmark {
char buffer[BUFFER_SIZE];
public:
std::string get_description() const override {
std::string get_description() const final {
return "ostream (to file, no buf, no flush)";
}
void start_up() override {
void start_up() final {
file_name_ = create_tmp_file();
stream.open(file_name_.c_str());
CHECK(stream.is_open());
// stream.rdbuf()->pubsetbuf(buffer, BUFFER_SIZE);
}
void run(int n) override {
void run(int n) final {
for (int i = 0; i < n; i++) {
stream << "This is just for test" << 987654321 << '\n';
}
}
void tear_down() override {
void tear_down() final {
stream.close();
unlink(file_name_.c_str());
}
};
class FILEWriteBench : public td::Benchmark {
class FILEWriteBench final : public td::Benchmark {
protected:
std::string file_name_;
FILE *file;
@ -75,24 +75,24 @@ class FILEWriteBench : public td::Benchmark {
char buffer[BUFFER_SIZE];
public:
std::string get_description() const override {
std::string get_description() const final {
return "std::fprintf (to file, no buf, no flush)";
}
void start_up() override {
void start_up() final {
file_name_ = create_tmp_file();
file = fopen(file_name_.c_str(), "w");
// setvbuf(file, buffer, _IOFBF, BUFFER_SIZE);
}
void run(int n) override {
void run(int n) final {
for (int i = 0; i < n; i++) {
std::fprintf(file, "This is just for test%d\n", 987654321);
// std::fflush(file);
}
}
void tear_down() override {
void tear_down() final {
std::fclose(file);
unlink(file_name_.c_str());
}
@ -101,24 +101,24 @@ class FILEWriteBench : public td::Benchmark {
#if TD_ANDROID
#include <android/log.h>
#define ALOG(...) __android_log_print(ANDROID_LOG_VERBOSE, "XXX", __VA_ARGS__)
class ALogWriteBench : public td::Benchmark {
class ALogWriteBench final : public td::Benchmark {
public:
std::string get_description() const override {
std::string get_description() const final {
return "android_log";
}
void start_up() override {
void start_up() final {
}
void run(int n) override {
void run(int n) final {
for (int i = 0; i < n; i++) {
ALOG("This is just for test%d\n", 987654321);
}
}
void tear_down() override {
void tear_down() final {
}
};
#endif
class LogWriteBench : public td::Benchmark {
class LogWriteBench final : public td::Benchmark {
protected:
std::string file_name_;
std::ofstream stream;
@ -127,24 +127,24 @@ class LogWriteBench : public td::Benchmark {
char buffer[BUFFER_SIZE];
public:
std::string get_description() const override {
std::string get_description() const final {
return "td_log (slow in debug mode)";
}
void start_up() override {
void start_up() final {
file_name_ = create_tmp_file();
stream.open(file_name_.c_str());
CHECK(stream.is_open());
old_buf = std::cerr.rdbuf(stream.rdbuf());
}
void run(int n) override {
void run(int n) final {
for (int i = 0; i < n; i++) {
LOG(DEBUG) << "This is just for test" << 987654321;
}
}
void tear_down() override {
void tear_down() final {
stream.close();
unlink(file_name_.c_str());
std::cerr.rdbuf(old_buf);

View File

@ -119,20 +119,20 @@ BENCH(Time, "Clocks::monotonic") {
}
*/
#if !TD_WINDOWS
class PipeBench : public Benchmark {
class PipeBench final : public Benchmark {
public:
int p[2];
string get_description() const override {
string get_description() const final {
return "pipe write + read int32";
}
void start_up() override {
void start_up() final {
int res = pipe(p);
CHECK(res == 0);
}
void run(int n) override {
void run(int n) final {
int res = 0;
for (int i = 0; i < n; i++) {
int val = 1;
@ -145,7 +145,7 @@ class PipeBench : public Benchmark {
do_not_optimize_away(res);
}
void tear_down() override {
void tear_down() final {
close(p[0]);
close(p[1]);
}
@ -153,42 +153,42 @@ class PipeBench : public Benchmark {
#endif
#if TD_LINUX || TD_ANDROID || TD_TIZEN
class SemBench : public Benchmark {
class SemBench final : public Benchmark {
sem_t sem;
public:
string get_description() const override {
string get_description() const final {
return "sem post + wait";
}
void start_up() override {
void start_up() final {
int err = sem_init(&sem, 0, 0);
CHECK(err != -1);
}
void run(int n) override {
void run(int n) final {
for (int i = 0; i < n; i++) {
sem_post(&sem);
sem_wait(&sem);
}
}
void tear_down() override {
void tear_down() final {
sem_destroy(&sem);
}
};
#endif
#if !TD_WINDOWS
class UtimeBench : public Benchmark {
class UtimeBench final : public Benchmark {
public:
void start_up() override {
void start_up() final {
FileFd::open("test", FileFd::Flags::Create | FileFd::Flags::Write).move_as_ok().close();
}
string get_description() const override {
string get_description() const final {
return "utime";
}
void run(int n) override {
void run(int n) final {
for (int i = 0; i < n; i++) {
int err = utime("test", nullptr);
CHECK(err >= 0);
@ -210,19 +210,19 @@ BENCH(Pwrite, "pwrite") {
fd.close();
}
class CreateFileBench : public Benchmark {
string get_description() const override {
class CreateFileBench final : public Benchmark {
string get_description() const final {
return "create_file";
}
void start_up() override {
void start_up() final {
mkdir("A").ensure();
}
void run(int n) override {
void run(int n) final {
for (int i = 0; i < n; i++) {
FileFd::open(PSLICE() << "A/" << i, FileFd::Flags::Write | FileFd::Flags::Create).move_as_ok().close();
}
}
void tear_down() override {
void tear_down() final {
td::walk_path("A/", [&](CSlice path, auto type) {
if (type == td::WalkPath::Type::ExitDir) {
rmdir(path).ignore();
@ -233,17 +233,17 @@ class CreateFileBench : public Benchmark {
}
};
class WalkPathBench : public Benchmark {
string get_description() const override {
class WalkPathBench final : public Benchmark {
string get_description() const final {
return "walk_path";
}
void start_up_n(int n) override {
void start_up_n(int n) final {
mkdir("A").ensure();
for (int i = 0; i < n; i++) {
FileFd::open(PSLICE() << "A/" << i, FileFd::Flags::Write | FileFd::Flags::Create).move_as_ok().close();
}
}
void run(int n) override {
void run(int n) final {
int cnt = 0;
td::walk_path("A/", [&](CSlice path, auto type) {
if (type == td::WalkPath::Type::EnterDir) {
@ -253,7 +253,7 @@ class WalkPathBench : public Benchmark {
cnt++;
}).ignore();
}
void tear_down() override {
void tear_down() final {
td::walk_path("A/", [&](CSlice path, auto type) {
if (type == td::WalkPath::Type::ExitDir) {
rmdir(path).ignore();
@ -266,13 +266,13 @@ class WalkPathBench : public Benchmark {
#if !TD_THREAD_UNSUPPORTED
template <int ThreadN = 2>
class AtomicReleaseIncBench : public Benchmark {
string get_description() const override {
class AtomicReleaseIncBench final : public Benchmark {
string get_description() const final {
return PSTRING() << "AtomicReleaseInc" << ThreadN;
}
static std::atomic<uint64> a_;
void run(int n) override {
void run(int n) final {
std::vector<thread> threads;
for (int i = 0; i < ThreadN; i++) {
threads.emplace_back([&] {
@ -290,13 +290,13 @@ template <int ThreadN>
std::atomic<uint64> AtomicReleaseIncBench<ThreadN>::a_;
template <int ThreadN = 2>
class AtomicReleaseCasIncBench : public Benchmark {
string get_description() const override {
class AtomicReleaseCasIncBench final : public Benchmark {
string get_description() const final {
return PSTRING() << "AtomicReleaseCasInc" << ThreadN;
}
static std::atomic<uint64> a_;
void run(int n) override {
void run(int n) final {
std::vector<thread> threads;
for (int i = 0; i < ThreadN; i++) {
threads.emplace_back([&] {
@ -316,12 +316,12 @@ template <int ThreadN>
std::atomic<uint64> AtomicReleaseCasIncBench<ThreadN>::a_;
template <int ThreadN = 2>
class RwMutexReadBench : public Benchmark {
string get_description() const override {
class RwMutexReadBench final : public Benchmark {
string get_description() const final {
return PSTRING() << "RwMutexRead" << ThreadN;
}
RwMutex mutex_;
void run(int n) override {
void run(int n) final {
std::vector<thread> threads;
for (int i = 0; i < ThreadN; i++) {
threads.emplace_back([&] {
@ -336,12 +336,12 @@ class RwMutexReadBench : public Benchmark {
}
};
template <int ThreadN = 2>
class RwMutexWriteBench : public Benchmark {
string get_description() const override {
class RwMutexWriteBench final : public Benchmark {
string get_description() const final {
return PSTRING() << "RwMutexWrite" << ThreadN;
}
RwMutex mutex_;
void run(int n) override {
void run(int n) final {
std::vector<thread> threads;
for (int i = 0; i < ThreadN; i++) {
threads.emplace_back([&] {

View File

@ -562,7 +562,7 @@ class SemCheatQueue {
};
template <class QueueT>
class QueueBenchmark2 : public td::Benchmark {
class QueueBenchmark2 final : public td::Benchmark {
QueueT client, server;
int connections_n, queries_n;
@ -575,16 +575,16 @@ class QueueBenchmark2 : public td::Benchmark {
explicit QueueBenchmark2(int connections_n = 1) : connections_n(connections_n) {
}
std::string get_description() const override {
std::string get_description() const final {
return "QueueBenchmark2";
}
void start_up() override {
void start_up() final {
client.init();
server.init();
}
void tear_down() override {
void tear_down() final {
client.destroy();
server.destroy();
}
@ -689,7 +689,7 @@ class QueueBenchmark2 : public td::Benchmark {
return static_cast<QueueBenchmark2 *>(arg)->server_run(nullptr);
}
void run(int n) override {
void run(int n) final {
pthread_t client_thread_id;
pthread_t server_thread_id;
@ -704,7 +704,7 @@ class QueueBenchmark2 : public td::Benchmark {
};
template <class QueueT>
class QueueBenchmark : public td::Benchmark {
class QueueBenchmark final : public td::Benchmark {
QueueT client, server;
const int connections_n;
int queries_n;
@ -713,16 +713,16 @@ class QueueBenchmark : public td::Benchmark {
explicit QueueBenchmark(int connections_n = 1) : connections_n(connections_n) {
}
std::string get_description() const override {
std::string get_description() const final {
return "QueueBenchmark";
}
void start_up() override {
void start_up() final {
client.init();
server.init();
}
void tear_down() override {
void tear_down() final {
client.destroy();
server.destroy();
}
@ -821,7 +821,7 @@ class QueueBenchmark : public td::Benchmark {
return static_cast<QueueBenchmark *>(arg)->server_run(nullptr);
}
void run(int n) override {
void run(int n) final {
pthread_t client_thread_id;
pthread_t server_thread_id;
@ -836,7 +836,7 @@ class QueueBenchmark : public td::Benchmark {
};
template <class QueueT>
class RingBenchmark : public td::Benchmark {
class RingBenchmark final : public td::Benchmark {
static constexpr int QN = 504;
struct Thread {
@ -869,7 +869,7 @@ class RingBenchmark : public td::Benchmark {
return static_cast<Thread *>(arg)->run();
}
void start_up() override {
void start_up() final {
for (int i = 0; i < QN; i++) {
q[i].int_id = i;
q[i].queue.init();
@ -877,13 +877,13 @@ class RingBenchmark : public td::Benchmark {
}
}
void tear_down() override {
void tear_down() final {
for (int i = 0; i < QN; i++) {
q[i].queue.destroy();
}
}
void run(int n) override {
void run(int n) final {
for (int i = 0; i < QN; i++) {
pthread_create(&q[i].id, nullptr, run_gateway, &q[i]);
}

View File

@ -37,17 +37,17 @@ static Status init_db(SqliteDb &db) {
return Status::OK();
}
class MessagesDbBench : public Benchmark {
class MessagesDbBench final : public Benchmark {
public:
string get_description() const override {
string get_description() const final {
return "MessagesDb";
}
void start_up() override {
void start_up() final {
LOG(ERROR) << "START UP";
do_start_up().ensure();
scheduler_->start();
}
void run(int n) override {
void run(int n) final {
auto guard = scheduler_->get_main_guard();
for (int i = 0; i < n; i += 20) {
auto dialog_id = DialogId{UserId{Random::fast(1, 100)}};
@ -67,7 +67,7 @@ class MessagesDbBench : public Benchmark {
}
}
}
void tear_down() override {
void tear_down() final {
scheduler_->run_main(0.1);
{
auto guard = scheduler_->get_main_guard();

View File

@ -35,7 +35,7 @@ struct overload<F> : public F {
template <class F, class... Fs>
struct overload<F, Fs...>
: public overload<F>
, overload<Fs...> {
, public overload<Fs...> {
overload(F f, Fs... fs) : overload<F>(f), overload<Fs...>(fs...) {
}
using overload<F>::operator();

View File

@ -13,7 +13,7 @@ To compile `TDLib` you will need to:
```
brew install gperf cmake coreutils
```
* If you don't want to build `TDLib` for macOS, you can pregenerate required source code files using `CMake` prepare_cross_compiling target:
* If you don't want to build `TDLib` for macOS first, you **must** pregenerate required source code files using `CMake` prepare_cross_compiling target:
```
cd <path to TDLib sources>
mkdir native-build

View File

@ -1,3 +1,3 @@
./src.ps1 | Select-String -NotMatch "CxCli.h" | Select-String -NotMatch "DotNet" | ForEach-Object {
./src.ps1 | Select-String -NotMatch "CxCli.h" | Select-String -NotMatch "DotNet" | Select-String -NotMatch "/tl-parser/" | ForEach-Object {
clang-format -verbose -style=file -i $_
}

View File

@ -1,2 +1,2 @@
#!/bin/sh
./src.sh | grep -v CxCli.h | grep -iv dotnet | xargs -n 1 clang-format -verbose -style=file -i
./src.sh | grep -v CxCli.h | grep -iv dotnet | grep -v /tl-parser/ | xargs -n 1 clang-format -verbose -style=file -i

22
manual_checks.md Normal file
View File

@ -0,0 +1,22 @@
# Manual checks
## After every merge
1. Find if any `get_channel_difference` has been added to `MessagesManager.cpp`, and replace it with `delayed_get_channel_difference`.
### Example
The following line
```cpp
get_channel_difference(dialog_id, old_pts, true, "add_pending_channel_update pts mismatch");
```
should become
```cpp
auto enable_pull_based_backpressure
= G()->shared_config()
.get_option_boolean("enable_pull_based_backpressure", false);
get_channel_difference_delayed(dialog_id, old_pts, true,
enable_pull_based_backpressure,
"add_pending_channel_update pts mismatch");
```

View File

@ -223,22 +223,27 @@ abstract class TlDocumentationGenerator
}
}
foreach (array_diff_key($info, $known_fields) as $field_name => $field_info) {
if ($field_name !== 'description') {
$this->printError("Have info about unexisted field `$field_name`");
}
}
if (!$info['description']) {
$this->printError("Have no description for class `$class_name`");
}
foreach ($info as &$v) {
$v = $this->escapeDocumentation($this->addDot($v));
}
$description = $info['description'];
unset($info['description']);
if (!$description) {
$this->printError("Have no description for class `$class_name`");
}
foreach (array_diff_key($info, $known_fields) as $field_name => $field_info) {
$this->printError("Have info about unexisted field `$field_name`");
}
if (array_keys($info) !== array_keys($known_fields)) {
$this->printError("Have wrong documentation for class `$class_name`");
}
$base_class_name = $current_class ?: $this->getBaseClassName($is_function);
$class_description = $info['description'];
$class_description = $description;
if ($is_function) {
$class_description .= $this->getFunctionReturnTypeDescription($this->getTypeName($type), false);
}
@ -254,7 +259,7 @@ abstract class TlDocumentationGenerator
if ($is_function) {
$default_constructor_prefix = 'Default constructor for a function, which ';
$full_constructor_prefix = 'Creates a function, which ';
$class_description = lcfirst($info['description']);
$class_description = lcfirst($description);
$class_description .= $this->getFunctionReturnTypeDescription($this->getTypeName($type), true);
} else {
$default_constructor_prefix = '';

View File

@ -15,7 +15,6 @@ resPQ#05162463 nonce:int128 server_nonce:int128 pq:string server_public_key_fing
p_q_inner_data_dc#a9f55f95 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 dc:int = P_Q_inner_data;
p_q_inner_data_temp_dc#56fddf88 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 dc:int expires_in:int = P_Q_inner_data;
server_DH_params_fail#79cb045d nonce:int128 server_nonce:int128 new_nonce_hash:int128 = Server_DH_Params;
server_DH_params_ok#d0e8075c nonce:int128 server_nonce:int128 encrypted_answer:string = Server_DH_Params;
server_DH_inner_data#b5890dba nonce:int128 server_nonce:int128 g:int dh_prime:string g_a:string server_time:int = Server_DH_inner_data;
@ -41,8 +40,8 @@ future_salts#ae500895 req_msg_id:long now:int salts:vector<future_salt> = Future
pong#347773c5 msg_id:long ping_id:long = Pong;
destroy_session_ok#e22045fc session_id:long = DestroySessionRes;
destroy_session_none#62d350c9 session_id:long = DestroySessionRes;
//destroy_session_ok#e22045fc session_id:long = DestroySessionRes;
//destroy_session_none#62d350c9 session_id:long = DestroySessionRes;
new_session_created#9ec20908 first_msg_id:long unique_id:long server_salt:long = NewSession;
@ -80,18 +79,10 @@ set_client_DH_params#f5045f1f nonce:int128 server_nonce:int128 encrypted_data:st
rpc_drop_answer#58e4a740 req_msg_id:long = RpcDropAnswer;
get_future_salts#b921bd04 num:int = FutureSalts;
ping#7abe77ec ping_id:long = Pong;
//ping#7abe77ec ping_id:long = Pong;
ping_delay_disconnect#f3427b8c ping_id:long disconnect_delay:int = Pong;
destroy_session#e7512126 session_id:long = DestroySessionRes;
//destroy_session#e7512126 session_id:long = DestroySessionRes;
http_wait#9299359f max_delay:int wait_after:int max_wait:int = HttpWait;
destroy_auth_key#d1435160 = DestroyAuthKeyRes;
//test.useGzipPacked = GzipPacked;
//test.useServerDhInnerData = Server_DH_inner_data;
//test.useNewSessionCreated = NewSession;
//test.useMsgsAck = MsgsAck;
//test.useBadMsgNotification = BadMsgNotification;
//test.useOther key:rsa_public_key p_q_data:P_Q_inner_data dh_data:client_DH_inner_data = RpcError;

View File

@ -1721,7 +1721,7 @@ messageVoiceChatScheduled group_call_id:int32 start_date:int32 = MessageContent;
//@description A newly created voice chat @group_call_id Identifier of the voice chat. The voice chat can be received through the method getGroupCall
messageVoiceChatStarted group_call_id:int32 = MessageContent;
//@description A message with information about an ended voice chat @duration Call duration
//@description A message with information about an ended voice chat @duration Call duration, in seconds
messageVoiceChatEnded duration:int32 = MessageContent;
//@description A message with information about an invite to a voice chat @group_call_id Identifier of the voice chat. The voice chat can be received through the method getGroupCall @user_ids Invited user identifiers
@ -2170,12 +2170,12 @@ groupCallRecentSpeaker participant_id:MessageSender is_speaking:Bool = GroupCall
//@recent_speakers Recently speaking users in the group call
//@is_my_video_enabled True, if the current user's video is enabled
//@is_my_video_paused True, if the current user's video is paused
//@can_start_video True, if video can be enabled by group call participants. This flag is generally useless after the user has already joined the group call
//@can_enable_video True, if the current user can broadcast video or share screen
//@mute_new_participants True, if only group call administrators can unmute new participants
//@can_change_mute_new_participants True, if the current user can enable or disable mute_new_participants setting
//@record_duration Duration of the ongoing group call recording, in seconds; 0 if none. An updateGroupCall update is not triggered when value of this field changes, but the same recording goes on
//@duration Call duration; for ended calls only
groupCall id:int32 title:string scheduled_start_date:int32 enabled_start_notification:Bool is_active:Bool is_joined:Bool need_rejoin:Bool can_be_managed:Bool participant_count:int32 loaded_all_participants:Bool recent_speakers:vector<groupCallRecentSpeaker> is_my_video_enabled:Bool is_my_video_paused:Bool can_start_video:Bool mute_new_participants:Bool can_change_mute_new_participants:Bool record_duration:int32 duration:int32 = GroupCall;
//@duration Call duration, in seconds; for ended calls only
groupCall id:int32 title:string scheduled_start_date:int32 enabled_start_notification:Bool is_active:Bool is_joined:Bool need_rejoin:Bool can_be_managed:Bool participant_count:int32 loaded_all_participants:Bool recent_speakers:vector<groupCallRecentSpeaker> is_my_video_enabled:Bool is_my_video_paused:Bool can_enable_video:Bool mute_new_participants:Bool can_change_mute_new_participants:Bool record_duration:int32 duration:int32 = GroupCall;
//@description Describes a group of video synchronization source identifiers @semantics The semantics of sources, one of "SIM" or "FID" @source_ids The list of synchronization source identifiers
groupCallVideoSourceGroup semantics:string source_ids:vector<int32> = GroupCallVideoSourceGroup;
@ -2187,7 +2187,7 @@ groupCallParticipantVideoInfo source_groups:vector<groupCallVideoSourceGroup> en
//@description Represents a group call participant
//@participant_id Identifier of the group call participant
//@audio_source_id User's audio channel synchronization source identifier
//@can_enable_video True, if the user can broadcast video or share screen
//@screen_sharing_audio_source_id User's screen sharing audio channel synchronization source identifier
//@video_info Information about user's video channel; may be null if there is no active video
//@screen_sharing_video_info Information about user's screen sharing video channel; may be null if there is no active screen sharing video
//@bio The participant user's bio or the participant chat's description
@ -2203,7 +2203,7 @@ groupCallParticipantVideoInfo source_groups:vector<groupCallVideoSourceGroup> en
//@can_unmute_self True, if the participant is muted for all users, but can unmute themselves
//@volume_level Participant's volume level; 1-20000 in hundreds of percents
//@order User's order in the group call participant list. Orders must be compared lexicographically. The bigger is order, the higher is user in the list. If order is empty, the user must be removed from the participant list
groupCallParticipant participant_id:MessageSender audio_source_id:int32 can_enable_video:Bool video_info:groupCallParticipantVideoInfo screen_sharing_video_info:groupCallParticipantVideoInfo bio:string is_current_user:Bool is_speaking:Bool is_hand_raised:Bool can_be_muted_for_all_users:Bool can_be_unmuted_for_all_users:Bool can_be_muted_for_current_user:Bool can_be_unmuted_for_current_user:Bool is_muted_for_all_users:Bool is_muted_for_current_user:Bool can_unmute_self:Bool volume_level:int32 order:string = GroupCallParticipant;
groupCallParticipant participant_id:MessageSender audio_source_id:int32 screen_sharing_audio_source_id:int32 video_info:groupCallParticipantVideoInfo screen_sharing_video_info:groupCallParticipantVideoInfo bio:string is_current_user:Bool is_speaking:Bool is_hand_raised:Bool can_be_muted_for_all_users:Bool can_be_unmuted_for_all_users:Bool can_be_muted_for_current_user:Bool can_be_unmuted_for_current_user:Bool is_muted_for_all_users:Bool is_muted_for_current_user:Bool can_unmute_self:Bool volume_level:int32 order:string = GroupCallParticipant;
//@class CallProblem @description Describes the exact type of a problem with a call
@ -4801,8 +4801,11 @@ toggleGroupCallEnabledStartNotification group_call_id:int32 enabled_start_notifi
//@invite_hash If non-empty, invite hash to be used to join the group call without being muted by administrators
joinGroupCall group_call_id:int32 participant_id:MessageSender audio_source_id:int32 payload:string is_muted:Bool is_my_video_enabled:Bool invite_hash:string = Text;
//@description Starts screen sharing in a joined group call. Returns join response payload for tgcalls @group_call_id Group call identifier @payload Group call join payload; received from tgcalls
startGroupCallScreenSharing group_call_id:int32 payload:string = Text;
//@description Starts screen sharing in a joined group call. Returns join response payload for tgcalls
//@group_call_id Group call identifier
//@audio_source_id Screen sharing audio channel synchronization source identifier; received from tgcalls
//@payload Group call join payload; received from tgcalls
startGroupCallScreenSharing group_call_id:int32 audio_source_id:int32 payload:string = Text;
//@description Pauses or unpauses screen sharing in a joined group call @group_call_id Group call identifier @is_paused True if screen sharing is paused
toggleGroupCallScreenSharingIsPaused group_call_id:int32 is_paused:Bool = Ok;

View File

@ -1196,7 +1196,7 @@ peerBlocked#e8fd8014 peer_id:Peer date:int = PeerBlocked;
stats.messageStats#8999f295 views_graph:StatsGraph = stats.MessageStats;
groupCallDiscarded#7780bcb4 id:long access_hash:long duration:int = GroupCall;
groupCall#653dbaad flags:# join_muted:flags.1?true can_change_join_muted:flags.2?true join_date_asc:flags.6?true schedule_start_subscribed:flags.8?true can_start_video:flags.9?true id:long access_hash:long participants_count:int title:flags.3?string stream_dc_id:flags.4?int record_start_date:flags.5?int schedule_date:flags.7?int version:int = GroupCall;
groupCall#d597650c flags:# join_muted:flags.1?true can_change_join_muted:flags.2?true join_date_asc:flags.6?true schedule_start_subscribed:flags.8?true can_start_video:flags.9?true id:long access_hash:long participants_count:int title:flags.3?string stream_dc_id:flags.4?int record_start_date:flags.5?int schedule_date:flags.7?int unmuted_video_count:flags.10?int unmuted_video_limit:int version:int = GroupCall;
inputGroupCall#d8aa840f id:long access_hash:long = InputGroupCall;
@ -1239,7 +1239,7 @@ phone.exportedGroupCallInvite#204bd158 link:string = phone.ExportedGroupCallInvi
groupCallParticipantVideoSourceGroup#dcb118b7 semantics:string sources:Vector<int> = GroupCallParticipantVideoSourceGroup;
groupCallParticipantVideo#78e41663 flags:# paused:flags.0?true endpoint:string source_groups:Vector<GroupCallParticipantVideoSourceGroup> = GroupCallParticipantVideo;
groupCallParticipantVideo#67753ac8 flags:# paused:flags.0?true endpoint:string source_groups:Vector<GroupCallParticipantVideoSourceGroup> audio_source:flags.1?int = GroupCallParticipantVideo;
stickers.suggestedShortName#85fea03f short_name:string = stickers.SuggestedShortName;
@ -1639,7 +1639,7 @@ phone.leaveGroupCall#500377f9 call:InputGroupCall source:int = Updates;
phone.inviteToGroupCall#7b393160 call:InputGroupCall users:Vector<InputUser> = Updates;
phone.discardGroupCall#7a777135 call:InputGroupCall = Updates;
phone.toggleGroupCallSettings#74bbb43d flags:# reset_invite_hash:flags.1?true call:InputGroupCall join_muted:flags.0?Bool = Updates;
phone.getGroupCall#c7cb017 call:InputGroupCall = phone.GroupCall;
phone.getGroupCall#41845db call:InputGroupCall limit:int = phone.GroupCall;
phone.getGroupParticipants#c558d8ab call:InputGroupCall ids:Vector<InputPeer> sources:Vector<int> offset:string limit:int = phone.GroupParticipants;
phone.checkGroupCall#b59cf977 call:InputGroupCall sources:Vector<int> = Vector<int>;
phone.toggleGroupCallRecord#c02a66d7 flags:# start:flags.0?true call:InputGroupCall title:flags.1?string = Updates;

View File

@ -16,7 +16,7 @@
namespace td {
class TlWriterCCommon : public tl::TL_writer {
class TlWriterCCommon final : public tl::TL_writer {
public:
int is_header_;
std::string prefix_;
@ -24,47 +24,47 @@ class TlWriterCCommon : public tl::TL_writer {
: TL_writer(name), is_header_(is_header), prefix_(prefix) {
}
int get_max_arity() const override {
int get_max_arity() const final {
return 0;
}
bool is_built_in_simple_type(const std::string &name) const override {
bool is_built_in_simple_type(const std::string &name) const final {
return name == "Bool" || name == "Int32" || name == "Int53" || name == "Int64" || name == "Double" ||
name == "String" || name == "Bytes";
}
bool is_built_in_complex_type(const std::string &name) const override {
bool is_built_in_complex_type(const std::string &name) const final {
return name == "Vector";
}
bool is_type_bare(const tl::tl_type *t) const override {
bool is_type_bare(const tl::tl_type *t) const final {
return t->simple_constructors <= 1 || (is_built_in_simple_type(t->name) && t->name != "Bool") ||
is_built_in_complex_type(t->name);
}
std::vector<std::string> get_parsers() const override {
std::vector<std::string> get_parsers() const final {
return {};
}
int get_parser_type(const tl::tl_combinator *t, const std::string &name) const override {
int get_parser_type(const tl::tl_combinator *t, const std::string &name) const final {
return 0;
}
std::vector<std::string> get_storers() const override {
std::vector<std::string> get_storers() const final {
return {};
}
std::vector<std::string> get_additional_functions() const override {
std::vector<std::string> get_additional_functions() const final {
return {"TdConvertToInternal", "TdConvertFromInternal", "TdSerialize", "TdToString",
"TdDestroyObject", "TdStackStorer", "TdStackFetcher", "enum"};
}
int get_storer_type(const tl::tl_combinator *t, const std::string &name) const override {
int get_storer_type(const tl::tl_combinator *t, const std::string &name) const final {
return name == "to_string" || name == "to_cpp_string";
}
std::string gen_base_tl_class_name() const override {
std::string gen_base_tl_class_name() const final {
return "Object";
}
std::string gen_base_type_class_name(int arity) const override {
std::string gen_base_type_class_name(int arity) const final {
assert(arity == 0);
return "Object";
}
std::string gen_base_function_class_name() const override {
std::string gen_base_function_class_name() const final {
return "Function";
}
@ -118,13 +118,13 @@ class TlWriterCCommon : public tl::TL_writer {
return name;
}
std::string gen_class_name(std::string name) const override {
std::string gen_class_name(std::string name) const final {
if (name == "Object" || name == "#") {
assert(false);
}
return to_CamelCase(name);
}
std::string gen_field_name(std::string name) const override {
std::string gen_field_name(std::string name) const final {
return gen_native_field_name(name);
}
@ -220,10 +220,10 @@ class TlWriterCCommon : public tl::TL_writer {
return !force ? ("struct Td" + gen_main_class_name(t) + " *") : gen_main_class_name(t);
}
std::string gen_type_name(const tl::tl_tree_type *tree_type) const override {
std::string gen_type_name(const tl::tl_tree_type *tree_type) const final {
return gen_type_name(tree_type, false);
}
std::string gen_output_begin() const override {
std::string gen_output_begin() const final {
if (is_header_ == 1) {
return "#pragma once\n"
"#ifdef __cplusplus\n"
@ -279,7 +279,7 @@ class TlWriterCCommon : public tl::TL_writer {
"#include \"td/utils/tl_storers.h\"\n"
"\n";
}
std::string gen_output_end() const override {
std::string gen_output_end() const final {
if (is_header_ == 1) {
return "#ifdef __cplusplus\n"
"}\n"
@ -290,7 +290,7 @@ class TlWriterCCommon : public tl::TL_writer {
return "";
}
std::string gen_forward_class_declaration(const std::string &class_name, bool is_proxy) const override {
std::string gen_forward_class_declaration(const std::string &class_name, bool is_proxy) const final {
if (is_header_ != 1 || class_name == "") {
return "";
}
@ -304,7 +304,7 @@ class TlWriterCCommon : public tl::TL_writer {
}
std::string gen_class_begin(const std::string &class_name, const std::string &base_class_name,
bool is_proxy) const override {
bool is_proxy) const final {
if (is_header_ != 1 || class_name == "") {
return "";
}
@ -315,12 +315,12 @@ class TlWriterCCommon : public tl::TL_writer {
}
return "struct Td" + class_name + " {\n" + " int ID;\n int refcnt;\n" + tail;
}
std::string gen_class_end() const override {
std::string gen_class_end() const final {
return "";
}
std::string gen_field_definition(const std::string &class_name, const std::string &type_name,
const std::string &field_name) const override {
const std::string &field_name) const final {
if (is_header_ != 1 || class_name == "") {
return "";
}
@ -328,14 +328,14 @@ class TlWriterCCommon : public tl::TL_writer {
}
std::string gen_store_function_begin(const std::string &storer_name, const std::string &class_name, int arity,
std::vector<tl::var_description> &vars, int storer_type) const override {
std::vector<tl::var_description> &vars, int storer_type) const final {
return "";
}
std::string gen_store_function_end(const std::vector<tl::var_description> &vars, int storer_type) const override {
std::string gen_store_function_end(const std::vector<tl::var_description> &vars, int storer_type) const final {
return "";
}
std::string gen_constructor_begin(int field_count, const std::string &class_name, bool is_default) const override {
std::string gen_constructor_begin(int field_count, const std::string &class_name, bool is_default) const final {
if (!is_default || is_header_ == -1 || class_name == "") {
return "";
}
@ -348,7 +348,7 @@ class TlWriterCCommon : public tl::TL_writer {
return ss.str();
}
std::string gen_constructor_parameter(int field_num, const std::string &class_name, const tl::arg &a,
bool is_default) const override {
bool is_default) const final {
if (!is_default || is_header_ == -1) {
return "";
}
@ -359,10 +359,10 @@ class TlWriterCCommon : public tl::TL_writer {
return ss.str();
}
std::string gen_constructor_field_init(int field_num, const std::string &class_name, const tl::arg &a,
bool is_default) const override {
bool is_default) const final {
return "";
}
std::string gen_constructor_end(const tl::tl_combinator *t, int field_count, bool is_default) const override {
std::string gen_constructor_end(const tl::tl_combinator *t, int field_count, bool is_default) const final {
if (!is_default || is_header_ == -1) {
return "";
}
@ -389,7 +389,7 @@ class TlWriterCCommon : public tl::TL_writer {
return ss.str();
}
std::string gen_additional_function(const std::string &function_name, const tl::tl_combinator *t,
bool is_function) const override {
bool is_function) const final {
std::stringstream ss;
if (function_name == "enum") {
return ss.str();
@ -547,11 +547,11 @@ class TlWriterCCommon : public tl::TL_writer {
}
};
struct file_store_methods_to_td : public file_store_methods {
struct file_store_methods_to_td final : public file_store_methods {
explicit file_store_methods_to_td(const class TlWriterCCommon *cl) : cl(cl) {
}
void store_simple_type(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
std::string type_name) const override {
std::string type_name) const final {
if (type_name == "String") {
ss << offset << res_var << " = (" << var << ") ? " << var << ": \"\";\n";
} else if (type_name == "Bytes") {
@ -563,35 +563,35 @@ class TlWriterCCommon : public tl::TL_writer {
}
}
void store_common_type(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
std::string type_name) const override {
std::string type_name) const final {
ss << offset << res_var << " = TdConvertToInternal (" << var << ");\n";
}
void store_array_start(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
}
void store_array_el(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
std::string idx) const override {
std::string idx) const final {
ss << offset << res_var << ".push_back (std::move (" << var << "));\n";
}
void store_array_finish(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
}
void store_nil(std::stringstream &ss, std::string offset) const override {
void store_nil(std::stringstream &ss, std::string offset) const final {
ss << offset << "return nullptr;\n";
}
std::string store_field_start(std::stringstream &ss, std::string offset, int depth,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
std::string res_var = "v" + int_to_string(depth);
ss << offset << cl->gen_native_type_name(tree_type, true) << " " << res_var << ";\n";
return res_var;
}
void store_field_finish(std::stringstream &ss, std::string offset, std::string res_var) const override {
void store_field_finish(std::stringstream &ss, std::string offset, std::string res_var) const final {
}
void store_arg_finish(std::stringstream &ss, std::string offset, std::string arg_name,
std::string res_var) const override {
std::string res_var) const final {
}
void store_constructor_finish(std::stringstream &ss, std::string offset, const tl::tl_combinator *t,
std::vector<std::string> res_var) const override {
std::vector<std::string> res_var) const final {
auto native_class_name = cl->gen_native_class_name(t->name);
ss << offset << "return td::td_api::make_object<td::td_api::" << native_class_name << ">(";
bool is_first = true;
@ -609,11 +609,11 @@ class TlWriterCCommon : public tl::TL_writer {
const class TlWriterCCommon *cl;
};
struct file_store_methods_destroy : public file_store_methods {
struct file_store_methods_destroy final : public file_store_methods {
explicit file_store_methods_destroy(const class TlWriterCCommon *cl) : cl(cl) {
}
void store_simple_type(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
std::string type_name) const override {
std::string type_name) const final {
if (type_name == "String") {
ss << offset << "free (" << var << ");\n";
} else if (type_name == "Bytes") {
@ -621,32 +621,32 @@ class TlWriterCCommon : public tl::TL_writer {
}
}
void store_common_type(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
std::string type_name) const override {
std::string type_name) const final {
ss << offset << "TdDestroyObject (" << var << ");\n";
}
void store_array_start(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
}
void store_array_el(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
std::string idx) const override {
std::string idx) const final {
}
void store_array_finish(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
ss << offset << "delete[] " << var << "->data;\n" << offset << "delete " << var << ";\n";
}
void store_nil(std::stringstream &ss, std::string offset) const override {
void store_nil(std::stringstream &ss, std::string offset) const final {
ss << offset << "return;\n";
}
std::string store_field_start(std::stringstream &ss, std::string offset, int depth,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
return "";
}
void store_field_finish(std::stringstream &ss, std::string offset, std::string res_var) const override {
void store_field_finish(std::stringstream &ss, std::string offset, std::string res_var) const final {
}
void store_arg_finish(std::stringstream &ss, std::string offset, std::string arg_name,
std::string res_var) const override {
std::string res_var) const final {
}
void store_constructor_start(std::stringstream &ss, std::string offset, const tl::tl_combinator *t) const override {
void store_constructor_start(std::stringstream &ss, std::string offset, const tl::tl_combinator *t) const final {
ss << "#if TD_MSVC\n";
ss << offset << "static_assert (sizeof (long) == sizeof (var->refcnt), \"Illegal InterlockedDecrement\");\n";
ss << offset << "int ref = InterlockedDecrement (reinterpret_cast<long *>(&var->refcnt));\n";
@ -661,16 +661,16 @@ class TlWriterCCommon : public tl::TL_writer {
ss << offset << "}\n";
}
void store_constructor_finish(std::stringstream &ss, std::string offset, const tl::tl_combinator *t,
std::vector<std::string> res_var) const override {
std::vector<std::string> res_var) const final {
ss << offset << "delete var;\n";
}
const class TlWriterCCommon *cl;
};
struct file_store_methods_stack : public file_store_methods {
struct file_store_methods_stack final : public file_store_methods {
explicit file_store_methods_stack(const class TlWriterCCommon *cl) : cl(cl) {
}
void store_simple_type(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
std::string type_name) const override {
std::string type_name) const final {
if (type_name == "String") {
ss << offset << "M->pack_string (" << var << ");\n";
} else if (type_name == "Bytes") {
@ -686,41 +686,41 @@ class TlWriterCCommon : public tl::TL_writer {
}
}
void store_common_type(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
std::string type_name) const override {
std::string type_name) const final {
ss << offset << "TdStackStorer (" << var << ", M);\n";
}
void store_array_start(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
ss << offset << "M->new_array ();\n";
}
void store_array_el(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
std::string idx) const override {
std::string idx) const final {
ss << offset << "M->new_arr_field (" << idx << ");\n";
}
void store_array_finish(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
}
void store_nil(std::stringstream &ss, std::string offset) const override {
void store_nil(std::stringstream &ss, std::string offset) const final {
ss << offset << "M->pack_bool (0);\n" << offset << "return;\n";
}
std::string store_field_start(std::stringstream &ss, std::string offset, int depth,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
return "";
}
void store_field_finish(std::stringstream &ss, std::string offset, std::string res_var) const override {
void store_field_finish(std::stringstream &ss, std::string offset, std::string res_var) const final {
}
void store_arg_finish(std::stringstream &ss, std::string offset, std::string arg_name,
std::string res_var) const override {
std::string res_var) const final {
ss << offset << "M->new_field (\"" << arg_name << "\");\n";
}
void store_constructor_start(std::stringstream &ss, std::string offset, const tl::tl_combinator *t) const override {
void store_constructor_start(std::stringstream &ss, std::string offset, const tl::tl_combinator *t) const final {
ss << offset << "M->new_table ();\n";
auto class_name = cl->gen_class_name(t->name);
ss << offset << "M->pack_string (\"" << class_name << "\");\n";
ss << offset << "M->new_field (\"ID\");\n";
}
void store_constructor_finish(std::stringstream &ss, std::string offset, const tl::tl_combinator *t,
std::vector<std::string> res_var) const override {
std::vector<std::string> res_var) const final {
}
const class TlWriterCCommon *cl;
};
@ -767,15 +767,15 @@ class TlWriterCCommon : public tl::TL_writer {
}
};
struct file_fetch_methods_from_td : public file_fetch_methods {
struct file_fetch_methods_from_td final : public file_fetch_methods {
explicit file_fetch_methods_from_td(const class TlWriterCCommon *cl) : cl(cl) {
}
std::string fetch_field_start(std::stringstream &ss, std::string offset, int depth,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
return "";
}
void fetch_simple_type(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
std::string type_name) const override {
std::string type_name) const final {
if (type_name == "String") {
ss << offset << res_var << " = (" << var << ".length ()) ? td::str_dup (" << var << ") : nullptr;\n";
} else if (type_name == "Bytes") {
@ -791,7 +791,7 @@ class TlWriterCCommon : public tl::TL_writer {
}
}
void fetch_common_type(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
auto native_type_name = cl->gen_native_type_name(tree_type, false);
ss << offset << "if (!" << var << ") {\n"
<< offset << " " << res_var << " = nullptr;\n"
@ -801,32 +801,32 @@ class TlWriterCCommon : public tl::TL_writer {
<< offset << "}\n";
}
void fetch_array_size(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
ss << offset << res_var << " = (int)" << var << ".size ();\n";
}
std::string fetch_array_field_start(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
std::string idx, const tl::tl_tree_type *tree_type) const override {
std::string idx, const tl::tl_tree_type *tree_type) const final {
return var + "[" + idx + "]";
}
std::string fetch_dict_field_start(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
std::string key, const tl::tl_tree_type *tree_type) const override {
std::string key, const tl::tl_tree_type *tree_type) const final {
return var + "." + key;
}
void fetch_field_finish(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
}
const class TlWriterCCommon *cl;
};
struct file_fetch_methods_stack : public file_fetch_methods {
struct file_fetch_methods_stack final : public file_fetch_methods {
explicit file_fetch_methods_stack(const class TlWriterCCommon *cl) : cl(cl) {
}
std::string fetch_field_start(std::stringstream &ss, std::string offset, int depth,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
return "";
}
void fetch_simple_type(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
std::string type_name) const override {
std::string type_name) const final {
if (type_name == "String") {
ss << offset << res_var << " = M->get_string ();\n";
} else if (type_name == "Bytes") {
@ -842,7 +842,7 @@ class TlWriterCCommon : public tl::TL_writer {
}
}
void fetch_common_type(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
auto class_name = cl->gen_main_class_name(tree_type->type);
ss << offset << "if (M->is_nil ()) {\n"
<< offset << " " << res_var << " = nullptr;\n"
@ -851,21 +851,21 @@ class TlWriterCCommon : public tl::TL_writer {
<< offset << "}\n";
}
void fetch_array_size(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
ss << offset << res_var << " = M->get_arr_size ();\n";
}
std::string fetch_array_field_start(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
std::string idx, const tl::tl_tree_type *tree_type) const override {
std::string idx, const tl::tl_tree_type *tree_type) const final {
ss << offset << " M->get_arr_field (" << idx << ");\n";
return "";
}
std::string fetch_dict_field_start(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
std::string key, const tl::tl_tree_type *tree_type) const override {
std::string key, const tl::tl_tree_type *tree_type) const final {
ss << offset << "M->get_field (\"" << key << "\");\n";
return "";
}
void fetch_field_finish(std::stringstream &ss, std::string offset, std::string res_var, std::string var,
const tl::tl_tree_type *tree_type) const override {
const tl::tl_tree_type *tree_type) const final {
ss << offset << "M->pop ();\n";
}
const class TlWriterCCommon *cl;
@ -949,74 +949,74 @@ class TlWriterCCommon : public tl::TL_writer {
<< "}\n";
}
std::string gen_array_type_name(const tl::tl_tree_array *arr, const std::string &field_name) const override {
std::string gen_array_type_name(const tl::tl_tree_array *arr, const std::string &field_name) const final {
assert(false);
return std::string();
}
std::string gen_var_type_name() const override {
std::string gen_var_type_name() const final {
assert(false);
return std::string();
}
std::string gen_int_const(const tl::tl_tree *tree_c, const std::vector<tl::var_description> &vars) const override {
std::string gen_int_const(const tl::tl_tree *tree_c, const std::vector<tl::var_description> &vars) const final {
assert(false);
return std::string();
}
std::string gen_var_name(const tl::var_description &desc) const override {
std::string gen_var_name(const tl::var_description &desc) const final {
assert(false);
return "";
}
std::string gen_parameter_name(int index) const override {
std::string gen_parameter_name(int index) const final {
assert(false);
return "";
}
std::string gen_class_alias(const std::string &class_name, const std::string &alias_name) const override {
std::string gen_class_alias(const std::string &class_name, const std::string &alias_name) const final {
return "";
}
std::string gen_vars(const tl::tl_combinator *t, const tl::tl_tree_type *result_type,
std::vector<tl::var_description> &vars) const override {
std::vector<tl::var_description> &vars) const final {
assert(vars.empty());
return "";
}
std::string gen_function_vars(const tl::tl_combinator *t, std::vector<tl::var_description> &vars) const override {
std::string gen_function_vars(const tl::tl_combinator *t, std::vector<tl::var_description> &vars) const final {
assert(vars.empty());
return "";
}
std::string gen_uni(const tl::tl_tree_type *result_type, std::vector<tl::var_description> &vars,
bool check_negative) const override {
bool check_negative) const final {
assert(result_type->children.empty());
return "";
}
std::string gen_constructor_id_store(std::int32_t id, int storer_type) const override {
std::string gen_constructor_id_store(std::int32_t id, int storer_type) const final {
return "";
}
std::string gen_field_fetch(int field_num, const tl::arg &a, std::vector<tl::var_description> &vars, bool flat,
int parser_type) const override {
int parser_type) const final {
return "";
}
std::string gen_field_store(const tl::arg &a, std::vector<tl::var_description> &vars, bool flat,
int storer_type) const override {
int storer_type) const final {
return "";
}
std::string gen_type_fetch(const std::string &field_name, const tl::tl_tree_type *tree_type,
const std::vector<tl::var_description> &vars, int parser_type) const override {
const std::vector<tl::var_description> &vars, int parser_type) const final {
assert(vars.empty());
return "";
}
std::string gen_type_store(const std::string &field_name, const tl::tl_tree_type *tree_type,
const std::vector<tl::var_description> &vars, int storer_type) const override {
const std::vector<tl::var_description> &vars, int storer_type) const final {
return "";
}
std::string gen_var_type_fetch(const tl::arg &a) const override {
std::string gen_var_type_fetch(const tl::arg &a) const final {
assert(false);
return "";
}
std::string gen_get_id(const std::string &class_name, std::int32_t id, bool is_proxy) const override {
std::string gen_get_id(const std::string &class_name, std::int32_t id, bool is_proxy) const final {
if (is_proxy || is_header_ != 1) {
return "";
}
@ -1024,47 +1024,47 @@ class TlWriterCCommon : public tl::TL_writer {
return "";
}
std::string gen_function_result_type(const tl::tl_tree *result) const override {
std::string gen_function_result_type(const tl::tl_tree *result) const final {
return "";
}
std::string gen_fetch_function_begin(const std::string &parser_name, const std::string &class_name,
const std::string &parent_class_name, int arity, int field_count,
std::vector<tl::var_description> &vars, int parser_type) const override {
std::vector<tl::var_description> &vars, int parser_type) const final {
return "";
}
std::string gen_fetch_function_end(bool has_parent, int field_count, const std::vector<tl::var_description> &vars,
int parser_type) const override {
int parser_type) const final {
return "";
}
std::string gen_fetch_function_result_begin(const std::string &parser_name, const std::string &class_name,
const tl::tl_tree *result) const override {
const tl::tl_tree *result) const final {
return "";
}
std::string gen_fetch_function_result_end() const override {
std::string gen_fetch_function_result_end() const final {
return "";
}
std::string gen_fetch_function_result_any_begin(const std::string &parser_name, const std::string &class_name,
bool is_proxy) const override {
bool is_proxy) const final {
return "";
}
std::string gen_fetch_function_result_any_end(bool is_proxy) const override {
std::string gen_fetch_function_result_any_end(bool is_proxy) const final {
return "";
}
std::string gen_fetch_switch_begin() const override {
std::string gen_fetch_switch_begin() const final {
return "";
}
std::string gen_fetch_switch_case(const tl::tl_combinator *t, int arity) const override {
std::string gen_fetch_switch_case(const tl::tl_combinator *t, int arity) const final {
return "";
}
std::string gen_fetch_switch_end() const override {
std::string gen_fetch_switch_end() const final {
return "";
}
std::string gen_additional_proxy_function_begin(const std::string &function_name, const tl::tl_type *type,
const std::string &name, int arity, bool is_function) const override {
const std::string &name, int arity, bool is_function) const final {
std::stringstream ss;
std::string class_name;
std::string native_class_name;
@ -1208,7 +1208,7 @@ class TlWriterCCommon : public tl::TL_writer {
}
std::string gen_additional_proxy_function_case(const std::string &function_name, const tl::tl_type *type,
const std::string &class_name, int arity) const override {
const std::string &class_name, int arity) const final {
if (is_header_ != (function_name == "enum" ? 1 : 0)) {
return "";
}
@ -1243,8 +1243,7 @@ class TlWriterCCommon : public tl::TL_writer {
}
std::string gen_additional_proxy_function_case(const std::string &function_name, const tl::tl_type *type,
const tl::tl_combinator *t, int arity,
bool is_function) const override {
const tl::tl_combinator *t, int arity, bool is_function) const final {
if (is_header_ != (function_name == "enum" ? 1 : 0)) {
return "";
}
@ -1321,7 +1320,7 @@ class TlWriterCCommon : public tl::TL_writer {
}
}
std::string gen_additional_proxy_function_end(const std::string &function_name, const tl::tl_type *type,
bool is_function) const override {
bool is_function) const final {
if (is_header_ != (function_name == "enum" ? 1 : 0)) {
return "";
}
@ -1352,7 +1351,7 @@ class TlWriterCCommon : public tl::TL_writer {
}
}
int get_additional_function_type(const std::string &additional_function_name) const override {
int get_additional_function_type(const std::string &additional_function_name) const final {
return 2;
}
};

View File

@ -17,59 +17,59 @@
namespace td {
namespace tl {
class TlWriterDotNet : public TL_writer {
class TlWriterDotNet final : public TL_writer {
public:
bool is_header_;
std::string prefix_;
TlWriterDotNet(const std::string &name, bool is_header, const std::string &prefix = "")
: TL_writer(name), is_header_(is_header), prefix_(prefix) {
}
int get_max_arity(void) const override {
int get_max_arity(void) const final {
return 0;
}
bool is_built_in_simple_type(const std::string &name) const override {
bool is_built_in_simple_type(const std::string &name) const final {
return name == "Bool" || name == "Int32" || name == "Int53" || name == "Int64" || name == "Double" ||
name == "String" || name == "Bytes";
}
bool is_built_in_complex_type(const std::string &name) const override {
bool is_built_in_complex_type(const std::string &name) const final {
return name == "Vector";
}
bool is_type_bare(const tl_type *t) const override {
bool is_type_bare(const tl_type *t) const final {
return t->simple_constructors <= 1 || (is_built_in_simple_type(t->name) && t->name != "Bool") ||
is_built_in_complex_type(t->name);
}
std::vector<std::string> get_parsers(void) const override {
std::vector<std::string> get_parsers(void) const final {
return {"FromUnmanaged"};
}
int get_parser_type(const tl_combinator *t, const std::string &name) const override {
int get_parser_type(const tl_combinator *t, const std::string &name) const final {
return 0;
}
Mode get_parser_mode(int type) const override {
Mode get_parser_mode(int type) const final {
return All; // Server;
}
std::vector<std::string> get_storers(void) const override {
std::vector<std::string> get_storers(void) const final {
return {"ToUnmanaged", "ToString"};
}
std::vector<std::string> get_additional_functions(void) const override {
std::vector<std::string> get_additional_functions(void) const final {
return {"ToUnmanaged", "FromUnmanaged"};
}
int get_storer_type(const tl_combinator *t, const std::string &name) const override {
int get_storer_type(const tl_combinator *t, const std::string &name) const final {
return name == "ToString";
}
Mode get_storer_mode(int type) const override {
Mode get_storer_mode(int type) const final {
return type <= 1 ? All : Server;
}
std::string gen_base_tl_class_name(void) const override {
std::string gen_base_tl_class_name(void) const final {
return "BaseObject";
}
std::string gen_base_type_class_name(int arity) const override {
std::string gen_base_type_class_name(int arity) const final {
assert(arity == 0);
return "Object";
}
std::string gen_base_function_class_name(void) const override {
std::string gen_base_function_class_name(void) const final {
return "Function";
}
@ -123,19 +123,19 @@ class TlWriterDotNet : public TL_writer {
return name;
}
std::string gen_class_name(std::string name) const override {
std::string gen_class_name(std::string name) const final {
if (name == "Object" || name == "#") {
assert(0);
}
return to_CamelCase(name);
}
std::string gen_field_name(std::string name) const override {
std::string gen_field_name(std::string name) const final {
assert(name.size() > 0);
assert(is_alnum(name.back()));
return to_CamelCase(name);
}
std::string gen_type_name(const tl_tree_type *tree_type) const override {
std::string gen_type_name(const tl_tree_type *tree_type) const final {
const tl_type *t = tree_type->type;
const std::string &name = t->name;
@ -178,20 +178,20 @@ class TlWriterDotNet : public TL_writer {
return gen_main_class_name(t) + "^";
}
std::string gen_output_begin(void) const override {
std::string gen_output_begin(void) const final {
return prefix_ +
"#include \"td/tl/tl_dotnet_object.h\"\n\n"
"namespace Telegram {\n"
"namespace Td {\n"
"namespace Api {\n";
}
std::string gen_output_end() const override {
std::string gen_output_end() const final {
return "}\n"
"}\n"
"}\n";
}
std::string gen_forward_class_declaration(const std::string &class_name, bool is_proxy) const override {
std::string gen_forward_class_declaration(const std::string &class_name, bool is_proxy) const final {
if (!is_header_) {
return "";
}
@ -201,7 +201,7 @@ class TlWriterDotNet : public TL_writer {
}
std::string gen_class_begin(const std::string &class_name, const std::string &base_class_name,
bool is_proxy) const override {
bool is_proxy) const final {
if (!is_header_) {
return "";
}
@ -212,12 +212,12 @@ class TlWriterDotNet : public TL_writer {
<< " public:\n";
return ss.str();
}
std::string gen_class_end(void) const override {
std::string gen_class_end(void) const final {
return "";
}
std::string gen_field_definition(const std::string &class_name, const std::string &type_name,
const std::string &field_name) const override {
const std::string &field_name) const final {
if (!is_header_) {
return "";
}
@ -245,7 +245,7 @@ class TlWriterDotNet : public TL_writer {
}
std::string gen_store_function_begin(const std::string &storer_name, const std::string &class_name, int arity,
std::vector<var_description> &vars, int storer_type) const override {
std::vector<var_description> &vars, int storer_type) const final {
if (storer_type < 0) {
return "";
}
@ -266,18 +266,18 @@ class TlWriterDotNet : public TL_writer {
}
return ss.str();
}
std::string gen_store_function_end(const std::vector<var_description> &vars, int storer_type) const override {
std::string gen_store_function_end(const std::vector<var_description> &vars, int storer_type) const final {
return "";
}
std::string gen_constructor_begin(int field_count, const std::string &class_name, bool is_default) const override {
std::string gen_constructor_begin(int field_count, const std::string &class_name, bool is_default) const final {
std::stringstream ss;
ss << "\n";
ss << (is_header_ ? " " : gen_class_name(class_name) + "::") << gen_class_name(class_name) << "(";
return ss.str();
}
std::string gen_constructor_parameter(int field_num, const std::string &class_name, const arg &a,
bool is_default) const override {
bool is_default) const final {
if (is_default) {
return "";
}
@ -296,7 +296,7 @@ class TlWriterDotNet : public TL_writer {
return ss.str();
}
std::string gen_constructor_field_init(int field_num, const std::string &class_name, const arg &a,
bool is_default) const override {
bool is_default) const final {
if (is_default || is_header_) {
return "";
}
@ -313,7 +313,7 @@ class TlWriterDotNet : public TL_writer {
return ss.str();
}
std::string gen_constructor_end(const tl_combinator *t, int field_count, bool is_default) const override {
std::string gen_constructor_end(const tl_combinator *t, int field_count, bool is_default) const final {
if (is_header_) {
return ");\n";
}
@ -325,7 +325,7 @@ class TlWriterDotNet : public TL_writer {
return ss.str();
}
std::string gen_additional_function(const std::string &function_name, const tl_combinator *t,
bool is_function) const override {
bool is_function) const final {
std::stringstream ss;
if (is_header_ && function_name == "ToUnmanaged") {
ss << "};\n";
@ -390,124 +390,124 @@ class TlWriterDotNet : public TL_writer {
ss << ");\n}\n";
}
std::string gen_array_type_name(const tl_tree_array *arr, const std::string &field_name) const override {
std::string gen_array_type_name(const tl_tree_array *arr, const std::string &field_name) const final {
assert(0);
return std::string();
}
std::string gen_var_type_name(void) const override {
std::string gen_var_type_name(void) const final {
assert(0);
return std::string();
}
std::string gen_int_const(const tl_tree *tree_c, const std::vector<var_description> &vars) const override {
std::string gen_int_const(const tl_tree *tree_c, const std::vector<var_description> &vars) const final {
assert(0);
return std::string();
}
std::string gen_var_name(const var_description &desc) const override {
std::string gen_var_name(const var_description &desc) const final {
assert(0);
return "";
}
std::string gen_parameter_name(int index) const override {
std::string gen_parameter_name(int index) const final {
assert(0);
return "";
}
std::string gen_class_alias(const std::string &class_name, const std::string &alias_name) const override {
std::string gen_class_alias(const std::string &class_name, const std::string &alias_name) const final {
return "";
}
std::string gen_vars(const tl_combinator *t, const tl_tree_type *result_type,
std::vector<var_description> &vars) const override {
std::vector<var_description> &vars) const final {
assert(vars.empty());
return "";
}
std::string gen_function_vars(const tl_combinator *t, std::vector<var_description> &vars) const override {
std::string gen_function_vars(const tl_combinator *t, std::vector<var_description> &vars) const final {
assert(vars.empty());
return "";
}
std::string gen_uni(const tl_tree_type *result_type, std::vector<var_description> &vars,
bool check_negative) const override {
bool check_negative) const final {
assert(result_type->children.empty());
return "";
}
std::string gen_constructor_id_store(std::int32_t id, int storer_type) const override {
std::string gen_constructor_id_store(std::int32_t id, int storer_type) const final {
return "";
}
std::string gen_field_fetch(int field_num, const arg &a, std::vector<var_description> &vars, bool flat,
int parser_type) const override {
int parser_type) const final {
return "";
// std::stringstream ss;
// ss << gen_field_name(a.name) << " = from_unmanaged(from->" <<
// gen_native_field_name(a.name) << ");\n"; return ss.str();
}
std::string gen_field_store(const arg &a, std::vector<var_description> &vars, bool flat,
int storer_type) const override {
int storer_type) const final {
return "";
// std::stringstream ss;
// ss << "to_unmanaged(" << gen_field_name(a.name) << ")";
// return ss.str();
}
std::string gen_type_fetch(const std::string &field_name, const tl_tree_type *tree_type,
const std::vector<var_description> &vars, int parser_type) const override {
const std::vector<var_description> &vars, int parser_type) const final {
assert(vars.empty());
return "";
}
std::string gen_type_store(const std::string &field_name, const tl_tree_type *tree_type,
const std::vector<var_description> &vars, int storer_type) const override {
const std::vector<var_description> &vars, int storer_type) const final {
return "";
}
std::string gen_var_type_fetch(const arg &a) const override {
std::string gen_var_type_fetch(const arg &a) const final {
assert(0);
return "";
}
std::string gen_get_id(const std::string &class_name, std::int32_t id, bool is_proxy) const override {
std::string gen_get_id(const std::string &class_name, std::int32_t id, bool is_proxy) const final {
return "";
}
std::string gen_function_result_type(const tl_tree *result) const override {
std::string gen_function_result_type(const tl_tree *result) const final {
return "";
}
std::string gen_fetch_function_begin(const std::string &parser_name, const std::string &class_name,
const std::string &parent_class_name, int arity, int field_count,
std::vector<var_description> &vars, int parser_type) const override {
std::vector<var_description> &vars, int parser_type) const final {
return "";
}
std::string gen_fetch_function_end(bool has_parent, int field_count, const std::vector<var_description> &vars,
int parser_type) const override {
int parser_type) const final {
return "";
}
std::string gen_fetch_function_result_begin(const std::string &parser_name, const std::string &class_name,
const tl_tree *result) const override {
const tl_tree *result) const final {
return "";
}
std::string gen_fetch_function_result_end(void) const override {
std::string gen_fetch_function_result_end(void) const final {
return "";
}
std::string gen_fetch_function_result_any_begin(const std::string &parser_name, const std::string &class_name,
bool is_proxy) const override {
bool is_proxy) const final {
return "";
}
std::string gen_fetch_function_result_any_end(bool is_proxy) const override {
std::string gen_fetch_function_result_any_end(bool is_proxy) const final {
return "";
}
std::string gen_fetch_switch_begin(void) const override {
std::string gen_fetch_switch_begin(void) const final {
return "";
}
std::string gen_fetch_switch_case(const tl_combinator *t, int arity) const override {
std::string gen_fetch_switch_case(const tl_combinator *t, int arity) const final {
return "";
}
std::string gen_fetch_switch_end(void) const override {
std::string gen_fetch_switch_end(void) const final {
return "";
}
std::string gen_additional_proxy_function_begin(const std::string &function_name, const tl_type *type,
const std::string &name, int arity, bool is_function) const override {
const std::string &name, int arity, bool is_function) const final {
std::stringstream ss;
if (is_header_ && function_name == "ToUnmanaged") {
ss << "};\n";
@ -542,15 +542,15 @@ class TlWriterDotNet : public TL_writer {
return ss.str();
}
std::string gen_additional_proxy_function_case(const std::string &function_name, const tl_type *type,
const std::string &class_name, int arity) const override {
const std::string &class_name, int arity) const final {
return "";
}
std::string gen_additional_proxy_function_case(const std::string &function_name, const tl_type *type,
const tl_combinator *t, int arity, bool is_function) const override {
const tl_combinator *t, int arity, bool is_function) const final {
return "";
}
std::string gen_additional_proxy_function_end(const std::string &function_name, const tl_type *type,
bool is_function) const override {
bool is_function) const final {
return "";
}
};

View File

@ -14,95 +14,94 @@
namespace td {
class TD_TL_writer_hpp : public TD_TL_writer {
class TD_TL_writer_hpp final : public TD_TL_writer {
public:
TD_TL_writer_hpp(const std::string &tl_name, const std::string &string_type, const std::string &bytes_type)
: TD_TL_writer(tl_name, string_type, bytes_type) {
}
bool is_documentation_generated() const override;
bool is_documentation_generated() const final;
int get_additional_function_type(const std::string &additional_function_name) const override;
std::vector<std::string> get_additional_functions() const override;
int get_additional_function_type(const std::string &additional_function_name) const final;
std::vector<std::string> get_additional_functions() const final;
std::string gen_base_type_class_name(int arity) const override;
std::string gen_base_tl_class_name() const override;
std::string gen_base_type_class_name(int arity) const final;
std::string gen_base_tl_class_name() const final;
std::string gen_output_begin() const override;
std::string gen_output_end() const override;
std::string gen_output_begin() const final;
std::string gen_output_end() const final;
std::string gen_forward_class_declaration(const std::string &class_name, bool is_proxy) const override;
std::string gen_forward_class_declaration(const std::string &class_name, bool is_proxy) const final;
std::string gen_class_begin(const std::string &class_name, const std::string &base_class_name,
bool is_proxy) const override;
std::string gen_class_end() const override;
bool is_proxy) const final;
std::string gen_class_end() const final;
std::string gen_class_alias(const std::string &class_name, const std::string &alias_name) const override;
std::string gen_class_alias(const std::string &class_name, const std::string &alias_name) const final;
std::string gen_field_definition(const std::string &class_name, const std::string &type_name,
const std::string &field_name) const override;
const std::string &field_name) const final;
std::string gen_vars(const tl::tl_combinator *t, const tl::tl_tree_type *result_type,
std::vector<tl::var_description> &vars) const override;
std::string gen_function_vars(const tl::tl_combinator *t, std::vector<tl::var_description> &vars) const override;
std::vector<tl::var_description> &vars) const final;
std::string gen_function_vars(const tl::tl_combinator *t, std::vector<tl::var_description> &vars) const final;
std::string gen_uni(const tl::tl_tree_type *result_type, std::vector<tl::var_description> &vars,
bool check_negative) const override;
std::string gen_constructor_id_store(std::int32_t id, int storer_type) const override;
bool check_negative) const final;
std::string gen_constructor_id_store(std::int32_t id, int storer_type) const final;
std::string gen_field_fetch(int field_num, const tl::arg &a, std::vector<tl::var_description> &vars, bool flat,
int parser_type) const override;
int parser_type) const final;
std::string gen_field_store(const tl::arg &a, std::vector<tl::var_description> &vars, bool flat,
int storer_type) const override;
int storer_type) const final;
std::string gen_type_fetch(const std::string &field_name, const tl::tl_tree_type *tree_type,
const std::vector<tl::var_description> &vars, int parser_type) const override;
const std::vector<tl::var_description> &vars, int parser_type) const final;
std::string gen_type_store(const std::string &field_name, const tl::tl_tree_type *tree_type,
const std::vector<tl::var_description> &vars, int storer_type) const override;
std::string gen_var_type_fetch(const tl::arg &a) const override;
const std::vector<tl::var_description> &vars, int storer_type) const final;
std::string gen_var_type_fetch(const tl::arg &a) const final;
std::string gen_get_id(const std::string &class_name, std::int32_t id, bool is_proxy) const override;
std::string gen_get_id(const std::string &class_name, std::int32_t id, bool is_proxy) const final;
std::string gen_function_result_type(const tl::tl_tree *result) const override;
std::string gen_function_result_type(const tl::tl_tree *result) const final;
std::string gen_fetch_function_begin(const std::string &parser_name, const std::string &class_name,
const std::string &parent_class_name, int arity, int field_count,
std::vector<tl::var_description> &vars, int parser_type) const override;
std::vector<tl::var_description> &vars, int parser_type) const final;
std::string gen_fetch_function_end(bool has_parent, int field_count, const std::vector<tl::var_description> &vars,
int parser_type) const override;
int parser_type) const final;
std::string gen_fetch_function_result_begin(const std::string &parser_name, const std::string &class_name,
const tl::tl_tree *result) const override;
std::string gen_fetch_function_result_end() const override;
const tl::tl_tree *result) const final;
std::string gen_fetch_function_result_end() const final;
std::string gen_fetch_function_result_any_begin(const std::string &parser_name, const std::string &class_name,
bool is_proxy) const override;
std::string gen_fetch_function_result_any_end(bool is_proxy) const override;
bool is_proxy) const final;
std::string gen_fetch_function_result_any_end(bool is_proxy) const final;
std::string gen_store_function_begin(const std::string &storer_name, const std::string &class_name, int arity,
std::vector<tl::var_description> &vars, int storer_type) const override;
std::string gen_store_function_end(const std::vector<tl::var_description> &vars, int storer_type) const override;
std::vector<tl::var_description> &vars, int storer_type) const final;
std::string gen_store_function_end(const std::vector<tl::var_description> &vars, int storer_type) const final;
std::string gen_fetch_switch_begin() const override;
std::string gen_fetch_switch_case(const tl::tl_combinator *t, int arity) const override;
std::string gen_fetch_switch_end() const override;
std::string gen_fetch_switch_begin() const final;
std::string gen_fetch_switch_case(const tl::tl_combinator *t, int arity) const final;
std::string gen_fetch_switch_end() const final;
std::string gen_constructor_begin(int field_count, const std::string &class_name, bool is_default) const override;
std::string gen_constructor_begin(int field_count, const std::string &class_name, bool is_default) const final;
std::string gen_constructor_parameter(int field_num, const std::string &class_name, const tl::arg &a,
bool is_default) const override;
bool is_default) const final;
std::string gen_constructor_field_init(int field_num, const std::string &class_name, const tl::arg &a,
bool is_default) const override;
std::string gen_constructor_end(const tl::tl_combinator *t, int field_count, bool is_default) const override;
bool is_default) const final;
std::string gen_constructor_end(const tl::tl_combinator *t, int field_count, bool is_default) const final;
std::string gen_additional_function(const std::string &function_name, const tl::tl_combinator *t,
bool is_function) const override;
bool is_function) const final;
std::string gen_additional_proxy_function_begin(const std::string &function_name, const tl::tl_type *type,
const std::string &class_name, int arity,
bool is_function) const override;
bool is_function) const final;
std::string gen_additional_proxy_function_case(const std::string &function_name, const tl::tl_type *type,
const std::string &class_name, int arity) const override;
const std::string &class_name, int arity) const final;
std::string gen_additional_proxy_function_case(const std::string &function_name, const tl::tl_type *type,
const tl::tl_combinator *t, int arity,
bool is_function) const override;
const tl::tl_combinator *t, int arity, bool is_function) const final;
std::string gen_additional_proxy_function_end(const std::string &function_name, const tl::tl_type *type,
bool is_function) const override;
bool is_function) const final;
};
} // namespace td

View File

@ -14,7 +14,7 @@
namespace td {
class TD_TL_writer_java : public tl::TL_writer {
class TD_TL_writer_java final : public tl::TL_writer {
static const int MAX_ARITY = 0;
static const std::string base_type_class_names[MAX_ARITY + 1];
@ -28,92 +28,92 @@ class TD_TL_writer_java : public tl::TL_writer {
: TL_writer(tl_name), package_name(package_name) {
}
int get_max_arity() const override;
int get_max_arity() const final;
bool is_built_in_simple_type(const std::string &name) const override;
bool is_built_in_complex_type(const std::string &name) const override;
bool is_type_bare(const tl::tl_type *t) const override;
bool is_combinator_supported(const tl::tl_combinator *constructor) const override;
bool is_built_in_simple_type(const std::string &name) const final;
bool is_built_in_complex_type(const std::string &name) const final;
bool is_type_bare(const tl::tl_type *t) const final;
bool is_combinator_supported(const tl::tl_combinator *constructor) const final;
int get_parser_type(const tl::tl_combinator *t, const std::string &parser_name) const override;
int get_storer_type(const tl::tl_combinator *t, const std::string &storer_name) const override;
std::vector<std::string> get_parsers() const override;
std::vector<std::string> get_storers() const override;
int get_parser_type(const tl::tl_combinator *t, const std::string &parser_name) const final;
int get_storer_type(const tl::tl_combinator *t, const std::string &storer_name) const final;
std::vector<std::string> get_parsers() const final;
std::vector<std::string> get_storers() const final;
std::string gen_base_tl_class_name() const override;
std::string gen_base_type_class_name(int arity) const override;
std::string gen_base_function_class_name() const override;
std::string gen_class_name(std::string name) const override;
std::string gen_field_name(std::string name) const override;
std::string gen_var_name(const tl::var_description &desc) const override;
std::string gen_parameter_name(int index) const override;
std::string gen_type_name(const tl::tl_tree_type *tree_type) const override;
std::string gen_array_type_name(const tl::tl_tree_array *arr, const std::string &field_name) const override;
std::string gen_var_type_name() const override;
std::string gen_base_tl_class_name() const final;
std::string gen_base_type_class_name(int arity) const final;
std::string gen_base_function_class_name() const final;
std::string gen_class_name(std::string name) const final;
std::string gen_field_name(std::string name) const final;
std::string gen_var_name(const tl::var_description &desc) const final;
std::string gen_parameter_name(int index) const final;
std::string gen_type_name(const tl::tl_tree_type *tree_type) const final;
std::string gen_array_type_name(const tl::tl_tree_array *arr, const std::string &field_name) const final;
std::string gen_var_type_name() const final;
std::string gen_int_const(const tl::tl_tree *tree_c, const std::vector<tl::var_description> &vars) const override;
std::string gen_int_const(const tl::tl_tree *tree_c, const std::vector<tl::var_description> &vars) const final;
std::string gen_output_begin() const override;
std::string gen_output_end() const override;
std::string gen_output_begin() const final;
std::string gen_output_end() const final;
std::string gen_forward_class_declaration(const std::string &class_name, bool is_proxy) const override;
std::string gen_forward_class_declaration(const std::string &class_name, bool is_proxy) const final;
std::string gen_class_begin(const std::string &class_name, const std::string &base_class_name,
bool is_proxy) const override;
std::string gen_class_end() const override;
bool is_proxy) const final;
std::string gen_class_end() const final;
std::string gen_class_alias(const std::string &class_name, const std::string &alias_name) const override;
std::string gen_class_alias(const std::string &class_name, const std::string &alias_name) const final;
std::string gen_field_definition(const std::string &class_name, const std::string &type_name,
const std::string &field_name) const override;
const std::string &field_name) const final;
std::string gen_vars(const tl::tl_combinator *t, const tl::tl_tree_type *result_type,
std::vector<tl::var_description> &vars) const override;
std::string gen_function_vars(const tl::tl_combinator *t, std::vector<tl::var_description> &vars) const override;
std::vector<tl::var_description> &vars) const final;
std::string gen_function_vars(const tl::tl_combinator *t, std::vector<tl::var_description> &vars) const final;
std::string gen_uni(const tl::tl_tree_type *result_type, std::vector<tl::var_description> &vars,
bool check_negative) const override;
std::string gen_constructor_id_store(std::int32_t id, int storer_type) const override;
bool check_negative) const final;
std::string gen_constructor_id_store(std::int32_t id, int storer_type) const final;
std::string gen_field_fetch(int field_num, const tl::arg &a, std::vector<tl::var_description> &vars, bool flat,
int parser_type) const override;
int parser_type) const final;
std::string gen_field_store(const tl::arg &a, std::vector<tl::var_description> &vars, bool flat,
int storer_type) const override;
int storer_type) const final;
std::string gen_type_fetch(const std::string &field_name, const tl::tl_tree_type *tree_type,
const std::vector<tl::var_description> &vars, int parser_type) const override;
const std::vector<tl::var_description> &vars, int parser_type) const final;
std::string gen_type_store(const std::string &field_name, const tl::tl_tree_type *tree_type,
const std::vector<tl::var_description> &vars, int storer_type) const override;
std::string gen_var_type_fetch(const tl::arg &a) const override;
const std::vector<tl::var_description> &vars, int storer_type) const final;
std::string gen_var_type_fetch(const tl::arg &a) const final;
std::string gen_get_id(const std::string &class_name, std::int32_t id, bool is_proxy) const override;
std::string gen_get_id(const std::string &class_name, std::int32_t id, bool is_proxy) const final;
std::string gen_function_result_type(const tl::tl_tree *result) const override;
std::string gen_function_result_type(const tl::tl_tree *result) const final;
std::string gen_fetch_function_begin(const std::string &parser_name, const std::string &class_name,
const std::string &parent_class_name, int arity, int field_count,
std::vector<tl::var_description> &vars, int parser_type) const override;
std::vector<tl::var_description> &vars, int parser_type) const final;
std::string gen_fetch_function_end(bool has_parent, int field_count, const std::vector<tl::var_description> &vars,
int parser_type) const override;
int parser_type) const final;
std::string gen_fetch_function_result_begin(const std::string &parser_name, const std::string &class_name,
const tl::tl_tree *result) const override;
std::string gen_fetch_function_result_end() const override;
const tl::tl_tree *result) const final;
std::string gen_fetch_function_result_end() const final;
std::string gen_fetch_function_result_any_begin(const std::string &parser_name, const std::string &class_name,
bool is_proxy) const override;
std::string gen_fetch_function_result_any_end(bool is_proxy) const override;
bool is_proxy) const final;
std::string gen_fetch_function_result_any_end(bool is_proxy) const final;
std::string gen_store_function_begin(const std::string &storer_name, const std::string &class_name, int arity,
std::vector<tl::var_description> &vars, int storer_type) const override;
std::string gen_store_function_end(const std::vector<tl::var_description> &vars, int storer_type) const override;
std::vector<tl::var_description> &vars, int storer_type) const final;
std::string gen_store_function_end(const std::vector<tl::var_description> &vars, int storer_type) const final;
std::string gen_fetch_switch_begin() const override;
std::string gen_fetch_switch_case(const tl::tl_combinator *t, int arity) const override;
std::string gen_fetch_switch_end() const override;
std::string gen_fetch_switch_begin() const final;
std::string gen_fetch_switch_case(const tl::tl_combinator *t, int arity) const final;
std::string gen_fetch_switch_end() const final;
std::string gen_constructor_begin(int field_count, const std::string &class_name, bool is_default) const override;
std::string gen_constructor_begin(int field_count, const std::string &class_name, bool is_default) const final;
std::string gen_constructor_parameter(int field_num, const std::string &class_name, const tl::arg &a,
bool is_default) const override;
bool is_default) const final;
std::string gen_constructor_field_init(int field_num, const std::string &class_name, const tl::arg &a,
bool is_default) const override;
std::string gen_constructor_end(const tl::tl_combinator *t, int field_count, bool is_default) const override;
bool is_default) const final;
std::string gen_constructor_end(const tl::tl_combinator *t, int field_count, bool is_default) const final;
};
} // namespace td

View File

@ -15,7 +15,7 @@
namespace td {
class TD_TL_writer_jni_cpp : public TD_TL_writer_cpp {
class TD_TL_writer_jni_cpp final : public TD_TL_writer_cpp {
std::string gen_vector_fetch(std::string field_name, const tl::tl_tree_type *t,
const std::vector<tl::var_description> &vars, int parser_type) const;
@ -32,9 +32,9 @@ class TD_TL_writer_jni_cpp : public TD_TL_writer_cpp {
std::string gen_type_signature(const tl::tl_tree_type *tree_type) const;
std::string get_pretty_field_name(std::string field_name) const override;
std::string get_pretty_field_name(std::string field_name) const final;
std::string get_pretty_class_name(std::string class_name) const override;
std::string get_pretty_class_name(std::string class_name) const final;
public:
TD_TL_writer_jni_cpp(const std::string &tl_name, const std::string &string_type, const std::string &bytes_type,
@ -42,69 +42,68 @@ class TD_TL_writer_jni_cpp : public TD_TL_writer_cpp {
: TD_TL_writer_cpp(tl_name, string_type, bytes_type, ext_include) {
}
bool is_built_in_simple_type(const std::string &name) const override;
bool is_built_in_complex_type(const std::string &name) const override;
bool is_built_in_simple_type(const std::string &name) const final;
bool is_built_in_complex_type(const std::string &name) const final;
int get_parser_type(const tl::tl_combinator *t, const std::string &parser_name) const override;
int get_additional_function_type(const std::string &additional_function_name) const override;
std::vector<std::string> get_parsers() const override;
std::vector<std::string> get_storers() const override;
std::vector<std::string> get_additional_functions() const override;
int get_parser_type(const tl::tl_combinator *t, const std::string &parser_name) const final;
int get_additional_function_type(const std::string &additional_function_name) const final;
std::vector<std::string> get_parsers() const final;
std::vector<std::string> get_storers() const final;
std::vector<std::string> get_additional_functions() const final;
std::string gen_base_type_class_name(int arity) const override;
std::string gen_base_tl_class_name() const override;
std::string gen_base_type_class_name(int arity) const final;
std::string gen_base_tl_class_name() const final;
std::string gen_class_begin(const std::string &class_name, const std::string &base_class_name,
bool is_proxy) const override;
bool is_proxy) const final;
std::string gen_field_definition(const std::string &class_name, const std::string &type_name,
const std::string &field_name) const override;
const std::string &field_name) const final;
std::string gen_constructor_id_store(std::int32_t id, int storer_type) const override;
std::string gen_constructor_id_store(std::int32_t id, int storer_type) const final;
std::string gen_field_fetch(int field_num, const tl::arg &a, std::vector<tl::var_description> &vars, bool flat,
int parser_type) const override;
int parser_type) const final;
std::string gen_field_store(const tl::arg &a, std::vector<tl::var_description> &vars, bool flat,
int storer_type) const override;
int storer_type) const final;
std::string gen_type_fetch(const std::string &field_name, const tl::tl_tree_type *tree_type,
const std::vector<tl::var_description> &vars, int parser_type) const override;
const std::vector<tl::var_description> &vars, int parser_type) const final;
std::string gen_type_store(const std::string &field_name, const tl::tl_tree_type *tree_type,
const std::vector<tl::var_description> &vars, int storer_type) const override;
const std::vector<tl::var_description> &vars, int storer_type) const final;
std::string gen_get_id(const std::string &class_name, std::int32_t id, bool is_proxy) const override;
std::string gen_get_id(const std::string &class_name, std::int32_t id, bool is_proxy) const final;
std::string gen_fetch_function_begin(const std::string &parser_name, const std::string &class_name,
const std::string &parent_class_name, int arity, int field_count,
std::vector<tl::var_description> &vars, int parser_type) const override;
std::vector<tl::var_description> &vars, int parser_type) const final;
std::string gen_fetch_function_end(bool has_parent, int field_count, const std::vector<tl::var_description> &vars,
int parser_type) const override;
int parser_type) const final;
std::string gen_fetch_function_result_begin(const std::string &parser_name, const std::string &class_name,
const tl::tl_tree *result) const override;
std::string gen_fetch_function_result_end() const override;
const tl::tl_tree *result) const final;
std::string gen_fetch_function_result_end() const final;
std::string gen_fetch_function_result_any_begin(const std::string &parser_name, const std::string &class_name,
bool is_proxy) const override;
std::string gen_fetch_function_result_any_end(bool is_proxy) const override;
bool is_proxy) const final;
std::string gen_fetch_function_result_any_end(bool is_proxy) const final;
std::string gen_store_function_begin(const std::string &storer_name, const std::string &class_name, int arity,
std::vector<tl::var_description> &vars, int storer_type) const override;
std::vector<tl::var_description> &vars, int storer_type) const final;
std::string gen_fetch_switch_begin() const override;
std::string gen_fetch_switch_case(const tl::tl_combinator *t, int arity) const override;
std::string gen_fetch_switch_end() const override;
std::string gen_fetch_switch_begin() const final;
std::string gen_fetch_switch_case(const tl::tl_combinator *t, int arity) const final;
std::string gen_fetch_switch_end() const final;
std::string gen_additional_function(const std::string &function_name, const tl::tl_combinator *t,
bool is_function) const override;
bool is_function) const final;
std::string gen_additional_proxy_function_begin(const std::string &function_name, const tl::tl_type *type,
const std::string &class_name, int arity,
bool is_function) const override;
bool is_function) const final;
std::string gen_additional_proxy_function_case(const std::string &function_name, const tl::tl_type *type,
const std::string &class_name, int arity) const override;
const std::string &class_name, int arity) const final;
std::string gen_additional_proxy_function_case(const std::string &function_name, const tl::tl_type *type,
const tl::tl_combinator *t, int arity,
bool is_function) const override;
const tl::tl_combinator *t, int arity, bool is_function) const final;
std::string gen_additional_proxy_function_end(const std::string &function_name, const tl::tl_type *type,
bool is_function) const override;
bool is_function) const final;
};
} // namespace td

View File

@ -13,45 +13,44 @@
namespace td {
class TD_TL_writer_jni_h : public TD_TL_writer_h {
class TD_TL_writer_jni_h final : public TD_TL_writer_h {
public:
TD_TL_writer_jni_h(const std::string &tl_name, const std::string &string_type, const std::string &bytes_type,
const std::vector<std::string> &ext_include)
: TD_TL_writer_h(tl_name, string_type, bytes_type, ext_include) {
}
bool is_built_in_simple_type(const std::string &name) const override;
bool is_built_in_complex_type(const std::string &name) const override;
bool is_built_in_simple_type(const std::string &name) const final;
bool is_built_in_complex_type(const std::string &name) const final;
int get_parser_type(const tl::tl_combinator *t, const std::string &parser_name) const override;
int get_additional_function_type(const std::string &additional_function_name) const override;
std::vector<std::string> get_parsers() const override;
std::vector<std::string> get_storers() const override;
std::vector<std::string> get_additional_functions() const override;
int get_parser_type(const tl::tl_combinator *t, const std::string &parser_name) const final;
int get_additional_function_type(const std::string &additional_function_name) const final;
std::vector<std::string> get_parsers() const final;
std::vector<std::string> get_storers() const final;
std::vector<std::string> get_additional_functions() const final;
std::string gen_base_type_class_name(int arity) const override;
std::string gen_base_tl_class_name() const override;
std::string gen_base_type_class_name(int arity) const final;
std::string gen_base_tl_class_name() const final;
std::string gen_output_begin() const override;
std::string gen_output_begin() const final;
std::string gen_class_begin(const std::string &class_name, const std::string &base_class_name,
bool is_proxy) const override;
bool is_proxy) const final;
std::string gen_field_definition(const std::string &class_name, const std::string &type_name,
const std::string &field_name) const override;
const std::string &field_name) const final;
std::string gen_additional_function(const std::string &function_name, const tl::tl_combinator *t,
bool is_function) const override;
bool is_function) const final;
std::string gen_additional_proxy_function_begin(const std::string &function_name, const tl::tl_type *type,
const std::string &class_name, int arity,
bool is_function) const override;
bool is_function) const final;
std::string gen_additional_proxy_function_case(const std::string &function_name, const tl::tl_type *type,
const std::string &class_name, int arity) const override;
const std::string &class_name, int arity) const final;
std::string gen_additional_proxy_function_case(const std::string &function_name, const tl::tl_type *type,
const tl::tl_combinator *t, int arity,
bool is_function) const override;
const tl::tl_combinator *t, int arity, bool is_function) const final;
std::string gen_additional_proxy_function_end(const std::string &function_name, const tl::tl_type *type,
bool is_function) const override;
bool is_function) const final;
};
} // namespace td

29
td/mtproto/DhCallback.h Normal file
View File

@ -0,0 +1,29 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#pragma once
#include "td/utils/Slice.h"
namespace td {
namespace mtproto {
class DhCallback {
public:
DhCallback() = default;
DhCallback(const DhCallback &) = delete;
DhCallback &operator=(const DhCallback &) = delete;
DhCallback(DhCallback &&) = delete;
DhCallback &operator=(DhCallback &&) = delete;
virtual ~DhCallback() = default;
virtual int is_good_prime(Slice prime_str) const = 0;
virtual void add_good_prime(Slice prime_str) const = 0;
virtual void add_bad_prime(Slice prime_str) const = 0;
};
} // namespace mtproto
} // namespace td

View File

@ -6,6 +6,8 @@
//
#include "td/mtproto/DhHandshake.h"
#include "td/mtproto/DhCallback.h"
#include "td/utils/as.h"
#include "td/utils/crypto.h"
#include "td/utils/logging.h"
@ -14,6 +16,7 @@
#include "td/utils/UInt.h"
namespace td {
namespace mtproto {
Status DhHandshake::check_config(Slice prime_str, const BigNum &prime, int32 g_int, BigNumContext &ctx,
DhCallback *callback) {
@ -225,4 +228,5 @@ int64 DhHandshake::calc_key_id(Slice auth_key) {
return as<int64>(auth_key_sha1.raw + 12);
}
} // namespace mtproto
} // namespace td

View File

@ -14,21 +14,9 @@
#include <utility>
namespace td {
namespace mtproto {
/*** DH ***/
class DhCallback {
public:
DhCallback() = default;
DhCallback(const DhCallback &) = delete;
DhCallback &operator=(const DhCallback &) = delete;
DhCallback(DhCallback &&) = delete;
DhCallback &operator=(DhCallback &&) = delete;
virtual ~DhCallback() = default;
virtual int is_good_prime(Slice prime_str) const = 0;
virtual void add_good_prime(Slice prime_str) const = 0;
virtual void add_bad_prime(Slice prime_str) const = 0;
};
class DhCallback;
class DhHandshake {
public:
@ -117,7 +105,7 @@ class DhHandshake {
string prime_str_;
BigNum prime_;
BigNum g_;
int32 g_int_;
int32 g_int_ = 0;
BigNum b_;
BigNum g_b_;
BigNum g_a_;
@ -132,4 +120,5 @@ class DhHandshake {
BigNumContext ctx_;
};
} // namespace mtproto
} // namespace td

View File

@ -6,10 +6,11 @@
//
#include "td/mtproto/Handshake.h"
#include "td/mtproto/DhCallback.h"
#include "td/mtproto/DhHandshake.h"
#include "td/mtproto/KDF.h"
#include "td/mtproto/utils.h"
#include "td/mtproto/mtproto_api.h"
#include "td/mtproto/utils.h"
#include "td/utils/as.h"
#include "td/utils/buffer.h"
@ -22,7 +23,8 @@
#include "td/utils/Status.h"
#include "td/utils/Time.h"
#include "td/utils/tl_parsers.h"
#include "td/utils/tl_storers.h"
#include <algorithm>
namespace td {
namespace mtproto {
@ -53,7 +55,7 @@ bool AuthKeyHandshake::is_ready_for_start() const {
return state_ == Start;
}
bool AuthKeyHandshake::is_ready_for_message(const UInt128 &message_nonce) const {
return state_ != Finish && state_ != Start && nonce == message_nonce;
return state_ != Finish && state_ != Start && nonce_ == message_nonce;
}
bool AuthKeyHandshake::is_ready_for_finish() const {
return state_ == Finish;
@ -62,76 +64,83 @@ void AuthKeyHandshake::on_finish() {
clear();
}
template <class DataT>
Result<size_t> AuthKeyHandshake::fill_data_with_hash(uint8 *data_with_hash, const DataT &data) {
// data_with_hash := SHA1(data) + data + (any random bytes); such that the length equal 255 bytes;
uint8 *data_ptr = data_with_hash + 20;
size_t data_size = tl_calc_length(data);
if (data_size + 20 + 4 > 255) {
return Status::Error("Too big data");
}
as<int32>(data_ptr) = data.get_id();
auto real_size = tl_store_unsafe(data, data_ptr + 4);
CHECK(real_size == data_size);
sha1(Slice(data_ptr, data_size + 4), data_with_hash);
return data_size + 20 + 4;
string AuthKeyHandshake::store_object(const mtproto_api::Object &object) {
auto storer = create_storer(object);
size_t size = storer.size();
string result(size, '\0');
auto real_size = storer.store(MutableSlice(result).ubegin());
CHECK(real_size == size);
return result;
}
Status AuthKeyHandshake::on_res_pq(Slice message, Callback *connection, PublicRsaKeyInterface *public_rsa_key) {
TRY_RESULT(res_pq, fetch_result<mtproto_api::req_pq_multi>(message, false));
if (res_pq->nonce_ != nonce) {
if (res_pq->nonce_ != nonce_) {
return Status::Error("Nonce mismatch");
}
server_nonce = res_pq->server_nonce_;
server_nonce_ = res_pq->server_nonce_;
auto r_rsa = public_rsa_key->get_rsa(res_pq->server_public_key_fingerprints_);
if (r_rsa.is_error()) {
auto r_rsa_key = public_rsa_key->get_rsa_key(res_pq->server_public_key_fingerprints_);
if (r_rsa_key.is_error()) {
public_rsa_key->drop_keys();
return r_rsa.move_as_error();
return r_rsa_key.move_as_error();
}
int64 rsa_fingerprint = r_rsa.ok().second;
RSA rsa = std::move(r_rsa.ok_ref().first);
auto rsa_key = r_rsa_key.move_as_ok();
string p, q;
if (pq_factorize(res_pq->pq_, &p, &q) == -1) {
return Status::Error("Failed to factorize");
}
Random::secure_bytes(new_nonce.raw, sizeof(new_nonce));
Random::secure_bytes(new_nonce_.raw, sizeof(new_nonce_));
alignas(8) uint8 data_with_hash[255];
Result<size_t> r_data_size = 0;
string data;
switch (mode_) {
case Mode::Main:
r_data_size = fill_data_with_hash(
data_with_hash, mtproto_api::p_q_inner_data_dc(res_pq->pq_, p, q, nonce, server_nonce, new_nonce, dc_id_));
data = store_object(mtproto_api::p_q_inner_data_dc(res_pq->pq_, p, q, nonce_, server_nonce_, new_nonce_, dc_id_));
break;
case Mode::Temp:
r_data_size = fill_data_with_hash(
data_with_hash,
mtproto_api::p_q_inner_data_temp_dc(res_pq->pq_, p, q, nonce, server_nonce, new_nonce, dc_id_, expires_in_));
data = store_object(mtproto_api::p_q_inner_data_temp_dc(res_pq->pq_, p, q, nonce_, server_nonce_, new_nonce_,
dc_id_, expires_in_));
expires_at_ = Time::now() + expires_in_;
break;
case Mode::Unknown:
default:
UNREACHABLE();
r_data_size = Status::Error(500, "Unreachable");
}
if (r_data_size.is_error()) {
return r_data_size.move_as_error();
string encrypted_data(256, '\0');
auto data_size = data.size();
if (data_size > 144) {
return Status::Error("Too big data");
}
size_t size = r_data_size.ok();
// encrypted_data := RSA (data_with_hash, server_public_key); a 255-byte long number (big endian)
// is raised to the requisite power over the requisite modulus, and the result is stored as a 256-byte number.
string encrypted_data(256, 0);
rsa.encrypt(data_with_hash, size, sizeof(data_with_hash), reinterpret_cast<unsigned char *>(&encrypted_data[0]),
encrypted_data.size());
data.resize(192);
Random::secure_bytes(MutableSlice(data).substr(data_size));
// req_DH_params#d712e4be nonce:int128 server_nonce:int128 p:string q:string public_key_fingerprint:long
// encrypted_data:string = Server_DH_Params
mtproto_api::req_DH_params req_dh_params(nonce, server_nonce, p, q, rsa_fingerprint, encrypted_data);
while (true) {
string aes_key(32, '\0');
Random::secure_bytes(MutableSlice(aes_key));
string data_with_hash = data + sha256(aes_key + data);
std::reverse(data_with_hash.begin(), data_with_hash.begin() + data.size());
string decrypted_data(256, '\0');
string aes_iv(32, '\0');
aes_ige_encrypt(aes_key, aes_iv, data_with_hash, MutableSlice(decrypted_data).substr(32));
auto hash = sha256(MutableSlice(decrypted_data).substr(32));
for (size_t i = 0; i < 32; i++) {
decrypted_data[i] = static_cast<char>(aes_key[i] ^ hash[i]);
}
if (rsa_key.rsa.encrypt(decrypted_data, encrypted_data)) {
break;
}
}
mtproto_api::req_DH_params req_dh_params(nonce_, server_nonce_, p, q, rsa_key.fingerprint, encrypted_data);
send(connection, create_storer(req_dh_params));
state_ = ServerDHParams;
@ -139,30 +148,22 @@ Status AuthKeyHandshake::on_res_pq(Slice message, Callback *connection, PublicRs
}
Status AuthKeyHandshake::on_server_dh_params(Slice message, Callback *connection, DhCallback *dh_callback) {
TRY_RESULT(server_dh_params, fetch_result<mtproto_api::req_DH_params>(message, false));
switch (server_dh_params->get_id()) {
case mtproto_api::server_DH_params_ok::ID:
break;
case mtproto_api::server_DH_params_fail::ID:
return Status::Error("Server dh params fail");
default:
return Status::Error("Unknown result");
}
auto dh_params = move_tl_object_as<mtproto_api::server_DH_params_ok>(server_dh_params);
TRY_RESULT(dh_params, fetch_result<mtproto_api::req_DH_params>(message, false));
// server_DH_params_ok#d0e8075c nonce:int128 server_nonce:int128 encrypted_answer:string = Server_DH_Params;
if (dh_params->nonce_ != nonce) {
if (dh_params->nonce_ != nonce_) {
return Status::Error("Nonce mismatch");
}
if (dh_params->server_nonce_ != server_nonce) {
if (dh_params->server_nonce_ != server_nonce_) {
return Status::Error("Server nonce mismatch");
}
if (dh_params->encrypted_answer_.size() & 15) {
return Status::Error("Bad padding for encrypted part");
}
tmp_KDF(server_nonce, new_nonce, &tmp_aes_key, &tmp_aes_iv);
UInt256 tmp_aes_key;
UInt256 tmp_aes_iv;
tmp_KDF(server_nonce_, new_nonce_, &tmp_aes_key, &tmp_aes_iv);
auto save_tmp_aes_iv = tmp_aes_iv;
// encrypted_answer := AES256_ige_encrypt (answer_with_hash, tmp_aes_key, tmp_aes_iv);
MutableSlice answer(const_cast<char *>(dh_params->encrypted_answer_.begin()), dh_params->encrypted_answer_.size());
@ -193,10 +194,10 @@ Status AuthKeyHandshake::on_server_dh_params(Slice message, Callback *connection
return Status::Error("SHA1 mismatch");
}
if (dh_inner_data.nonce_ != nonce) {
if (dh_inner_data.nonce_ != nonce_) {
return Status::Error("Nonce mismatch");
}
if (dh_inner_data.server_nonce_ != server_nonce) {
if (dh_inner_data.server_nonce_ != server_nonce_) {
return Status::Error("Server nonce mismatch");
}
@ -209,22 +210,19 @@ Status AuthKeyHandshake::on_server_dh_params(Slice message, Callback *connection
string g_b = handshake.get_g_b();
auto auth_key_params = handshake.gen_key();
mtproto_api::client_DH_inner_data data(nonce, server_nonce, 0, g_b);
size_t data_size = 4 + tl_calc_length(data);
size_t encrypted_data_size = 20 + data_size;
auto data = store_object(mtproto_api::client_DH_inner_data(nonce_, server_nonce_, 0, g_b));
size_t encrypted_data_size = 20 + data.size();
size_t encrypted_data_size_with_pad = (encrypted_data_size + 15) & -16;
string encrypted_data_str(encrypted_data_size_with_pad, 0);
string encrypted_data_str(encrypted_data_size_with_pad, '\0');
MutableSlice encrypted_data = encrypted_data_str;
as<int32>(encrypted_data.begin() + 20) = data.get_id();
auto real_size = tl_store_unsafe(data, encrypted_data.ubegin() + 20 + 4);
CHECK(real_size + 4 == data_size);
sha1(encrypted_data.substr(20, data_size), encrypted_data.ubegin());
sha1(data, encrypted_data.ubegin());
encrypted_data.substr(20, data.size()).copy_from(data);
Random::secure_bytes(encrypted_data.ubegin() + encrypted_data_size,
encrypted_data_size_with_pad - encrypted_data_size);
tmp_KDF(server_nonce, new_nonce, &tmp_aes_key, &tmp_aes_iv);
tmp_KDF(server_nonce_, new_nonce_, &tmp_aes_key, &tmp_aes_iv);
aes_ige_encrypt(as_slice(tmp_aes_key), as_slice(tmp_aes_iv), encrypted_data, encrypted_data);
mtproto_api::set_client_DH_params set_client_dh_params(nonce, server_nonce, encrypted_data);
mtproto_api::set_client_DH_params set_client_dh_params(nonce_, server_nonce_, encrypted_data);
send(connection, create_storer(set_client_dh_params));
auth_key_ = AuthKey(auth_key_params.first, std::move(auth_key_params.second));
@ -233,7 +231,7 @@ Status AuthKeyHandshake::on_server_dh_params(Slice message, Callback *connection
}
auth_key_.set_created_at(dh_inner_data.server_time_);
server_salt_ = as<int64>(new_nonce.raw) ^ as<int64>(server_nonce.raw);
server_salt_ = as<int64>(new_nonce_.raw) ^ as<int64>(server_nonce_.raw);
state_ = DHGenResponse;
return Status::OK();
@ -300,8 +298,8 @@ Status AuthKeyHandshake::on_start(Callback *connection) {
clear();
return Status::Error(PSLICE() << "on_start called after start " << tag("state", state_));
}
Random::secure_bytes(nonce.raw, sizeof(nonce));
send(connection, create_storer(mtproto_api::req_pq_multi(nonce)));
Random::secure_bytes(nonce_.raw, sizeof(nonce_));
send(connection, create_storer(mtproto_api::req_pq_multi(nonce_)));
state_ = ResPQ;
return Status::OK();

View File

@ -7,7 +7,6 @@
#pragma once
#include "td/mtproto/AuthKey.h"
#include "td/mtproto/DhHandshake.h"
#include "td/mtproto/RSA.h"
#include "td/utils/buffer.h"
@ -17,8 +16,15 @@
#include "td/utils/UInt.h"
namespace td {
namespace mtproto_api {
class Object;
} // namespace mtproto_api
namespace mtproto {
class DhCallback;
class AuthKeyHandshakeContext {
public:
virtual ~AuthKeyHandshakeContext() = default;
@ -107,16 +113,13 @@ class AuthKeyHandshake {
double server_time_diff_ = 0;
uint64 server_salt_ = 0;
UInt128 nonce;
UInt128 server_nonce;
UInt256 new_nonce;
UInt256 tmp_aes_key;
UInt256 tmp_aes_iv;
UInt128 nonce_;
UInt128 server_nonce_;
UInt256 new_nonce_;
BufferSlice last_query_;
template <class DataT>
Result<size_t> fill_data_with_hash(uint8 *data_with_hash, const DataT &data) TD_WARN_UNUSED_RESULT;
static string store_object(const mtproto_api::Object &object);
void send(Callback *connection, const Storer &storer);
void do_send(Callback *connection, const Storer &storer);

View File

@ -19,7 +19,7 @@ namespace td {
namespace mtproto {
// Has Raw connection. Generates new auth key. And returns it and raw_connection. Or error...
class HandshakeActor : public Actor {
class HandshakeActor final : public Actor {
public:
HandshakeActor(unique_ptr<AuthKeyHandshake> handshake, unique_ptr<RawConnection> raw_connection,
unique_ptr<AuthKeyHandshakeContext> context, double timeout,
@ -35,19 +35,19 @@ class HandshakeActor : public Actor {
Promise<unique_ptr<RawConnection>> raw_connection_promise_;
Promise<unique_ptr<AuthKeyHandshake>> handshake_promise_;
void start_up() override;
void tear_down() override {
void start_up() final;
void tear_down() final {
finish(Status::OK());
}
void hangup() override {
void hangup() final {
finish(Status::Error(1, "Canceled"));
stop();
}
void timeout_expired() override {
void timeout_expired() final {
finish(Status::Error("Timeout expired"));
stop();
}
void loop() override;
void loop() final;
void finish(Status status) {
// NB: order may be important for parent

View File

@ -24,7 +24,7 @@
namespace td {
namespace mtproto {
class HandshakeConnection
class HandshakeConnection final
: private RawConnection::Callback
, private AuthKeyHandshake::Callback {
public:
@ -60,11 +60,11 @@ class HandshakeConnection
AuthKeyHandshake *handshake_;
unique_ptr<AuthKeyHandshakeContext> context_;
void send_no_crypto(const Storer &storer) override {
void send_no_crypto(const Storer &storer) final {
raw_connection_->send_no_crypto(PacketStorer<NoCryptoImpl>(0, storer));
}
Status on_raw_packet(const PacketInfo &packet_info, BufferSlice packet) override {
Status on_raw_packet(const PacketInfo &packet_info, BufferSlice packet) final {
if (packet_info.no_crypto_flag == false) {
return Status::Error("Expected not encrypted packet");
}

View File

@ -21,29 +21,29 @@ namespace td {
namespace mtproto {
namespace http {
class Transport : public IStreamTransport {
class Transport final : public IStreamTransport {
public:
explicit Transport(string secret) : secret_(std::move(secret)) {
}
Result<size_t> read_next(BufferSlice *message, uint32 *quick_ack) override TD_WARN_UNUSED_RESULT;
bool support_quick_ack() const override {
Result<size_t> read_next(BufferSlice *message, uint32 *quick_ack) final TD_WARN_UNUSED_RESULT;
bool support_quick_ack() const final {
return false;
}
void write(BufferWriter &&message, bool quick_ack) override;
bool can_read() const override;
bool can_write() const override;
void init(ChainBufferReader *input, ChainBufferWriter *output) override {
void write(BufferWriter &&message, bool quick_ack) final;
bool can_read() const final;
bool can_write() const final;
void init(ChainBufferReader *input, ChainBufferWriter *output) final {
reader_.init(input);
output_ = output;
}
size_t max_prepend_size() const override;
size_t max_append_size() const override;
TransportType get_type() const override {
size_t max_prepend_size() const final;
size_t max_append_size() const final;
TransportType get_type() const final {
return {TransportType::Http, 0, ProxySecret::from_raw(secret_)};
}
bool use_random_padding() const override;
bool use_random_padding() const final;
private:
string secret_;

View File

@ -15,11 +15,11 @@ namespace td {
namespace mtproto {
template <class Impl>
class PacketStorer
class PacketStorer final
: public Storer
, public Impl {
public:
size_t size() const override {
size_t size() const final {
if (size_ != std::numeric_limits<size_t>::max()) {
return size_;
}
@ -28,7 +28,7 @@ class PacketStorer
return size_ = storer.get_length();
}
size_t store(uint8 *ptr) const override {
size_t store(uint8 *ptr) const final {
TlStorerUnsafe storer(ptr);
this->do_store(storer);
return static_cast<size_t>(storer.get_buf() - ptr);

View File

@ -21,7 +21,7 @@ namespace mtproto {
ActorOwn<> create_ping_actor(string debug, unique_ptr<RawConnection> raw_connection, unique_ptr<AuthData> auth_data,
Promise<unique_ptr<RawConnection>> promise, ActorShared<> parent) {
class PingActor : public Actor {
class PingActor final : public Actor {
public:
PingActor(unique_ptr<RawConnection> raw_connection, unique_ptr<AuthData> auth_data,
Promise<unique_ptr<RawConnection>> promise, ActorShared<> parent)
@ -38,22 +38,22 @@ ActorOwn<> create_ping_actor(string debug, unique_ptr<RawConnection> raw_connect
Promise<unique_ptr<RawConnection>> promise_;
ActorShared<> parent_;
void start_up() override {
void start_up() final {
Scheduler::subscribe(ping_connection_->get_poll_info().extract_pollable_fd(this));
set_timeout_in(10);
yield();
}
void hangup() override {
void hangup() final {
finish(Status::Error("Canceled"));
stop();
}
void tear_down() override {
void tear_down() final {
finish(Status::OK());
}
void loop() override {
void loop() final {
auto status = ping_connection_->flush();
if (status.is_error()) {
finish(std::move(status));
@ -65,7 +65,7 @@ ActorOwn<> create_ping_actor(string debug, unique_ptr<RawConnection> raw_connect
}
}
void timeout_expired() override {
void timeout_expired() final {
finish(Status::Error("Pong timeout expired"));
stop();
}

View File

@ -27,7 +27,7 @@ namespace td {
namespace mtproto {
namespace detail {
class PingConnectionReqPQ
class PingConnectionReqPQ final
: public PingConnection
, private RawConnection::Callback {
public:
@ -35,15 +35,15 @@ class PingConnectionReqPQ
: raw_connection_(std::move(raw_connection)), ping_count_(ping_count) {
}
PollableFdInfo &get_poll_info() override {
PollableFdInfo &get_poll_info() final {
return raw_connection_->get_poll_info();
}
unique_ptr<RawConnection> move_as_raw_connection() override {
unique_ptr<RawConnection> move_as_raw_connection() final {
return std::move(raw_connection_);
}
Status flush() override {
Status flush() final {
if (!was_ping_) {
UInt128 nonce;
Random::secure_bytes(nonce.raw, sizeof(nonce));
@ -55,14 +55,14 @@ class PingConnectionReqPQ
}
return raw_connection_->flush(AuthKey(), *this);
}
bool was_pong() const override {
bool was_pong() const final {
return finish_time_ > 0;
}
double rtt() const override {
double rtt() const final {
return finish_time_ - start_time_;
}
Status on_raw_packet(const PacketInfo &packet_info, BufferSlice packet) override {
Status on_raw_packet(const PacketInfo &packet_info, BufferSlice packet) final {
if (packet.size() < 12) {
return Status::Error("Result is too small");
}
@ -86,7 +86,7 @@ class PingConnectionReqPQ
bool was_ping_ = false;
};
class PingConnectionPingPong
class PingConnectionPingPong final
: public PingConnection
, private SessionConnection::Callback {
public:
@ -105,31 +105,31 @@ class PingConnectionPingPong
double rtt_;
bool is_closed_{false};
Status status_;
void on_connected() override {
void on_connected() final {
}
void on_closed(Status status) override {
void on_closed(Status status) final {
is_closed_ = true;
CHECK(status.is_error());
status_ = std::move(status);
}
void on_auth_key_updated() override {
void on_auth_key_updated() final {
}
void on_tmp_auth_key_updated() override {
void on_tmp_auth_key_updated() final {
}
void on_server_salt_updated() override {
void on_server_salt_updated() final {
}
void on_server_time_difference_updated() override {
void on_server_time_difference_updated() final {
}
void on_session_created(uint64 unique_id, uint64 first_id) override {
void on_session_created(uint64 unique_id, uint64 first_id) final {
}
void on_session_failed(Status status) override {
void on_session_failed(Status status) final {
}
void on_container_sent(uint64 container_id, vector<uint64> msgs_id) override {
void on_container_sent(uint64 container_id, vector<uint64> msgs_id) final {
}
Status on_pong() override {
Status on_pong() final {
pong_cnt_++;
if (pong_cnt_ == 1) {
rtt_ = Time::now();
@ -140,30 +140,30 @@ class PingConnectionPingPong
return Status::OK();
}
void on_message_ack(uint64 id) override {
void on_message_ack(uint64 id) final {
}
Status on_message_result_ok(uint64 id, BufferSlice packet, size_t original_size) override {
Status on_message_result_ok(uint64 id, BufferSlice packet, size_t original_size) final {
LOG(ERROR) << "Unexpected message";
return Status::OK();
}
void on_message_result_error(uint64 id, int code, BufferSlice descr) override {
void on_message_result_error(uint64 id, int code, BufferSlice descr) final {
}
void on_message_failed(uint64 id, Status status) override {
void on_message_failed(uint64 id, Status status) final {
}
void on_message_info(uint64 id, int32 state, uint64 answer_id, int32 answer_size) override {
void on_message_info(uint64 id, int32 state, uint64 answer_id, int32 answer_size) final {
}
Status on_destroy_auth_key() override {
Status on_destroy_auth_key() final {
LOG(ERROR) << "Destroy auth key";
return Status::OK();
}
PollableFdInfo &get_poll_info() override {
PollableFdInfo &get_poll_info() final {
return connection_->get_poll_info();
}
unique_ptr<RawConnection> move_as_raw_connection() override {
unique_ptr<RawConnection> move_as_raw_connection() final {
return connection_->move_as_raw_connection();
}
Status flush() override {
Status flush() final {
if (was_pong()) {
return Status::OK();
}
@ -175,10 +175,10 @@ class PingConnectionPingPong
}
return Status::OK();
}
bool was_pong() const override {
bool was_pong() const final {
return pong_cnt_ >= 2;
}
double rtt() const override {
double rtt() const final {
return rtt_;
}
};

View File

@ -12,7 +12,6 @@
#include "td/utils/common.h"
#include "td/utils/crypto.h"
#include "td/utils/misc.h"
#include "td/utils/Random.h"
#include "td/utils/ScopeGuard.h"
#include "td/utils/Slice.h"
#include "td/utils/Status.h"
@ -27,6 +26,7 @@
#endif
namespace td {
namespace mtproto {
RSA::RSA(BigNum n, BigNum e) : n_(std::move(n)), e_(std::move(e)) {
}
@ -127,27 +127,22 @@ size_t RSA::size() const {
return 256;
}
size_t RSA::encrypt(unsigned char *from, size_t from_len, size_t max_from_len, unsigned char *to, size_t to_len) const {
CHECK(from_len > 0 && from_len <= 2550);
size_t pad = (25500 - from_len - 32) % 255 + 32;
size_t chunks = (from_len + pad) / 255;
bool RSA::encrypt(Slice from, MutableSlice to) const {
CHECK(from.size() == 256)
CHECK(to.size() == 256)
int bits = n_.get_num_bits();
CHECK(bits >= 2041 && bits <= 2048);
CHECK(chunks * 255 == from_len + pad);
CHECK(from_len + pad <= max_from_len);
CHECK(chunks * 256 <= to_len);
Random::secure_bytes(from + from_len, pad);
size_t result = chunks * 256;
BigNum x = BigNum::from_binary(from);
if (BigNum::compare(x, n_) >= 0) {
return false;
}
BigNumContext ctx;
BigNum y;
while (chunks-- > 0) {
BigNum x = BigNum::from_binary(Slice(from, 255));
BigNum::mod_exp(y, x, e_, n_, ctx);
MutableSlice(to, 256).copy_from(y.to_binary(256));
to += 256;
}
return result;
to.copy_from(y.to_binary(256));
return true;
}
void RSA::decrypt_signature(Slice from, MutableSlice to) const {
@ -159,4 +154,5 @@ void RSA::decrypt_signature(Slice from, MutableSlice to) const {
to.copy_from(y.to_binary(256));
}
} // namespace mtproto
} // namespace td

View File

@ -11,16 +11,16 @@
#include "td/utils/Slice.h"
#include "td/utils/Status.h"
#include <utility>
namespace td {
namespace mtproto {
class RSA {
public:
RSA clone() const;
int64 get_fingerprint() const;
size_t size() const;
size_t encrypt(unsigned char *from, size_t from_len, size_t max_from_len, unsigned char *to, size_t to_len) const;
bool encrypt(Slice from, MutableSlice to) const;
void decrypt_signature(Slice from, MutableSlice to) const;
@ -35,8 +35,15 @@ class RSA {
class PublicRsaKeyInterface {
public:
virtual ~PublicRsaKeyInterface() = default;
virtual Result<std::pair<RSA, int64>> get_rsa(const vector<int64> &fingerprints) = 0;
struct RsaKey {
RSA rsa;
int64 fingerprint;
};
virtual Result<RsaKey> get_rsa_key(const vector<int64> &fingerprints) = 0;
virtual void drop_keys() = 0;
};
} // namespace mtproto
} // namespace td

View File

@ -33,7 +33,7 @@
namespace td {
namespace mtproto {
class RawConnectionDefault : public RawConnection {
class RawConnectionDefault final : public RawConnection {
public:
RawConnectionDefault(SocketFd socket_fd, TransportType transport_type, unique_ptr<StatsCallback> stats_callback)
: socket_fd_(std::move(socket_fd))
@ -42,18 +42,18 @@ class RawConnectionDefault : public RawConnection {
transport_->init(&socket_fd_.input_buffer(), &socket_fd_.output_buffer());
}
void set_connection_token(StateManager::ConnectionToken connection_token) override {
void set_connection_token(StateManager::ConnectionToken connection_token) final {
connection_token_ = std::move(connection_token);
}
bool can_send() const override {
bool can_send() const final {
return transport_->can_write();
}
TransportType get_transport_type() const override {
TransportType get_transport_type() const final {
return transport_->get_type();
}
void send_crypto(const Storer &storer, int64 session_id, int64 salt, const AuthKey &auth_key,
uint64 quick_ack_token) override {
uint64 quick_ack_token) final {
PacketInfo info;
info.version = 2;
info.no_crypto_flag = false;
@ -78,7 +78,7 @@ class RawConnectionDefault : public RawConnection {
transport_->write(std::move(packet), use_quick_ack);
}
uint64 send_no_crypto(const Storer &storer) override {
uint64 send_no_crypto(const Storer &storer) final {
PacketInfo info;
info.no_crypto_flag = true;
@ -90,16 +90,16 @@ class RawConnectionDefault : public RawConnection {
return info.message_id;
}
PollableFdInfo &get_poll_info() override {
PollableFdInfo &get_poll_info() final {
return socket_fd_.get_poll_info();
}
StatsCallback *stats_callback() override {
StatsCallback *stats_callback() final {
return stats_callback_.get();
}
// NB: After first returned error, all subsequent calls will return error too.
Status flush(const AuthKey &auth_key, Callback &callback) override {
Status flush(const AuthKey &auth_key, Callback &callback) final {
auto status = do_flush(auth_key, callback);
if (status.is_error()) {
if (stats_callback_ && status.code() != 2) {
@ -110,19 +110,19 @@ class RawConnectionDefault : public RawConnection {
return status;
}
bool has_error() const override {
bool has_error() const final {
return has_error_;
}
void close() override {
void close() final {
transport_.reset();
socket_fd_.close();
}
PublicFields &extra() override {
PublicFields &extra() final {
return extra_;
}
const PublicFields &extra() const override {
const PublicFields &extra() const final {
return extra_;
}
@ -260,7 +260,7 @@ class RawConnectionDefault : public RawConnection {
};
#if TD_EXPERIMENTAL_WATCH_OS
class RawConnectionHttp : public RawConnection {
class RawConnectionHttp final : public RawConnection {
public:
RawConnectionHttp(IPAddress ip_address, unique_ptr<StatsCallback> stats_callback)
: ip_address_(std::move(ip_address)), stats_callback_(std::move(stats_callback)) {
@ -268,18 +268,18 @@ class RawConnectionHttp : public RawConnection {
answers_->init();
}
void set_connection_token(StateManager::ConnectionToken connection_token) override {
void set_connection_token(StateManager::ConnectionToken connection_token) final {
connection_token_ = std::move(connection_token);
}
bool can_send() const override {
bool can_send() const final {
return mode_ == Send;
}
TransportType get_transport_type() const override {
TransportType get_transport_type() const final {
return mtproto::TransportType{mtproto::TransportType::Http, 0, mtproto::ProxySecret()};
}
void send_crypto(const Storer &storer, int64 session_id, int64 salt, const AuthKey &auth_key,
uint64 quick_ack_token) override {
uint64 quick_ack_token) final {
PacketInfo info;
info.version = 2;
info.no_crypto_flag = false;
@ -293,7 +293,7 @@ class RawConnectionHttp : public RawConnection {
send_packet(packet.as_buffer_slice());
}
uint64 send_no_crypto(const Storer &storer) override {
uint64 send_no_crypto(const Storer &storer) final {
PacketInfo info;
info.no_crypto_flag = true;
@ -304,16 +304,16 @@ class RawConnectionHttp : public RawConnection {
return info.message_id;
}
PollableFdInfo &get_poll_info() override {
PollableFdInfo &get_poll_info() final {
return answers_->reader_get_event_fd().get_poll_info();
}
StatsCallback *stats_callback() override {
StatsCallback *stats_callback() final {
return stats_callback_.get();
}
// NB: After first returned error, all subsequent calls will return error too.
Status flush(const AuthKey &auth_key, Callback &callback) override {
Status flush(const AuthKey &auth_key, Callback &callback) final {
auto status = do_flush(auth_key, callback);
if (status.is_error()) {
if (stats_callback_ && status.code() != 2) {
@ -324,17 +324,17 @@ class RawConnectionHttp : public RawConnection {
return status;
}
bool has_error() const override {
bool has_error() const final {
return has_error_;
}
void close() override {
void close() final {
}
PublicFields &extra() override {
PublicFields &extra() final {
return extra_;
}
const PublicFields &extra() const override {
const PublicFields &extra() const final {
return extra_;
}

View File

@ -65,7 +65,7 @@ inline StringBuilder &operator<<(StringBuilder &stream, const MsgInfo &id) {
<< "] [seq_no:" << format::as_hex(id.seq_no) << "]";
}
class SessionConnection
class SessionConnection final
: public Named
, private RawConnection::Callback {
public:
@ -264,10 +264,10 @@ class SessionConnection
Status init() TD_WARN_UNUSED_RESULT;
Status do_flush() TD_WARN_UNUSED_RESULT;
Status before_write() override TD_WARN_UNUSED_RESULT;
Status on_raw_packet(const PacketInfo &info, BufferSlice packet) override;
Status on_quick_ack(uint64 quick_ack_token) override;
void on_read(size_t size) override;
Status before_write() final TD_WARN_UNUSED_RESULT;
Status on_raw_packet(const PacketInfo &info, BufferSlice packet) final;
Status on_quick_ack(uint64 quick_ack_token) final;
void on_read(size_t size) final;
};
} // namespace mtproto

View File

@ -49,24 +49,24 @@ class ITransport {
virtual ~ITransport() = default;
};
class AbridgedTransport : public ITransport {
class AbridgedTransport final : public ITransport {
public:
size_t read_from_stream(ChainBufferReader *stream, BufferSlice *message, uint32 *quick_ack) override;
void write_prepare_inplace(BufferWriter *message, bool quick_ack) override;
void init_output_stream(ChainBufferWriter *stream) override;
bool support_quick_ack() const override {
size_t read_from_stream(ChainBufferReader *stream, BufferSlice *message, uint32 *quick_ack) final;
void write_prepare_inplace(BufferWriter *message, bool quick_ack) final;
void init_output_stream(ChainBufferWriter *stream) final;
bool support_quick_ack() const final {
return false;
}
};
class IntermediateTransport : ITransport {
class IntermediateTransport final : public ITransport {
public:
explicit IntermediateTransport(bool with_padding) : with_padding_(with_padding) {
}
size_t read_from_stream(ChainBufferReader *stream, BufferSlice *message, uint32 *quick_ack) override;
void write_prepare_inplace(BufferWriter *message, bool quick_ack) override;
void init_output_stream(ChainBufferWriter *stream) override;
bool support_quick_ack() const override {
size_t read_from_stream(ChainBufferReader *stream, BufferSlice *message, uint32 *quick_ack) final;
void write_prepare_inplace(BufferWriter *message, bool quick_ack) final;
void init_output_stream(ChainBufferWriter *stream) final;
bool support_quick_ack() const final {
return true;
}
bool with_padding() const {
@ -79,44 +79,44 @@ class IntermediateTransport : ITransport {
using TransportImpl = IntermediateTransport;
class OldTransport : public IStreamTransport {
class OldTransport final : public IStreamTransport {
public:
OldTransport() = default;
Result<size_t> read_next(BufferSlice *message, uint32 *quick_ack) override TD_WARN_UNUSED_RESULT {
Result<size_t> read_next(BufferSlice *message, uint32 *quick_ack) final TD_WARN_UNUSED_RESULT {
return impl_.read_from_stream(input_, message, quick_ack);
}
bool support_quick_ack() const override {
bool support_quick_ack() const final {
return impl_.support_quick_ack();
}
void write(BufferWriter &&message, bool quick_ack) override {
void write(BufferWriter &&message, bool quick_ack) final {
impl_.write_prepare_inplace(&message, quick_ack);
output_->append(message.as_buffer_slice());
}
void init(ChainBufferReader *input, ChainBufferWriter *output) override {
void init(ChainBufferReader *input, ChainBufferWriter *output) final {
input_ = input;
output_ = output;
impl_.init_output_stream(output_);
}
bool can_read() const override {
bool can_read() const final {
return true;
}
bool can_write() const override {
bool can_write() const final {
return true;
}
size_t max_prepend_size() const override {
size_t max_prepend_size() const final {
return 4;
}
size_t max_append_size() const override {
size_t max_append_size() const final {
return 15;
}
TransportType get_type() const override {
TransportType get_type() const final {
return TransportType{TransportType::Tcp, 0, ProxySecret()};
}
bool use_random_padding() const override {
bool use_random_padding() const final {
return false;
}
@ -126,31 +126,31 @@ class OldTransport : public IStreamTransport {
ChainBufferWriter *output_;
};
class ObfuscatedTransport : public IStreamTransport {
class ObfuscatedTransport final : public IStreamTransport {
public:
ObfuscatedTransport(int16 dc_id, const ProxySecret &secret)
: dc_id_(dc_id), secret_(secret), impl_(secret_.use_random_padding()) {
}
Result<size_t> read_next(BufferSlice *message, uint32 *quick_ack) override TD_WARN_UNUSED_RESULT;
Result<size_t> read_next(BufferSlice *message, uint32 *quick_ack) final TD_WARN_UNUSED_RESULT;
bool support_quick_ack() const override {
bool support_quick_ack() const final {
return impl_.support_quick_ack();
}
void write(BufferWriter &&message, bool quick_ack) override;
void write(BufferWriter &&message, bool quick_ack) final;
void init(ChainBufferReader *input, ChainBufferWriter *output) override;
void init(ChainBufferReader *input, ChainBufferWriter *output) final;
bool can_read() const override {
bool can_read() const final {
return true;
}
bool can_write() const override {
bool can_write() const final {
return true;
}
size_t max_prepend_size() const override {
size_t max_prepend_size() const final {
size_t res = 4;
if (secret_.emulate_tls()) {
res += 5;
@ -165,14 +165,14 @@ class ObfuscatedTransport : public IStreamTransport {
return res;
}
size_t max_append_size() const override {
size_t max_append_size() const final {
return 15;
}
TransportType get_type() const override {
TransportType get_type() const final {
return TransportType{TransportType::ObfuscatedTcp, dc_id_, secret_};
}
bool use_random_padding() const override {
bool use_random_padding() const final {
return secret_.use_random_padding();
}

View File

@ -23,7 +23,7 @@ class Grease {
static void init(MutableSlice res);
};
class TlsInit : public TransparentProxy {
class TlsInit final : public TransparentProxy {
public:
TlsInit(SocketFd socket_fd, string domain, string secret, unique_ptr<Callback> callback, ActorShared<> parent,
double server_time_difference)
@ -43,7 +43,7 @@ class TlsInit : public TransparentProxy {
void send_hello();
Status wait_hello_response();
Status loop_impl() override;
Status loop_impl() final;
};
} // namespace mtproto

View File

@ -13,7 +13,7 @@ namespace mtproto {
class TlsReaderByteFlow final : public ByteFlowBase {
public:
bool loop() override;
bool loop() final;
};
} // namespace mtproto

View File

@ -253,25 +253,24 @@ Status Transport::read_crypto_impl(int X, MutableSlice message, const AuthKey &a
auto *prefix = reinterpret_cast<PrefixT *>(header->data);
*prefix_ptr = prefix;
size_t data_size = prefix->message_data_length + sizeof(PrefixT);
bool is_length_ok = true;
bool is_length_bad = false;
UInt128 real_message_key;
if (info->version == 1) {
is_length_ok &= !info->check_mod4 || prefix->message_data_length % 4 == 0;
is_length_bad |= info->check_mod4 && prefix->message_data_length % 4 != 0;
auto expected_size = calc_crypto_size<HeaderT>(data_size);
is_length_ok = (is_length_ok & (expected_size == message.size())) != 0;
auto check_size = data_size * is_length_ok + tail_size * (1 - is_length_ok);
is_length_bad |= expected_size != message.size();
auto check_size = data_size * (1 - is_length_bad) + tail_size * is_length_bad;
std::tie(info->message_ack, real_message_key) = calc_message_ack_and_key(*header, check_size);
} else {
std::tie(info->message_ack, real_message_key) = calc_message_key2(auth_key, X, to_decrypt);
}
bool is_key_ok = true;
int is_key_bad = false;
for (size_t i = 0; i < sizeof(real_message_key.raw); i++) {
is_key_ok &= real_message_key.raw[i] == header->message_key.raw[i];
is_key_bad |= real_message_key.raw[i] ^ header->message_key.raw[i];
}
if (!is_key_ok) {
if (is_key_bad != 0) {
return Status::Error(PSLICE() << "Invalid MTProto message: message_key mismatch [found = "
<< format::as_hex_dump(header->message_key)
<< "] [expected = " << format::as_hex_dump(real_message_key) << "]");
@ -295,7 +294,7 @@ Status Transport::read_crypto_impl(int X, MutableSlice message, const AuthKey &a
<< tag("message_data_length", prefix->message_data_length));
}
} else {
if (!is_length_ok) {
if (is_length_bad) {
return Status::Error(PSLICE() << "Invalid MTProto message: invalid length " << tag("total_size", message.size())
<< tag("message_data_length", prefix->message_data_length));
}

View File

@ -9,6 +9,7 @@
#include "td/mtproto/mtproto_api.h"
namespace td {
namespace mtproto {
TLStorer<mtproto_api::Function> create_storer(const mtproto_api::Function &function) {
return TLStorer<mtproto_api::Function>(function);
@ -18,4 +19,5 @@ TLObjectStorer<mtproto_api::Object> create_storer(const mtproto_api::Object &obj
return TLObjectStorer<mtproto_api::Object>(object);
}
} // namespace mtproto
} // namespace td

View File

@ -18,7 +18,7 @@ template <class T>
using TLStorer = DefaultStorer<T>;
template <class T>
class TLObjectStorer : public Storer {
class TLObjectStorer final : public Storer {
mutable size_t size_ = std::numeric_limits<size_t>::max();
const T &object_;
@ -26,7 +26,7 @@ class TLObjectStorer : public Storer {
explicit TLObjectStorer(const T &object) : object_(object) {
}
size_t size() const override {
size_t size() const final {
if (size_ == std::numeric_limits<size_t>::max()) {
TlStorerCalcLength storer;
storer.store_binary(object_.get_id());
@ -35,7 +35,7 @@ class TLObjectStorer : public Storer {
}
return size_;
}
size_t store(uint8 *ptr) const override {
size_t store(uint8 *ptr) const final {
TlStorerUnsafe storer(ptr);
storer.store_binary(object_.get_id());
object_.store(storer);
@ -48,8 +48,11 @@ class Object;
class Function;
} // namespace mtproto_api
namespace mtproto {
TLStorer<mtproto_api::Function> create_storer(const mtproto_api::Function &function);
TLObjectStorer<mtproto_api::Object> create_storer(const mtproto_api::Object &object);
} // namespace mtproto
} // namespace td

View File

@ -39,7 +39,7 @@
namespace td {
class GetSavedGifsQuery : public Td::ResultHandler {
class GetSavedGifsQuery final : public Td::ResultHandler {
bool is_repair_ = false;
public:
@ -49,7 +49,7 @@ class GetSavedGifsQuery : public Td::ResultHandler {
send_query(G()->net_query_creator().create(telegram_api::messages_getSavedGifs(hash)));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::messages_getSavedGifs>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -59,7 +59,7 @@ class GetSavedGifsQuery : public Td::ResultHandler {
td->animations_manager_->on_get_saved_animations(is_repair_, std::move(ptr));
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
if (!G()->is_expected_error(status)) {
LOG(ERROR) << "Receive error for get saved animations: " << status;
}
@ -67,7 +67,7 @@ class GetSavedGifsQuery : public Td::ResultHandler {
}
};
class SaveGifQuery : public Td::ResultHandler {
class SaveGifQuery final : public Td::ResultHandler {
FileId file_id_;
string file_reference_;
bool unsave_ = false;
@ -89,7 +89,7 @@ class SaveGifQuery : public Td::ResultHandler {
send_query(G()->net_query_creator().create(telegram_api::messages_saveGif(std::move(input_document), unsave)));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::messages_saveGif>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -104,7 +104,7 @@ class SaveGifQuery : public Td::ResultHandler {
promise_.set_value(Unit());
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
if (!td->auth_manager_->is_bot() && FileReferenceManager::is_file_reference_error(status)) {
VLOG(file_references) << "Receive " << status << " for " << file_id_;
td->file_manager_->delete_file_reference(file_id_, file_reference_);

View File

@ -27,7 +27,7 @@ namespace td {
class Td;
class AnimationsManager : public Actor {
class AnimationsManager final : public Actor {
public:
AnimationsManager(Td *td, ActorShared<> parent);
@ -144,7 +144,7 @@ class AnimationsManager : public Actor {
void save_saved_animations_to_database();
void tear_down() override;
void tear_down() final;
class AnimationListLogEvent;

View File

@ -23,7 +23,7 @@
namespace td {
class AuthManager : public NetActor {
class AuthManager final : public NetActor {
public:
AuthManager(int32 api_id, const string &api_hash, ActorShared<> parent);
@ -238,14 +238,14 @@ class AuthManager : public NetActor {
void on_get_login_token(tl_object_ptr<telegram_api::auth_LoginToken> login_token);
void on_get_authorization(tl_object_ptr<telegram_api::auth_Authorization> auth_ptr);
void on_result(NetQueryPtr result) override;
void on_result(NetQueryPtr result) final;
void update_state(State new_state, bool force = false, bool should_save_state = true);
tl_object_ptr<td_api::AuthorizationState> get_authorization_state_object(State authorization_state) const;
void send_ok(uint64 query_id);
void start_up() override;
void tear_down() override;
void start_up() final;
void tear_down() final;
};
} // namespace td

View File

@ -30,7 +30,7 @@ static td_api::object_ptr<td_api::autoDownloadSettings> convert_auto_download_se
settings->video_upload_maxbitrate_, video_preload_large, audio_preload_next, phonecalls_less_data);
}
class GetAutoDownloadSettingsQuery : public Td::ResultHandler {
class GetAutoDownloadSettingsQuery final : public Td::ResultHandler {
Promise<td_api::object_ptr<td_api::autoDownloadSettingsPresets>> promise_;
public:
@ -42,7 +42,7 @@ class GetAutoDownloadSettingsQuery : public Td::ResultHandler {
send_query(G()->net_query_creator().create(telegram_api::account_getAutoDownloadSettings()));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::account_getAutoDownloadSettings>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -54,7 +54,7 @@ class GetAutoDownloadSettingsQuery : public Td::ResultHandler {
convert_auto_download_settings(settings->high_)));
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
promise_.set_error(std::move(status));
}
};
@ -79,7 +79,7 @@ telegram_api::object_ptr<telegram_api::autoDownloadSettings> get_input_auto_down
settings.max_video_file_size, settings.max_other_file_size, settings.video_upload_bitrate);
}
class SaveAutoDownloadSettingsQuery : public Td::ResultHandler {
class SaveAutoDownloadSettingsQuery final : public Td::ResultHandler {
Promise<Unit> promise_;
public:
@ -98,7 +98,7 @@ class SaveAutoDownloadSettingsQuery : public Td::ResultHandler {
flags, false /*ignored*/, false /*ignored*/, get_input_auto_download_settings(settings))));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::account_saveAutoDownloadSettings>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -108,7 +108,7 @@ class SaveAutoDownloadSettingsQuery : public Td::ResultHandler {
promise_.set_value(Unit());
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
promise_.set_error(std::move(status));
}
};

View File

@ -40,7 +40,7 @@
namespace td {
class GetBackgroundQuery : public Td::ResultHandler {
class GetBackgroundQuery final : public Td::ResultHandler {
Promise<Unit> promise_;
BackgroundId background_id_;
string background_name_;
@ -57,7 +57,7 @@ class GetBackgroundQuery : public Td::ResultHandler {
send_query(G()->net_query_creator().create(telegram_api::account_getWallPaper(std::move(input_wallpaper))));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::account_getWallPaper>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -68,14 +68,14 @@ class GetBackgroundQuery : public Td::ResultHandler {
promise_.set_value(Unit());
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
LOG(INFO) << "Receive error for GetBackgroundQuery for " << background_id_ << "/" << background_name_ << ": "
<< status;
promise_.set_error(std::move(status));
}
};
class GetBackgroundsQuery : public Td::ResultHandler {
class GetBackgroundsQuery final : public Td::ResultHandler {
Promise<telegram_api::object_ptr<telegram_api::account_WallPapers>> promise_;
public:
@ -87,7 +87,7 @@ class GetBackgroundsQuery : public Td::ResultHandler {
send_query(G()->net_query_creator().create(telegram_api::account_getWallPapers(0)));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::account_getWallPapers>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -96,12 +96,12 @@ class GetBackgroundsQuery : public Td::ResultHandler {
promise_.set_value(result_ptr.move_as_ok());
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
promise_.set_error(std::move(status));
}
};
class InstallBackgroundQuery : public Td::ResultHandler {
class InstallBackgroundQuery final : public Td::ResultHandler {
Promise<Unit> promise_;
public:
@ -113,7 +113,7 @@ class InstallBackgroundQuery : public Td::ResultHandler {
telegram_api::account_installWallPaper(std::move(input_wallpaper), type.get_input_wallpaper_settings())));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::account_installWallPaper>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -123,12 +123,12 @@ class InstallBackgroundQuery : public Td::ResultHandler {
promise_.set_value(Unit());
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
promise_.set_error(std::move(status));
}
};
class UploadBackgroundQuery : public Td::ResultHandler {
class UploadBackgroundQuery final : public Td::ResultHandler {
Promise<Unit> promise_;
FileId file_id_;
BackgroundType type_;
@ -150,7 +150,7 @@ class UploadBackgroundQuery : public Td::ResultHandler {
std::move(input_file), type_.get_mime_type(), type.get_input_wallpaper_settings())));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::account_uploadWallPaper>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -160,7 +160,7 @@ class UploadBackgroundQuery : public Td::ResultHandler {
std::move(promise_));
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
CHECK(status.is_error());
CHECK(file_id_.is_valid());
if (begins_with(status.message(), "FILE_PART_") && ends_with(status.message(), "_MISSING")) {
@ -176,7 +176,7 @@ class UploadBackgroundQuery : public Td::ResultHandler {
}
};
class UnsaveBackgroundQuery : public Td::ResultHandler {
class UnsaveBackgroundQuery final : public Td::ResultHandler {
Promise<Unit> promise_;
public:
@ -188,7 +188,7 @@ class UnsaveBackgroundQuery : public Td::ResultHandler {
std::move(input_wallpaper), true, telegram_api::make_object<telegram_api::wallPaperSettings>())));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::account_saveWallPaper>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -199,7 +199,7 @@ class UnsaveBackgroundQuery : public Td::ResultHandler {
promise_.set_value(Unit());
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
if (!G()->is_expected_error(status)) {
LOG(ERROR) << "Receive error for save background: " << status;
}
@ -207,7 +207,7 @@ class UnsaveBackgroundQuery : public Td::ResultHandler {
}
};
class ResetBackgroundsQuery : public Td::ResultHandler {
class ResetBackgroundsQuery final : public Td::ResultHandler {
Promise<Unit> promise_;
public:
@ -218,7 +218,7 @@ class ResetBackgroundsQuery : public Td::ResultHandler {
send_query(G()->net_query_creator().create(telegram_api::account_resetWallPapers()));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::account_resetWallPapers>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -229,7 +229,7 @@ class ResetBackgroundsQuery : public Td::ResultHandler {
promise_.set_value(Unit());
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
if (!G()->is_expected_error(status)) {
LOG(ERROR) << "Receive error for reset backgrounds: " << status;
}
@ -237,22 +237,22 @@ class ResetBackgroundsQuery : public Td::ResultHandler {
}
};
class BackgroundManager::UploadBackgroundFileCallback : public FileManager::UploadCallback {
class BackgroundManager::UploadBackgroundFileCallback final : public FileManager::UploadCallback {
public:
void on_upload_ok(FileId file_id, tl_object_ptr<telegram_api::InputFile> input_file) override {
void on_upload_ok(FileId file_id, tl_object_ptr<telegram_api::InputFile> input_file) final {
send_closure_later(G()->background_manager(), &BackgroundManager::on_upload_background_file, file_id,
std::move(input_file));
}
void on_upload_encrypted_ok(FileId file_id, tl_object_ptr<telegram_api::InputEncryptedFile> input_file) override {
void on_upload_encrypted_ok(FileId file_id, tl_object_ptr<telegram_api::InputEncryptedFile> input_file) final {
UNREACHABLE();
}
void on_upload_secure_ok(FileId file_id, tl_object_ptr<telegram_api::InputSecureFile> input_file) override {
void on_upload_secure_ok(FileId file_id, tl_object_ptr<telegram_api::InputSecureFile> input_file) final {
UNREACHABLE();
}
void on_upload_error(FileId file_id, Status error) override {
void on_upload_error(FileId file_id, Status error) final {
send_closure_later(G()->background_manager(), &BackgroundManager::on_upload_background_file_error, file_id,
std::move(error));
}

View File

@ -29,7 +29,7 @@ namespace td {
class Td;
class BackgroundManager : public Actor {
class BackgroundManager final : public Actor {
public:
BackgroundManager(Td *td, ActorShared<> parent);
@ -95,9 +95,9 @@ class BackgroundManager : public Actor {
class UploadBackgroundFileCallback;
void start_up() override;
void start_up() final;
void tear_down() override;
void tear_down() final;
void memory_cleanup(bool full);

View File

@ -22,7 +22,7 @@
namespace td {
class SetBotCommandsQuery : public Td::ResultHandler {
class SetBotCommandsQuery final : public Td::ResultHandler {
Promise<Unit> promise_;
public:
@ -35,7 +35,7 @@ class SetBotCommandsQuery : public Td::ResultHandler {
transform(commands, [](const BotCommand &command) { return command.get_input_bot_command(); }))));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::bots_setBotCommands>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -47,12 +47,12 @@ class SetBotCommandsQuery : public Td::ResultHandler {
promise_.set_value(Unit());
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
promise_.set_error(std::move(status));
}
};
class ResetBotCommandsQuery : public Td::ResultHandler {
class ResetBotCommandsQuery final : public Td::ResultHandler {
Promise<Unit> promise_;
public:
@ -64,7 +64,7 @@ class ResetBotCommandsQuery : public Td::ResultHandler {
telegram_api::bots_resetBotCommands(scope.get_input_bot_command_scope(td), language_code)));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::bots_resetBotCommands>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -73,12 +73,12 @@ class ResetBotCommandsQuery : public Td::ResultHandler {
promise_.set_value(Unit());
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
promise_.set_error(std::move(status));
}
};
class GetBotCommandsQuery : public Td::ResultHandler {
class GetBotCommandsQuery final : public Td::ResultHandler {
Promise<td_api::object_ptr<td_api::botCommands>> promise_;
public:
@ -91,7 +91,7 @@ class GetBotCommandsQuery : public Td::ResultHandler {
telegram_api::bots_getBotCommands(scope.get_input_bot_command_scope(td), language_code)));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::bots_getBotCommands>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -101,7 +101,7 @@ class GetBotCommandsQuery : public Td::ResultHandler {
promise_.set_value(commands.get_bot_commands_object(td));
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
promise_.set_error(std::move(status));
}
};

View File

@ -557,7 +557,7 @@ void CallActor::on_dh_config(Result<std::shared_ptr<DhConfig>> r_dh_config, bool
}
dh_config_ = r_dh_config.move_as_ok();
auto check_result = DhHandshake::check_config(dh_config_->g, dh_config_->prime, DhCache::instance());
auto check_result = mtproto::DhHandshake::check_config(dh_config_->g, dh_config_->prime, DhCache::instance());
if (check_result.is_error()) {
return on_error(std::move(check_result));
}

View File

@ -89,7 +89,7 @@ struct CallState {
tl_object_ptr<td_api::CallState> get_call_state_object() const;
};
class CallActor : public NetQueryCallback {
class CallActor final : public NetQueryCallback {
public:
CallActor(CallId call_id, ActorShared<> parent, Promise<int64> promise);
@ -110,7 +110,7 @@ class CallActor : public NetQueryCallback {
ActorShared<> parent_;
Promise<int64> call_id_promise_;
DhHandshake dh_handshake_;
mtproto::DhHandshake dh_handshake_;
std::shared_ptr<DhConfig> dh_config_;
bool dh_config_query_sent_{false};
bool dh_config_ready_{false};
@ -191,15 +191,15 @@ class CallActor : public NetQueryCallback {
static vector<string> get_emojis_fingerprint(const string &key, const string &g_a);
void start_up() override;
void loop() override;
void start_up() final;
void loop() final;
Container<Promise<NetQueryPtr>> container_;
void on_result(NetQueryPtr query) override;
void on_result(NetQueryPtr query) final;
void send_with_promise(NetQueryPtr query, Promise<NetQueryPtr> promise);
void timeout_expired() override;
void hangup() override;
void timeout_expired() final;
void hangup() final;
void on_error(Status status);
};

View File

@ -22,7 +22,7 @@
namespace td {
class CallManager : public Actor {
class CallManager final : public Actor {
public:
using Update = telegram_api::object_ptr<telegram_api::updatePhoneCall>;
explicit CallManager(ActorShared<> parent);
@ -55,7 +55,7 @@ class CallManager : public Actor {
CallId create_call_actor();
void set_call_id(CallId call_id, Result<int64> r_server_call_id);
void hangup() override;
void hangup_shared() override;
void hangup() final;
void hangup_shared() final;
};
} // namespace td

View File

@ -28,7 +28,7 @@
namespace td {
class GetBotCallbackAnswerQuery : public Td::ResultHandler {
class GetBotCallbackAnswerQuery final : public Td::ResultHandler {
Promise<Unit> promise_;
int64 result_id_;
DialogId dialog_id_;
@ -77,7 +77,7 @@ class GetBotCallbackAnswerQuery : public Td::ResultHandler {
send_query(std::move(net_query));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::messages_getBotCallbackAnswer>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -87,9 +87,9 @@ class GetBotCallbackAnswerQuery : public Td::ResultHandler {
promise_.set_value(Unit());
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
if (status.message() == "DATA_INVALID") {
td->messages_manager_->get_message_from_server({dialog_id_, message_id_}, Auto());
td->messages_manager_->get_message_from_server({dialog_id_, message_id_}, Auto(), "GetBotCallbackAnswerQuery");
} else if (status.message() == "BOT_RESPONSE_TIMEOUT") {
status = Status::Error(502, "The bot is not responding");
}
@ -99,7 +99,7 @@ class GetBotCallbackAnswerQuery : public Td::ResultHandler {
}
};
class SetBotCallbackAnswerQuery : public Td::ResultHandler {
class SetBotCallbackAnswerQuery final : public Td::ResultHandler {
Promise<Unit> promise_;
public:
@ -111,7 +111,7 @@ class SetBotCallbackAnswerQuery : public Td::ResultHandler {
flags, false /*ignored*/, callback_query_id, text, url, cache_time)));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::messages_setBotCallbackAnswer>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -124,7 +124,7 @@ class SetBotCallbackAnswerQuery : public Td::ResultHandler {
promise_.set_value(Unit());
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
promise_.set_error(std::move(status));
}
};

View File

@ -48,21 +48,21 @@ class TdReceiver {
}
unique_ptr<TdCallback> create_callback(ClientManager::ClientId client_id) {
class Callback : public TdCallback {
class Callback final : public TdCallback {
public:
Callback(ClientManager::ClientId client_id, TdReceiver *impl) : client_id_(client_id), impl_(impl) {
}
void on_result(uint64 id, td_api::object_ptr<td_api::Object> result) override {
void on_result(uint64 id, td_api::object_ptr<td_api::Object> result) final {
impl_->responses_.push({client_id_, id, std::move(result)});
}
void on_error(uint64 id, td_api::object_ptr<td_api::error> error) override {
void on_error(uint64 id, td_api::object_ptr<td_api::error> error) final {
impl_->responses_.push({client_id_, id, std::move(error)});
}
Callback(const Callback &) = delete;
Callback &operator=(const Callback &) = delete;
Callback(Callback &&) = delete;
Callback &operator=(Callback &&) = delete;
~Callback() override {
~Callback() final {
impl_->responses_.push({client_id_, 0, nullptr});
}
@ -232,7 +232,7 @@ class Client::Impl final {
#else
class MultiTd : public Actor {
class MultiTd final : public Actor {
public:
explicit MultiTd(Td::Options options) : options_(std::move(options)) {
}
@ -288,22 +288,22 @@ class TdReceiver {
}
unique_ptr<TdCallback> create_callback(ClientManager::ClientId client_id) {
class Callback : public TdCallback {
class Callback final : public TdCallback {
public:
explicit Callback(ClientManager::ClientId client_id, std::shared_ptr<OutputQueue> output_queue)
: client_id_(client_id), output_queue_(std::move(output_queue)) {
}
void on_result(uint64 id, td_api::object_ptr<td_api::Object> result) override {
void on_result(uint64 id, td_api::object_ptr<td_api::Object> result) final {
output_queue_->writer_put({client_id_, id, std::move(result)});
}
void on_error(uint64 id, td_api::object_ptr<td_api::error> error) override {
void on_error(uint64 id, td_api::object_ptr<td_api::error> error) final {
output_queue_->writer_put({client_id_, id, std::move(error)});
}
Callback(const Callback &) = delete;
Callback &operator=(const Callback &) = delete;
Callback(Callback &&) = delete;
Callback &operator=(Callback &&) = delete;
~Callback() override {
~Callback() final {
output_queue_->writer_put({client_id_, 0, nullptr});
}
@ -342,9 +342,11 @@ class TdReceiver {
class MultiImpl {
public:
static constexpr int32 ADDITIONAL_THREAD_COUNT = 3;
explicit MultiImpl(std::shared_ptr<NetQueryStats> net_query_stats) {
concurrent_scheduler_ = std::make_shared<ConcurrentScheduler>();
concurrent_scheduler_->init(3);
concurrent_scheduler_->init(ADDITIONAL_THREAD_COUNT);
concurrent_scheduler_->start();
{
@ -421,7 +423,8 @@ class MultiImplPool {
if (impls_.empty()) {
init_openssl_threads();
impls_.resize(clamp(thread::hardware_concurrency(), 8u, 24u) * 5 / 4);
impls_.resize(clamp(thread::hardware_concurrency(), 8u, 20u) * 5 / 4);
CHECK(impls_.size() * (1 + MultiImpl::ADDITIONAL_THREAD_COUNT + 1 /* IOCP */) < 128);
net_query_stats_ = std::make_shared<NetQueryStats>();
}

View File

@ -27,7 +27,7 @@ class Td;
* This is a low-level Actor interface for interaction with TDLib. The interface is a lot more flexible than
* the Client interface, however, for most usages the Client interface should be sufficient.
*/
class ClientActor : public Actor {
class ClientActor final : public Actor {
public:
/// Options for ClientActor creation.
struct Options {

View File

@ -146,7 +146,7 @@ Result<int32> HttpDate::parse_http_date(string slice) {
}
Result<SimpleConfig> decode_config(Slice input) {
static auto rsa = RSA::from_pem_public_key(
static auto rsa = mtproto::RSA::from_pem_public_key(
"-----BEGIN RSA PUBLIC KEY-----\n"
"MIIBCgKCAQEAyr+18Rex2ohtVy8sroGP\n"
"BwXD3DOoKCSpjDqYoXgCqB7ioln4eDCFfOBUlfXUEvM/fnKCpF46VkAftlb4VuPD\n"
@ -379,7 +379,7 @@ ActorOwn<> get_simple_config_firebase_firestore(Promise<SimpleConfigResult> prom
}
ActorOwn<> get_full_config(DcOption option, Promise<FullConfig> promise, ActorShared<> parent) {
class SessionCallback : public Session::Callback {
class SessionCallback final : public Session::Callback {
public:
SessionCallback(ActorShared<> parent, DcOption option) : parent_(std::move(parent)), option_(std::move(option)) {
}
@ -417,17 +417,17 @@ ActorOwn<> get_full_config(DcOption option, Promise<FullConfig> promise, ActorSh
std::vector<Promise<unique_ptr<mtproto::RawConnection>>> delay_forever_;
};
class SimpleAuthData : public AuthDataShared {
class SimpleAuthData final : public AuthDataShared {
public:
explicit SimpleAuthData(DcId dc_id) : dc_id_(dc_id) {
}
DcId dc_id() const override {
DcId dc_id() const final {
return dc_id_;
}
const std::shared_ptr<PublicRsaKeyShared> &public_rsa_key() override {
const std::shared_ptr<PublicRsaKeyShared> &public_rsa_key() final {
return public_rsa_key_;
}
mtproto::AuthKey get_auth_key() override {
mtproto::AuthKey get_auth_key() final {
string dc_key = G()->td_db()->get_binlog_pmc()->get(auth_key_key());
mtproto::AuthKey res;
@ -436,31 +436,31 @@ ActorOwn<> get_full_config(DcOption option, Promise<FullConfig> promise, ActorSh
}
return res;
}
AuthKeyState get_auth_key_state() override {
AuthKeyState get_auth_key_state() final {
return AuthDataShared::get_auth_key_state(get_auth_key());
}
void set_auth_key(const mtproto::AuthKey &auth_key) override {
void set_auth_key(const mtproto::AuthKey &auth_key) final {
G()->td_db()->get_binlog_pmc()->set(auth_key_key(), serialize(auth_key));
//notify();
}
void update_server_time_difference(double diff) override {
void update_server_time_difference(double diff) final {
G()->update_server_time_difference(diff);
}
double get_server_time_difference() override {
double get_server_time_difference() final {
return G()->get_server_time_difference();
}
void add_auth_key_listener(unique_ptr<Listener> listener) override {
void add_auth_key_listener(unique_ptr<Listener> listener) final {
if (listener->notify()) {
auth_key_listeners_.push_back(std::move(listener));
}
}
void set_future_salts(const std::vector<mtproto::ServerSalt> &future_salts) override {
void set_future_salts(const std::vector<mtproto::ServerSalt> &future_salts) final {
G()->td_db()->get_binlog_pmc()->set(future_salts_key(), serialize(future_salts));
}
std::vector<mtproto::ServerSalt> get_future_salts() override {
std::vector<mtproto::ServerSalt> get_future_salts() final {
string future_salts = G()->td_db()->get_binlog_pmc()->get(future_salts_key());
std::vector<mtproto::ServerSalt> res;
if (!future_salts.empty()) {
@ -487,14 +487,14 @@ ActorOwn<> get_full_config(DcOption option, Promise<FullConfig> promise, ActorSh
}
};
class GetConfigActor : public NetQueryCallback {
class GetConfigActor final : public NetQueryCallback {
public:
GetConfigActor(DcOption option, Promise<FullConfig> promise, ActorShared<> parent)
: option_(std::move(option)), promise_(std::move(promise)), parent_(std::move(parent)) {
}
private:
void start_up() override {
void start_up() final {
auto auth_data = std::make_shared<SimpleAuthData>(option_.get_dc_id());
int32 raw_dc_id = option_.get_dc_id().get_raw_id();
auto session_callback = make_unique<SessionCallback>(actor_shared(this, 1), std::move(option_));
@ -514,10 +514,10 @@ ActorOwn<> get_full_config(DcOption option, Promise<FullConfig> promise, ActorSh
send_closure(session_, &Session::send, std::move(query));
set_timeout_in(10);
}
void on_result(NetQueryPtr query) override {
void on_result(NetQueryPtr query) final {
promise_.set_result(fetch_result<telegram_api::help_getConfig>(std::move(query)));
}
void hangup_shared() override {
void hangup_shared() final {
if (get_link_token() == 1) {
if (promise_) {
promise_.set_error(Status::Error("Failed"));
@ -525,10 +525,10 @@ ActorOwn<> get_full_config(DcOption option, Promise<FullConfig> promise, ActorSh
stop();
}
}
void hangup() override {
void hangup() final {
session_.reset();
}
void timeout_expired() override {
void timeout_expired() final {
promise_.set_error(Status::Error("Timeout expired"));
session_.reset();
}
@ -542,7 +542,7 @@ ActorOwn<> get_full_config(DcOption option, Promise<FullConfig> promise, ActorSh
return ActorOwn<>(create_actor<GetConfigActor>("GetConfigActor", option, std::move(promise), std::move(parent)));
}
class ConfigRecoverer : public Actor {
class ConfigRecoverer final : public Actor {
public:
explicit ConfigRecoverer(ActorShared<> parent) : parent_(std::move(parent)) {
connecting_since_ = Time::now();
@ -732,11 +732,11 @@ class ConfigRecoverer : public Actor {
ActorShared<> parent_;
void hangup_shared() override {
void hangup_shared() final {
ref_cnt_--;
try_stop();
}
void hangup() override {
void hangup() final {
ref_cnt_--;
close_flag_ = true;
full_config_query_.reset();
@ -753,7 +753,7 @@ class ConfigRecoverer : public Actor {
double max_connecting_delay() const {
return expect_blocking() ? 5 : 20;
}
void loop() override {
void loop() final {
if (close_flag_) {
return;
}
@ -839,20 +839,20 @@ class ConfigRecoverer : public Actor {
}
}
void start_up() override {
class StateCallback : public StateManager::Callback {
void start_up() final {
class StateCallback final : public StateManager::Callback {
public:
explicit StateCallback(ActorId<ConfigRecoverer> parent) : parent_(std::move(parent)) {
}
bool on_state(StateManager::State state) override {
bool on_state(StateManager::State state) final {
send_closure(parent_, &ConfigRecoverer::on_connecting, state == StateManager::State::Connecting);
return parent_.is_alive();
}
bool on_network(NetType network_type, uint32 network_generation) override {
bool on_network(NetType network_type, uint32 network_generation) final {
send_closure(parent_, &ConfigRecoverer::on_network, network_type != NetType::None, network_generation);
return parent_.is_alive();
}
bool on_online(bool online_flag) override {
bool on_online(bool online_flag) final {
send_closure(parent_, &ConfigRecoverer::on_online, online_flag);
return parent_.is_alive();
}

View File

@ -83,7 +83,7 @@ using FullConfig = tl_object_ptr<telegram_api::config>;
ActorOwn<> get_full_config(DcId dc_id, IPAddress ip_address, Promise<FullConfig> promise);
class ConfigRecoverer;
class ConfigManager : public NetQueryCallback {
class ConfigManager final : public NetQueryCallback {
public:
explicit ConfigManager(ActorShared<> parent);
@ -136,13 +136,13 @@ class ConfigManager : public NetQueryCallback {
static constexpr uint64 REFCNT_TOKEN = std::numeric_limits<uint64>::max() - 2;
void start_up() override;
void hangup_shared() override;
void hangup() override;
void loop() override;
void start_up() final;
void hangup_shared() final;
void hangup() final;
void loop() final;
void try_stop();
void on_result(NetQueryPtr res) override;
void on_result(NetQueryPtr res) final;
void request_config_from_dc_impl(DcId dc_id);
void process_config(tl_object_ptr<telegram_api::config> config);

File diff suppressed because it is too large Load Diff

View File

@ -58,14 +58,14 @@ struct BinlogEvent;
class Td;
class ContactsManager : public Actor {
class ContactsManager final : public Actor {
public:
ContactsManager(Td *td, ActorShared<> parent);
ContactsManager(const ContactsManager &) = delete;
ContactsManager &operator=(const ContactsManager &) = delete;
ContactsManager(ContactsManager &&) = delete;
ContactsManager &operator=(ContactsManager &&) = delete;
~ContactsManager() override;
~ContactsManager() final;
static UserId load_my_id();
@ -513,20 +513,19 @@ class ContactsManager : public Actor {
ChannelId get_channel_linked_channel_id(ChannelId channel_id);
int32 get_channel_slow_mode_delay(ChannelId channel_id);
static DialogId get_participant_dialog_id(const td_api::object_ptr<td_api::MessageSender> &participant_id);
void add_dialog_participant(DialogId dialog_id, UserId user_id, int32 forward_limit, Promise<Unit> &&promise);
void add_dialog_participants(DialogId dialog_id, const vector<UserId> &user_ids, Promise<Unit> &&promise);
void set_dialog_participant_status(DialogId dialog_id, DialogId participant_dialog_id,
void set_dialog_participant_status(DialogId dialog_id, const tl_object_ptr<td_api::MessageSender> &participant_id,
const tl_object_ptr<td_api::ChatMemberStatus> &chat_member_status,
Promise<Unit> &&promise);
void ban_dialog_participant(DialogId dialog_id, DialogId participant_dialog_id, int32 banned_until_date,
bool revoke_messages, Promise<Unit> &&promise);
void ban_dialog_participant(DialogId dialog_id, const tl_object_ptr<td_api::MessageSender> &participant_id,
int32 banned_until_date, bool revoke_messages, Promise<Unit> &&promise);
DialogParticipant get_dialog_participant(DialogId dialog_id, DialogId participant_dialog_id, int64 &random_id,
DialogParticipant get_dialog_participant(DialogId dialog_id,
const tl_object_ptr<td_api::MessageSender> &participant_id, int64 &random_id,
bool force, Promise<Unit> &&promise);
void search_dialog_participants(DialogId dialog_id, const string &query, int32 limit, DialogParticipantsFilter filter,
@ -1393,6 +1392,8 @@ class ContactsManager : public Actor {
bool update_permanent_invite_link(DialogInviteLink &invite_link, DialogInviteLink new_invite_link);
static Result<DialogId> get_participant_dialog_id(const td_api::object_ptr<td_api::MessageSender> &participant_id);
void add_chat_participant(ChatId chat_id, UserId user_id, int32 forward_limit, Promise<Unit> &&promise);
void add_channel_participant(ChannelId channel_id, UserId user_id, Promise<Unit> &&promise,
@ -1498,8 +1499,7 @@ class ContactsManager : public Actor {
void add_channel_participant_to_cache(ChannelId channel_id, const DialogParticipant &dialog_participant,
bool allow_replace);
const DialogParticipant *get_channel_participant_from_cache(ChannelId channel_id,
DialogId participant_dialog_id) const;
const DialogParticipant *get_channel_participant_from_cache(ChannelId channel_id, DialogId participant_dialog_id);
void change_channel_participant_status_impl(ChannelId channel_id, DialogId participant_dialog_id,
DialogParticipantStatus status, DialogParticipantStatus old_status,
@ -1557,7 +1557,7 @@ class ContactsManager : public Actor {
void on_channel_participant_cache_timeout(ChannelId channel_id);
void tear_down() override;
void tear_down() final;
Td *td_;
ActorShared<> parent_;
@ -1663,7 +1663,7 @@ class ContactsManager : public Actor {
struct ChannelParticipantInfo {
DialogParticipant participant_;
mutable int32 last_access_date_ = 0;
int32 last_access_date_ = 0;
};
struct ChannelParticipants {
std::unordered_map<DialogId, ChannelParticipantInfo, DialogIdHash> participants_;

View File

@ -25,7 +25,7 @@
namespace td {
class GetNearestDcQuery : public Td::ResultHandler {
class GetNearestDcQuery final : public Td::ResultHandler {
Promise<string> promise_;
public:
@ -36,7 +36,7 @@ class GetNearestDcQuery : public Td::ResultHandler {
send_query(G()->net_query_creator().create_unauth(telegram_api::help_getNearestDc()));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::help_getNearestDc>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -46,7 +46,7 @@ class GetNearestDcQuery : public Td::ResultHandler {
promise_.set_value(std::move(result->country_));
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
if (!G()->is_expected_error(status) && status.message() != "BOT_METHOD_INVALID") {
LOG(ERROR) << "GetNearestDc returned " << status;
}
@ -54,7 +54,7 @@ class GetNearestDcQuery : public Td::ResultHandler {
}
};
class GetCountriesListQuery : public Td::ResultHandler {
class GetCountriesListQuery final : public Td::ResultHandler {
Promise<tl_object_ptr<telegram_api::help_CountriesList>> promise_;
public:
@ -67,7 +67,7 @@ class GetCountriesListQuery : public Td::ResultHandler {
send_query(G()->net_query_creator().create_unauth(telegram_api::help_getCountriesList(language_code, hash)));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::help_getCountriesList>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -76,7 +76,7 @@ class GetCountriesListQuery : public Td::ResultHandler {
promise_.set_value(result_ptr.move_as_ok());
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
if (!G()->is_expected_error(status)) {
LOG(ERROR) << "GetCountriesList returned " << status;
}

View File

@ -21,7 +21,7 @@ namespace td {
class Td;
class CountryInfoManager : public Actor {
class CountryInfoManager final : public Actor {
public:
CountryInfoManager(Td *td, ActorShared<> parent);
@ -36,10 +36,10 @@ class CountryInfoManager : public Actor {
CountryInfoManager &operator=(const CountryInfoManager &) = delete;
CountryInfoManager(CountryInfoManager &&) = delete;
CountryInfoManager &operator=(CountryInfoManager &&) = delete;
~CountryInfoManager() override;
~CountryInfoManager() final;
private:
void tear_down() override;
void tear_down() final;
struct CallingCodeInfo;
struct CountryInfo;

View File

@ -16,7 +16,7 @@
namespace td {
class DelayDispatcher : public Actor {
class DelayDispatcher final : public Actor {
public:
DelayDispatcher(double default_delay, ActorShared<> parent)
: default_delay_(default_delay), parent_(std::move(parent)) {
@ -38,8 +38,8 @@ class DelayDispatcher : public Actor {
double default_delay_;
ActorShared<> parent_;
void loop() override;
void tear_down() override;
void loop() final;
void tear_down() final;
};
} // namespace td

View File

@ -85,8 +85,8 @@ bool resolve_dependencies_force(Td *td, const Dependencies &dependencies, const
}
}
for (auto web_page_id : dependencies.web_page_ids) {
if (web_page_id.is_valid()) {
td->web_pages_manager_->have_web_page_force(web_page_id);
if (web_page_id.is_valid() && !td->web_pages_manager_->have_web_page_force(web_page_id)) {
LOG(INFO) << "Can't find " << web_page_id << " from " << source;
success = false;
}
}

View File

@ -132,51 +132,51 @@ void DeviceTokenManager::register_device(tl_object_ptr<td_api::DeviceToken> devi
case td_api::deviceTokenApplePush::ID: {
auto device_token = static_cast<td_api::deviceTokenApplePush *>(device_token_ptr.get());
token = std::move(device_token->device_token_);
token_type = TokenType::APNS;
token_type = TokenType::Apns;
is_app_sandbox = device_token->is_app_sandbox_;
break;
}
case td_api::deviceTokenFirebaseCloudMessaging::ID: {
auto device_token = static_cast<td_api::deviceTokenFirebaseCloudMessaging *>(device_token_ptr.get());
token = std::move(device_token->token_);
token_type = TokenType::FCM;
token_type = TokenType::Fcm;
encrypt = device_token->encrypt_;
break;
}
case td_api::deviceTokenMicrosoftPush::ID: {
auto device_token = static_cast<td_api::deviceTokenMicrosoftPush *>(device_token_ptr.get());
token = std::move(device_token->channel_uri_);
token_type = TokenType::MPNS;
token_type = TokenType::Mpns;
break;
}
case td_api::deviceTokenSimplePush::ID: {
auto device_token = static_cast<td_api::deviceTokenSimplePush *>(device_token_ptr.get());
token = std::move(device_token->endpoint_);
token_type = TokenType::SIMPLE_PUSH;
token_type = TokenType::SimplePush;
break;
}
case td_api::deviceTokenUbuntuPush::ID: {
auto device_token = static_cast<td_api::deviceTokenUbuntuPush *>(device_token_ptr.get());
token = std::move(device_token->token_);
token_type = TokenType::UBUNTU_PHONE;
token_type = TokenType::UbuntuPhone;
break;
}
case td_api::deviceTokenBlackBerryPush::ID: {
auto device_token = static_cast<td_api::deviceTokenBlackBerryPush *>(device_token_ptr.get());
token = std::move(device_token->token_);
token_type = TokenType::BLACKBERRY;
token_type = TokenType::BlackBerry;
break;
}
case td_api::deviceTokenWindowsPush::ID: {
auto device_token = static_cast<td_api::deviceTokenWindowsPush *>(device_token_ptr.get());
token = std::move(device_token->access_token_);
token_type = TokenType::WNS;
token_type = TokenType::Wns;
break;
}
case td_api::deviceTokenApplePushVoIP::ID: {
auto device_token = static_cast<td_api::deviceTokenApplePushVoIP *>(device_token_ptr.get());
token = std::move(device_token->device_token_);
token_type = TokenType::APNS_VOIP;
token_type = TokenType::ApnsVoip;
is_app_sandbox = device_token->is_app_sandbox_;
encrypt = device_token->encrypt_;
break;
@ -205,19 +205,19 @@ void DeviceTokenManager::register_device(tl_object_ptr<td_api::DeviceToken> devi
}));
}));
}
token_type = TokenType::WEB_PUSH;
token_type = TokenType::WebPush;
break;
}
case td_api::deviceTokenMicrosoftPushVoIP::ID: {
auto device_token = static_cast<td_api::deviceTokenMicrosoftPushVoIP *>(device_token_ptr.get());
token = std::move(device_token->channel_uri_);
token_type = TokenType::MPNS_VOIP;
token_type = TokenType::MpnsVoip;
break;
}
case td_api::deviceTokenTizenPush::ID: {
auto device_token = static_cast<td_api::deviceTokenTizenPush *>(device_token_ptr.get());
token = std::move(device_token->reg_id_);
token_type = TokenType::TIZEN;
token_type = TokenType::Tizen;
break;
}
default:
@ -255,7 +255,7 @@ void DeviceTokenManager::register_device(tl_object_ptr<td_api::DeviceToken> devi
info.encryption_key.resize(ENCRYPTION_KEY_LENGTH);
while (true) {
Random::secure_bytes(info.encryption_key);
info.encryption_key_id = DhHandshake::calc_key_id(info.encryption_key);
info.encryption_key_id = mtproto::DhHandshake::calc_key_id(info.encryption_key);
if (info.encryption_key_id <= -MIN_ENCRYPTION_KEY_ID || info.encryption_key_id >= MIN_ENCRYPTION_KEY_ID) {
// ensure that encryption key ID never collide with anything
break;
@ -273,7 +273,7 @@ void DeviceTokenManager::register_device(tl_object_ptr<td_api::DeviceToken> devi
}
void DeviceTokenManager::reregister_device() {
for (int32 token_type = 1; token_type < TokenType::SIZE; token_type++) {
for (int32 token_type = 1; token_type < TokenType::Size; token_type++) {
auto &token = tokens_[token_type];
if (token.state == TokenInfo::State::Sync && !token.token.empty()) {
token.state = TokenInfo::State::Reregister;
@ -284,7 +284,7 @@ void DeviceTokenManager::reregister_device() {
vector<std::pair<int64, Slice>> DeviceTokenManager::get_encryption_keys() const {
vector<std::pair<int64, Slice>> result;
for (int32 token_type = 1; token_type < TokenType::SIZE; token_type++) {
for (int32 token_type = 1; token_type < TokenType::Size; token_type++) {
auto &info = tokens_[token_type];
if (!info.token.empty() && info.state != TokenInfo::State::Unregister) {
if (info.encrypt) {
@ -302,7 +302,7 @@ string DeviceTokenManager::get_database_key(int32 token_type) {
}
void DeviceTokenManager::start_up() {
for (int32 token_type = 1; token_type < TokenType::SIZE; token_type++) {
for (int32 token_type = 1; token_type < TokenType::Size; token_type++) {
auto serialized = G()->td_db()->get_binlog_pmc()->get(get_database_key(token_type));
if (serialized.empty()) {
continue;
@ -360,7 +360,7 @@ void DeviceTokenManager::loop() {
if (sync_cnt_ != 0 || G()->close_flag()) {
return;
}
for (int32 token_type = 1; token_type < TokenType::SIZE; token_type++) {
for (int32 token_type = 1; token_type < TokenType::Size; token_type++) {
auto &info = tokens_[token_type];
if (info.state == TokenInfo::State::Sync) {
continue;
@ -387,7 +387,7 @@ void DeviceTokenManager::loop() {
void DeviceTokenManager::on_result(NetQueryPtr net_query) {
auto token_type = static_cast<TokenType>(get_link_token());
CHECK(token_type >= 1 && token_type < TokenType::SIZE);
CHECK(token_type >= 1 && token_type < TokenType::Size);
auto &info = tokens_[token_type];
if (info.net_query_id != net_query->id()) {
net_query->clear();

View File

@ -22,7 +22,7 @@
namespace td {
class DeviceTokenManager : public NetQueryCallback {
class DeviceTokenManager final : public NetQueryCallback {
public:
explicit DeviceTokenManager(ActorShared<> parent) : parent_(std::move(parent)) {
}
@ -36,19 +36,19 @@ class DeviceTokenManager : public NetQueryCallback {
private:
ActorShared<> parent_;
enum TokenType : int32 {
APNS = 1,
FCM = 2,
MPNS = 3,
SIMPLE_PUSH = 4,
UBUNTU_PHONE = 5,
BLACKBERRY = 6,
UNUSED = 7,
WNS = 8,
APNS_VOIP = 9,
WEB_PUSH = 10,
MPNS_VOIP = 11,
TIZEN = 12,
SIZE
Apns = 1,
Fcm = 2,
Mpns = 3,
SimplePush = 4,
UbuntuPhone = 5,
BlackBerry = 6,
Unused = 7,
Wns = 8,
ApnsVoip = 9,
WebPush = 10,
MpnsVoip = 11,
Tizen = 12,
Size
};
struct TokenInfo {
enum class State : int32 { Sync, Unregister, Register, Reregister };
@ -73,18 +73,18 @@ class DeviceTokenManager : public NetQueryCallback {
friend StringBuilder &operator<<(StringBuilder &string_builder, const TokenInfo &token_info);
std::array<TokenInfo, TokenType::SIZE> tokens_;
std::array<TokenInfo, TokenType::Size> tokens_;
int32 sync_cnt_{0};
void start_up() override;
void start_up() final;
static string get_database_key(int32 token_type);
void save_info(int32 token_type);
void dec_sync_cnt();
void loop() override;
void on_result(NetQueryPtr net_query) override;
void loop() final;
void on_result(NetQueryPtr net_query) final;
};
} // namespace td

View File

@ -6,19 +6,19 @@
//
#pragma once
#include "td/mtproto/DhHandshake.h"
#include "td/mtproto/DhCallback.h"
#include "td/utils/Slice.h"
namespace td {
class DhCache : public DhCallback {
class DhCache final : public mtproto::DhCallback {
public:
int is_good_prime(Slice prime_str) const override;
void add_good_prime(Slice prime_str) const override;
void add_bad_prime(Slice prime_str) const override;
int is_good_prime(Slice prime_str) const final;
void add_good_prime(Slice prime_str) const final;
void add_bad_prime(Slice prime_str) const final;
static DhCallback *instance() {
static mtproto::DhCallback *instance() {
static DhCache res;
return &res;
}

View File

@ -117,7 +117,7 @@ Status drop_dialog_db(SqliteDb &db, int version) {
return status;
}
class DialogDbImpl : public DialogDbSyncInterface {
class DialogDbImpl final : public DialogDbSyncInterface {
public:
explicit DialogDbImpl(SqliteDb db) : db_(std::move(db)) {
init().ensure();
@ -162,7 +162,7 @@ class DialogDbImpl : public DialogDbSyncInterface {
}
Status add_dialog(DialogId dialog_id, FolderId folder_id, int64 order, BufferSlice data,
vector<NotificationGroupKey> notification_groups) override {
vector<NotificationGroupKey> notification_groups) final {
SCOPE_EXIT {
add_dialog_stmt_.reset();
};
@ -201,7 +201,7 @@ class DialogDbImpl : public DialogDbSyncInterface {
return Status::OK();
}
Result<BufferSlice> get_dialog(DialogId dialog_id) override {
Result<BufferSlice> get_dialog(DialogId dialog_id) final {
SCOPE_EXIT {
get_dialog_stmt_.reset();
};
@ -214,7 +214,7 @@ class DialogDbImpl : public DialogDbSyncInterface {
return BufferSlice(get_dialog_stmt_.view_blob(0));
}
Result<NotificationGroupKey> get_notification_group(NotificationGroupId notification_group_id) override {
Result<NotificationGroupKey> get_notification_group(NotificationGroupId notification_group_id) final {
SCOPE_EXIT {
get_notification_group_stmt_.reset();
};
@ -227,7 +227,7 @@ class DialogDbImpl : public DialogDbSyncInterface {
get_last_notification_date(get_notification_group_stmt_, 1));
}
Result<int32> get_secret_chat_count(FolderId folder_id) override {
Result<int32> get_secret_chat_count(FolderId folder_id) final {
SCOPE_EXIT {
get_secret_chat_count_stmt_.reset();
};
@ -237,8 +237,7 @@ class DialogDbImpl : public DialogDbSyncInterface {
return get_secret_chat_count_stmt_.view_int32(0);
}
Result<DialogDbGetDialogsResult> get_dialogs(FolderId folder_id, int64 order, DialogId dialog_id,
int32 limit) override {
Result<DialogDbGetDialogsResult> get_dialogs(FolderId folder_id, int64 order, DialogId dialog_id, int32 limit) final {
SCOPE_EXIT {
get_dialogs_stmt_.reset();
};
@ -263,7 +262,7 @@ class DialogDbImpl : public DialogDbSyncInterface {
}
Result<vector<NotificationGroupKey>> get_notification_groups_by_last_notification_date(
NotificationGroupKey notification_group_key, int32 limit) override {
NotificationGroupKey notification_group_key, int32 limit) final {
auto &stmt = get_notification_groups_by_last_notification_date_stmt_;
SCOPE_EXIT {
stmt.reset();
@ -285,10 +284,10 @@ class DialogDbImpl : public DialogDbSyncInterface {
return std::move(notification_groups);
}
Status begin_transaction() override {
Status begin_transaction() final {
return db_.begin_transaction();
}
Status commit_transaction() override {
Status commit_transaction() final {
return db_.commit_transaction();
}
@ -314,14 +313,14 @@ class DialogDbImpl : public DialogDbSyncInterface {
std::shared_ptr<DialogDbSyncSafeInterface> create_dialog_db_sync(
std::shared_ptr<SqliteConnectionSafe> sqlite_connection) {
class DialogDbSyncSafe : public DialogDbSyncSafeInterface {
class DialogDbSyncSafe final : public DialogDbSyncSafeInterface {
public:
explicit DialogDbSyncSafe(std::shared_ptr<SqliteConnectionSafe> sqlite_connection)
: lsls_db_([safe_connection = std::move(sqlite_connection)] {
return make_unique<DialogDbImpl>(safe_connection->get().clone());
}) {
}
DialogDbSyncInterface &get() override {
DialogDbSyncInterface &get() final {
return *lsls_db_.get();
}
@ -331,48 +330,47 @@ std::shared_ptr<DialogDbSyncSafeInterface> create_dialog_db_sync(
return std::make_shared<DialogDbSyncSafe>(std::move(sqlite_connection));
}
class DialogDbAsync : public DialogDbAsyncInterface {
class DialogDbAsync final : public DialogDbAsyncInterface {
public:
DialogDbAsync(std::shared_ptr<DialogDbSyncSafeInterface> sync_db, int32 scheduler_id) {
impl_ = create_actor_on_scheduler<Impl>("DialogDbActor", scheduler_id, std::move(sync_db));
}
void add_dialog(DialogId dialog_id, FolderId folder_id, int64 order, BufferSlice data,
vector<NotificationGroupKey> notification_groups, Promise<> promise) override {
vector<NotificationGroupKey> notification_groups, Promise<> promise) final {
send_closure(impl_, &Impl::add_dialog, dialog_id, folder_id, order, std::move(data), std::move(notification_groups),
std::move(promise));
}
void get_notification_groups_by_last_notification_date(NotificationGroupKey notification_group_key, int32 limit,
Promise<vector<NotificationGroupKey>> promise) override {
Promise<vector<NotificationGroupKey>> promise) final {
send_closure(impl_, &Impl::get_notification_groups_by_last_notification_date, notification_group_key, limit,
std::move(promise));
}
void get_notification_group(NotificationGroupId notification_group_id,
Promise<NotificationGroupKey> promise) override {
void get_notification_group(NotificationGroupId notification_group_id, Promise<NotificationGroupKey> promise) final {
send_closure(impl_, &Impl::get_notification_group, notification_group_id, std::move(promise));
}
void get_secret_chat_count(FolderId folder_id, Promise<int32> promise) override {
void get_secret_chat_count(FolderId folder_id, Promise<int32> promise) final {
send_closure(impl_, &Impl::get_secret_chat_count, folder_id, std::move(promise));
}
void get_dialog(DialogId dialog_id, Promise<BufferSlice> promise) override {
void get_dialog(DialogId dialog_id, Promise<BufferSlice> promise) final {
send_closure_later(impl_, &Impl::get_dialog, dialog_id, std::move(promise));
}
void get_dialogs(FolderId folder_id, int64 order, DialogId dialog_id, int32 limit,
Promise<DialogDbGetDialogsResult> promise) override {
Promise<DialogDbGetDialogsResult> promise) final {
send_closure_later(impl_, &Impl::get_dialogs, folder_id, order, dialog_id, limit, std::move(promise));
}
void close(Promise<> promise) override {
void close(Promise<> promise) final {
send_closure_later(impl_, &Impl::close, std::move(promise));
}
private:
class Impl : public Actor {
class Impl final : public Actor {
public:
explicit Impl(std::shared_ptr<DialogDbSyncSafeInterface> sync_db_safe) : sync_db_safe_(std::move(sync_db_safe)) {
}
@ -474,11 +472,11 @@ class DialogDbAsync : public DialogDbAsyncInterface {
cancel_timeout();
}
void timeout_expired() override {
void timeout_expired() final {
do_flush();
}
void start_up() override {
void start_up() final {
sync_db_ = &sync_db_safe_->get();
}
};

View File

@ -261,7 +261,7 @@ void FileReferenceManager::send_query(Destination dest, FileSourceId file_source
file_sources_[file_source_id.get()].visit(overloaded(
[&](const FileSourceMessage &source) {
send_closure_later(G()->messages_manager(), &MessagesManager::get_message_from_server, source.full_message_id,
std::move(promise), nullptr);
std::move(promise), "FileSourceMessage", nullptr);
},
[&](const FileSourceUserPhoto &source) {
send_closure_later(G()->contacts_manager(), &ContactsManager::reload_user_profile_photo, source.user_id,

View File

@ -33,7 +33,7 @@ class Td;
extern int VERBOSITY_NAME(file_references);
class FileReferenceManager : public Actor {
class FileReferenceManager final : public Actor {
public:
static bool is_file_reference_error(const Status &error);
static size_t get_file_reference_error_pos(const Status &error);

View File

@ -61,17 +61,17 @@ class WebPagesManager;
namespace td {
class Global : public ActorContext {
class Global final : public ActorContext {
public:
Global();
~Global() override;
~Global() final;
Global(const Global &) = delete;
Global &operator=(const Global &) = delete;
Global(Global &&other) = delete;
Global &operator=(Global &&other) = delete;
static constexpr int32 ID = -572104940;
int32 get_id() const override {
int32 get_id() const final {
return ID;
}

File diff suppressed because it is too large Load Diff

View File

@ -24,19 +24,20 @@
#include "td/utils/Status.h"
#include <unordered_map>
#include <utility>
namespace td {
class Td;
class GroupCallManager : public Actor {
class GroupCallManager final : public Actor {
public:
GroupCallManager(Td *td, ActorShared<> parent);
GroupCallManager(const GroupCallManager &) = delete;
GroupCallManager &operator=(const GroupCallManager &) = delete;
GroupCallManager(GroupCallManager &&) = delete;
GroupCallManager &operator=(GroupCallManager &&) = delete;
~GroupCallManager() override;
~GroupCallManager() final;
void memory_cleanup();
@ -71,7 +72,8 @@ class GroupCallManager : public Actor {
void join_group_call(GroupCallId group_call_id, DialogId as_dialog_id, int32 audio_source, string &&payload,
bool is_muted, bool is_my_video_enabled, const string &invite_hash, Promise<string> &&promise);
void start_group_call_screen_sharing(GroupCallId group_call_id, string &&payload, Promise<string> &&promise);
void start_group_call_screen_sharing(GroupCallId group_call_id, int32 audio_source, string &&payload,
Promise<string> &&promise);
void end_group_call_screen_sharing(GroupCallId group_call_id, Promise<Unit> &&promise);
@ -151,7 +153,7 @@ class GroupCallManager : public Actor {
static constexpr int32 CHECK_GROUP_CALL_IS_JOINED_TIMEOUT = 10;
static constexpr size_t MAX_TITLE_LENGTH = 64; // server side limit for group call/call record title length
void tear_down() override;
void tear_down() final;
void memory_cleanup(bool full);
@ -220,6 +222,8 @@ class GroupCallManager : public Actor {
static bool get_group_call_has_recording(const GroupCall *group_call);
static bool get_group_call_can_enable_video(const GroupCall *group_call);
bool need_group_call_participants(InputGroupCallId input_group_call_id) const;
bool need_group_call_participants(InputGroupCallId input_group_call_id, const GroupCall *group_call) const;
@ -228,7 +232,8 @@ class GroupCallManager : public Actor {
void sync_group_call_participants(InputGroupCallId input_group_call_id);
void on_sync_group_call_participants_failed(InputGroupCallId input_group_call_id);
void on_sync_group_call_participants(InputGroupCallId input_group_call_id,
Result<tl_object_ptr<telegram_api::phone_groupCall>> &&result);
GroupCallParticipantOrder get_real_participant_order(bool can_self_unmute, const GroupCallParticipant &participant,
const GroupCallParticipants *participants) const;
@ -248,7 +253,9 @@ class GroupCallManager : public Actor {
void update_group_call_participants_order(InputGroupCallId input_group_call_id, bool can_self_unmute,
GroupCallParticipants *participants, const char *source);
int process_group_call_participant(InputGroupCallId group_call_id, GroupCallParticipant &&participant);
// returns participant_count_diff and video_participant_count_diff
std::pair<int32, int32> process_group_call_participant(InputGroupCallId group_call_id,
GroupCallParticipant &&participant);
void on_add_group_call_participant(InputGroupCallId input_group_call_id, DialogId participant_dialog_id);
@ -345,6 +352,8 @@ class GroupCallManager : public Actor {
bool set_group_call_participant_count(GroupCall *group_call, int32 count, const char *source,
bool force_update = false);
bool set_group_call_unmuted_video_count(GroupCall *group_call, int32 count, const char *source);
void update_group_call_dialog(const GroupCall *group_call, const char *source, bool force);
vector<td_api::object_ptr<td_api::groupCallRecentSpeaker>> get_recent_speakers(const GroupCall *group_call,

View File

@ -25,7 +25,6 @@ GroupCallParticipant::GroupCallParticipant(const tl_object_ptr<telegram_api::gro
server_is_muted_by_themselves = participant->can_self_unmute_;
server_is_muted_by_admin = participant->muted_ && !participant->can_self_unmute_;
server_is_muted_locally = participant->muted_by_you_;
can_enable_video = participant->video_joined_;
is_self = participant->self_;
if ((participant->flags_ & telegram_api::groupCallParticipant::VOLUME_MASK) != 0) {
volume_level = participant->volume_;
@ -58,10 +57,17 @@ GroupCallParticipant::GroupCallParticipant(const tl_object_ptr<telegram_api::gro
version = call_version;
if (participant->video_ != nullptr) {
video_payload = get_group_call_video_payload(participant->video_.get());
video_payload = GroupCallVideoPayload(participant->video_.get());
}
if (participant->presentation_ != nullptr) {
presentation_payload = get_group_call_video_payload(participant->presentation_.get());
if (participant->presentation_->flags_ & telegram_api::groupCallParticipantVideo::AUDIO_SOURCE_MASK) {
presentation_audio_source = participant->presentation_->audio_source_;
}
presentation_payload = GroupCallVideoPayload(participant->presentation_.get());
}
if (is_just_joined && get_has_video()) {
video_diff++;
}
}
@ -78,7 +84,8 @@ GroupCallParticipantOrder GroupCallParticipant::get_real_order(bool can_self_unm
}
auto sort_raise_hand_rating = can_self_unmute ? raise_hand_rating : 0;
auto sort_joined_date = joined_date_asc ? std::numeric_limits<int32>::max() - joined_date : joined_date;
return GroupCallParticipantOrder(sort_active_date, sort_raise_hand_rating, sort_joined_date);
bool has_video = !video_payload.is_empty() || !presentation_payload.is_empty();
return GroupCallParticipantOrder(has_video, sort_active_date, sort_raise_hand_rating, sort_joined_date);
}
bool GroupCallParticipant::get_is_muted_by_themselves() const {
@ -105,6 +112,10 @@ bool GroupCallParticipant::get_is_hand_raised() const {
return have_pending_is_hand_raised ? pending_is_hand_raised : raise_hand_rating != 0;
}
int32 GroupCallParticipant::get_has_video() const {
return video_payload.is_empty() && presentation_payload.is_empty() ? 0 : 1;
}
void GroupCallParticipant::update_from(const GroupCallParticipant &old_participant) {
CHECK(!old_participant.is_min);
if (joined_date < old_participant.joined_date) {
@ -255,9 +266,9 @@ td_api::object_ptr<td_api::groupCallParticipant> GroupCallParticipant::get_group
}
return td_api::make_object<td_api::groupCallParticipant>(
td->messages_manager_->get_message_sender_object(dialog_id), audio_source, can_enable_video,
get_group_call_participant_video_info_object(video_payload),
get_group_call_participant_video_info_object(presentation_payload), about, is_self, is_speaking,
td->messages_manager_->get_message_sender_object(dialog_id), audio_source, presentation_audio_source,
video_payload.get_group_call_participant_video_info_object(),
presentation_payload.get_group_call_participant_video_info_object(), about, is_self, is_speaking,
get_is_hand_raised(), can_be_muted_for_all_users, can_be_unmuted_for_all_users, can_be_muted_only_for_self,
can_be_unmuted_only_for_self, get_is_muted_for_all_users(), get_is_muted_locally(), get_is_muted_by_themselves(),
get_volume_level(), order.get_group_call_participant_order_object());
@ -265,7 +276,7 @@ td_api::object_ptr<td_api::groupCallParticipant> GroupCallParticipant::get_group
bool operator==(const GroupCallParticipant &lhs, const GroupCallParticipant &rhs) {
return lhs.dialog_id == rhs.dialog_id && lhs.audio_source == rhs.audio_source &&
lhs.can_enable_video == rhs.can_enable_video && lhs.video_payload == rhs.video_payload &&
lhs.presentation_audio_source == rhs.presentation_audio_source && lhs.video_payload == rhs.video_payload &&
lhs.presentation_payload == rhs.presentation_payload && lhs.about == rhs.about && lhs.is_self == rhs.is_self &&
lhs.is_speaking == rhs.is_speaking && lhs.get_is_hand_raised() == rhs.get_is_hand_raised() &&
lhs.can_be_muted_for_all_users == rhs.can_be_muted_for_all_users &&

View File

@ -25,11 +25,11 @@ struct GroupCallParticipant {
GroupCallVideoPayload video_payload;
GroupCallVideoPayload presentation_payload;
int32 audio_source = 0;
int32 presentation_audio_source = 0;
int32 joined_date = 0;
int32 active_date = 0;
int32 volume_level = 10000;
int64 raise_hand_rating = 0;
bool can_enable_video = false;
bool is_volume_level_local = false;
bool server_is_muted_by_themselves = false;
bool server_is_muted_by_admin = false;
@ -45,6 +45,7 @@ struct GroupCallParticipant {
bool is_fake = false;
bool is_just_joined = false;
bool is_speaking = false;
int32 video_diff = 0;
int32 local_active_date = 0;
GroupCallParticipantOrder order;
int32 version = 0;
@ -95,6 +96,8 @@ struct GroupCallParticipant {
bool get_is_hand_raised() const;
int32 get_has_video() const;
td_api::object_ptr<td_api::groupCallParticipant> get_group_call_participant_object(Td *td) const;
};

View File

@ -15,11 +15,11 @@
namespace td {
GroupCallParticipantOrder GroupCallParticipantOrder::min() {
return GroupCallParticipantOrder(0, 0, 1);
return GroupCallParticipantOrder(false, 0, 0, 1);
}
GroupCallParticipantOrder GroupCallParticipantOrder::max() {
return GroupCallParticipantOrder(std::numeric_limits<int32>::max(), std::numeric_limits<int64>::max(),
return GroupCallParticipantOrder(true, std::numeric_limits<int32>::max(), std::numeric_limits<int64>::max(),
std::numeric_limits<int32>::max());
}
@ -31,13 +31,13 @@ string GroupCallParticipantOrder::get_group_call_participant_order_object() cons
if (!is_valid()) {
return string();
}
return PSTRING() << lpad0(to_string(active_date), 10) << lpad0(to_string(raise_hand_rating), 19)
<< lpad0(to_string(joined_date), 10);
return PSTRING() << (has_video_ ? '1' : '0') << lpad0(to_string(active_date_), 10)
<< lpad0(to_string(raise_hand_rating_), 19) << lpad0(to_string(joined_date_), 10);
}
bool operator==(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs) {
return lhs.active_date == rhs.active_date && lhs.joined_date == rhs.joined_date &&
lhs.raise_hand_rating == rhs.raise_hand_rating;
return lhs.has_video_ == rhs.has_video_ && lhs.active_date_ == rhs.active_date_ &&
lhs.joined_date_ == rhs.joined_date_ && lhs.raise_hand_rating_ == rhs.raise_hand_rating_;
}
bool operator!=(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs) {
@ -45,8 +45,10 @@ bool operator!=(const GroupCallParticipantOrder &lhs, const GroupCallParticipant
}
bool operator<(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs) {
return std::tie(lhs.active_date, lhs.raise_hand_rating, lhs.joined_date) <
std::tie(rhs.active_date, rhs.raise_hand_rating, rhs.joined_date);
auto lhs_has_video_ = static_cast<int32>(lhs.has_video_);
auto rhs_has_video_ = static_cast<int32>(rhs.has_video_);
return std::tie(lhs_has_video_, lhs.active_date_, lhs.raise_hand_rating_, lhs.joined_date_) <
std::tie(rhs_has_video_, rhs.active_date_, rhs.raise_hand_rating_, rhs.joined_date_);
}
bool operator<=(const GroupCallParticipantOrder &lhs, const GroupCallParticipantOrder &rhs) {
@ -63,9 +65,9 @@ bool operator>=(const GroupCallParticipantOrder &lhs, const GroupCallParticipant
StringBuilder &operator<<(StringBuilder &string_builder,
const GroupCallParticipantOrder &group_call_participant_order) {
return string_builder << group_call_participant_order.active_date << '/'
<< group_call_participant_order.raise_hand_rating << '/'
<< group_call_participant_order.joined_date;
return string_builder << group_call_participant_order.has_video_ << '/' << group_call_participant_order.active_date_
<< '/' << group_call_participant_order.raise_hand_rating_ << '/'
<< group_call_participant_order.joined_date_;
}
} // namespace td

View File

@ -12,9 +12,10 @@
namespace td {
class GroupCallParticipantOrder {
int32 active_date = 0;
int32 joined_date = 0;
int64 raise_hand_rating = 0;
bool has_video_ = false;
int32 active_date_ = 0;
int32 joined_date_ = 0;
int64 raise_hand_rating_ = 0;
friend StringBuilder &operator<<(StringBuilder &string_builder,
const GroupCallParticipantOrder &group_call_participant_order);
@ -26,8 +27,11 @@ class GroupCallParticipantOrder {
public:
GroupCallParticipantOrder() = default;
GroupCallParticipantOrder(int32 active_date, int64 raise_hand_rating, int32 joined_date)
: active_date(active_date), joined_date(joined_date), raise_hand_rating(raise_hand_rating) {
GroupCallParticipantOrder(bool has_video, int32 active_date, int64 raise_hand_rating, int32 joined_date)
: has_video_(has_video)
, active_date_(active_date)
, joined_date_(joined_date)
, raise_hand_rating_(raise_hand_rating) {
}
static GroupCallParticipantOrder min();
@ -36,6 +40,10 @@ class GroupCallParticipantOrder {
bool is_valid() const;
bool has_video() const {
return has_video_;
}
string get_group_call_participant_order_object() const;
};

View File

@ -10,39 +10,52 @@
namespace td {
static bool operator==(const GroupCallVideoSourceGroup &lhs, const GroupCallVideoSourceGroup &rhs) {
return lhs.semantics == rhs.semantics && lhs.source_ids == rhs.source_ids;
}
bool operator==(const GroupCallVideoPayload &lhs, const GroupCallVideoPayload &rhs) {
return lhs.source_groups == rhs.source_groups && lhs.endpoint == rhs.endpoint && lhs.is_paused == rhs.is_paused;
if (lhs.source_groups_.size() != rhs.source_groups_.size() || lhs.endpoint_ != rhs.endpoint_ ||
lhs.is_paused_ != rhs.is_paused_) {
return false;
}
for (size_t i = 0; i < lhs.source_groups_.size(); i++) {
if (lhs.source_groups_[i].semantics_ != rhs.source_groups_[i].semantics_ ||
lhs.source_groups_[i].source_ids_ != rhs.source_groups_[i].source_ids_) {
return false;
}
}
return true;
}
static td_api::object_ptr<td_api::groupCallVideoSourceGroup> get_group_call_video_source_group_object(
const GroupCallVideoSourceGroup &group) {
return td_api::make_object<td_api::groupCallVideoSourceGroup>(group.semantics, vector<int32>(group.source_ids));
bool GroupCallVideoPayload::is_empty() const {
return endpoint_.empty() || source_groups_.empty();
}
td_api::object_ptr<td_api::groupCallParticipantVideoInfo> get_group_call_participant_video_info_object(
const GroupCallVideoPayload &payload) {
if (payload.endpoint.empty() || payload.source_groups.empty()) {
td_api::object_ptr<td_api::groupCallParticipantVideoInfo>
GroupCallVideoPayload::get_group_call_participant_video_info_object() const {
if (is_empty()) {
return nullptr;
}
auto get_group_call_video_source_group_object = [](const GroupCallVideoSourceGroup &group) {
return td_api::make_object<td_api::groupCallVideoSourceGroup>(group.semantics_, vector<int32>(group.source_ids_));
};
return td_api::make_object<td_api::groupCallParticipantVideoInfo>(
transform(payload.source_groups, get_group_call_video_source_group_object), payload.endpoint, payload.is_paused);
transform(source_groups_, get_group_call_video_source_group_object), endpoint_, is_paused_);
}
GroupCallVideoPayload get_group_call_video_payload(const telegram_api::groupCallParticipantVideo *video) {
GroupCallVideoPayload result;
result.endpoint = video->endpoint_;
result.source_groups = transform(video->source_groups_, [](auto &&source_group) {
GroupCallVideoPayload::GroupCallVideoPayload(const telegram_api::groupCallParticipantVideo *video) {
if (video == nullptr) {
return;
}
endpoint_ = video->endpoint_;
source_groups_ = transform(video->source_groups_, [](auto &&source_group) {
GroupCallVideoSourceGroup result;
result.semantics = source_group->semantics_;
result.source_ids = source_group->sources_;
result.semantics_ = source_group->semantics_;
result.source_ids_ = source_group->sources_;
return result;
});
result.is_paused = video->paused_;
return result;
if (!is_empty()) {
is_paused_ = video->paused_;
}
}
} // namespace td

View File

@ -13,22 +13,28 @@
namespace td {
struct GroupCallVideoSourceGroup {
string semantics;
vector<int32> source_ids;
};
class GroupCallVideoPayload {
struct GroupCallVideoSourceGroup {
string semantics_;
vector<int32> source_ids_;
};
struct GroupCallVideoPayload {
vector<GroupCallVideoSourceGroup> source_groups;
string endpoint;
bool is_paused = false;
vector<GroupCallVideoSourceGroup> source_groups_;
string endpoint_;
bool is_paused_ = false;
friend bool operator==(const GroupCallVideoPayload &lhs, const GroupCallVideoPayload &rhs);
public:
GroupCallVideoPayload() = default;
explicit GroupCallVideoPayload(const telegram_api::groupCallParticipantVideo *video);
bool is_empty() const;
td_api::object_ptr<td_api::groupCallParticipantVideoInfo> get_group_call_participant_video_info_object() const;
};
bool operator==(const GroupCallVideoPayload &lhs, const GroupCallVideoPayload &rhs);
td_api::object_ptr<td_api::groupCallParticipantVideoInfo> get_group_call_participant_video_info_object(
const GroupCallVideoPayload &payload);
GroupCallVideoPayload get_group_call_video_payload(const telegram_api::groupCallParticipantVideo *video);
} // namespace td

View File

@ -15,7 +15,7 @@
namespace td {
class HashtagHints : public Actor {
class HashtagHints final : public Actor {
public:
HashtagHints(string mode, ActorShared<> parent);
@ -35,7 +35,7 @@ class HashtagHints : public Actor {
string get_key() const;
void start_up() override;
void start_up() final;
void hashtag_used_impl(const string &hashtag);
void from_db(Result<string> data, bool dummy);

View File

@ -60,7 +60,7 @@
namespace td {
class GetInlineBotResultsQuery : public Td::ResultHandler {
class GetInlineBotResultsQuery final : public Td::ResultHandler {
Promise<Unit> promise_;
DialogId dialog_id_;
UserId bot_user_id_;
@ -93,7 +93,7 @@ class GetInlineBotResultsQuery : public Td::ResultHandler {
return result;
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::messages_getInlineBotResults>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -104,7 +104,7 @@ class GetInlineBotResultsQuery : public Td::ResultHandler {
promise_.set_value(Unit());
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
if (status.code() == NetQuery::Canceled) {
status = Status::Error(406, "Request canceled");
} else if (status.message() == "BOT_RESPONSE_TIMEOUT") {
@ -117,7 +117,7 @@ class GetInlineBotResultsQuery : public Td::ResultHandler {
}
};
class SetInlineBotResultsQuery : public Td::ResultHandler {
class SetInlineBotResultsQuery final : public Td::ResultHandler {
Promise<Unit> promise_;
public:
@ -147,7 +147,7 @@ class SetInlineBotResultsQuery : public Td::ResultHandler {
std::move(inline_bot_switch_pm))));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::messages_setInlineBotResults>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -160,7 +160,7 @@ class SetInlineBotResultsQuery : public Td::ResultHandler {
promise_.set_value(Unit());
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
promise_.set_error(std::move(status));
}
};

View File

@ -35,7 +35,7 @@ class Td;
class Game;
class InlineQueriesManager : public Actor {
class InlineQueriesManager final : public Actor {
public:
InlineQueriesManager(Td *td, ActorShared<> parent);
@ -113,9 +113,9 @@ class InlineQueriesManager : public Actor {
static void on_drop_inline_query_result_timeout_callback(void *inline_queries_manager_ptr, int64 query_hash);
void loop() override;
void loop() final;
void tear_down() override;
void tear_down() final;
void memory_cleanup(bool full);

View File

@ -135,7 +135,7 @@ tl_object_ptr<telegram_api::JSONValue> convert_json_value(td_api::object_ptr<td_
namespace {
class JsonableJsonValue : public Jsonable {
class JsonableJsonValue final : public Jsonable {
public:
explicit JsonableJsonValue(const td_api::JsonValue *json_value) : json_value_(json_value) {
}

View File

@ -27,7 +27,7 @@ namespace td {
class SqliteKeyValue;
class LanguagePackManager : public NetQueryCallback {
class LanguagePackManager final : public NetQueryCallback {
public:
explicit LanguagePackManager(ActorShared<> parent) : parent_(std::move(parent)) {
}
@ -35,7 +35,7 @@ class LanguagePackManager : public NetQueryCallback {
LanguagePackManager &operator=(const LanguagePackManager &) = delete;
LanguagePackManager(LanguagePackManager &&) = delete;
LanguagePackManager &operator=(LanguagePackManager &&) = delete;
~LanguagePackManager() override;
~LanguagePackManager() final;
static bool check_language_pack_name(Slice name);
@ -188,11 +188,11 @@ class LanguagePackManager : public NetQueryCallback {
Status do_delete_language(string language_code);
void on_result(NetQueryPtr query) override;
void on_result(NetQueryPtr query) final;
void start_up() override;
void hangup() override;
void tear_down() override;
void start_up() final;
void hangup() final;
void tear_down() final;
Container<Promise<NetQueryPtr>> container_;
void send_with_promise(NetQueryPtr query, Promise<NetQueryPtr> promise);

View File

@ -64,13 +64,13 @@ static bool is_valid_username(Slice username) {
return true;
}
class LinkManager::InternalLinkActiveSessions : public InternalLink {
class LinkManager::InternalLinkActiveSessions final : public InternalLink {
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
return td_api::make_object<td_api::internalLinkTypeActiveSessions>();
}
};
class LinkManager::InternalLinkAuthenticationCode : public InternalLink {
class LinkManager::InternalLinkAuthenticationCode final : public InternalLink {
string code_;
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
@ -82,7 +82,7 @@ class LinkManager::InternalLinkAuthenticationCode : public InternalLink {
}
};
class LinkManager::InternalLinkBackground : public InternalLink {
class LinkManager::InternalLinkBackground final : public InternalLink {
string background_name_;
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
@ -94,7 +94,7 @@ class LinkManager::InternalLinkBackground : public InternalLink {
}
};
class LinkManager::InternalLinkBotStart : public InternalLink {
class LinkManager::InternalLinkBotStart final : public InternalLink {
string bot_username_;
string start_parameter_;
@ -108,7 +108,7 @@ class LinkManager::InternalLinkBotStart : public InternalLink {
}
};
class LinkManager::InternalLinkBotStartInGroup : public InternalLink {
class LinkManager::InternalLinkBotStartInGroup final : public InternalLink {
string bot_username_;
string start_parameter_;
@ -122,13 +122,13 @@ class LinkManager::InternalLinkBotStartInGroup : public InternalLink {
}
};
class LinkManager::InternalLinkChangePhoneNumber : public InternalLink {
class LinkManager::InternalLinkChangePhoneNumber final : public InternalLink {
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
return td_api::make_object<td_api::internalLinkTypeChangePhoneNumber>();
}
};
class LinkManager::InternalLinkConfirmPhone : public InternalLink {
class LinkManager::InternalLinkConfirmPhone final : public InternalLink {
string hash_;
string phone_number_;
@ -142,19 +142,19 @@ class LinkManager::InternalLinkConfirmPhone : public InternalLink {
}
};
class LinkManager::InternalLinkDialogInvite : public InternalLink {
class LinkManager::InternalLinkDialogInvite final : public InternalLink {
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
return td_api::make_object<td_api::internalLinkTypeChatInvite>();
}
};
class LinkManager::InternalLinkFilterSettings : public InternalLink {
class LinkManager::InternalLinkFilterSettings final : public InternalLink {
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
return td_api::make_object<td_api::internalLinkTypeFilterSettings>();
}
};
class LinkManager::InternalLinkGame : public InternalLink {
class LinkManager::InternalLinkGame final : public InternalLink {
string bot_username_;
string game_short_name_;
@ -168,7 +168,7 @@ class LinkManager::InternalLinkGame : public InternalLink {
}
};
class LinkManager::InternalLinkLanguage : public InternalLink {
class LinkManager::InternalLinkLanguage final : public InternalLink {
string language_pack_id_;
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
@ -180,13 +180,13 @@ class LinkManager::InternalLinkLanguage : public InternalLink {
}
};
class LinkManager::InternalLinkMessage : public InternalLink {
class LinkManager::InternalLinkMessage final : public InternalLink {
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
return td_api::make_object<td_api::internalLinkTypeMessage>();
}
};
class LinkManager::InternalLinkMessageDraft : public InternalLink {
class LinkManager::InternalLinkMessageDraft final : public InternalLink {
FormattedText text_;
bool contains_link_ = false;
@ -200,7 +200,7 @@ class LinkManager::InternalLinkMessageDraft : public InternalLink {
}
};
class LinkManager::InternalLinkPassportDataRequest : public InternalLink {
class LinkManager::InternalLinkPassportDataRequest final : public InternalLink {
UserId bot_user_id_;
string scope_;
string public_key_;
@ -223,7 +223,7 @@ class LinkManager::InternalLinkPassportDataRequest : public InternalLink {
}
};
class LinkManager::InternalLinkProxy : public InternalLink {
class LinkManager::InternalLinkProxy final : public InternalLink {
string server_;
int32 port_;
td_api::object_ptr<td_api::ProxyType> type_;
@ -254,7 +254,7 @@ class LinkManager::InternalLinkProxy : public InternalLink {
}
};
class LinkManager::InternalLinkPublicDialog : public InternalLink {
class LinkManager::InternalLinkPublicDialog final : public InternalLink {
string dialog_username_;
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
@ -266,19 +266,19 @@ class LinkManager::InternalLinkPublicDialog : public InternalLink {
}
};
class LinkManager::InternalLinkQrCodeAuthentication : public InternalLink {
class LinkManager::InternalLinkQrCodeAuthentication final : public InternalLink {
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
return td_api::make_object<td_api::internalLinkTypeQrCodeAuthentication>();
}
};
class LinkManager::InternalLinkSettings : public InternalLink {
class LinkManager::InternalLinkSettings final : public InternalLink {
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
return td_api::make_object<td_api::internalLinkTypeSettings>();
}
};
class LinkManager::InternalLinkStickerSet : public InternalLink {
class LinkManager::InternalLinkStickerSet final : public InternalLink {
string sticker_set_name_;
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
@ -290,7 +290,7 @@ class LinkManager::InternalLinkStickerSet : public InternalLink {
}
};
class LinkManager::InternalLinkTheme : public InternalLink {
class LinkManager::InternalLinkTheme final : public InternalLink {
string theme_name_;
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
@ -302,19 +302,19 @@ class LinkManager::InternalLinkTheme : public InternalLink {
}
};
class LinkManager::InternalLinkThemeSettings : public InternalLink {
class LinkManager::InternalLinkThemeSettings final : public InternalLink {
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
return td_api::make_object<td_api::internalLinkTypeThemeSettings>();
}
};
class LinkManager::InternalLinkUnknownDeepLink : public InternalLink {
class LinkManager::InternalLinkUnknownDeepLink final : public InternalLink {
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
return td_api::make_object<td_api::internalLinkTypeUnknownDeepLink>();
}
};
class LinkManager::InternalLinkVoiceChat : public InternalLink {
class LinkManager::InternalLinkVoiceChat final : public InternalLink {
string dialog_username_;
string invite_hash_;
@ -328,7 +328,7 @@ class LinkManager::InternalLinkVoiceChat : public InternalLink {
}
};
class RequestUrlAuthQuery : public Td::ResultHandler {
class RequestUrlAuthQuery final : public Td::ResultHandler {
Promise<td_api::object_ptr<td_api::LoginUrlInfo>> promise_;
string url_;
DialogId dialog_id_;
@ -355,7 +355,7 @@ class RequestUrlAuthQuery : public Td::ResultHandler {
url_)));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::messages_requestUrlAuth>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -389,7 +389,7 @@ class RequestUrlAuthQuery : public Td::ResultHandler {
}
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
if (!dialog_id_.is_valid() ||
!td->messages_manager_->on_get_dialog_error(dialog_id_, status, "RequestUrlAuthQuery")) {
LOG(INFO) << "RequestUrlAuthQuery returned " << status;
@ -398,7 +398,7 @@ class RequestUrlAuthQuery : public Td::ResultHandler {
}
};
class AcceptUrlAuthQuery : public Td::ResultHandler {
class AcceptUrlAuthQuery final : public Td::ResultHandler {
Promise<td_api::object_ptr<td_api::httpUrl>> promise_;
string url_;
DialogId dialog_id_;
@ -427,7 +427,7 @@ class AcceptUrlAuthQuery : public Td::ResultHandler {
button_id, url_)));
}
void on_result(uint64 id, BufferSlice packet) override {
void on_result(uint64 id, BufferSlice packet) final {
auto result_ptr = fetch_result<telegram_api::messages_acceptUrlAuth>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
@ -450,7 +450,7 @@ class AcceptUrlAuthQuery : public Td::ResultHandler {
}
}
void on_error(uint64 id, Status status) override {
void on_error(uint64 id, Status status) final {
if (!dialog_id_.is_valid() ||
!td->messages_manager_->on_get_dialog_error(dialog_id_, status, "AcceptUrlAuthQuery")) {
LOG(INFO) << "AcceptUrlAuthQuery returned " << status;

View File

@ -23,7 +23,7 @@ namespace td {
class Td;
class LinkManager : public Actor {
class LinkManager final : public Actor {
public:
LinkManager(Td *td, ActorShared<> parent);
@ -31,7 +31,7 @@ class LinkManager : public Actor {
LinkManager &operator=(const LinkManager &) = delete;
LinkManager(LinkManager &&) = delete;
LinkManager &operator=(LinkManager &&) = delete;
~LinkManager() override;
~LinkManager() final;
class InternalLink {
public:

View File

@ -88,7 +88,7 @@
namespace td {
class MessageText : public MessageContent {
class MessageText final : public MessageContent {
public:
FormattedText text;
WebPageId web_page_id;
@ -97,12 +97,12 @@ class MessageText : public MessageContent {
MessageText(FormattedText text, WebPageId web_page_id) : text(std::move(text)), web_page_id(web_page_id) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::Text;
}
};
class MessageAnimation : public MessageContent {
class MessageAnimation final : public MessageContent {
public:
FileId file_id;
@ -112,12 +112,12 @@ class MessageAnimation : public MessageContent {
MessageAnimation(FileId file_id, FormattedText &&caption) : file_id(file_id), caption(std::move(caption)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::Animation;
}
};
class MessageAudio : public MessageContent {
class MessageAudio final : public MessageContent {
public:
FileId file_id;
@ -127,12 +127,12 @@ class MessageAudio : public MessageContent {
MessageAudio(FileId file_id, FormattedText &&caption) : file_id(file_id), caption(std::move(caption)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::Audio;
}
};
class MessageDocument : public MessageContent {
class MessageDocument final : public MessageContent {
public:
FileId file_id;
@ -142,12 +142,12 @@ class MessageDocument : public MessageContent {
MessageDocument(FileId file_id, FormattedText &&caption) : file_id(file_id), caption(std::move(caption)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::Document;
}
};
class MessagePhoto : public MessageContent {
class MessagePhoto final : public MessageContent {
public:
Photo photo;
@ -157,12 +157,12 @@ class MessagePhoto : public MessageContent {
MessagePhoto(Photo &&photo, FormattedText &&caption) : photo(std::move(photo)), caption(std::move(caption)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::Photo;
}
};
class MessageSticker : public MessageContent {
class MessageSticker final : public MessageContent {
public:
FileId file_id;
@ -170,12 +170,12 @@ class MessageSticker : public MessageContent {
explicit MessageSticker(FileId file_id) : file_id(file_id) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::Sticker;
}
};
class MessageVideo : public MessageContent {
class MessageVideo final : public MessageContent {
public:
FileId file_id;
@ -185,12 +185,12 @@ class MessageVideo : public MessageContent {
MessageVideo(FileId file_id, FormattedText &&caption) : file_id(file_id), caption(std::move(caption)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::Video;
}
};
class MessageVoiceNote : public MessageContent {
class MessageVoiceNote final : public MessageContent {
public:
FileId file_id;
@ -202,12 +202,12 @@ class MessageVoiceNote : public MessageContent {
: file_id(file_id), caption(std::move(caption)), is_listened(is_listened) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::VoiceNote;
}
};
class MessageContact : public MessageContent {
class MessageContact final : public MessageContent {
public:
Contact contact;
@ -215,12 +215,12 @@ class MessageContact : public MessageContent {
explicit MessageContact(Contact &&contact) : contact(std::move(contact)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::Contact;
}
};
class MessageLocation : public MessageContent {
class MessageLocation final : public MessageContent {
public:
Location location;
@ -228,12 +228,12 @@ class MessageLocation : public MessageContent {
explicit MessageLocation(Location &&location) : location(std::move(location)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::Location;
}
};
class MessageVenue : public MessageContent {
class MessageVenue final : public MessageContent {
public:
Venue venue;
@ -241,12 +241,12 @@ class MessageVenue : public MessageContent {
explicit MessageVenue(Venue &&venue) : venue(std::move(venue)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::Venue;
}
};
class MessageChatCreate : public MessageContent {
class MessageChatCreate final : public MessageContent {
public:
string title;
vector<UserId> participant_user_ids;
@ -256,12 +256,12 @@ class MessageChatCreate : public MessageContent {
: title(std::move(title)), participant_user_ids(std::move(participant_user_ids)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ChatCreate;
}
};
class MessageChatChangeTitle : public MessageContent {
class MessageChatChangeTitle final : public MessageContent {
public:
string title;
@ -269,12 +269,12 @@ class MessageChatChangeTitle : public MessageContent {
explicit MessageChatChangeTitle(string &&title) : title(std::move(title)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ChatChangeTitle;
}
};
class MessageChatChangePhoto : public MessageContent {
class MessageChatChangePhoto final : public MessageContent {
public:
Photo photo;
@ -282,26 +282,26 @@ class MessageChatChangePhoto : public MessageContent {
explicit MessageChatChangePhoto(Photo &&photo) : photo(std::move(photo)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ChatChangePhoto;
}
};
class MessageChatDeletePhoto : public MessageContent {
class MessageChatDeletePhoto final : public MessageContent {
public:
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ChatDeletePhoto;
}
};
class MessageChatDeleteHistory : public MessageContent {
class MessageChatDeleteHistory final : public MessageContent {
public:
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ChatDeleteHistory;
}
};
class MessageChatAddUsers : public MessageContent {
class MessageChatAddUsers final : public MessageContent {
public:
vector<UserId> user_ids;
@ -309,19 +309,19 @@ class MessageChatAddUsers : public MessageContent {
explicit MessageChatAddUsers(vector<UserId> &&user_ids) : user_ids(std::move(user_ids)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ChatAddUsers;
}
};
class MessageChatJoinedByLink : public MessageContent {
class MessageChatJoinedByLink final : public MessageContent {
public:
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ChatJoinedByLink;
}
};
class MessageChatDeleteUser : public MessageContent {
class MessageChatDeleteUser final : public MessageContent {
public:
UserId user_id;
@ -329,12 +329,12 @@ class MessageChatDeleteUser : public MessageContent {
explicit MessageChatDeleteUser(UserId user_id) : user_id(user_id) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ChatDeleteUser;
}
};
class MessageChatMigrateTo : public MessageContent {
class MessageChatMigrateTo final : public MessageContent {
public:
ChannelId migrated_to_channel_id;
@ -342,12 +342,12 @@ class MessageChatMigrateTo : public MessageContent {
explicit MessageChatMigrateTo(ChannelId migrated_to_channel_id) : migrated_to_channel_id(migrated_to_channel_id) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ChatMigrateTo;
}
};
class MessageChannelCreate : public MessageContent {
class MessageChannelCreate final : public MessageContent {
public:
string title;
@ -355,12 +355,12 @@ class MessageChannelCreate : public MessageContent {
explicit MessageChannelCreate(string &&title) : title(std::move(title)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ChannelCreate;
}
};
class MessageChannelMigrateFrom : public MessageContent {
class MessageChannelMigrateFrom final : public MessageContent {
public:
string title;
ChatId migrated_from_chat_id;
@ -370,12 +370,12 @@ class MessageChannelMigrateFrom : public MessageContent {
: title(std::move(title)), migrated_from_chat_id(migrated_from_chat_id) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ChannelMigrateFrom;
}
};
class MessagePinMessage : public MessageContent {
class MessagePinMessage final : public MessageContent {
public:
MessageId message_id;
@ -383,12 +383,12 @@ class MessagePinMessage : public MessageContent {
explicit MessagePinMessage(MessageId message_id) : message_id(message_id) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::PinMessage;
}
};
class MessageGame : public MessageContent {
class MessageGame final : public MessageContent {
public:
Game game;
@ -396,12 +396,12 @@ class MessageGame : public MessageContent {
explicit MessageGame(Game &&game) : game(std::move(game)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::Game;
}
};
class MessageGameScore : public MessageContent {
class MessageGameScore final : public MessageContent {
public:
MessageId game_message_id;
int64 game_id;
@ -412,19 +412,19 @@ class MessageGameScore : public MessageContent {
: game_message_id(game_message_id), game_id(game_id), score(score) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::GameScore;
}
};
class MessageScreenshotTaken : public MessageContent {
class MessageScreenshotTaken final : public MessageContent {
public:
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ScreenshotTaken;
}
};
class MessageChatSetTtl : public MessageContent {
class MessageChatSetTtl final : public MessageContent {
public:
int32 ttl;
@ -432,12 +432,12 @@ class MessageChatSetTtl : public MessageContent {
explicit MessageChatSetTtl(int32 ttl) : ttl(ttl) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ChatSetTtl;
}
};
class MessageUnsupported : public MessageContent {
class MessageUnsupported final : public MessageContent {
public:
static constexpr int32 CURRENT_VERSION = 7;
int32 version = CURRENT_VERSION;
@ -446,12 +446,12 @@ class MessageUnsupported : public MessageContent {
explicit MessageUnsupported(int32 version) : version(version) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::Unsupported;
}
};
class MessageCall : public MessageContent {
class MessageCall final : public MessageContent {
public:
int64 call_id;
int32 duration;
@ -463,12 +463,12 @@ class MessageCall : public MessageContent {
: call_id(call_id), duration(duration), discard_reason(discard_reason), is_video(is_video) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::Call;
}
};
class MessageInvoice : public MessageContent {
class MessageInvoice final : public MessageContent {
public:
InputInvoice input_invoice;
@ -476,12 +476,12 @@ class MessageInvoice : public MessageContent {
explicit MessageInvoice(InputInvoice &&input_invoice) : input_invoice(std::move(input_invoice)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::Invoice;
}
};
class MessagePaymentSuccessful : public MessageContent {
class MessagePaymentSuccessful final : public MessageContent {
public:
DialogId invoice_dialog_id;
MessageId invoice_message_id;
@ -504,12 +504,12 @@ class MessagePaymentSuccessful : public MessageContent {
, total_amount(total_amount) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::PaymentSuccessful;
}
};
class MessageVideoNote : public MessageContent {
class MessageVideoNote final : public MessageContent {
public:
FileId file_id;
@ -519,37 +519,37 @@ class MessageVideoNote : public MessageContent {
MessageVideoNote(FileId file_id, bool is_viewed) : file_id(file_id), is_viewed(is_viewed) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::VideoNote;
}
};
class MessageContactRegistered : public MessageContent {
class MessageContactRegistered final : public MessageContent {
public:
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ContactRegistered;
}
};
class MessageExpiredPhoto : public MessageContent {
class MessageExpiredPhoto final : public MessageContent {
public:
MessageExpiredPhoto() = default;
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ExpiredPhoto;
}
};
class MessageExpiredVideo : public MessageContent {
class MessageExpiredVideo final : public MessageContent {
public:
MessageExpiredVideo() = default;
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ExpiredVideo;
}
};
class MessageLiveLocation : public MessageContent {
class MessageLiveLocation final : public MessageContent {
public:
Location location;
int32 period = 0;
@ -574,12 +574,12 @@ class MessageLiveLocation : public MessageContent {
}
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::LiveLocation;
}
};
class MessageCustomServiceAction : public MessageContent {
class MessageCustomServiceAction final : public MessageContent {
public:
string message;
@ -587,12 +587,12 @@ class MessageCustomServiceAction : public MessageContent {
explicit MessageCustomServiceAction(string &&message) : message(std::move(message)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::CustomServiceAction;
}
};
class MessageWebsiteConnected : public MessageContent {
class MessageWebsiteConnected final : public MessageContent {
public:
string domain_name;
@ -600,12 +600,12 @@ class MessageWebsiteConnected : public MessageContent {
explicit MessageWebsiteConnected(string &&domain_name) : domain_name(std::move(domain_name)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::WebsiteConnected;
}
};
class MessagePassportDataSent : public MessageContent {
class MessagePassportDataSent final : public MessageContent {
public:
vector<SecureValueType> types;
@ -613,12 +613,12 @@ class MessagePassportDataSent : public MessageContent {
explicit MessagePassportDataSent(vector<SecureValueType> &&types) : types(std::move(types)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::PassportDataSent;
}
};
class MessagePassportDataReceived : public MessageContent {
class MessagePassportDataReceived final : public MessageContent {
public:
vector<EncryptedSecureValue> values;
EncryptedSecureCredentials credentials;
@ -628,12 +628,12 @@ class MessagePassportDataReceived : public MessageContent {
: values(std::move(values)), credentials(std::move(credentials)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::PassportDataReceived;
}
};
class MessagePoll : public MessageContent {
class MessagePoll final : public MessageContent {
public:
PollId poll_id;
@ -641,12 +641,12 @@ class MessagePoll : public MessageContent {
explicit MessagePoll(PollId poll_id) : poll_id(poll_id) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::Poll;
}
};
class MessageDice : public MessageContent {
class MessageDice final : public MessageContent {
public:
string emoji;
int32 dice_value = 0;
@ -659,7 +659,7 @@ class MessageDice : public MessageContent {
, dice_value(dice_value) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::Dice;
}
@ -676,7 +676,7 @@ class MessageDice : public MessageContent {
constexpr const char *MessageDice::DEFAULT_EMOJI;
class MessageProximityAlertTriggered : public MessageContent {
class MessageProximityAlertTriggered final : public MessageContent {
public:
DialogId traveler_dialog_id;
DialogId watcher_dialog_id;
@ -687,12 +687,12 @@ class MessageProximityAlertTriggered : public MessageContent {
: traveler_dialog_id(traveler_dialog_id), watcher_dialog_id(watcher_dialog_id), distance(distance) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::ProximityAlertTriggered;
}
};
class MessageGroupCall : public MessageContent {
class MessageGroupCall final : public MessageContent {
public:
InputGroupCallId input_group_call_id;
int32 duration = -1;
@ -703,12 +703,12 @@ class MessageGroupCall : public MessageContent {
: input_group_call_id(input_group_call_id), duration(duration), schedule_date(schedule_date) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::GroupCall;
}
};
class MessageInviteToGroupCall : public MessageContent {
class MessageInviteToGroupCall final : public MessageContent {
public:
InputGroupCallId input_group_call_id;
vector<UserId> user_ids;
@ -718,7 +718,7 @@ class MessageInviteToGroupCall : public MessageContent {
: input_group_call_id(input_group_call_id), user_ids(std::move(user_ids)) {
}
MessageContentType get_type() const override {
MessageContentType get_type() const final {
return MessageContentType::InviteToGroupCall;
}
};

View File

@ -10,7 +10,7 @@
#include "td/telegram/Dependencies.h"
#include "td/telegram/LinkManager.h"
#include "td/telegram/misc.h"
#include "td/telegram/SecretChatActor.h"
#include "td/telegram/SecretChatLayer.h"
#include "td/utils/algorithm.h"
#include "td/utils/format.h"
@ -2992,17 +2992,17 @@ vector<tl_object_ptr<secret_api::MessageEntity>> get_input_secret_message_entiti
result.push_back(make_tl_object<secret_api::messageEntityItalic>(entity.offset, entity.length));
break;
case MessageEntity::Type::Underline:
if (layer >= SecretChatActor::NEW_ENTITIES_LAYER) {
if (layer >= static_cast<int32>(SecretChatLayer::NewEntities)) {
result.push_back(make_tl_object<secret_api::messageEntityUnderline>(entity.offset, entity.length));
}
break;
case MessageEntity::Type::Strikethrough:
if (layer >= SecretChatActor::NEW_ENTITIES_LAYER) {
if (layer >= static_cast<int32>(SecretChatLayer::NewEntities)) {
result.push_back(make_tl_object<secret_api::messageEntityStrike>(entity.offset, entity.length));
}
break;
case MessageEntity::Type::BlockQuote:
if (layer >= SecretChatActor::NEW_ENTITIES_LAYER) {
if (layer >= static_cast<int32>(SecretChatLayer::NewEntities)) {
result.push_back(make_tl_object<secret_api::messageEntityBlockquote>(entity.offset, entity.length));
}
break;

View File

@ -177,7 +177,7 @@ Status drop_messages_db(SqliteDb &db, int32 version) {
return db.exec("DROP TABLE IF EXISTS messages");
}
class MessagesDbImpl : public MessagesDbSyncInterface {
class MessagesDbImpl final : public MessagesDbSyncInterface {
public:
explicit MessagesDbImpl(SqliteDb db) : db_(std::move(db)) {
init().ensure();
@ -279,7 +279,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
Status add_message(FullMessageId full_message_id, ServerMessageId unique_message_id, UserId sender_user_id,
int64 random_id, int32 ttl_expires_at, int32 index_mask, int64 search_id, string text,
NotificationId notification_id, MessageId top_thread_message_id, BufferSlice data) override {
NotificationId notification_id, MessageId top_thread_message_id, BufferSlice data) final {
LOG(INFO) << "Add " << full_message_id << " to database";
auto dialog_id = full_message_id.get_dialog_id();
auto message_id = full_message_id.get_message_id();
@ -358,7 +358,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
return Status::OK();
}
Status add_scheduled_message(FullMessageId full_message_id, BufferSlice data) override {
Status add_scheduled_message(FullMessageId full_message_id, BufferSlice data) final {
LOG(INFO) << "Add " << full_message_id << " to database";
auto dialog_id = full_message_id.get_dialog_id();
auto message_id = full_message_id.get_message_id();
@ -383,7 +383,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
return Status::OK();
}
Status delete_message(FullMessageId full_message_id) override {
Status delete_message(FullMessageId full_message_id) final {
LOG(INFO) << "Delete " << full_message_id << " from database";
auto dialog_id = full_message_id.get_dialog_id();
auto message_id = full_message_id.get_message_id();
@ -407,7 +407,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
return Status::OK();
}
Status delete_all_dialog_messages(DialogId dialog_id, MessageId from_message_id) override {
Status delete_all_dialog_messages(DialogId dialog_id, MessageId from_message_id) final {
LOG(INFO) << "Delete all messages in " << dialog_id << " up to " << from_message_id << " from database";
CHECK(dialog_id.is_valid());
CHECK(from_message_id.is_valid());
@ -423,7 +423,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
return status;
}
Status delete_dialog_messages_from_user(DialogId dialog_id, UserId sender_user_id) override {
Status delete_dialog_messages_from_user(DialogId dialog_id, UserId sender_user_id) final {
LOG(INFO) << "Delete all messages in " << dialog_id << " sent by " << sender_user_id << " from database";
CHECK(dialog_id.is_valid());
CHECK(sender_user_id.is_valid());
@ -436,7 +436,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
return Status::OK();
}
Result<BufferSlice> get_message(FullMessageId full_message_id) override {
Result<BufferSlice> get_message(FullMessageId full_message_id) final {
auto dialog_id = full_message_id.get_dialog_id();
auto message_id = full_message_id.get_message_id();
CHECK(dialog_id.is_valid());
@ -462,8 +462,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
return BufferSlice(stmt.view_blob(0));
}
Result<std::pair<DialogId, BufferSlice>> get_message_by_unique_message_id(
ServerMessageId unique_message_id) override {
Result<std::pair<DialogId, BufferSlice>> get_message_by_unique_message_id(ServerMessageId unique_message_id) final {
if (!unique_message_id.is_valid()) {
return Status::Error("Invalid unique_message_id");
}
@ -479,7 +478,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
return std::make_pair(dialog_id, BufferSlice(get_message_by_unique_message_id_stmt_.view_blob(1)));
}
Result<BufferSlice> get_message_by_random_id(DialogId dialog_id, int64 random_id) override {
Result<BufferSlice> get_message_by_random_id(DialogId dialog_id, int64 random_id) final {
SCOPE_EXIT {
get_message_by_random_id_stmt_.reset();
};
@ -493,7 +492,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
}
Result<BufferSlice> get_dialog_message_by_date(DialogId dialog_id, MessageId first_message_id,
MessageId last_message_id, int32 date) override {
MessageId last_message_id, int32 date) final {
int64 left_message_id = first_message_id.get();
int64 right_message_id = last_message_id.get();
LOG_CHECK(left_message_id <= right_message_id) << first_message_id << " " << last_message_id;
@ -557,7 +556,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
Result<std::pair<std::vector<std::pair<DialogId, BufferSlice>>, int32>> get_expiring_messages(int32 expires_from,
int32 expires_till,
int32 limit) override {
int32 limit) final {
SCOPE_EXIT {
get_expiring_messages_stmt_.reset();
get_expiring_messages_helper_stmt_.reset();
@ -591,7 +590,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
return std::make_pair(std::move(messages), next_expires_till);
}
Result<std::vector<BufferSlice>> get_messages(MessagesDbMessagesQuery query) override {
Result<std::vector<BufferSlice>> get_messages(MessagesDbMessagesQuery query) final {
if (query.index_mask != 0) {
return get_messages_from_index(query.dialog_id, query.from_message_id, query.index_mask, query.offset,
query.limit);
@ -599,12 +598,12 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
return get_messages_impl(get_messages_stmt_, query.dialog_id, query.from_message_id, query.offset, query.limit);
}
Result<std::vector<BufferSlice>> get_scheduled_messages(DialogId dialog_id, int32 limit) override {
Result<std::vector<BufferSlice>> get_scheduled_messages(DialogId dialog_id, int32 limit) final {
return get_messages_inner(get_scheduled_messages_stmt_, dialog_id, std::numeric_limits<int64>::max(), limit);
}
Result<vector<BufferSlice>> get_messages_from_notification_id(DialogId dialog_id, NotificationId from_notification_id,
int32 limit) override {
int32 limit) final {
auto &stmt = get_messages_from_notification_id_stmt_;
SCOPE_EXIT {
stmt.reset();
@ -672,7 +671,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
return sb.as_cslice().str();
}
Result<MessagesDbFtsResult> get_messages_fts(MessagesDbFtsQuery query) override {
Result<MessagesDbFtsResult> get_messages_fts(MessagesDbFtsQuery query) final {
SCOPE_EXIT {
get_messages_fts_stmt_.reset();
};
@ -745,7 +744,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
return get_messages_impl(stmt, dialog_id, from_message_id, offset, limit);
}
Result<MessagesDbCallsResult> get_calls(MessagesDbCallsQuery query) override {
Result<MessagesDbCallsResult> get_calls(MessagesDbCallsQuery query) final {
CHECK(query.index_mask != 0);
LOG_CHECK(query.index_mask < (1 << MESSAGES_DB_INDEX_COUNT)) << tag("index_mask", query.index_mask);
int index_i = -1;
@ -786,10 +785,10 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
return std::move(result);
}
Status begin_transaction() override {
Status begin_transaction() final {
return db_.begin_transaction();
}
Status commit_transaction() override {
Status commit_transaction() final {
return db_.commit_transaction();
}
@ -926,14 +925,14 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
std::shared_ptr<MessagesDbSyncSafeInterface> create_messages_db_sync(
std::shared_ptr<SqliteConnectionSafe> sqlite_connection) {
class MessagesDbSyncSafe : public MessagesDbSyncSafeInterface {
class MessagesDbSyncSafe final : public MessagesDbSyncSafeInterface {
public:
explicit MessagesDbSyncSafe(std::shared_ptr<SqliteConnectionSafe> sqlite_connection)
: lsls_db_([safe_connection = std::move(sqlite_connection)] {
return make_unique<MessagesDbImpl>(safe_connection->get().clone());
}) {
}
MessagesDbSyncInterface &get() override {
MessagesDbSyncInterface &get() final {
return *lsls_db_.get();
}
@ -943,7 +942,7 @@ std::shared_ptr<MessagesDbSyncSafeInterface> create_messages_db_sync(
return std::make_shared<MessagesDbSyncSafe>(std::move(sqlite_connection));
}
class MessagesDbAsync : public MessagesDbAsyncInterface {
class MessagesDbAsync final : public MessagesDbAsyncInterface {
public:
MessagesDbAsync(std::shared_ptr<MessagesDbSyncSafeInterface> sync_db, int32 scheduler_id) {
impl_ = create_actor_on_scheduler<Impl>("MessagesDbActor", scheduler_id, std::move(sync_db));
@ -952,74 +951,73 @@ class MessagesDbAsync : public MessagesDbAsyncInterface {
void add_message(FullMessageId full_message_id, ServerMessageId unique_message_id, UserId sender_user_id,
int64 random_id, int32 ttl_expires_at, int32 index_mask, int64 search_id, string text,
NotificationId notification_id, MessageId top_thread_message_id, BufferSlice data,
Promise<> promise) override {
Promise<> promise) final {
send_closure_later(impl_, &Impl::add_message, full_message_id, unique_message_id, sender_user_id, random_id,
ttl_expires_at, index_mask, search_id, std::move(text), notification_id, top_thread_message_id,
std::move(data), std::move(promise));
}
void add_scheduled_message(FullMessageId full_message_id, BufferSlice data, Promise<> promise) override {
void add_scheduled_message(FullMessageId full_message_id, BufferSlice data, Promise<> promise) final {
send_closure_later(impl_, &Impl::add_scheduled_message, full_message_id, std::move(data), std::move(promise));
}
void delete_message(FullMessageId full_message_id, Promise<> promise) override {
void delete_message(FullMessageId full_message_id, Promise<> promise) final {
send_closure_later(impl_, &Impl::delete_message, full_message_id, std::move(promise));
}
void delete_all_dialog_messages(DialogId dialog_id, MessageId from_message_id, Promise<> promise) override {
void delete_all_dialog_messages(DialogId dialog_id, MessageId from_message_id, Promise<> promise) final {
send_closure_later(impl_, &Impl::delete_all_dialog_messages, dialog_id, from_message_id, std::move(promise));
}
void delete_dialog_messages_from_user(DialogId dialog_id, UserId sender_user_id, Promise<> promise) override {
void delete_dialog_messages_from_user(DialogId dialog_id, UserId sender_user_id, Promise<> promise) final {
send_closure_later(impl_, &Impl::delete_dialog_messages_from_user, dialog_id, sender_user_id, std::move(promise));
}
void get_message(FullMessageId full_message_id, Promise<BufferSlice> promise) override {
void get_message(FullMessageId full_message_id, Promise<BufferSlice> promise) final {
send_closure_later(impl_, &Impl::get_message, full_message_id, std::move(promise));
}
void get_message_by_unique_message_id(ServerMessageId unique_message_id,
Promise<std::pair<DialogId, BufferSlice>> promise) override {
Promise<std::pair<DialogId, BufferSlice>> promise) final {
send_closure_later(impl_, &Impl::get_message_by_unique_message_id, unique_message_id, std::move(promise));
}
void get_message_by_random_id(DialogId dialog_id, int64 random_id, Promise<BufferSlice> promise) override {
void get_message_by_random_id(DialogId dialog_id, int64 random_id, Promise<BufferSlice> promise) final {
send_closure_later(impl_, &Impl::get_message_by_random_id, dialog_id, random_id, std::move(promise));
}
void get_dialog_message_by_date(DialogId dialog_id, MessageId first_message_id, MessageId last_message_id, int32 date,
Promise<BufferSlice> promise) override {
Promise<BufferSlice> promise) final {
send_closure_later(impl_, &Impl::get_dialog_message_by_date, dialog_id, first_message_id, last_message_id, date,
std::move(promise));
}
void get_messages(MessagesDbMessagesQuery query, Promise<std::vector<BufferSlice>> promise) override {
void get_messages(MessagesDbMessagesQuery query, Promise<std::vector<BufferSlice>> promise) final {
send_closure_later(impl_, &Impl::get_messages, std::move(query), std::move(promise));
}
void get_scheduled_messages(DialogId dialog_id, int32 limit, Promise<std::vector<BufferSlice>> promise) override {
void get_scheduled_messages(DialogId dialog_id, int32 limit, Promise<std::vector<BufferSlice>> promise) final {
send_closure_later(impl_, &Impl::get_scheduled_messages, dialog_id, limit, std::move(promise));
}
void get_messages_from_notification_id(DialogId dialog_id, NotificationId from_notification_id, int32 limit,
Promise<vector<BufferSlice>> promise) override {
Promise<vector<BufferSlice>> promise) final {
send_closure_later(impl_, &Impl::get_messages_from_notification_id, dialog_id, from_notification_id, limit,
std::move(promise));
}
void get_calls(MessagesDbCallsQuery query, Promise<MessagesDbCallsResult> promise) override {
void get_calls(MessagesDbCallsQuery query, Promise<MessagesDbCallsResult> promise) final {
send_closure_later(impl_, &Impl::get_calls, std::move(query), std::move(promise));
}
void get_messages_fts(MessagesDbFtsQuery query, Promise<MessagesDbFtsResult> promise) override {
void get_messages_fts(MessagesDbFtsQuery query, Promise<MessagesDbFtsResult> promise) final {
send_closure_later(impl_, &Impl::get_messages_fts, std::move(query), std::move(promise));
}
void get_expiring_messages(
int32 expires_from, int32 expires_till, int32 limit,
Promise<std::pair<std::vector<std::pair<DialogId, BufferSlice>>, int32>> promise) override {
void get_expiring_messages(int32 expires_from, int32 expires_till, int32 limit,
Promise<std::pair<std::vector<std::pair<DialogId, BufferSlice>>, int32>> promise) final {
send_closure_later(impl_, &Impl::get_expiring_messages, expires_from, expires_till, limit, std::move(promise));
}
void close(Promise<> promise) override {
void close(Promise<> promise) final {
send_closure_later(impl_, &Impl::close, std::move(promise));
}
void force_flush() override {
void force_flush() final {
send_closure_later(impl_, &Impl::force_flush);
}
private:
class Impl : public Actor {
class Impl final : public Actor {
public:
explicit Impl(std::shared_ptr<MessagesDbSyncSafeInterface> sync_db_safe) : sync_db_safe_(std::move(sync_db_safe)) {
}
@ -1163,11 +1161,11 @@ class MessagesDbAsync : public MessagesDbAsyncInterface {
pending_write_results_.clear();
cancel_timeout();
}
void timeout_expired() override {
void timeout_expired() final {
do_flush();
}
void start_up() override {
void start_up() final {
sync_db_ = &sync_db_safe_->get();
}
};

File diff suppressed because it is too large Load Diff

View File

@ -89,7 +89,7 @@ class MessageContent;
class MultiSequenceDispatcher;
class Td;
class MessagesManager : public Actor {
class MessagesManager final : public Actor {
public:
// static constexpr int32 MESSAGE_FLAG_IS_UNREAD = 1 << 0;
static constexpr int32 MESSAGE_FLAG_IS_OUT = 1 << 1;
@ -136,7 +136,7 @@ class MessagesManager : public Actor {
MessagesManager &operator=(const MessagesManager &) = delete;
MessagesManager(MessagesManager &&) = delete;
MessagesManager &operator=(MessagesManager &&) = delete;
~MessagesManager() override;
~MessagesManager() final;
void memory_cleanup();
@ -562,10 +562,10 @@ class MessagesManager : public Actor {
bool get_messages(DialogId dialog_id, const vector<MessageId> &message_ids, Promise<Unit> &&promise);
void get_message_from_server(FullMessageId full_message_id, Promise<Unit> &&promise,
void get_message_from_server(FullMessageId full_message_id, Promise<Unit> &&promise, const char *source,
tl_object_ptr<telegram_api::InputMessage> input_message = nullptr);
void get_messages_from_server(vector<FullMessageId> &&message_ids, Promise<Unit> &&promise,
void get_messages_from_server(vector<FullMessageId> &&message_ids, Promise<Unit> &&promise, const char *source,
tl_object_ptr<telegram_api::InputMessage> input_message = nullptr);
struct MessageThreadInfo {
@ -1208,6 +1208,7 @@ class MessagesManager : public Actor {
bool can_invite_members = false;
bool is_opened = false;
bool was_opened = false;
bool need_restore_reply_markup = true;
@ -1545,7 +1546,7 @@ class MessagesManager : public Actor {
}
};
class MessagesIterator : public MessagesIteratorBase {
class MessagesIterator final : public MessagesIteratorBase {
public:
MessagesIterator() = default;
@ -1559,7 +1560,7 @@ class MessagesManager : public Actor {
}
};
class MessagesConstIterator : public MessagesIteratorBase {
class MessagesConstIterator final : public MessagesIteratorBase {
public:
MessagesConstIterator() = default;
@ -2609,9 +2610,9 @@ class MessagesManager : public Actor {
void on_message_ttl_expired(Dialog *d, Message *m);
void on_message_ttl_expired_impl(Dialog *d, Message *m);
void start_up() override;
void loop() override;
void tear_down() override;
void start_up() final;
void loop() final;
void tear_down() final;
void create_folders();
void init();
@ -2999,7 +3000,7 @@ class MessagesManager : public Actor {
being_loaded_secret_thumbnails_; // thumbnail_file_id -> ...
// TTL
class TtlNode : private HeapNode {
class TtlNode final : private HeapNode {
public:
TtlNode(DialogId dialog_id, MessageId message_id, bool by_ttl_period)
: full_message_id_(dialog_id, message_id), by_ttl_period_(by_ttl_period) {

View File

@ -8,8 +8,7 @@
namespace td {
Result<NewPasswordState> get_new_password_state(
tl_object_ptr<telegram_api::PasswordKdfAlgo> new_algo,
Result<NewPasswordState> get_new_password_state(tl_object_ptr<telegram_api::PasswordKdfAlgo> new_algo,
tl_object_ptr<telegram_api::SecurePasswordKdfAlgo> new_secure_algo) {
NewPasswordState state;
CHECK(new_algo != nullptr);

Some files were not shown because too many files have changed in this diff Show More