mirror of
				https://github.com/godotengine/godot.git
				synced 2025-11-04 07:31:16 +00:00 
			
		
		
		
	
		
			
	
	
		
			166 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			166 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/** 
							 | 
						||
| 
								 | 
							
								 @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 data         initial contents of the packet's data; the packet's data will remain uninitialized if data 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;
							 | 
						||
| 
								 | 
							
								    packet -> userData = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return packet;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/** Destroys the packet and deallocates its data.
							 | 
						||
| 
								 | 
							
								    @param packet packet to be destroyed
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								void
							 | 
						||
| 
								 | 
							
								enet_packet_destroy (ENetPacket * packet)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (packet == NULL)
							 | 
						||
| 
								 | 
							
								      return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    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 (void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    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);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/** @} */
							 |