[fpc-pascal] Is there a Pos() function for TBytes?

Bo Berglund bo.berglund at gmail.com
Thu Apr 20 11:19:50 CEST 2023


On Thu, 20 Apr 2023 08:40:48 +0200 (CEST), Michael Van Canneyt via fpc-pascal
<fpc-pascal at lists.freepascal.org> wrote:

>> I found this page:
>> https://www.freepascal.org/docs-html/rtl/system/copy.html
>>
>> Here there is also reference to the other functions for strings:
>> Delete  (string and dyn array)
>> Copy    (string and dyn array)
>> Insert  (string and dyn array but limited to 255 elements, why?)
>> Pos     (string only..)
>>
>> They describe what can be done with strings and in some cases dynamic arrays
>> (like TBytes?), but for Pos() there is only string...
>>
>> And Insert seems to have a limit of 255 elements, why?
>>
>> What I need is a Pos(token) for TBytes where the token can be a single or
>> multiple bytes in size (just like for strings).
>>
>> Is there such a thing?
>
>Not that I am aware of, but I think it would be a welcome addition to one of
>the RTL units. I've been in need of such a function on multiple occasions,
>and had to resort to custom code each time.
>

FWIW, I threw together two overloaded Pos functions for a TBytes container like
this (except I didn't name them Pos in order not to interfere with the RTL):

function PosInBytes(const Pattern, Target: TBytes): integer; overload;
function PosInBytes(const Pattern: byte; const Target: TBytes): integer;
overload;

implementation

function PosInBytes(const Pattern, Target: TBytes): integer;
var
  i, j, res: integer;
begin
  Result := -1;
  for i := 0 to Length(Target) - 1 - Length(Pattern) do
  begin
    if Target[i] = Pattern[0] then  //First byte of pattern found
    begin
      res := i;
      for j := 1 to Length(Pattern)-1 do
      begin
        if Target[i+j] <> Pattern[j] then
        begin
          res := -1;
          break;
        end;
      end;
      if res >= 0 then break;
    end;
  end;
  Result := res;
end;

function PosInBytes(const Pattern: byte; Target: TBytes): integer;
var
  i: integer;
begin
  Result := -1;
  for i :=  0 to Length(Target) - 1 do
  begin
    if Target[i] = Pattern then
    begin
      Result := i;
      break;
    end;
  end;
end;


-- 
Bo Berglund
Developer in Sweden



More information about the fpc-pascal mailing list