home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 September / Chip_2001-09_cd1.bin / zkuste / delphi / nastroje / d5 / MFTP.ZIP / src / FTPMISC.PAS < prev    next >
Pascal/Delphi Source File  |  2001-01-07  |  13KB  |  628 lines

  1. unit FtpMisc;
  2.  
  3. interface
  4.  
  5. uses SysUtils, Windows;
  6.  
  7. {$I mftp.inc}
  8.  
  9. {$ifdef OPTIMIZATION}
  10. const
  11.   SumMonthDays: array [Boolean] of TDayTable =
  12.      ((0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334),
  13.      (0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335));
  14. {$endif}
  15.  
  16. const
  17.    EOS = #0;
  18.  
  19. function fnmatch(Pattern, Filename: PChar; P: Boolean = False): Boolean;
  20.  
  21. function PrepareURL(S: String): String;
  22. function BuildFTPTopURL(Server: String; Port: Integer; Username, Password: String): String;
  23.  
  24. function DOSName2UnixName(S: String): String;
  25. function FormatMTime(S: String): String;
  26. function FormatNTime(S: String): String;
  27. function FormatNTTime(D, T: String): String;
  28. function GetTempFilename: String;
  29. function UnformatInteger(S: String): Integer;
  30.  
  31. function ReplaceInvalidChars(const S: string; RepWith: Char): String; {BDS}
  32.  
  33. {$ifdef COMPATIBLE}
  34. function FormatInteger(I: Integer): String;
  35. function FormatIntegerStr(S: String): String;
  36. {$endif}
  37.  
  38. {$ifdef OPTIMIZATION}
  39. function optimizedAnsiCompareText(const S1, S2: String): Integer;
  40. function optimizedEncodeDate(Year, Month, Day: Integer): Integer;
  41. procedure optimizedDecodeDate(Date: TDateTime; var Year, Month, Day: Word);
  42. {$endif}
  43.  
  44. {$ifndef DELPHI5}
  45. procedure FreeAndNil(var Obj);
  46. {$endif}
  47.  
  48. function GetWindowsDirectory: String;
  49.  
  50. implementation
  51.  
  52. var Temp, CurrentYear: Word;
  53.     TempDir, WinDir, CYS: String;
  54.     PS: PChar;
  55.  
  56. function PrepareURL;
  57. var i, c: Integer;
  58. begin
  59.    i := Pos('%', S);
  60.  
  61.    while i > 0 do
  62.    begin
  63.       Result := Result + Copy(S, 1, i - 1);
  64.       Delete(S, 1, i);
  65.  
  66.       if S = '' then
  67.       begin
  68.          Result := Result + '%';
  69.          Exit;
  70.       end;
  71.  
  72.       case Ord(S[1]) of
  73.          48..57: c := Ord(S[1]) - 48;
  74.          65..70: c := Ord(S[1]) - 55;
  75.          97..102: c := Ord(S[1]) - 87;
  76.          else
  77.          begin
  78.             c := -1;
  79.             Result := Result + S[1];
  80.          end;
  81.       end;
  82.  
  83.       Delete(S, 1, 1);
  84.  
  85.       if (c <> -1) and (S <> '') then
  86.       begin
  87.          case Ord(S[1]) of
  88.             48..57: Result := Result + Chr(c * 16 + (Ord(S[1]) - 48));
  89.             65..70: Result := Result + Chr(c * 16 + (Ord(S[1]) - 55));
  90.             97..102: Result := Result + Chr(c * 16 + (Ord(S[1]) - 87));
  91.             else Result := Result + Chr(c) + S[1];
  92.          end;
  93.  
  94.          Delete(S, 1, 1);
  95.       end;
  96.  
  97.       i := Pos('%', S);
  98.    end;
  99.  
  100.    Result := Result + S;
  101. end;
  102.  
  103. function BuildFTPTopURL;
  104. begin
  105.    Result := 'ftp://';
  106.  
  107.    if (not (LowerCase(Username) = 'anonymous')) and (not (LowerCase(Username) = 'ftp')) then
  108.       Result := Result + Username + ':' + Password + '@';
  109.  
  110.    Result := Result + Server;
  111.    if Port <> 21 then Result := Result + ':' + IntToStr(Port);
  112. end;
  113.  
  114. function DOSName2UnixName;
  115. begin
  116.    if S[1] = '/' then
  117.    begin
  118.       Result := Copy(S, 4, 999);
  119.    end
  120.    else
  121.    begin
  122.       Result := Copy(S, 3, 999);
  123.  
  124.       Temp := Pos('\', Result);
  125.       while Temp <> 0 do
  126.       begin
  127.          Result[Temp] := '/';
  128.          Temp := Pos('\', Result);
  129.       end;
  130.    end;
  131. end;
  132.  
  133. function FormatMTime;
  134. var  P: Integer;
  135.      TS: TTimeStamp;
  136.      TD: TDateTime;
  137. begin
  138.    try
  139.       P := StrToInt(S);
  140.       TS.Time := (P mod 86400) * 1000;
  141.       TS.Date := P div 86400 + 719163;
  142.       TD := TimeStampToDateTime(TS);
  143.       {$ifndef Y2K_DATE}
  144.       Result := FormatDateTime('mm/dd/yy hh:mm', TD);
  145.       {$else}
  146.       Result := FormatDateTime('mm/dd/yyyy hh:mm', TD);
  147.       {$endif}
  148.    except
  149.       Result := DefaultDateTime;
  150.    end;
  151. end;
  152.  
  153. function FormatNTime;
  154. var Year, Month, Day: String;
  155.     Times: String;
  156.     I: Integer;
  157. begin
  158.    try
  159.       case S[1] of
  160.          'J':
  161.             if S[2] = 'a' then Month := '1' else
  162.             if S[3] = 'n' then Month := '6' else Month := '7';
  163.          'F':
  164.             Month := '2';
  165.          'M':
  166.             if S[3] = 'r' then Month := '3' else Month := '5';
  167.          'A':
  168.             if S[2] = 'p' then Month := '4' else Month := '8';
  169.          'S':
  170.             Month := '9';
  171.          'O':
  172.             Month := '10';
  173.          'N':
  174.             Month := '11';
  175.          'D':
  176.             Month := '12';
  177.       end;
  178.  
  179.       I := Pos(' ', S);
  180.       Delete(S, 1, I);
  181.       while S[1] = ' ' do Delete(S, 1, 1);
  182.       Day := Trim(Copy(S, 1, 2));
  183.       // if Length(Day) = 1 then Day := Day;
  184.  
  185.       if S[3] = ' ' then Delete(S, 1, 3) else Delete(S, 1, 2);
  186.  
  187.       I := Pos(':', S);
  188.       if I = 0 then
  189.       begin
  190.          Year := Trim(S);
  191.          {$ifndef Y2K_DATE}
  192.          Delete(Year, 1, 2);
  193.          {$endif}
  194.          Times := '12:00 AM';
  195.       end
  196.       else
  197.       begin
  198.          Year := CYS;
  199.          Times := Trim(S);
  200.          if Length(Times) = 5 then
  201.          begin
  202.             I := StrToInt(Copy(Times, 1, 2));
  203.             if I > 12 then
  204.             begin
  205.                Delete(Times, 1, 2);
  206.                Times := IntToStr(I - 12) + Times + ' PM';
  207.             end
  208.             else
  209.             begin
  210.                Times := Times + ' AM';
  211.             end;
  212.             if Times[1] = '0' then Delete(Times, 1, 1);
  213.          end
  214.          else
  215.          begin
  216.             Times := Times + ' AM';
  217.          end;
  218.       end;
  219.  
  220.       Result := Month + '/' + Day + '/' + Year + ' ' + Times;
  221.    except
  222.       Result := DefaultDateTime;
  223.    end;
  224. end;
  225.  
  226. function FormatNTTime;
  227. begin
  228.    D[3] := '/';
  229.    D[6] := '/';
  230.    Result := D + ' ' + Copy(T, 1, 5) + ' ' + Copy(T, 6, 2);
  231. end;
  232.  
  233. function GetTempFilename;
  234. var N: LongWord;
  235. begin
  236.    Randomize;
  237.    repeat
  238.       N := Random(1000000000);
  239.       Result := TempDir + IntToStr(N);
  240.    until (not FileExists(Result));
  241. end;
  242.  
  243. function UnformatInteger;
  244. var R: String;
  245.     I: Integer;
  246. begin
  247.    for I := 1 to Length(S) do
  248.       if S[I] <> ',' then R := R + S[I];
  249.  
  250.    Result := StrToInt(R);
  251. end;
  252.  
  253. {$ifdef COMPATIBLE}
  254. function FormatInteger;
  255. begin
  256.    try
  257.       result := FormatIntegerStr(IntToStr(i));
  258.    except
  259.       result := '';
  260.    end;
  261. end;
  262.  
  263. function FormatIntegerStr;
  264. var s1: string;
  265.     l, p: integer;
  266. begin
  267.    Result := '';
  268.    s1 := Trim(s);
  269.    l := Length(s1);
  270.    for p := 1 to l do
  271.    begin
  272.       Result := s1[l + 1 - p] + Result;
  273.       if (p mod 3 = 0) and (p <> l) then
  274.          Result := ',' + Result;
  275.    end;
  276. end;
  277. {$endif}
  278.  
  279. function ReplaceInvalidChars;
  280. { These are Win32 specific. They are bad for Win16, too, but there are
  281.   a lot more in Win16. }
  282. const InvalidChars = ['?', '*', '/', '\', ':', '"'];
  283. var x: integer;
  284. begin
  285.    Result := S;
  286.    for x := 1 to Length(Result) do
  287.    begin
  288.       if Result[x] in InvalidChars then
  289.          if (Result[x] = '/') or (Result[x] = '\') then
  290.             Result[x] := '-'
  291.          else
  292.             Result[x] := RepWith;
  293.    end;
  294. end;
  295.  
  296. {$ifdef OPTIMIZATION}
  297. function optimizedAnsiCompareText;
  298. asm
  299.    test EAX,EAX
  300.    jne @@nzs1
  301.    test EDX,EDX
  302.    jz @@konec
  303.    dec EAX
  304.    jmp @@konec
  305.  
  306. @@nzs1:
  307.    test EDX,EDX
  308.    jne @@nzs1s2
  309.    mov EAX,1
  310.    jmp @@konec
  311.  
  312. @@nzs1s2:
  313.    push -1
  314.    push EDX
  315.    push -1
  316.    push EAX
  317.    push NORM_IGNORECASE
  318.    push LOCALE_USER_DEFAULT
  319.    call CompareString
  320.    sub EAX,2
  321. @@konec:
  322. end;
  323.  
  324.  
  325. function optimizedEncodeDate;
  326. asm
  327.    push EBX
  328.    mov EBX, EAX
  329.    imul EAX, EDX, 31
  330.    add EAX, ECX
  331.    mov ECX, EBX
  332.    sub EAX, 396 + DateDelta //31 + 365 + DateDelta
  333.    imul ECX, 365
  334.    add EAX, ECX
  335.    cmp EDX, 3
  336.    jl @@decyear
  337.    imul EDX, 7
  338.    sub EAX, 2
  339.    sar EDX, 4
  340.    sub EAX, EDX
  341.    jmp @@calc
  342. @@decyear:
  343.    dec EBX
  344. @@calc:
  345.    sar EBX, 2
  346.    add EAX, EBX
  347.    imul EBX, 5243
  348.    sar EBX, 17
  349.    sub EAX, EBX
  350.    sar EBX, 2
  351.    add EAX, EBX
  352.    pop EBX
  353. end;
  354.  
  355. procedure optimizedDecodeDate;
  356. const
  357.    D1 = 365;
  358.    D4 = D1 * 4 + 1;
  359.    D100 = D4 * 25 - 1;
  360.    D400 = D100 * 4 + 1;
  361. var
  362.    Y,M,D: Integer;
  363. begin
  364.    D := Trunc(Date) + (DateDelta - 1);
  365.    if D < 0 then exit;
  366.  
  367.    asm
  368.       mov EAX, D
  369.       mov ECX, 1
  370.       cmp EAX, 16 * D400
  371.       jb @@za0
  372.       sub EAX, 16 * D400
  373.       add ECX, 16 * 400
  374.  
  375.    @@za0:
  376.       cmp EAX, 8 * D400
  377.       jb @@za01
  378.       sub EAX, 8 * D400
  379.       add ECX, 8 * 400
  380.  
  381.    @@za01:
  382.       cmp EAX, 4 * D400
  383.       jb @@za02
  384.       sub EAX, 4 * D400
  385.       add ECX, 4 * 400
  386.    
  387.    @@za02:
  388.       cmp EAX, 2 * D400
  389.       jb @@za03
  390.       sub EAX, 2 * D400
  391.       add ECX, 2 * 400
  392.  
  393.    @@za03:
  394.       cmp EAX, D400
  395.       jb @@za04
  396.       sub EAX, D400
  397.       add ECX, 400
  398.    @@za04:
  399.  
  400.       cmp EAX, 2 * D100
  401.       jb @@za1
  402.       sub EAX, 2 * D100
  403.       add ECX, 2 * 100
  404.  
  405.    @@za1:
  406.       cmp EAX, D100
  407.       jb @@za11
  408.       sub EAX, D100
  409.       add ECX, 100
  410.  
  411.    @@za11:
  412.       cmp EAX, 16 * D4
  413.       jb @@za3
  414.       sub EAX, 16 * D4
  415.       add ECX, 16 * 4
  416.  
  417.    @@za3:
  418.       cmp EAX, 8 * D4
  419.       jb @@za31
  420.       sub EAX, 8 * D4
  421.       add ECX, 8 * 4
  422.  
  423.    @@za31:
  424.       cmp EAX, 4 * D4
  425.       jb @@za32
  426.       sub EAX, 4 * D4
  427.       add ECX, 4 * 4
  428.  
  429.    @@za32:
  430.       cmp EAX, 2 * D4
  431.       jb @@za33
  432.       sub EAX,2 * D4
  433.       add ECX,2 * 4
  434.  
  435.    @@za33:
  436.       cmp EAX, D4
  437.       jb @@za34
  438.       sub EAX, D4
  439.       add ECX, 4
  440.  
  441.       @@za34:
  442.       cmp EAX, 2 * D1
  443.       jb @@za2
  444.       sub EAX, 2 * D1
  445.       add ECX, 2
  446.  
  447.    @@za2:
  448.       cmp EAX, D1
  449.       jb @@za21
  450.       sub EAX, D1
  451.       inc ECX
  452.  
  453.    @@za21:
  454.       mov D, EAX
  455.       mov Y, ECX
  456.    end;
  457.   Year:=Y;
  458.   if ((Y and 3)=0) and ((LongWord(Y) mod LongWord(100)<>0) or (LongWord(Y) mod LongWord(400)=0)) then begin
  459.    if D<182 then begin
  460.     if D<91 then begin
  461.      if D<60 then if D<31 then M:=1 else M:=2 else M:=3;
  462.     end else begin
  463.      if D<152 then if D<121 then M:=4 else M:=5 else M:=6;
  464.     end;
  465.    end else begin
  466.     if D<274 then begin
  467.      if D<244 then if D<213 then M:=7 else M:=8 else M:=9;
  468.     end else begin
  469.      if D<335 then if D<305 then M:=10 else M:=11 else M:=12;
  470.     end;
  471.    end;
  472.    Day:=D-SumMonthDays[true,M]+1;
  473.   end else begin
  474.    if D<181 then begin
  475.     if D<90 then begin
  476.      if D<59 then if D<31 then M:=1 else M:=2 else M:=3;
  477.     end else begin
  478.      if D<151 then if D<120 then M:=4 else M:=5 else M:=6;
  479.     end;
  480.    end else begin
  481.     if D<273 then begin
  482.      if D<243 then if D<212 then M:=7 else M:=8 else M:=9;
  483.     end else begin
  484.      if D<334 then if D<304 then M:=10 else M:=11 else M:=12;
  485.     end;
  486.    end;
  487.    Day:=D-SumMonthDays[false,M]+1;
  488.   end;
  489.   Month:=M;
  490. end;
  491.  
  492. function optimizedDate: TDateTime;
  493. var SystemTime:TSystemTime;
  494. begin
  495.    GetLocalTime(SystemTime);
  496.    with SystemTime do Result := optimizedEncodeDate(wYear,wMonth,wDay);
  497. end;
  498. {$endif}
  499.  
  500. function fnmatch;
  501. begin
  502.    if P then
  503.    begin
  504.       if Pattern^ = '?' then
  505.       begin
  506.          Inc(Filename);
  507.       end
  508.       else
  509.       begin
  510.          while Filename^ <> Pattern^ do
  511.          begin
  512.             if Filename^ = EOS then
  513.             begin
  514.                Result := False;
  515.                Exit;               
  516.             end;
  517.   
  518.             Inc(Filename);
  519.          end;
  520.       end;
  521.    end;
  522.  
  523.    while Filename^ <> EOS do
  524.    begin
  525.       case Pattern^ of
  526.          EOS:
  527.          begin
  528.             Result := (Filename^ = EOS);
  529.             Exit;
  530.          end;
  531.  
  532.          '?':
  533.          begin
  534.             if Filename^ = EOS then
  535.             begin
  536.                Result := False;
  537.                Exit;
  538.             end;
  539.  
  540.             Inc(Filename);
  541.          end;
  542.  
  543.          '*':
  544.          begin
  545.             while Pattern^ = '*' do Inc(Pattern);
  546.  
  547.             if Pattern^ = EOS then
  548.             begin
  549.                Result := True;
  550.                Exit;
  551.             end;
  552.  
  553.             while Pattern^ <> EOS do
  554.             begin
  555.                if fnmatch(Pattern, Filename, True) then
  556.                begin
  557.                   Result := True;
  558.                   Exit;
  559.                end
  560.                else
  561.                begin
  562.                   Inc(Filename);
  563.                   if Filename^ = EOS then
  564.                   begin
  565.                      Result := False;
  566.                      Exit;
  567.                   end;
  568.                end;
  569.             end;
  570.  
  571.             Result := False;
  572.             Exit;
  573.          end;
  574.  
  575.          else
  576.          begin
  577.             if Filename^ <> Pattern^ then
  578.             begin
  579.                Result := False;
  580.                Exit;
  581.             end;
  582.             Inc(Filename);
  583.          end;
  584.       end;
  585.  
  586.       Inc(Pattern);
  587.    end;
  588.  
  589.    Result := (Pattern^ = EOS);
  590. end;
  591.  
  592. {$ifndef DELPHI5}
  593. procedure FreeAndNil;
  594. var
  595.    P: TObject;
  596. begin
  597.    P := TObject(Obj);
  598.    TObject(Obj) := nil;  // clear the reference before destroying the object
  599.    P.Free;
  600. end;
  601. {$endif}
  602.  
  603. function GetWindowsDirectory: String;
  604. begin
  605.    Result := WinDir;
  606. end;
  607.  
  608. initialization
  609.    {$ifdef OPTIMIZATION}
  610.    optimizedDecodeDate(optimizedDate, CurrentYear, Temp, Temp);
  611.    {$else}
  612.    DecodeDate(Date, CurrentYear, Temp, Temp);
  613.    {$endif}
  614.    CYS := IntToStr(CurrentYear);
  615.    {$ifndef Y2K_DATE}
  616.    Delete(CYS, 1, 2);
  617.    {$endif}
  618.  
  619.    GetMem(PS, 254);
  620.    Windows.GetWindowsDirectory(PS, 254);
  621.    WinDir := StrPas(PS);
  622.    GetTempPath(254, PS);
  623.    TempDir := StrPas(PS);
  624.  
  625. finalization
  626.    FreeMem(PS);
  627. end.
  628.