Find method Binary
search through the stream beginning from the current position.
Although the binary nature of the Find method it supports text search
as well.
This methods allows the application to pass complex data as search
pattern. The data is converted to binary sequence of bytes first and
then the actual search is performed. If several alternative sequences
are to be searched the method can be instructed to search for any of
them (but they must have the same length). See the remarks for
details.
Despite the complex features supported by the method there are
simple and complex ways to use it. You can choose what suits your
needs best.
Syntax:
variable = object.Find(what [, flags [, chunkSize]])
Parameters:
what - What to search for. A variant parameter that
accepts almost any possible value and converts it to binary
sequence. See the remarks for detailed description.
flags - optional, default is 0. How to perform the search.
Appropriate combinations of the following flags can be specified.
&H00 - After search position on the beginning of the found
sequence or stay at the end of stream if nothing has been found.
&H01 - After the search return the original position in the
stream - where the search began (even on unsuccessful search).
&H02 - After the search stay after the found sequence. If
nothing is found then stay at the end of stream.
&H04 - Find any of the specified chunks. If specified the
chunkSize parameter is taken into account if not specified it will be
ignored.
chunkSize - optional, default is 0. Takes effect only if
&H04 is specified in the flags parameter. In this case the byte
sequence which is result of conversion of the what parameter
to binary is separated into chunks with length chunkSize
bytes and each chunk is searched separately. If one of them is found
the method returns its position. Note that if the size is specified
so that the last chunk is smaller than the others this last chunk will be
ignored.
returns: the position in the stream if successful or -1 if
unsuccessful (nothing found).
Examples:
Search for the short integer values of 6. It will appear (on x86
based Windows systems) as 00 06 in the binary stream.
Dim main,strm
Set main = Server.CreateObject("newObjects.utilctls.SFMain")
Set strm = main.OpenFile(Server.MapPath("test.bin"))
Do
pos = strm.Find(CInt(6),&H02)
If pos >= 0 Then
Response.Write "Found at Pos = [" & pos & "]<BR>"
End If
Loop Until pos < 0
Search for something more complicated - two textual parts with and
binary data between them. For simplicity we search two words - first is
at the end of line the second must be in the beginning of the next line
in a text file. But this technique can be used for any sequence.
Dim main,strm
Set main = Server.CreateObject("newObjects.utilctls.SFMain")
Set strm = main.OpenFile(Server.MapPath("test.bin"))
Dim a(3)
a(0) = "First"
a(1) = CByte(AscB(vbCr))
a(2) = CByte(AscB(vbLf))
a(3) = "Second"
Do
pos = strm.Find(a,&H02)
If pos >= 0 Then
Response.Write "Found at Pos = [" & pos & "]<BR>"
End If
Loop Until pos < 0
This piece of code will search for all the occurrences of the words
"Cat" and "Dog" in the file. File can be a text file
or some kind of binary file.
Dim main,strm
Set main = Server.CreateObject("newObjects.utilctls.SFMain")
Set strm = main.OpenFile(Server.MapPath("test.txt"))
Do
pos = strm.Find("CatDog",&H04,3)
If pos >= 0 Then
Response.Write "Found at Pos = [" & pos & "]<BR>"
strm.Pos = strm.Pos + 1
End If
Loop Until pos < 0
Remarks:
About what parameter. The application can pass basic variant
types (as numeric values or string) and arrays of them. The data
contained in the parameter is converted into binary sequence of bytes.
Thus if you pass a binary data it will be used "as is". If
string is passed it will be converted as the unicodeText
and codePage specify and the
result will be treated as sequence of bytes. In case of strings the
terminating null character is ignored (this is a binary search
method we cannot rely on no preliminary assumption how the strings are
recorded in it or you can search partial string etc.). The array
passed may contain variants in turn (but not other arrays). This is
probably the most useful form for the scripts - it allows you to pass
different values which will be converted properly and concatenated
into single binary sequence used further.
Note that objects cannot be passed to the method through the
what parameter! There is no way to determine how to convert
them - thus their default property cannot be resolved. So when using
values contained in objects (and most likely in their default
properties) the application is responsible to convert them to basic
values. In VBScript this can be done by using the CLng, CByte, CStr
and the other conversion functions, in JScript use the TypeConvertor
component from this library which supplies the same functionality that
can be found in VBScript internally but is not available in JScript.
If you are feeling confused by the above requirement consider one
example situation - an object with a default property which will
return a number, for example 7. Converting it to string and then
passing it to this method will result in one byte containing the ASCII
code of the character '7' (or two bytes in UNICODE mode), but if you
convert it to long integer first (using CLng function) it will result
in 4 bytes sequence. Thus the resulting binary sequence searched will
be different. This illustrates why there is no way to resolve the
default properties of the objects in the method itself.
How the non-string values are converted? They are used
as they appear in the memory. If you need complete control on each
byte pass array of bytes or array of variants where the important
bytes are carefully converted to VT_BYTE subtype by using CByte.
What will happen if you pass array of several strings? All
the strings will be converted and concatenated. Then depending on the
flags if chunks are used the result will be separated in chunks or
searched as whole if chunks feature is not used.
Mixing strings with other data. If you are searching for a
byte sequence that consist of textual parts and binary parts -
you can describe it by creating an array where the text parts are
strings and the non-string parts are represented by elements holding
numeric data (bytes for example). This allows the scripting
application to specify any possible byte sequence even if the script
language itself is not capable of doing so.
It is recommended to use bytes and strings mostly. Do not forget
that the longer numeric values can be represented in different manner
in the stream. For example a short integer value (two bytes) can be
represented as the high byte first or contrary its low byte can be
first in the memory representation. This depends on how and where the
stream has been created. Therefore using non-byte numeric values
requires you to consider their representation in the memory and
evaluate if it is possible the stream to contain them in an unexpected
form.
String searches are always case sensitive.
Applies to: SFStream object
|