Logo Search packages:      
Sourcecode: vche version File versions  Download package

search.c

/*
   Search functions
   --------------------------------------------------------------------
   VCHE - Virtual Console Hex Editor

   Copyright (C) 1998, 1999 Diego Javier Grigna <diego@grigna.com>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "common.h"

#if defined(VCHE_VC) || defined(VCHE_RAW)
    #define SEARCH_COLOR_BG_LGRAY VC_COLOR_BG_LIGHTGRAY
#elif defined(VCHE_NC)
    #define SEARCH_COLOR_BG_LGRAY BUF_BLGRAY
#endif

int vc_case_sensitive;

char srch[ 64]; /* The string to search */
static long search_again_offset;
static long re_search;

static void search_string( char *str, long offset);
static long search_in_memory( char *sbuffer, char *pattern, long sizes, long sizep);
static void search_hilite_byte( char byte, int what_attr);

void search( void)
{
#if defined(VCHE_NC)
 WINDOW *w;
#endif
 char temp[ 64];
 char rever[ 64];
 int b1, b2;
 int len;
 int i;

#if defined(VCHE_VC) || defined(VCHE_RAW)
 lib_save_screen();
#endif

#if defined(VCHE_NC)
 w =
#endif

 lib_dialog( "Enter search string: ", srch, 38, VC_COLOR_BACKCYAN, VC_COLOR_WHITE);

#if defined(VCHE_VC) || defined(VCHE_RAW)
 term_goto( (vc_cols - 38) / 2, vc_lines / 2);
 key_scanf( srch, 38);
#elif defined(VCHE_NC)
 term_wgoto( w, 2, 2);
 key_scanf( w, srch, 38);
#endif

 strcpy( temp, trim_spaces( srch));

 i = 0;
 len = strlen( temp);

 if( !strncasecmp( temp, "0x", 2)) {
     while( len > 0) {
            temp[ len - 2] = toupper( temp[ len - 2]);
            temp[ len - 1] = toupper( temp[ len - 1]);
            b1 = hex2bin( temp, len - 2);
            b2 = hex2bin( temp, len - 1);
            rever[ i] = b1 * 16 + b2;
            len-=2;
            i++;
     }
     rever[ i] = 0;
     len = strlen( rever);
     i = 0;
     while( len > 0) {
            temp[ i] = rever[ len - 1];
            len--;
            i++;
     }
     temp[ i] = 0;
 } /* end if strncase... */

 memset( &srch, 0, 63);
 strcpy( srch, temp);

 ll_edit_head = NULL;

 if( srch[ 0] != 0 )
     search_string( srch, 0);

#if defined(VCHE_VC) || defined(VCHE_RAW)
 lib_load_screen();
#elif defined(VCHE_NC)
 delwin( w);
#endif
}

void search_again( void)
{
 search_again_offset = search_again_offset < fpos ? fpos : search_again_offset;

 ll_edit_head = NULL;

 if( srch[ 0] != 0 )
     search_string( srch, search_again_offset);
}

void filegoto( void)
{
#if defined(VCHE_NC)
 WINDOW *w;
#endif
 char posstr[ 64];
 long newpos = -1;

#if defined(VCHE_VC) || defined(VCHE_RAW)
 lib_save_screen();
#endif

 memset( &posstr, 0, sizeof( posstr));
 sprintf( posstr, "%ld", fpos);

#if defined(VCHE_NC)
 w =
#endif
 lib_dialog( "Enter file position: ", posstr, 38, VC_COLOR_BACKCYAN, VC_COLOR_WHITE);

#if defined(VCHE_VC) || defined(VCHE_RAW)
 term_goto( (vc_cols - 38) / 2, vc_lines / 2);
 key_scanf( posstr, 38);
#elif defined(VCHE_NC)
 term_wgoto( w, 2, 2);
 key_scanf( w, posstr, 38);
#endif

 if( !strncasecmp( posstr, "0x", 2))
     sscanf( posstr, "%lx", &newpos);
 else
     newpos = atol( posstr);

 if( vc_filesize >= 0 && (newpos < 0 || newpos > vc_filesize)) {
     lib_alert( "Invalid offset!", 5);
#if defined(VCHE_VC) || defined(VCHE_RAW)
     lib_load_screen();
#elif defined(VCHE_NC)
     delwin( w);
#endif
     return;
 }

 fpos = lseek( fd, (long) newpos, SEEK_SET);

#if defined(VCHE_VC) || defined(VCHE_RAW)
 lib_load_screen();
#elif defined(VCHE_NC)
 delwin( w);
#endif
}

static void search_string( char *str, long offset)
{
#if defined(VCHE_NC)
 WINDOW *w;
#endif
 struct ll_edit *node;
 struct ll_edit *tmp;
 char search_buf[ 8192];    /* Buffer used to read data from file         */
 long filepos = 0;          /* File position                              */
 long bytes_read;           /* Bytes read from file                       */
 long sizep = strlen( str); /* Size of pattern to search                  */
 long retv;                 /* Return value for search_in_memory function */
 int i = 0;

 search_again_offset = 0;
 lseek( fd, (long) offset, SEEK_SET);

#if defined(VCHE_VC) || defined(VCHE_RAW)
 lib_save_screen();
#endif

#if defined(VCHE_NC)
 w =
#endif
 lib_message( " Searching... ", 5);

 while( filepos < vc_filesize) {
        filepos = file_getpos();
        bytes_read = read( fd, &search_buf, sizeof( search_buf) - 1);
        if( bytes_read <= 0) 
            break;

        if( bytes_read == 1 && sizep > 1)
            break;

        retv = search_in_memory( search_buf, str, bytes_read, sizep);

        /* String found */
        if( retv >= 0) {
            fpos = filepos + retv;
            search_again_offset = fpos + sizep;
            /*
             * Put the string in the linked list byte by byte.
             */
            while( i < sizep) {
                   node = ll_edit_head;
                   tmp  = ll_edit_head;

                   while( node != NULL) {
                          if( node->filepos < ( fpos + i)) {
                              tmp  = node;
                              node = node->next;
                          } else
                              break;
                   }

                   ll_edit_add( search_buf[ retv + i], fpos + i, tmp);
                   i++;
            }
#if defined(VCHE_VC) || defined(VCHE_RAW)
            lib_load_screen();
#elif defined(VCHE_NC)
            delwin( w);
#endif
            lseek( fd, (long) fpos, SEEK_SET);
            return;
        }
 
        /* String found partially, lseek to the matching characters */
        if( retv == -2)
            lseek( fd, (long) filepos + re_search, SEEK_SET);
 } /* end while(....) */

 lib_alert( "String not found", 5);
#if defined(VCHE_VC) || defined(VCHE_RAW)
 lib_load_screen();
#elif defined(VCHE_NC)
 delwin( w);
#endif

 lseek( fd, (long) fpos, SEEK_SET);
}

/*
 * Search for pattern inside sbuffer.
 *
 * sbuffer == String were to search.
 * pattern == Pattern to search.
 * sizes   == Size of sbuffer.
 * sizep   == Size of pattern.
 *
 * Return values:    -1  == Not found.
 *                   -2  == Found partially, must search again.
 *                  >= 0 == Found.
 */

static long search_in_memory( char *sbuffer, char *pattern, long sizes, long sizep)
{
 long found; /* Found characters */
 int s;      /* buffer index     */
 int p;      /* pattern index    */
 register char tmps;  /* buffer temporal variable */
 register char tmpp;  /* pattern temporal variable */

 found = 0;
 s = p = 0;

 while( s < sizes && p < sizep && found < sizep) {

        if( vc_case_sensitive == VC_CASE_INSENSITIVE) {
            tmps = toupper( sbuffer[ s]);
            tmpp = toupper( pattern[ p]);
        } else {
            tmps = sbuffer[ s];
            tmpp = pattern[ p];
        }

        if( tmps == tmpp) {
            found++; 
            s++;
            p++;
        } else {
            s++;
            p = 0;
            found = 0;
        }
 }

 /* 
  * String found
  * Return offset inside sbuffer, were pattern
  * was found.
  */
 if( found == sizep)
     return s - found;

 /* Found partially */
 if( found > 0) {
     re_search = s - found;
     return -2;
 }

 /* Not found */
 return -1;
}

void search_hilite_found_string( void)
{
 struct ll_edit *node = ll_edit_head;
 int bytes;

 while( node != NULL) {
        if( node->filepos < fpos)
            node = node->next;
        else
            break;
 }

 if( node != NULL) {
     bytes = node->filepos - fpos;
     while( bytes < bread && node != NULL && node->filepos <= (fpos + bytes)) {

          ey = bytes / bytes_per_row;
          ex = - ey * bytes_per_row + bytes;

          if( flags.nohex)
              search_hilite_byte( node->byte, SEARCH_COLOR_BG_LGRAY);
          else
              edit_insert_in_obuffer( node->byte, SEARCH_COLOR_BG_LGRAY);

          node = node->next;
          ex++;
          if( ex > bytes_per_row - 1) {
              ex = 0;
              ey++;
          }
          if( node != NULL)
              bytes = node->filepos - fpos;
     }

 }

 ll_edit_free();
}

static void search_hilite_byte( char byte, int what_attr)
{
 int posa;
 int ay, ax;
 int posxya;

 ay = ey + 1;

 ax = ex + vc_cols - bytes_per_row;

 posxya = 4 + 2 *( ay * vc_cols + ax);
 posa = posxya - (4 + 2 * vc_cols);

 obuffer[ posa    ] = byte;

 obuffer[ posa + 1] = what_attr;
}


Generated by  Doxygen 1.6.0   Back to index