Make all owned MTPD types immutable.

Remove custom refcounting in mtpData, use std::shared_ptr instead.
This commit is contained in:
John Preston 2017-03-09 21:13:55 +03:00
parent 839bf313cf
commit 3b373e236e
9 changed files with 7191 additions and 9237 deletions

View file

@ -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() {

View file

@ -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;

View file

@ -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);

View file

@ -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());
}

View file

@ -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

View file

@ -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

View file

@ -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() {

View file

@ -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!