git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.RemObjects@68 b6239004-a887-0f4b-9937-50029ccdca16
223 lines
6.4 KiB
ObjectPascal
223 lines
6.4 KiB
ObjectPascal
unit fClientForm;
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,
|
|
uROClient, uROClientIntf, uRORemoteService, uROBinMessage, uROWinInetHTTPChannel,
|
|
uROPoweredByRemObjectsButton, ExtCtrls, ComCtrls, Mask, uROTypes;
|
|
|
|
type
|
|
TClientForm = class(TForm)
|
|
ROMessage: TROBinMessage;
|
|
ROChannel: TROWinInetHTTPChannel;
|
|
RORemoteService: TRORemoteService;
|
|
Panel1: TPanel;
|
|
Panel2: TPanel;
|
|
ROPoweredByRemObjectsButton1: TROPoweredByRemObjectsButton;
|
|
GroupBox1: TGroupBox;
|
|
Label1: TLabel;
|
|
edTargetURL: TEdit;
|
|
btGetList: TButton;
|
|
Panel3: TPanel;
|
|
GroupBox2: TGroupBox;
|
|
Label2: TLabel;
|
|
cbChunkSize: TComboBox;
|
|
Label3: TLabel;
|
|
edChunkCount: TEdit;
|
|
Label4: TLabel;
|
|
edThreadCount: TMaskEdit;
|
|
GroupBox3: TGroupBox;
|
|
lvFileList: TListView;
|
|
GroupBox4: TGroupBox;
|
|
edLog: TMemo;
|
|
btDownload: TButton;
|
|
procedure btGetListClick(Sender: TObject);
|
|
procedure lvFileListChange(Sender: TObject; Item: TListItem;
|
|
Change: TItemChange);
|
|
procedure cbChunkSizeChange(Sender: TObject);
|
|
procedure btDownloadClick(Sender: TObject);
|
|
private
|
|
{ Private declarations }
|
|
fOutFile: TFileStream;
|
|
procedure CalcChunkCount;
|
|
function GetPartSize: integer;
|
|
procedure SetControlsEnabled(aState: boolean);
|
|
public
|
|
{ Public declarations }
|
|
procedure LogMessage(msg: string);
|
|
procedure WriteChunk(aChunkNo: integer; aChunkSize: integer; aData: Binary);
|
|
end;
|
|
|
|
var
|
|
ClientForm: TClientForm;
|
|
|
|
implementation
|
|
|
|
uses ExtendedFileTransferLibrary_Intf, uROClasses, DownloadThread;
|
|
|
|
{$R *.dfm}
|
|
|
|
procedure TClientForm.btDownloadClick(Sender: TObject);
|
|
var
|
|
threads: array of TDownloadThread;
|
|
numThreads: integer;
|
|
i: integer;
|
|
curChunk: integer;
|
|
chunkCount: integer;
|
|
allDone: boolean;
|
|
begin
|
|
if not Assigned(lvFileList.Selected) then ShowMessage('Please select a file!')
|
|
else begin
|
|
edLog.Lines.Clear;
|
|
fOutFile := TFileStream.Create(lvFileList.Selected.Caption, fmCreate);
|
|
try
|
|
chunkCount := StrToInt(edChunkCount.Text);
|
|
numThreads := StrToInt(Trim(edThreadCount.Text));
|
|
if numThreads <= 0 then numThreads := 1;
|
|
SetLength(threads, numThreads);
|
|
curChunk := 1;
|
|
|
|
LogMessage('Starting download process...');
|
|
SetControlsEnabled(false);
|
|
|
|
for i := 0 to numThreads - 1 do begin
|
|
if curChunk <= chunkCount then begin
|
|
threads[i] := TDownloadThread.Create(i + 1, lvFileList.Selected.Caption,
|
|
curChunk, GetPartSize, edTargetURL.Text);
|
|
inc(curChunk);
|
|
threads[i].Resume;
|
|
end
|
|
else threads[i] := nil;
|
|
end;
|
|
|
|
// Loading chunks using available threads in the pool
|
|
while curChunk <= chunkCount do begin
|
|
for i := 0 to numThreads - 1 do
|
|
if Assigned(threads[i]) and threads[i].Done then begin
|
|
threads[i].Free;
|
|
threads[i] := nil;
|
|
if curChunk <= chunkCount then begin
|
|
threads[i] := TDownloadThread.Create(i + 1, lvFileList.Selected.Caption,
|
|
curChunk, GetPartSize, edTargetURL.Text);
|
|
inc(curChunk);
|
|
threads[i].Resume;
|
|
end;
|
|
end;
|
|
if curChunk <= chunkCount then Application.ProcessMessages;
|
|
end;
|
|
|
|
// Waiting for all threads to finish
|
|
repeat
|
|
allDone := true;
|
|
for i := 0 to numThreads - 1 do
|
|
if Assigned(threads[i]) then begin
|
|
if threads[i].Done then begin
|
|
threads[i].Free;
|
|
threads[i] := nil;
|
|
end
|
|
else allDone := false;
|
|
end;
|
|
if not allDone then Application.ProcessMessages;
|
|
until allDone;
|
|
finally
|
|
fOutFile.Free;
|
|
LogMessage('Download complete!');
|
|
SetControlsEnabled(true);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TClientForm.btGetListClick(Sender: TObject);
|
|
var
|
|
files: FileInfoArray;
|
|
i: integer;
|
|
item: TListItem;
|
|
begin
|
|
ROChannel.TargetURL := edTargetURL.Text;
|
|
files := nil;
|
|
lvFileList.Items.BeginUpdate;
|
|
try
|
|
lvFileList.Items.Clear;
|
|
files := (RORemoteService as IExtendedFileTransferService).GetFilesList;
|
|
for i := 0 to files.Count - 1 do begin
|
|
item := lvFileList.Items.Add;
|
|
item.Caption := {$IFDEF UNICODE}AnsiStringToWideString{$ENDIF}(files.Items[i].FileName);
|
|
item.SubItems.Append(IntToStr(files.Items[i].Size));
|
|
item.SubItems.Append({$IFDEF UNICODE}AnsiStringToWideString{$ENDIF}(files.Items[i].TypeName));
|
|
end;
|
|
if lvFileList.Items.Count > 0 then begin
|
|
lvFileList.Selected := lvFileList.Items[0];
|
|
lvFileList.SetFocus;
|
|
end;
|
|
finally
|
|
if Assigned(files) then files.Free;
|
|
lvFileList.Items.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TClientForm.CalcChunkCount;
|
|
var
|
|
size: integer;
|
|
chunk: integer;
|
|
begin
|
|
if Assigned(lvFileList.Selected) then begin
|
|
size := StrToInt(lvFileList.Selected.SubItems[0]);
|
|
chunk := GetPartSize;
|
|
if chunk <> 0 then begin
|
|
if size mod chunk > 0 then edChunkCount.Text := IntToStr((size div chunk) + 1)
|
|
else edChunkCount.Text := IntToStr(size div chunk);
|
|
end
|
|
else edChunkCount.Text := 'Error!';
|
|
end;
|
|
end;
|
|
|
|
procedure TClientForm.cbChunkSizeChange(Sender: TObject);
|
|
begin
|
|
CalcChunkCount;
|
|
end;
|
|
|
|
function TClientForm.GetPartSize: integer;
|
|
begin
|
|
case cbChunkSize.ItemIndex of
|
|
0: Result := 500;
|
|
1: Result := 64 * 1024;
|
|
2: Result := 128 * 1024;
|
|
3: Result := 512 * 1024;
|
|
4: Result := 1 * 1024 * 1024;
|
|
5: Result := 2 * 1024 * 1024;
|
|
6: Result := 3 * 1024 * 1024;
|
|
else Result := 0;
|
|
end;
|
|
end;
|
|
|
|
procedure TClientForm.LogMessage(msg: string);
|
|
begin
|
|
edLog.Lines.Append(msg);
|
|
end;
|
|
|
|
procedure TClientForm.lvFileListChange(Sender: TObject; Item: TListItem;
|
|
Change: TItemChange);
|
|
begin
|
|
CalcChunkCount;
|
|
end;
|
|
|
|
procedure TClientForm.SetControlsEnabled(aState: boolean);
|
|
begin
|
|
cbChunkSize.Enabled := aState;
|
|
edThreadCount.Enabled := aState;
|
|
btDownload.Enabled := aState;
|
|
edTargetURL.Enabled := aState;
|
|
end;
|
|
|
|
procedure TClientForm.WriteChunk(aChunkNo, aChunkSize: integer; aData: Binary);
|
|
var
|
|
lOffset: integer;
|
|
begin
|
|
lOffset := aChunkSize * (aChunkNo - 1);
|
|
fOutFile.Seek(lOffset, soFromBeginning);
|
|
fOutFile.CopyFrom(aData, aData.Size)
|
|
end;
|
|
|
|
end.
|