SFML/DSFML/import/dsfml/network/packet.d

418 lines
12 KiB
D
Raw Normal View History

/*
* DSFML - SFML Library wrapper for the D programming language.
* Copyright (C) 2008 Julien Dagorn (sirjulio13@gmail.com)
* Copyright (C) 2010 Andreas Hollandt
*
* This software is provided 'as-is', without any express or
* implied warranty. In no event will the authors be held
* liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute
* it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented;
* you must not claim that you wrote the original software.
* If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but
* is not required.
*
* 2. Altered source versions must be plainly marked as such,
* and must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any
* source distribution.
*/
module dsfml.network.packet;
import dsfml.system.common;
import dsfml.system.stringutil;
/**
* Packet wraps data to send / to receive through the network
*
* The order of insertion and extraction must be the same.
*
* You can derive from Packet and override onSend and onReceive to do custom operations before send or after reception.
*
* Litterals integer are promoted to int.
* Litterals floating point are promoted to float.
*
* Extraction or insertion can be specified with explicit template.
* Examples:
* ------------------------------------------------------------
* Packet p = new Packet();
*
* int i = 32, j = 42;
* string k = hello;
*
* p.set(i, k, j); //Set the data in the packet
*
* int a, b;
* string c;
* p.get(a, c, b); //Get data from the packet
*
* //...
*
* Packet p = new Packet();
* p.set!(byte)(5); // Litteral are inserted with byte type
* ------------------------------------------------------------
*
* See_Also:
* $(LINK2 http://www.digitalmars.com/d/1.0/lex.html, D litterals Specification) for more informations.
*/
class Packet : DSFMLObject
{
/**
* Default constructor
*
*/
this()
{
super(sfPacket_Create());
}
override void dispose()
{
sfPacket_Destroy(m_ptr);
}
/**
* Append data to the end of the packet.
*
* Params:
* data = Array of data to append
*
*/
void append(byte[] data)
{
if (data !is null)
sfPacket_Append(m_ptr, data.ptr, data.length);
}
/**
* Clear the packet data
*
*/
void clear()
{
sfPacket_Clear(m_ptr);
}
/**
* Get an array to the data contained in the packet
* $(B the returned array may be invalid after you
* append data to the packet)
*
* Returns:
* array of data
*
* Remarks:
* return an array of $(B all) data in the packet.
*
* ----------
* Packet p = new Packet();
*
* string str1 = "Hi";
* string str2 = "Hello";
*
* p.set(str1, str2);
*
* // Retrieve str1 from packet
* string str3;
* p.get(str3);
*
* // Returns an array containing str1 and str2.
* byte[] ptr = p.getData();
* ----------
*/
byte[] getData()
{
if (canRead)
return sfPacket_GetData(m_ptr)[0..getDataSize()];
else
return null;
}
/**
* Get the size of the data contained in the packet
*
* Returns:
* Data size, in bytes
*/
uint getDataSize()
{
return sfPacket_GetDataSize(m_ptr);
}
/**
* Tell if the reading position has reached the end of the packet
*
* Returns:
* true if all data have been read.
*/
bool endOfPacket()
{
return cast(bool)sfPacket_EndOfPacket(m_ptr);
}
/**
* Tell if the packet is valid for reading
*
* Returns:
* True if data can be extracted from the packet
*
*/
bool canRead()
{
return cast(bool)sfPacket_CanRead(m_ptr);
}
/**
* Add new variables to the packet
* Accept (u)byte, (u)short, (u)int, float, double, string and wstring types
*/
Packet set(T...)(T t)
{
foreach (v; t)
internalSet(t);
return this;
}
/**
* Retrieve data from the packet
* Accept (u)byte, (u)short, (u)int, float, double, string and wstring types
*/
Packet get(T...)(ref T t)
{
foreach (v; t)
internalGet(t);
return this;
}
/**
* Called before packet is send
*
* Params:
* size = Variable to fill with the size of the data to send
* Returns:
* Array of byte to send
*/
byte[] onSend()
{
return getData();
}
/**
* Called after a packet has been received
*
* Params:
* data = Array of byte received
*/
void onReceive(byte[] data)
{
append(data);
}
private:
void internalGet(ref bool data)
{
data = cast(bool)sfPacket_ReadInt32(m_ptr);
}
void internalGet(ref byte data)
{
data = sfPacket_ReadInt8(m_ptr);
}
void internalGet(ref ubyte data)
{
data = sfPacket_ReadUint8(m_ptr);
}
void internalGet(ref short data)
{
data = sfPacket_ReadInt16(m_ptr);
}
void internalGet(ref ushort data)
{
data = sfPacket_ReadUint16(m_ptr);
}
void internalGet(ref int data)
{
data = sfPacket_ReadInt32(m_ptr);
}
void internalGet(ref uint data)
{
data = sfPacket_ReadUint32(m_ptr);
}
void internalGet(ref float data)
{
data = sfPacket_ReadFloat(m_ptr);
}
void internalGet(ref double data)
{
data = sfPacket_ReadDouble(m_ptr);
}
void internalGet(ref string data)
{
scope char[] temp = new char[sfPacket_GetDataSize(m_ptr)];
sfPacket_ReadString(m_ptr, temp.ptr);
size_t l = fromStringz(temp.ptr).length;
data = cast(string) temp[0 .. l];
}
void internalGet(ref wstring data)
{
scope wchar[] temp = new wchar[sfPacket_GetDataSize(m_ptr)];
sfPacket_ReadWideString(m_ptr, temp.ptr);
size_t l = fromStringz(temp.ptr).length;
data = cast(wstring) temp[0 .. l];
}
void internalSet(bool data)
{
sfPacket_WriteInt32(m_ptr, cast(int)data);
}
void internalSet(byte data)
{
sfPacket_WriteInt8(m_ptr, data);
}
void internalSet(ubyte data)
{
sfPacket_WriteUint8(m_ptr, data);
}
void internalSet(short data)
{
sfPacket_WriteInt16(m_ptr, data);
}
void internalSet(ushort data)
{
sfPacket_WriteUint16(m_ptr, data);
}
void internalSet(int data)
{
sfPacket_WriteInt32(m_ptr, data);
}
void internalSet(uint data)
{
sfPacket_WriteUint32(m_ptr, data);
}
void internalSet(float data)
{
sfPacket_WriteFloat(m_ptr, data);
}
void internalSet(double data)
{
sfPacket_WriteDouble(m_ptr, data);
}
void internalSet(string data)
{
sfPacket_WriteString(m_ptr, toStringz(data));
}
void internalSet(wstring data)
{
sfPacket_WriteWideString(m_ptr, toStringz(data));
}
// External ====================================================================
extern (C)
{
typedef void* function() pf_sfPacket_Create;
typedef void function(void*) pf_sfPacket_Destroy;
typedef void function(void*, void*, size_t) pf_sfPacket_Append;
typedef void function(void*) pf_sfPacket_Clear;
typedef byte* function(void*) pf_sfPacket_GetData;
typedef uint function(void*) pf_sfPacket_GetDataSize;
typedef int function(void*) pf_sfPacket_EndOfPacket;
typedef int function(void*) pf_sfPacket_CanRead;
typedef byte function(void*) pf_sfPacket_ReadInt8;
typedef ubyte function(void*) pf_sfPacket_ReadUint8;
typedef short function(void*) pf_sfPacket_ReadInt16;
typedef ushort function(void*) pf_sfPacket_ReadUint16;
typedef int function(void*) pf_sfPacket_ReadInt32;
typedef uint function(void*) pf_sfPacket_ReadUint32;
typedef float function(void*) pf_sfPacket_ReadFloat;
typedef double function(void*) pf_sfPacket_ReadDouble;
typedef void function(void*, char*) pf_sfPacket_ReadString;
typedef void function(void*, wchar*) pf_sfPacket_ReadWideString;
typedef void function(void*, byte) pf_sfPacket_WriteInt8;
typedef void function(void*, ubyte) pf_sfPacket_WriteUint8;
typedef void function(void*, short) pf_sfPacket_WriteInt16;
typedef void function(void*, ushort) pf_sfPacket_WriteUint16;
typedef void function(void*, int) pf_sfPacket_WriteInt32;
typedef void function(void*, uint) pf_sfPacket_WriteUint32;
typedef void function(void*, float) pf_sfPacket_WriteFloat;
typedef void function(void*, double) pf_sfPacket_WriteDouble;
typedef void function(void*, cchar*) pf_sfPacket_WriteString;
typedef void function(void*, cwchar*) pf_sfPacket_WriteWideString;
static pf_sfPacket_Create sfPacket_Create;
static pf_sfPacket_Destroy sfPacket_Destroy;
static pf_sfPacket_Append sfPacket_Append;
static pf_sfPacket_Clear sfPacket_Clear;
static pf_sfPacket_GetData sfPacket_GetData;
static pf_sfPacket_GetDataSize sfPacket_GetDataSize;
static pf_sfPacket_EndOfPacket sfPacket_EndOfPacket;
static pf_sfPacket_CanRead sfPacket_CanRead;
static pf_sfPacket_ReadInt8 sfPacket_ReadInt8;
static pf_sfPacket_ReadUint8 sfPacket_ReadUint8;
static pf_sfPacket_ReadInt16 sfPacket_ReadInt16;
static pf_sfPacket_ReadUint16 sfPacket_ReadUint16;
static pf_sfPacket_ReadInt32 sfPacket_ReadInt32;
static pf_sfPacket_ReadUint32 sfPacket_ReadUint32;
static pf_sfPacket_ReadFloat sfPacket_ReadFloat;
static pf_sfPacket_ReadDouble sfPacket_ReadDouble;
static pf_sfPacket_ReadString sfPacket_ReadString;
static pf_sfPacket_ReadWideString sfPacket_ReadWideString;
static pf_sfPacket_WriteInt8 sfPacket_WriteInt8;
static pf_sfPacket_WriteUint8 sfPacket_WriteUint8;
static pf_sfPacket_WriteInt16 sfPacket_WriteInt16;
static pf_sfPacket_WriteUint16 sfPacket_WriteUint16;
static pf_sfPacket_WriteInt32 sfPacket_WriteInt32;
static pf_sfPacket_WriteUint32 sfPacket_WriteUint32;
static pf_sfPacket_WriteFloat sfPacket_WriteFloat;
static pf_sfPacket_WriteDouble sfPacket_WriteDouble;
static pf_sfPacket_WriteString sfPacket_WriteString;
static pf_sfPacket_WriteWideString sfPacket_WriteWideString;
}
static this()
{
debug
DllLoader dll = DllLoader.load("csfml-network-d");
else
DllLoader dll = DllLoader.load("csfml-network");
sfPacket_Append = cast(pf_sfPacket_Append)dll.getSymbol("sfPacket_Append");
sfPacket_CanRead = cast(pf_sfPacket_CanRead)dll.getSymbol("sfPacket_CanRead");
sfPacket_Clear = cast(pf_sfPacket_Clear)dll.getSymbol("sfPacket_Clear");
sfPacket_Create = cast(pf_sfPacket_Create)dll.getSymbol("sfPacket_Create");
sfPacket_Destroy = cast(pf_sfPacket_Destroy)dll.getSymbol("sfPacket_Destroy");
sfPacket_EndOfPacket = cast(pf_sfPacket_EndOfPacket)dll.getSymbol("sfPacket_EndOfPacket");
sfPacket_GetData = cast(pf_sfPacket_GetData)dll.getSymbol("sfPacket_GetData");
sfPacket_GetDataSize = cast(pf_sfPacket_GetDataSize)dll.getSymbol("sfPacket_GetDataSize");
sfPacket_ReadDouble = cast(pf_sfPacket_ReadDouble)dll.getSymbol("sfPacket_ReadDouble");
sfPacket_ReadFloat = cast(pf_sfPacket_ReadFloat)dll.getSymbol("sfPacket_ReadFloat");
sfPacket_ReadInt16 = cast(pf_sfPacket_ReadInt16)dll.getSymbol("sfPacket_ReadInt16");
sfPacket_ReadInt32 = cast(pf_sfPacket_ReadInt32)dll.getSymbol("sfPacket_ReadInt32");
sfPacket_ReadInt8 = cast(pf_sfPacket_ReadInt8)dll.getSymbol("sfPacket_ReadInt8");
sfPacket_ReadString = cast(pf_sfPacket_ReadString)dll.getSymbol("sfPacket_ReadString");
sfPacket_ReadWideString = cast(pf_sfPacket_ReadWideString)dll.getSymbol("sfPacket_ReadWideString");
sfPacket_ReadUint16 = cast(pf_sfPacket_ReadUint16)dll.getSymbol("sfPacket_ReadUint16");
sfPacket_ReadUint32 = cast(pf_sfPacket_ReadUint32)dll.getSymbol("sfPacket_ReadUint32");
sfPacket_ReadUint8 = cast(pf_sfPacket_ReadUint8)dll.getSymbol("sfPacket_ReadUint8");
sfPacket_WriteDouble = cast(pf_sfPacket_WriteDouble)dll.getSymbol("sfPacket_WriteDouble");
sfPacket_WriteFloat = cast(pf_sfPacket_WriteFloat)dll.getSymbol("sfPacket_WriteFloat");
sfPacket_WriteInt16 = cast(pf_sfPacket_WriteInt16)dll.getSymbol("sfPacket_WriteInt16");
sfPacket_WriteInt32 = cast(pf_sfPacket_WriteInt32)dll.getSymbol("sfPacket_WriteInt32");
sfPacket_WriteInt8 = cast(pf_sfPacket_WriteInt8)dll.getSymbol("sfPacket_WriteInt8");
sfPacket_WriteString = cast(pf_sfPacket_WriteString)dll.getSymbol("sfPacket_WriteString");
sfPacket_WriteWideString = cast(pf_sfPacket_WriteWideString)dll.getSymbol("sfPacket_WriteWideString");
sfPacket_WriteUint16 = cast(pf_sfPacket_WriteUint16)dll.getSymbol("sfPacket_WriteUint16");
sfPacket_WriteUint32 = cast(pf_sfPacket_WriteUint32)dll.getSymbol("sfPacket_WriteUint32");
sfPacket_WriteUint8 = cast(pf_sfPacket_WriteUint8)dll.getSymbol("sfPacket_WriteUint8");
}
}