home *** CD-ROM | disk | FTP | other *** search
/ Power CD-ROM!! 7 / POWERCD7.ISO / prgmming / clipper / flocate.prg < prev    next >
Text File  |  1993-10-14  |  4KB  |  115 lines

  1. /*
  2.  * File......: FLOCATE.PRG
  3.  * Author....: Dave Pearson
  4.  * BBS.......: The Dark Knight Returns
  5.  * Net/Node..: 050/069
  6.  * User Name.: Dave Pearson
  7.  * Date......: 13/04/93
  8.  * Revision..: 1.0
  9.  *
  10.  * This is an original work by Dave Pearson and is placed in the public
  11.  * domain.
  12.  *
  13.  * Modification history:
  14.  * ---------------------
  15.  *
  16.  * $Log$
  17.  *
  18.  */
  19.  
  20. #include "gt_lib.ch"
  21.  
  22. #define MAX_BUFFER_SIZE 8192
  23. #define ERR_READ_ERROR  -1
  24. #define ERR_NOT_FOUND   -2
  25.  
  26. /*  $DOC$
  27.  *  $FUNCNAME$
  28.  *      GT_FLOCATE()
  29.  *  $CATEGORY$
  30.  *      File I/O
  31.  *  $ONELINER$
  32.  *      Find a string in a low level file.
  33.  *  $SYNTAX$
  34.  *      GT_FLocate(<nFileHandle>,<cString>,[<lCaseSensitive>],;
  35.  *                 [<nStartPos>]) --> nLocation
  36.  *  $ARGUMENTS$
  37.  *      <nFileHandle> is the handle of a file that has been opened or
  38.  *      created with one of Clipper's low level file functions.
  39.  *
  40.  *      <cString> is the string you are looking for.
  41.  *
  42.  *      <lCaseSensitive> is an optional logical value to describe the
  43.  *      type of search. If True (.T.) the search will be a case sensitive
  44.  *      search. The default is False (.F.)
  45.  *
  46.  *      <nStartPos> is an optional numeric value to describe the position
  47.  *      at which the search will start. The default is 0.
  48.  *  $RETURNS$
  49.  *      The byte location of the string if a match is found. -1 if there
  50.  *      was an error reading the file. -2 if a match could not be found.
  51.  *  $DESCRIPTION$
  52.  *      GT_FLocate() can be used to find a text string in a file that has
  53.  *      been opened with one of Clipper's low level file functions.
  54.  *
  55.  *      Note that as well as returning the location of the hit GT_Flocate()
  56.  *      will also place the file pointer at the first byte of the match. If
  57.  *      no match was found the file pointer will be in it's original
  58.  *      location.
  59.  *  $EXAMPLES$
  60.  *      // The following example opens a file and prints every byte location
  61.  *      // of the target word.
  62.  *
  63.  *      local nFile := fopen("LIFE.42")
  64.  *      local nHit  := 0
  65.  *      do while nHit >= 0
  66.  *         if (nHit := GT_FLocate(nFile,"Meaning")) >= 0
  67.  *            ? nHit
  68.  *         endif
  69.  *      enddo
  70.  *      fclose(nFile)
  71.  *  $SEEALSO$
  72.  *      GT_FTELL() GT_FSIZE()
  73.  *  $END$
  74.  */
  75.  
  76. function GT_FLocate(nFileHandle,cString,lCaseSensitive,nStartPos)
  77. local nOffset     := ERR_NOT_FOUND,;
  78.       nOldOffset  := 0            ,;
  79.       nBufferSize := 0            ,;
  80.       cBuffer     := NULL         ,;
  81.       cTextBuff   := NULL         ,;
  82.       nPosition   := 0            ,;
  83.       nFileLength := 0            ,;
  84.       nIsInBuff   := 0
  85. default lCaseSensitive to FALSE
  86. default nStartPos      to 0
  87. if valtype(nFileHandle) == TYPE_NUMERIC .and. valtype(cString) == TYPE_CHAR
  88.    nFileLength := GT_FSize(nFileHandle)
  89.    if nStartPos < nFileLength
  90.       nOldOffset  := GT_FTell(nFileHandle)
  91.       nBufferSize := min(MAX_BUFFER_SIZE,nFileLength-nStartPos)
  92.       cBuffer     := space(nBufferSize)
  93.       cTextBuff   := space(len(cString))
  94.       nPosition   := fseek(nFileHandle,nStartPos,FS_SET)
  95.       do while nPosition < nFileLength
  96.          if fread(nFileHandle,@cBuffer,nBufferSize) == F_ERROR
  97.             nOffset := ERR_READ_ERROR
  98.             exit
  99.          endif
  100.          cTextBuff := right(cTextBuff,len(cString))+if(!lCaseSensitive,upper(cBuffer),cBuffer)
  101.          if (nIsInBuff := at(if(!lCaseSensitive,upper(cString),cString),cTextBuff)) != 0
  102.             nOffset := nPosition + nIsInBuff - len(cString) - 1
  103.             exit
  104.          endif
  105.          nPosition := GT_FTell(nFileHandle)
  106.       enddo
  107.       if nOffset < 0
  108.          fseek(nFileHandle,nOldOffset,FS_SET)
  109.       else
  110.          fseek(nFileHandle,nOffset,FS_SET)
  111.       endif
  112.    endif
  113. endif
  114. return(nOffset)
  115.