mtproto_serialized_request.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "mtproto/core_types.h"
  9. #include <crl/crl_time.h>
  10. namespace MTP {
  11. namespace details {
  12. class RequestData;
  13. class SerializedRequest;
  14. class RequestConstructHider {
  15. struct Tag {};
  16. friend class RequestData;
  17. friend class SerializedRequest;
  18. };
  19. class SerializedRequest {
  20. public:
  21. SerializedRequest() = default;
  22. static constexpr auto kSaltInts = 2;
  23. static constexpr auto kSessionIdInts = 2;
  24. static constexpr auto kMessageIdPosition = kSaltInts + kSessionIdInts;
  25. static constexpr auto kMessageIdInts = 2;
  26. static constexpr auto kSeqNoPosition = kMessageIdPosition
  27. + kMessageIdInts;
  28. static constexpr auto kSeqNoInts = 1;
  29. static constexpr auto kMessageLengthPosition = kSeqNoPosition
  30. + kSeqNoInts;
  31. static constexpr auto kMessageLengthInts = 1;
  32. static constexpr auto kMessageBodyPosition = kMessageLengthPosition
  33. + kMessageLengthInts;
  34. static SerializedRequest Prepare(uint32 size, uint32 reserveSize = 0);
  35. template <
  36. typename Request,
  37. typename = std::enable_if_t<tl::is_boxed_v<Request>>>
  38. static SerializedRequest Serialize(const Request &request);
  39. // For template MTP requests and MTPBoxed instantiation.
  40. template <typename Accumulator>
  41. void write(Accumulator &to) const {
  42. if (const auto size = sizeInBytes()) {
  43. tl::Writer<Accumulator>::PutBytes(to, dataInBytes(), size);
  44. }
  45. }
  46. RequestData *operator->() const;
  47. RequestData &operator*() const;
  48. explicit operator bool() const;
  49. void setMsgId(mtpMsgId msgId);
  50. [[nodiscard]] mtpMsgId getMsgId() const;
  51. void setSeqNo(uint32 seqNo);
  52. [[nodiscard]] uint32 getSeqNo() const;
  53. void addPadding(bool forAuthKeyInner);
  54. [[nodiscard]] uint32 messageSize() const;
  55. [[nodiscard]] bool needAck() const;
  56. using ResponseType = void; // don't know real response type =(
  57. private:
  58. explicit SerializedRequest(const RequestConstructHider::Tag &);
  59. [[nodiscard]] size_t sizeInBytes() const;
  60. [[nodiscard]] const void *dataInBytes() const;
  61. std::shared_ptr<RequestData> _data;
  62. };
  63. class RequestData : public mtpBuffer {
  64. public:
  65. explicit RequestData(const RequestConstructHider::Tag &) {
  66. }
  67. SerializedRequest after;
  68. crl::time lastSentTime = 0;
  69. mtpRequestId requestId = 0;
  70. bool needsLayer = false;
  71. bool forceSendInContainer = false;
  72. };
  73. template <typename Request, typename>
  74. SerializedRequest SerializedRequest::Serialize(const Request &request) {
  75. const auto requestSize = tl::count_length(request) >> 2;
  76. auto serialized = Prepare(requestSize);
  77. request.template write<mtpBuffer>(*serialized);
  78. return serialized;
  79. }
  80. } // namespace details
  81. } // namespace MTP