a4a418a679
git-svn-id: http://mc-server.googlecode.com/svn/trunk@504 0a769ca7-a7f5-676a-18bf-c427514a06d6
308 lines
5.4 KiB
C++
308 lines
5.4 KiB
C++
|
|
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
|
|
|
#include "cPacket.h"
|
|
#include "../Endianness.h"
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
// These checks cannot be done in preprocessor, since sizeof() is evaluated while compiling, so in preprocessing it's unknown.
|
|
// Check some basic type assumptions:
|
|
#if (sizeof(int) != 4)
|
|
#error "Bad size for int, protocol won't work"
|
|
#endif
|
|
|
|
#if (sizeof(float) != 4)
|
|
#error "Bad size for float, protocol won't work"
|
|
#endif
|
|
|
|
#if (sizeof(double) != 8)
|
|
#error "Bad size for double, protocol won't work"
|
|
#endif
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
int cPacket::ReadString16(const char * a_Data, int a_Size, AString & a_OutString )
|
|
{
|
|
int TotalBytes = 0;
|
|
short StrLen;
|
|
HANDLE_PACKET_READ(ReadShort, StrLen, TotalBytes);
|
|
|
|
if (2 * StrLen > a_Size - TotalBytes)
|
|
{
|
|
// The string is not yet complete in the buffer
|
|
return PACKET_INCOMPLETE;
|
|
}
|
|
|
|
// Simple UTF-16 to UTF-8 conversion - discard higher bits, ignore multishort sequences:
|
|
a_OutString.clear();
|
|
a_OutString.reserve(StrLen);
|
|
short * UTF16 = (short *)(a_Data + TotalBytes);
|
|
for ( int i = 0; i < StrLen; ++i )
|
|
{
|
|
a_OutString.push_back( (char)ntohs(UTF16[i]) );
|
|
}
|
|
|
|
return TotalBytes + StrLen * sizeof(short);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int cPacket::ReadShort(const char * a_Data, int a_Size, short & a_OutShort )
|
|
{
|
|
if (a_Size < 2)
|
|
{
|
|
return PACKET_INCOMPLETE;
|
|
}
|
|
a_OutShort = ntohs(*((short *)a_Data));
|
|
return 2;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int cPacket::ReadInteger(const char * a_Data, int a_Size, int & a_OutInteger )
|
|
{
|
|
if (a_Size < 4)
|
|
{
|
|
return PACKET_INCOMPLETE;
|
|
}
|
|
a_OutInteger = ntohl(*((int *)a_Data));
|
|
return 4;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int cPacket::ReadInteger(const char * a_Data, int a_Size, unsigned int & a_OutInteger )
|
|
{
|
|
if (a_Size < 4)
|
|
{
|
|
return PACKET_INCOMPLETE;
|
|
}
|
|
a_OutInteger = ntohl(*((unsigned int *)a_Data));
|
|
return 4;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int cPacket::ReadFloat(const char * a_Data, int a_Size, float & a_OutFloat )
|
|
{
|
|
if (a_Size < sizeof(float))
|
|
{
|
|
return PACKET_INCOMPLETE;
|
|
}
|
|
a_OutFloat = NetworkToHostFloat4(a_Data);
|
|
return sizeof(float);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int cPacket::ReadDouble(const char * a_Data, int a_Size, double & a_OutDouble )
|
|
{
|
|
if (a_Size < sizeof(double))
|
|
{
|
|
return PACKET_INCOMPLETE;
|
|
}
|
|
a_OutDouble = NetworkToHostDouble8(a_Data);
|
|
return sizeof(double);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int cPacket::ReadByte(const char * a_Data, int a_Size, char & a_OutByte )
|
|
{
|
|
if (a_Size < 1)
|
|
{
|
|
return PACKET_INCOMPLETE;
|
|
}
|
|
a_OutByte = *a_Data;
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int cPacket::ReadByte(const char * a_Data, int a_Size, unsigned char & a_OutByte )
|
|
{
|
|
if (a_Size < 1)
|
|
{
|
|
return PACKET_INCOMPLETE;
|
|
}
|
|
a_OutByte = *((unsigned char *)a_Data);
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int cPacket::ReadLong(const char * a_Data, int a_Size, long long & a_OutLong )
|
|
{
|
|
if (a_Size < sizeof(a_OutLong))
|
|
{
|
|
return PACKET_INCOMPLETE;
|
|
}
|
|
a_OutLong = NetworkToHostLong8(a_Data);
|
|
return sizeof(a_OutLong);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int cPacket::ReadBool(const char * a_Data, int a_Size, bool & a_OutBool )
|
|
{
|
|
if (a_Size < sizeof(bool))
|
|
{
|
|
return PACKET_INCOMPLETE;
|
|
}
|
|
a_OutBool = (*a_Data != 0);
|
|
return sizeof(bool);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cPacket::AppendString(AString & a_Dst, const AString & a_String)
|
|
{
|
|
AppendShort(a_Dst, (unsigned short)a_String.size());
|
|
a_Dst.append(a_String);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cPacket::AppendString16(AString & a_Dst, const AString & a_String)
|
|
{
|
|
AppendShort(a_Dst, (unsigned short)a_String.size());
|
|
AString UTF16;
|
|
UTF16.resize(a_String.size() * sizeof(short));
|
|
for( unsigned int i = 0; i < a_String.size(); ++i )
|
|
{
|
|
UTF16[i * sizeof( short )] = 0x00;
|
|
UTF16[i * sizeof( short ) + 1] = a_String[i];
|
|
}
|
|
a_Dst.append(UTF16.data(), a_String.size() * sizeof(short));
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cPacket::AppendShort(AString & a_Dst, short a_Short)
|
|
{
|
|
short ConvertedShort = htons( a_Short );
|
|
a_Dst.append((const char *)&ConvertedShort, sizeof(short));
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cPacket::AppendShort(AString & a_Dst, unsigned short a_Short)
|
|
{
|
|
short ConvertedShort = htons( a_Short );
|
|
a_Dst.append((const char *)&ConvertedShort, sizeof(short));
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cPacket::AppendInteger(AString & a_Dst, int a_Integer)
|
|
{
|
|
int ConvertedInt = htonl( a_Integer );
|
|
a_Dst.append((const char *)&ConvertedInt, sizeof(int));
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cPacket::AppendInteger(AString & a_Dst, unsigned int a_Integer)
|
|
{
|
|
unsigned int ConvertedInt = htonl( a_Integer );
|
|
a_Dst.append((const char *)&ConvertedInt, sizeof(int));
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cPacket::AppendFloat(AString & a_Dst, float a_Float)
|
|
{
|
|
unsigned int ConvertedFloat = HostToNetwork4(&a_Float);
|
|
a_Dst.append((const char *)&ConvertedFloat, sizeof(int));
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cPacket::AppendDouble(AString & a_Dst, const double & a_Double)
|
|
{
|
|
unsigned long long ConvertedDouble = HostToNetwork8(&a_Double);
|
|
a_Dst.append((const char *)&ConvertedDouble, 8);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cPacket::AppendByte(AString & a_Dst, char a_Byte)
|
|
{
|
|
a_Dst.append(&a_Byte, 1);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cPacket::AppendLong(AString & a_Dst, const long long & a_Long)
|
|
{
|
|
unsigned long long ConvertedLong = HostToNetwork8(&a_Long);
|
|
a_Dst.append((const char *)&ConvertedLong, sizeof(a_Long));
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cPacket::AppendBool(AString & a_Dst, bool a_Bool)
|
|
{
|
|
a_Dst.append((const char *)&a_Bool, 1);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cPacket::AppendData(AString & a_Dst, const char * a_Data, unsigned int a_Size)
|
|
{
|
|
a_Dst.append(a_Data, a_Size);
|
|
}
|
|
|
|
|
|
|
|
|