fork download
  1. #include <cinttypes>
  2. #include <iostream>
  3. #include <vector>
  4. #include <stdexcept>
  5. #include <cstring>
  6.  
  7. using namespace std;
  8.  
  9. struct IReceiver {
  10. virtual void Receive(const char* data, unsigned int size) = 0;
  11. virtual ~IReceiver() {};
  12. };
  13.  
  14. struct ICallback {
  15. virtual void BinaryPacket(const char* data, unsigned int size) = 0;
  16. virtual void TextPacket(const char* data, unsigned int size) = 0;
  17. virtual ~ICallback() {}
  18. };
  19.  
  20. class CallbackImpl : public ICallback {
  21. public:
  22. CallbackImpl(std::ostream& out)
  23. : m_out(out)
  24. , m_packetsReceived(0) {}
  25.  
  26. void BinaryPacket(const char* data, unsigned int size) override {
  27. m_out << "Binary packet received (" << size << " bytes)" << std::endl;
  28. ++m_packetsReceived;
  29. }
  30. void TextPacket(const char* data, unsigned int size) override {
  31. m_out << "Text packet received (" << size << " characters)" << std::endl;
  32. ++m_packetsReceived;
  33. }
  34. uint32_t packetsReceived() const {return m_packetsReceived;}
  35.  
  36. private:
  37. std::ostream& m_out;
  38. uint32_t m_packetsReceived;
  39. };
  40.  
  41. class ReceiverImpl : public IReceiver {
  42. private:
  43. enum PacketType { None, Binary, Text };
  44.  
  45. public:
  46. ReceiverImpl(ICallback* callback)
  47. : m_callback(callback)
  48. , m_currentPacketType(None)
  49. , m_binaryDataSize(-1)
  50. , m_checkBeginIndex(-1) {
  51.  
  52. m_inputBuffer.reserve(4096);
  53. }
  54.  
  55. void Receive(const char* data, unsigned int size) override {
  56. if (!data || size == 0) {
  57. return;
  58. }
  59. m_inputBuffer.insert(m_inputBuffer.end(), data, data + size);
  60. while (processData());
  61. }
  62.  
  63. private:
  64. int processData() {
  65. switch (m_currentPacketType) {
  66. case None: {
  67. if (m_inputBuffer.size() == 0) {
  68. return 0;
  69. }
  70. if (m_inputBuffer[0] == 0x24) {
  71. m_currentPacketType = Binary;
  72. m_binaryDataSize = -1;
  73. } else {
  74. m_currentPacketType = Text;
  75. m_checkBeginIndex = 0;
  76. }
  77. return 1;
  78. }
  79. case Binary: {
  80. constexpr uint32_t SizeBytesCount = (uint32_t) sizeof(uint32_t);
  81. uint32_t size = (uint32_t) m_inputBuffer.size();
  82. if (m_binaryDataSize == (uint32_t) -1) {
  83. if (size < SizeBytesCount + 1) {
  84. return 0;
  85. }
  86. memcpy(&m_binaryDataSize, &m_inputBuffer[1], SizeBytesCount);
  87. }
  88. if (size > m_binaryDataSize + SizeBytesCount) {
  89. m_callback->BinaryPacket(&m_inputBuffer[SizeBytesCount + 1], m_binaryDataSize);
  90. finishPacket(m_binaryDataSize + SizeBytesCount + 1);
  91. return 1;
  92. }
  93. return 0;
  94. }
  95. case Text: {
  96. const uint32_t eolIndex = findEol();
  97. if (eolIndex == (uint32_t) -1) {
  98. return 0;
  99. }
  100. m_callback->TextPacket(&m_inputBuffer[0], eolIndex);
  101. finishPacket(eolIndex + 4);
  102. return 1;
  103. }
  104. default: {
  105. break;
  106. }
  107. }
  108. throw std::runtime_error("What are you doing here?");
  109. }
  110. uint32_t findEol() {
  111. if (m_inputBuffer.size() < 4) {
  112. return (uint32_t) -1;
  113. }
  114.  
  115. const char* const begin = m_inputBuffer.data();
  116. const char* const end = begin + m_inputBuffer.size() - 3;
  117. const char* it = begin + m_checkBeginIndex;
  118. while (it != end) {
  119. const char* const eolPtr = (const char*) memchr(it, '\r', end - it);
  120. if (!eolPtr) {
  121. break;
  122. }
  123. if (eolPtr[1] == '\n' && eolPtr[2] == '\r' && eolPtr[3] == '\n') {
  124. return (uint32_t) (eolPtr - begin);
  125. }
  126. it = eolPtr + 1;
  127. }
  128. m_checkBeginIndex = (uint32_t) (end - begin);
  129. return (uint32_t) -1;
  130. }
  131. void finishPacket(uint32_t packetSize) {
  132. m_inputBuffer.assign(m_inputBuffer.begin() + packetSize, m_inputBuffer.end());
  133. m_currentPacketType = None;
  134. }
  135.  
  136. private:
  137. ICallback* m_callback;
  138. std::vector<char> m_inputBuffer;
  139. PacketType m_currentPacketType;
  140. uint32_t m_binaryDataSize;
  141. uint32_t m_checkBeginIndex;
  142. };
  143.  
  144. class DataProvider {
  145. public:
  146. DataProvider() : m_currentPos(0) {}
  147. void prepareData(uint32_t packetsCount) {
  148. srand(298);
  149. m_data.clear();
  150. for (; packetsCount; --packetsCount) {
  151. const uint32_t packetSize = 128 + rand() % 16000;
  152. std::vector<char> data;
  153. if (rand() & 0x01) {
  154. data = generateBinaryPacket(packetSize);
  155. } else {
  156. data = generateTextPacket(packetSize);
  157. }
  158. m_data.insert(m_data.end(), data.begin(), data.end());
  159. }
  160. }
  161. void sendData(IReceiver* receiver) {
  162. m_currentPos = 0;
  163. const uint32_t size = (uint32_t) m_data.size();
  164. while (m_currentPos < size) {
  165. uint32_t sendSize = 500 + rand() % 2000;
  166. if (m_currentPos + sendSize > size) {
  167. sendSize = size - m_currentPos;
  168. }
  169. receiver->Receive(&m_data[m_currentPos], sendSize);
  170. m_currentPos += sendSize;
  171. }
  172. }
  173.  
  174. private:
  175. static std::vector<char> generateBinaryPacket(uint32_t size) {
  176. constexpr uint32_t SizeBytesCount = sizeof(uint32_t);
  177. std::vector<char> data(size + SizeBytesCount + 1, 0);
  178. data[0] = 0x24;
  179. memcpy(&data[1], &size, SizeBytesCount);
  180. for (uint32_t i = SizeBytesCount + 1, n = (uint32_t) data.size(); i < n; ++i) {
  181. data[i] = (char) rand();
  182. }
  183. return data;
  184. }
  185. static std::vector<char> generateTextPacket(uint32_t size) {
  186. std::vector<char> data(size + 4, ' ');
  187. for (uint32_t i = 0; i < size; ++i) {
  188. do {
  189. data[i] = (char) (32 + rand() % 95);
  190. } while (data[i] == 0x24);
  191. }
  192. memcpy(&data[size], "\r\n\r\n", 4);
  193. return data;
  194. }
  195. private:
  196. std::vector<char> m_data;
  197. uint32_t m_currentPos;
  198. };
  199.  
  200.  
  201. int main() {
  202. CallbackImpl* callback = nullptr;
  203. ReceiverImpl* receiver = nullptr;
  204. try {
  205. callback = new CallbackImpl(std::cout);
  206. receiver = new ReceiverImpl(callback);
  207.  
  208. constexpr uint32_t TestPacketsCount = 256;
  209. DataProvider dataProvider;
  210.  
  211. std::cout << "Prepearing data..." << std::endl;
  212. dataProvider.prepareData(TestPacketsCount);
  213. std::cout << "OK." << std::endl;
  214.  
  215. std::cout << "Sending data..." << std::endl;
  216. dataProvider.sendData(receiver);
  217. std::cout << "OK." << std::endl;
  218.  
  219. std::cout << "Packets received " << callback->packetsReceived() << " of " << TestPacketsCount << std::endl;
  220.  
  221. } catch (std::exception& exc) {
  222. std::cerr << "Exception caught: " << exc.what() << std::endl;
  223. }
  224. delete callback;
  225. delete receiver;
  226.  
  227. return 0;
  228. }
Success #stdin #stdout 0.04s 6252KB
stdin
Standard input is empty
stdout
Prepearing data...
OK.
Sending data...
Binary packet received (6606 bytes)
Binary packet received (10558 bytes)
Text packet received (11732 characters)
Binary packet received (13012 bytes)
Binary packet received (12483 bytes)
Binary packet received (10184 bytes)
Binary packet received (15572 bytes)
Binary packet received (5085 bytes)
Text packet received (13989 characters)
Binary packet received (9294 bytes)
Text packet received (7116 characters)
Binary packet received (4359 bytes)
Text packet received (14398 characters)
Binary packet received (14482 bytes)
Binary packet received (11111 bytes)
Binary packet received (5647 bytes)
Text packet received (9726 characters)
Text packet received (8675 characters)
Text packet received (2309 characters)
Binary packet received (15928 bytes)
Text packet received (13630 characters)
Text packet received (927 characters)
Text packet received (8469 characters)
Text packet received (1603 characters)
Text packet received (12011 characters)
Text packet received (2543 characters)
Binary packet received (10516 bytes)
Binary packet received (1730 bytes)
Text packet received (2717 characters)
Text packet received (13451 characters)
Binary packet received (11269 bytes)
Text packet received (6315 characters)
Text packet received (10798 characters)
Text packet received (14634 characters)
Text packet received (14086 characters)
Binary packet received (1585 bytes)
Binary packet received (398 bytes)
Binary packet received (4532 bytes)
Text packet received (8941 characters)
Binary packet received (5701 bytes)
Text packet received (13830 characters)
Binary packet received (13934 bytes)
Binary packet received (2243 bytes)
Binary packet received (4001 bytes)
Binary packet received (10828 bytes)
Binary packet received (4718 bytes)
Binary packet received (7979 bytes)
Binary packet received (2327 bytes)
Binary packet received (12933 bytes)
Binary packet received (14548 bytes)
Text packet received (11400 characters)
Binary packet received (5389 bytes)
Binary packet received (13695 bytes)
Binary packet received (1868 bytes)
Binary packet received (1771 bytes)
Binary packet received (15949 bytes)
Binary packet received (8871 bytes)
Binary packet received (3600 bytes)
Text packet received (3885 characters)
Binary packet received (15717 bytes)
Binary packet received (3543 bytes)
Binary packet received (1602 bytes)
Binary packet received (4505 bytes)
Binary packet received (5600 bytes)
Text packet received (5715 characters)
Text packet received (3092 characters)
Binary packet received (14290 bytes)
Binary packet received (4959 bytes)
Binary packet received (4058 bytes)
Text packet received (9651 characters)
Binary packet received (14850 bytes)
Text packet received (15741 characters)
Binary packet received (2715 bytes)
Text packet received (8201 characters)
Text packet received (7008 characters)
Text packet received (6088 characters)
Binary packet received (3395 bytes)
Binary packet received (14421 bytes)
Text packet received (9342 characters)
Binary packet received (2928 bytes)
Text packet received (12296 characters)
Binary packet received (6288 bytes)
Text packet received (2409 characters)
Text packet received (11474 characters)
Text packet received (13255 characters)
Text packet received (4709 characters)
Binary packet received (2905 bytes)
Text packet received (7868 characters)
Binary packet received (7603 bytes)
Text packet received (5407 characters)
Binary packet received (10062 bytes)
Text packet received (4591 characters)
Binary packet received (8888 bytes)
Text packet received (10399 characters)
Text packet received (12184 characters)
Binary packet received (8985 bytes)
Text packet received (4596 characters)
Text packet received (13402 characters)
Text packet received (11545 characters)
Binary packet received (9979 bytes)
Text packet received (2002 characters)
Binary packet received (5589 bytes)
Text packet received (13718 characters)
Text packet received (10645 characters)
Binary packet received (5075 bytes)
Text packet received (15352 characters)
Text packet received (7245 characters)
Binary packet received (13342 bytes)
Binary packet received (10834 bytes)
Text packet received (4356 characters)
Binary packet received (8981 bytes)
Text packet received (871 characters)
Binary packet received (6091 bytes)
Binary packet received (6329 bytes)
Binary packet received (2069 bytes)
Binary packet received (4549 bytes)
Binary packet received (12222 bytes)
Text packet received (3950 characters)
Binary packet received (12997 bytes)
Text packet received (4817 characters)
Binary packet received (6286 bytes)
Binary packet received (1862 bytes)
Text packet received (6113 characters)
Binary packet received (1720 bytes)
Text packet received (3037 characters)
Text packet received (3236 characters)
Text packet received (4023 characters)
Binary packet received (3688 bytes)
Text packet received (1453 characters)
Binary packet received (5013 bytes)
Text packet received (4019 characters)
Text packet received (439 characters)
Binary packet received (11467 bytes)
Binary packet received (389 bytes)
Text packet received (13342 characters)
Binary packet received (9948 bytes)
Text packet received (8092 characters)
Text packet received (5740 characters)
Text packet received (1549 characters)
Binary packet received (6924 bytes)
Text packet received (10504 characters)
Binary packet received (7461 bytes)
Text packet received (11704 characters)
Text packet received (10682 characters)
Text packet received (5389 characters)
Binary packet received (10016 bytes)
Text packet received (6701 characters)
Binary packet received (11857 bytes)
Text packet received (8485 characters)
Binary packet received (14750 bytes)
Text packet received (6788 characters)
Text packet received (1946 characters)
Text packet received (5568 characters)
Binary packet received (9981 bytes)
Text packet received (11934 characters)
Text packet received (2023 characters)
Binary packet received (15543 bytes)
Text packet received (3337 characters)
Text packet received (13967 characters)
Text packet received (13959 characters)
Text packet received (7927 characters)
Binary packet received (3171 bytes)
Text packet received (8647 characters)
Text packet received (12563 characters)
Binary packet received (5328 bytes)
Text packet received (15719 characters)
Text packet received (5448 characters)
Binary packet received (13935 bytes)
Binary packet received (4506 bytes)
Binary packet received (4347 bytes)
Text packet received (14547 characters)
Binary packet received (7406 bytes)
Binary packet received (4706 bytes)
Binary packet received (10428 bytes)
Binary packet received (9067 bytes)
Binary packet received (9022 bytes)
Binary packet received (9606 bytes)
Binary packet received (15369 bytes)
Text packet received (5162 characters)
Binary packet received (15771 bytes)
Text packet received (791 characters)
Text packet received (4112 characters)
Text packet received (13175 characters)
Text packet received (4676 characters)
Text packet received (15487 characters)
Binary packet received (15246 bytes)
Binary packet received (14875 bytes)
Binary packet received (5788 bytes)
Text packet received (15550 characters)
Binary packet received (14803 bytes)
Text packet received (6023 characters)
Text packet received (168 characters)
Text packet received (1461 characters)
Binary packet received (1028 bytes)
Text packet received (9638 characters)
Binary packet received (9125 bytes)
Text packet received (6644 characters)
Binary packet received (2835 bytes)
Text packet received (13160 characters)
Binary packet received (13569 bytes)
Text packet received (12676 characters)
Binary packet received (15610 bytes)
Text packet received (9193 characters)
Text packet received (1980 characters)
Binary packet received (11060 bytes)
Text packet received (3785 characters)
Text packet received (5623 characters)
Text packet received (6135 characters)
Text packet received (8670 characters)
Binary packet received (9537 bytes)
Binary packet received (4367 bytes)
Binary packet received (13712 bytes)
Text packet received (13043 characters)
Text packet received (14545 characters)
Text packet received (1636 characters)
Text packet received (4820 characters)
Binary packet received (825 bytes)
Text packet received (5679 characters)
Binary packet received (5588 bytes)
Binary packet received (198 bytes)
Binary packet received (3805 bytes)
Text packet received (5106 characters)
Text packet received (3002 characters)
Binary packet received (8086 bytes)
Text packet received (12019 characters)
Binary packet received (11447 bytes)
Binary packet received (7591 bytes)
Binary packet received (12678 bytes)
Text packet received (16034 characters)
Binary packet received (7099 bytes)
Binary packet received (9379 bytes)
Binary packet received (3015 bytes)
Text packet received (4127 characters)
Binary packet received (7103 bytes)
Text packet received (10121 characters)
Text packet received (3644 characters)
Binary packet received (13754 bytes)
Text packet received (7028 characters)
Binary packet received (4011 bytes)
Text packet received (1960 characters)
Text packet received (11328 characters)
Binary packet received (12271 bytes)
Text packet received (15398 characters)
Binary packet received (266 bytes)
Binary packet received (15279 bytes)
Binary packet received (12666 bytes)
Text packet received (2710 characters)
Binary packet received (15202 bytes)
Text packet received (2410 characters)
Binary packet received (9584 bytes)
Text packet received (5740 characters)
Binary packet received (6919 bytes)
Binary packet received (14357 bytes)
Text packet received (15212 characters)
Binary packet received (8459 bytes)
Binary packet received (6109 bytes)
OK.
Packets received 256 of 256