Introduction

ATStreamSearch Component

ATStreamSearch is a Delphi/C++Builder non-visual component which implements text searching functionality. You set the FileName or Stream property and then call FindFirst/FindNext methods to perform search with needed options. Streams and files can be of unlimited size (Int64) - even for RegEx search!

Search options supported are:

  • Case Sensitive
  • Whole Words
  • Backward Search (not for RegEx mode)
  • RegEx (available only when DIRegEx library is used)

Text encodings currently supported are:

  • ANSI
  • OEM
  • EBCDIC
  • KOI8
  • ISO
  • Mac
  • Unicode (UCS-2) LE and BE
  • Plus many others

Screenshot of demo application


Installation

To install the component in the Delphi/C++Builder IDE:
  • Create a new package
  • Add ATStreamSearch.pas file to this package
  • Compile and install this package

Component will be installed into the "Samples" page of component pallette.


Additional libraries used

Additional optional third-party libraries used in ATStreamSearch are:

  1. DIRegEx: used for RegEx (regular expressions) search. asoRegEx search option is available only when this library is compiled in. After you install this library, enable its usage in file ATStreamSearchOptions.inc, uncomment the "REGEX" define.

  2. Tnt Unicode Controls: used for search in Unicode-named files (TTntFileStream class is used). After you install this library, enable its usage in file ATStreamSearchOptions.inc, uncomment the "TNT" define.

Download links for mentioned libraries are listed in Copyrights topic.


Usage: Properties

Properties

FileName (public) | File name (WideString). Assign this property to prepare the search in a given file. Assign the empty string to free the internal stream allocated.
Stream (public) | Stream (TStream). Assign this property to prepare the search in a given stream. Stream is not freed after the search is finished - you must free it by yourself.
FoundStart (public, read-only) | Resulting match position (0-based). Can be read only after successfull FindFirst/FindNext methods call.
FoundLength (public, read-only) | Resulting match length. Can be read only after successfull FindFirst/FindNext methods call.


Usage: Methods

Methods

function FindFirst(
const AText: WideString;
const AStartPos: Int64;
AEncoding: TATEncoding;
AOptions: TATStreamSearchOptions): Boolean;

Starts the search.
Before the search, the FileName or Stream property must be assigned.
Parameters:

  • AText: string to find.
    Unicode string must be in the Little-Endian format.

  • AStartPos: search start position (0-based).
    If it is 0, search will be performed from the beginning or end of the file/stream, depending of "Backward Search" option presence.

  • AEncoding: text encoding. Possible values are:
    • vEncANSI: ANSI encoding (locale dependent)
    • vEncOEM: OEM encoding (locale dependent)
    • vEncEBCDIC: IBM EBCDIC US encoding
    • vEncKOI8: KOI8-R encoding
    • vEncISO: ISO encoding (locale dependent)
    • vEncMac: Macintosh encoding (locale dependent)
    • plus many others, see the complete list in ATxCodepages.pas

  • AOptions: search options that are set of flags:
    • asoCaseSens: Case Sensitive search
    • asoWholeWords: Whole Words search
    • asoBackward: Backward search (Note: ignored in RegEx mode)
    • asoRegEx: RegEx search
    • asoRegExMLine: RegEx multiline search (used with asoRegEx)
Result is True if search was successfull.
In this case you can read the FoundStart and FoundLength properties to get the resulting position and length.
Notes:
  • RegEx notes:
    • On invalid regex this method raises an exception with descriptive message.
    • It is not recommended to use "Case Sensitive" and "Whole Words" options with quite complex regex that already specifies these options. For example, you shouldn't use the "Case Sensitive" option with regex containing (?i), and shouldn't use the "Whole Words" option with regex containing /b or /pZ. Otherwise the search result can be incorrect.
  • Encodings notes:
    • ANSI, OEM, EBCDIC, KOI8, ISO, Mac encodings are always available.
    • EBCDIC, KOI8, ISO, Mac encodings are used via MultiByteToWideChar API, if possible. But if they are not installed on OS (for example, on Win9x), then the hardcoded codepages are used.
    • All other encodings are used via MultiByteToWideChar API, they are available only when installed on OS.
function FindNext(AFindPrevious: Boolean = False): Boolean;

Continues the search.
AFindPrevious: continue search in reverse direction (Note: not supported for RegEx search).
Result is the same as for FindFirst method.


Usage: Events

Events

OnProgress Search progress callback. It is of type:
  TATStreamSearchProgress = procedure(
    const ACurrentPos, AMaximalPos: Int64;
    var AContinueSearching: Boolean) of object;
ACurrentPos: current search position,
AMaximalPos: maximal search position,
AContinueSearching: if set to False then search will be stopped.


Usage notes

  1. Since the DIRegEx regular expression engine uses a recursive algorithm, there are rare cases of complex RegEx patterns where it can run out of stack space and cause a stack overflow which can crash the application. This only happens very rarely, but as a precaution you might want to increase the stack size available to the application. You can do this in the Project Options, Linker Tab, Max Stack Size edit. Doubling the default value of $00100000 to $00200000 is usually a smart move.

  2. There is an issue regarding to the searching in ANSI mode under Multi-Byte locales (for example, Chinese or Korean). MB locales allow to show Unicode characters so that 2 bytes can form the single Multi-Byte character. But this is not taken into account by ATStreamSearch component, which always treats 1 byte as 1 single ANSI character. This leads to the incorrect search results comparing to the standard Windows controls (which support MB locales correctly).

    This issue can be seen in the ATStreamSearch demo. You can open ANSI file containing some Multi-Byte characters, and it will be displayed correctly in the upper ATBinHex control. But the search results for MB characters will be highlighted incorrectly.


License

This package, unless otherwise stated in the particular source code file, is distributed under Mozilla Public License Version 1.1 (the "License"). You may obtain a copy of the License at http://www.mozilla.org/MPL/

Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License.

Copyright © 2006-2007 Alexey Torgashin.


Copyrights & Links

  • ATStreamSearch © 2007-2008 Alexey Torgashin
    http://atorg.net.ru

  • Tnt Unicode Controls © 2002-2007 Troy Wolbrink
    http://www.yunqa.de

  • DIRegEx © 2000-2007 Ralf Junker, The Delphi Inspiration
    http://www.yunqa.de


Versions history

1.2.5
  • Added: Option asoRegExMLine for multiline search. "MLINE" define removed.
1.2.4 (10 oct 2008)
  • Added: Delphi 2009 compat.
  • Added: Multiline regex search (coDotAll) disabled, "MLINE" define.
1.2.2 (17 Jan 2008):
  • Added: FindNext method has additional AFindPrevious parameter to find previous match.
  • Fixed: Wrong search result on (AStartPos > 0).
1.2.0 (17 Dec 2007):
  • Changed: TATStreamSearchEncoding type changed to TATEncoding, declared in ATxCodepages.pas. TATEncoding type is more universal, and allows to easily add custom encodings. All encodings ids are changed.
  • Added: Many encodings added to TATEncoding type.
1.1.2 (27 Jun 2007):
  • Fixed: Under MBCS locale demo could show AV - ATBinHex component fixed for this.
  • Added: Note about searching under MBCS locale in the help.
1.1.1 (04 Apr 2007):
  • Changed: Update for DIRegEx 4.1 final.
1.1.0 (28 Mar 2007):
  • Changed: License updated to MPL 1.1.
  • Changed: Update for DIRegEx 4.1 beta.
  • Changed: Ids aseUTF16LE/aseUTF16BE renamed to aseUnicodeLE/aseUnicodeBE.
  • Added: Additional regex check is performed when "Whole Words" option is specified.
1.0.1 (17 Mar 2007):
  • Added: If regex is invalid, the special exception is raised on FindFirst call.
  • Added: "Usage notes" topic in the help file.
1.0.0 (16 Mar 2007):
  • Initial release.


Contacts

If you encounter problems with installation/usage of this component, or you have comments or suggestions, contact the author:

Alexey Torgashin
http://atorg.net.ru
support@uvviewsoft.com