📄 idworkopunits.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: 56088: IdWorkOpUnits.pas
{
Rev 1.4 6/11/2004 8:40:12 AM DSiders
Added "Do not Localize" comments.
}
{
{ Rev 1.3 2004.05.06 1:47:28 PM czhower
{ Now uses IndexOf
}
{
{ Rev 1.2 2004.04.22 11:45:18 PM czhower
{ Bug fixes
}
{
{ Rev 1.1 2004.02.09 9:16:58 PM czhower
{ Updated to compile and match lib changes.
}
{
{ Rev 1.0 2004.02.03 12:39:10 AM czhower
{ Move
}
{
{ Rev 1.14 2003.10.19 2:50:42 PM czhower
{ Fiber cleanup
}
{
{ Rev 1.13 2003.10.11 5:44:20 PM czhower
{ Chained servers now functional.
}
{
{ Rev 1.12 2003.07.17 4:42:08 PM czhower
{ More IOCP improvements.
}
{
{ Rev 1.11 2003.07.17 3:55:18 PM czhower
{ Removed IdIOChainEngineIOCP and merged it into TIdChaingEngine in
{ IdIOHandlerChain.pas.
}
{
{ Rev 1.7 2003.07.14 11:00:52 PM czhower
{ More IOCP fixes.
}
{
{ Rev 1.6 2003.07.14 12:54:34 AM czhower
{ Fixed graceful close detection if it occurs after connect.
}
{
Rev 1.5 7/7/2003 1:25:26 PM BGooijen
Added BytesSent property to TIdWorkOpUnitWriteFile
}
{
Rev 1.4 7/5/2003 11:47:14 PM BGooijen
Added TIdWorkOpUnitCheckForDisconnect and TIdWorkOpUnitWriteFile
}
{
Rev 1.3 3/27/2003 2:43:06 PM BGooijen
Added woWriteStream and woWriteBuffer
}
{
{ Rev 1.2 3/22/2003 09:45:30 PM JPMugaas
{ Now should compile under D4.
}
{
Rev 1.1 3/2/2003 12:36:26 AM BGooijen
Added woReadBuffer and TIdWorkOpUnitReadBuffer to read a buffer. Now
ReadBuffer doesn't use ReadStream any more.
TIdIOHandlerChain.ReadLn now supports MaxLineLength (splitting, and
exceptions).
woReadLn doesn't check the intire buffer any more, but continued where it
stopped the last time.
Added basic support for timeouts (probably only on read operations, and maybe
connect), accuratie of timeout is currently 500msec.
}
{
Rev 1.0 2/27/2003 10:11:50 PM BGooijen
WorkOpUnits combined in one file
}
unit IdWorkOpUnits;
interface
uses
Classes,
IdWorkOpUnit, IdGlobal,
SysUtils;
type
TIdWorkOpUnitStreamBaseRead = class(TIdWorkOpUnitRead)
protected
FStream: TStream;
public
constructor Create(AStream: TStream); reintroduce; virtual;
end;
TIdWorkOpUnitStreamBaseWrite = class(TIdWorkOpUnitWrite)
protected
FFreeStream: Boolean;
FStream: TStream;
public
constructor Create(
AStream: TStream;
AFreeStream: Boolean = True
); reintroduce; virtual;
destructor Destroy; override;
end;
TIdWorkOpUnitWriteBuffer = class(TIdWorkOpUnitWrite)
protected
FBuffer: Pointer;
FFreeBuffer: Boolean;
FSize: Integer;
//
procedure Processing(ABytes: Integer); override;
procedure Starting; override;
public
constructor Create(ABuffer: Pointer; ASize: Integer;
AFreeBuffer: Boolean = True); reintroduce; virtual;
destructor Destroy; override;
end;
TIdWorkOpUnitWriteFile = class(TIdWorkOpUnitWrite)
protected
FFilename: String;
FBytesSent: Integer;
//
procedure Processing(ABytes: Integer); override;
procedure Starting; override;
public
constructor Create(AFileName: string); reintroduce;
end;
TIdWorkOpUnitWriteStream = class(TIdWorkOpUnitStreamBaseWrite)
protected
FCount: Integer;
FStartPos: Integer;
//
procedure Processing(ABytes: Integer); override;
procedure Starting; override;
public
constructor Create(AStream: TStream; AStartPos, ACount: Integer;
AFreeStream: Boolean); reintroduce; virtual;
end;
TIdWorkOpUnitWaitConnected = class(TIdWorkOpUnit)
protected
procedure Starting; override;
public
procedure Process(
AOverlapped: PIdOverlapped;
AByteCount: Integer
); override;
end;
TIdWorkOpUnitReadSized = class(TIdWorkOpUnitRead)
protected
FSize: Integer;
//
procedure Processing(
ABuffer: TIdBytes
); override;
public
constructor Create(ASize: Integer); reintroduce;
end;
TIdWorkOpUnitReadSizedStream = class(TIdWorkOpUnitStreamBaseRead)
protected
FSize: Integer;
//
procedure Processing(
ABuffer: TIdBytes
); override;
public
constructor Create(AStream: TStream; ASize: Integer);
reintroduce;
end;
TIdWorkOpUnitReadLn = class(TIdWorkOpUnitRead)
protected
FLastPos: Integer;
FMaxLength: Integer;
FTerminator: string;
//
procedure Processing(
ABuffer: TIdBytes
); override;
public
constructor Create(
ATerminator: string;
AMaxLength: Integer
); reintroduce;
end;
TIdWorkOpUnitReadUntilDisconnect = class(TIdWorkOpUnitStreamBaseRead)
protected
procedure Processing(
ABuffer: TIdBytes
); override;
end;
TIdWorkOpUnitReadAvailable = class(TIdWorkOpUnitRead)
protected
procedure Processing(
ABuffer: TIdBytes
); override;
end;
implementation
{ TIdWorkOpUnitWriteStream }
constructor TIdWorkOpUnitWriteStream.Create(AStream: TStream; AStartPos,ACount:integer; AFreeStream: Boolean);
begin
inherited Create(AStream, AFreeStream);
FStream.Position := AStartPos;
FCount := ACount;
end;
procedure TIdWorkOpUnitWriteStream.Processing(ABytes: Integer);
//TODO: This used to use pages from IdBuffer, which because of .Net do not exist
// anymore. We need to maybe keep a local persistent buffer instead then for
// storage reasons.
var
LBuffer: TIdBytes;
LSize: Integer;
begin
FCount := FCount - ABytes;
if FCount = 0 then begin
Complete;
end else begin
FStream.Position := ABytes;
//
//TODO: Dont hard code this value. Also find an optimal size for IOCP
LSize := Min(FCount, WOPageSize);
SetLength(LBuffer, LSize);
//
FStream.ReadBuffer(LBuffer[0], LSize);
Write(@LBuffer[0], LSize);
end;
end;
procedure TIdWorkOpUnitWriteStream.Starting;
begin
Processing(0);
end;
{ TIdWorkOpUnitWriteBuffer }
constructor TIdWorkOpUnitWriteBuffer.Create(ABuffer: pointer; ASize: integer; AFreeBuffer: Boolean = True);
begin
inherited Create;
FSize := ASize;
FBuffer := ABuffer;
FFreeBuffer := AFreeBuffer;
end;
destructor TIdWorkOpUnitWriteBuffer.Destroy;
begin
if FFreeBuffer then begin
FreeMem(FBuffer);
FBuffer := nil;
end;
inherited;
end;
procedure TIdWorkOpUnitWriteBuffer.Processing(ABytes: Integer);
begin
//TODO: Change the pointer to a type that points to bytes
FBuffer := Pointer(Cardinal(FBuffer) + Cardinal(ABytes));
FSize := FSize - ABytes;
if FSize = 0 then begin
Complete;
end else begin
//TODO: Reduce this down so it never sends more than a page
Write(FBuffer, Min(FSize, WOPageSize));
end;
end;
procedure TIdWorkOpUnitWriteBuffer.Starting;
begin
Processing(0);
end;
{ TIdWorkOpUnitWriteFile }
constructor TIdWorkOpUnitWriteFile.Create(AFileName:string);
begin
inherited Create;
FFilename := AFileName;
end;
procedure TIdWorkOpUnitWriteFile.Processing(ABytes: Integer);
begin
Assert(False, 'Need to implement WriteFile, also add to a bubble'); {do not localize}
end;
procedure TIdWorkOpUnitWriteFile.Starting;
begin
end;
{ TIdWorkOpUnitSizedStream }
constructor TIdWorkOpUnitReadSizedStream.Create(AStream: TStream; ASize:integer);
begin
inherited Create(AStream);
FSize := ASize;
end;
procedure TIdWorkOpUnitWaitConnected.Process(
AOverlapped: PIdOverlapped;
AByteCount: Integer
);
begin
end;
procedure TIdWorkOpUnitWaitConnected.Starting;
begin
end;
{ TIdWorkOpUnitReadLn }
constructor TIdWorkOpUnitReadLn.Create(
ATerminator: string;
AMaxLength: Integer);
begin
inherited Create;
FLastPos := 1;
FTerminator := ATerminator;
FMaxLength := AMaxLength;
end;
procedure TIdWorkOpUnitReadLn.Processing(
ABuffer: TIdBytes
);
begin
//TODO: ReadLn is very common. Need to optimize this class and maybe
// even pass pack the result directly so we dont search twice.
//Also allow for hinting from the user.
IOHandler.InputBuffer.Write(ABuffer);
if not IOHandler.Connected then begin
Complete;
end else if IOHandler.InputBuffer.IndexOf(FTerminator, FLastPos) = -1 then begin
Read;
end else begin
Complete;
end;
end;
procedure TIdWorkOpUnitReadUntilDisconnect.Processing(
ABuffer: TIdBytes
);
begin
// 0 is disconnected, so keep requesting til 0
if Length(ABuffer) = 0 then begin
Complete;
end else begin
FStream.WriteBuffer(ABuffer[0], Length(ABuffer));
Read;
end;
end;
{ TIdWorkOpUnitReadAvailable }
procedure TIdWorkOpUnitReadAvailable.Processing(
ABuffer: TIdBytes
);
begin
Complete;
end;
{ TIdWorkOpUnitReadSized }
constructor TIdWorkOpUnitReadSized.Create(ASize: Integer);
begin
inherited Create;
FSize := ASize;
end;
procedure TIdWorkOpUnitReadSized.Processing(
ABuffer: TIdBytes
);
begin
IOHandler.InputBuffer.Write(ABuffer);
FSize := FSize - Length(ABuffer);
if FSize = 0 then begin
Complete;
end else begin
Read;
end;
end;
{ TIdWorkOpUnitStreamBaseRead }
constructor TIdWorkOpUnitStreamBaseRead.Create(AStream: TStream);
begin
inherited Create;
FStream := AStream;
end;
{ TIdWorkOpUnitStreamBaseWrite }
constructor TIdWorkOpUnitStreamBaseWrite.Create(AStream: TStream;
AFreeStream: Boolean);
begin
inherited Create;
FStream := AStream;
FFreeStream := AFreeStream;
end;
destructor TIdWorkOpUnitStreamBaseWrite.Destroy;
begin
if FFreeStream then begin
FreeAndNil(FStream);
end;
inherited;
end;
procedure TIdWorkOpUnitReadSizedStream.Processing(
ABuffer: TIdBytes
);
begin
FStream.WriteBuffer(ABuffer[0], Length(ABuffer));
FSize := FSize - Length(ABuffer);
if FSize = 0 then begin
Complete;
end else begin
Read;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -