204 lines
4.8 KiB
Plaintext
204 lines
4.8 KiB
Plaintext
{
|
|
$Project$
|
|
$Workfile$
|
|
$Revision$
|
|
$DateUTC$
|
|
$Id$
|
|
|
|
This file is part of the Indy (Internet Direct) project, and is offered
|
|
under the dual-licensing agreement described on the Indy website.
|
|
(http://www.indyproject.org/)
|
|
|
|
Copyright:
|
|
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
|
}
|
|
{
|
|
$Log$
|
|
}
|
|
{
|
|
Rev 1.0 27-03-05 10:04:24 MterWoord
|
|
Second import, first time the filenames weren't prefixed with Id
|
|
|
|
Rev 1.0 27-03-05 09:08:58 MterWoord
|
|
Created
|
|
}
|
|
|
|
unit IdSocketStream;
|
|
|
|
interface
|
|
|
|
uses
|
|
System.IO, System.Net.Sockets, IdStack, System.Collections, IdGlobal;
|
|
|
|
type
|
|
TIdSocketStream = class(System.IO.Stream)
|
|
private
|
|
FInternalSocket: Socket;
|
|
public
|
|
function get_CanRead: Boolean; override;
|
|
function get_CanSeek: Boolean; override;
|
|
function get_CanWrite: Boolean; override;
|
|
function get_Length: Int64; override;
|
|
function get_Position: Int64; override;
|
|
procedure set_Position(Value: Int64); override;
|
|
{ Private Declarations }
|
|
public
|
|
constructor Create(const AInternalSocket: Socket); reintroduce;
|
|
destructor Destroy; override;
|
|
procedure Close; override;
|
|
function Read(ABuffer: array of byte; AOffset: Integer; ACount: Integer) : Integer; override;
|
|
function ReadByte : Integer; override;
|
|
function Seek(AOffset: Int64; AOrigin: SeekOrigin) : Int64; override;
|
|
procedure SetLength(ALength: Int64); override;
|
|
procedure Write(ABuffer: array of byte; AOffset: integer; ACount: Integer); override;
|
|
procedure WriteByte(AInput: byte); override;
|
|
procedure Flush; override;
|
|
property CanRead: Boolean read get_CanRead;
|
|
property CanWrite: Boolean read get_CanWrite;
|
|
property CanSeek: Boolean read get_CanSeek;
|
|
property Length: Int64 read get_Length;
|
|
property Position: Int64 read get_Position write set_Position;
|
|
property InternalSocket: Socket read FInternalSocket;
|
|
end;
|
|
|
|
implementation
|
|
|
|
procedure TIdSocketStream.Close;
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
constructor TIdSocketStream.Create(const AInternalSocket: Socket);
|
|
begin
|
|
inherited Create;
|
|
FInternalSocket := AInternalSocket;
|
|
end;
|
|
|
|
function TIdSocketStream.get_Length: Int64;
|
|
begin
|
|
Result := 0;
|
|
if FInternalSocket.Poll(1, SelectMode.SelectRead) then
|
|
Result := FInternalSocket.Available;
|
|
end;
|
|
|
|
function TIdSocketStream.get_CanSeek: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TIdSocketStream.get_CanRead: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TIdSocketStream.get_CanWrite: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TIdSocketStream.get_Position: Int64;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
procedure TIdSocketStream.set_Position(Value: Int64);
|
|
begin
|
|
raise NotSupportedException.Create;
|
|
end;
|
|
|
|
procedure TIdSocketStream.Write(ABuffer: array of byte; AOffset,
|
|
ACount: Integer);
|
|
begin
|
|
try
|
|
GStack.Send(FInternalSocket, ABuffer, AOffset, ACount);
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
Console.WriteLine('TIdSocketStream.Write: ' + E.ToString);
|
|
raise;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TIdSocketStream.ReadByte: Integer;
|
|
var
|
|
TempBuff: array[0..1] of byte;
|
|
begin
|
|
Result := -1;
|
|
if Length > 0 then
|
|
begin
|
|
if Read(TempBuff, 0, 1) <> 0 then
|
|
Result := TempBuff[0];
|
|
end;
|
|
end;
|
|
|
|
procedure TIdSocketStream.SetLength(ALength: Int64);
|
|
begin
|
|
raise NotSupportedException.Create;
|
|
end;
|
|
|
|
procedure TIdSocketStream.WriteByte(AInput: byte);
|
|
begin
|
|
Write([AInput], 0, 1);
|
|
end;
|
|
|
|
procedure TIdSocketStream.Flush;
|
|
begin
|
|
end;
|
|
|
|
function TIdSocketStream.Seek(AOffset: Int64; AOrigin: SeekOrigin): Int64;
|
|
begin
|
|
raise NotSupportedException.Create;
|
|
end;
|
|
|
|
function TIdSocketStream.Read(ABuffer: array of byte; AOffset,
|
|
ACount: Integer): Integer;
|
|
var
|
|
I: Integer;
|
|
TempArray: ArrayList;
|
|
TempBytesToRead: Integer;
|
|
TempBuff: TIdBytes;
|
|
BytesRead: Integer;
|
|
begin
|
|
try
|
|
i := 0;
|
|
TempArray := ArrayList.Create;
|
|
while i < ACount do
|
|
begin
|
|
TempBytesToRead := Math.Min(50, ACount - i);
|
|
TempBuff := ToBytes(System.&String.Create(#0, TempBytesToRead));
|
|
if CanRead then
|
|
begin
|
|
BytesRead := GStack.Receive(FInternalSocket, TempBuff);
|
|
if BytesRead <> 0 then
|
|
begin
|
|
&Array.Copy(TempBuff, 0, ABuffer, i + AOffset, BytesRead);
|
|
Inc(i, BytesRead);
|
|
if BytesRead <> 50 then
|
|
Break;
|
|
end
|
|
else
|
|
Break;
|
|
end
|
|
else
|
|
Break;
|
|
end;
|
|
Result := i;
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
Console.WriteLine('Exception "{0}". I = {1}, BytesRead = {2}, AOffset = {3}, ACount = {4}, TempBytesToRead = {5}',
|
|
[E.GetType().FullName + ': ' + E.Message, I, BytesRead, AOffset, ACount, TempBytesToRead]);
|
|
raise;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
destructor TIdSocketStream.Destroy;
|
|
begin
|
|
FInternalSocket := nil;
|
|
inherited;
|
|
end;
|
|
|
|
end.
|