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
9/** @defgroup Packet ENet packet functions
10 @{
11*/
12
13/** Creates a packet that may be sent to a peer.
14 @param data initial contents of the packet's data; the packet's data will remain uninitialized if data is NULL.
15 @param dataLength size of the data allocated for this packet
16 @param flags flags for this packet as described for the ENetPacket structure.
17 @returns the packet on success, NULL on failure
18*/
19ENetPacket *
20enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
21{
22 ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket));
23 if (packet == NULL)
24 return NULL;
25
26 if (flags & ENET_PACKET_FLAG_NO_ALLOCATE)
27 packet -> data = (enet_uint8 *) data;
28 else
29 if (dataLength <= 0)
30 packet -> data = NULL;
31 else
32 {
33 packet -> data = (enet_uint8 *) enet_malloc (dataLength);
34 if (packet -> data == NULL)
35 {
36 enet_free (packet);
37 return NULL;
38 }
39
40 if (data != NULL)
41 memcpy (packet -> data, data, dataLength);
42 }
43
44 packet -> referenceCount = 0;
45 packet -> flags = flags;
46 packet -> dataLength = dataLength;
47 packet -> freeCallback = NULL;
48 packet -> userData = NULL;
49
50 return packet;
51}
52
53/** Destroys the packet and deallocates its data.
54 @param packet packet to be destroyed
55*/
56void
57enet_packet_destroy (ENetPacket * packet)
58{
59 if (packet == NULL)
60 return;
61
62 if (packet -> freeCallback != NULL)
63 (* packet -> freeCallback) (packet);
64 if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE) &&
65 packet -> data != NULL)
66 enet_free (packet -> data);
67 enet_free (packet);
68}
69
70/** Attempts to resize the data in the packet to length specified in the
71 dataLength parameter
72 @param packet packet to resize
73 @param dataLength new size for the packet data
74 @returns 0 on success, < 0 on failure
75*/
76int
77enet_packet_resize (ENetPacket * packet, size_t dataLength)
78{
79 enet_uint8 * newData;
80
81 if (dataLength <= packet -> dataLength || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
82 {
83 packet -> dataLength = dataLength;
84
85 return 0;
86 }
87
88 newData = (enet_uint8 *) enet_malloc (dataLength);
89 if (newData == NULL)
90 return -1;
91
92 memcpy (newData, packet -> data, packet -> dataLength);
93 enet_free (packet -> data);
94
95 packet -> data = newData;
96 packet -> dataLength = dataLength;
97
98 return 0;
99}
100
101static const enet_uint32 crcTable [256] =
102{
103 0, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
104 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
105 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
106 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
107 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
108 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
109 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
110 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
111 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
112 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
113 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
114 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
115 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
116 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
117 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
118 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
119 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
120 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
121 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
122 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
123 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
124 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
125 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
126 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
127 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x5005713,
128 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0xBDBDF21,
129 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
130 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
131 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
132 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
133 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
134 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
135};
136
137enet_uint32
138enet_crc32 (const ENetBuffer * buffers, size_t bufferCount)
139{
140 enet_uint32 crc = 0xFFFFFFFF;
141
142 while (bufferCount -- > 0)
143 {
144 const enet_uint8 * data = (const enet_uint8 *) buffers -> data,
145 * dataEnd = & data [buffers -> dataLength];
146
147 while (data < dataEnd)
148 {
149 crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++];
150 }
151
152 ++ buffers;
153 }
154
155 return ENET_HOST_TO_NET_32 (~ crc);
156}
157
158/** @} */
159