mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
Make all owned MTPD types immutable.
Remove custom refcounting in mtpData, use std::shared_ptr instead.
This commit is contained in:
parent
839bf313cf
commit
3b373e236e
9 changed files with 7191 additions and 9237 deletions
|
@ -2042,7 +2042,7 @@ mtpBuffer ConnectionPrivate::ungzip(const mtpPrime *from, const mtpPrime *end) c
|
|||
return result;
|
||||
}
|
||||
stream.avail_in = packedLen;
|
||||
stream.next_in = (Bytef*)&packed._string().v[0];
|
||||
stream.next_in = const_cast<Bytef*>(reinterpret_cast<const Bytef*>(packed.c_string().v.data()));
|
||||
|
||||
stream.avail_out = 0;
|
||||
while (!stream.avail_out) {
|
||||
|
@ -2382,7 +2382,7 @@ void ConnectionPrivate::pqAnswered() {
|
|||
return restart();
|
||||
}
|
||||
|
||||
const auto &res_pq_data(res_pq.c_resPQ());
|
||||
auto &res_pq_data = res_pq.c_resPQ();
|
||||
if (res_pq_data.vnonce != _authKeyData->nonce) {
|
||||
LOG(("AuthKey Error: received nonce <> sent nonce (in res_pq)!"));
|
||||
DEBUG_LOG(("AuthKey Error: received nonce: %1, sent nonce: %2").arg(Logs::mb(&res_pq_data.vnonce, 16).str()).arg(Logs::mb(&_authKeyData->nonce, 16).str()));
|
||||
|
@ -2391,8 +2391,8 @@ void ConnectionPrivate::pqAnswered() {
|
|||
|
||||
static MTP::internal::RSAPublicKeys RSAKeys = MTP::internal::InitRSAPublicKeys();
|
||||
const MTP::internal::RSAPublicKey *rsaKey = nullptr;
|
||||
const auto &fingerPrints(res_pq.c_resPQ().vserver_public_key_fingerprints.c_vector().v);
|
||||
for (const auto &fingerPrint : fingerPrints) {
|
||||
auto &fingerPrints = res_pq.c_resPQ().vserver_public_key_fingerprints.c_vector().v;
|
||||
for (auto &fingerPrint : fingerPrints) {
|
||||
auto it = RSAKeys.constFind(static_cast<uint64>(fingerPrint.v));
|
||||
if (it != RSAKeys.cend()) {
|
||||
rsaKey = &it.value();
|
||||
|
@ -2401,7 +2401,7 @@ void ConnectionPrivate::pqAnswered() {
|
|||
}
|
||||
if (!rsaKey) {
|
||||
QStringList suggested, my;
|
||||
for (const auto &fingerPrint : fingerPrints) {
|
||||
for (auto &fingerPrint : fingerPrints) {
|
||||
suggested.push_back(QString("%1").arg(fingerPrint.v));
|
||||
}
|
||||
for (auto i = RSAKeys.cbegin(), e = RSAKeys.cend(); i != e; ++i) {
|
||||
|
@ -2412,49 +2412,54 @@ void ConnectionPrivate::pqAnswered() {
|
|||
}
|
||||
|
||||
_authKeyData->server_nonce = res_pq_data.vserver_nonce;
|
||||
_authKeyData->new_nonce = rand_value<MTPint256>();
|
||||
|
||||
MTPP_Q_inner_data p_q_inner;
|
||||
MTPDp_q_inner_data &p_q_inner_data(p_q_inner._p_q_inner_data());
|
||||
p_q_inner_data.vnonce = _authKeyData->nonce;
|
||||
p_q_inner_data.vserver_nonce = _authKeyData->server_nonce;
|
||||
p_q_inner_data.vpq = res_pq_data.vpq;
|
||||
|
||||
const string &pq(res_pq_data.vpq.c_string().v);
|
||||
string &p(p_q_inner_data.vp._string().v), &q(p_q_inner_data.vq._string().v);
|
||||
|
||||
auto &pq = res_pq_data.vpq.c_string().v;
|
||||
auto p = std::string();
|
||||
auto q = std::string();
|
||||
if (!MTP::internal::parsePQ(pq, p, q)) {
|
||||
LOG(("AuthKey Error: could not factor pq!"));
|
||||
DEBUG_LOG(("AuthKey Error: problematic pq: %1").arg(Logs::mb(&pq[0], pq.length()).str()));
|
||||
return restart();
|
||||
}
|
||||
|
||||
_authKeyData->new_nonce = rand_value<MTPint256>();
|
||||
p_q_inner_data.vnew_nonce = _authKeyData->new_nonce;
|
||||
auto p_q_inner = MTP_p_q_inner_data(res_pq_data.vpq, MTP_string(std::move(p)), MTP_string(std::move(q)), _authKeyData->nonce, _authKeyData->server_nonce, _authKeyData->new_nonce);
|
||||
auto dhEncString = encryptPQInnerRSA(p_q_inner, rsaKey);
|
||||
if (dhEncString.empty()) {
|
||||
return restart();
|
||||
}
|
||||
|
||||
connect(_conn, SIGNAL(receivedData()), this, SLOT(dhParamsAnswered()));
|
||||
|
||||
DEBUG_LOG(("AuthKey Info: sending Req_DH_params..."));
|
||||
|
||||
MTPReq_DH_params req_DH_params;
|
||||
req_DH_params.vnonce = _authKeyData->nonce;
|
||||
req_DH_params.vserver_nonce = _authKeyData->server_nonce;
|
||||
req_DH_params.vpublic_key_fingerprint = MTP_long(rsaKey->getFingerPrint());
|
||||
req_DH_params.vp = p_q_inner_data.vp;
|
||||
req_DH_params.vq = p_q_inner_data.vq;
|
||||
req_DH_params.vp = p_q_inner.c_p_q_inner_data().vp;
|
||||
req_DH_params.vq = p_q_inner.c_p_q_inner_data().vq;
|
||||
req_DH_params.vencrypted_data = MTP_string(std::move(dhEncString));
|
||||
sendRequestNotSecure(req_DH_params);
|
||||
}
|
||||
|
||||
string &dhEncString(req_DH_params.vencrypted_data._string().v);
|
||||
|
||||
uint32 p_q_inner_size = p_q_inner.innerLength(), encSize = (p_q_inner_size >> 2) + 6;
|
||||
std::string ConnectionPrivate::encryptPQInnerRSA(const MTPP_Q_inner_data &data, const MTP::internal::RSAPublicKey *key) {
|
||||
auto p_q_inner_size = data.innerLength();
|
||||
auto encSize = (p_q_inner_size >> 2) + 6;
|
||||
if (encSize >= 65) {
|
||||
mtpBuffer tmp;
|
||||
auto tmp = mtpBuffer();
|
||||
tmp.reserve(encSize);
|
||||
p_q_inner.write(tmp);
|
||||
data.write(tmp);
|
||||
LOG(("AuthKey Error: too large data for RSA encrypt, size %1").arg(encSize * sizeof(mtpPrime)));
|
||||
DEBUG_LOG(("AuthKey Error: bad data for RSA encrypt %1").arg(Logs::mb(&tmp[0], tmp.size() * 4).str()));
|
||||
return restart(); // can't be 255-byte string
|
||||
return std::string(); // can't be 255-byte string
|
||||
}
|
||||
|
||||
mtpBuffer encBuffer;
|
||||
auto encBuffer = mtpBuffer();
|
||||
encBuffer.reserve(65); // 260 bytes
|
||||
encBuffer.resize(6);
|
||||
encBuffer[0] = 0;
|
||||
p_q_inner.write(encBuffer);
|
||||
data.write(encBuffer);
|
||||
|
||||
hashSha1(&encBuffer[6], p_q_inner_size, &encBuffer[1]);
|
||||
if (encSize < 65) {
|
||||
|
@ -2462,13 +2467,11 @@ void ConnectionPrivate::pqAnswered() {
|
|||
memset_rand(&encBuffer[encSize], (65 - encSize) * sizeof(mtpPrime));
|
||||
}
|
||||
|
||||
if (!rsaKey->encrypt(reinterpret_cast<const char*>(&encBuffer[0]) + 3, dhEncString)) {
|
||||
return restart();
|
||||
auto dhEncString = std::string();
|
||||
if (!key->encrypt(reinterpret_cast<const char*>(&encBuffer[0]) + 3, dhEncString)) {
|
||||
return std::string();
|
||||
}
|
||||
connect(_conn, SIGNAL(receivedData()), this, SLOT(dhParamsAnswered()));
|
||||
|
||||
DEBUG_LOG(("AuthKey Info: sending Req_DH_params..."));
|
||||
sendRequestNotSecure(req_DH_params);
|
||||
return dhEncString;
|
||||
}
|
||||
|
||||
void ConnectionPrivate::dhParamsAnswered() {
|
||||
|
@ -2598,15 +2601,11 @@ void ConnectionPrivate::dhClientParamsSend() {
|
|||
return restart();
|
||||
}
|
||||
|
||||
MTPClient_DH_Inner_Data client_dh_inner;
|
||||
MTPDclient_DH_inner_data &client_dh_inner_data(client_dh_inner._client_DH_inner_data());
|
||||
client_dh_inner_data.vnonce = _authKeyData->nonce;
|
||||
client_dh_inner_data.vserver_nonce = _authKeyData->server_nonce;
|
||||
client_dh_inner_data.vretry_id = _authKeyData->retry_id;
|
||||
client_dh_inner_data.vg_b._string().v.resize(256);
|
||||
auto g_b_string = std::string(256, ' ');
|
||||
|
||||
// gen rand 'b'
|
||||
uint32 b[64], *g_b((uint32*)&client_dh_inner_data.vg_b._string().v[0]);
|
||||
uint32 b[64];
|
||||
auto g_b = reinterpret_cast<uint32*>(&g_b_string[0]);
|
||||
memset_rand(b, sizeof(b));
|
||||
|
||||
// count g_b and auth_key using openssl BIGNUM methods
|
||||
|
@ -2620,21 +2619,33 @@ void ConnectionPrivate::dhClientParamsSend() {
|
|||
memcpy(&_authKeyData->auth_key_aux_hash, auth_key_sha.data(), 8);
|
||||
memcpy(&_authKeyData->auth_key_hash, auth_key_sha.data() + 12, 8);
|
||||
|
||||
auto client_dh_inner = MTP_client_DH_inner_data(_authKeyData->nonce, _authKeyData->server_nonce, _authKeyData->retry_id, MTP_string(std::move(g_b_string)));
|
||||
|
||||
auto sdhEncString = encryptClientDHInner(client_dh_inner);
|
||||
|
||||
connect(_conn, SIGNAL(receivedData()), this, SLOT(dhClientParamsAnswered()));
|
||||
|
||||
MTPSet_client_DH_params req_client_DH_params;
|
||||
req_client_DH_params.vnonce = _authKeyData->nonce;
|
||||
req_client_DH_params.vserver_nonce = _authKeyData->server_nonce;
|
||||
req_client_DH_params.vencrypted_data = MTP_string(std::move(sdhEncString));
|
||||
|
||||
string &sdhEncString(req_client_DH_params.vencrypted_data._string().v);
|
||||
DEBUG_LOG(("AuthKey Info: sending Req_client_DH_params..."));
|
||||
sendRequestNotSecure(req_client_DH_params);
|
||||
}
|
||||
|
||||
uint32 client_dh_inner_size = client_dh_inner.innerLength(), encSize = (client_dh_inner_size >> 2) + 5, encFullSize = encSize;
|
||||
std::string ConnectionPrivate::encryptClientDHInner(const MTPClient_DH_Inner_Data &data) {
|
||||
auto client_dh_inner_size = data.innerLength();
|
||||
auto encSize = (client_dh_inner_size >> 2) + 5;
|
||||
auto encFullSize = encSize;
|
||||
if (encSize & 0x03) {
|
||||
encFullSize += 4 - (encSize & 0x03);
|
||||
}
|
||||
|
||||
mtpBuffer encBuffer;
|
||||
auto encBuffer = mtpBuffer();
|
||||
encBuffer.reserve(encFullSize);
|
||||
encBuffer.resize(5);
|
||||
client_dh_inner.write(encBuffer);
|
||||
data.write(encBuffer);
|
||||
|
||||
hashSha1(&encBuffer[5], client_dh_inner_size, &encBuffer[0]);
|
||||
if (encSize < encFullSize) {
|
||||
|
@ -2642,14 +2653,11 @@ void ConnectionPrivate::dhClientParamsSend() {
|
|||
memset_rand(&encBuffer[encSize], (encFullSize - encSize) * sizeof(mtpPrime));
|
||||
}
|
||||
|
||||
sdhEncString.resize(encFullSize * 4);
|
||||
auto sdhEncString = std::string(encFullSize * 4, ' ');
|
||||
|
||||
aesIgeEncrypt(&encBuffer[0], &sdhEncString[0], encFullSize * sizeof(mtpPrime), _authKeyData->aesKey, _authKeyData->aesIV);
|
||||
|
||||
connect(_conn, SIGNAL(receivedData()), this, SLOT(dhClientParamsAnswered()));
|
||||
|
||||
DEBUG_LOG(("AuthKey Info: sending Req_client_DH_params..."));
|
||||
sendRequestNotSecure(req_client_DH_params);
|
||||
return sdhEncString;
|
||||
}
|
||||
|
||||
void ConnectionPrivate::dhClientParamsAnswered() {
|
||||
|
|
|
@ -33,6 +33,7 @@ namespace internal {
|
|||
class AbstractConnection;
|
||||
class ConnectionPrivate;
|
||||
class SessionData;
|
||||
class RSAPublicKey;
|
||||
|
||||
class Thread : public QThread {
|
||||
Q_OBJECT
|
||||
|
@ -179,6 +180,9 @@ private:
|
|||
|
||||
bool setState(int32 state, int32 ifState = Connection::UpdateAlways);
|
||||
|
||||
std::string encryptPQInnerRSA(const MTPP_Q_inner_data &data, const MTP::internal::RSAPublicKey *key);
|
||||
std::string encryptClientDHInner(const MTPClient_DH_Inner_Data &data);
|
||||
|
||||
Instance *_instance = nullptr;
|
||||
|
||||
mutable QReadWriteLock stateConnMutex;
|
||||
|
|
|
@ -104,7 +104,7 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
|||
throw Exception(QString("ungzip init, code: %1").arg(res));
|
||||
}
|
||||
stream.avail_in = packedLen;
|
||||
stream.next_in = (Bytef*)&packed._string().v[0];
|
||||
stream.next_in = const_cast<Bytef*>(reinterpret_cast<const Bytef*>(packed.c_string().v.data()));
|
||||
stream.avail_out = 0;
|
||||
while (!stream.avail_out) {
|
||||
result.resize(result.size() + unpackedChunk);
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace MTP {
|
|||
using DcId = int32;
|
||||
using ShiftedDcId = int32;
|
||||
|
||||
}
|
||||
} // namespace MTP
|
||||
|
||||
using mtpPrime = int32;
|
||||
using mtpRequestId = int32;
|
||||
|
@ -177,68 +177,23 @@ public:
|
|||
|
||||
class mtpData {
|
||||
public:
|
||||
mtpData() : cnt(1) {
|
||||
}
|
||||
mtpData(const mtpData &) : cnt(1) {
|
||||
}
|
||||
|
||||
mtpData *incr() {
|
||||
++cnt;
|
||||
return this;
|
||||
}
|
||||
bool decr() {
|
||||
return !--cnt;
|
||||
}
|
||||
bool needSplit() {
|
||||
return (cnt > 1);
|
||||
}
|
||||
|
||||
virtual mtpData *clone() = 0;
|
||||
virtual ~mtpData() {
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 cnt;
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class mtpDataImpl : public mtpData {
|
||||
public:
|
||||
virtual mtpData *clone() {
|
||||
return new T(*(T*)this);
|
||||
}
|
||||
};
|
||||
|
||||
class mtpDataOwner {
|
||||
public:
|
||||
mtpDataOwner(const mtpDataOwner &v) : data(v.data ? v.data->incr() : 0) {
|
||||
}
|
||||
mtpDataOwner &operator=(const mtpDataOwner &v) {
|
||||
setData(v.data ? v.data->incr() : v.data);
|
||||
return *this;
|
||||
}
|
||||
~mtpDataOwner() {
|
||||
if (data && data->decr()) delete data;
|
||||
}
|
||||
mtpDataOwner(mtpDataOwner &&other) = default;
|
||||
mtpDataOwner(const mtpDataOwner &other) = default;
|
||||
mtpDataOwner &operator=(mtpDataOwner &&other) = default;
|
||||
mtpDataOwner &operator=(const mtpDataOwner &other) = default;
|
||||
|
||||
protected:
|
||||
explicit mtpDataOwner(mtpData *_data) : data(_data) {
|
||||
explicit mtpDataOwner(std::shared_ptr<const mtpData> &&data) : data(data) {
|
||||
}
|
||||
void split() {
|
||||
if (data && data->needSplit()) {
|
||||
mtpData *clone = data->clone();
|
||||
if (data->decr()) delete data;
|
||||
data = clone;
|
||||
}
|
||||
}
|
||||
void setData(mtpData *_data) {
|
||||
if (data != _data) {
|
||||
if (data && data->decr()) delete data;
|
||||
data = _data;
|
||||
}
|
||||
}
|
||||
mtpData *data;
|
||||
std::shared_ptr<const mtpData> data;
|
||||
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -614,12 +569,14 @@ inline bool operator!=(const MTPdouble &a, const MTPdouble &b) {
|
|||
return a.v != b.v;
|
||||
}
|
||||
|
||||
class MTPDstring : public mtpDataImpl<MTPDstring> {
|
||||
class MTPDstring : public mtpData {
|
||||
public:
|
||||
MTPDstring() {
|
||||
}
|
||||
MTPDstring(const std::string &val) : v(val) {
|
||||
}
|
||||
MTPDstring(std::string &&val) : v(std::move(val)) {
|
||||
}
|
||||
MTPDstring(const QString &val) : v(val.toUtf8().constData()) {
|
||||
}
|
||||
MTPDstring(const QByteArray &val) : v(val.constData(), val.size()) {
|
||||
|
@ -628,24 +585,20 @@ public:
|
|||
}
|
||||
|
||||
std::string v;
|
||||
|
||||
};
|
||||
|
||||
class MTPstring : private mtpDataOwner {
|
||||
public:
|
||||
MTPstring() : mtpDataOwner(new MTPDstring()) {
|
||||
MTPstring() : mtpDataOwner(nullptr) {
|
||||
}
|
||||
MTPstring(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_string) : mtpDataOwner(0) {
|
||||
read(from, end, cons);
|
||||
}
|
||||
|
||||
MTPDstring &_string() {
|
||||
t_assert(data != nullptr);
|
||||
split();
|
||||
return *(MTPDstring*)data;
|
||||
}
|
||||
const MTPDstring &c_string() const {
|
||||
t_assert(data != nullptr);
|
||||
return *(const MTPDstring*)data;
|
||||
return static_cast<const MTPDstring&>(*data);
|
||||
}
|
||||
|
||||
uint32 innerLength() const {
|
||||
|
@ -679,10 +632,8 @@ public:
|
|||
}
|
||||
if (from > end) throw mtpErrorInsufficient();
|
||||
|
||||
if (!data) setData(new MTPDstring());
|
||||
MTPDstring &v(_string());
|
||||
v.v.resize(l);
|
||||
memcpy(&v.v[0], buf, l);
|
||||
auto string = std::string(reinterpret_cast<const char*>(buf), l);
|
||||
data = std::make_shared<MTPDstring>(std::move(string));
|
||||
}
|
||||
void write(mtpBuffer &to) const {
|
||||
uint32 l = c_string().v.length(), s = l + ((l < 254) ? 1 : 4), was = to.size();
|
||||
|
@ -705,23 +656,28 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
explicit MTPstring(MTPDstring *_data) : mtpDataOwner(_data) {
|
||||
explicit MTPstring(std::shared_ptr<const MTPDstring> &&data) : mtpDataOwner(std::move(data)) {
|
||||
}
|
||||
|
||||
friend MTPstring MTP_string(const std::string &v);
|
||||
friend MTPstring MTP_string(std::string &&v);
|
||||
friend MTPstring MTP_string(const QString &v);
|
||||
friend MTPstring MTP_string(const char *v);
|
||||
|
||||
friend MTPstring MTP_bytes(const QByteArray &v);
|
||||
|
||||
};
|
||||
inline MTPstring MTP_string(const std::string &v) {
|
||||
return MTPstring(new MTPDstring(v));
|
||||
return MTPstring(std::make_shared<MTPDstring>(v));
|
||||
}
|
||||
inline MTPstring MTP_string(std::string &&v) {
|
||||
return MTPstring(std::make_shared<MTPDstring>(std::move(v)));
|
||||
}
|
||||
inline MTPstring MTP_string(const QString &v) {
|
||||
return MTPstring(new MTPDstring(v));
|
||||
return MTPstring(std::make_shared<MTPDstring>(v));
|
||||
}
|
||||
inline MTPstring MTP_string(const char *v) {
|
||||
return MTPstring(new MTPDstring(v));
|
||||
return MTPstring(std::make_shared<MTPDstring>(v));
|
||||
}
|
||||
MTPstring MTP_string(const QByteArray &v) = delete;
|
||||
using MTPString = MTPBoxed<MTPstring>;
|
||||
|
@ -730,7 +686,7 @@ using MTPbytes = MTPstring;
|
|||
using MTPBytes = MTPBoxed<MTPbytes>;
|
||||
|
||||
inline MTPbytes MTP_bytes(const QByteArray &v) {
|
||||
return MTPbytes(new MTPDstring(v));
|
||||
return MTPbytes(std::make_shared<MTPDstring>(v));
|
||||
}
|
||||
|
||||
inline bool operator==(const MTPstring &a, const MTPstring &b) {
|
||||
|
@ -751,7 +707,7 @@ inline QByteArray qba(const MTPstring &v) {
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
class MTPDvector : public mtpDataImpl<MTPDvector<T> > {
|
||||
class MTPDvector : public mtpData {
|
||||
public:
|
||||
MTPDvector() {
|
||||
}
|
||||
|
@ -769,26 +725,21 @@ public:
|
|||
template <typename T>
|
||||
class MTPvector : private mtpDataOwner {
|
||||
public:
|
||||
MTPvector() : mtpDataOwner(new MTPDvector<T>()) {
|
||||
MTPvector() : mtpDataOwner(nullptr) {
|
||||
}
|
||||
MTPvector(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_vector) : mtpDataOwner(0) {
|
||||
read(from, end, cons);
|
||||
}
|
||||
|
||||
MTPDvector<T> &_vector() {
|
||||
t_assert(data != nullptr);
|
||||
split();
|
||||
return *(MTPDvector<T>*)data;
|
||||
}
|
||||
const MTPDvector<T> &c_vector() const {
|
||||
t_assert(data != nullptr);
|
||||
return *(const MTPDvector<T>*)data;
|
||||
return static_cast<const MTPDvector<T>&>(*data);
|
||||
}
|
||||
|
||||
uint32 innerLength() const {
|
||||
uint32 result(sizeof(uint32));
|
||||
for (typename VType::const_iterator i = c_vector().v.cbegin(), e = c_vector().v.cend(); i != e; ++i) {
|
||||
result += i->innerLength();
|
||||
for_const (auto &item, c_vector().v) {
|
||||
result += item.innerLength();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -800,23 +751,22 @@ public:
|
|||
if (cons != mtpc_vector) throw mtpErrorUnexpected(cons, "MTPvector");
|
||||
uint32 count = (uint32)*(from++);
|
||||
|
||||
if (!data) setData(new MTPDvector<T>());
|
||||
MTPDvector<T> &v(_vector());
|
||||
v.v.resize(0);
|
||||
v.v.reserve(count);
|
||||
for (uint32 i = 0; i < count; ++i) {
|
||||
v.v.push_back(T(from, end));
|
||||
auto vector = QVector<T>();
|
||||
vector.reserve(count);
|
||||
for (auto i = 0; i != count; ++i) {
|
||||
vector.push_back(T(from, end));
|
||||
}
|
||||
data = std::make_shared<MTPDvector<T>>(std::move(vector));
|
||||
}
|
||||
void write(mtpBuffer &to) const {
|
||||
to.push_back(c_vector().v.size());
|
||||
for (typename VType::const_iterator i = c_vector().v.cbegin(), e = c_vector().v.cend(); i != e; ++i) {
|
||||
(*i).write(to);
|
||||
for_const (auto &item, c_vector().v) {
|
||||
item.write(to);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
explicit MTPvector(MTPDvector<T> *_data) : mtpDataOwner(_data) {
|
||||
explicit MTPvector(std::shared_ptr<MTPDvector<T>> &&data) : mtpDataOwner(std::move(data)) {
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
|
@ -825,19 +775,25 @@ private:
|
|||
friend MTPvector<U> MTP_vector(uint32 count, const U &value);
|
||||
template <typename U>
|
||||
friend MTPvector<U> MTP_vector(const QVector<U> &v);
|
||||
using VType = typename MTPDvector<T>::VType;
|
||||
template <typename U>
|
||||
friend MTPvector<U> MTP_vector(QVector<U> &&v);
|
||||
|
||||
};
|
||||
template <typename T>
|
||||
inline MTPvector<T> MTP_vector(uint32 count) {
|
||||
return MTPvector<T>(new MTPDvector<T>(count));
|
||||
return MTPvector<T>(std::make_shared<MTPDvector<T>>(count));
|
||||
}
|
||||
template <typename T>
|
||||
inline MTPvector<T> MTP_vector(uint32 count, const T &value) {
|
||||
return MTPvector<T>(new MTPDvector<T>(count, value));
|
||||
return MTPvector<T>(std::make_shared<MTPDvector<T>>(count, value));
|
||||
}
|
||||
template <typename T>
|
||||
inline MTPvector<T> MTP_vector(const QVector<T> &v) {
|
||||
return MTPvector<T>(new MTPDvector<T>(v));
|
||||
return MTPvector<T>(std::make_shared<MTPDvector<T>>(v));
|
||||
}
|
||||
template <typename T>
|
||||
inline MTPvector<T> MTP_vector(QVector<T> &&v) {
|
||||
return MTPvector<T>(std::make_shared<MTPDvector<T>>(std::move(v)));
|
||||
}
|
||||
template <typename T>
|
||||
using MTPVector = MTPBoxed<MTPvector<T>>;
|
||||
|
@ -866,7 +822,7 @@ struct MTPStringLogger {
|
|||
}
|
||||
|
||||
MTPStringLogger &add(const QString &data) {
|
||||
QByteArray d = data.toUtf8();
|
||||
auto d = data.toUtf8();
|
||||
return add(d.constData(), d.size());
|
||||
}
|
||||
|
||||
|
|
|
@ -573,7 +573,7 @@ for restype in typesList:
|
|||
trivialConditions = data[7];
|
||||
|
||||
dataText = '';
|
||||
dataText += '\nclass MTPD' + name + ' : public mtpDataImpl<MTPD' + name + '> {\n'; # data class
|
||||
dataText += '\nclass MTPD' + name + ' : public mtpData {\n'; # data class
|
||||
dataText += 'public:\n';
|
||||
|
||||
sizeList = [];
|
||||
|
@ -608,28 +608,20 @@ for restype in typesList:
|
|||
dataText += '\tMTPD' + name + '() {\n\t}\n'; # default constructor
|
||||
switchLines += '\t\tcase mtpc_' + name + ': '; # for by-type-id type constructor
|
||||
if (len(prms) > len(trivialConditions)):
|
||||
switchLines += 'setData(new MTPD' + name + '()); ';
|
||||
switchLines += 'data = std::make_shared<MTPD' + name + '>(); ';
|
||||
withData = 1;
|
||||
|
||||
getters += '\n\tMTPD' + name + ' &_' + name + '() {\n'; # splitting getter
|
||||
getters += '\tconst MTPD' + name + ' &c_' + name + '() const;\n'; # const getter
|
||||
constructsInline += 'inline const MTPD' + name + ' &MTP' + restype + '::c_' + name + '() const {\n';
|
||||
if (withType):
|
||||
getters += '\t\tt_assert(data != nullptr && _type == mtpc_' + name + ');\n';
|
||||
constructsInline += '\tt_assert(data != nullptr && _type == mtpc_' + name + ');\n';
|
||||
else:
|
||||
getters += '\t\tt_assert(data != nullptr);\n';
|
||||
getters += '\t\tsplit();\n';
|
||||
getters += '\t\treturn *(MTPD' + name + '*)data;\n';
|
||||
getters += '\t}\n';
|
||||
constructsInline += '\tt_assert(data != nullptr);\n';
|
||||
constructsInline += '\treturn static_cast<const MTPD' + name + '&>(*data);\n';
|
||||
constructsInline += '}\n';
|
||||
|
||||
getters += '\tconst MTPD' + name + ' &c_' + name + '() const {\n'; # const getter
|
||||
if (withType):
|
||||
getters += '\t\tt_assert(data != nullptr && _type == mtpc_' + name + ');\n';
|
||||
else:
|
||||
getters += '\t\tt_assert(data != nullptr);\n';
|
||||
getters += '\t\treturn *(const MTPD' + name + '*)data;\n';
|
||||
getters += '\t}\n';
|
||||
|
||||
constructsText += '\texplicit MTP' + restype + '(MTPD' + name + ' *_data);\n'; # by-data type constructor
|
||||
constructsInline += 'inline MTP' + restype + '::MTP' + restype + '(MTPD' + name + ' *_data) : mtpDataOwner(_data)';
|
||||
constructsText += '\texplicit MTP' + restype + '(std::shared_ptr<const MTPD' + name + '> &&data);\n'; # by-data type constructor
|
||||
constructsInline += 'inline MTP' + restype + '::MTP' + restype + '(std::shared_ptr<const MTPD' + name + '> &&data) : mtpDataOwner(std::move(data))';
|
||||
if (withType):
|
||||
constructsInline += ', _type(mtpc_' + name + ')';
|
||||
constructsInline += ' {\n}\n';
|
||||
|
@ -654,11 +646,11 @@ for restype in typesList:
|
|||
readText += '\t\t';
|
||||
writeText += '\t\t';
|
||||
if (paramName in conditions):
|
||||
readText += '\tif (v.has_' + paramName + '()) { v.v' + paramName + '.read(from, end); } else { v.v' + paramName + ' = MTP' + paramType + '(); }\n';
|
||||
readText += '\tif (v->has_' + paramName + '()) { v->v' + paramName + '.read(from, end); } else { v->v' + paramName + ' = MTP' + paramType + '(); }\n';
|
||||
writeText += '\tif (v.has_' + paramName + '()) v.v' + paramName + '.write(to);\n';
|
||||
sizeList.append('(v.has_' + paramName + '() ? v.v' + paramName + '.innerLength() : 0)');
|
||||
else:
|
||||
readText += '\tv.v' + paramName + '.read(from, end);\n';
|
||||
readText += '\tv->v' + paramName + '.read(from, end);\n';
|
||||
writeText += '\tv.v' + paramName + '.write(to);\n';
|
||||
sizeList.append('v.v' + paramName + '.innerLength()');
|
||||
|
||||
|
@ -677,7 +669,7 @@ for restype in typesList:
|
|||
sizeCases += '\t\t\treturn ' + ' + '.join(sizeList) + ';\n';
|
||||
sizeCases += '\t\t}\n';
|
||||
sizeFast = '\tconst MTPD' + name + ' &v(c_' + name + '());\n\treturn ' + ' + '.join(sizeList) + ';\n';
|
||||
newFast = 'new MTPD' + name + '()';
|
||||
newFast = 'std::make_shared<MTPD' + name + '>()';
|
||||
else:
|
||||
sizeFast = '\treturn 0;\n';
|
||||
|
||||
|
@ -691,7 +683,7 @@ for restype in typesList:
|
|||
friendDecl += '\tfriend class MTP::internal::TypeCreator;\n';
|
||||
creatorProxyText += '\tinline static MTP' + restype + ' new_' + name + '(' + ', '.join(creatorParams) + ') {\n';
|
||||
if (len(prms) > len(trivialConditions)): # creator with params
|
||||
creatorProxyText += '\t\treturn MTP' + restype + '(new MTPD' + name + '(' + ', '.join(creatorParamsList) + '));\n';
|
||||
creatorProxyText += '\t\treturn MTP' + restype + '(std::make_shared<MTPD' + name + '>(' + ', '.join(creatorParamsList) + '));\n';
|
||||
else:
|
||||
if (withType): # creator by type
|
||||
creatorProxyText += '\t\treturn MTP' + restype + '(mtpc_' + name + ');\n';
|
||||
|
@ -708,24 +700,24 @@ for restype in typesList:
|
|||
reader += '\t\tcase mtpc_' + name + ': _type = cons; '; # read switch line
|
||||
if (len(prms) > len(trivialConditions)):
|
||||
reader += '{\n';
|
||||
reader += '\t\t\tif (!data) setData(new MTPD' + name + '());\n';
|
||||
reader += '\t\t\tMTPD' + name + ' &v(_' + name + '());\n';
|
||||
reader += '\t\t\tauto v = std::make_shared<MTPD' + name + '>();\n';
|
||||
reader += readText;
|
||||
reader += '\t\t\tdata = std::move(v);\n';
|
||||
reader += '\t\t} break;\n';
|
||||
|
||||
writer += '\t\tcase mtpc_' + name + ': {\n'; # write switch line
|
||||
writer += '\t\t\tconst MTPD' + name + ' &v(c_' + name + '());\n';
|
||||
writer += '\t\t\tauto &v = c_' + name + '();\n';
|
||||
writer += writeText;
|
||||
writer += '\t\t} break;\n';
|
||||
else:
|
||||
reader += 'break;\n';
|
||||
else:
|
||||
if (len(prms) > len(trivialConditions)):
|
||||
reader += '\n\tif (!data) setData(new MTPD' + name + '());\n';
|
||||
reader += '\tMTPD' + name + ' &v(_' + name + '());\n';
|
||||
reader += '\n\tauto v = std::make_shared<MTPD' + name + '>();\n';
|
||||
reader += readText;
|
||||
reader += '\tdata = std::move(v);\n';
|
||||
|
||||
writer += '\tconst MTPD' + name + ' &v(c_' + name + '());\n';
|
||||
writer += '\tauto &v = c_' + name + '();\n';
|
||||
writer += writeText;
|
||||
|
||||
forwards += '\n';
|
||||
|
@ -739,8 +731,7 @@ for restype in typesList:
|
|||
inits = [];
|
||||
if (withType):
|
||||
if (withData):
|
||||
inits.append('mtpDataOwner(0)');
|
||||
inits.append('_type(0)');
|
||||
inits.append('mtpDataOwner(nullptr)');
|
||||
else:
|
||||
if (withData):
|
||||
inits.append('mtpDataOwner(' + newFast + ')');
|
||||
|
@ -757,9 +748,7 @@ for restype in typesList:
|
|||
|
||||
inits = [];
|
||||
if (withData):
|
||||
inits.append('mtpDataOwner(0)');
|
||||
if (withType):
|
||||
inits.append('_type(0)');
|
||||
inits.append('mtpDataOwner(nullptr)');
|
||||
typesText += '\tMTP' + restype + '(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons';
|
||||
if (not withType):
|
||||
typesText += ' = mtpc_' + name;
|
||||
|
@ -798,7 +787,7 @@ for restype in typesList:
|
|||
inlineMethods += 'inline void MTP' + restype + '::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {\n';
|
||||
if (withData):
|
||||
if (withType):
|
||||
inlineMethods += '\tif (cons != _type) setData(0);\n';
|
||||
inlineMethods += '\tdata.reset();\n';
|
||||
else:
|
||||
inlineMethods += '\tif (cons != mtpc_' + v[0][0] + ') throw mtpErrorUnexpected(cons, "MTP' + restype + '");\n';
|
||||
if (withType):
|
||||
|
@ -827,7 +816,7 @@ for restype in typesList:
|
|||
typesText += '\texplicit MTP' + restype + '(mtpTypeId type);\n';
|
||||
inlineMethods += 'inline MTP' + restype + '::MTP' + restype + '(mtpTypeId type) : ';
|
||||
if (withData):
|
||||
inlineMethods += 'mtpDataOwner(0), ';
|
||||
inlineMethods += 'mtpDataOwner(nullptr), ';
|
||||
inlineMethods += '_type(type)';
|
||||
inlineMethods += ' {\n';
|
||||
inlineMethods += '\tswitch (type) {\n'; # type id check
|
||||
|
@ -843,7 +832,7 @@ for restype in typesList:
|
|||
typesText += '\n' + friendDecl;
|
||||
|
||||
if (withType):
|
||||
typesText += '\n\tmtpTypeId _type;\n'; # type field var
|
||||
typesText += '\n\tmtpTypeId _type = 0;\n'; # type field var
|
||||
|
||||
typesText += '};\n'; # type class ended
|
||||
|
||||
|
|
|
@ -262,7 +262,7 @@ DcId Instance::Private::mainDcId() const {
|
|||
}
|
||||
|
||||
void Instance::Private::configLoadRequest() {
|
||||
if (_configLoader) {
|
||||
if (_configLoader || true) {
|
||||
return;
|
||||
}
|
||||
_configLoader = std::make_unique<internal::ConfigLoader>(_instance, rpcDone([this](const MTPConfig &result) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -206,13 +206,15 @@ void Session::sendPong(quint64 msgId, quint64 pingId) {
|
|||
}
|
||||
|
||||
void Session::sendMsgsStateInfo(quint64 msgId, QByteArray data) {
|
||||
MTPMsgsStateInfo req(MTP_msgs_state_info(MTP_long(msgId), MTPstring()));
|
||||
auto &info = req._msgs_state_info().vinfo._string().v;
|
||||
info.resize(data.size());
|
||||
auto info = std::string();
|
||||
if (!data.isEmpty()) {
|
||||
memcpy(&info[0], data.constData(), data.size());
|
||||
info.resize(data.size());
|
||||
auto src = gsl::as_bytes(gsl::make_span(data));
|
||||
// auto dst = gsl::as_writeable_bytes(gsl::make_span(info));
|
||||
auto dst = gsl::as_writeable_bytes(gsl::make_span(&info[0], info.size()));
|
||||
base::copy_bytes(dst, src);
|
||||
}
|
||||
send(req);
|
||||
send(MTPMsgsStateInfo(MTP_msgs_state_info(MTP_long(msgId), MTP_string(std::move(info)))));
|
||||
}
|
||||
|
||||
void Session::checkRequestsByTimer() {
|
||||
|
|
|
@ -1400,9 +1400,9 @@ EntitiesInText entitiesFromMTP(const QVector<MTPMessageEntity> &entities) {
|
|||
}
|
||||
|
||||
MTPVector<MTPMessageEntity> linksToMTP(const EntitiesInText &links, bool sending) {
|
||||
MTPVector<MTPMessageEntity> result(MTP_vector<MTPMessageEntity>(0));
|
||||
auto &v = result._vector().v;
|
||||
for_const (const auto &link, links) {
|
||||
auto v = QVector<MTPMessageEntity>();
|
||||
v.reserve(links.size());
|
||||
for_const (auto &link, links) {
|
||||
if (link.length() <= 0) continue;
|
||||
if (sending
|
||||
&& link.type() != EntityInTextCode
|
||||
|
@ -1441,7 +1441,7 @@ MTPVector<MTPMessageEntity> linksToMTP(const EntitiesInText &links, bool sending
|
|||
case EntityInTextPre: v.push_back(MTP_messageEntityPre(offset, length, MTP_string(link.data()))); break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return MTP_vector<MTPMessageEntity>(std::move(v));
|
||||
}
|
||||
|
||||
// Some code is duplicated in flattextarea.cpp!
|
||||
|
|
Loading…
Add table
Reference in a new issue