summaryrefslogtreecommitdiff
path: root/src/enet/packet.c
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2011-01-02 01:48:38 +0200
committerAndrei Karas <akaras@inbox.ru>2011-01-02 02:41:24 +0200
commit3eeae12c498d1a4dbe969462d2ba841f77ee3ccb (patch)
treeff8eab35e732bc0749fc11677c8873a7b3a58704 /src/enet/packet.c
downloadmv-3eeae12c498d1a4dbe969462d2ba841f77ee3ccb.tar.gz
mv-3eeae12c498d1a4dbe969462d2ba841f77ee3ccb.tar.bz2
mv-3eeae12c498d1a4dbe969462d2ba841f77ee3ccb.tar.xz
mv-3eeae12c498d1a4dbe969462d2ba841f77ee3ccb.zip
Initial commit.
This code based on mana client http://www.gitorious.org/mana/mana and my private repository.
Diffstat (limited to 'src/enet/packet.c')
-rw-r--r--src/enet/packet.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/src/enet/packet.c b/src/enet/packet.c
new file mode 100644
index 000000000..d6730dd33
--- /dev/null
+++ b/src/enet/packet.c
@@ -0,0 +1,159 @@
+/**
+ @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
+ {
+ 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))
+ 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);
+}
+
+/** @} */