/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once #include "mtproto/core_types.h" #include namespace MTP { namespace details { class RequestData; class SerializedRequest; class RequestConstructHider { struct Tag {}; friend class RequestData; friend class SerializedRequest; }; class SerializedRequest { public: SerializedRequest() = default; static constexpr auto kSaltInts = 2; static constexpr auto kSessionIdInts = 2; static constexpr auto kMessageIdPosition = kSaltInts + kSessionIdInts; static constexpr auto kMessageIdInts = 2; static constexpr auto kSeqNoPosition = kMessageIdPosition + kMessageIdInts; static constexpr auto kSeqNoInts = 1; static constexpr auto kMessageLengthPosition = kSeqNoPosition + kSeqNoInts; static constexpr auto kMessageLengthInts = 1; static constexpr auto kMessageBodyPosition = kMessageLengthPosition + kMessageLengthInts; static SerializedRequest Prepare(uint32 size, uint32 reserveSize = 0); template < typename Request, typename = std::enable_if_t>> static SerializedRequest Serialize(const Request &request); // For template MTP requests and MTPBoxed instantiation. template void write(Accumulator &to) const { if (const auto size = sizeInBytes()) { tl::Writer::PutBytes(to, dataInBytes(), size); } } RequestData *operator->() const; RequestData &operator*() const; explicit operator bool() const; void setMsgId(mtpMsgId msgId); [[nodiscard]] mtpMsgId getMsgId() const; void setSeqNo(uint32 seqNo); [[nodiscard]] uint32 getSeqNo() const; void addPadding(bool extended, bool old); [[nodiscard]] uint32 messageSize() const; [[nodiscard]] bool needAck() const; using ResponseType = void; // don't know real response type =( private: explicit SerializedRequest(const RequestConstructHider::Tag &); [[nodiscard]] size_t sizeInBytes() const; [[nodiscard]] const void *dataInBytes() const; std::shared_ptr _data; }; class RequestData : public mtpBuffer { public: explicit RequestData(const RequestConstructHider::Tag &) { } SerializedRequest after; crl::time lastSentTime = 0; mtpRequestId requestId = 0; bool needsLayer = false; bool forceSendInContainer = false; }; template SerializedRequest SerializedRequest::Serialize(const Request &request) { const auto requestSize = tl::count_length(request) >> 2; auto serialized = Prepare(requestSize); request.template write(*serialized); return serialized; } } // namespace details } // namespace MTP