FramingIface_test.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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/Iface.h"
  16. #include "interface/FramingIface.h"
  17. #include "memory/Allocator.h"
  18. #include "memory/MallocAllocator.h"
  19. #include "util/Endian.h"
  20. #include "util/Bits.h"
  21. #include "util/CString.h"
  22. #include "wire/Error.h"
  23. union MessageLength
  24. {
  25. uint32_t length_be;
  26. uint8_t bytes[4];
  27. };
  28. struct Context
  29. {
  30. struct Iface iface;
  31. struct Message** receivedMsg;
  32. struct Allocator* childAlloc;
  33. struct Iface dummyIf;
  34. Identity
  35. };
  36. static Iface_DEFUN messageOut(struct Message* msg, struct Iface* iface)
  37. {
  38. struct Context* ctx = Identity_check((struct Context*) iface);
  39. Allocator_adopt(ctx->childAlloc, msg->alloc);
  40. ctx->receivedMsg[0] = msg;
  41. return NULL;
  42. }
  43. static void send(struct Iface* sendTo, struct Message* toSend, struct Allocator* cloneWith)
  44. {
  45. struct Allocator* child = Allocator_child(cloneWith);
  46. toSend = Message_clone(toSend, child);
  47. Iface_send(sendTo, toSend);
  48. Allocator_free(child);
  49. }
  50. int main()
  51. {
  52. struct Allocator* alloc = MallocAllocator_new(1<<20);
  53. struct Context* ctx = Allocator_calloc(alloc, sizeof(struct Context), 1);
  54. Identity_set(ctx);
  55. struct Iface* fi = FramingIface_new(1024, &ctx->dummyIf, alloc);
  56. ctx->iface.send = messageOut;
  57. Iface_plumb(&ctx->iface, fi);
  58. struct Message* output = NULL;
  59. ctx->receivedMsg = &output;
  60. char* text = "Hello World!";
  61. Assert_true(12 == CString_strlen(text));
  62. union MessageLength ml = { .length_be = Endian_hostToBigEndian32(12) };
  63. struct Message* msg;
  64. // first 2 bytes of length
  65. msg = Message_new(0, 2, alloc);
  66. Message_push(msg, ml.bytes, 2, NULL);
  67. send(&ctx->dummyIf, msg, alloc);
  68. // last 2 bytes of length and first 5 bytes of message "Hello"
  69. msg = Message_new(0, 7, alloc);
  70. Message_push(msg, text, 5, NULL);
  71. Message_push(msg, &ml.bytes[2], 2, NULL);
  72. send(&ctx->dummyIf, msg, alloc);
  73. Assert_true(output == NULL);
  74. ctx->childAlloc = Allocator_child(alloc);
  75. // last 7 bytes of message " World!" and first byte of length of second message.
  76. msg = Message_new(0, 8, alloc);
  77. Message_push(msg, ml.bytes, 1, NULL);
  78. Message_push(msg, &text[5], 7, NULL);
  79. send(&ctx->dummyIf, msg, alloc);
  80. Assert_true(output && output->length == (int)CString_strlen(text));
  81. Assert_true(!Bits_memcmp(output->bytes, text, CString_strlen(text)));
  82. Allocator_free(ctx->childAlloc);
  83. ctx->childAlloc = Allocator_child(alloc);
  84. // Send last 3 bytes of length and entire message.
  85. msg = Message_new(0, 15, alloc);
  86. Message_push(msg, text, 12, NULL);
  87. Message_push(msg, &ml.bytes[1], 3, NULL);
  88. send(&ctx->dummyIf, msg, alloc);
  89. Assert_true(output && output->length == (int)CString_strlen(text));
  90. Assert_true(!Bits_memcmp(output->bytes, text, CString_strlen(text)));
  91. Allocator_free(alloc);
  92. return 0;
  93. }