packet.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <array>
  5. #include <vector>
  6. #include "common/common_types.h"
  7. namespace Network {
  8. /// A class that serializes data for network transfer. It also handles endianness
  9. class Packet {
  10. public:
  11. Packet() = default;
  12. ~Packet() = default;
  13. /**
  14. * Append data to the end of the packet
  15. * @param data Pointer to the sequence of bytes to append
  16. * @param size_in_bytes Number of bytes to append
  17. */
  18. void Append(const void* data, std::size_t size_in_bytes);
  19. /**
  20. * Reads data from the current read position of the packet
  21. * @param out_data Pointer where the data should get written to
  22. * @param size_in_bytes Number of bytes to read
  23. */
  24. void Read(void* out_data, std::size_t size_in_bytes);
  25. /**
  26. * Clear the packet
  27. * After calling Clear, the packet is empty.
  28. */
  29. void Clear();
  30. /**
  31. * Ignores bytes while reading
  32. * @param length THe number of bytes to ignore
  33. */
  34. void IgnoreBytes(u32 length);
  35. /**
  36. * Get a pointer to the data contained in the packet
  37. * @return Pointer to the data
  38. */
  39. const void* GetData() const;
  40. /**
  41. * This function returns the number of bytes pointed to by
  42. * what getData returns.
  43. * @return Data size, in bytes
  44. */
  45. std::size_t GetDataSize() const;
  46. /**
  47. * This function is useful to know if there is some data
  48. * left to be read, without actually reading it.
  49. * @return True if all data was read, false otherwise
  50. */
  51. bool EndOfPacket() const;
  52. explicit operator bool() const;
  53. /// Overloads of read function to read data from the packet
  54. Packet& Read(bool& out_data);
  55. Packet& Read(s8& out_data);
  56. Packet& Read(u8& out_data);
  57. Packet& Read(s16& out_data);
  58. Packet& Read(u16& out_data);
  59. Packet& Read(s32& out_data);
  60. Packet& Read(u32& out_data);
  61. Packet& Read(s64& out_data);
  62. Packet& Read(u64& out_data);
  63. Packet& Read(float& out_data);
  64. Packet& Read(double& out_data);
  65. Packet& Read(char* out_data);
  66. Packet& Read(std::string& out_data);
  67. template <typename T>
  68. Packet& Read(std::vector<T>& out_data);
  69. template <typename T, std::size_t S>
  70. Packet& Read(std::array<T, S>& out_data);
  71. /// Overloads of write function to write data into the packet
  72. Packet& Write(bool in_data);
  73. Packet& Write(s8 in_data);
  74. Packet& Write(u8 in_data);
  75. Packet& Write(s16 in_data);
  76. Packet& Write(u16 in_data);
  77. Packet& Write(s32 in_data);
  78. Packet& Write(u32 in_data);
  79. Packet& Write(s64 in_data);
  80. Packet& Write(u64 in_data);
  81. Packet& Write(float in_data);
  82. Packet& Write(double in_data);
  83. Packet& Write(const char* in_data);
  84. Packet& Write(const std::string& in_data);
  85. template <typename T>
  86. Packet& Write(const std::vector<T>& in_data);
  87. template <typename T, std::size_t S>
  88. Packet& Write(const std::array<T, S>& data);
  89. private:
  90. /**
  91. * Check if the packet can extract a given number of bytes
  92. * This function updates accordingly the state of the packet.
  93. * @param size Size to check
  94. * @return True if size bytes can be read from the packet
  95. */
  96. bool CheckSize(std::size_t size);
  97. // Member data
  98. std::vector<char> data; ///< Data stored in the packet
  99. std::size_t read_pos = 0; ///< Current reading position in the packet
  100. bool is_valid = true; ///< Reading state of the packet
  101. };
  102. template <typename T>
  103. Packet& Packet::Read(std::vector<T>& out_data) {
  104. // First extract the size
  105. u32 size = 0;
  106. Read(size);
  107. out_data.resize(size);
  108. // Then extract the data
  109. for (std::size_t i = 0; i < out_data.size(); ++i) {
  110. T character;
  111. Read(character);
  112. out_data[i] = character;
  113. }
  114. return *this;
  115. }
  116. template <typename T, std::size_t S>
  117. Packet& Packet::Read(std::array<T, S>& out_data) {
  118. for (std::size_t i = 0; i < out_data.size(); ++i) {
  119. T character;
  120. Read(character);
  121. out_data[i] = character;
  122. }
  123. return *this;
  124. }
  125. template <typename T>
  126. Packet& Packet::Write(const std::vector<T>& in_data) {
  127. // First insert the size
  128. Write(static_cast<u32>(in_data.size()));
  129. // Then insert the data
  130. for (std::size_t i = 0; i < in_data.size(); ++i) {
  131. Write(in_data[i]);
  132. }
  133. return *this;
  134. }
  135. template <typename T, std::size_t S>
  136. Packet& Packet::Write(const std::array<T, S>& in_data) {
  137. for (std::size_t i = 0; i < in_data.size(); ++i) {
  138. Write(in_data[i]);
  139. }
  140. return *this;
  141. }
  142. } // namespace Network