{$MODE OBJFPC}
{$MODESWITCH result}
{$MODESWITCH autoderef}
{$MODESWITCH duplicatelocals}
unit dstreamsocket;

interface

uses
  dtypes,
  dstrnum,
  dexception,
  dstream,
  dsocket;

type
PStreamSocket = ^TStreamSocket;
TStreamSocket = object(TStream)
private
  FSocket: PSocket;
public
  constructor Init(Socket: PSocket); overload;
  destructor Done; virtual;
  function Create(Socket: PSocket): PStreamSocket; static; inline; overload;
protected
  function DoRead(P: Pointer; Size: LongInt): LongInt; virtual;
  function DoWrite(P: Pointer; Size: LongInt): LongInt; virtual;
end;

function Data(const Socket: TSocket): TData; inline; overload;
function Data(Socket: PSocket): TData; inline; overload;

operator := (const Socket: TSocket): TData;
operator := (Socket: PSocket): TData;

implementation

constructor TStreamSocket.Init(Socket: PSocket);
begin
  inherited Init;
  FSocket := Socket;
  FName := 'socket';
  FReady := True;
end;

destructor TStreamSocket.Done;
begin
end;

function TStreamSocket.Create(Socket: PSocket): PStreamSocket;
begin
  Result := New(PStreamSocket, Init(Socket));
end;

function TStreamSocket.DoRead(P: Pointer; Size: LongInt): LongInt;
begin
  Result := FSocket.Recv(P, Size);
end;

function TStreamSocket.DoWrite(P: Pointer; Size: LongInt): LongInt;
begin
  Result := FSocket.Send(P, Size);
end;

function Data(const Socket: TSocket): TData;
begin
  Result.Init(TStreamSocket.Create(@Socket), True);
end;

function Data(Socket: PSocket): TData;
begin
  Result.Init(TStreamSocket.Create(Socket), True);
end;

operator := (const Socket: TSocket): TData;
begin
  Result := Data(Socket);
end;

operator := (Socket: PSocket): TData;
begin
  Result := Data(Socket);
end;

end.
