mirror of https://github.com/procxx/kepka.git
Move a lot of code from scheme.h to scheme.cpp.
This commit is contained in:
parent
1207ddb2ea
commit
c8810f87b9
|
@ -158,7 +158,7 @@ void StickerSetBox::Inner::gotSet(const MTPmessages_StickerSet &set) {
|
||||||
}
|
}
|
||||||
if (d.vset.type() == mtpc_stickerSet) {
|
if (d.vset.type() == mtpc_stickerSet) {
|
||||||
auto &s = d.vset.c_stickerSet();
|
auto &s = d.vset.c_stickerSet();
|
||||||
_setTitle = stickerSetTitle(s);
|
_setTitle = Stickers::GetSetTitle(s);
|
||||||
_setShortName = qs(s.vshort_name);
|
_setShortName = qs(s.vshort_name);
|
||||||
_setId = s.vid.v;
|
_setId = s.vid.v;
|
||||||
_setAccess = s.vaccess_hash.v;
|
_setAccess = s.vaccess_hash.v;
|
||||||
|
|
|
@ -524,7 +524,7 @@ void FeaturedSetsReceived(const QVector<MTPStickerSetCovered> &data, const QVect
|
||||||
|
|
||||||
if (set) {
|
if (set) {
|
||||||
auto it = sets.find(set->vid.v);
|
auto it = sets.find(set->vid.v);
|
||||||
auto title = stickerSetTitle(*set);
|
auto title = GetSetTitle(*set);
|
||||||
if (it == sets.cend()) {
|
if (it == sets.cend()) {
|
||||||
auto setClientFlags = MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_not_loaded;
|
auto setClientFlags = MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_not_loaded;
|
||||||
if (unreadMap.contains(set->vid.v)) {
|
if (unreadMap.contains(set->vid.v)) {
|
||||||
|
@ -684,7 +684,7 @@ std::vector<gsl::not_null<EmojiPtr>> GetEmojiListFromSet(gsl::not_null<DocumentD
|
||||||
Set *FeedSet(const MTPDstickerSet &set) {
|
Set *FeedSet(const MTPDstickerSet &set) {
|
||||||
auto &sets = Global::RefStickerSets();
|
auto &sets = Global::RefStickerSets();
|
||||||
auto it = sets.find(set.vid.v);
|
auto it = sets.find(set.vid.v);
|
||||||
auto title = stickerSetTitle(set);
|
auto title = GetSetTitle(set);
|
||||||
auto flags = MTPDstickerSet::Flags(0);
|
auto flags = MTPDstickerSet::Flags(0);
|
||||||
if (it == sets.cend()) {
|
if (it == sets.cend()) {
|
||||||
it = sets.insert(set.vid.v, Stickers::Set(set.vid.v, set.vaccess_hash.v, title, qs(set.vshort_name), set.vcount.v, set.vhash.v, set.vflags.v | MTPDstickerSet_ClientFlag::f_not_loaded));
|
it = sets.insert(set.vid.v, Stickers::Set(set.vid.v, set.vaccess_hash.v, title, qs(set.vshort_name), set.vcount.v, set.vhash.v, set.vflags.v | MTPDstickerSet_ClientFlag::f_not_loaded));
|
||||||
|
@ -807,6 +807,14 @@ Set *FeedSetFull(const MTPmessages_StickerSet &data) {
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString GetSetTitle(const MTPDstickerSet &s) {
|
||||||
|
auto title = qs(s.vtitle);
|
||||||
|
if ((s.vflags.v & MTPDstickerSet::Flag::f_official) && !title.compare(qstr("Great Minds"), Qt::CaseInsensitive)) {
|
||||||
|
return lang(lng_stickers_default_set);
|
||||||
|
}
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
FeaturedReader::FeaturedReader(QObject *parent) : QObject(parent)
|
FeaturedReader::FeaturedReader(QObject *parent) : QObject(parent)
|
||||||
|
|
|
@ -45,6 +45,8 @@ std::vector<gsl::not_null<EmojiPtr>> GetEmojiListFromSet(gsl::not_null<DocumentD
|
||||||
Set *FeedSet(const MTPDstickerSet &data);
|
Set *FeedSet(const MTPDstickerSet &data);
|
||||||
Set *FeedSetFull(const MTPmessages_StickerSet &data);
|
Set *FeedSetFull(const MTPmessages_StickerSet &data);
|
||||||
|
|
||||||
|
QString GetSetTitle(const MTPDstickerSet &s);
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
class FeaturedReader : public QObject, private MTP::Sender {
|
class FeaturedReader : public QObject, private MTP::Sender {
|
||||||
|
|
|
@ -83,6 +83,9 @@ funcsText = '';
|
||||||
typesText = '';
|
typesText = '';
|
||||||
dataTexts = '';
|
dataTexts = '';
|
||||||
creatorProxyText = '';
|
creatorProxyText = '';
|
||||||
|
factories = '';
|
||||||
|
flagOperators = '';
|
||||||
|
methods = '';
|
||||||
inlineMethods = '';
|
inlineMethods = '';
|
||||||
textSerializeInit = '';
|
textSerializeInit = '';
|
||||||
textSerializeMethods = '';
|
textSerializeMethods = '';
|
||||||
|
@ -297,6 +300,7 @@ with open(input_file) as f:
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if funcsNow:
|
if funcsNow:
|
||||||
|
methodBodies = ''
|
||||||
if (isTemplate != ''):
|
if (isTemplate != ''):
|
||||||
funcsText += '\ntemplate <typename TQueryType>';
|
funcsText += '\ntemplate <typename TQueryType>';
|
||||||
funcsText += '\nclass MTP' + name + ' { // RPC method \'' + nametype.group(1) + '\'\n'; # class
|
funcsText += '\nclass MTP' + name + ' { // RPC method \'' + nametype.group(1) + '\'\n'; # class
|
||||||
|
@ -318,7 +322,7 @@ with open(input_file) as f:
|
||||||
funcsText += '\n';
|
funcsText += '\n';
|
||||||
funcsText += '\t\tMAX_FIELD = (1 << ' + str(maxbit) + '),\n';
|
funcsText += '\t\tMAX_FIELD = (1 << ' + str(maxbit) + '),\n';
|
||||||
funcsText += '\t};\n';
|
funcsText += '\t};\n';
|
||||||
funcsText += '\tQ_DECLARE_FLAGS(Flags, Flag);\n';
|
funcsText += '\tusing Flags = QFlags<Flag>;\n';
|
||||||
funcsText += '\tfriend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }\n';
|
funcsText += '\tfriend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }\n';
|
||||||
funcsText += '\n';
|
funcsText += '\n';
|
||||||
if (len(conditions)):
|
if (len(conditions)):
|
||||||
|
@ -352,7 +356,12 @@ with open(input_file) as f:
|
||||||
funcsText += '\tMTP' + name + '(' + ', '.join(prmsStr) + ') : ' + ', '.join(prmsInit) + ' {\n\t}\n';
|
funcsText += '\tMTP' + name + '(' + ', '.join(prmsStr) + ') : ' + ', '.join(prmsInit) + ' {\n\t}\n';
|
||||||
|
|
||||||
funcsText += '\n';
|
funcsText += '\n';
|
||||||
funcsText += '\tuint32 innerLength() const {\n'; # count size
|
funcsText += '\tuint32 innerLength() const;\n'; # count size
|
||||||
|
if (isTemplate != ''):
|
||||||
|
methodBodies += 'template <typename TQueryType>\n'
|
||||||
|
methodBodies += 'uint32 MTP' + name + '<TQueryType>::innerLength() const {\n';
|
||||||
|
else:
|
||||||
|
methodBodies += 'uint32 MTP' + name + '::innerLength() const {\n';
|
||||||
size = [];
|
size = [];
|
||||||
for k in prmsList:
|
for k in prmsList:
|
||||||
v = prms[k];
|
v = prms[k];
|
||||||
|
@ -363,56 +372,56 @@ with open(input_file) as f:
|
||||||
size.append('v' + k + '.innerLength()');
|
size.append('v' + k + '.innerLength()');
|
||||||
if (not len(size)):
|
if (not len(size)):
|
||||||
size.append('0');
|
size.append('0');
|
||||||
funcsText += '\t\treturn ' + ' + '.join(size) + ';\n';
|
methodBodies += '\treturn ' + ' + '.join(size) + ';\n';
|
||||||
funcsText += '\t}\n';
|
methodBodies += '}\n';
|
||||||
|
|
||||||
funcsText += '\tmtpTypeId type() const {\n\t\treturn mtpc_' + name + ';\n\t}\n'; # type id
|
funcsText += '\tmtpTypeId type() const {\n\t\treturn mtpc_' + name + ';\n\t}\n'; # type id
|
||||||
|
|
||||||
funcsText += '\tvoid read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_' + name + ') {\n'; # read method
|
funcsText += '\tvoid read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_' + name + ');\n'; # read method
|
||||||
|
if (isTemplate != ''):
|
||||||
|
methodBodies += 'template <typename TQueryType>\n'
|
||||||
|
methodBodies += 'void MTP' + name + '<TQueryType>::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {\n';
|
||||||
|
else:
|
||||||
|
methodBodies += 'void MTP' + name + '::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {\n';
|
||||||
for k in prmsList:
|
for k in prmsList:
|
||||||
v = prms[k];
|
v = prms[k];
|
||||||
if (k in conditionsList):
|
if (k in conditionsList):
|
||||||
if (not k in trivialConditions):
|
if (not k in trivialConditions):
|
||||||
funcsText += '\t\tif (has_' + k + '()) { v' + k + '.read(from, end); } else { v' + k + ' = MTP' + v + '(); }\n';
|
methodBodies += '\tif (has_' + k + '()) { v' + k + '.read(from, end); } else { v' + k + ' = MTP' + v + '(); }\n';
|
||||||
else:
|
else:
|
||||||
funcsText += '\t\tv' + k + '.read(from, end);\n';
|
methodBodies += '\tv' + k + '.read(from, end);\n';
|
||||||
funcsText += '\t}\n';
|
methodBodies += '}\n';
|
||||||
|
|
||||||
funcsText += '\tvoid write(mtpBuffer &to) const {\n'; # write method
|
funcsText += '\tvoid write(mtpBuffer &to) const;\n'; # write method
|
||||||
|
if (isTemplate != ''):
|
||||||
|
methodBodies += 'template <typename TQueryType>\n'
|
||||||
|
methodBodies += 'void MTP' + name + '<TQueryType>::write(mtpBuffer &to) const {\n';
|
||||||
|
else:
|
||||||
|
methodBodies += 'void MTP' + name + '::write(mtpBuffer &to) const {\n';
|
||||||
for k in prmsList:
|
for k in prmsList:
|
||||||
v = prms[k];
|
v = prms[k];
|
||||||
if (k in conditionsList):
|
if (k in conditionsList):
|
||||||
if (not k in trivialConditions):
|
if (not k in trivialConditions):
|
||||||
funcsText += '\t\tif (has_' + k + '()) v' + k + '.write(to);\n';
|
methodBodies += '\tif (has_' + k + '()) v' + k + '.write(to);\n';
|
||||||
else:
|
else:
|
||||||
funcsText += '\t\tv' + k + '.write(to);\n';
|
methodBodies += '\tv' + k + '.write(to);\n';
|
||||||
funcsText += '\t}\n';
|
methodBodies += '}\n';
|
||||||
|
|
||||||
if (isTemplate != ''):
|
if (isTemplate != ''):
|
||||||
funcsText += '\n\tusing ResponseType = typename TQueryType::ResponseType;\n';
|
funcsText += '\n\tusing ResponseType = typename TQueryType::ResponseType;\n';
|
||||||
|
inlineMethods += methodBodies;
|
||||||
else:
|
else:
|
||||||
funcsText += '\n\tusing ResponseType = MTP' + resType + ';\n'; # method return type
|
funcsText += '\n\tusing ResponseType = MTP' + resType + ';\n'; # method return type
|
||||||
|
methods += methodBodies;
|
||||||
|
|
||||||
funcsText += '};\n'; # class ending
|
funcsText += '};\n'; # class ending
|
||||||
if (len(conditionsList)):
|
if (len(conditionsList)):
|
||||||
funcsText += 'Q_DECLARE_OPERATORS_FOR_FLAGS(MTP' + name + '::Flags)\n\n';
|
funcsText += 'Q_DECLARE_OPERATORS_FOR_FLAGS(MTP' + name + '::Flags)\n\n';
|
||||||
if (isTemplate != ''):
|
if (isTemplate != ''):
|
||||||
funcsText += 'template <typename TQueryType>\n';
|
funcsText += 'template <typename TQueryType>\n';
|
||||||
funcsText += 'class MTP' + Name + ' : public MTPBoxed<MTP' + name + '<TQueryType> > {\n';
|
funcsText += 'using MTP' + Name + ' = MTPBoxed<MTP' + name + '<TQueryType>>;\n';
|
||||||
funcsText += 'public:\n';
|
|
||||||
funcsText += '\tMTP' + Name + '() = default;\n';
|
|
||||||
funcsText += '\tMTP' + Name + '(const MTP' + name + '<TQueryType> &v) : MTPBoxed<MTP' + name + '<TQueryType> >(v) {\n\t}\n';
|
|
||||||
if (len(prms) > len(trivialConditions)):
|
|
||||||
funcsText += '\tMTP' + Name + '(' + ', '.join(prmsStr) + ') : MTPBoxed<MTP' + name + '<TQueryType> >(MTP' + name + '<TQueryType>(' + ', '.join(prmsNames) + ')) {\n\t}\n';
|
|
||||||
funcsText += '};\n';
|
|
||||||
else:
|
else:
|
||||||
funcsText += 'class MTP' + Name + ' : public MTPBoxed<MTP' + name + '> {\n';
|
funcsText += 'using MTP' + Name + ' = MTPBoxed<MTP' + name + '>;\n';
|
||||||
funcsText += 'public:\n';
|
|
||||||
funcsText += '\tMTP' + Name + '() = default;\n';
|
|
||||||
funcsText += '\tMTP' + Name + '(const MTP' + name + ' &v) : MTPBoxed<MTP' + name + '>(v) {\n\t}\n';
|
|
||||||
if (len(prms) > len(trivialConditions)):
|
|
||||||
funcsText += '\tMTP' + Name + '(' + ', '.join(prmsStr) + ') : MTPBoxed<MTP' + name + '>(MTP' + name + '(' + ', '.join(prmsNames) + ')) {\n\t}\n';
|
|
||||||
funcsText += '};\n';
|
|
||||||
funcs = funcs + 1;
|
funcs = funcs + 1;
|
||||||
|
|
||||||
if (not restype in funcsDict):
|
if (not restype in funcsDict):
|
||||||
|
@ -545,9 +554,11 @@ for restype in typesList:
|
||||||
v = typesDict[restype];
|
v = typesDict[restype];
|
||||||
resType = TypesDict[restype];
|
resType = TypesDict[restype];
|
||||||
withData = 0;
|
withData = 0;
|
||||||
creatorsText = '';
|
creatorsDeclarations = '';
|
||||||
|
creatorsBodies = '';
|
||||||
|
flagDeclarations = '';
|
||||||
constructsText = '';
|
constructsText = '';
|
||||||
constructsInline = '';
|
constructsBodies = '';
|
||||||
|
|
||||||
forwards += 'class MTP' + restype + ';\n';
|
forwards += 'class MTP' + restype + ';\n';
|
||||||
forwTypedefs += 'using MTP' + resType + ' = MTPBoxed<MTP' + restype + '>;\n';
|
forwTypedefs += 'using MTP' + resType + ' = MTPBoxed<MTP' + restype + '>;\n';
|
||||||
|
@ -594,7 +605,7 @@ for restype in typesList:
|
||||||
dataText += '\n';
|
dataText += '\n';
|
||||||
dataText += '\t\tMAX_FIELD = (1 << ' + str(maxbit) + '),\n';
|
dataText += '\t\tMAX_FIELD = (1 << ' + str(maxbit) + '),\n';
|
||||||
dataText += '\t};\n';
|
dataText += '\t};\n';
|
||||||
dataText += '\tQ_DECLARE_FLAGS(Flags, Flag);\n';
|
dataText += '\tusing Flags = QFlags<Flag>;\n';
|
||||||
dataText += '\tfriend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }\n';
|
dataText += '\tfriend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }\n';
|
||||||
dataText += '\n';
|
dataText += '\n';
|
||||||
if (len(conditions)):
|
if (len(conditions)):
|
||||||
|
@ -612,17 +623,17 @@ for restype in typesList:
|
||||||
withData = 1;
|
withData = 1;
|
||||||
|
|
||||||
getters += '\tconst MTPD' + name + ' &c_' + name + '() const;\n'; # const getter
|
getters += '\tconst MTPD' + name + ' &c_' + name + '() const;\n'; # const getter
|
||||||
constructsInline += 'inline const MTPD' + name + ' &MTP' + restype + '::c_' + name + '() const {\n';
|
constructsBodies += 'const MTPD' + name + ' &MTP' + restype + '::c_' + name + '() const {\n';
|
||||||
if (withType):
|
if (withType):
|
||||||
constructsInline += '\tt_assert(_type == mtpc_' + name + ');\n';
|
constructsBodies += '\tt_assert(_type == mtpc_' + name + ');\n';
|
||||||
constructsInline += '\treturn queryData<MTPD' + name + '>();\n';
|
constructsBodies += '\treturn queryData<MTPD' + name + '>();\n';
|
||||||
constructsInline += '}\n';
|
constructsBodies += '}\n';
|
||||||
|
|
||||||
constructsText += '\texplicit MTP' + restype + '(const MTPD' + name + ' *data);\n'; # by-data type constructor
|
constructsText += '\texplicit MTP' + restype + '(const MTPD' + name + ' *data);\n'; # by-data type constructor
|
||||||
constructsInline += 'inline MTP' + restype + '::MTP' + restype + '(const MTPD' + name + ' *data) : TypeDataOwner(data)';
|
constructsBodies += 'MTP' + restype + '::MTP' + restype + '(const MTPD' + name + ' *data) : TypeDataOwner(data)';
|
||||||
if (withType):
|
if (withType):
|
||||||
constructsInline += ', _type(mtpc_' + name + ')';
|
constructsBodies += ', _type(mtpc_' + name + ')';
|
||||||
constructsInline += ' {\n}\n';
|
constructsBodies += ' {\n}\n';
|
||||||
|
|
||||||
dataText += '\tMTPD' + name + '('; # params constructor
|
dataText += '\tMTPD' + name + '('; # params constructor
|
||||||
prmsStr = [];
|
prmsStr = [];
|
||||||
|
@ -689,10 +700,11 @@ for restype in typesList:
|
||||||
creatorProxyText += '\t\treturn MTP' + restype + '();\n';
|
creatorProxyText += '\t\treturn MTP' + restype + '();\n';
|
||||||
creatorProxyText += '\t}\n';
|
creatorProxyText += '\t}\n';
|
||||||
if (len(conditionsList)):
|
if (len(conditionsList)):
|
||||||
creatorsText += 'Q_DECLARE_OPERATORS_FOR_FLAGS(MTPD' + name + '::Flags)\n';
|
flagDeclarations += 'Q_DECLARE_OPERATORS_FOR_FLAGS(MTPD' + name + '::Flags)\n';
|
||||||
creatorsText += 'inline MTP' + restype + ' MTP_' + name + '(' + ', '.join(creatorParams) + ') {\n';
|
creatorsDeclarations += 'MTP' + restype + ' MTP_' + name + '(' + ', '.join(creatorParams) + ');\n';
|
||||||
creatorsText += '\treturn MTP::internal::TypeCreator::new_' + name + '(' + ', '.join(creatorParamsList) + ');\n';
|
creatorsBodies += 'MTP' + restype + ' MTP_' + name + '(' + ', '.join(creatorParams) + ') {\n';
|
||||||
creatorsText += '}\n';
|
creatorsBodies += '\treturn MTP::internal::TypeCreator::new_' + name + '(' + ', '.join(creatorParamsList) + ');\n';
|
||||||
|
creatorsBodies += '}\n';
|
||||||
|
|
||||||
if (withType):
|
if (withType):
|
||||||
reader += '\t\tcase mtpc_' + name + ': _type = cons; '; # read switch line
|
reader += '\t\tcase mtpc_' + name + ': _type = cons; '; # read switch line
|
||||||
|
@ -732,10 +744,10 @@ for restype in typesList:
|
||||||
inits.append('TypeDataOwner(' + newFast + ')');
|
inits.append('TypeDataOwner(' + newFast + ')');
|
||||||
if (withData and not withType):
|
if (withData and not withType):
|
||||||
typesText += ';\n';
|
typesText += ';\n';
|
||||||
inlineMethods += '\ninline MTP' + restype + '::MTP' + restype + '()';
|
methods += '\nMTP' + restype + '::MTP' + restype + '()';
|
||||||
if (inits):
|
if (inits):
|
||||||
inlineMethods += ' : ' + ', '.join(inits);
|
methods += ' : ' + ', '.join(inits);
|
||||||
inlineMethods += ' {\n}\n';
|
methods += ' {\n}\n';
|
||||||
else:
|
else:
|
||||||
if (inits):
|
if (inits):
|
||||||
typesText += ' : ' + ', '.join(inits);
|
typesText += ' : ' + ', '.join(inits);
|
||||||
|
@ -745,68 +757,68 @@ for restype in typesList:
|
||||||
typesText += getters;
|
typesText += getters;
|
||||||
|
|
||||||
typesText += '\n\tuint32 innerLength() const;\n'; # size method
|
typesText += '\n\tuint32 innerLength() const;\n'; # size method
|
||||||
inlineMethods += '\ninline uint32 MTP' + restype + '::innerLength() const {\n';
|
methods += '\nuint32 MTP' + restype + '::innerLength() const {\n';
|
||||||
if (withType and sizeCases):
|
if (withType and sizeCases):
|
||||||
inlineMethods += '\tswitch (_type) {\n';
|
methods += '\tswitch (_type) {\n';
|
||||||
inlineMethods += sizeCases;
|
methods += sizeCases;
|
||||||
inlineMethods += '\t}\n';
|
methods += '\t}\n';
|
||||||
inlineMethods += '\treturn 0;\n';
|
methods += '\treturn 0;\n';
|
||||||
else:
|
else:
|
||||||
inlineMethods += sizeFast;
|
methods += sizeFast;
|
||||||
inlineMethods += '}\n';
|
methods += '}\n';
|
||||||
|
|
||||||
typesText += '\tmtpTypeId type() const;\n'; # type id method
|
typesText += '\tmtpTypeId type() const;\n'; # type id method
|
||||||
inlineMethods += 'inline mtpTypeId MTP' + restype + '::type() const {\n';
|
methods += 'mtpTypeId MTP' + restype + '::type() const {\n';
|
||||||
if (withType):
|
if (withType):
|
||||||
inlineMethods += '\tt_assert(_type != 0);\n';
|
methods += '\tt_assert(_type != 0);\n';
|
||||||
inlineMethods += '\treturn _type;\n';
|
methods += '\treturn _type;\n';
|
||||||
else:
|
else:
|
||||||
inlineMethods += '\treturn mtpc_' + v[0][0] + ';\n';
|
methods += '\treturn mtpc_' + v[0][0] + ';\n';
|
||||||
inlineMethods += '}\n';
|
methods += '}\n';
|
||||||
|
|
||||||
typesText += '\tvoid read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons'; # read method
|
typesText += '\tvoid read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons'; # read method
|
||||||
if (not withType):
|
if (not withType):
|
||||||
typesText += ' = mtpc_' + name;
|
typesText += ' = mtpc_' + name;
|
||||||
typesText += ');\n';
|
typesText += ');\n';
|
||||||
inlineMethods += 'inline void MTP' + restype + '::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {\n';
|
methods += 'void MTP' + restype + '::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {\n';
|
||||||
if (withData):
|
if (withData):
|
||||||
if not (withType):
|
if not (withType):
|
||||||
inlineMethods += '\tif (cons != mtpc_' + v[0][0] + ') throw mtpErrorUnexpected(cons, "MTP' + restype + '");\n';
|
methods += '\tif (cons != mtpc_' + v[0][0] + ') throw mtpErrorUnexpected(cons, "MTP' + restype + '");\n';
|
||||||
if (withType):
|
if (withType):
|
||||||
inlineMethods += '\tswitch (cons) {\n'
|
methods += '\tswitch (cons) {\n'
|
||||||
inlineMethods += reader;
|
methods += reader;
|
||||||
inlineMethods += '\t\tdefault: throw mtpErrorUnexpected(cons, "MTP' + restype + '");\n';
|
methods += '\t\tdefault: throw mtpErrorUnexpected(cons, "MTP' + restype + '");\n';
|
||||||
inlineMethods += '\t}\n';
|
methods += '\t}\n';
|
||||||
else:
|
else:
|
||||||
inlineMethods += reader;
|
methods += reader;
|
||||||
inlineMethods += '}\n';
|
methods += '}\n';
|
||||||
|
|
||||||
typesText += '\tvoid write(mtpBuffer &to) const;\n'; # write method
|
typesText += '\tvoid write(mtpBuffer &to) const;\n'; # write method
|
||||||
inlineMethods += 'inline void MTP' + restype + '::write(mtpBuffer &to) const {\n';
|
methods += 'void MTP' + restype + '::write(mtpBuffer &to) const {\n';
|
||||||
if (withType and writer != ''):
|
if (withType and writer != ''):
|
||||||
inlineMethods += '\tswitch (_type) {\n';
|
methods += '\tswitch (_type) {\n';
|
||||||
inlineMethods += writer;
|
methods += writer;
|
||||||
inlineMethods += '\t}\n';
|
methods += '\t}\n';
|
||||||
else:
|
else:
|
||||||
inlineMethods += writer;
|
methods += writer;
|
||||||
inlineMethods += '}\n';
|
methods += '}\n';
|
||||||
|
|
||||||
typesText += '\n\tusing ResponseType = void;\n'; # no response types declared
|
typesText += '\n\tusing ResponseType = void;\n'; # no response types declared
|
||||||
|
|
||||||
typesText += '\nprivate:\n'; # private constructors
|
typesText += '\nprivate:\n'; # private constructors
|
||||||
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) : ';
|
methods += 'MTP' + restype + '::MTP' + restype + '(mtpTypeId type) : ';
|
||||||
inlineMethods += '_type(type)';
|
methods += '_type(type)';
|
||||||
inlineMethods += ' {\n';
|
methods += ' {\n';
|
||||||
inlineMethods += '\tswitch (type) {\n'; # type id check
|
methods += '\tswitch (type) {\n'; # type id check
|
||||||
inlineMethods += switchLines;
|
methods += switchLines;
|
||||||
inlineMethods += '\t\tdefault: throw mtpErrorBadTypeId(type, "MTP' + restype + '");\n\t}\n';
|
methods += '\t\tdefault: throw mtpErrorBadTypeId(type, "MTP' + restype + '");\n\t}\n';
|
||||||
inlineMethods += '}\n'; # by-type-id constructor end
|
methods += '}\n'; # by-type-id constructor end
|
||||||
|
|
||||||
if (withData):
|
if (withData):
|
||||||
typesText += constructsText;
|
typesText += constructsText;
|
||||||
inlineMethods += constructsInline;
|
methods += constructsBodies;
|
||||||
|
|
||||||
if (friendDecl):
|
if (friendDecl):
|
||||||
typesText += '\n' + friendDecl;
|
typesText += '\n' + friendDecl;
|
||||||
|
@ -816,9 +828,13 @@ for restype in typesList:
|
||||||
|
|
||||||
typesText += '};\n'; # type class ended
|
typesText += '};\n'; # type class ended
|
||||||
|
|
||||||
inlineMethods += creatorsText;
|
flagOperators += flagDeclarations;
|
||||||
|
factories += creatorsDeclarations;
|
||||||
|
methods += creatorsBodies;
|
||||||
typesText += 'using MTP' + resType + ' = MTPBoxed<MTP' + restype + '>;\n'; # boxed type definition
|
typesText += 'using MTP' + resType + ' = MTPBoxed<MTP' + restype + '>;\n'; # boxed type definition
|
||||||
|
|
||||||
|
flagOperators += '\n'
|
||||||
|
|
||||||
for childName in parentFlagsList:
|
for childName in parentFlagsList:
|
||||||
parentName = parentFlags[childName];
|
parentName = parentFlags[childName];
|
||||||
for flag in parentFlagsCheck[childName]:
|
for flag in parentFlagsCheck[childName]:
|
||||||
|
@ -836,8 +852,8 @@ for childName in parentFlagsList:
|
||||||
error
|
error
|
||||||
else:
|
else:
|
||||||
parentFlagsCheck[parentName][flag] = parentFlagsCheck[childName][flag];
|
parentFlagsCheck[parentName][flag] = parentFlagsCheck[childName][flag];
|
||||||
inlineMethods += 'inline ' + parentName + '::Flags mtpCastFlags(' + childName + '::Flags flags) { return ' + parentName + '::Flags(QFlag(flags)); }\n';
|
flagOperators += 'inline ' + parentName + '::Flags mtpCastFlags(' + childName + '::Flags flags) { return ' + parentName + '::Flags(QFlag(flags)); }\n';
|
||||||
inlineMethods += 'inline ' + parentName + '::Flags mtpCastFlags(MTPflags<' + childName + '::Flags> flags) { return mtpCastFlags(flags.v); }\n';
|
flagOperators += 'inline ' + parentName + '::Flags mtpCastFlags(MTPflags<' + childName + '::Flags> flags) { return mtpCastFlags(flags.v); }\n';
|
||||||
|
|
||||||
# manual types added here
|
# manual types added here
|
||||||
textSerializeMethods += '\
|
textSerializeMethods += '\
|
||||||
|
@ -946,20 +962,12 @@ enum {\n\
|
||||||
' + dataTexts + '\n\
|
' + dataTexts + '\n\
|
||||||
// RPC methods\n\
|
// RPC methods\n\
|
||||||
' + funcsText + '\n\
|
' + funcsText + '\n\
|
||||||
// Creator proxy class definition\n\
|
// Template methods definition\n\
|
||||||
namespace MTP {\n\
|
|
||||||
namespace internal {\n\
|
|
||||||
\n\
|
|
||||||
class TypeCreator {\n\
|
|
||||||
public:\n\
|
|
||||||
' + creatorProxyText + '\n\
|
|
||||||
};\n\
|
|
||||||
\n\
|
|
||||||
} // namespace internal\n\
|
|
||||||
} // namespace MTP\n\
|
|
||||||
\n\
|
|
||||||
// Inline methods definition\n\
|
|
||||||
' + inlineMethods + '\n\
|
' + inlineMethods + '\n\
|
||||||
|
// Flag operators definition\n\
|
||||||
|
' + flagOperators + '\n\
|
||||||
|
// Factory methods declaration\n\
|
||||||
|
' + factories + '\n\
|
||||||
// Human-readable text serialization\n\
|
// Human-readable text serialization\n\
|
||||||
void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32 level, mtpPrime vcons);\n'
|
void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32 level, mtpPrime vcons);\n'
|
||||||
|
|
||||||
|
@ -986,6 +994,21 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org\n\
|
||||||
*/\n\
|
*/\n\
|
||||||
#include "scheme.h"\n\
|
#include "scheme.h"\n\
|
||||||
\n\
|
\n\
|
||||||
|
// Creator proxy class definition\n\
|
||||||
|
namespace MTP {\n\
|
||||||
|
namespace internal {\n\
|
||||||
|
\n\
|
||||||
|
class TypeCreator {\n\
|
||||||
|
public:\n\
|
||||||
|
' + creatorProxyText + '\n\
|
||||||
|
};\n\
|
||||||
|
\n\
|
||||||
|
} // namespace internal\n\
|
||||||
|
} // namespace MTP\n\
|
||||||
|
\n\
|
||||||
|
// Methods definition\n\
|
||||||
|
' + methods + '\n\
|
||||||
|
\n\
|
||||||
using Types = QVector<mtpTypeId>;\n\
|
using Types = QVector<mtpTypeId>;\n\
|
||||||
using StagesFlags = QVector<int32>;\n\
|
using StagesFlags = QVector<int32>;\n\
|
||||||
\n\
|
\n\
|
||||||
|
|
|
@ -84,7 +84,7 @@ private:
|
||||||
Over = 0x01,
|
Over = 0x01,
|
||||||
DeleteOver = 0x02,
|
DeleteOver = 0x02,
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(StateFlags, StateFlag);
|
using StateFlags = QFlags<StateFlag>;
|
||||||
StateFlags _state;
|
StateFlags _state;
|
||||||
friend inline StateFlags operator~(StateFlag flag) {
|
friend inline StateFlags operator~(StateFlag flag) {
|
||||||
return ~StateFlags(flag);
|
return ~StateFlags(flag);
|
||||||
|
|
|
@ -22,7 +22,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "core/basic_types.h"
|
#include "core/basic_types.h"
|
||||||
#include "structs.h"
|
#include "structs.h"
|
||||||
#include "mtproto/core_types.h"
|
|
||||||
|
|
||||||
class FileLoader;
|
class FileLoader;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "core/basic_types.h"
|
#include "core/basic_types.h"
|
||||||
#include "structs.h"
|
#include "structs.h"
|
||||||
#include "mtproto/core_types.h"
|
|
||||||
#include "history/history_location_manager.h"
|
#include "history/history_location_manager.h"
|
||||||
|
|
||||||
namespace InlineBots {
|
namespace InlineBots {
|
||||||
|
|
|
@ -31,6 +31,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "data/data_drafts.h"
|
#include "data/data_drafts.h"
|
||||||
#include "ui/widgets/dropdown_menu.h"
|
#include "ui/widgets/dropdown_menu.h"
|
||||||
#include "chat_helpers/message_field.h"
|
#include "chat_helpers/message_field.h"
|
||||||
|
#include "chat_helpers/stickers.h"
|
||||||
#include "observer_peer.h"
|
#include "observer_peer.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "dialogs/dialogs_widget.h"
|
#include "dialogs/dialogs_widget.h"
|
||||||
|
@ -5218,7 +5219,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||||
auto &sets = Global::RefStickerSets();
|
auto &sets = Global::RefStickerSets();
|
||||||
auto it = sets.find(s.vid.v);
|
auto it = sets.find(s.vid.v);
|
||||||
if (it == sets.cend()) {
|
if (it == sets.cend()) {
|
||||||
it = sets.insert(s.vid.v, Stickers::Set(s.vid.v, s.vaccess_hash.v, stickerSetTitle(s), qs(s.vshort_name), s.vcount.v, s.vhash.v, s.vflags.v | MTPDstickerSet::Flag::f_installed));
|
it = sets.insert(s.vid.v, Stickers::Set(s.vid.v, s.vaccess_hash.v, Stickers::GetSetTitle(s), qs(s.vshort_name), s.vcount.v, s.vhash.v, s.vflags.v | MTPDstickerSet::Flag::f_installed));
|
||||||
} else {
|
} else {
|
||||||
it->flags |= MTPDstickerSet::Flag::f_installed;
|
it->flags |= MTPDstickerSet::Flag::f_installed;
|
||||||
if (it->flags & MTPDstickerSet::Flag::f_archived) {
|
if (it->flags & MTPDstickerSet::Flag::f_archived) {
|
||||||
|
|
|
@ -20,7 +20,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "mtproto/core_types.h"
|
|
||||||
#include "mtproto/auth_key.h"
|
#include "mtproto/auth_key.h"
|
||||||
#include "mtproto/dc_options.h"
|
#include "mtproto/dc_options.h"
|
||||||
#include "core/single_timer.h"
|
#include "core/single_timer.h"
|
||||||
|
|
|
@ -20,7 +20,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "mtproto/core_types.h"
|
|
||||||
#include "mtproto/dc_options.h"
|
#include "mtproto/dc_options.h"
|
||||||
|
|
||||||
namespace MTP {
|
namespace MTP {
|
||||||
|
|
|
@ -20,7 +20,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "mtproto/core_types.h"
|
|
||||||
#include "mtproto/connection_tcp.h"
|
#include "mtproto/connection_tcp.h"
|
||||||
|
|
||||||
namespace MTP {
|
namespace MTP {
|
||||||
|
|
|
@ -20,7 +20,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "mtproto/core_types.h"
|
|
||||||
#include "mtproto/connection_abstract.h"
|
#include "mtproto/connection_abstract.h"
|
||||||
|
|
||||||
namespace MTP {
|
namespace MTP {
|
||||||
|
|
|
@ -20,7 +20,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "mtproto/core_types.h"
|
|
||||||
#include "mtproto/auth_key.h"
|
#include "mtproto/auth_key.h"
|
||||||
#include "mtproto/connection_abstract.h"
|
#include "mtproto/connection_abstract.h"
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,131 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
|
|
||||||
#include "lang/lang_keys.h"
|
uint32 MTPstring::innerLength() const {
|
||||||
|
uint32 l = v.length();
|
||||||
|
if (l < 254) {
|
||||||
|
l += 1;
|
||||||
|
} else {
|
||||||
|
l += 4;
|
||||||
|
}
|
||||||
|
uint32 d = l & 0x03;
|
||||||
|
if (d) l += (4 - d);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
QString mtpWrapNumber(float64 number) {
|
void MTPstring::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
|
||||||
return QString::number(number);
|
if (from + 1 > end) throw mtpErrorInsufficient();
|
||||||
|
if (cons != mtpc_string) throw mtpErrorUnexpected(cons, "MTPstring");
|
||||||
|
|
||||||
|
uint32 l;
|
||||||
|
const uchar *buf = (const uchar*)from;
|
||||||
|
if (buf[0] == 254) {
|
||||||
|
l = (uint32)buf[1] + ((uint32)buf[2] << 8) + ((uint32)buf[3] << 16);
|
||||||
|
buf += 4;
|
||||||
|
from += ((l + 4) >> 2) + (((l + 4) & 0x03) ? 1 : 0);
|
||||||
|
} else {
|
||||||
|
l = (uint32)buf[0];
|
||||||
|
++buf;
|
||||||
|
from += ((l + 1) >> 2) + (((l + 1) & 0x03) ? 1 : 0);
|
||||||
|
}
|
||||||
|
if (from > end) throw mtpErrorInsufficient();
|
||||||
|
|
||||||
|
v = QByteArray(reinterpret_cast<const char*>(buf), l);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MTPstring::write(mtpBuffer &to) const {
|
||||||
|
uint32 l = v.length(), s = l + ((l < 254) ? 1 : 4), was = to.size();
|
||||||
|
if (s & 0x03) {
|
||||||
|
s += 4;
|
||||||
|
}
|
||||||
|
s >>= 2;
|
||||||
|
to.resize(was + s);
|
||||||
|
char *buf = (char*)&to[was];
|
||||||
|
if (l < 254) {
|
||||||
|
uchar sl = (uchar)l;
|
||||||
|
*(buf++) = *(char*)(&sl);
|
||||||
|
} else {
|
||||||
|
*(buf++) = (char)254;
|
||||||
|
*(buf++) = (char)(l & 0xFF);
|
||||||
|
*(buf++) = (char)((l >> 8) & 0xFF);
|
||||||
|
*(buf++) = (char)((l >> 16) & 0xFF);
|
||||||
|
}
|
||||||
|
memcpy(buf, v.constData(), l);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 mtpRequest::innerLength() const { // for template MTP requests and MTPBoxed instanciation
|
||||||
|
mtpRequestData *value = data();
|
||||||
|
if (!value || value->size() < 9) return 0;
|
||||||
|
return value->at(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mtpRequest::write(mtpBuffer &to) const {
|
||||||
|
mtpRequestData *value = data();
|
||||||
|
if (!value || value->size() < 9) return;
|
||||||
|
uint32 was = to.size(), s = innerLength() / sizeof(mtpPrime);
|
||||||
|
to.resize(was + s);
|
||||||
|
memcpy(to.data() + was, value->constData() + 8, s * sizeof(mtpPrime));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mtpRequestData::isSentContainer(const mtpRequest &request) { // "request-like" wrap for msgIds vector
|
||||||
|
if (request->size() < 9) return false;
|
||||||
|
return (!request->msDate && !(*request)[6]); // msDate = 0, seqNo = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mtpRequestData::isStateRequest(const mtpRequest &request) {
|
||||||
|
if (request->size() < 9) return false;
|
||||||
|
return (mtpTypeId((*request)[8]) == mtpc_msgs_state_req);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mtpRequestData::needAckByType(mtpTypeId type) {
|
||||||
|
switch (type) {
|
||||||
|
case mtpc_msg_container:
|
||||||
|
case mtpc_msgs_ack:
|
||||||
|
case mtpc_http_wait:
|
||||||
|
case mtpc_bad_msg_notification:
|
||||||
|
case mtpc_msgs_all_info:
|
||||||
|
case mtpc_msgs_state_info:
|
||||||
|
case mtpc_msg_detailed_info:
|
||||||
|
case mtpc_msg_new_detailed_info:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mtpRequest mtpRequestData::prepare(uint32 requestSize, uint32 maxSize) {
|
||||||
|
if (!maxSize) maxSize = requestSize;
|
||||||
|
mtpRequest result(new mtpRequestData(true));
|
||||||
|
result->reserve(8 + maxSize + _padding(maxSize)); // 2: salt, 2: session_id, 2: msg_id, 1: seq_no, 1: message_length
|
||||||
|
result->resize(7);
|
||||||
|
result->push_back(requestSize << 2);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mtpRequestData::padding(mtpRequest &request) {
|
||||||
|
if (request->size() < 9) return;
|
||||||
|
|
||||||
|
uint32 requestSize = (request.innerLength() >> 2), padding = _padding(requestSize), fullSize = 8 + requestSize + padding; // 2: salt, 2: session_id, 2: msg_id, 1: seq_no, 1: message_length
|
||||||
|
if (uint32(request->size()) != fullSize) {
|
||||||
|
request->resize(fullSize);
|
||||||
|
if (padding) {
|
||||||
|
memset_rand(request->data() + (fullSize - padding), padding * sizeof(mtpPrime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 mtpRequestData::_padding(uint32 requestSize) {
|
||||||
|
#ifdef TDESKTOP_MTPROTO_OLD
|
||||||
|
return ((8 + requestSize) & 0x03) ? (4 - ((8 + requestSize) & 0x03)) : 0;
|
||||||
|
#else // TDESKTOP_MTPROTO_OLD
|
||||||
|
auto result = ((8 + requestSize) & 0x03) ? (4 - ((8 + requestSize) & 0x03)) : 0;
|
||||||
|
|
||||||
|
// At least 12 bytes of random padding.
|
||||||
|
if (result < 3) {
|
||||||
|
result += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
#endif // TDESKTOP_MTPROTO_OLD
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -33,31 +154,31 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||||
case mtpc_int: {
|
case mtpc_int: {
|
||||||
MTPint value;
|
MTPint value;
|
||||||
value.read(from, end, cons);
|
value.read(from, end, cons);
|
||||||
to.add(mtpWrapNumber(value.v)).add(" [INT]");
|
to.add(QString::number(value.v)).add(" [INT]");
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_long: {
|
case mtpc_long: {
|
||||||
MTPlong value;
|
MTPlong value;
|
||||||
value.read(from, end, cons);
|
value.read(from, end, cons);
|
||||||
to.add(mtpWrapNumber(value.v)).add(" [LONG]");
|
to.add(QString::number(value.v)).add(" [LONG]");
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_int128: {
|
case mtpc_int128: {
|
||||||
MTPint128 value;
|
MTPint128 value;
|
||||||
value.read(from, end, cons);
|
value.read(from, end, cons);
|
||||||
to.add(mtpWrapNumber(value.h)).add(" * 2^64 + ").add(mtpWrapNumber(value.l)).add(" [INT128]");
|
to.add(QString::number(value.h)).add(" * 2^64 + ").add(QString::number(value.l)).add(" [INT128]");
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_int256: {
|
case mtpc_int256: {
|
||||||
MTPint256 value;
|
MTPint256 value;
|
||||||
value.read(from, end, cons);
|
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(QString::number(value.h.h)).add(" * 2^192 + ").add(QString::number(value.h.l)).add(" * 2^128 + ").add(QString::number(value.l.h)).add(" * 2 ^ 64 + ").add(QString::number(value.l.l)).add(" [INT256]");
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_double: {
|
case mtpc_double: {
|
||||||
MTPdouble value;
|
MTPdouble value;
|
||||||
value.read(from, end, cons);
|
value.read(from, end, cons);
|
||||||
to.add(mtpWrapNumber(value.v)).add(" [DOUBLE]");
|
to.add(QString::number(value.v)).add(" [DOUBLE]");
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_string: {
|
case mtpc_string: {
|
||||||
|
@ -68,9 +189,9 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||||
if (str.toUtf8() == strUtf8) {
|
if (str.toUtf8() == strUtf8) {
|
||||||
to.add("\"").add(str.replace('\\', "\\\\").replace('"', "\\\"").replace('\n', "\\n")).add("\" [STRING]");
|
to.add("\"").add(str.replace('\\', "\\\\").replace('"', "\\\"").replace('\n', "\\n")).add("\" [STRING]");
|
||||||
} else if (strUtf8.size() < 64) {
|
} else if (strUtf8.size() < 64) {
|
||||||
to.add(Logs::mb(strUtf8.constData(), strUtf8.size()).str()).add(" [").add(mtpWrapNumber(strUtf8.size())).add(" BYTES]");
|
to.add(Logs::mb(strUtf8.constData(), strUtf8.size()).str()).add(" [").add(QString::number(strUtf8.size())).add(" BYTES]");
|
||||||
} else {
|
} else {
|
||||||
to.add(Logs::mb(strUtf8.constData(), 16).str()).add("... [").add(mtpWrapNumber(strUtf8.size())).add(" BYTES]");
|
to.add(Logs::mb(strUtf8.constData(), 16).str()).add("... [").add(QString::number(strUtf8.size())).add(" BYTES]");
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -79,7 +200,7 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||||
throw Exception("from >= end in vector");
|
throw Exception("from >= end in vector");
|
||||||
}
|
}
|
||||||
int32 cnt = *(from++);
|
int32 cnt = *(from++);
|
||||||
to.add("[ vector<0x").add(mtpWrapNumber(vcons, 16)).add(">");
|
to.add("[ vector<0x").add(QString::number(vcons, 16)).add(">");
|
||||||
if (cnt) {
|
if (cnt) {
|
||||||
to.add("\n").addSpaces(level);
|
to.add("\n").addSpaces(level);
|
||||||
for (int32 i = 0; i < cnt; ++i) {
|
for (int32 i = 0; i < cnt; ++i) {
|
||||||
|
@ -140,7 +261,7 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||||
default: {
|
default: {
|
||||||
for (uint32 i = 1; i < mtpLayerMaxSingle; ++i) {
|
for (uint32 i = 1; i < mtpLayerMaxSingle; ++i) {
|
||||||
if (cons == mtpLayers[i]) {
|
if (cons == mtpLayers[i]) {
|
||||||
to.add("[LAYER").add(mtpWrapNumber(i + 1)).add("] "); mtpTextSerializeType(to, from, end, 0, level);
|
to.add("[LAYER").add(QString::number(i + 1)).add("] "); mtpTextSerializeType(to, from, end, 0, level);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,22 +270,10 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||||
throw Exception("from >= end in invokeWithLayer");
|
throw Exception("from >= end in invokeWithLayer");
|
||||||
}
|
}
|
||||||
int32 layer = *(from++);
|
int32 layer = *(from++);
|
||||||
to.add("[LAYER").add(mtpWrapNumber(layer)).add("] "); mtpTextSerializeType(to, from, end, 0, level);
|
to.add("[LAYER").add(QString::number(layer)).add("] "); mtpTextSerializeType(to, from, end, 0, level);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw Exception(QString("unknown cons 0x%1").arg(cons, 0, 16));
|
throw Exception(QString("unknown cons 0x%1").arg(cons, 0, 16));
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const MTPReplyMarkup MTPnullMarkup = MTP_replyKeyboardMarkup(MTP_flags(0), MTP_vector<MTPKeyboardButtonRow>(0));
|
|
||||||
const MTPVector<MTPMessageEntity> MTPnullEntities = MTP_vector<MTPMessageEntity>(0);
|
|
||||||
const MTPMessageFwdHeader MTPnullFwdHeader = MTP_messageFwdHeader(MTP_flags(0), MTPint(), MTPint(), MTPint(), MTPint(), MTPstring());
|
|
||||||
|
|
||||||
QString stickerSetTitle(const MTPDstickerSet &s) {
|
|
||||||
QString title = qs(s.vtitle);
|
|
||||||
if ((s.vflags.v & MTPDstickerSet::Flag::f_official) && !title.compare(qstr("Great Minds"), Qt::CaseInsensitive)) {
|
|
||||||
return lang(lng_stickers_default_set);
|
|
||||||
}
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
|
@ -42,8 +42,7 @@ using mtpTypeId = uint32;
|
||||||
class mtpRequestData;
|
class mtpRequestData;
|
||||||
class mtpRequest : public QSharedPointer<mtpRequestData> {
|
class mtpRequest : public QSharedPointer<mtpRequestData> {
|
||||||
public:
|
public:
|
||||||
mtpRequest() {
|
mtpRequest() = default;
|
||||||
}
|
|
||||||
explicit mtpRequest(mtpRequestData *ptr) : QSharedPointer<mtpRequestData>(ptr) {
|
explicit mtpRequest(mtpRequestData *ptr) : QSharedPointer<mtpRequestData>(ptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,35 +57,17 @@ class mtpRequestData : public mtpBuffer {
|
||||||
public:
|
public:
|
||||||
// in toSend: = 0 - must send in container, > 0 - can send without container
|
// in toSend: = 0 - must send in container, > 0 - can send without container
|
||||||
// in haveSent: = 0 - container with msgIds, > 0 - when was sent
|
// in haveSent: = 0 - container with msgIds, > 0 - when was sent
|
||||||
TimeMs msDate;
|
TimeMs msDate = 0;
|
||||||
|
|
||||||
mtpRequestId requestId;
|
mtpRequestId requestId = 0;
|
||||||
mtpRequest after;
|
mtpRequest after;
|
||||||
bool needsLayer;
|
bool needsLayer = false;
|
||||||
|
|
||||||
mtpRequestData(bool/* sure*/) : msDate(0), requestId(0), needsLayer(false) {
|
mtpRequestData(bool/* sure*/) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static mtpRequest prepare(uint32 requestSize, uint32 maxSize = 0) {
|
static mtpRequest prepare(uint32 requestSize, uint32 maxSize = 0);
|
||||||
if (!maxSize) maxSize = requestSize;
|
static void padding(mtpRequest &request);
|
||||||
mtpRequest result(new mtpRequestData(true));
|
|
||||||
result->reserve(8 + maxSize + _padding(maxSize)); // 2: salt, 2: session_id, 2: msg_id, 1: seq_no, 1: message_length
|
|
||||||
result->resize(7);
|
|
||||||
result->push_back(requestSize << 2);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void padding(mtpRequest &request) {
|
|
||||||
if (request->size() < 9) return;
|
|
||||||
|
|
||||||
uint32 requestSize = (request.innerLength() >> 2), padding = _padding(requestSize), fullSize = 8 + requestSize + padding; // 2: salt, 2: session_id, 2: msg_id, 1: seq_no, 1: message_length
|
|
||||||
if (uint32(request->size()) != fullSize) {
|
|
||||||
request->resize(fullSize);
|
|
||||||
if (padding) {
|
|
||||||
memset_rand(request->data() + (fullSize - padding), padding * sizeof(mtpPrime));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32 messageSize(const mtpRequest &request) {
|
static uint32 messageSize(const mtpRequest &request) {
|
||||||
if (request->size() < 9) return 0;
|
if (request->size() < 9) return 0;
|
||||||
|
@ -95,41 +76,17 @@ public:
|
||||||
|
|
||||||
static bool isSentContainer(const mtpRequest &request); // "request-like" wrap for msgIds vector
|
static bool isSentContainer(const mtpRequest &request); // "request-like" wrap for msgIds vector
|
||||||
static bool isStateRequest(const mtpRequest &request);
|
static bool isStateRequest(const mtpRequest &request);
|
||||||
static bool needAck(const mtpRequest &request);
|
static bool needAck(const mtpRequest &request) {
|
||||||
|
if (request->size() < 9) return false;
|
||||||
|
return mtpRequestData::needAckByType((*request)[8]);
|
||||||
|
}
|
||||||
static bool needAckByType(mtpTypeId type);
|
static bool needAckByType(mtpTypeId type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static uint32 _padding(uint32 requestSize) {
|
static uint32 _padding(uint32 requestSize);
|
||||||
#ifdef TDESKTOP_MTPROTO_OLD
|
|
||||||
return ((8 + requestSize) & 0x03) ? (4 - ((8 + requestSize) & 0x03)) : 0;
|
|
||||||
#else // TDESKTOP_MTPROTO_OLD
|
|
||||||
auto result = ((8 + requestSize) & 0x03) ? (4 - ((8 + requestSize) & 0x03)) : 0;
|
|
||||||
|
|
||||||
// At least 12 bytes of random padding.
|
|
||||||
if (result < 3) {
|
|
||||||
result += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
#endif // TDESKTOP_MTPROTO_OLD
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline uint32 mtpRequest::innerLength() const { // for template MTP requests and MTPBoxed instanciation
|
|
||||||
mtpRequestData *value = data();
|
|
||||||
if (!value || value->size() < 9) return 0;
|
|
||||||
return value->at(7);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void mtpRequest::write(mtpBuffer &to) const {
|
|
||||||
mtpRequestData *value = data();
|
|
||||||
if (!value || value->size() < 9) return;
|
|
||||||
uint32 was = to.size(), s = innerLength() / sizeof(mtpPrime);
|
|
||||||
to.resize(was + s);
|
|
||||||
memcpy(to.data() + was, value->constData() + 8, s * sizeof(mtpPrime));
|
|
||||||
}
|
|
||||||
|
|
||||||
using mtpPreRequestMap = QMap<mtpRequestId, mtpRequest>;
|
using mtpPreRequestMap = QMap<mtpRequestId, mtpRequest>;
|
||||||
using mtpRequestMap = QMap<mtpMsgId, mtpRequest>;
|
using mtpRequestMap = QMap<mtpMsgId, mtpRequest>;
|
||||||
using mtpMsgIdsSet = QMap<mtpMsgId, bool>;
|
using mtpMsgIdsSet = QMap<mtpMsgId, bool>;
|
||||||
|
@ -152,18 +109,21 @@ class mtpErrorUnexpected : public Exception {
|
||||||
public:
|
public:
|
||||||
mtpErrorUnexpected(mtpTypeId typeId, const QString &type) : Exception(QString("MTP Unexpected type id #%1 read in %2").arg(uint32(typeId), 0, 16).arg(type), false) { // maybe api changed?..
|
mtpErrorUnexpected(mtpTypeId typeId, const QString &type) : Exception(QString("MTP Unexpected type id #%1 read in %2").arg(uint32(typeId), 0, 16).arg(type), false) { // maybe api changed?..
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class mtpErrorInsufficient : public Exception {
|
class mtpErrorInsufficient : public Exception {
|
||||||
public:
|
public:
|
||||||
mtpErrorInsufficient() : Exception("MTP Insufficient bytes in input buffer") {
|
mtpErrorInsufficient() : Exception("MTP Insufficient bytes in input buffer") {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class mtpErrorBadTypeId : public Exception {
|
class mtpErrorBadTypeId : public Exception {
|
||||||
public:
|
public:
|
||||||
mtpErrorBadTypeId(mtpTypeId typeId, const QString &type) : Exception(QString("MTP Bad type id %1 passed to constructor of %2").arg(typeId).arg(type)) {
|
mtpErrorBadTypeId(mtpTypeId typeId, const QString &type) : Exception(QString("MTP Bad type id %1 passed to constructor of %2").arg(typeId).arg(type)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace MTP {
|
namespace MTP {
|
||||||
|
@ -228,10 +188,10 @@ protected:
|
||||||
_data = data;
|
_data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unsafe cast, type should be checked by the caller.
|
||||||
template <typename DataType>
|
template <typename DataType>
|
||||||
const DataType &queryData() const {
|
const DataType &queryData() const {
|
||||||
// Unsafe cast, type should be checked by the caller.
|
Expects(_data != nullptr);
|
||||||
t_assert(_data != nullptr);
|
|
||||||
return static_cast<const DataType &>(*_data);
|
return static_cast<const DataType &>(*_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,20 +279,16 @@ 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:
|
||||||
|
using bareT::bareT;
|
||||||
MTPBoxed() = default;
|
MTPBoxed() = default;
|
||||||
|
MTPBoxed(const MTPBoxed<bareT> &v) = default;
|
||||||
|
MTPBoxed<bareT> &operator=(const MTPBoxed<bareT> &v) = default;
|
||||||
MTPBoxed(const bareT &v) : bareT(v) {
|
MTPBoxed(const bareT &v) : bareT(v) {
|
||||||
}
|
}
|
||||||
MTPBoxed(const MTPBoxed<bareT> &v) : bareT(v) {
|
|
||||||
}
|
|
||||||
|
|
||||||
MTPBoxed<bareT> &operator=(const bareT &v) {
|
MTPBoxed<bareT> &operator=(const bareT &v) {
|
||||||
*((bareT*)this) = v;
|
*((bareT*)this) = v;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
MTPBoxed<bareT> &operator=(const MTPBoxed<bareT> &v) {
|
|
||||||
*((bareT*)this) = v;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 innerLength() const {
|
uint32 innerLength() const {
|
||||||
return sizeof(mtpTypeId) + bareT::innerLength();
|
return sizeof(mtpTypeId) + bareT::innerLength();
|
||||||
|
@ -631,58 +587,12 @@ class MTPstring {
|
||||||
public:
|
public:
|
||||||
MTPstring() = default;
|
MTPstring() = default;
|
||||||
|
|
||||||
uint32 innerLength() const {
|
uint32 innerLength() const;
|
||||||
uint32 l = v.length();
|
|
||||||
if (l < 254) {
|
|
||||||
l += 1;
|
|
||||||
} else {
|
|
||||||
l += 4;
|
|
||||||
}
|
|
||||||
uint32 d = l & 0x03;
|
|
||||||
if (d) l += (4 - d);
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
mtpTypeId type() const {
|
mtpTypeId type() const {
|
||||||
return mtpc_string;
|
return mtpc_string;
|
||||||
}
|
}
|
||||||
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_string) {
|
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_string);
|
||||||
if (from + 1 > end) throw mtpErrorInsufficient();
|
void write(mtpBuffer &to) const;
|
||||||
if (cons != mtpc_string) throw mtpErrorUnexpected(cons, "MTPstring");
|
|
||||||
|
|
||||||
uint32 l;
|
|
||||||
const uchar *buf = (const uchar*)from;
|
|
||||||
if (buf[0] == 254) {
|
|
||||||
l = (uint32)buf[1] + ((uint32)buf[2] << 8) + ((uint32)buf[3] << 16);
|
|
||||||
buf += 4;
|
|
||||||
from += ((l + 4) >> 2) + (((l + 4) & 0x03) ? 1 : 0);
|
|
||||||
} else {
|
|
||||||
l = (uint32)buf[0];
|
|
||||||
++buf;
|
|
||||||
from += ((l + 1) >> 2) + (((l + 1) & 0x03) ? 1 : 0);
|
|
||||||
}
|
|
||||||
if (from > end) throw mtpErrorInsufficient();
|
|
||||||
|
|
||||||
v = QByteArray(reinterpret_cast<const char*>(buf), l);
|
|
||||||
}
|
|
||||||
void write(mtpBuffer &to) const {
|
|
||||||
uint32 l = v.length(), s = l + ((l < 254) ? 1 : 4), was = to.size();
|
|
||||||
if (s & 0x03) {
|
|
||||||
s += 4;
|
|
||||||
}
|
|
||||||
s >>= 2;
|
|
||||||
to.resize(was + s);
|
|
||||||
char *buf = (char*)&to[was];
|
|
||||||
if (l < 254) {
|
|
||||||
uchar sl = (uchar)l;
|
|
||||||
*(buf++) = *(char*)(&sl);
|
|
||||||
} else {
|
|
||||||
*(buf++) = (char)254;
|
|
||||||
*(buf++) = (char)(l & 0xFF);
|
|
||||||
*(buf++) = (char)((l >> 8) & 0xFF);
|
|
||||||
*(buf++) = (char)((l >> 16) & 0xFF);
|
|
||||||
}
|
|
||||||
memcpy(buf, v.constData(), l);
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray v;
|
QByteArray v;
|
||||||
|
|
||||||
|
@ -832,11 +742,6 @@ inline bool operator!=(const MTPvector<T> &a, const MTPvector<T> &b) {
|
||||||
|
|
||||||
// Human-readable text serialization
|
// Human-readable text serialization
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
QString mtpWrapNumber(Type number, int32 base = 10) {
|
|
||||||
return QString::number(number, base);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MTPStringLogger {
|
struct MTPStringLogger {
|
||||||
MTPStringLogger() : p(new char[MTPDebugBufferSize]), size(0), alloced(MTPDebugBufferSize) {
|
MTPStringLogger() : p(new char[MTPDebugBufferSize]), size(0), alloced(MTPDebugBufferSize) {
|
||||||
}
|
}
|
||||||
|
@ -899,141 +804,3 @@ inline QString mtpTextSerialize(const mtpPrime *&from, const mtpPrime *end) {
|
||||||
}
|
}
|
||||||
return QString::fromUtf8(to.p, to.size);
|
return QString::fromUtf8(to.p, to.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "scheme.h"
|
|
||||||
|
|
||||||
inline MTPbool MTP_bool(bool v) {
|
|
||||||
return v ? MTP_boolTrue() : MTP_boolFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool mtpIsTrue(const MTPBool &v) {
|
|
||||||
return v.type() == mtpc_boolTrue;
|
|
||||||
}
|
|
||||||
inline bool mtpIsFalse(const MTPBool &v) {
|
|
||||||
return !mtpIsTrue(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
// we must validate that MTProto scheme flags don't intersect with client side flags
|
|
||||||
// and define common bit operators which allow use Type_ClientFlag together with Type::Flag
|
|
||||||
#define DEFINE_MTP_CLIENT_FLAGS(Type) \
|
|
||||||
static_assert(static_cast<int32>(Type::Flag::MAX_FIELD) < static_cast<int32>(Type##_ClientFlag::MIN_FIELD), \
|
|
||||||
"MTProto flags conflict with client side flags!"); \
|
|
||||||
inline Type::Flags qFlags(Type##_ClientFlag v) { return Type::Flags(static_cast<int32>(v)); } \
|
|
||||||
inline Type::Flags operator&(Type::Flags i, Type##_ClientFlag v) { return i & qFlags(v); } \
|
|
||||||
inline Type::Flags operator&(Type##_ClientFlag i, Type##_ClientFlag v) { return qFlags(i) & v; } \
|
|
||||||
inline Type::Flags &operator&=(Type::Flags &i, Type##_ClientFlag v) { return i &= qFlags(v); } \
|
|
||||||
inline Type::Flags operator|(Type::Flags i, Type##_ClientFlag v) { return i | qFlags(v); } \
|
|
||||||
inline Type::Flags operator|(Type::Flag i, Type##_ClientFlag v) { return i | qFlags(v); } \
|
|
||||||
inline Type::Flags operator|(Type##_ClientFlag i, Type##_ClientFlag v) { return qFlags(i) | v; } \
|
|
||||||
inline Type::Flags operator|(Type##_ClientFlag i, Type::Flag v) { return qFlags(i) | v; } \
|
|
||||||
inline Type::Flags &operator|=(Type::Flags &i, Type##_ClientFlag v) { return i |= qFlags(v); } \
|
|
||||||
inline Type::Flags operator~(Type##_ClientFlag v) { return ~qFlags(v); }
|
|
||||||
|
|
||||||
// we use the same flags field for some additional client side flags
|
|
||||||
enum class MTPDmessage_ClientFlag : int32 {
|
|
||||||
// message has links for "shared links" indexing
|
|
||||||
f_has_text_links = (1 << 30),
|
|
||||||
|
|
||||||
// message is a group migrate (group -> supergroup) service message
|
|
||||||
f_is_group_migrate = (1 << 29),
|
|
||||||
|
|
||||||
// message needs initDimensions() + resize() + paint()
|
|
||||||
f_pending_init_dimensions = (1 << 28),
|
|
||||||
|
|
||||||
// message needs resize() + paint()
|
|
||||||
f_pending_resize = (1 << 27),
|
|
||||||
|
|
||||||
// message needs paint()
|
|
||||||
f_pending_paint = (1 << 26),
|
|
||||||
|
|
||||||
// message is attached to previous one when displaying the history
|
|
||||||
f_attach_to_previous = (1 << 25),
|
|
||||||
|
|
||||||
// message is attached to next one when displaying the history
|
|
||||||
f_attach_to_next = (1 << 24),
|
|
||||||
|
|
||||||
// message was sent from inline bot, need to re-set media when sent
|
|
||||||
f_from_inline_bot = (1 << 23),
|
|
||||||
|
|
||||||
// message has a switch inline keyboard button, need to return to inline
|
|
||||||
f_has_switch_inline_button = (1 << 22),
|
|
||||||
|
|
||||||
// message is generated on the client side and should be unread
|
|
||||||
f_clientside_unread = (1 << 21),
|
|
||||||
|
|
||||||
// update this when adding new client side flags
|
|
||||||
MIN_FIELD = (1 << 21),
|
|
||||||
};
|
|
||||||
DEFINE_MTP_CLIENT_FLAGS(MTPDmessage)
|
|
||||||
|
|
||||||
enum class MTPDreplyKeyboardMarkup_ClientFlag : int32 {
|
|
||||||
// none (zero) markup
|
|
||||||
f_zero = (1 << 30),
|
|
||||||
|
|
||||||
// markup just wants a text reply
|
|
||||||
f_force_reply = (1 << 29),
|
|
||||||
|
|
||||||
// markup keyboard is inline
|
|
||||||
f_inline = (1 << 28),
|
|
||||||
|
|
||||||
// markup has a switch inline keyboard button
|
|
||||||
f_has_switch_inline_button = (1 << 27),
|
|
||||||
|
|
||||||
// update this when adding new client side flags
|
|
||||||
MIN_FIELD = (1 << 27),
|
|
||||||
};
|
|
||||||
DEFINE_MTP_CLIENT_FLAGS(MTPDreplyKeyboardMarkup)
|
|
||||||
|
|
||||||
enum class MTPDstickerSet_ClientFlag : int32 {
|
|
||||||
// old value for sticker set is not yet loaded flag
|
|
||||||
f_not_loaded__old = (1 << 31),
|
|
||||||
|
|
||||||
// sticker set is not yet loaded
|
|
||||||
f_not_loaded = (1 << 30),
|
|
||||||
|
|
||||||
// sticker set is one of featured (should be saved locally)
|
|
||||||
f_featured = (1 << 29),
|
|
||||||
|
|
||||||
// sticker set is an unread featured set
|
|
||||||
f_unread = (1 << 28),
|
|
||||||
|
|
||||||
// special set like recent or custom stickers
|
|
||||||
f_special = (1 << 27),
|
|
||||||
|
|
||||||
// update this when adding new client side flags
|
|
||||||
MIN_FIELD = (1 << 27),
|
|
||||||
};
|
|
||||||
DEFINE_MTP_CLIENT_FLAGS(MTPDstickerSet)
|
|
||||||
|
|
||||||
extern const MTPReplyMarkup MTPnullMarkup;
|
|
||||||
extern const MTPVector<MTPMessageEntity> MTPnullEntities;
|
|
||||||
extern const MTPMessageFwdHeader MTPnullFwdHeader;
|
|
||||||
|
|
||||||
QString stickerSetTitle(const MTPDstickerSet &s);
|
|
||||||
|
|
||||||
inline bool mtpRequestData::isSentContainer(const mtpRequest &request) { // "request-like" wrap for msgIds vector
|
|
||||||
if (request->size() < 9) return false;
|
|
||||||
return (!request->msDate && !(*request)[6]); // msDate = 0, seqNo = 0
|
|
||||||
}
|
|
||||||
inline bool mtpRequestData::isStateRequest(const mtpRequest &request) {
|
|
||||||
if (request->size() < 9) return false;
|
|
||||||
return (mtpTypeId((*request)[8]) == mtpc_msgs_state_req);
|
|
||||||
}
|
|
||||||
inline bool mtpRequestData::needAck(const mtpRequest &request) {
|
|
||||||
if (request->size() < 9) return false;
|
|
||||||
return mtpRequestData::needAckByType((*request)[8]);
|
|
||||||
}
|
|
||||||
inline bool mtpRequestData::needAckByType(mtpTypeId type) {
|
|
||||||
switch (type) {
|
|
||||||
case mtpc_msg_container:
|
|
||||||
case mtpc_msgs_ack:
|
|
||||||
case mtpc_http_wait:
|
|
||||||
case mtpc_bad_msg_notification:
|
|
||||||
case mtpc_msgs_all_info:
|
|
||||||
case mtpc_msgs_state_info:
|
|
||||||
case mtpc_msg_detailed_info:
|
|
||||||
case mtpc_msg_new_detailed_info:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "mtproto/core_types.h"
|
#include "mtproto/type_utils.h"
|
||||||
#include "mtproto/session.h"
|
#include "mtproto/session.h"
|
||||||
#include "core/single_timer.h"
|
#include "core/single_timer.h"
|
||||||
#include "mtproto/mtp_instance.h"
|
#include "mtproto/mtp_instance.h"
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#include "mtproto/type_utils.h"
|
||||||
|
|
||||||
|
const MTPReplyMarkup MTPnullMarkup = MTP_replyKeyboardMarkup(MTP_flags(0), MTP_vector<MTPKeyboardButtonRow>(0));
|
||||||
|
const MTPVector<MTPMessageEntity> MTPnullEntities = MTP_vector<MTPMessageEntity>(0);
|
||||||
|
const MTPMessageFwdHeader MTPnullFwdHeader = MTP_messageFwdHeader(MTP_flags(0), MTPint(), MTPint(), MTPint(), MTPint(), MTPstring());
|
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "scheme.h"
|
||||||
|
|
||||||
|
inline MTPbool MTP_bool(bool v) {
|
||||||
|
return v ? MTP_boolTrue() : MTP_boolFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool mtpIsTrue(const MTPBool &v) {
|
||||||
|
return v.type() == mtpc_boolTrue;
|
||||||
|
}
|
||||||
|
inline bool mtpIsFalse(const MTPBool &v) {
|
||||||
|
return !mtpIsTrue(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// we must validate that MTProto scheme flags don't intersect with client side flags
|
||||||
|
// and define common bit operators which allow use Type_ClientFlag together with Type::Flag
|
||||||
|
#define DEFINE_MTP_CLIENT_FLAGS(Type) \
|
||||||
|
static_assert(static_cast<int32>(Type::Flag::MAX_FIELD) < static_cast<int32>(Type##_ClientFlag::MIN_FIELD), \
|
||||||
|
"MTProto flags conflict with client side flags!"); \
|
||||||
|
inline Type::Flags qFlags(Type##_ClientFlag v) { return Type::Flags(static_cast<int32>(v)); } \
|
||||||
|
inline Type::Flags operator&(Type::Flags i, Type##_ClientFlag v) { return i & qFlags(v); } \
|
||||||
|
inline Type::Flags operator&(Type##_ClientFlag i, Type##_ClientFlag v) { return qFlags(i) & v; } \
|
||||||
|
inline Type::Flags &operator&=(Type::Flags &i, Type##_ClientFlag v) { return i &= qFlags(v); } \
|
||||||
|
inline Type::Flags operator|(Type::Flags i, Type##_ClientFlag v) { return i | qFlags(v); } \
|
||||||
|
inline Type::Flags operator|(Type::Flag i, Type##_ClientFlag v) { return i | qFlags(v); } \
|
||||||
|
inline Type::Flags operator|(Type##_ClientFlag i, Type##_ClientFlag v) { return qFlags(i) | v; } \
|
||||||
|
inline Type::Flags operator|(Type##_ClientFlag i, Type::Flag v) { return qFlags(i) | v; } \
|
||||||
|
inline Type::Flags &operator|=(Type::Flags &i, Type##_ClientFlag v) { return i |= qFlags(v); } \
|
||||||
|
inline Type::Flags operator~(Type##_ClientFlag v) { return ~qFlags(v); }
|
||||||
|
|
||||||
|
// we use the same flags field for some additional client side flags
|
||||||
|
enum class MTPDmessage_ClientFlag : int32 {
|
||||||
|
// message has links for "shared links" indexing
|
||||||
|
f_has_text_links = (1 << 30),
|
||||||
|
|
||||||
|
// message is a group migrate (group -> supergroup) service message
|
||||||
|
f_is_group_migrate = (1 << 29),
|
||||||
|
|
||||||
|
// message needs initDimensions() + resize() + paint()
|
||||||
|
f_pending_init_dimensions = (1 << 28),
|
||||||
|
|
||||||
|
// message needs resize() + paint()
|
||||||
|
f_pending_resize = (1 << 27),
|
||||||
|
|
||||||
|
// message needs paint()
|
||||||
|
f_pending_paint = (1 << 26),
|
||||||
|
|
||||||
|
// message is attached to previous one when displaying the history
|
||||||
|
f_attach_to_previous = (1 << 25),
|
||||||
|
|
||||||
|
// message is attached to next one when displaying the history
|
||||||
|
f_attach_to_next = (1 << 24),
|
||||||
|
|
||||||
|
// message was sent from inline bot, need to re-set media when sent
|
||||||
|
f_from_inline_bot = (1 << 23),
|
||||||
|
|
||||||
|
// message has a switch inline keyboard button, need to return to inline
|
||||||
|
f_has_switch_inline_button = (1 << 22),
|
||||||
|
|
||||||
|
// message is generated on the client side and should be unread
|
||||||
|
f_clientside_unread = (1 << 21),
|
||||||
|
|
||||||
|
// update this when adding new client side flags
|
||||||
|
MIN_FIELD = (1 << 21),
|
||||||
|
};
|
||||||
|
DEFINE_MTP_CLIENT_FLAGS(MTPDmessage)
|
||||||
|
|
||||||
|
enum class MTPDreplyKeyboardMarkup_ClientFlag : int32 {
|
||||||
|
// none (zero) markup
|
||||||
|
f_zero = (1 << 30),
|
||||||
|
|
||||||
|
// markup just wants a text reply
|
||||||
|
f_force_reply = (1 << 29),
|
||||||
|
|
||||||
|
// markup keyboard is inline
|
||||||
|
f_inline = (1 << 28),
|
||||||
|
|
||||||
|
// markup has a switch inline keyboard button
|
||||||
|
f_has_switch_inline_button = (1 << 27),
|
||||||
|
|
||||||
|
// update this when adding new client side flags
|
||||||
|
MIN_FIELD = (1 << 27),
|
||||||
|
};
|
||||||
|
DEFINE_MTP_CLIENT_FLAGS(MTPDreplyKeyboardMarkup)
|
||||||
|
|
||||||
|
enum class MTPDstickerSet_ClientFlag : int32 {
|
||||||
|
// old value for sticker set is not yet loaded flag
|
||||||
|
f_not_loaded__old = (1 << 31),
|
||||||
|
|
||||||
|
// sticker set is not yet loaded
|
||||||
|
f_not_loaded = (1 << 30),
|
||||||
|
|
||||||
|
// sticker set is one of featured (should be saved locally)
|
||||||
|
f_featured = (1 << 29),
|
||||||
|
|
||||||
|
// sticker set is an unread featured set
|
||||||
|
f_unread = (1 << 28),
|
||||||
|
|
||||||
|
// special set like recent or custom stickers
|
||||||
|
f_special = (1 << 27),
|
||||||
|
|
||||||
|
// update this when adding new client side flags
|
||||||
|
MIN_FIELD = (1 << 27),
|
||||||
|
};
|
||||||
|
DEFINE_MTP_CLIENT_FLAGS(MTPDstickerSet)
|
||||||
|
|
||||||
|
extern const MTPReplyMarkup MTPnullMarkup;
|
||||||
|
extern const MTPVector<MTPMessageEntity> MTPnullEntities;
|
||||||
|
extern const MTPMessageFwdHeader MTPnullFwdHeader;
|
|
@ -291,6 +291,8 @@
|
||||||
<(src_loc)/mtproto/session.h
|
<(src_loc)/mtproto/session.h
|
||||||
<(src_loc)/mtproto/special_config_request.cpp
|
<(src_loc)/mtproto/special_config_request.cpp
|
||||||
<(src_loc)/mtproto/special_config_request.h
|
<(src_loc)/mtproto/special_config_request.h
|
||||||
|
<(src_loc)/mtproto/type_utils.cpp
|
||||||
|
<(src_loc)/mtproto/type_utils.h
|
||||||
<(src_loc)/overview/overview_layout.cpp
|
<(src_loc)/overview/overview_layout.cpp
|
||||||
<(src_loc)/overview/overview_layout.h
|
<(src_loc)/overview/overview_layout.h
|
||||||
<(src_loc)/platform/linux/linux_desktop_environment.cpp
|
<(src_loc)/platform/linux/linux_desktop_environment.cpp
|
||||||
|
|
Loading…
Reference in New Issue