Remove read() constructors from MTP types.

This will allow us to handle errors in parsing not by exceptions.
This commit is contained in:
John Preston 2017-03-09 22:15:31 +03:00
parent 3b373e236e
commit 02da80439b
8 changed files with 1209 additions and 3612 deletions

View File

@ -4467,13 +4467,18 @@ void MainWidget::updateReceived(const mtpPrime *from, const mtpPrime *end) {
App::wnd()->checkAutoLock(); App::wnd()->checkAutoLock();
if (mtpTypeId(*from) == mtpc_new_session_created) { if (mtpTypeId(*from) == mtpc_new_session_created) {
MTPNewSession newSession(from, end); try {
MTPNewSession newSession;
newSession.read(from, end);
} catch (mtpErrorUnexpected &) {
}
updSeq = 0; updSeq = 0;
MTP_LOG(0, ("getDifference { after new_session_created }%1").arg(cTestMode() ? " TESTMODE" : "")); MTP_LOG(0, ("getDifference { after new_session_created }%1").arg(cTestMode() ? " TESTMODE" : ""));
return getDifference(); return getDifference();
} else { } else {
try { try {
MTPUpdates updates(from, end); MTPUpdates updates;
updates.read(from, end);
_lastUpdateTime = getms(true); _lastUpdateTime = getms(true);
noUpdatesTimer.start(NoUpdatesTimeout); noUpdatesTimer.start(NoUpdatesTimeout);

View File

@ -1524,15 +1524,18 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
if (from + 4 >= end) throw mtpErrorInsufficient(); if (from + 4 >= end) throw mtpErrorInsufficient();
otherEnd = from + 4; otherEnd = from + 4;
MTPlong inMsgId(from, otherEnd); MTPlong inMsgId;
inMsgId.read(from, otherEnd);
bool isReply = ((inMsgId.v & 0x03) == 1); bool isReply = ((inMsgId.v & 0x03) == 1);
if (!isReply && ((inMsgId.v & 0x03) != 3)) { if (!isReply && ((inMsgId.v & 0x03) != 3)) {
LOG(("Message Error: bad msg_id %1 in contained message received").arg(inMsgId.v)); LOG(("Message Error: bad msg_id %1 in contained message received").arg(inMsgId.v));
return HandleResult::RestartConnection; return HandleResult::RestartConnection;
} }
MTPint inSeqNo(from, otherEnd); MTPint inSeqNo;
MTPint bytes(from, otherEnd); inSeqNo.read(from, otherEnd);
MTPint bytes;
bytes.read(from, otherEnd);
if ((bytes.v & 0x03) || bytes.v < 4) { if ((bytes.v & 0x03) || bytes.v < 4) {
LOG(("Message Error: bad length %1 of contained message received").arg(bytes.v)); LOG(("Message Error: bad length %1 of contained message received").arg(bytes.v));
return HandleResult::RestartConnection; return HandleResult::RestartConnection;
@ -1565,7 +1568,8 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
} return HandleResult::Success; } return HandleResult::Success;
case mtpc_msgs_ack: { case mtpc_msgs_ack: {
MTPMsgsAck msg(from, end); MTPMsgsAck msg;
msg.read(from, end);
const auto &ids(msg.c_msgs_ack().vmsg_ids.c_vector().v); const auto &ids(msg.c_msgs_ack().vmsg_ids.c_vector().v);
uint32 idsCount = ids.size(); uint32 idsCount = ids.size();
@ -1583,7 +1587,8 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
} return HandleResult::Success; } return HandleResult::Success;
case mtpc_bad_msg_notification: { case mtpc_bad_msg_notification: {
MTPBadMsgNotification msg(from, end); MTPBadMsgNotification msg;
msg.read(from, end);
const auto &data(msg.c_bad_msg_notification()); const auto &data(msg.c_bad_msg_notification());
LOG(("Message Info: bad message notification received (error_code %3) for msg_id = %1, seq_no = %2").arg(data.vbad_msg_id.v).arg(data.vbad_msg_seqno.v).arg(data.verror_code.v)); LOG(("Message Info: bad message notification received (error_code %3) for msg_id = %1, seq_no = %2").arg(data.vbad_msg_id.v).arg(data.vbad_msg_seqno.v).arg(data.verror_code.v));
@ -1659,7 +1664,8 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
} return HandleResult::Success; } return HandleResult::Success;
case mtpc_bad_server_salt: { case mtpc_bad_server_salt: {
MTPBadMsgNotification msg(from, end); MTPBadMsgNotification msg;
msg.read(from, end);
const auto &data(msg.c_bad_server_salt()); const auto &data(msg.c_bad_server_salt());
DEBUG_LOG(("Message Info: bad server salt received (error_code %4) for msg_id = %1, seq_no = %2, new salt: %3").arg(data.vbad_msg_id.v).arg(data.vbad_msg_seqno.v).arg(data.vnew_server_salt.v).arg(data.verror_code.v)); DEBUG_LOG(("Message Info: bad server salt received (error_code %4) for msg_id = %1, seq_no = %2, new salt: %3").arg(data.vbad_msg_id.v).arg(data.vbad_msg_seqno.v).arg(data.vnew_server_salt.v).arg(data.verror_code.v));
@ -1693,7 +1699,8 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
DEBUG_LOG(("Message Info: skipping with bad time...")); DEBUG_LOG(("Message Info: skipping with bad time..."));
return HandleResult::Ignored; return HandleResult::Ignored;
} }
MTPMsgsStateReq msg(from, end); MTPMsgsStateReq msg;
msg.read(from, end);
const auto &ids(msg.c_msgs_state_req().vmsg_ids.c_vector().v); const auto &ids(msg.c_msgs_state_req().vmsg_ids.c_vector().v);
uint32 idsCount = ids.size(); uint32 idsCount = ids.size();
DEBUG_LOG(("Message Info: msgs_state_req received, ids: %1").arg(Logs::vector(ids))); DEBUG_LOG(("Message Info: msgs_state_req received, ids: %1").arg(Logs::vector(ids)));
@ -1740,7 +1747,8 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
} return HandleResult::Success; } return HandleResult::Success;
case mtpc_msgs_state_info: { case mtpc_msgs_state_info: {
MTPMsgsStateInfo msg(from, end); MTPMsgsStateInfo msg;
msg.read(from, end);
const auto &data(msg.c_msgs_state_info()); const auto &data(msg.c_msgs_state_info());
uint64 reqMsgId = data.vreq_msg_id.v; uint64 reqMsgId = data.vreq_msg_id.v;
@ -1776,10 +1784,12 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
try { try {
const mtpPrime *rFrom = requestBuffer->constData() + 8, *rEnd = requestBuffer->constData() + requestBuffer->size(); const mtpPrime *rFrom = requestBuffer->constData() + 8, *rEnd = requestBuffer->constData() + requestBuffer->size();
if (mtpTypeId(*rFrom) == mtpc_msgs_state_req) { if (mtpTypeId(*rFrom) == mtpc_msgs_state_req) {
MTPMsgsStateReq request(rFrom, rEnd); MTPMsgsStateReq request;
request.read(rFrom, rEnd);
handleMsgsStates(request.c_msgs_state_req().vmsg_ids.c_vector().v, states, toAck); handleMsgsStates(request.c_msgs_state_req().vmsg_ids.c_vector().v, states, toAck);
} else { } else {
MTPMsgResendReq request(rFrom, rEnd); MTPMsgResendReq request;
request.read(rFrom, rEnd);
handleMsgsStates(request.c_msg_resend_req().vmsg_ids.c_vector().v, states, toAck); handleMsgsStates(request.c_msg_resend_req().vmsg_ids.c_vector().v, states, toAck);
} }
} catch(Exception &) { } catch(Exception &) {
@ -1796,7 +1806,8 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
return HandleResult::Ignored; return HandleResult::Ignored;
} }
MTPMsgsAllInfo msg(from, end); MTPMsgsAllInfo msg;
msg.read(from, end);
const auto &data(msg.c_msgs_all_info()); const auto &data(msg.c_msgs_all_info());
const auto &ids(data.vmsg_ids.c_vector().v); const auto &ids(data.vmsg_ids.c_vector().v);
const auto &states(data.vinfo.c_string().v); const auto &states(data.vinfo.c_string().v);
@ -1810,7 +1821,8 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
} return HandleResult::Success; } return HandleResult::Success;
case mtpc_msg_detailed_info: { case mtpc_msg_detailed_info: {
MTPMsgDetailedInfo msg(from, end); MTPMsgDetailedInfo msg;
msg.read(from, end);
const auto &data(msg.c_msg_detailed_info()); const auto &data(msg.c_msg_detailed_info());
DEBUG_LOG(("Message Info: msg detailed info, sent msgId %1, answerId %2, status %3, bytes %4").arg(data.vmsg_id.v).arg(data.vanswer_msg_id.v).arg(data.vstatus.v).arg(data.vbytes.v)); DEBUG_LOG(("Message Info: msg detailed info, sent msgId %1, answerId %2, status %3, bytes %4").arg(data.vmsg_id.v).arg(data.vanswer_msg_id.v).arg(data.vstatus.v).arg(data.vbytes.v));
@ -1845,7 +1857,8 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
DEBUG_LOG(("Message Info: skipping msg_new_detailed_info with bad time...")); DEBUG_LOG(("Message Info: skipping msg_new_detailed_info with bad time..."));
return HandleResult::Ignored; return HandleResult::Ignored;
} }
MTPMsgDetailedInfo msg(from, end); MTPMsgDetailedInfo msg;
msg.read(from, end);
const auto &data(msg.c_msg_new_detailed_info()); const auto &data(msg.c_msg_new_detailed_info());
DEBUG_LOG(("Message Info: msg new detailed info, answerId %2, status %3, bytes %4").arg(data.vanswer_msg_id.v).arg(data.vstatus.v).arg(data.vbytes.v)); DEBUG_LOG(("Message Info: msg new detailed info, answerId %2, status %3, bytes %4").arg(data.vanswer_msg_id.v).arg(data.vstatus.v).arg(data.vbytes.v));
@ -1865,7 +1878,8 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
} return HandleResult::Success; } return HandleResult::Success;
case mtpc_msg_resend_req: { case mtpc_msg_resend_req: {
MTPMsgResendReq msg(from, end); MTPMsgResendReq msg;
msg.read(from, end);
const auto &ids(msg.c_msg_resend_req().vmsg_ids.c_vector().v); const auto &ids(msg.c_msg_resend_req().vmsg_ids.c_vector().v);
uint32 idsCount = ids.size(); uint32 idsCount = ids.size();
@ -1883,7 +1897,8 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
if (from + 3 > end) throw mtpErrorInsufficient(); if (from + 3 > end) throw mtpErrorInsufficient();
mtpResponse response; mtpResponse response;
MTPlong reqMsgId(++from, end); MTPlong reqMsgId;
reqMsgId.read(++from, end);
mtpTypeId typeId = from[0]; mtpTypeId typeId = from[0];
DEBUG_LOG(("RPC Info: response received for %1, queueing...").arg(reqMsgId.v)); DEBUG_LOG(("RPC Info: response received for %1, queueing...").arg(reqMsgId.v));
@ -1926,7 +1941,8 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
case mtpc_new_session_created: { case mtpc_new_session_created: {
const mtpPrime *start = from; const mtpPrime *start = from;
MTPNewSession msg(from, end); MTPNewSession msg;
msg.read(from, end);
const auto &data(msg.c_new_session_created()); const auto &data(msg.c_new_session_created());
if (badTime) { if (badTime) {
@ -1966,14 +1982,16 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
case mtpc_ping: { case mtpc_ping: {
if (badTime) return HandleResult::Ignored; if (badTime) return HandleResult::Ignored;
MTPPing msg(from, end); MTPPing msg;
msg.read(from, end);
DEBUG_LOG(("Message Info: ping received, ping_id: %1, sending pong...").arg(msg.vping_id.v)); DEBUG_LOG(("Message Info: ping received, ping_id: %1, sending pong...").arg(msg.vping_id.v));
emit sendPongAsync(msgId, msg.vping_id.v); emit sendPongAsync(msgId, msg.vping_id.v);
} return HandleResult::Success; } return HandleResult::Success;
case mtpc_pong: { case mtpc_pong: {
MTPPong msg(from, end); MTPPong msg;
msg.read(from, end);
const auto &data(msg.c_pong()); const auto &data(msg.c_pong());
DEBUG_LOG(("Message Info: pong received, msg_id: %1, ping_id: %2").arg(data.vmsg_id.v).arg(data.vping_id.v)); DEBUG_LOG(("Message Info: pong received, msg_id: %1, ping_id: %2").arg(data.vmsg_id.v).arg(data.vping_id.v));
@ -2025,7 +2043,8 @@ ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPr
} }
mtpBuffer ConnectionPrivate::ungzip(const mtpPrime *from, const mtpPrime *end) const { mtpBuffer ConnectionPrivate::ungzip(const mtpPrime *from, const mtpPrime *end) const {
MTPstring packed(from, end); // read packed string as serialized mtp string type MTPstring packed;
packed.read(from, end); // read packed string as serialized mtp string type
uint32 packedLen = packed.c_string().v.size(), unpackedChunk = packedLen, unpackedLen = 0; uint32 packedLen = packed.c_string().v.size(), unpackedChunk = packedLen, unpackedLen = 0;
mtpBuffer result; // * 4 because of mtpPrime type mtpBuffer result; // * 4 because of mtpPrime type
@ -2527,7 +2546,8 @@ void ConnectionPrivate::dhParamsAnswered() {
aesIgeDecrypt(&encDHStr[0], &decBuffer[0], encDHLen, _authKeyData->aesKey, _authKeyData->aesIV); aesIgeDecrypt(&encDHStr[0], &decBuffer[0], encDHLen, _authKeyData->aesKey, _authKeyData->aesIV);
const mtpPrime *from(&decBuffer[5]), *to(from), *end(from + (encDHBufLen - 5)); const mtpPrime *from(&decBuffer[5]), *to(from), *end(from + (encDHBufLen - 5));
MTPServer_DH_inner_data dh_inner(to, end); MTPServer_DH_inner_data dh_inner;
dh_inner.read(to, end);
const auto &dh_inner_data(dh_inner.c_server_DH_inner_data()); const auto &dh_inner_data(dh_inner.c_server_DH_inner_data());
if (dh_inner_data.vnonce != _authKeyData->nonce) { if (dh_inner_data.vnonce != _authKeyData->nonce) {
LOG(("AuthKey Error: received nonce <> sent nonce (in server_DH_inner_data)!")); LOG(("AuthKey Error: received nonce <> sent nonce (in server_DH_inner_data)!"));

View File

@ -31,32 +31,38 @@ QString mtpWrapNumber(float64 number) {
void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons, uint32 level, mtpPrime vcons) { void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons, uint32 level, mtpPrime vcons) {
switch (mtpTypeId(cons)) { switch (mtpTypeId(cons)) {
case mtpc_int: { case mtpc_int: {
MTPint value(from, end, cons); MTPint value;
value.read(from, end, cons);
to.add(mtpWrapNumber(value.v)).add(" [INT]"); to.add(mtpWrapNumber(value.v)).add(" [INT]");
} break; } break;
case mtpc_long: { case mtpc_long: {
MTPlong value(from, end, cons); MTPlong value;
value.read(from, end, cons);
to.add(mtpWrapNumber(value.v)).add(" [LONG]"); to.add(mtpWrapNumber(value.v)).add(" [LONG]");
} break; } break;
case mtpc_int128: { case mtpc_int128: {
MTPint128 value(from, end, cons); MTPint128 value;
value.read(from, end, cons);
to.add(mtpWrapNumber(value.h)).add(" * 2^64 + ").add(mtpWrapNumber(value.l)).add(" [INT128]"); to.add(mtpWrapNumber(value.h)).add(" * 2^64 + ").add(mtpWrapNumber(value.l)).add(" [INT128]");
} break; } break;
case mtpc_int256: { case mtpc_int256: {
MTPint256 value(from, end, cons); MTPint256 value;
value.read(from, end, cons);
to.add(mtpWrapNumber(value.h.h)).add(" * 2^192 + ").add(mtpWrapNumber(value.h.l)).add(" * 2^128 + ").add(mtpWrapNumber(value.l.h)).add(" * 2 ^ 64 + ").add(mtpWrapNumber(value.l.l)).add(" [INT256]"); to.add(mtpWrapNumber(value.h.h)).add(" * 2^192 + ").add(mtpWrapNumber(value.h.l)).add(" * 2^128 + ").add(mtpWrapNumber(value.l.h)).add(" * 2 ^ 64 + ").add(mtpWrapNumber(value.l.l)).add(" [INT256]");
} break; } break;
case mtpc_double: { case mtpc_double: {
MTPdouble value(from, end, cons); MTPdouble value;
value.read(from, end, cons);
to.add(mtpWrapNumber(value.v)).add(" [DOUBLE]"); to.add(mtpWrapNumber(value.v)).add(" [DOUBLE]");
} break; } break;
case mtpc_string: { case mtpc_string: {
MTPstring value(from, end, cons); MTPstring value;
value.read(from, end, cons);
QByteArray strUtf8(value.c_string().v.c_str(), value.c_string().v.length()); QByteArray strUtf8(value.c_string().v.c_str(), value.c_string().v.length());
QString str = QString::fromUtf8(strUtf8); QString str = QString::fromUtf8(strUtf8);
if (str.toUtf8() == strUtf8) { if (str.toUtf8() == strUtf8) {
@ -88,7 +94,8 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP
} break; } break;
case mtpc_gzip_packed: { case mtpc_gzip_packed: {
MTPstring packed(from, end); // read packed string as serialized mtp string type MTPstring packed;
packed.read(from, end); // read packed string as serialized mtp string type
uint32 packedLen = packed.c_string().v.size(), unpackedChunk = packedLen; uint32 packedLen = packed.c_string().v.size(), unpackedChunk = packedLen;
mtpBuffer result; // * 4 because of mtpPrime type mtpBuffer result; // * 4 because of mtpPrime type
result.resize(0); result.resize(0);

View File

@ -190,6 +190,7 @@ public:
mtpDataOwner &operator=(const mtpDataOwner &other) = default; mtpDataOwner &operator=(const mtpDataOwner &other) = default;
protected: protected:
mtpDataOwner() = default;
explicit mtpDataOwner(std::shared_ptr<const mtpData> &&data) : data(data) { explicit mtpDataOwner(std::shared_ptr<const mtpData> &&data) : data(data) {
} }
std::shared_ptr<const mtpData> data; std::shared_ptr<const mtpData> data;
@ -261,15 +262,11 @@ static const uint32 mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0])
template <typename bareT> template <typename bareT>
class MTPBoxed : public bareT { class MTPBoxed : public bareT {
public: public:
MTPBoxed() { MTPBoxed() = default;
}
MTPBoxed(const bareT &v) : bareT(v) { MTPBoxed(const bareT &v) : bareT(v) {
} }
MTPBoxed(const MTPBoxed<bareT> &v) : bareT(v) { MTPBoxed(const MTPBoxed<bareT> &v) : bareT(v) {
} }
MTPBoxed(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) {
read(from, end, cons);
}
MTPBoxed<bareT> &operator=(const bareT &v) { MTPBoxed<bareT> &operator=(const bareT &v) {
*((bareT*)this) = v; *((bareT*)this) = v;
@ -300,13 +297,9 @@ class MTPBoxed<MTPBoxed<T> > {
class MTPint { class MTPint {
public: public:
int32 v; int32 v = 0;
MTPint() { MTPint() = default;
}
MTPint(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_int) {
read(from, end, cons);
}
uint32 innerLength() const { uint32 innerLength() const {
return sizeof(int32); return sizeof(int32);
@ -337,14 +330,10 @@ using MTPInt = MTPBoxed<MTPint>;
template <typename Flags> template <typename Flags>
class MTPflags { class MTPflags {
public: public:
Flags v; Flags v = Flags(0);
static_assert(sizeof(Flags) == sizeof(int32), "MTPflags are allowed only wrapping int32 flag types!"); static_assert(sizeof(Flags) == sizeof(int32), "MTPflags are allowed only wrapping int32 flag types!");
MTPflags() { MTPflags() = default;
}
MTPflags(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_flags) {
read(from, end, cons);
}
uint32 innerLength() const { uint32 innerLength() const {
return sizeof(Flags); return sizeof(Flags);
@ -386,13 +375,9 @@ inline bool operator!=(const MTPint &a, const MTPint &b) {
class MTPlong { class MTPlong {
public: public:
uint64 v; uint64 v = 0;
MTPlong() { MTPlong() = default;
}
MTPlong(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_long) {
read(from, end, cons);
}
uint32 innerLength() const { uint32 innerLength() const {
return sizeof(uint64); return sizeof(uint64);
@ -431,14 +416,10 @@ inline bool operator!=(const MTPlong &a, const MTPlong &b) {
class MTPint128 { class MTPint128 {
public: public:
uint64 l; uint64 l = 0;
uint64 h; uint64 h = 0;
MTPint128() { MTPint128() = default;
}
MTPint128(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_int128) {
read(from, end, cons);
}
uint32 innerLength() const { uint32 innerLength() const {
return sizeof(uint64) + sizeof(uint64); return sizeof(uint64) + sizeof(uint64);
@ -483,11 +464,7 @@ public:
MTPint128 l; MTPint128 l;
MTPint128 h; MTPint128 h;
MTPint256() { MTPint256() = default;
}
MTPint256(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_int256) {
read(from, end, cons);
}
uint32 innerLength() const { uint32 innerLength() const {
return l.innerLength() + h.innerLength(); return l.innerLength() + h.innerLength();
@ -525,13 +502,9 @@ inline bool operator!=(const MTPint256 &a, const MTPint256 &b) {
class MTPdouble { class MTPdouble {
public: public:
float64 v; float64 v = 0.;
MTPdouble() { MTPdouble() = default;
}
MTPdouble(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_double) {
read(from, end, cons);
}
uint32 innerLength() const { uint32 innerLength() const {
return sizeof(float64); return sizeof(float64);
@ -590,11 +563,7 @@ public:
class MTPstring : private mtpDataOwner { class MTPstring : private mtpDataOwner {
public: public:
MTPstring() : mtpDataOwner(nullptr) { MTPstring() = default;
}
MTPstring(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_string) : mtpDataOwner(0) {
read(from, end, cons);
}
const MTPDstring &c_string() const { const MTPDstring &c_string() const {
t_assert(data != nullptr); t_assert(data != nullptr);
@ -725,11 +694,7 @@ public:
template <typename T> template <typename T>
class MTPvector : private mtpDataOwner { class MTPvector : private mtpDataOwner {
public: public:
MTPvector() : mtpDataOwner(nullptr) { MTPvector() = default;
}
MTPvector(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_vector) : mtpDataOwner(0) {
read(from, end, cons);
}
const MTPDvector<T> &c_vector() const { const MTPDvector<T> &c_vector() const {
t_assert(data != nullptr); t_assert(data != nullptr);
@ -749,12 +714,11 @@ public:
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_vector) { void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_vector) {
if (from + 1 > end) throw mtpErrorInsufficient(); if (from + 1 > end) throw mtpErrorInsufficient();
if (cons != mtpc_vector) throw mtpErrorUnexpected(cons, "MTPvector"); if (cons != mtpc_vector) throw mtpErrorUnexpected(cons, "MTPvector");
uint32 count = (uint32)*(from++); auto count = static_cast<uint32>(*(from++));
auto vector = QVector<T>(); auto vector = QVector<T>(count, T());
vector.reserve(count); for (auto &item : vector) {
for (auto i = 0; i != count; ++i) { item.read(from, end);
vector.push_back(T(from, end));
} }
data = std::make_shared<MTPDvector<T>>(std::move(vector)); data = std::make_shared<MTPDvector<T>>(std::move(vector));
} }

View File

@ -345,8 +345,7 @@ with open('scheme.tl') as f:
prmsStr.append('const ' + ptypeFull + ' &_' + paramName); prmsStr.append('const ' + ptypeFull + ' &_' + paramName);
funcsText += '\n'; funcsText += '\n';
funcsText += '\tMTP' + name + '() {\n\t}\n'; # constructor funcsText += '\tMTP' + name + '() = default;\n'; # constructor
funcsText += '\tMTP' + name + '(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_' + name + ') {\n\t\tread(from, end, cons);\n\t}\n'; # stream constructor
if (len(prms) > len(trivialConditions)): if (len(prms) > len(trivialConditions)):
funcsText += '\tMTP' + name + '(' + ', '.join(prmsStr) + ') : ' + ', '.join(prmsInit) + ' {\n\t}\n'; funcsText += '\tMTP' + name + '(' + ', '.join(prmsStr) + ') : ' + ', '.join(prmsInit) + ' {\n\t}\n';
@ -399,7 +398,7 @@ with open('scheme.tl') as f:
funcsText += 'template <typename TQueryType>\n'; funcsText += 'template <typename TQueryType>\n';
funcsText += 'class MTP' + Name + ' : public MTPBoxed<MTP' + name + '<TQueryType> > {\n'; funcsText += 'class MTP' + Name + ' : public MTPBoxed<MTP' + name + '<TQueryType> > {\n';
funcsText += 'public:\n'; funcsText += 'public:\n';
funcsText += '\tMTP' + Name + '() {\n\t}\n'; funcsText += '\tMTP' + Name + '() = default;\n';
funcsText += '\tMTP' + Name + '(const MTP' + name + '<TQueryType> &v) : MTPBoxed<MTP' + name + '<TQueryType> >(v) {\n\t}\n'; funcsText += '\tMTP' + Name + '(const MTP' + name + '<TQueryType> &v) : MTPBoxed<MTP' + name + '<TQueryType> >(v) {\n\t}\n';
if (len(prms) > len(trivialConditions)): if (len(prms) > len(trivialConditions)):
funcsText += '\tMTP' + Name + '(' + ', '.join(prmsStr) + ') : MTPBoxed<MTP' + name + '<TQueryType> >(MTP' + name + '<TQueryType>(' + ', '.join(prmsNames) + ')) {\n\t}\n'; funcsText += '\tMTP' + Name + '(' + ', '.join(prmsStr) + ') : MTPBoxed<MTP' + name + '<TQueryType> >(MTP' + name + '<TQueryType>(' + ', '.join(prmsNames) + ')) {\n\t}\n';
@ -407,9 +406,8 @@ with open('scheme.tl') as f:
else: else:
funcsText += 'class MTP' + Name + ' : public MTPBoxed<MTP' + name + '> {\n'; funcsText += 'class MTP' + Name + ' : public MTPBoxed<MTP' + name + '> {\n';
funcsText += 'public:\n'; funcsText += 'public:\n';
funcsText += '\tMTP' + Name + '() {\n\t}\n'; funcsText += '\tMTP' + Name + '() = default;\n';
funcsText += '\tMTP' + Name + '(const MTP' + name + ' &v) : MTPBoxed<MTP' + name + '>(v) {\n\t}\n'; funcsText += '\tMTP' + Name + '(const MTP' + name + ' &v) : MTPBoxed<MTP' + name + '>(v) {\n\t}\n';
funcsText += '\tMTP' + Name + '(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = 0) : MTPBoxed<MTP' + name + '>(from, end, cons) {\n\t}\n';
if (len(prms) > len(trivialConditions)): if (len(prms) > len(trivialConditions)):
funcsText += '\tMTP' + Name + '(' + ', '.join(prmsStr) + ') : MTPBoxed<MTP' + name + '>(MTP' + name + '(' + ', '.join(prmsNames) + ')) {\n\t}\n'; funcsText += '\tMTP' + Name + '(' + ', '.join(prmsStr) + ') : MTPBoxed<MTP' + name + '>(MTP' + name + '(' + ', '.join(prmsNames) + ')) {\n\t}\n';
funcsText += '};\n'; funcsText += '};\n';
@ -605,7 +603,7 @@ for restype in typesList:
dataText += '\tbool has_' + paramName + '() const { return v' + hasFlags + '.v & Flag::f_' + paramName + '; }\n'; dataText += '\tbool has_' + paramName + '() const { return v' + hasFlags + '.v & Flag::f_' + paramName + '; }\n';
dataText += '\n'; dataText += '\n';
dataText += '\tMTPD' + name + '() {\n\t}\n'; # default constructor dataText += '\tMTPD' + name + '() = default;\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 += 'data = std::make_shared<MTPD' + name + '>(); '; switchLines += 'data = std::make_shared<MTPD' + name + '>(); ';
@ -729,10 +727,7 @@ for restype in typesList:
typesText += 'public:\n'; typesText += 'public:\n';
typesText += '\tMTP' + restype + '()'; # default constructor typesText += '\tMTP' + restype + '()'; # default constructor
inits = []; inits = [];
if (withType): if not (withType):
if (withData):
inits.append('mtpDataOwner(nullptr)');
else:
if (withData): if (withData):
inits.append('mtpDataOwner(' + newFast + ')'); inits.append('mtpDataOwner(' + newFast + ')');
if (withData and not withType): if (withData and not withType):
@ -746,17 +741,6 @@ for restype in typesList:
typesText += ' : ' + ', '.join(inits); typesText += ' : ' + ', '.join(inits);
typesText += ' {\n\t}\n'; typesText += ' {\n\t}\n';
inits = [];
if (withData):
inits.append('mtpDataOwner(nullptr)');
typesText += '\tMTP' + restype + '(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons';
if (not withType):
typesText += ' = mtpc_' + name;
typesText += ')'; # read constructor
if (inits):
typesText += ' : ' + ', '.join(inits);
typesText += ' {\n\t\tread(from, end, cons);\n\t}\n';
if (withData): if (withData):
typesText += getters; typesText += getters;
@ -815,8 +799,6 @@ for restype in typesList:
if (withType): # by-type-id constructor if (withType): # by-type-id constructor
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):
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

View File

@ -733,9 +733,11 @@ void Instance::Private::execCallback(mtpRequestId requestId, const mtpPrime *fro
if (from >= end) throw mtpErrorInsufficient(); if (from >= end) throw mtpErrorInsufficient();
if (*from == mtpc_rpc_error) { if (*from == mtpc_rpc_error) {
RPCError err(MTPRpcError(from, end)); auto mtpError = MTPRpcError();
DEBUG_LOG(("RPC Info: error received, code %1, type %2, description: %3").arg(err.code()).arg(err.type()).arg(err.description())); mtpError.read(from, end);
if (!rpcErrorOccured(requestId, h, err)) { auto error = RPCError(mtpError);
DEBUG_LOG(("RPC Info: error received, code %1, type %2, description: %3").arg(error.code()).arg(error.type()).arg(error.description()));
if (!rpcErrorOccured(requestId, h, error)) {
QMutexLocker locker(&_parserMapLock); QMutexLocker locker(&_parserMapLock);
_parserMap.emplace(requestId, h); _parserMap.emplace(requestId, h);
return; return;

View File

@ -83,8 +83,9 @@ public:
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const = 0; virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const = 0;
virtual ~RPCAbstractDoneHandler() { virtual ~RPCAbstractDoneHandler() {
} }
}; };
typedef QSharedPointer<RPCAbstractDoneHandler> RPCDoneHandlerPtr; using RPCDoneHandlerPtr = QSharedPointer<RPCAbstractDoneHandler>;
class RPCAbstractFailHandler { // abstract fail class RPCAbstractFailHandler { // abstract fail
public: public:
@ -92,7 +93,7 @@ public:
virtual ~RPCAbstractFailHandler() { virtual ~RPCAbstractFailHandler() {
} }
}; };
typedef QSharedPointer<RPCAbstractFailHandler> RPCFailHandlerPtr; using RPCFailHandlerPtr = QSharedPointer<RPCAbstractFailHandler>;
struct RPCResponseHandler { struct RPCResponseHandler {
RPCResponseHandler() { RPCResponseHandler() {
@ -102,19 +103,21 @@ struct RPCResponseHandler {
RPCDoneHandlerPtr onDone; RPCDoneHandlerPtr onDone;
RPCFailHandlerPtr onFail; RPCFailHandlerPtr onFail;
}; };
inline RPCResponseHandler rpcCb(const RPCDoneHandlerPtr &onDone = RPCDoneHandlerPtr(), const RPCFailHandlerPtr &onFail = RPCFailHandlerPtr()) { inline RPCResponseHandler rpcCb(const RPCDoneHandlerPtr &onDone = RPCDoneHandlerPtr(), const RPCFailHandlerPtr &onFail = RPCFailHandlerPtr()) {
return RPCResponseHandler(onDone, onFail); return RPCResponseHandler(onDone, onFail);
} }
template <typename TReturn> template <typename TReturn>
class RPCDoneHandlerBare : public RPCAbstractDoneHandler { // done(from, end) class RPCDoneHandlerBare : public RPCAbstractDoneHandler { // done(from, end)
typedef TReturn (*CallbackType)(const mtpPrime *, const mtpPrime *); using CallbackType = TReturn (*)(const mtpPrime *, const mtpPrime *);
public: public:
RPCDoneHandlerBare(CallbackType onDone) : _onDone(onDone) { RPCDoneHandlerBare(CallbackType onDone) : _onDone(onDone) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
(*_onDone)(from, end); (*_onDone)(from, end);
} }
@ -125,12 +128,12 @@ private:
template <typename TReturn> template <typename TReturn>
class RPCDoneHandlerBareReq : public RPCAbstractDoneHandler { // done(from, end, req_id) class RPCDoneHandlerBareReq : public RPCAbstractDoneHandler { // done(from, end, req_id)
typedef TReturn (*CallbackType)(const mtpPrime *, const mtpPrime *, mtpRequestId); using CallbackType = TReturn (*)(const mtpPrime *, const mtpPrime *, mtpRequestId);
public: public:
RPCDoneHandlerBareReq(CallbackType onDone) : _onDone(onDone) { RPCDoneHandlerBareReq(CallbackType onDone) : _onDone(onDone) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
(*_onDone)(from, end, requestId); (*_onDone)(from, end, requestId);
} }
@ -141,13 +144,15 @@ private:
template <typename TReturn, typename TResponse> template <typename TReturn, typename TResponse>
class RPCDoneHandlerPlain : public RPCAbstractDoneHandler { // done(result) class RPCDoneHandlerPlain : public RPCAbstractDoneHandler { // done(result)
typedef TReturn (*CallbackType)(const TResponse &); using CallbackType = TReturn (*)(const TResponse &);
public: public:
RPCDoneHandlerPlain(CallbackType onDone) : _onDone(onDone) { RPCDoneHandlerPlain(CallbackType onDone) : _onDone(onDone) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
(*_onDone)(TResponse(from, end)); auto response = TResponse();
response.read(from, end);
(*_onDone)(std::move(responce));
} }
private: private:
@ -157,13 +162,15 @@ private:
template <typename TReturn, typename TResponse> template <typename TReturn, typename TResponse>
class RPCDoneHandlerReq : public RPCAbstractDoneHandler { // done(result, req_id) class RPCDoneHandlerReq : public RPCAbstractDoneHandler { // done(result, req_id)
typedef TReturn (*CallbackType)(const TResponse &, mtpRequestId); using CallbackType = TReturn (*)(const TResponse &, mtpRequestId);
public: public:
RPCDoneHandlerReq(CallbackType onDone) : _onDone(onDone) { RPCDoneHandlerReq(CallbackType onDone) : _onDone(onDone) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
(*_onDone)(TResponse(from, end), requestId); auto response = TResponse();
response.read(from, end);
(*_onDone)(std::move(response), requestId);
} }
private: private:
@ -173,12 +180,12 @@ private:
template <typename TReturn> template <typename TReturn>
class RPCDoneHandlerNo : public RPCAbstractDoneHandler { // done() class RPCDoneHandlerNo : public RPCAbstractDoneHandler { // done()
typedef TReturn (*CallbackType)(); using CallbackType = TReturn (*)();
public: public:
RPCDoneHandlerNo(CallbackType onDone) : _onDone(onDone) { RPCDoneHandlerNo(CallbackType onDone) : _onDone(onDone) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
(*_onDone)(); (*_onDone)();
} }
@ -189,7 +196,7 @@ private:
template <typename TReturn> template <typename TReturn>
class RPCDoneHandlerNoReq : public RPCAbstractDoneHandler { // done(req_id) class RPCDoneHandlerNoReq : public RPCAbstractDoneHandler { // done(req_id)
typedef TReturn (*CallbackType)(mtpRequestId); using CallbackType = TReturn (*)(mtpRequestId);
public: public:
RPCDoneHandlerNoReq(CallbackType onDone) : _onDone(onDone) { RPCDoneHandlerNoReq(CallbackType onDone) : _onDone(onDone) {
@ -204,12 +211,12 @@ private:
}; };
class RPCFailHandlerPlain : public RPCAbstractFailHandler { // fail(error) class RPCFailHandlerPlain : public RPCAbstractFailHandler { // fail(error)
typedef bool (*CallbackType)(const RPCError &); using CallbackType = bool (*)(const RPCError &);
public: public:
RPCFailHandlerPlain(CallbackType onFail) : _onFail(onFail) { RPCFailHandlerPlain(CallbackType onFail) : _onFail(onFail) {
} }
virtual bool operator()(mtpRequestId requestId, const RPCError &e) const { bool operator()(mtpRequestId requestId, const RPCError &e) const override {
return (*_onFail)(e); return (*_onFail)(e);
} }
@ -219,12 +226,12 @@ private:
}; };
class RPCFailHandlerReq : public RPCAbstractFailHandler { // fail(error, req_id) class RPCFailHandlerReq : public RPCAbstractFailHandler { // fail(error, req_id)
typedef bool (*CallbackType)(const RPCError &, mtpRequestId); using CallbackType = bool (*)(const RPCError &, mtpRequestId);
public: public:
RPCFailHandlerReq(CallbackType onFail) : _onFail(onFail) { RPCFailHandlerReq(CallbackType onFail) : _onFail(onFail) {
} }
virtual bool operator()(mtpRequestId requestId, const RPCError &e) const { bool operator()(mtpRequestId requestId, const RPCError &e) const override {
return (*_onFail)(e, requestId); return (*_onFail)(e, requestId);
} }
@ -234,12 +241,12 @@ private:
}; };
class RPCFailHandlerNo : public RPCAbstractFailHandler { // fail() class RPCFailHandlerNo : public RPCAbstractFailHandler { // fail()
typedef bool (*CallbackType)(); using CallbackType = bool (*)();
public: public:
RPCFailHandlerNo(CallbackType onFail) : _onFail(onFail) { RPCFailHandlerNo(CallbackType onFail) : _onFail(onFail) {
} }
virtual bool operator()(mtpRequestId requestId, const RPCError &e) const { bool operator()(mtpRequestId requestId, const RPCError &e) const override {
return (*_onFail)(); return (*_onFail)();
} }
@ -249,12 +256,12 @@ private:
}; };
class RPCFailHandlerNoReq : public RPCAbstractFailHandler { // fail(req_id) class RPCFailHandlerNoReq : public RPCAbstractFailHandler { // fail(req_id)
typedef bool (*CallbackType)(mtpRequestId); using CallbackType = bool (*)(mtpRequestId);
public: public:
RPCFailHandlerNoReq(CallbackType onFail) : _onFail(onFail) { RPCFailHandlerNoReq(CallbackType onFail) : _onFail(onFail) {
} }
virtual bool operator()(mtpRequestId requestId, const RPCError &e) const { bool operator()(mtpRequestId requestId, const RPCError &e) const override {
return (*_onFail)(requestId); return (*_onFail)(requestId);
} }
@ -269,8 +276,10 @@ struct RPCCallbackClear {
mtpRequestId requestId; mtpRequestId requestId;
int32 errorCode; int32 errorCode;
}; };
typedef QVector<RPCCallbackClear> RPCCallbackClears;
using RPCCallbackClears = QVector<RPCCallbackClear> ;
template <typename TReturn> template <typename TReturn>
inline RPCDoneHandlerPtr rpcDone(TReturn (*onDone)(const mtpPrime *, const mtpPrime *)) { // done(from, end) inline RPCDoneHandlerPtr rpcDone(TReturn (*onDone)(const mtpPrime *, const mtpPrime *)) { // done(from, end)
@ -324,34 +333,36 @@ class RPCOwnedDoneHandler : public RPCAbstractDoneHandler { // abstract done
public: public:
RPCOwnedDoneHandler(RPCSender *owner); RPCOwnedDoneHandler(RPCSender *owner);
void invalidate() { void invalidate() {
_owner = 0; _owner = nullptr;
} }
~RPCOwnedDoneHandler(); ~RPCOwnedDoneHandler();
protected: protected:
RPCSender *_owner; RPCSender *_owner = nullptr;
}; };
class RPCOwnedFailHandler : public RPCAbstractFailHandler { // abstract fail class RPCOwnedFailHandler : public RPCAbstractFailHandler { // abstract fail
public: public:
RPCOwnedFailHandler(RPCSender *owner); RPCOwnedFailHandler(RPCSender *owner);
void invalidate() { void invalidate() {
_owner = 0; _owner = nullptr;
} }
~RPCOwnedFailHandler(); ~RPCOwnedFailHandler();
protected: protected:
RPCSender *_owner; RPCSender *_owner = nullptr;
}; };
template <typename TReturn, typename TReceiver> template <typename TReturn, typename TReceiver>
class RPCDoneHandlerBareOwned : public RPCOwnedDoneHandler { // done(from, end) class RPCDoneHandlerBareOwned : public RPCOwnedDoneHandler { // done(from, end)
typedef TReturn (TReceiver::*CallbackType)(const mtpPrime *, const mtpPrime *); using CallbackType = TReturn (TReceiver::*)(const mtpPrime *, const mtpPrime *);
public: public:
RPCDoneHandlerBareOwned(TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone) { RPCDoneHandlerBareOwned(TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(from, end); if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(from, end);
} }
@ -362,12 +373,12 @@ private:
template <typename TReturn, typename TReceiver> template <typename TReturn, typename TReceiver>
class RPCDoneHandlerBareOwnedReq : public RPCOwnedDoneHandler { // done(from, end, req_id) class RPCDoneHandlerBareOwnedReq : public RPCOwnedDoneHandler { // done(from, end, req_id)
typedef TReturn (TReceiver::*CallbackType)(const mtpPrime *, const mtpPrime *, mtpRequestId); using CallbackType = TReturn (TReceiver::*)(const mtpPrime *, const mtpPrime *, mtpRequestId);
public: public:
RPCDoneHandlerBareOwnedReq(TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone) { RPCDoneHandlerBareOwnedReq(TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(from, end, requestId); if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(from, end, requestId);
} }
@ -378,13 +389,17 @@ private:
template <typename TReturn, typename TReceiver, typename TResponse> template <typename TReturn, typename TReceiver, typename TResponse>
class RPCDoneHandlerOwned : public RPCOwnedDoneHandler { // done(result) class RPCDoneHandlerOwned : public RPCOwnedDoneHandler { // done(result)
typedef TReturn (TReceiver::*CallbackType)(const TResponse &); using CallbackType = TReturn (TReceiver::*)(const TResponse &);
public: public:
RPCDoneHandlerOwned(TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone) { RPCDoneHandlerOwned(TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(TResponse(from, end)); if (_owner) {
auto response = TResponse();
response.read(from, end);
(static_cast<TReceiver*>(_owner)->*_onDone)(std::move(response));
}
} }
private: private:
@ -394,13 +409,17 @@ private:
template <typename TReturn, typename TReceiver, typename TResponse> template <typename TReturn, typename TReceiver, typename TResponse>
class RPCDoneHandlerOwnedReq : public RPCOwnedDoneHandler { // done(result, req_id) class RPCDoneHandlerOwnedReq : public RPCOwnedDoneHandler { // done(result, req_id)
typedef TReturn (TReceiver::*CallbackType)(const TResponse &, mtpRequestId); using CallbackType = TReturn (TReceiver::*)(const TResponse &, mtpRequestId);
public: public:
RPCDoneHandlerOwnedReq(TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone) { RPCDoneHandlerOwnedReq(TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(TResponse(from, end), requestId); if (_owner) {
auto response = TResponse();
response.read(from, end);
(static_cast<TReceiver*>(_owner)->*_onDone)(std::move(response), requestId);
}
} }
private: private:
@ -410,12 +429,12 @@ private:
template <typename TReturn, typename TReceiver> template <typename TReturn, typename TReceiver>
class RPCDoneHandlerOwnedNo : public RPCOwnedDoneHandler { // done() class RPCDoneHandlerOwnedNo : public RPCOwnedDoneHandler { // done()
typedef TReturn (TReceiver::*CallbackType)(); using CallbackType = TReturn (TReceiver::*)();
public: public:
RPCDoneHandlerOwnedNo(TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone) { RPCDoneHandlerOwnedNo(TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(); if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)();
} }
@ -426,12 +445,12 @@ private:
template <typename TReturn, typename TReceiver> template <typename TReturn, typename TReceiver>
class RPCDoneHandlerOwnedNoReq : public RPCOwnedDoneHandler { // done(req_id) class RPCDoneHandlerOwnedNoReq : public RPCOwnedDoneHandler { // done(req_id)
typedef TReturn (TReceiver::*CallbackType)(mtpRequestId); using CallbackType = TReturn (TReceiver::*)(mtpRequestId);
public: public:
RPCDoneHandlerOwnedNoReq(TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone) { RPCDoneHandlerOwnedNoReq(TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(requestId); if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(requestId);
} }
@ -442,12 +461,12 @@ private:
template <typename T, typename TReturn, typename TReceiver> template <typename T, typename TReturn, typename TReceiver>
class RPCBindedDoneHandlerBareOwned : public RPCOwnedDoneHandler { // done(b, from, end) class RPCBindedDoneHandlerBareOwned : public RPCOwnedDoneHandler { // done(b, from, end)
typedef TReturn (TReceiver::*CallbackType)(T, const mtpPrime *, const mtpPrime *); using CallbackType = TReturn (TReceiver::*)(T, const mtpPrime *, const mtpPrime *);
public: public:
RPCBindedDoneHandlerBareOwned(T b, TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _b(b), _onDone(onDone) { RPCBindedDoneHandlerBareOwned(T b, TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _b(b), _onDone(onDone) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(_b, from, end); if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(_b, from, end);
} }
@ -459,12 +478,12 @@ private:
template <typename T, typename TReturn, typename TReceiver> template <typename T, typename TReturn, typename TReceiver>
class RPCBindedDoneHandlerBareOwnedReq : public RPCOwnedDoneHandler { // done(b, from, end, req_id) class RPCBindedDoneHandlerBareOwnedReq : public RPCOwnedDoneHandler { // done(b, from, end, req_id)
typedef TReturn (TReceiver::*CallbackType)(T, const mtpPrime *, const mtpPrime *, mtpRequestId); using CallbackType = TReturn (TReceiver::*)(T, const mtpPrime *, const mtpPrime *, mtpRequestId);
public: public:
RPCBindedDoneHandlerBareOwnedReq(T b, TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _b(b), _onDone(onDone) { RPCBindedDoneHandlerBareOwnedReq(T b, TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _b(b), _onDone(onDone) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(_b, from, end, requestId); if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(_b, from, end, requestId);
} }
@ -476,13 +495,17 @@ private:
template <typename T, typename TReturn, typename TReceiver, typename TResponse> template <typename T, typename TReturn, typename TReceiver, typename TResponse>
class RPCBindedDoneHandlerOwned : public RPCOwnedDoneHandler { // done(b, result) class RPCBindedDoneHandlerOwned : public RPCOwnedDoneHandler { // done(b, result)
typedef TReturn (TReceiver::*CallbackType)(T, const TResponse &); using CallbackType = TReturn (TReceiver::*)(T, const TResponse &);
public: public:
RPCBindedDoneHandlerOwned(T b, TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone), _b(b) { RPCBindedDoneHandlerOwned(T b, TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone), _b(b) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(_b, TResponse(from, end)); if (_owner) {
auto response = TResponse();
response.read(from, end);
(static_cast<TReceiver*>(_owner)->*_onDone)(_b, std::move(response));
}
} }
private: private:
@ -493,13 +516,17 @@ private:
template <typename T, typename TReturn, typename TReceiver, typename TResponse> template <typename T, typename TReturn, typename TReceiver, typename TResponse>
class RPCBindedDoneHandlerOwnedReq : public RPCOwnedDoneHandler { // done(b, result, req_id) class RPCBindedDoneHandlerOwnedReq : public RPCOwnedDoneHandler { // done(b, result, req_id)
typedef TReturn (TReceiver::*CallbackType)(T, const TResponse &, mtpRequestId); using CallbackType = TReturn (TReceiver::*)(T, const TResponse &, mtpRequestId);
public: public:
RPCBindedDoneHandlerOwnedReq(T b, TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone), _b(b) { RPCBindedDoneHandlerOwnedReq(T b, TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _onDone(onDone), _b(b) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(_b, TResponse(from, end), requestId); if (_owner) {
auto response = TResponse();
response.read(from, end);
(static_cast<TReceiver*>(_owner)->*_onDone)(_b, std::move(response), requestId);
}
} }
private: private:
@ -510,12 +537,12 @@ private:
template <typename T, typename TReturn, typename TReceiver> template <typename T, typename TReturn, typename TReceiver>
class RPCBindedDoneHandlerOwnedNo : public RPCOwnedDoneHandler { // done(b) class RPCBindedDoneHandlerOwnedNo : public RPCOwnedDoneHandler { // done(b)
typedef TReturn (TReceiver::*CallbackType)(T); using CallbackType = TReturn (TReceiver::*)(T);
public: public:
RPCBindedDoneHandlerOwnedNo(T b, TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _b(b), _onDone(onDone) { RPCBindedDoneHandlerOwnedNo(T b, TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _b(b), _onDone(onDone) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(_b); if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(_b);
} }
@ -527,12 +554,12 @@ private:
template <typename T, typename TReturn, typename TReceiver> template <typename T, typename TReturn, typename TReceiver>
class RPCBindedDoneHandlerOwnedNoReq : public RPCOwnedDoneHandler { // done(b, req_id) class RPCBindedDoneHandlerOwnedNoReq : public RPCOwnedDoneHandler { // done(b, req_id)
typedef TReturn (TReceiver::*CallbackType)(T, mtpRequestId); using CallbackType = TReturn (TReceiver::*)(T, mtpRequestId);
public: public:
RPCBindedDoneHandlerOwnedNoReq(T b, TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _b(b), _onDone(onDone) { RPCBindedDoneHandlerOwnedNoReq(T b, TReceiver *receiver, CallbackType onDone) : RPCOwnedDoneHandler(receiver), _b(b), _onDone(onDone) {
} }
virtual void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(_b, requestId); if (_owner) (static_cast<TReceiver*>(_owner)->*_onDone)(_b, requestId);
} }
@ -544,12 +571,12 @@ private:
template <typename TReceiver> template <typename TReceiver>
class RPCFailHandlerOwned : public RPCOwnedFailHandler { // fail(error) class RPCFailHandlerOwned : public RPCOwnedFailHandler { // fail(error)
typedef bool (TReceiver::*CallbackType)(const RPCError &); using CallbackType = bool (TReceiver::*)(const RPCError &);
public: public:
RPCFailHandlerOwned(TReceiver *receiver, CallbackType onFail) : RPCOwnedFailHandler(receiver), _onFail(onFail) { RPCFailHandlerOwned(TReceiver *receiver, CallbackType onFail) : RPCOwnedFailHandler(receiver), _onFail(onFail) {
} }
virtual bool operator()(mtpRequestId requestId, const RPCError &e) const { bool operator()(mtpRequestId requestId, const RPCError &e) const override {
return _owner ? (static_cast<TReceiver*>(_owner)->*_onFail)(e) : true; return _owner ? (static_cast<TReceiver*>(_owner)->*_onFail)(e) : true;
} }
@ -560,12 +587,12 @@ private:
template <typename TReceiver> template <typename TReceiver>
class RPCFailHandlerOwnedReq : public RPCOwnedFailHandler { // fail(error, req_id) class RPCFailHandlerOwnedReq : public RPCOwnedFailHandler { // fail(error, req_id)
typedef bool (TReceiver::*CallbackType)(const RPCError &, mtpRequestId); using CallbackType = bool (TReceiver::*)(const RPCError &, mtpRequestId);
public: public:
RPCFailHandlerOwnedReq(TReceiver *receiver, CallbackType onFail) : RPCOwnedFailHandler(receiver), _onFail(onFail) { RPCFailHandlerOwnedReq(TReceiver *receiver, CallbackType onFail) : RPCOwnedFailHandler(receiver), _onFail(onFail) {
} }
virtual bool operator()(mtpRequestId requestId, const RPCError &e) const { bool operator()(mtpRequestId requestId, const RPCError &e) const override {
return _owner ? (static_cast<TReceiver*>(_owner)->*_onFail)(e, requestId) : true; return _owner ? (static_cast<TReceiver*>(_owner)->*_onFail)(e, requestId) : true;
} }
@ -576,12 +603,12 @@ private:
template <typename TReceiver> template <typename TReceiver>
class RPCFailHandlerOwnedNo : public RPCOwnedFailHandler { // fail() class RPCFailHandlerOwnedNo : public RPCOwnedFailHandler { // fail()
typedef bool (TReceiver::*CallbackType)(); using CallbackType = bool (TReceiver::*)();
public: public:
RPCFailHandlerOwnedNo(TReceiver *receiver, CallbackType onFail) : RPCOwnedFailHandler(receiver), _onFail(onFail) { RPCFailHandlerOwnedNo(TReceiver *receiver, CallbackType onFail) : RPCOwnedFailHandler(receiver), _onFail(onFail) {
} }
virtual bool operator()(mtpRequestId requestId, const RPCError &e) const { bool operator()(mtpRequestId requestId, const RPCError &e) const override {
return _owner ? (static_cast<TReceiver*>(_owner)->*_onFail)() : true; return _owner ? (static_cast<TReceiver*>(_owner)->*_onFail)() : true;
} }
@ -592,12 +619,12 @@ private:
template <typename TReceiver> template <typename TReceiver>
class RPCFailHandlerOwnedNoReq : public RPCOwnedFailHandler { // fail(req_id) class RPCFailHandlerOwnedNoReq : public RPCOwnedFailHandler { // fail(req_id)
typedef bool (TReceiver::*CallbackType)(mtpRequestId); using CallbackType = bool (TReceiver::*)(mtpRequestId);
public: public:
RPCFailHandlerOwnedNoReq(TReceiver *receiver, CallbackType onFail) : RPCOwnedFailHandler(receiver), _onFail(onFail) { RPCFailHandlerOwnedNoReq(TReceiver *receiver, CallbackType onFail) : RPCOwnedFailHandler(receiver), _onFail(onFail) {
} }
virtual bool operator()(mtpRequestId requestId, const RPCError &e) const { bool operator()(mtpRequestId requestId, const RPCError &e) const override {
return _owner ? (static_cast<TReceiver*>(_owner)->*_onFail)(requestId) : true; return _owner ? (static_cast<TReceiver*>(_owner)->*_onFail)(requestId) : true;
} }
@ -608,12 +635,12 @@ private:
template <typename T, typename TReceiver> template <typename T, typename TReceiver>
class RPCBindedFailHandlerOwned : public RPCOwnedFailHandler { // fail(b, error) class RPCBindedFailHandlerOwned : public RPCOwnedFailHandler { // fail(b, error)
typedef bool (TReceiver::*CallbackType)(T, const RPCError &); using CallbackType = bool (TReceiver::*)(T, const RPCError &);
public: public:
RPCBindedFailHandlerOwned(T b, TReceiver *receiver, CallbackType onFail) : RPCOwnedFailHandler(receiver), _onFail(onFail), _b(b) { RPCBindedFailHandlerOwned(T b, TReceiver *receiver, CallbackType onFail) : RPCOwnedFailHandler(receiver), _onFail(onFail), _b(b) {
} }
virtual bool operator()(mtpRequestId requestId, const RPCError &e) const { bool operator()(mtpRequestId requestId, const RPCError &e) const override {
return _owner ? (static_cast<TReceiver*>(_owner)->*_onFail)(_b, e) : true; return _owner ? (static_cast<TReceiver*>(_owner)->*_onFail)(_b, e) : true;
} }
@ -625,12 +652,12 @@ private:
template <typename T, typename TReceiver> template <typename T, typename TReceiver>
class RPCBindedFailHandlerOwnedReq : public RPCOwnedFailHandler { // fail(b, error, req_id) class RPCBindedFailHandlerOwnedReq : public RPCOwnedFailHandler { // fail(b, error, req_id)
typedef bool (TReceiver::*CallbackType)(T, const RPCError &, mtpRequestId); using CallbackType = bool (TReceiver::*)(T, const RPCError &, mtpRequestId);
public: public:
RPCBindedFailHandlerOwnedReq(T b, TReceiver *receiver, CallbackType onFail) : RPCOwnedFailHandler(receiver), _onFail(onFail), _b(b) { RPCBindedFailHandlerOwnedReq(T b, TReceiver *receiver, CallbackType onFail) : RPCOwnedFailHandler(receiver), _onFail(onFail), _b(b) {
} }
virtual bool operator()(mtpRequestId requestId, const RPCError &e) const { bool operator()(mtpRequestId requestId, const RPCError &e) const override {
return _owner ? (static_cast<TReceiver*>(_owner)->*_onFail)(_b, e, requestId) : true; return _owner ? (static_cast<TReceiver*>(_owner)->*_onFail)(_b, e, requestId) : true;
} }
@ -642,12 +669,12 @@ private:
template <typename T, typename TReceiver> template <typename T, typename TReceiver>
class RPCBindedFailHandlerOwnedNo : public RPCOwnedFailHandler { // fail(b) class RPCBindedFailHandlerOwnedNo : public RPCOwnedFailHandler { // fail(b)
typedef bool (TReceiver::*CallbackType)(T); using CallbackType = bool (TReceiver::*)(T);
public: public:
RPCBindedFailHandlerOwnedNo(T b, TReceiver *receiver, CallbackType onFail) : RPCOwnedFailHandler(receiver), _onFail(onFail), _b(b) { RPCBindedFailHandlerOwnedNo(T b, TReceiver *receiver, CallbackType onFail) : RPCOwnedFailHandler(receiver), _onFail(onFail), _b(b) {
} }
virtual bool operator()(mtpRequestId requestId, const RPCError &e) const { bool operator()(mtpRequestId requestId, const RPCError &e) const override {
return _owner ? (static_cast<TReceiver*>(_owner)->*_onFail)(_b) : true; return _owner ? (static_cast<TReceiver*>(_owner)->*_onFail)(_b) : true;
} }
@ -659,12 +686,12 @@ private:
template <typename T, typename TReceiver> template <typename T, typename TReceiver>
class RPCBindedFailHandlerOwnedNoReq : public RPCOwnedFailHandler { // fail(b, req_id) class RPCBindedFailHandlerOwnedNoReq : public RPCOwnedFailHandler { // fail(b, req_id)
typedef bool (TReceiver::*CallbackType)(T, mtpRequestId); using CallbackType = bool (TReceiver::*)(T, mtpRequestId);
public: public:
RPCBindedFailHandlerOwnedNoReq(T b, TReceiver *receiver, CallbackType onFail) : RPCOwnedFailHandler(receiver), _onFail(onFail), _b(b) { RPCBindedFailHandlerOwnedNoReq(T b, TReceiver *receiver, CallbackType onFail) : RPCOwnedFailHandler(receiver), _onFail(onFail), _b(b) {
} }
virtual bool operator()(mtpRequestId requestId, const RPCError &e) const { bool operator()(mtpRequestId requestId, const RPCError &e) const override {
return _owner ? (static_cast<TReceiver*>(_owner)->*_onFail)(_b, requestId) : true; return _owner ? (static_cast<TReceiver*>(_owner)->*_onFail)(_b, requestId) : true;
} }
@ -675,9 +702,9 @@ private:
}; };
class RPCSender { class RPCSender {
typedef QSet<RPCOwnedDoneHandler*> DoneHandlers; using DoneHandlers = QSet<RPCOwnedDoneHandler*>;
DoneHandlers _rpcDoneHandlers; DoneHandlers _rpcDoneHandlers;
typedef QSet<RPCOwnedFailHandler*> FailHandlers; using FailHandlers = QSet<RPCOwnedFailHandler*>;
FailHandlers _rpcFailHandlers; FailHandlers _rpcFailHandlers;
void _rpcRegHandler(RPCOwnedDoneHandler *handler) { void _rpcRegHandler(RPCOwnedDoneHandler *handler) {
@ -700,7 +727,6 @@ class RPCSender {
friend class RPCOwnedFailHandler; friend class RPCOwnedFailHandler;
public: public:
template <typename TReturn, typename TReceiver> // done(from, end) template <typename TReturn, typename TReceiver> // done(from, end)
RPCDoneHandlerPtr rpcDone(TReturn (TReceiver::*onDone)(const mtpPrime *, const mtpPrime *)) { RPCDoneHandlerPtr rpcDone(TReturn (TReceiver::*onDone)(const mtpPrime *, const mtpPrime *)) {
return RPCDoneHandlerPtr(new RPCDoneHandlerBareOwned<TReturn, TReceiver>(static_cast<TReceiver*>(this), onDone)); return RPCDoneHandlerPtr(new RPCDoneHandlerBareOwned<TReturn, TReceiver>(static_cast<TReceiver*>(this), onDone));
@ -810,7 +836,6 @@ public:
} }
protected: protected:
void rpcInvalidate() { void rpcInvalidate() {
for (DoneHandlers::iterator i = _rpcDoneHandlers.begin(), e = _rpcDoneHandlers.end(); i != e; ++i) { for (DoneHandlers::iterator i = _rpcDoneHandlers.begin(), e = _rpcDoneHandlers.end(); i != e; ++i) {
(*i)->invalidate(); (*i)->invalidate();
@ -824,8 +849,8 @@ protected:
}; };
typedef void (*MTPStateChangedHandler)(int32 dcId, int32 state); using MTPStateChangedHandler = void (*)(int32 dcId, int32 state);
typedef void(*MTPSessionResetHandler)(int32 dcId); using MTPSessionResetHandler = void (*)(int32 dcId);
template <typename Base, typename FunctionType> template <typename Base, typename FunctionType>
class RPCHandlerImplementation : public Base { class RPCHandlerImplementation : public Base {
@ -865,22 +890,30 @@ public:
}; };
template <typename R, typename T> template <typename R, typename TResponse>
class RPCDoneHandlerImplementationPlain : public RPCDoneHandlerImplementation<R(const T&)> { // done(result) class RPCDoneHandlerImplementationPlain : public RPCDoneHandlerImplementation<R(const TResponse&)> { // done(result)
public: public:
using RPCDoneHandlerImplementation<R(const T&)>::Parent::Parent; using RPCDoneHandlerImplementation<R(const TResponse&)>::Parent::Parent;
void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
return this->_handler ? this->_handler(T(from, end)) : void(0); if (this->_handler) {
auto response = TResponse();
response.read(from, end);
this->_handler(std::move(response));
}
} }
}; };
template <typename R, typename T> template <typename R, typename TResponse>
class RPCDoneHandlerImplementationReq : public RPCDoneHandlerImplementation<R(const T&, mtpRequestId)> { // done(result, req_id) class RPCDoneHandlerImplementationReq : public RPCDoneHandlerImplementation<R(const TResponse&, mtpRequestId)> { // done(result, req_id)
public: public:
using RPCDoneHandlerImplementation<R(const T&, mtpRequestId)>::Parent::Parent; using RPCDoneHandlerImplementation<R(const TResponse&, mtpRequestId)>::Parent::Parent;
void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override {
return this->_handler ? this->_handler(T(from, end), requestId) : void(0); if (this->_handler) {
auto response = TResponse();
response.read(from, end);
this->_handler(std::move(response), requestId);
}
} }
}; };

File diff suppressed because it is too large Load Diff