| /* |
| * Copyright 2012 The Emscripten Authors. All rights reserved. |
| * Emscripten is available under two separate licenses, the MIT license and the |
| * University of Illinois/NCSA Open Source License. Both these licenses can be |
| * found in the LICENSE file. |
| */ |
| |
| /** |
| @file packet.c |
| @brief ENet packet management functions |
| */ |
| #include <string.h> |
| #define ENET_BUILDING_LIB 1 |
| #include "enet/enet.h" |
| |
| /** @defgroup Packet ENet packet functions |
| @{ |
| */ |
| |
| /** Creates a packet that may be sent to a peer. |
| @param dataContents initial contents of the packet's data; the packet's data will remain uninitialized if dataContents is NULL. |
| @param dataLength size of the data allocated for this packet |
| @param flags flags for this packet as described for the ENetPacket structure. |
| @returns the packet on success, NULL on failure |
| */ |
| ENetPacket * |
| enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags) |
| { |
| ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket)); |
| if (packet == NULL) |
| return NULL; |
| |
| if (flags & ENET_PACKET_FLAG_NO_ALLOCATE) |
| packet -> data = (enet_uint8 *) data; |
| else |
| if (dataLength <= 0) |
| packet -> data = NULL; |
| else |
| { |
| packet -> data = (enet_uint8 *) enet_malloc (dataLength); |
| if (packet -> data == NULL) |
| { |
| enet_free (packet); |
| return NULL; |
| } |
| |
| if (data != NULL) |
| memcpy (packet -> data, data, dataLength); |
| } |
| |
| packet -> referenceCount = 0; |
| packet -> flags = flags; |
| packet -> dataLength = dataLength; |
| packet -> freeCallback = NULL; |
| |
| return packet; |
| } |
| |
| /** Destroys the packet and deallocates its data. |
| @param packet packet to be destroyed |
| */ |
| void |
| enet_packet_destroy (ENetPacket * packet) |
| { |
| if (packet -> freeCallback != NULL) |
| (* packet -> freeCallback) (packet); |
| if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE) && |
| packet -> data != NULL) |
| enet_free (packet -> data); |
| enet_free (packet); |
| } |
| |
| /** Attempts to resize the data in the packet to length specified in the |
| dataLength parameter |
| @param packet packet to resize |
| @param dataLength new size for the packet data |
| @returns 0 on success, < 0 on failure |
| */ |
| int |
| enet_packet_resize (ENetPacket * packet, size_t dataLength) |
| { |
| enet_uint8 * newData; |
| |
| if (dataLength <= packet -> dataLength || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE)) |
| { |
| packet -> dataLength = dataLength; |
| |
| return 0; |
| } |
| |
| newData = (enet_uint8 *) enet_malloc (dataLength); |
| if (newData == NULL) |
| return -1; |
| |
| memcpy (newData, packet -> data, packet -> dataLength); |
| enet_free (packet -> data); |
| |
| packet -> data = newData; |
| packet -> dataLength = dataLength; |
| |
| return 0; |
| } |
| |
| static int initializedCRC32 = 0; |
| static enet_uint32 crcTable [256]; |
| |
| static enet_uint32 |
| reflect_crc (int val, int bits) |
| { |
| int result = 0, bit; |
| |
| for (bit = 0; bit < bits; bit ++) |
| { |
| if(val & 1) result |= 1 << (bits - 1 - bit); |
| val >>= 1; |
| } |
| |
| return result; |
| } |
| |
| static void |
| initialize_crc32 () |
| { |
| int byte; |
| |
| for (byte = 0; byte < 256; ++ byte) |
| { |
| enet_uint32 crc = reflect_crc (byte, 8) << 24; |
| int offset; |
| |
| for(offset = 0; offset < 8; ++ offset) |
| { |
| if (crc & 0x80000000) |
| crc = (crc << 1) ^ 0x04c11db7; |
| else |
| crc <<= 1; |
| } |
| |
| crcTable [byte] = reflect_crc (crc, 32); |
| } |
| |
| initializedCRC32 = 1; |
| } |
| |
| enet_uint32 |
| enet_crc32 (const ENetBuffer * buffers, size_t bufferCount) |
| { |
| enet_uint32 crc = 0xFFFFFFFF; |
| |
| if (! initializedCRC32) initialize_crc32 (); |
| |
| while (bufferCount -- > 0) |
| { |
| const enet_uint8 * data = (const enet_uint8 *) buffers -> data, |
| * dataEnd = & data [buffers -> dataLength]; |
| |
| while (data < dataEnd) |
| { |
| crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++]; |
| } |
| |
| ++ buffers; |
| } |
| |
| return ENET_HOST_TO_NET_32 (~ crc); |
| } |
| |
| /** @} */ |