packet.c.us.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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 data initial contents of the packet's data; the packet's data will remain uninitialized if data 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. ENetPacket *packet = (ENetPacket *) enet_malloc(sizeof(ENetPacket));
  19. if (packet == NULL) {
  20. return NULL;
  21. }
  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. packet->data = (enet_uint8 *) enet_malloc(dataLength);
  28. if (packet->data == NULL) {
  29. enet_free(packet);
  30. return NULL;
  31. }
  32. if (data != NULL) {
  33. memcpy(packet->data, data, dataLength);
  34. }
  35. }
  36. packet->referenceCount = 0;
  37. packet->flags = flags;
  38. packet->dataLength = dataLength;
  39. packet->freeCallback = NULL;
  40. packet->userData = NULL;
  41. return packet;
  42. }
  43. ENetPacket * enet_packet_create_offset(const void *data, size_t dataLength, size_t dataOffset, enet_uint32 flags) {
  44. ENetPacket *packet = (ENetPacket *) enet_malloc(sizeof(ENetPacket));
  45. if (packet == NULL) {
  46. return NULL;
  47. }
  48. if (flags & ENET_PACKET_FLAG_NO_ALLOCATE) {
  49. packet->data = (enet_uint8 *) data;
  50. } else if ((dataLength + dataOffset) <= 0) {
  51. packet->data = NULL;
  52. } else {
  53. packet->data = (enet_uint8 *) enet_malloc(dataLength + dataOffset);
  54. if (packet->data == NULL) {
  55. enet_free(packet);
  56. return NULL;
  57. }
  58. if (data != NULL) {
  59. memcpy(packet->data + dataOffset, data, dataLength);
  60. }
  61. }
  62. packet->referenceCount = 0;
  63. packet->flags = flags;
  64. packet->dataLength = dataLength + dataOffset;
  65. packet->freeCallback = NULL;
  66. packet->userData = NULL;
  67. return packet;
  68. }
  69. /** Destroys the packet and deallocates its data.
  70. * @param packet packet to be destroyed
  71. */
  72. void enet_packet_destroy(ENetPacket *packet) {
  73. if (packet == NULL) {
  74. return;
  75. }
  76. if (packet->freeCallback != NULL) {
  77. (*packet->freeCallback)(packet);
  78. }
  79. if (!(packet->flags & ENET_PACKET_FLAG_NO_ALLOCATE) &&
  80. packet->data != NULL)
  81. {
  82. enet_free(packet->data);
  83. }
  84. enet_free(packet);
  85. }
  86. /** Attempts to resize the data in the packet to length specified in the
  87. * dataLength parameter
  88. * @param packet packet to resize
  89. * @param dataLength new size for the packet data
  90. * @returns 0 on success, < 0 on failure
  91. */
  92. int enet_packet_resize(ENetPacket *packet, size_t dataLength) {
  93. enet_uint8 *newData;
  94. if (dataLength <= packet->dataLength || (packet->flags & ENET_PACKET_FLAG_NO_ALLOCATE)) {
  95. packet->dataLength = dataLength;
  96. return 0;
  97. }
  98. newData = (enet_uint8 *) enet_malloc(dataLength);
  99. if (newData == NULL) {
  100. return -1;
  101. }
  102. memcpy(newData, packet->data, packet->dataLength);
  103. enet_free(packet->data);
  104. packet->data = newData;
  105. packet->dataLength = dataLength;
  106. return 0;
  107. }
  108. static int initializedCRC32 = 0;
  109. static enet_uint32 crcTable [256];
  110. static enet_uint32 reflect_crc(int val, int bits) {
  111. int result = 0, bit;
  112. for (bit = 0; bit < bits; bit++) {
  113. if (val & 1) { result |= 1 << (bits - 1 - bit); }
  114. val >>= 1;
  115. }
  116. return result;
  117. }
  118. static void initialize_crc32(void) {
  119. int byte;
  120. for (byte = 0; byte < 256; ++byte) {
  121. enet_uint32 crc = reflect_crc(byte, 8) << 24;
  122. int offset;
  123. for (offset = 0; offset < 8; ++offset) {
  124. if (crc & 0x80000000) {
  125. crc = (crc << 1) ^ 0x04c11db7;
  126. } else {
  127. crc <<= 1;
  128. }
  129. }
  130. crcTable [byte] = reflect_crc(crc, 32);
  131. }
  132. initializedCRC32 = 1;
  133. }
  134. enet_uint32 enet_crc32(const ENetBuffer *buffers, size_t bufferCount) {
  135. enet_uint32 crc = 0xFFFFFFFF;
  136. if (!initializedCRC32) { initialize_crc32(); }
  137. while (bufferCount-- > 0) {
  138. const enet_uint8 *data = (const enet_uint8 *) buffers->data,
  139. *dataEnd = &data [buffers->dataLength];
  140. while (data < dataEnd) {
  141. crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++];
  142. }
  143. ++buffers;
  144. }
  145. return ENET_HOST_TO_NET_32(~crc);
  146. }
  147. /** @} */