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