Created
November 2, 2013 03:53
-
-
Save FRex/7275301 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
unit SFUtils; | |
{$mode objfpc}{$H+} | |
interface | |
uses | |
Classes, SysUtils; | |
type | |
TRawBytes = array of byte; | |
TPacketSizeCheckFailed = class | |
constructor Create; overload; | |
end; | |
TPacket = class | |
private | |
FData: array of byte; | |
FValid: boolean; | |
FReadPos: longword; | |
procedure CheckSize(i: integer); | |
public | |
constructor Create; overload; | |
procedure Clear; | |
function GetDataSize: longword; | |
property DataSize: longword read GetDataSize; | |
function GetData: TRawBytes; | |
property Data: TRawBytes read GetData; | |
function GetEndOfPacket: boolean; | |
property EndOfPacket: boolean read GetEndOfPacket; | |
function GetCanRead: boolean; | |
property CanRead: boolean read GetCanRead; | |
function ReadBool: boolean; | |
function ReadInt8: shortint; | |
function ReadUint8: byte; | |
function ReadInt16: smallint; | |
function ReadUint16: word; | |
function ReadInt32: longint; | |
function ReadUint32: longword; | |
function ReadString: string; | |
function ReadSingle: single; | |
function ReadDouble: double; | |
procedure WriteBool(v: boolean); | |
procedure WriteInt8(v: shortint); | |
procedure WriteUint8(v: byte); | |
procedure WriteInt16(v: smallint); | |
procedure WriteUint16(v: word); | |
procedure WriteInt32(v: longint); | |
procedure WriteUint32(v: longword); | |
procedure WriteString(const v: string); | |
procedure WriteSingle(v: single); | |
procedure WriteDouble(v: double); | |
procedure Append(const bytes; size: longword); | |
end; | |
implementation | |
uses Sockets; | |
constructor TPacketSizeCheckFailed.Create; | |
begin | |
inherited; | |
end; | |
procedure TPacket.CheckSize(i: integer); | |
begin | |
FValid := FValid and (FReadPos + i <= Length(FData)); | |
if not FValid then | |
raise TPacketSizeCheckFailed.Create; | |
end; | |
constructor TPacket.Create; | |
begin | |
inherited; | |
FReadPos := 0; | |
FValid := True; | |
end; | |
procedure TPacket.Clear; | |
begin | |
SetLength(FData, 0); | |
FReadPos := 0; | |
FValid := True; | |
end; | |
function TPacket.GetDataSize: longword; | |
begin | |
Result := Length(FData); | |
end; | |
function TPacket.GetData: TRawBytes; | |
begin | |
Result := FData; | |
end; | |
function TPacket.GetEndOfPacket: boolean; | |
begin | |
Result := High(FData) < FReadPos; | |
end; | |
function TPacket.GetCanRead: boolean; | |
begin | |
Result := FValid; | |
end; | |
function TPacket.ReadBool: boolean; | |
begin | |
Result := ReadUint8 <> 0; | |
end; | |
function TPacket.ReadInt8: shortint; | |
begin | |
CheckSize(SizeOf(shortint)); | |
Move(FData[FReadPos], Result, SizeOf(shortint)); | |
Inc(FReadPos, SizeOf(shortint)); | |
end; | |
function TPacket.ReadUint8: byte; | |
begin | |
CheckSize(SizeOf(byte)); | |
Move(FData[FReadPos], Result, SizeOf(byte)); | |
Inc(FReadPos, SizeOf(byte)); | |
end; | |
function TPacket.ReadInt16: smallint; | |
begin | |
CheckSize(SizeOf(smallint)); | |
Move(FData[FReadPos], Result, SizeOf(smallint)); | |
Inc(FReadPos, SizeOf(smallint)); | |
Result := ntohs(Result); | |
end; | |
function TPacket.ReadUint16: word; | |
begin | |
CheckSize(SizeOf(word)); | |
Move(FData[FReadPos], Result, SizeOf(word)); | |
Inc(FReadPos, SizeOf(word)); | |
Result := ntohs(Result); | |
end; | |
function TPacket.ReadInt32: longint; | |
begin | |
CheckSize(SizeOf(longint)); | |
Move(FData[FReadPos], Result, SizeOf(longint)); | |
Inc(FReadPos, SizeOf(longint)); | |
Result := ntohl(Result); | |
end; | |
function TPacket.ReadUint32: longword; | |
begin | |
CheckSize(SizeOf(longword)); | |
Move(FData[FReadPos], Result, SizeOf(longword)); | |
Inc(FReadPos, SizeOf(longword)); | |
Result := ntohl(Result); | |
end; | |
function TPacket.ReadString: string; | |
var | |
l: longword; | |
begin | |
l := ReadUint32; | |
CheckSize(l); | |
SetLength(Result, l); | |
Move(FData[FReadPos], Result[1], l); | |
Inc(FReadPos, l); | |
end; | |
function TPacket.ReadSingle: single; | |
begin | |
Move(FData[FReadPos], Result, SizeOf(single)); | |
Inc(FReadPos, SizeOf(single)); | |
end; | |
function TPacket.ReadDouble: double; | |
begin | |
Move(FData[FReadPos], Result, SizeOf(double)); | |
Inc(FReadPos, SizeOf(double)); | |
end; | |
procedure TPacket.WriteBool(v: boolean); | |
begin | |
if v then | |
WriteUint8(1) | |
else | |
WriteUint8(0); | |
end; | |
procedure TPacket.WriteInt8(v: shortint); | |
begin | |
SetLength(FData, Length(FData) + SizeOf(shortint)); | |
move(v, FData[Length(FData) - SizeOf(shortint)], SizeOf(shortint)); | |
end; | |
procedure TPacket.WriteUint8(v: byte); | |
begin | |
SetLength(FData, Length(FData) + SizeOf(byte)); | |
move(v, FData[Length(FData) - SizeOf(byte)], SizeOf(byte)); | |
end; | |
procedure TPacket.WriteInt16(v: smallint); | |
begin | |
SetLength(FData, Length(FData) + SizeOf(smallint)); | |
move(htons(v), FData[Length(FData) - SizeOf(smallint)], SizeOf(smallint)); | |
end; | |
procedure TPacket.WriteUint16(v: word); | |
begin | |
SetLength(FData, Length(FData) + SizeOf(word)); | |
move(htons(v), FData[Length(FData) - SizeOf(word)], SizeOf(word)); | |
end; | |
procedure TPacket.WriteInt32(v: longint); | |
begin | |
SetLength(FData, Length(FData) + SizeOf(longint)); | |
move(htonl(v), FData[Length(FData) - SizeOf(longint)], SizeOf(longint)); | |
end; | |
procedure TPacket.WriteUint32(v: longword); | |
begin | |
SetLength(FData, Length(FData) + SizeOf(longword)); | |
move(htonl(v), FData[Length(FData) - SizeOf(longword)], SizeOf(longword)); | |
end; | |
procedure TPacket.WriteString(const v: string); | |
begin | |
WriteUint32(Length(v)); | |
SetLength(FData, Length(FData) + Length(v)); | |
move(v[1], FData[Length(FData) - Length(v)], Length(v)); | |
end; | |
procedure TPacket.WriteSingle(v: single); | |
begin | |
SetLength(FData, Length(FData) + SizeOf(single)); | |
move(v, FData[Length(FData) - SizeOf(single)], SizeOf(single)); | |
end; | |
procedure TPacket.WriteDouble(v: double); | |
begin | |
SetLength(FData, Length(FData) + SizeOf(double)); | |
move(v, FData[Length(FData) - SizeOf(double)], SizeOf(double)); | |
end; | |
procedure TPacket.Append(const bytes; size: longword); | |
var | |
i: integer; | |
begin | |
SetLength(FData, Length(FData) + size); | |
Move(bytes, FData[Length(FData) - size], size); | |
end; | |
end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment