FramingInterface_test.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include "interface/Interface.h"
  16. #include "interface/FramingInterface.h"
  17. #include "memory/Allocator.h"
  18. #include "memory/MallocAllocator.h"
  19. #include "util/platform/libc/strlen.h"
  20. #include "util/Endian.h"
  21. #include "util/Bits.h"
  22. #include "wire/Error.h"
  23. union MessageLength
  24. {
  25. uint32_t length_be;
  26. uint8_t bytes[4];
  27. };
  28. static uint8_t messageOut(struct Message* msg, struct Interface* iface)
  29. {
  30. struct Message** msgPtr = iface->receiverContext;
  31. Allocator_adopt((*msgPtr)->alloc, msg->alloc);
  32. *msgPtr = msg;
  33. return 0;
  34. }
  35. static void send(struct Interface* sendTo, struct Message* toSend, struct Allocator* cloneWith)
  36. {
  37. struct Allocator* child = Allocator_child(cloneWith);
  38. toSend = Message_clone(toSend, child);
  39. Interface_receiveMessage(sendTo, toSend);
  40. Allocator_free(child);
  41. }
  42. int main()
  43. {
  44. struct Allocator* alloc = MallocAllocator_new(1<<20);
  45. struct Interface dummy = { .sendMessage = NULL };
  46. struct Interface* fi = FramingInterface_new(1024, &dummy, alloc);
  47. fi->receiveMessage = messageOut;
  48. struct Message* output = NULL;
  49. fi->receiverContext = &output;
  50. char* text = "Hello World!";
  51. Assert_always(12 == strlen(text));
  52. union MessageLength ml = { .length_be = Endian_hostToBigEndian32(12) };
  53. struct Message* msg;
  54. {
  55. // first 2 bytes of length
  56. Message_STACK(msg, 0, 2);
  57. Message_push(msg, ml.bytes, 2, NULL);
  58. send(&dummy, msg, alloc);
  59. }
  60. {
  61. // last 2 bytes of length and first 5 bytes of message "Hello"
  62. Message_STACK(msg, 0, 7);
  63. Message_push(msg, text, 5, NULL);
  64. Message_push(msg, &ml.bytes[2], 2, NULL);
  65. send(&dummy, msg, alloc);
  66. }
  67. Assert_always(output == NULL);
  68. struct Allocator* child = Allocator_child(alloc);
  69. output = &(struct Message) { .alloc = child };
  70. {
  71. // last 7 bytes of message " World!" and first byte of length of second message.
  72. Message_STACK(msg, 0, 8);
  73. Message_push(msg, ml.bytes, 1, NULL);
  74. Message_push(msg, &text[5], 7, NULL);
  75. send(&dummy, msg, alloc);
  76. }
  77. Assert_always(output && output->length == (int)strlen(text));
  78. Assert_always(!Bits_memcmp(output->bytes, text, strlen(text)));
  79. Allocator_free(child);
  80. child = Allocator_child(alloc);
  81. output = &(struct Message) { .alloc = child };
  82. {
  83. // Send last 3 bytes of length and entire message.
  84. Message_STACK(msg, 0, 15);
  85. Message_push(msg, text, 12, NULL);
  86. Message_push(msg, &ml.bytes[1], 3, NULL);
  87. send(&dummy, msg, alloc);
  88. }
  89. Assert_always(output && output->length == (int)strlen(text));
  90. Assert_always(!Bits_memcmp(output->bytes, text, strlen(text)));
  91. Allocator_free(alloc);
  92. return 0;
  93. }