fork download
  1. #include <iostream>
  2. #include <vector>
  3. #include <stdexcept>
  4. #include <cstdint>
  5.  
  6. class Packet
  7. {
  8. private:
  9. std::vector<uint8_t> buffer;
  10. int byteIndex;
  11. int maxByteIndex;
  12.  
  13. public:
  14. Packet() : byteIndex(0), maxByteIndex(0)
  15. {
  16. }
  17.  
  18. char* GetBuffer()
  19. {
  20. return reinterpret_cast<char*>(&buffer[0]);
  21. }
  22.  
  23. int GetLength()
  24. {
  25. return buffer.size();
  26. }
  27.  
  28. int GetByteIndex()
  29. {
  30. return byteIndex;
  31. }
  32.  
  33. void SetByteIndex(int value)
  34. {
  35. if (value < 0 || value >= buffer.size())
  36. {
  37. throw std::out_of_range("ByteIndex must be an index in the Buffer");
  38. }
  39. byteIndex = value;
  40. }
  41.  
  42. bool HasHeader()
  43. {
  44. return byteIndex >= 2;
  45. }
  46.  
  47. bool HasData()
  48. {
  49. return byteIndex == maxByteIndex;
  50. }
  51.  
  52. void Begin()
  53. {
  54. buffer.push_back(0);
  55. buffer.push_back(0);
  56. byteIndex += 2;
  57. }
  58.  
  59. void End()
  60. {
  61. buffer[0] = static_cast<uint8_t>(buffer.size()) >> 8;
  62. buffer[1] = static_cast<uint8_t>(buffer.size());
  63. }
  64.  
  65. bool ReadHeader()
  66. {
  67. int previousByteIndex = byteIndex;
  68. byteIndex = 0;
  69. uint16_t length;
  70. ReadUInt16(length);
  71. maxByteIndex = length - 1;
  72. byteIndex = previousByteIndex;
  73. return maxByteIndex > 2;
  74. }
  75.  
  76. void WriteEventID(uint8_t value)
  77. {
  78. buffer.push_back(value);
  79. byteIndex++;
  80. }
  81.  
  82. void WriteByte(uint8_t value)
  83. {
  84. buffer.push_back(value);
  85. byteIndex++;
  86. }
  87.  
  88. void WriteUInt16(uint16_t value)
  89. {
  90. buffer.push_back(static_cast<uint8_t>(value >> 8));
  91. buffer.push_back(static_cast<uint8_t>(value));
  92. byteIndex += 2;
  93. }
  94.  
  95. void WriteString(std::string value, int maxLength = 255)
  96. {
  97. if (maxLength < 0 || maxLength > 65535)
  98. {
  99. throw std::out_of_range("maxLength must be in the range [0, 65535]");
  100. }
  101. if (value.length() > maxLength)
  102. {
  103. throw std::out_of_range("String length was over the given max length");
  104. }
  105. WriteUInt16(static_cast<uint16_t>(value.length()));
  106. for (int i = 0; i < value.length(); ++i)
  107. {
  108. WriteByte(value[i]);
  109. }
  110. }
  111.  
  112. bool ReadEventID(uint8_t& value)
  113. {
  114. return ReadByte(value);
  115. }
  116.  
  117. bool ReadByte(uint8_t& value)
  118. {
  119. value = 0;
  120. if (byteIndex >= buffer.size())
  121. {
  122. return false;
  123. }
  124. value = buffer[byteIndex];
  125. byteIndex++;
  126. return true;
  127. }
  128.  
  129. bool ReadUInt16(uint16_t& value)
  130. {
  131. value = 0;
  132. if (byteIndex + 1 >= buffer.size())
  133. {
  134. return false;
  135. }
  136. value = static_cast<uint16_t>(buffer[byteIndex] << 8);
  137. value |= static_cast<uint16_t>(buffer[byteIndex + 1]);
  138. byteIndex += 2;
  139. return true;
  140. }
  141.  
  142. bool ReadString(std::string& value, int maxLength = 255)
  143. {
  144. value = "";
  145. uint16_t length;
  146. if (!ReadUInt16(length) || length > maxLength || byteIndex + length > buffer.size())
  147. {
  148. return false;
  149. }
  150. for (int i = 0; i < length; ++i)
  151. {
  152. value += static_cast<char>(buffer[byteIndex + i]);
  153. }
  154. byteIndex += length;
  155. return true;
  156. }
  157. };
  158.  
  159. int main()
  160. {
  161. Packet packet;
  162. packet.Begin();
  163. packet.WriteEventID(42);
  164. packet.WriteByte(43);
  165. packet.WriteUInt16(65535);
  166. packet.WriteString("Hello World", 20);
  167. packet.End();
  168.  
  169. packet.SetByteIndex(2);
  170. uint8_t eventID;
  171. if (!packet.ReadEventID(eventID)) { std::cout << "Error reading" << std::endl; return -1; }
  172. std::cout << static_cast<int>(eventID) << std::endl;
  173. uint8_t byteValue;
  174. if (!packet.ReadByte(byteValue)) { std::cout << "Error reading" << std::endl; return -1; }
  175. std::cout << static_cast<int>(byteValue) << std::endl;
  176. uint16_t ushortValue;
  177. if (!packet.ReadUInt16(ushortValue)) { std::cout << "Error reading" << std::endl; return -1; }
  178. std::cout << ushortValue << std::endl;
  179. std::string stringValue;
  180. if (!packet.ReadString(stringValue)) { std::cout << "Error reading" << std::endl; return -1; }
  181. std::cout << stringValue << std::endl;
  182.  
  183. /*
  184. To read from a TCP stream:
  185. // packet is a per end point object that persists through read callbacks
  186. for (int readByteIndex = 0; readByteIndex < receiveBufferSize; ++readByteIndex)
  187. {
  188. packet.WriteByte(receiveBuffer[readByteIndex]);
  189. if (!packet.HasHeader())
  190. {
  191. if (!packet.ReadHeader())
  192. {
  193. DisconnectEndPoint();
  194. }
  195. }
  196. if (!packet.HasData())
  197. {
  198. // Packets is a ConcurrentQueue
  199. endPoint.Packets.Enqueue(packet);
  200. packet = new Packet();
  201. }
  202. }
  203. */
  204.  
  205. return 0;
  206. }
Success #stdin #stdout 0s 2964KB
stdin
Standard input is empty
stdout
42
43
65535
Hello World