Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Validating COM or URL string


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Jan 12, 2017 1:45 PM Last Post By: Remy Lebeau (Te...
Fred Smith

Posts: 81
Registered: 12/4/15
Validating COM or URL string  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 12, 2017 7:08 AM
This funciton checks a string to see if it contains a valid IP address or port number.
Currently it only check ports numbers up to 9. Which is the best & efficient way to change it so it check port numbers up to 99 ?
Thanks

function ValidComOrURLString(const testStr: string): boolean;
var
  sl: TStringList;
  cntr: integer;
  urlBit: integer;
  chk: string;
begin
  Result := False;
  chk := UpperCase(testStr);
  if Length(chk) < 4 then
    Exit;
  if chk[1] = 'C' then
  begin
    Result := (Length(chk) = 4) and (Copy(chk, 1, 3) = 'COM') and (chk[4] in ['0'..'9'])
  end
  else if chk[1] in ['0'..'9'] then
  begin
    sl := TStringList.Create;
    sl.Delimiter := '.';
    sl.StrictDelimiter := True;
    sl.DelimitedText := chk;
    if sl.Count = 4 then
    begin
      Result := True;
      for Cntr := 0 to 3 do
      begin
        urlBit := StrToIntDef(sl[Cntr], -1);
        if (urlBit = -1) or (urlBit > 255) then
        begin
          Result := False;
          Break;
        end;
      end;
    end;
    sl.Free;
  end;
end;
Peter Below

Posts: 1,227
Registered: 12/16/99
Re: Validating COM or URL string  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 12, 2017 10:39 AM   in response to: Fred Smith in response to: Fred Smith
Fred Smith wrote:

This funciton checks a string to see if it contains a valid IP
address or port number. Currently it only check ports numbers up to
9. Which is the best & efficient way to change it so it check port
numbers up to 99 ? Thanks

You should learn how to use the Delphi TRegEx class from the
System.RegularExpressions unit. With it you can rewrite your
function as a one-liner:
 function ValidComOrURLString(const testStr: string): boolean;
 begin
    Result := TRegex.IsMatch(testStr, '^COM[0-9]{1,2}$');
 end;


--
Peter Below
TeamB

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Validating COM or URL string  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 12, 2017 1:45 PM   in response to: Fred Smith in response to: Fred Smith
Fred wrote:

This funciton checks a string to see if it contains a valid IP address
or port number.

Not particularly well, though.

Currently it only check ports numbers up to 9.

Because you are only looking at one character.

Which is the best & efficient way to change it so it check port
numbers up to 99 ?

Try something more like this:

uses
  ..., StrUtils;
 
function ValidComOrURLString(const testStr: string): boolean;
var
  sl: TStringList;
  cntr: integer;
  urlBit: integer;
begin
  Result := False;
  if Length(testStr) < 4 then
    Exit;
  if StartsText('COM', testStr) then
  begin
    Result := StrToIntDef(Copy(testStr, 4, MaxInt), 0) > 0;
  end
  else if testStr[1] in ['0'..'9'] then
  begin
    sl := TStringList.Create;
    try
      sl.Delimiter := '.';
      sl.StrictDelimiter := True;
      sl.DelimitedText := testStr;
      if sl.Count = 4 then
      begin
        for Cntr := 0 to 3 do
        begin
          urlBit := StrToIntDef(sl[Cntr], -1);
          if (urlBit < 0) or (urlBit > 255) then
            Exit;
        end;
        Result := True;
      end;
    finally
      sl.Free;
    end;
  end;
end;


Which could be greatly simplified by letting the OS parse the IP address
for you, such as with the inet_addr() function:

uses
  ...,
  StrUtils,
  Winsock // or replace this with appropriate cross-platform unit(s) ...
  ;
 
function ValidComOrURLString(const testStr: string): boolean;
begin
  Result := False;
  if Length(testStr) >= 4 then
  begin
    if StartsText('COM', testStr) then
      Result := (StrToIntDef(Copy(testStr, 4, MaxInt), 0) > 0)
    else
      Result := (inet_addr(PAnsiChar(AnsiString(testStr))) <> INADDR_NONE);
  end;
end;


Alternatively, use the inet_pton() or getaddrinfo() function if you need
to support both IPv4 and IPv6 addresses:

uses
  ...,
  StrUtils,
  // appropriate unit(s) for inet_pton ...
  ;
 
function ValidComOrURLString(const testStr: string): boolean;
var
  in4: IN_ADDR;
  in6: IN6_ADDR;
begin
  if StartsText('COM', testStr) then
    Result := (StrToIntDef(Copy(testStr, 4, MaxInt), 0) > 0)
  else
    Result := (inet_pton(PF_INET, PChar(testStr), @in4) = 1) or
                 (inet_pton(PF_INET6, PChar(testStr), @in6) = 1);
end;


uses
  ...,
  StrUtils,
  // appropriate unit(s) for getaddrinfo() ...
  ;
 
function ValidComOrURLString(const testStr: string): boolean;
var
  hints: addrinfo;
  pAddr: paddrinfo;
begin
  if StartsText('COM', testStr) then
    Result := (StrToIntDef(Copy(testStr, 4, MaxInt), 0) > 0)
  else
  begin
    FillChar(@hints, 0, SizeOf(hints));
    hints.ai_flags := AI_NUMERICHOST;
    hints.ai_family := AF_UNSPEC;
    Result := getaddrinfo(PAnsiChar(AnsiString(testStr)), nil, @hints, @pAddr) 
= 0;
    if Result then
    begin
      Result := pAddr.ai_family in [AF_INET, AF_INET6];
      freeaddrinfo(pAddr);
    end;
  end;
end;


--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02