Staz Software
HomeFutureBasicSharewareOrderContact

Tech Notes

STAZ Munger - The ultimate search routine

There comes a time in every programmers life when he starts to ask questions about things. Things like: "Why am I growing hair in certain places?" and "How do I search a large handle of text?"

I'll do my best to deal with both of those questions here, starting with grabbing your large handle and helping you look at it. Do that now. Grab your handle. Have you given it a name? We suggest doing that. It is a good programming practice to pre-dimension all of your variables. I'll call mine 'h'. That can be short for handle. (Or hair.)

dim h as handle

The next step, and it is an easy one, is to put your handle into a munger. In this case, we use the stazMunger. I like it because it's fast. We're talking a search routine that can zip through hundreds of files in a tenth of a second. And what is even more important is that the search is not case sensitive! If you search for "your HAIR" it will find "your hair". (I told you at the outset that we would deal with both questions. I have now fulfilled my obligation.)

Without further ado, the fastest, meanest, coolest, search function to ever toggle the bits of a Macintosh computer. I give you, stazMunger!

register on
local fn stazMunger(ptrIn as ptr , start as long , limit as long, @txtPtr as ^str255) 
register off
 dim as long p, theEnd, x, lgth, searchByte, lastByte
 dim as ptr txt
 lgth       = txtPtr.0`` - 1
 theEnd     = ptrIn + limit - lgth
 p          = ptrIn + start
 txt        = txtPtr + 1
 searchByte = gFBLowerChar(txt.0``)
 lastByte   = gFBLowerChar(|txt + lgth|)

 while p < theend
  long if gfblowerchar(|p|) == searchByte
   long if gFBLowerChar(|p + lgth|) == lastByte
    x  = lgth - 1
    while x > 0
     if gFBLowerChar(|txt + x|) != gFBLowerChar(|p + x|) then exit while
      x --
     wend
     if x <= 0 then p -= ptrIn : exit fn      ' Found
    end if
   end if
  p ++
 wend
 p  = -1                                         ' Not Found
end fn = p

Calling the function is not a big deal. You can grab the handle from anywhere. In the following little function, I fill a handle with the contents of a file, then call stazMunger using the handle. Because stazMunger does not move memory, you do not need to lock the handle. My sample function reads a file given only a file spec as a parameter.

local fn readTextFile(fsIn as ^fsSpec)
 dim h     as handle
 dim lgth  as long
 dim fs    as fsSpec

 BlockMove fsIn,@fs, sizeOf(fsSpec)

 open "I",#1,@fs
 lgth = lof(1,1)

 h = fn NewHandle(lgth)
 long if h
  HLock(h)
  read file #1, [h], lgth
  HUnLock(h)
 end if

 close #1
end fn = h

The next step is to feed the handle to stazMunger and ask for a search string.

dim as str255     searchFor
dim as handle     h
dim as long       offset , handleSize

offset     = 0
handleSize = fn GetHandleSize ( h )
searchFor  = "hair"
offset     = fn stazMunger ( [h] , offset , handleSize , searchFor )

When the job is complete, 'offset' will either equal an offet into the handle 'h' or it will equal -1 to indicate that the search string was not found. Cool, huh?

p.s. My thanks to Jay Reeve for his many speed-ups and improvements in this routine.

FutureBASIC

Demo

Order

Tour

Tech Notes

FAQ

Sample Code

Web Sites

Mailing List

System
Requirements

blank