restemplate/indy/Protocols/IdFTPListParseUnisysClearPa...

240 lines
6.5 KiB
Plaintext

{
$Project$
$Workfile$
$Revision$
$DateUTC$
$Id$
This file is part of the Indy (Internet Direct) project, and is offered
under the dual-licensing agreement described on the Indy website.
(http://www.indyproject.org/)
Copyright:
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
}
{
$Log$
}
{
Rev 1.0 12/8/2004 8:45:02 AM JPMugaas
}
unit IdFTPListParseUnisysClearPath;
{
Unisys ClearPath (MCP and OS/2)
DIRECTORY_FORMAT=NATIVE
Much of this is based on:
ClearPath Enterprise Servers
FTP Services for ClearPath
OS 2200 User's Guide
ClearPath OS 2200 Release 8.0 January 2003
© 2003 Unisys Corporation.
All rights reserved.
and
ClearPath Enterprise Servers
TCP/IP Distributed Systems Services Operations Guide
ClearPath MCP Release 9.0 April 2004
© 2004 Unisys Corporation.
All rights reserved.
With a sample showing a multiline response from:
http://article.gmane.org/gmane.text.xml.cocoon.devel/24912
This parses data in this form:
===
Report for: (UC)A ON PACK
A SEQDATA 84 03/08/1998 15:32
A/B SEQDATA 84 06/09/1998 12:03
A/B/C SEQDATA 84 06/09/1998 12:03
A/C SEQDATA 84 06/09/1998 12:03
A/C/C SEQDATA 84 06/09/1998 12:04
A/C/C/D SEQDATA 84 06/09/1998 12:04
6 Files 504 Octets
===
The parserm only support DIRECTORY_FORMAT=NATIVE which is the default on that server.
DIRECTORY_FORMAT=STANDARD does not need be supported because that is probably listed
in Unix format. If not, we'll deal with it given some data samples.
}
interface
{$i IdCompilerDefines.inc}
uses
Classes,
IdFTPList, IdFTPListParseBase, IdFTPListTypes;
type
TIdUnisysClearPathFTPListItem = class(TIdCreationDateFTPListItem)
protected
FFileKind : String;
public
property FileKind : String read FFileKind write FFileKind;
end;
TIdFTPLPUnisysClearPath = class(TIdFTPListBaseHeader)
protected
class function IsContinuedLine(const AData: String): Boolean;
class function MakeNewItem(AOwner : TIdFTPListItems) : TIdFTPListItem; override;
class function IsHeader(const AData: String): Boolean; override;
class function IsFooter(const AData : String): Boolean; override;
class function ParseLine(const AItem : TIdFTPListItem; const APath : String = ''): Boolean; override;
public
class function ParseListing(AListing : TStrings; ADir : TIdFTPListItems) : Boolean; override;
class function GetIdent : String; override;
end;
// RLebeau 2/14/09: this forces C++Builder to link to this unit so
// RegisterFTPListParser can be called correctly at program startup...
{$IFDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT}
{$HPPEMIT LINKUNIT}
{$ELSE}
{$HPPEMIT '#pragma link "IdFTPListParseUnisysClearPath"'}
{$ENDIF}
implementation
uses
IdGlobal, IdFTPCommon, IdGlobalProtocols, IdStrings, SysUtils;
{ TIdFTPLPUnisysClearPath }
class function TIdFTPLPUnisysClearPath.GetIdent: String;
begin
Result := 'Unisys Clearpath'; {Do not localize}
end;
class function TIdFTPLPUnisysClearPath.IsContinuedLine(const AData: String): Boolean;
begin
Result := TextStartsWith(AData, ' '); {Do not localize}
end;
class function TIdFTPLPUnisysClearPath.IsFooter(const AData: String): Boolean;
var
s : TStrings;
begin
Result := False;
s := TStringList.Create;
try
SplitDelimitedString(AData, s, True);
if s.Count = 4 then
begin
if (s[1] = 'Files') or (s[1] = 'File') then begin {Do not localize}
Result := (s[3] = 'Octets') or (s[3] = 'Octet'); {Do not localize}
end;
end;
finally
FreeAndNil(s);
end;
end;
class function TIdFTPLPUnisysClearPath.IsHeader(const AData: String): Boolean;
var
s : TStrings;
begin
Result := False;
s := TStringList.Create;
try
SplitDelimitedString(AData, s, True);
if s.Count > 2 then begin
Result := (s[0] = 'Report') and (s[1] = 'for:');
end;
finally
FreeAndNil(s);
end;
end;
class function TIdFTPLPUnisysClearPath.MakeNewItem(AOwner: TIdFTPListItems): TIdFTPListItem;
begin
Result := TIdUnisysClearPathFTPListItem.Create(AOwner);
end;
class function TIdFTPLPUnisysClearPath.ParseLine(const AItem: TIdFTPListItem;
const APath: String): Boolean;
var
s : TStrings;
LI : TIdUnisysClearPathFTPListItem;
begin
Result := False;
LI := AItem as TIdUnisysClearPathFTPListItem;
LI.ItemType := ditFile;
s := TStringList.Create;
try
SplitDelimitedString(LI.Data, s, True);
if s.Count > 4 then
begin
LI.FileName := s[0];
LI.FileKind := s[1];
//size
if IsNumeric(s[2]) then
begin
LI.Size := IndyStrToInt(s[2], 0);
AItem.SizeAvail := True;
//creation date
if IsMMDDYY(s[3], '/') then {Do not localize}
begin
LI.CreationDate := DateMMDDYY(s[3]);
if IsHHMMSS(s[4], ':') then {Do not localize}
begin
LI.CreationDate := LI.CreationDate + TimeHHMMSS(s[4]);
Result := True;
end;
end;
end;
s.Clear;
//remove path from localFileName
SplitDelimitedString(LI.FileName, s, True, '/'); {Do not localize}
if s.Count > 0 then begin
LI.LocalFileName := s[s.Count-1];
end else begin
Result := False;
end;
end;
finally
FreeAndNil(s);
end;
end;
class function TIdFTPLPUnisysClearPath.ParseListing(AListing: TStrings;
ADir: TIdFTPListItems): Boolean;
var
i : Integer;
LItem : TIdFTPListItem;
begin
for i := 0 to AListing.Count-1 do
begin
if not IsWhiteString(AListing[i]) then
begin
if not (IsHeader(AListing[i]) or IsFooter(AListing[i])) then
begin
if (not IsContinuedLine(AListing[i])) then //needed because some VMS computers return entries with multiple lines
begin
LItem := MakeNewItem(ADir);
LItem.Data := UnfoldLines(AListing[i], i, AListing);
Result := ParseLine(LItem);
if not Result then begin
FreeAndNil(LItem);
Exit;
end;
end;
end;
end;
end;
Result := True;
end;
initialization
RegisterFTPListParser(TIdFTPLPUnisysClearPath);
finalization
UnRegisterFTPListParser(TIdFTPLPUnisysClearPath);
end.