| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- { $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.
|