Разбор адреса FTP

Материал из DRKB


{ **** UBPFD *********** by kladovka.net.ru ****
>> Разбор адреса FTP

Функция анализирует строку aSrc и если в стоке дан корректный адрес FTP, возвращает имя пользователя, пароль, хост, порт и каталог. Если дан некорректный адрес, функция возвращает false, иначе - true.
Учтена возможность, когда в адресе не указываются некоторые параметры. В этом случае, если нотация соблюдена, опущенные параметры возвращаются пустыми строками.

Минимально подробный адрес: ftp://myftp.ru - В этом случае будет возвращён адрес, порт по умолчанию (21) и true.
Максимально подробный адрес: ftp://MyLogin:MyPassword@MyFtp.ru:6000/MyDirectory/ - Будут возвращены все параметры и true.

Зависимости: Classes, SysUtils

Copyright:   Роман Василенко
Дата:        13 июня 2004 г.
********************************************** }

function ParseFTP(aSrc: string; out oUserName, oPassword, oHost: string;
  out oPort: word; out oDir: string): boolean;
const
  ssPrefix = 0;
  ssUserName = 1;
  ssPassword = 2;
  ssHost = 3;
  ssPort = 4;
  ssDir = 5;
var
  f, StrState: Integer;
  sPort, pfx: string;
begin
  oUserName := '';
  oPassword := '';
  oHost := '';
  sPort := '';
  oPort := 21;
  oDir:='';
  StrState := ssPrefix;
  Result := False;
  f := 1;
  repeat
    case StrState of
      ssPrefix: // Разбор префикса ftp:// и определение анонимности адреса
        if aSrc[f] <> ':' then
          pfx := pfx + aSrc[f]
        else
        begin
          if (AnsiSameText(Trim(pfx), 'ftp'))
          and (aSrc[f] + aSrc[f + 1] + aSrc[f + 2] = '://') then
          begin
            if Pos('@', aSrc) < 1 then
              StrState := ssHost // Anonymous
            else
              StrState := ssUserName; // UserName[:Password]
            Inc(f, 2);
          end
          else break;
        end;
      ssUserName: // Извлечение имени пользователя
        if aSrc[f] = '@' then // Пароль не указан
          StrState := ssHost
        else
          if aSrc[f] = ':' then // Пароль указан
            StrState := ssPassword
          else
            oUserName := oUserName + aSrc[f];
      ssPassword: // Извлечение пароля
        if aSrc[f] = '@' then
          StrState := ssHost
        else
          oPassword := oPassword + aSrc[f];
      ssHost: // Извлечение хоста
        if aSrc[f] = ':' then // Порт указан
          StrState := ssPort
        else
          if aSrc[f] = '/' then // Порт не указан, возможно указан каталог
            StrState := ssDir
          else
            oHost := oHost + aSrc[f];
      ssPort: // Извлечение порта
        if aSrc[f] = '/' then
          StrState := ssDir
        else
          sPort := sPort + aSrc[f];
      ssDir:
        oDir := oDir + aSrc[f];
    end;
    Inc(f);
  until f > Length(aSrc);
  if (StrState > ssPassword) and (Trim(oHost) <> '') then
    Result := True;
  try
    if Trim(sPort) <> '' then
      oPort := StrToInt(sPort);
  except
    Result := False;
  end;
end;


Пример использования:

procedure TForm1.Button1Click(Sender: TObject);
const
  yn: array[false..true] of string=('INVALID', 'VALID');
var
  xValid: boolean;
  xUser, xPassword, xHost, xDir: string;
  xPort: word;
begin
  xValid := ParseFTP(Edit1.Text, xUser, xPassword, xHost, xPort, xDir);
  ShowMessage(Format('Address is %s'#13#13'Host: %s'#13'Port: %d'#13+
      'Dir: %s'#13'User: %s'#13'Password: %s',
      [yn[xValid], xHost, xPort, xDir, xUser, xPassword]));
end;


Author: Роман Василенко
ID: 03379