mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-02 13:14:36 +00:00
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) {
|
||||
auto &s = d.vset.c_stickerSet();
|
||||
_setTitle = stickerSetTitle(s);
|
||||
_setTitle = Stickers::GetSetTitle(s);
|
||||
_setShortName = qs(s.vshort_name);
|
||||
_setId = s.vid.v;
|
||||
_setAccess = s.vaccess_hash.v;
|
||||
|
@ -524,7 +524,7 @@ void FeaturedSetsReceived(const QVector<MTPStickerSetCovered> &data, const QVect
|
||||
|
||||
if (set) {
|
||||
auto it = sets.find(set->vid.v);
|
||||
auto title = stickerSetTitle(*set);
|
||||
auto title = GetSetTitle(*set);
|
||||
if (it == sets.cend()) {
|
||||
auto setClientFlags = MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_not_loaded;
|
||||
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) {
|
||||
auto &sets = Global::RefStickerSets();
|
||||
auto it = sets.find(set.vid.v);
|
||||
auto title = stickerSetTitle(set);
|
||||
auto title = GetSetTitle(set);
|
||||
auto flags = MTPDstickerSet::Flags(0);
|
||||
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));
|
||||
@ -807,6 +807,14 @@ Set *FeedSetFull(const MTPmessages_StickerSet &data) {
|
||||
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 {
|
||||
|
||||
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 *FeedSetFull(const MTPmessages_StickerSet &data);
|
||||
|
||||
QString GetSetTitle(const MTPDstickerSet &s);
|
||||
|
||||
namespace internal {
|
||||
|
||||
class FeaturedReader : public QObject, private MTP::Sender {
|
||||
|
@ -83,6 +83,9 @@ funcsText = '';
|
||||
typesText = '';
|
||||
dataTexts = '';
|
||||
creatorProxyText = '';
|
||||
factories = '';
|
||||
flagOperators = '';
|
||||
methods = '';
|
||||
inlineMethods = '';
|
||||
textSerializeInit = '';
|
||||
textSerializeMethods = '';
|
||||
@ -297,6 +300,7 @@ with open(input_file) as f:
|
||||
continue;
|
||||
|
||||
if funcsNow:
|
||||
methodBodies = ''
|
||||
if (isTemplate != ''):
|
||||
funcsText += '\ntemplate <typename TQueryType>';
|
||||
funcsText += '\nclass MTP' + name + ' { // RPC method \'' + nametype.group(1) + '\'\n'; # class
|
||||
@ -318,7 +322,7 @@ with open(input_file) as f:
|
||||
funcsText += '\n';
|
||||
funcsText += '\t\tMAX_FIELD = (1 << ' + str(maxbit) + '),\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 += '\n';
|
||||
if (len(conditions)):
|
||||
@ -352,7 +356,12 @@ with open(input_file) as f:
|
||||
funcsText += '\tMTP' + name + '(' + ', '.join(prmsStr) + ') : ' + ', '.join(prmsInit) + ' {\n\t}\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 = [];
|
||||
for k in prmsList:
|
||||
v = prms[k];
|
||||
@ -363,56 +372,56 @@ with open(input_file) as f:
|
||||
size.append('v' + k + '.innerLength()');
|
||||
if (not len(size)):
|
||||
size.append('0');
|
||||
funcsText += '\t\treturn ' + ' + '.join(size) + ';\n';
|
||||
funcsText += '\t}\n';
|
||||
methodBodies += '\treturn ' + ' + '.join(size) + ';\n';
|
||||
methodBodies += '}\n';
|
||||
|
||||
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:
|
||||
v = prms[k];
|
||||
if (k in conditionsList):
|
||||
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:
|
||||
funcsText += '\t\tv' + k + '.read(from, end);\n';
|
||||
funcsText += '\t}\n';
|
||||
methodBodies += '\tv' + k + '.read(from, end);\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:
|
||||
v = prms[k];
|
||||
if (k in conditionsList):
|
||||
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:
|
||||
funcsText += '\t\tv' + k + '.write(to);\n';
|
||||
funcsText += '\t}\n';
|
||||
methodBodies += '\tv' + k + '.write(to);\n';
|
||||
methodBodies += '}\n';
|
||||
|
||||
if (isTemplate != ''):
|
||||
funcsText += '\n\tusing ResponseType = typename TQueryType::ResponseType;\n';
|
||||
inlineMethods += methodBodies;
|
||||
else:
|
||||
funcsText += '\n\tusing ResponseType = MTP' + resType + ';\n'; # method return type
|
||||
methods += methodBodies;
|
||||
|
||||
funcsText += '};\n'; # class ending
|
||||
if (len(conditionsList)):
|
||||
funcsText += 'Q_DECLARE_OPERATORS_FOR_FLAGS(MTP' + name + '::Flags)\n\n';
|
||||
if (isTemplate != ''):
|
||||
funcsText += 'template <typename TQueryType>\n';
|
||||
funcsText += 'class MTP' + Name + ' : public 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';
|
||||
funcsText += 'using MTP' + Name + ' = MTPBoxed<MTP' + name + '<TQueryType>>;\n';
|
||||
else:
|
||||
funcsText += 'class MTP' + Name + ' : public 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';
|
||||
funcsText += 'using MTP' + Name + ' = MTPBoxed<MTP' + name + '>;\n';
|
||||
funcs = funcs + 1;
|
||||
|
||||
if (not restype in funcsDict):
|
||||
@ -545,9 +554,11 @@ for restype in typesList:
|
||||
v = typesDict[restype];
|
||||
resType = TypesDict[restype];
|
||||
withData = 0;
|
||||
creatorsText = '';
|
||||
creatorsDeclarations = '';
|
||||
creatorsBodies = '';
|
||||
flagDeclarations = '';
|
||||
constructsText = '';
|
||||
constructsInline = '';
|
||||
constructsBodies = '';
|
||||
|
||||
forwards += 'class MTP' + restype + ';\n';
|
||||
forwTypedefs += 'using MTP' + resType + ' = MTPBoxed<MTP' + restype + '>;\n';
|
||||
@ -594,7 +605,7 @@ for restype in typesList:
|
||||
dataText += '\n';
|
||||
dataText += '\t\tMAX_FIELD = (1 << ' + str(maxbit) + '),\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 += '\n';
|
||||
if (len(conditions)):
|
||||
@ -612,17 +623,17 @@ for restype in typesList:
|
||||
withData = 1;
|
||||
|
||||
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):
|
||||
constructsInline += '\tt_assert(_type == mtpc_' + name + ');\n';
|
||||
constructsInline += '\treturn queryData<MTPD' + name + '>();\n';
|
||||
constructsInline += '}\n';
|
||||
constructsBodies += '\tt_assert(_type == mtpc_' + name + ');\n';
|
||||
constructsBodies += '\treturn queryData<MTPD' + name + '>();\n';
|
||||
constructsBodies += '}\n';
|
||||
|
||||
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):
|
||||
constructsInline += ', _type(mtpc_' + name + ')';
|
||||
constructsInline += ' {\n}\n';
|
||||
constructsBodies += ', _type(mtpc_' + name + ')';
|
||||
constructsBodies += ' {\n}\n';
|
||||
|
||||
dataText += '\tMTPD' + name + '('; # params constructor
|
||||
prmsStr = [];
|
||||
@ -689,10 +700,11 @@ for restype in typesList:
|
||||
creatorProxyText += '\t\treturn MTP' + restype + '();\n';
|
||||
creatorProxyText += '\t}\n';
|
||||
if (len(conditionsList)):
|
||||
creatorsText += 'Q_DECLARE_OPERATORS_FOR_FLAGS(MTPD' + name + '::Flags)\n';
|
||||
creatorsText += 'inline MTP' + restype + ' MTP_' + name + '(' + ', '.join(creatorParams) + ') {\n';
|
||||
creatorsText += '\treturn MTP::internal::TypeCreator::new_' + name + '(' + ', '.join(creatorParamsList) + ');\n';
|
||||
creatorsText += '}\n';
|
||||
flagDeclarations += 'Q_DECLARE_OPERATORS_FOR_FLAGS(MTPD' + name + '::Flags)\n';
|
||||
creatorsDeclarations += 'MTP' + restype + ' MTP_' + name + '(' + ', '.join(creatorParams) + ');\n';
|
||||
creatorsBodies += 'MTP' + restype + ' MTP_' + name + '(' + ', '.join(creatorParams) + ') {\n';
|
||||
creatorsBodies += '\treturn MTP::internal::TypeCreator::new_' + name + '(' + ', '.join(creatorParamsList) + ');\n';
|
||||
creatorsBodies += '}\n';
|
||||
|
||||
if (withType):
|
||||
reader += '\t\tcase mtpc_' + name + ': _type = cons; '; # read switch line
|
||||
@ -732,10 +744,10 @@ for restype in typesList:
|
||||
inits.append('TypeDataOwner(' + newFast + ')');
|
||||
if (withData and not withType):
|
||||
typesText += ';\n';
|
||||
inlineMethods += '\ninline MTP' + restype + '::MTP' + restype + '()';
|
||||
methods += '\nMTP' + restype + '::MTP' + restype + '()';
|
||||
if (inits):
|
||||
inlineMethods += ' : ' + ', '.join(inits);
|
||||
inlineMethods += ' {\n}\n';
|
||||
methods += ' : ' + ', '.join(inits);
|
||||
methods += ' {\n}\n';
|
||||
else:
|
||||
if (inits):
|
||||
typesText += ' : ' + ', '.join(inits);
|
||||
@ -745,68 +757,68 @@ for restype in typesList:
|
||||
typesText += getters;
|
||||
|
||||
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):
|
||||
inlineMethods += '\tswitch (_type) {\n';
|
||||
inlineMethods += sizeCases;
|
||||
inlineMethods += '\t}\n';
|
||||
inlineMethods += '\treturn 0;\n';
|
||||
methods += '\tswitch (_type) {\n';
|
||||
methods += sizeCases;
|
||||
methods += '\t}\n';
|
||||
methods += '\treturn 0;\n';
|
||||
else:
|
||||
inlineMethods += sizeFast;
|
||||
inlineMethods += '}\n';
|
||||
methods += sizeFast;
|
||||
methods += '}\n';
|
||||
|
||||
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):
|
||||
inlineMethods += '\tt_assert(_type != 0);\n';
|
||||
inlineMethods += '\treturn _type;\n';
|
||||
methods += '\tt_assert(_type != 0);\n';
|
||||
methods += '\treturn _type;\n';
|
||||
else:
|
||||
inlineMethods += '\treturn mtpc_' + v[0][0] + ';\n';
|
||||
inlineMethods += '}\n';
|
||||
methods += '\treturn mtpc_' + v[0][0] + ';\n';
|
||||
methods += '}\n';
|
||||
|
||||
typesText += '\tvoid read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons'; # read method
|
||||
if (not withType):
|
||||
typesText += ' = mtpc_' + name;
|
||||
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 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):
|
||||
inlineMethods += '\tswitch (cons) {\n'
|
||||
inlineMethods += reader;
|
||||
inlineMethods += '\t\tdefault: throw mtpErrorUnexpected(cons, "MTP' + restype + '");\n';
|
||||
inlineMethods += '\t}\n';
|
||||
methods += '\tswitch (cons) {\n'
|
||||
methods += reader;
|
||||
methods += '\t\tdefault: throw mtpErrorUnexpected(cons, "MTP' + restype + '");\n';
|
||||
methods += '\t}\n';
|
||||
else:
|
||||
inlineMethods += reader;
|
||||
inlineMethods += '}\n';
|
||||
methods += reader;
|
||||
methods += '}\n';
|
||||
|
||||
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 != ''):
|
||||
inlineMethods += '\tswitch (_type) {\n';
|
||||
inlineMethods += writer;
|
||||
inlineMethods += '\t}\n';
|
||||
methods += '\tswitch (_type) {\n';
|
||||
methods += writer;
|
||||
methods += '\t}\n';
|
||||
else:
|
||||
inlineMethods += writer;
|
||||
inlineMethods += '}\n';
|
||||
methods += writer;
|
||||
methods += '}\n';
|
||||
|
||||
typesText += '\n\tusing ResponseType = void;\n'; # no response types declared
|
||||
|
||||
typesText += '\nprivate:\n'; # private constructors
|
||||
if (withType): # by-type-id constructor
|
||||
typesText += '\texplicit MTP' + restype + '(mtpTypeId type);\n';
|
||||
inlineMethods += 'inline MTP' + restype + '::MTP' + restype + '(mtpTypeId type) : ';
|
||||
inlineMethods += '_type(type)';
|
||||
inlineMethods += ' {\n';
|
||||
inlineMethods += '\tswitch (type) {\n'; # type id check
|
||||
inlineMethods += switchLines;
|
||||
inlineMethods += '\t\tdefault: throw mtpErrorBadTypeId(type, "MTP' + restype + '");\n\t}\n';
|
||||
inlineMethods += '}\n'; # by-type-id constructor end
|
||||
methods += 'MTP' + restype + '::MTP' + restype + '(mtpTypeId type) : ';
|
||||
methods += '_type(type)';
|
||||
methods += ' {\n';
|
||||
methods += '\tswitch (type) {\n'; # type id check
|
||||
methods += switchLines;
|
||||
methods += '\t\tdefault: throw mtpErrorBadTypeId(type, "MTP' + restype + '");\n\t}\n';
|
||||
methods += '}\n'; # by-type-id constructor end
|
||||
|
||||
if (withData):
|
||||
typesText += constructsText;
|
||||
inlineMethods += constructsInline;
|
||||
methods += constructsBodies;
|
||||
|
||||
if (friendDecl):
|
||||
typesText += '\n' + friendDecl;
|
||||
@ -816,9 +828,13 @@ for restype in typesList:
|
||||
|
||||
typesText += '};\n'; # type class ended
|
||||
|
||||
inlineMethods += creatorsText;
|
||||
flagOperators += flagDeclarations;
|
||||
factories += creatorsDeclarations;
|
||||
methods += creatorsBodies;
|
||||
typesText += 'using MTP' + resType + ' = MTPBoxed<MTP' + restype + '>;\n'; # boxed type definition
|
||||
|
||||
flagOperators += '\n'
|
||||
|
||||
for childName in parentFlagsList:
|
||||
parentName = parentFlags[childName];
|
||||
for flag in parentFlagsCheck[childName]:
|
||||
@ -836,8 +852,8 @@ for childName in parentFlagsList:
|
||||
error
|
||||
else:
|
||||
parentFlagsCheck[parentName][flag] = parentFlagsCheck[childName][flag];
|
||||
inlineMethods += '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(' + childName + '::Flags flags) { return ' + parentName + '::Flags(QFlag(flags)); }\n';
|
||||
flagOperators += 'inline ' + parentName + '::Flags mtpCastFlags(MTPflags<' + childName + '::Flags> flags) { return mtpCastFlags(flags.v); }\n';
|
||||
|
||||
# manual types added here
|
||||
textSerializeMethods += '\
|
||||
@ -946,20 +962,12 @@ enum {\n\
|
||||
' + dataTexts + '\n\
|
||||
// RPC methods\n\
|
||||
' + funcsText + '\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\
|
||||
// Inline methods definition\n\
|
||||
// Template methods definition\n\
|
||||
' + inlineMethods + '\n\
|
||||
// Flag operators definition\n\
|
||||
' + flagOperators + '\n\
|
||||
// Factory methods declaration\n\
|
||||
' + factories + '\n\
|
||||
// Human-readable text serialization\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\
|
||||
#include "scheme.h"\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 StagesFlags = QVector<int32>;\n\
|
||||
\n\
|
||||
|
@ -84,7 +84,7 @@ private:
|
||||
Over = 0x01,
|
||||
DeleteOver = 0x02,
|
||||
};
|
||||
Q_DECLARE_FLAGS(StateFlags, StateFlag);
|
||||
using StateFlags = QFlags<StateFlag>;
|
||||
StateFlags _state;
|
||||
friend inline StateFlags operator~(StateFlag flag) {
|
||||
return ~StateFlags(flag);
|
||||
|
@ -22,7 +22,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "core/basic_types.h"
|
||||
#include "structs.h"
|
||||
#include "mtproto/core_types.h"
|
||||
|
||||
class FileLoader;
|
||||
|
||||
|
@ -22,7 +22,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "core/basic_types.h"
|
||||
#include "structs.h"
|
||||
#include "mtproto/core_types.h"
|
||||
#include "history/history_location_manager.h"
|
||||
|
||||
namespace InlineBots {
|
||||
|
@ -31,6 +31,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "data/data_drafts.h"
|
||||
#include "ui/widgets/dropdown_menu.h"
|
||||
#include "chat_helpers/message_field.h"
|
||||
#include "chat_helpers/stickers.h"
|
||||
#include "observer_peer.h"
|
||||
#include "apiwrap.h"
|
||||
#include "dialogs/dialogs_widget.h"
|
||||
@ -5218,7 +5219,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
auto &sets = Global::RefStickerSets();
|
||||
auto it = sets.find(s.vid.v);
|
||||
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 {
|
||||
it->flags |= MTPDstickerSet::Flag::f_installed;
|
||||
if (it->flags & MTPDstickerSet::Flag::f_archived) {
|
||||
|
@ -20,7 +20,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "mtproto/core_types.h"
|
||||
#include "mtproto/auth_key.h"
|
||||
#include "mtproto/dc_options.h"
|
||||
#include "core/single_timer.h"
|
||||
|
@ -20,7 +20,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "mtproto/core_types.h"
|
||||
#include "mtproto/dc_options.h"
|
||||
|
||||
namespace MTP {
|
||||
|
@ -20,7 +20,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "mtproto/core_types.h"
|
||||
#include "mtproto/connection_tcp.h"
|
||||
|
||||
namespace MTP {
|
||||
|
@ -20,7 +20,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "mtproto/core_types.h"
|
||||
#include "mtproto/connection_abstract.h"
|
||||
|
||||
namespace MTP {
|
||||
|
@ -20,7 +20,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "mtproto/core_types.h"
|
||||
#include "mtproto/auth_key.h"
|
||||
#include "mtproto/connection_abstract.h"
|
||||
|
||||
|
@ -22,10 +22,131 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
#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) {
|
||||
return QString::number(number);
|
||||
void MTPstring::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
|
||||
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) {
|
||||
@ -33,31 +154,31 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
case mtpc_int: {
|
||||
MTPint value;
|
||||
value.read(from, end, cons);
|
||||
to.add(mtpWrapNumber(value.v)).add(" [INT]");
|
||||
to.add(QString::number(value.v)).add(" [INT]");
|
||||
} break;
|
||||
|
||||
case mtpc_long: {
|
||||
MTPlong value;
|
||||
value.read(from, end, cons);
|
||||
to.add(mtpWrapNumber(value.v)).add(" [LONG]");
|
||||
to.add(QString::number(value.v)).add(" [LONG]");
|
||||
} break;
|
||||
|
||||
case mtpc_int128: {
|
||||
MTPint128 value;
|
||||
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;
|
||||
|
||||
case mtpc_int256: {
|
||||
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(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;
|
||||
|
||||
case mtpc_double: {
|
||||
MTPdouble value;
|
||||
value.read(from, end, cons);
|
||||
to.add(mtpWrapNumber(value.v)).add(" [DOUBLE]");
|
||||
to.add(QString::number(value.v)).add(" [DOUBLE]");
|
||||
} break;
|
||||
|
||||
case mtpc_string: {
|
||||
@ -68,9 +189,9 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
if (str.toUtf8() == strUtf8) {
|
||||
to.add("\"").add(str.replace('\\', "\\\\").replace('"', "\\\"").replace('\n', "\\n")).add("\" [STRING]");
|
||||
} 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 {
|
||||
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;
|
||||
|
||||
@ -79,7 +200,7 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
throw Exception("from >= end in vector");
|
||||
}
|
||||
int32 cnt = *(from++);
|
||||
to.add("[ vector<0x").add(mtpWrapNumber(vcons, 16)).add(">");
|
||||
to.add("[ vector<0x").add(QString::number(vcons, 16)).add(">");
|
||||
if (cnt) {
|
||||
to.add("\n").addSpaces(level);
|
||||
for (int32 i = 0; i < cnt; ++i) {
|
||||
@ -140,7 +261,7 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
default: {
|
||||
for (uint32 i = 1; i < mtpLayerMaxSingle; ++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;
|
||||
}
|
||||
}
|
||||
@ -149,22 +270,10 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
throw Exception("from >= end in invokeWithLayer");
|
||||
}
|
||||
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;
|
||||
}
|
||||
throw Exception(QString("unknown cons 0x%1").arg(cons, 0, 16));
|
||||
} 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 mtpRequest : public QSharedPointer<mtpRequestData> {
|
||||
public:
|
||||
mtpRequest() {
|
||||
}
|
||||
mtpRequest() = default;
|
||||
explicit mtpRequest(mtpRequestData *ptr) : QSharedPointer<mtpRequestData>(ptr) {
|
||||
}
|
||||
|
||||
@ -58,35 +57,17 @@ class mtpRequestData : public mtpBuffer {
|
||||
public:
|
||||
// in toSend: = 0 - must send in container, > 0 - can send without container
|
||||
// in haveSent: = 0 - container with msgIds, > 0 - when was sent
|
||||
TimeMs msDate;
|
||||
TimeMs msDate = 0;
|
||||
|
||||
mtpRequestId requestId;
|
||||
mtpRequestId requestId = 0;
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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 mtpRequest prepare(uint32 requestSize, uint32 maxSize = 0);
|
||||
static void padding(mtpRequest &request);
|
||||
|
||||
static uint32 messageSize(const mtpRequest &request) {
|
||||
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 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);
|
||||
|
||||
private:
|
||||
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
|
||||
}
|
||||
static uint32 _padding(uint32 requestSize);
|
||||
|
||||
};
|
||||
|
||||
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 mtpRequestMap = QMap<mtpMsgId, mtpRequest>;
|
||||
using mtpMsgIdsSet = QMap<mtpMsgId, bool>;
|
||||
@ -152,18 +109,21 @@ class mtpErrorUnexpected : public Exception {
|
||||
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?..
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class mtpErrorInsufficient : public Exception {
|
||||
public:
|
||||
mtpErrorInsufficient() : Exception("MTP Insufficient bytes in input buffer") {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class mtpErrorBadTypeId : public Exception {
|
||||
public:
|
||||
mtpErrorBadTypeId(mtpTypeId typeId, const QString &type) : Exception(QString("MTP Bad type id %1 passed to constructor of %2").arg(typeId).arg(type)) {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
namespace MTP {
|
||||
@ -228,10 +188,10 @@ protected:
|
||||
_data = data;
|
||||
}
|
||||
|
||||
// Unsafe cast, type should be checked by the caller.
|
||||
template <typename DataType>
|
||||
const DataType &queryData() const {
|
||||
// Unsafe cast, type should be checked by the caller.
|
||||
t_assert(_data != nullptr);
|
||||
Expects(_data != nullptr);
|
||||
return static_cast<const DataType &>(*_data);
|
||||
}
|
||||
|
||||
@ -319,20 +279,16 @@ static const uint32 mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0])
|
||||
template <typename bareT>
|
||||
class MTPBoxed : public bareT {
|
||||
public:
|
||||
using bareT::bareT;
|
||||
MTPBoxed() = default;
|
||||
MTPBoxed(const MTPBoxed<bareT> &v) = default;
|
||||
MTPBoxed<bareT> &operator=(const MTPBoxed<bareT> &v) = default;
|
||||
MTPBoxed(const bareT &v) : bareT(v) {
|
||||
}
|
||||
MTPBoxed(const MTPBoxed<bareT> &v) : bareT(v) {
|
||||
}
|
||||
|
||||
MTPBoxed<bareT> &operator=(const bareT &v) {
|
||||
*((bareT*)this) = v;
|
||||
return *this;
|
||||
}
|
||||
MTPBoxed<bareT> &operator=(const MTPBoxed<bareT> &v) {
|
||||
*((bareT*)this) = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint32 innerLength() const {
|
||||
return sizeof(mtpTypeId) + bareT::innerLength();
|
||||
@ -631,58 +587,12 @@ class MTPstring {
|
||||
public:
|
||||
MTPstring() = default;
|
||||
|
||||
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;
|
||||
}
|
||||
uint32 innerLength() const;
|
||||
mtpTypeId type() const {
|
||||
return mtpc_string;
|
||||
}
|
||||
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_string) {
|
||||
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 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);
|
||||
}
|
||||
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_string);
|
||||
void write(mtpBuffer &to) const;
|
||||
|
||||
QByteArray v;
|
||||
|
||||
@ -832,11 +742,6 @@ inline bool operator!=(const MTPvector<T> &a, const MTPvector<T> &b) {
|
||||
|
||||
// Human-readable text serialization
|
||||
|
||||
template <typename Type>
|
||||
QString mtpWrapNumber(Type number, int32 base = 10) {
|
||||
return QString::number(number, base);
|
||||
}
|
||||
|
||||
struct MTPStringLogger {
|
||||
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);
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
#include "mtproto/core_types.h"
|
||||
#include "mtproto/type_utils.h"
|
||||
#include "mtproto/session.h"
|
||||
#include "core/single_timer.h"
|
||||
#include "mtproto/mtp_instance.h"
|
||||
|
25
Telegram/SourceFiles/mtproto/type_utils.cpp
Normal file
25
Telegram/SourceFiles/mtproto/type_utils.cpp
Normal file
@ -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());
|
130
Telegram/SourceFiles/mtproto/type_utils.h
Normal file
130
Telegram/SourceFiles/mtproto/type_utils.h
Normal file
@ -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/special_config_request.cpp
|
||||
<(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.h
|
||||
<(src_loc)/platform/linux/linux_desktop_environment.cpp
|
||||
|
Loading…
Reference in New Issue
Block a user