packet.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. // Copyright 2017 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #ifdef _WIN32
  5. #include <winsock2.h>
  6. #else
  7. #include <arpa/inet.h>
  8. #endif
  9. #include <cstring>
  10. #include <string>
  11. #include "network/packet.h"
  12. namespace Network {
  13. #ifndef htonll
  14. u64 htonll(u64 x) {
  15. return ((1 == htonl(1)) ? (x) : ((uint64_t)htonl((x)&0xFFFFFFFF) << 32) | htonl((x) >> 32));
  16. }
  17. #endif
  18. #ifndef ntohll
  19. u64 ntohll(u64 x) {
  20. return ((1 == ntohl(1)) ? (x) : ((uint64_t)ntohl((x)&0xFFFFFFFF) << 32) | ntohl((x) >> 32));
  21. }
  22. #endif
  23. void Packet::Append(const void* in_data, std::size_t size_in_bytes) {
  24. if (in_data && (size_in_bytes > 0)) {
  25. std::size_t start = data.size();
  26. data.resize(start + size_in_bytes);
  27. std::memcpy(&data[start], in_data, size_in_bytes);
  28. }
  29. }
  30. void Packet::Read(void* out_data, std::size_t size_in_bytes) {
  31. if (out_data && CheckSize(size_in_bytes)) {
  32. std::memcpy(out_data, &data[read_pos], size_in_bytes);
  33. read_pos += size_in_bytes;
  34. }
  35. }
  36. void Packet::Clear() {
  37. data.clear();
  38. read_pos = 0;
  39. is_valid = true;
  40. }
  41. const void* Packet::GetData() const {
  42. return !data.empty() ? &data[0] : nullptr;
  43. }
  44. void Packet::IgnoreBytes(u32 length) {
  45. read_pos += length;
  46. }
  47. std::size_t Packet::GetDataSize() const {
  48. return data.size();
  49. }
  50. bool Packet::EndOfPacket() const {
  51. return read_pos >= data.size();
  52. }
  53. Packet::operator bool() const {
  54. return is_valid ? &Packet::CheckSize : nullptr;
  55. }
  56. Packet& Packet::operator>>(bool& out_data) {
  57. u8 value;
  58. if (*this >> value) {
  59. out_data = (value != 0);
  60. }
  61. return *this;
  62. }
  63. Packet& Packet::operator>>(s8& out_data) {
  64. Read(&out_data, sizeof(out_data));
  65. return *this;
  66. }
  67. Packet& Packet::operator>>(u8& out_data) {
  68. Read(&out_data, sizeof(out_data));
  69. return *this;
  70. }
  71. Packet& Packet::operator>>(s16& out_data) {
  72. s16 value;
  73. Read(&value, sizeof(value));
  74. out_data = ntohs(value);
  75. return *this;
  76. }
  77. Packet& Packet::operator>>(u16& out_data) {
  78. u16 value;
  79. Read(&value, sizeof(value));
  80. out_data = ntohs(value);
  81. return *this;
  82. }
  83. Packet& Packet::operator>>(s32& out_data) {
  84. s32 value;
  85. Read(&value, sizeof(value));
  86. out_data = ntohl(value);
  87. return *this;
  88. }
  89. Packet& Packet::operator>>(u32& out_data) {
  90. u32 value;
  91. Read(&value, sizeof(value));
  92. out_data = ntohl(value);
  93. return *this;
  94. }
  95. Packet& Packet::operator>>(s64& out_data) {
  96. s64 value;
  97. Read(&value, sizeof(value));
  98. out_data = ntohll(value);
  99. return *this;
  100. }
  101. Packet& Packet::operator>>(u64& out_data) {
  102. u64 value;
  103. Read(&value, sizeof(value));
  104. out_data = ntohll(value);
  105. return *this;
  106. }
  107. Packet& Packet::operator>>(float& out_data) {
  108. Read(&out_data, sizeof(out_data));
  109. return *this;
  110. }
  111. Packet& Packet::operator>>(double& out_data) {
  112. Read(&out_data, sizeof(out_data));
  113. return *this;
  114. }
  115. Packet& Packet::operator>>(char* out_data) {
  116. // First extract string length
  117. u32 length = 0;
  118. *this >> length;
  119. if ((length > 0) && CheckSize(length)) {
  120. // Then extract characters
  121. std::memcpy(out_data, &data[read_pos], length);
  122. out_data[length] = '\0';
  123. // Update reading position
  124. read_pos += length;
  125. }
  126. return *this;
  127. }
  128. Packet& Packet::operator>>(std::string& out_data) {
  129. // First extract string length
  130. u32 length = 0;
  131. *this >> length;
  132. out_data.clear();
  133. if ((length > 0) && CheckSize(length)) {
  134. // Then extract characters
  135. out_data.assign(&data[read_pos], length);
  136. // Update reading position
  137. read_pos += length;
  138. }
  139. return *this;
  140. }
  141. Packet& Packet::operator<<(bool in_data) {
  142. *this << static_cast<u8>(in_data);
  143. return *this;
  144. }
  145. Packet& Packet::operator<<(s8 in_data) {
  146. Append(&in_data, sizeof(in_data));
  147. return *this;
  148. }
  149. Packet& Packet::operator<<(u8 in_data) {
  150. Append(&in_data, sizeof(in_data));
  151. return *this;
  152. }
  153. Packet& Packet::operator<<(s16 in_data) {
  154. s16 toWrite = htons(in_data);
  155. Append(&toWrite, sizeof(toWrite));
  156. return *this;
  157. }
  158. Packet& Packet::operator<<(u16 in_data) {
  159. u16 toWrite = htons(in_data);
  160. Append(&toWrite, sizeof(toWrite));
  161. return *this;
  162. }
  163. Packet& Packet::operator<<(s32 in_data) {
  164. s32 toWrite = htonl(in_data);
  165. Append(&toWrite, sizeof(toWrite));
  166. return *this;
  167. }
  168. Packet& Packet::operator<<(u32 in_data) {
  169. u32 toWrite = htonl(in_data);
  170. Append(&toWrite, sizeof(toWrite));
  171. return *this;
  172. }
  173. Packet& Packet::operator<<(s64 in_data) {
  174. s64 toWrite = htonll(in_data);
  175. Append(&toWrite, sizeof(toWrite));
  176. return *this;
  177. }
  178. Packet& Packet::operator<<(u64 in_data) {
  179. u64 toWrite = htonll(in_data);
  180. Append(&toWrite, sizeof(toWrite));
  181. return *this;
  182. }
  183. Packet& Packet::operator<<(float in_data) {
  184. Append(&in_data, sizeof(in_data));
  185. return *this;
  186. }
  187. Packet& Packet::operator<<(double in_data) {
  188. Append(&in_data, sizeof(in_data));
  189. return *this;
  190. }
  191. Packet& Packet::operator<<(const char* in_data) {
  192. // First insert string length
  193. u32 length = static_cast<u32>(std::strlen(in_data));
  194. *this << length;
  195. // Then insert characters
  196. Append(in_data, length * sizeof(char));
  197. return *this;
  198. }
  199. Packet& Packet::operator<<(const std::string& in_data) {
  200. // First insert string length
  201. u32 length = static_cast<u32>(in_data.size());
  202. *this << length;
  203. // Then insert characters
  204. if (length > 0)
  205. Append(in_data.c_str(), length * sizeof(std::string::value_type));
  206. return *this;
  207. }
  208. bool Packet::CheckSize(std::size_t size) {
  209. is_valid = is_valid && (read_pos + size <= data.size());
  210. return is_valid;
  211. }
  212. } // namespace Network