How to search an array of bytes for "StringA"?

Go To StackoverFlow.com

3

Using FreePascal (or Delphi if no FP examples), given a 2048 byte buffer that is as an "array of bytes", how can I search the buffer for "StringA"?

var
Buffer : array[1..2048] of byte;
...
  repeat
      i := 0;
      BlockRead(SrcFile, Buffer, SizeOf(Buffer), NumRead);      
      // Now I want to search the buffer for "StringA"? 
...

Thankyou

2012-04-04 20:27
by Gizmo_the_Great


6

I think this will work in fpc without extra Unicode/AnsiString conversion :

function Find(const buf : array of byte; const s : AnsiString) : integer;
//returns the 0-based index of the start of the first occurrence of S
//or -1 if there is no occurrence
var
  AnsiStr : AnsiString;
begin
  SetString(AnsiStr, PAnsiChar(@buf[0]), Length(buf));
  Result := Pos(s,AnsiStr) - 1;  // fpc has AnsiString overload for Pos()
end;
2012-04-04 21:08
by LU RD
+1 rather neat in my vie - David Heffernan 2012-04-04 21:14
Thankyou once again LURD. That works and is easy (ish) for me to understand! It does indeed work. My only problem (and it's for another question) is that the offset values returned are, of course, of each buffered segment, and are not relative to the position where it was found in the original source file. So the first hit, if it happens to be located within the source file and the first buffer read, match the offset of the source file. But after that, it is relative to the buffer and bears no resemblance to the original source file offset. I will think about that. Thanks again - Gizmo_the_Great 2012-04-04 21:29


4

Here's the naïve approach whereby we simply walk through the buffer byte by byte looking for the desired string.

function Find(const Buffer: array of Byte; const S: AnsiString): Integer;
//returns the 0-based index of the start of the first occurrence of S
//or -1 if there is no occurrence
var
  N: Integer;
begin
  N := Length(S);
  if N>0 then
    for Result := low(Buffer) to high(Buffer)-(N-1) do
      if CompareMem(@Buffer[Result], Pointer(S), N) then
        exit;
  Result := -1;
end;

I don't use FPC but I expect that this will work unchanged and if not then I'm sure you can convert it.

2012-04-04 20:35
by David Heffernan
FPC also has an one byte searching, architecture independent primitive called "indexbyte". This can be used to search for the first byte, and only then do comparemem. It is the basis for the generic implementation of e.g. POS( - Marco van de Voort 2012-04-06 09:23
Ads