1 //
2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 #include "td/telegram/InputDialogId.h"
8 
9 #include "td/telegram/ChannelId.h"
10 #include "td/telegram/ChatId.h"
11 #include "td/telegram/UserId.h"
12 
13 #include "td/utils/logging.h"
14 
15 namespace td {
16 
InputDialogId(const tl_object_ptr<telegram_api::InputPeer> & input_peer)17 InputDialogId::InputDialogId(const tl_object_ptr<telegram_api::InputPeer> &input_peer) {
18   CHECK(input_peer != nullptr);
19   switch (input_peer->get_id()) {
20     case telegram_api::inputPeerUser::ID: {
21       auto input_user = static_cast<const telegram_api::inputPeerUser *>(input_peer.get());
22       UserId user_id(input_user->user_id_);
23       if (user_id.is_valid()) {
24         dialog_id = DialogId(user_id);
25         access_hash = input_user->access_hash_;
26         return;
27       }
28       break;
29     }
30     case telegram_api::inputPeerChat::ID: {
31       auto input_chat = static_cast<const telegram_api::inputPeerChat *>(input_peer.get());
32       ChatId chat_id(input_chat->chat_id_);
33       if (chat_id.is_valid()) {
34         dialog_id = DialogId(chat_id);
35         return;
36       }
37       break;
38     }
39     case telegram_api::inputPeerChannel::ID: {
40       auto input_channel = static_cast<const telegram_api::inputPeerChannel *>(input_peer.get());
41       ChannelId channel_id(input_channel->channel_id_);
42       if (channel_id.is_valid()) {
43         dialog_id = DialogId(channel_id);
44         access_hash = input_channel->access_hash_;
45         return;
46       }
47       break;
48     }
49     default:
50       break;
51   }
52   LOG(ERROR) << "Receive " << to_string(input_peer);
53 }
54 
get_input_dialog_ids(const vector<tl_object_ptr<telegram_api::InputPeer>> & input_peers,std::unordered_set<DialogId,DialogIdHash> * added_dialog_ids)55 vector<InputDialogId> InputDialogId::get_input_dialog_ids(
56     const vector<tl_object_ptr<telegram_api::InputPeer>> &input_peers,
57     std::unordered_set<DialogId, DialogIdHash> *added_dialog_ids) {
58   std::unordered_set<DialogId, DialogIdHash> temp_added_dialog_ids;
59   if (added_dialog_ids == nullptr) {
60     added_dialog_ids = &temp_added_dialog_ids;
61   }
62   vector<InputDialogId> result;
63   result.reserve(input_peers.size());
64   for (auto &input_peer : input_peers) {
65     InputDialogId input_dialog_id(input_peer);
66     if (input_dialog_id.is_valid() && added_dialog_ids->insert(input_dialog_id.get_dialog_id()).second) {
67       result.push_back(input_dialog_id);
68     }
69   }
70   return result;
71 }
72 
get_input_dialog_peers(const vector<InputDialogId> & input_dialog_ids)73 vector<telegram_api::object_ptr<telegram_api::InputDialogPeer>> InputDialogId::get_input_dialog_peers(
74     const vector<InputDialogId> &input_dialog_ids) {
75   vector<telegram_api::object_ptr<telegram_api::InputDialogPeer>> result;
76   result.reserve(input_dialog_ids.size());
77   for (const auto &input_dialog_id : input_dialog_ids) {
78     auto input_peer = input_dialog_id.get_input_peer();
79     if (input_peer != nullptr) {
80       result.push_back(telegram_api::make_object<telegram_api::inputDialogPeer>(std::move(input_peer)));
81     }
82   }
83   return result;
84 }
85 
get_input_peers(const vector<InputDialogId> & input_dialog_ids)86 vector<telegram_api::object_ptr<telegram_api::InputPeer>> InputDialogId::get_input_peers(
87     const vector<InputDialogId> &input_dialog_ids) {
88   vector<telegram_api::object_ptr<telegram_api::InputPeer>> result;
89   result.reserve(input_dialog_ids.size());
90   for (const auto &input_dialog_id : input_dialog_ids) {
91     auto input_peer = input_dialog_id.get_input_peer();
92     CHECK(input_peer != nullptr);
93     result.push_back(std::move(input_peer));
94   }
95   return result;
96 }
97 
get_input_peer() const98 tl_object_ptr<telegram_api::InputPeer> InputDialogId::get_input_peer() const {
99   switch (dialog_id.get_type()) {
100     case DialogType::User:
101       return make_tl_object<telegram_api::inputPeerUser>(dialog_id.get_user_id().get(), access_hash);
102     case DialogType::Chat:
103       return make_tl_object<telegram_api::inputPeerChat>(dialog_id.get_chat_id().get());
104     case DialogType::Channel:
105       return make_tl_object<telegram_api::inputPeerChannel>(dialog_id.get_channel_id().get(), access_hash);
106     case DialogType::SecretChat:
107     case DialogType::None:
108       return nullptr;
109     default:
110       UNREACHABLE();
111       return nullptr;
112   }
113 }
114 
are_equivalent(const vector<InputDialogId> & lhs,const vector<InputDialogId> & rhs)115 bool InputDialogId::are_equivalent(const vector<InputDialogId> &lhs, const vector<InputDialogId> &rhs) {
116   auto lhs_it = lhs.begin();
117   auto rhs_it = rhs.begin();
118   while (lhs_it != lhs.end() || rhs_it != rhs.end()) {
119     while (lhs_it != lhs.end() && lhs_it->get_dialog_id().get_type() == DialogType::SecretChat) {
120       ++lhs_it;
121     }
122     while (rhs_it != rhs.end() && rhs_it->get_dialog_id().get_type() == DialogType::SecretChat) {
123       ++rhs_it;
124     }
125     if (lhs_it == lhs.end() || rhs_it == rhs.end()) {
126       break;
127     }
128     if (lhs_it->get_dialog_id() != rhs_it->get_dialog_id()) {
129       return false;
130     }
131     ++lhs_it;
132     ++rhs_it;
133   }
134   return lhs_it == lhs.end() && rhs_it == rhs.end();
135 }
136 
contains(const vector<InputDialogId> & input_dialog_ids,DialogId dialog_id)137 bool InputDialogId::contains(const vector<InputDialogId> &input_dialog_ids, DialogId dialog_id) {
138   for (auto &input_dialog_id : input_dialog_ids) {
139     if (input_dialog_id.get_dialog_id() == dialog_id) {
140       return true;
141     }
142   }
143   return false;
144 }
145 
146 }  // namespace td
147