📄 idiohandlerstream.pas
字号:
{ $HDR$}
{**********************************************************************}
{ Unit archived using Team Coherence }
{ Team Coherence is Copyright 2002 by Quality Software Components }
{ }
{ For further information / comments, visit our WEB site at }
{ http://www.TeamCoherence.com }
{**********************************************************************}
{}
{ $Log: 26782: IdIOHandlerStream.pas
{
{ Rev 1.20 10/21/2004 11:07:30 PM BGooijen
{ works in win32 now too
}
{
{ Rev 1.19 10/21/2004 1:52:56 PM BGooijen
{ Raid 214235
}
{
{ Rev 1.18 7/23/04 6:20:52 PM RLebeau
{ Removed memory leaks in Send/ReceiveStream property setters
}
{
{ Rev 1.17 2004.05.20 11:39:08 AM czhower
{ IdStreamVCL
}
{
{ Rev 1.16 23/04/2004 20:29:36 CCostelloe
{ Minor change to support IdMessageClient's new TIdIOHandlerStreamMsg
}
{
{ Rev 1.15 2004.04.16 11:30:32 PM czhower
{ Size fix to IdBuffer, optimizations, and memory leaks
}
{
{ Rev 1.14 2004.04.08 3:56:36 PM czhower
{ Fixed bug with Intercept byte count. Also removed Bytes from Buffer.
}
{
{ Rev 1.13 2004.03.07 11:48:46 AM czhower
{ Flushbuffer fix + other minor ones found
}
{
{ Rev 1.12 2004.03.03 11:55:04 AM czhower
{ IdStream change
}
{
{ Rev 1.11 2004.02.03 4:17:16 PM czhower
{ For unit name changes.
}
{
{ Rev 1.10 11/01/2004 19:52:44 CCostelloe
{ Revisions for TIdMessage SaveToFile & LoadFromFile for D7 & D8
}
{
{ Rev 1.8 08/01/2004 23:37:16 CCostelloe
{ Minor changes
}
{
{ Rev 1.7 1/8/2004 1:01:22 PM BGooijen
{ Cleaned up
}
{
{ Rev 1.6 1/8/2004 4:23:06 AM BGooijen
{ temp fixed TIdIOHandlerStream.WriteToDestination
}
{
{ Rev 1.5 08/01/2004 00:25:22 CCostelloe
{ Start of reimplementing LoadFrom/SaveToFile
}
{
{ Rev 1.4 2003.12.31 7:44:54 PM czhower
{ Matched constructors visibility to ancestor.
}
{
{ Rev 1.3 2003.10.24 10:44:54 AM czhower
{ IdStream implementation, bug fixes.
}
{
{ Rev 1.2 2003.10.14 11:19:14 PM czhower
{ Updated for better functionality.
}
{
{ Rev 1.1 2003.10.14 1:27:14 PM czhower
{ Uupdates + Intercept support
}
{
{ Rev 1.0 2003.10.13 6:40:40 PM czhower
{ Moved from root
}
{
{ Rev 1.9 2003.10.11 10:00:36 PM czhower
{ Compiles again.
}
{
{ Rev 1.8 10/10/2003 10:53:42 PM BGooijen
{ Changed const-ness of some methods to reflect base class changes
}
{
{ Rev 1.7 7/10/2003 6:07:58 PM SGrobety
{ .net
}
{
{ Rev 1.6 17/07/2003 00:01:24 CCostelloe
{ Added (empty) procedures for the base classes' abstract CheckForDataOnSource
{ and CheckForDisconnect
}
{
Rev 1.5 7/1/2003 12:45:56 PM BGooijen
changed FInputBuffer.Size := 0 to FInputBuffer.Clear
}
{
{ Rev 1.4 12-8-2002 21:05:28 BGooijen
{ Removed call to Close in .Destroy, this is already done in
{ TIdIOHandler.Destroy
}
{
{ Rev 1.3 12/7/2002 06:42:44 PM JPMugaas
{ These should now compile except for Socks server. IPVersion has to be a
{ property someplace for that.
}
{
{ Rev 1.2 12/5/2002 02:53:52 PM JPMugaas
{ Updated for new API definitions.
}
{
{ Rev 1.1 05/12/2002 15:29:16 AO'Neill
}
{
{ Rev 1.0 11/13/2002 07:55:08 AM JPMugaas
}
unit IdIOHandlerStream;
interface
uses
Classes,
IdGlobal, IdIOHandler, IdStreamVCL;
type
TIdIOHandlerStream = class;
TIdIOHandlerStreamType = (stRead, stWrite, stReadWrite);
TIdOnGetStreams = procedure(
ASender: TIdIOHandlerStream;
var VReceiveStream: TStream;
var VSendStream: TStream
) of object;
TIdIOHandlerStream = class(TIdIOHandler)
protected
FFreeStreams: Boolean;
FOnGetStreams: TIdOnGetStreams;
FReceiveIdStream: TIdStreamVCL;
FSendIdStream: TIdStreamVCL;
FStreamType: TIdIOHandlerStreamType;
//
function GetReceiveStream:TStream;
function GetSendStream:TStream;
procedure SetReceiveStream(AStream:TStream);
procedure SetSendStream(AStream:TStream);
function ReadFromSource(
ARaiseExceptionIfDisconnected: Boolean = True;
ATimeout: Integer = IdTimeoutDefault;
ARaiseExceptionOnTimeout: Boolean = True
): Integer; override;
public
procedure CheckForDataOnSource(
ATimeout: Integer = 0
); override;
procedure CheckForDisconnect(
ARaiseExceptionIfDisconnected: Boolean = True;
AIgnoreBuffer: Boolean = False
); override;
constructor Create(
AOwner: TComponent;
AReceiveStream: TStream;
ASendStream: TStream = nil
); reintroduce; overload; virtual;
constructor Create(
AOwner: TComponent
); reintroduce; overload;
function Connected
: Boolean;
override;
procedure Close;
override;
procedure Open;
override;
function Readable(AMSec: integer = IdTimeoutDefault): boolean; override;
procedure WriteDirect(
ABuffer: TIdBytes
); override;
//
property ReceiveStream: TStream read GetReceiveStream {write SetReceiveStream};
property SendStream: TStream read GetSendStream {write SetSendStream};
published
property FreeStreams: Boolean read FFreeStreams write FFreeStreams;
property StreamType: TIdIOHandlerStreamType read FStreamType
write FStreamType;
//
property OnGetStreams: TIdOnGetStreams read FOnGetStreams
write FOnGetStreams;
end;
implementation
uses
SysUtils;
{ TIdIOHandlerStream }
procedure TIdIOHandlerStream.CheckForDataOnSource(ATimeout: Integer = 0);
begin
{All that we are doing here is implementing the base class's abstract function}
end;
procedure TIdIOHandlerStream.CheckForDisconnect(
ARaiseExceptionIfDisconnected: Boolean = True;
AIgnoreBuffer: Boolean = False);
begin
{All that we are doing here is implementing the base class's abstract function}
end;
procedure TIdIOHandlerStream.Close;
begin
inherited;
if FreeStreams then begin
ReceiveStream.Free;
SendStream.Free;
end;
FreeAndNil(FReceiveIdStream);
FreeAndNil(FSendIdStream);
end;
function TIdIOHandlerStream.Connected: Boolean;
begin
Result := False; // Just to avoid warning message
case FStreamType of
stRead: Result := ReceiveStream <> nil;
stWrite: Result := SendStream <> nil;
stReadWrite: Result := (ReceiveStream <> nil) and (SendStream <> nil);
end;
end;
constructor TIdIOHandlerStream.Create( AOwner: TComponent );
begin
inherited Create(AOwner);
FFreeStreams := True;
//
FStreamType := stReadWrite;
end;
constructor TIdIOHandlerStream.Create(
AOwner: TComponent;
AReceiveStream: TStream;
ASendStream: TStream = nil
);
begin
inherited Create(AOwner);
FFreeStreams := True;
//
FStreamType := stReadWrite;
if (AReceiveStream <> nil) and (ASendStream = nil) then begin
FStreamType := stWrite;
end else if (AReceiveStream = nil) and (ASendStream <> nil) then begin
FStreamType := stRead;
end;
SetReceiveStream(AReceiveStream);
SetSendStream(ASendStream);
end;
procedure TIdIOHandlerStream.Open;
var
LReceiveStream, LSendStream: TStream;
begin
inherited;
if Assigned(OnGetStreams) then begin
LReceiveStream := nil;
LSendStream := nil;
OnGetStreams(Self, LReceiveStream, LSendStream);
if LReceiveStream <> nil then begin
FReceiveIdStream := TIdStreamVCL.Create(LReceiveStream);
end;
if LSendStream <> nil then begin
FSendIdStream := TIdStreamVCL.Create(LSendStream);
end;
end;
end;
function TIdIOHandlerStream.Readable(AMSec: integer): boolean;
begin
Result := ReceiveStream <> nil;
if Result then begin
Result := ReceiveStream.Position < ReceiveStream.Size;
end;
end;
function TIdIOHandlerStream.ReadFromSource(
ARaiseExceptionIfDisconnected: Boolean; ATimeout: Integer;
ARaiseExceptionOnTimeout: Boolean): Integer;
begin
Result := 0;
if ReceiveStream <> nil then begin
if FReceiveIdStream.VCLStream.Position < FReceiveIdStream.VCLStream.Size then begin
// We dont want to read the whole stream in at a time. If its a big file will consume way too
// much memory by loading it all at once. So lets read it in chunks.
Result := Min(32 * 1024, FReceiveIdStream.VCLStream.Size
- FReceiveIdStream.VCLStream.Position);
FInputBuffer.Write(FReceiveIdStream, Result);
end;
end else begin
FInputBuffer.Clear;
end;
end;
procedure TIdIOHandlerStream.WriteDirect(
ABuffer: TIdBytes
);
begin
if SendStream <> nil then begin
inherited;
FSendIdStream.Write(ABuffer, Length(ABuffer));
end;
end;
function TIdIOHandlerStream.GetReceiveStream: TStream;
begin
if FReceiveIdStream = nil then begin
Result := nil;
end else begin
Result := FReceiveIdStream.VCLStream;
end;
end;
function TIdIOHandlerStream.GetSendStream: TStream;
begin
if FSendIdStream = nil then begin
Result := nil;
end else begin
Result := FSendIdStream.VCLStream;
end;
end;
procedure TIdIOHandlerStream.SetReceiveStream(AStream: TStream);
begin
FreeAndNil(FReceiveIdStream);
if AStream <> nil then begin
FReceiveIdStream := TIdStreamVCL.Create(AStream);
end;
end;
procedure TIdIOHandlerStream.SetSendStream(AStream: TStream);
begin
FreeAndNil(FSendIdStream);
if AStream <> nil then begin
FSendIdStream := TIdStreamVCL.Create(AStream);
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -