📄 clftputils.pas
字号:
begin
resSize := 512;
Result := 'd';
end else
begin
resSize := AFileInfo.Size;
Result := '-';
end;
if (AFileInfo.Owner = []) and (AFileInfo.Group = []) and (AFileInfo.Other = []) then
begin
if AFileInfo.IsReadOnly then
begin
resAccessOwn := 'r-x';
end else
begin
resAccessOwn := 'rwx';
end;
resAccessGrp := resAccessOwn;
resAccessOth := resAccessOwn;
end else
begin
resAccessOwn := GetPermissionsStr(AFileInfo.Owner);
resAccessGrp := GetPermissionsStr(AFileInfo.Group);
resAccessOth := GetPermissionsStr(AFileInfo.Other);
end;
Result := Result + Format('%3s%3s%3s 1 %8s %8s %12d', //TODO Int64
[resAccessOwn, resAccessGrp, resAccessOth, 'owner ', 'group ', resSize]);
DecodeDate(AFileInfo.ModifiedDate, temp, resMonth, temp);
resTime := cMonths[resMonth] + FormatDateTime(' dd', AFileInfo.ModifiedDate);
if IsSixMonth(AFileInfo.ModifiedDate) then
begin
resTime := resTime + FormatDateTime(' hh:mm', AFileInfo.ModifiedDate);
end else
begin
resTime := resTime + FormatDateTime(' yyyy ', AFileInfo.ModifiedDate);
end;
Result := Result + ' ' + resTime + ' ' + AFileInfo.FileName;
end;
function TclUnixFileInfoParser.Check(const ASource: string): Boolean;
var
info: TclFtpFileInfo;
begin
Result := (UpperCase(ASource[1])[1] in ['D', '-', 'C', 'L']);
if Result then
begin
info := TclFtpFileInfo.Create();
try
Parse(info, ASource);
Result := (info.FileName <> '') and (info.ModifiedDate > 0);
finally
info.Free();
end;
end;
end;
function TclUnixFileInfoParser.CurrentYear: Integer;
var
y, m, d: Word;
begin
DecodeDate(Now(), y, m, d);
Result := y;
end;
function TclUnixFileInfoParser.GetMonth(const AMonth: string): Integer;
begin
Result := Succ(IndexOfStrArray(AMonth, cMonths));
end;
function TclUnixFileInfoParser.GetPermissionsStr(
APermissions: TclFtpFilePermissions): string;
begin
Result := '---';
if (fpRead in APermissions) then
Result[1] := 'r';
if (fpWrite in APermissions) then
Result[2] := 'w';
if (fpExecute in APermissions) then
Result[3] := 'x';
end;
function TclUnixFileInfoParser.IsSixMonth(ADate: TDateTime): Boolean;
var
curMonth, curDay, curYear: Word;
month, year: Word;
dateMonth, dateDay, dateYear: Word;
begin
DecodeDate(Now(), curYear, curMonth, curDay);
DecodeDate(ADate, dateYear, dateMonth, dateDay);
if (curMonth - 6) < 1 then
begin
month := 12 + (curMonth - 6);
year := curYear - 1;
end else
begin
month := curMonth - 6;
year := curYear;
end;
Result := True;
if (dateYear < year) then
begin
Result := False;
end else
if (dateYear = year) then
begin
Result := (dateMonth >= month);
if Result and (dateMonth = month) then
begin
Result := (dateDay >= curDay);
end;
end;
end;
procedure TclUnixFileInfoParser.Parse(AFileInfo: TclFtpFileInfo; const ASource: string);
var
cnt, startWord: Integer;
s: string;
ind, y, m, d, hh, mm: Integer;
begin
cnt := WordCount(ASource, [#32]);
if cnt < 6 then Exit;
s := UpperCase(Trim(ExtractWord(1, ASource, [#32])));
AFileInfo.IsDirectory := (s[1] = 'D');
AFileInfo.IsLink := (s[1] = 'L');
AFileInfo.IsReadOnly := (system.Pos('W', s) = 0);
if (Length(s) >= 9) then
begin
AFileInfo.Owner := ParsePermissionsStr(system.Copy(s, 2, 3));
AFileInfo.Group := ParsePermissionsStr(system.Copy(s, 5, 3));
AFileInfo.Other := ParsePermissionsStr(system.Copy(s, 8, 3));
end;
startWord := 5;
while startWord > 1 do
begin
try
AFileInfo.Size := StrToInt64(Trim(ExtractWord(startWord, ASource, [#32])));
m := GetMonth(Trim(ExtractWord(startWord + 1, ASource, [#32])));
d := StrToIntDef(Trim(ExtractWord(startWord + 2, ASource, [#32])), 1);
s := Trim(ExtractWord(startWord + 3, ASource, [#32]));
if system.Pos(':', s) > 0 then
begin
y := CurrentYear();
hh := StrToIntDef(ExtractWord(1, s, [':']), 0);
mm := StrToIntDef(ExtractWord(2, s, [':']), 0);
end else
begin
y := StrToIntDef(s, CurrentYear());
hh := 0;
mm := 0;
end;
AFileInfo.ModifiedDate := EncodeDate(y, m, d) + EncodeTime(hh, mm, 0, 0);
ind := WordPosition(startWord + 4, ASource, [#32]);
if (ind > 0) then
begin
AFileInfo.FileName := Trim(system.Copy(ASource, ind, Length(ASource)));
if AFileInfo.IsLink then
begin
s := AFileInfo.FileName;
ind := system.Pos('->', s);
if (ind > 0) then
begin
SetLength(s, ind - 1);
AFileInfo.FileName := TrimRight(s);
end;
end;
end;
Break;
except
Dec(startWord);
end;
end;
end;
function TclUnixFileInfoParser.ParsePermissionsStr(const APermissions: string): TclFtpFilePermissions;
var
s: string;
begin
Result := [];
if (Length(APermissions) < 3) then Exit;
s := LowerCase(APermissions);
if (s[1] = 'r') then
Result := Result + [fpRead];
if (s[2] = 'w') then
Result := Result + [fpWrite];
if (s[3] = 'x') then
Result := Result + [fpExecute];
end;
{ TclAs400FileInfoParser }
function TclAs400FileInfoParser.Build(AFileInfo: TclFtpFileInfo): string;
begin
Assert(False, 'Not implemented');
end;
function TclAs400FileInfoParser.Check(const ASource: string): Boolean;
var
s: string;
begin
if (WordCount(ASource, [#32]) > 5) then
begin
s := Trim(ExtractWord(5, ASource, [#32]));
Result := (s[1] = '*') or (s = 'DIR');
end else
if (WordCount(ASource, [#32]) > 2) then
begin
s := Trim(ExtractWord(2, ASource, [#32]));
Result := (s[1] = '*') or (s = 'DIR');
end else
begin
Result := False;
end;
end;
procedure TclAs400FileInfoParser.Parse(AFileInfo: TclFtpFileInfo; const ASource: string);
var
ind: Integer;
s: string;
begin
if (WordCount(ASource, [#32]) > 5) then
begin
AFileInfo.Size := StrToInt64Def(Trim(ExtractWord(2, ASource, [#32])), 0);
AFileInfo.ModifiedDate := ParseDate(Trim(ExtractWord(3, ASource, [#32]))) + ParseTime(Trim(ExtractWord(4, ASource, [#32])));
s := Trim(ExtractWord(5, ASource, [#32]));
AFileInfo.IsDirectory := (s = '*FILE') or (s = 'DIR');
ind := WordPosition(6, ASource, [#32]);
if (ind > 0) then
begin
AFileInfo.FileName := system.Copy(ASource, ind, 10000);
end;
end else
if (WordCount(ASource, [#32]) > 2) then
begin
s := Trim(ExtractWord(2, ASource, [#32]));
AFileInfo.IsDirectory := (s = '*FILE') or (s = 'DIR');
ind := WordPosition(3, ASource, [#32]);
if (ind > 0) then
begin
AFileInfo.FileName := system.Copy(ASource, ind, 10000);
end;
end;
end;
function TclAs400FileInfoParser.ParseDate(const ASrc: string): TDateTime;
procedure Exchange(var arg1, arg2: Integer);
var
temp: Integer;
begin
temp := arg2;
arg2 := arg1;
arg1 := temp;
end;
var
m, d, y: Integer;
delim: Char;
begin
delim := GetDelimiter(ASrc);
d := StrToIntDef(Trim(ExtractWord(1, ASrc, [delim])), 0);
m := StrToIntDef(Trim(ExtractWord(2, ASrc, [delim])), 0);
y := StrToIntDef(Trim(ExtractWord(3, ASrc, [delim])), 0);
y := GetCorrectY2k(y);
if (m > 12) then
begin
Exchange(d, m);
end;
if (d > 31) then
begin
Exchange(y, d);
end;
{$IFDEF DELPHI6}
if not TryEncodeDate(y, m, d, Result) then
begin
Result := 0;
end;
{$ELSE}
try
Result := EncodeDate(y, m, d);
except
Result := 0;
end;
{$ENDIF}
end;
{ TclFtpFileInfoParser }
function TclFtpFileInfoParser.GetDelimiter(const ASrc: string): Char;
var
i: Integer;
begin
for i := 1 to Length(ASrc) do
begin
Result := ASrc[i];
if not (Result in ['0'..'9']) then Exit;
end;
Result := #0;
end;
function TclFtpFileInfoParser.ParseTime(const ASrc: string): TDateTime;
var
pm, am: Integer;
s: string;
delim: Char;
h, m, sec: Word;
begin
s := UpperCase(ASrc);
pm := system.Pos('PM', s);
am := system.Pos('AM', s);
sec := 0;
if (pm > 0) then
begin
s := system.Copy(s, 1, pm - 1);
end;
if (am > 0) then
begin
s := system.Copy(s, 1, am - 1);
end;
s := Trim(s);
delim := GetDelimiter(s);
h := StrToIntDef(ExtractWord(1, s, [delim]), 0);
m := StrToIntDef(ExtractWord(2, s, [delim]), 0);
if (WordCount(s, [delim]) > 2) then
begin
sec := StrToIntDef(ExtractWord(3, s, [delim]), 0);
end;
if (pm > 0) then
begin
if h < 12 then
begin
h := h + 12;
end;
end;
if (am > 0) then
begin
if h = 12 then
begin
h := 0;
end;
end;
{$IFDEF DELPHI6}
if not TryEncodeTime(h, m, sec, 0, Result) then
begin
Result := 0;
end;
{$ELSE}
try
Result := EncodeTime(h, m, sec, 0);
except
Result := 0;
end;
{$ENDIF}
end;
initialization
RegisterFtpFileInfoParser(TclMsDosFileInfoParser.Create());
RegisterFtpFileInfoParser(TclUnixFileInfoParser.Create());
RegisterFtpFileInfoParser(TclAs400FileInfoParser.Create());
finalization
RegisteredFtpFileInfoParsers.Free();
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -