⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 idworkopunits.pas

📁 photo.163.com 相册下载器 多线程下载
💻 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 + -