packet.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /**
  2. @file packet.c
  3. @brief ENet packet management functions
  4. */
  5. #include <string.h>
  6. #define ENET_BUILDING_LIB 1
  7. #include "enet/enet.h"
  8. /** @defgroup Packet ENet packet functions
  9. @{
  10. */
  11. /** Creates a packet that may be sent to a peer.
  12. @param dataContents initial contents of the packet's data; the packet's data will remain uninitialized if dataContents is NULL.
  13. @param dataLength size of the data allocated for this packet
  14. @param flags flags for this packet as described for the ENetPacket structure.
  15. @returns the packet on success, NULL on failure
  16. */
  17. ENetPacket *enet_packet_create(const void * data, size_t dataLength, enet_uint32 flags)
  18. {
  19. ENetPacket * packet = (ENetPacket *) enet_malloc(sizeof(ENetPacket));
  20. if (packet == NULL)
  21. return NULL;
  22. if (flags & ENET_PACKET_FLAG_NO_ALLOCATE)
  23. packet->data = (enet_uint8 *) data;
  24. else if (dataLength <= 0)
  25. packet->data = NULL;
  26. else
  27. {
  28. packet->data = (enet_uint8 *) enet_malloc(dataLength);
  29. if (packet->data == NULL)
  30. {
  31. enet_free(packet);
  32. return NULL;
  33. }
  34. if (data != NULL)
  35. memcpy(packet->data, data, dataLength);
  36. }
  37. packet->referenceCount = 0;
  38. packet->flags = flags;
  39. packet->dataLength = dataLength;
  40. packet->freeCallback = NULL;
  41. return packet;
  42. }
  43. /** Destroys the packet and deallocates its data.
  44. @param packet packet to be destroyed
  45. */
  46. void enet_packet_destroy(ENetPacket * packet)
  47. {
  48. if (packet->freeCallback != NULL)
  49. (*packet->freeCallback)(packet);
  50. if (!(packet->flags & ENET_PACKET_FLAG_NO_ALLOCATE) && packet->data != NULL)
  51. enet_free(packet->data);
  52. enet_free(packet);
  53. }
  54. /** Attempts to resize the data in the packet to length specified in the
  55. dataLength parameter
  56. @param packet packet to resize
  57. @param dataLength new size for the packet data
  58. @returns 0 on success, < 0 on failure
  59. */
  60. int enet_packet_resize(ENetPacket * packet, size_t dataLength)
  61. {
  62. enet_uint8 * newData;
  63. if (dataLength <= packet->dataLength || (packet->flags & ENET_PACKET_FLAG_NO_ALLOCATE))
  64. {
  65. packet->dataLength = dataLength;
  66. return 0;
  67. }
  68. newData = (enet_uint8 *) enet_malloc(dataLength);
  69. if (newData == NULL)
  70. return -1;
  71. memcpy(newData, packet->data, packet->dataLength);
  72. enet_free(packet->data);
  73. packet->data = newData;
  74. packet->dataLength = dataLength;
  75. return 0;
  76. }
  77. static int initializedCRC32 = 0;
  78. static enet_uint32 crcTable[256];
  79. static enet_uint32 reflect_crc(int val, int bits)
  80. {
  81. int result = 0, bit;
  82. for (bit = 0; bit < bits; bit++)
  83. {
  84. if (val & 1)
  85. result |= 1 << (bits - 1 - bit);
  86. val >>= 1;
  87. }
  88. return result;
  89. }
  90. static void initialize_crc32()
  91. {
  92. int byte;
  93. for (byte = 0; byte < 256; ++byte)
  94. {
  95. enet_uint32 crc = reflect_crc(byte, 8) << 24;
  96. int offset;
  97. for (offset = 0; offset < 8; ++offset)
  98. {
  99. if (crc & 0x80000000)
  100. crc = (crc << 1) ^ 0x04c11db7;
  101. else
  102. crc <<= 1;
  103. }
  104. crcTable[byte] = reflect_crc(crc, 32);
  105. }
  106. initializedCRC32 = 1;
  107. }
  108. enet_uint32 enet_crc32(const ENetBuffer * buffers, size_t bufferCount)
  109. {
  110. enet_uint32 crc = 0xFFFFFFFF;
  111. if (!initializedCRC32)
  112. initialize_crc32();
  113. while (bufferCount-- > 0)
  114. {
  115. const enet_uint8 * data = (const enet_uint8 *) buffers->data, *dataEnd =
  116. &data[buffers->dataLength];
  117. while (data < dataEnd)
  118. {
  119. crc = (crc >> 8) ^ crcTable[(crc & 0xFF) ^ *data++];
  120. }
  121. ++buffers;
  122. }
  123. return ENET_HOST_TO_NET_32 (~ crc);
  124. }
  125. /** @} */