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

hex.c

/* 
   Hex viewing & editing 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 HEX_COLOR_BLUE     VC_COLOR_BACKBLUE
#elif defined(VCHE_NC)
    #define HEX_COLOR_BLUE     BUF_BBLUE
#endif

/* It's the fasted way to translate to base 16 */
char hex_trans_byte1[] = "0000000000000000111111111111111122222222222222223333333333333333444444444444444455555555555555556666666666666666777777777777777788888888888888889999999999999999AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFF";
char hex_trans_byte2[] = "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF";

/* Convertion table to base 16 */
char hex_trans[] = "0123456789ABCDEF";

char *hex_buffer;
char *hbuffer; /* The hex buffer    */
char *obuffer; /* The output buffer */
char *abuffer; /* The ascii buffer  */
#if defined(VCHE_VC)
char *zbuffer; /* The zero buffer   */
#endif
char *offset_buffer;


long fpos;                             /* File position                    */
int bread;                             /* bytes read                       */

int bytes_to_read;                     /* Quantity of bytes to read        */

int bytes_per_row;                     /* Quantity of ascii bytes per row  */
int bytes_per_row_hex;                 /* Quantity of hex bytes per row    */

void hex_mainloop( int view_or_edit)
{
#if defined(VCHE_VC)
 int tmp_flag_m = 0;
 int tmp_flag_z = 0;
#endif
 int tmp_flag_x = 0;
 int c;

 set_hexmode_variables();

 file_open( ll_file_current->filename);
 
 draw_filename( ll_file_current->filename);

 hex_showfile();

 lib_flush();

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

 if( view_or_edit) 
     goto editkey;

 while( 1) {
        c = key_get();

        switch( c) {
                /* Toggle read/write mode */
                case 'w': if( check_readonly() == -1)
                              break;
                          flags.readonly = flags.readonly ? 0 : 1;
                          set_flag( FLAG_READONLY);
                          ll_file_current->filepos = fpos;
                          file_open( ll_file_current->filename);
                          fpos = lseek( fd, (long) ll_file_current->filepos, SEEK_SET);
                          draw_filename( ll_file_current->filename);
                          hex_showfile();
                          lib_flush();
                          break;
                /* Toggle bell */
                case 'b': flags.bell = flags.bell ? 0 : 1;
                          set_flag( FLAG_BELL);
                          break;
                /* Go to next file if any */
                case 'n': ll_file_current->filepos = fpos;
                          if( file_go_next() == -1)
                              break;
                          fpos = lseek( fd, (long) ll_file_current->filepos, SEEK_SET);
                          draw_filename( ll_file_current->filename);
                          hex_showfile();
                          lib_flush();
                          break;
                /* Go to previous file if any */
                case 'p': ll_file_current->filepos = fpos;
                          if( file_go_prev() == -1)
                              break;
                          fpos = lseek( fd, (long) ll_file_current->filepos, SEEK_SET);
                          draw_filename( ll_file_current->filename);
                          hex_showfile();
                          lib_flush();
                          break;
                /* Refresh the screen */
            case 'r': draw_main_screen();
                          set_flag( FLAG_BELL);
                          set_flag( FLAG_EDIT);
                          set_flag( FLAG_NOHEX);
                          set_flag( FLAG_READONLY);
#if defined(VCHE_VC)
                          set_flag( FLAG_MASK);
                          set_flag( FLAG_ZERO);
#endif
                          draw_filename( ll_file_current->filename);
                          lib_fill_obuffer();
                          hex_showfile();
                          lib_flush();
                          break;
                /* Refresh file size */
                case 'R': file_getsize();
                          lib_fill_obuffer();
                          hex_showfile();
                          lib_flush();
                          break;
#if defined(VCHE_VC)
                /* Toggle non-printable ascii mask */
                case 'm': flags.mask = flags.mask ? 0 : 1;
                          set_flag( FLAG_MASK);
                          hex_showfile();
                          lib_flush();
                          break;
                /* Toggle zero mask */
                case '0': flags.zero = flags.zero ? 0 : 1;
                          set_flag( FLAG_ZERO);
                          hex_showfile();
                          lib_flush();
                          break;
#endif
                /* Help */  
                case '?'         :
                case 'h'         :
                case 'H'         : 
                case VC_KEY_F1   : help();
                                   break;
                /* Edit */
                case 'e'         : 
                case VC_KEY_F2   : 
editkey:
                                   if( flags.readonly) {
                                       lib_alert( "We are in READ ONLY mode!", 0);
                                       break;
                                   }

                                   lib_fill_obuffer();

#if defined(VCHE_VC)
                                   tmp_flag_m = flags.mask;
                                   tmp_flag_z = flags.zero;
#endif
                                   tmp_flag_x = flags.nohex;
                                   flags.edit  = 1;
#if defined(VCHE_VC)
                                   flags.mask  = 0;
                                   flags.zero  = 0;
#endif
                                   flags.nohex = 0;
                                   set_flag( FLAG_EDIT);
#if defined(VCHE_VC)
                                   set_flag( FLAG_MASK);
                                   set_flag( FLAG_ZERO);
#endif
                                   set_flag( FLAG_NOHEX);
                                   set_hexmode_variables();
                                   edit();
                                   flags.edit  = 0;
#if defined(VCHE_VC)
                                   flags.mask  = tmp_flag_m;
                                   flags.zero  = tmp_flag_z;
#endif
                                   flags.nohex = tmp_flag_x;
                                   set_flag( FLAG_EDIT);
#if defined(VCHE_VC)
                                   set_flag( FLAG_MASK);
                                   set_flag( FLAG_ZERO);
#endif
                                   set_flag( FLAG_NOHEX);
                                   set_hexmode_variables();
                                   tmp_flag_x = 0;
#if defined(VCHE_VC)
                                   tmp_flag_m = 0;
                                   tmp_flag_z = 0;
#endif
                                   draw_fkeys( fkeys[ flags.nohex]);
                                   hex_showfile();
                                   lib_flush();
                                   break;
                /* No-hex/hex toggle */
                case 'x'         : 
                case VC_KEY_F3   : 
                                   flags.nohex = flags.nohex ? 0 : 1;
                                   set_flag( FLAG_NOHEX);
                                   set_hexmode_variables();
                                   draw_fkeys( fkeys[ flags.nohex]);
                                   lib_fill_obuffer();
                                   hex_showfile();
                                   lib_flush();
                                   break;
                /* Search a string, case-sensitive */
                case 's'         : 
                case VC_KEY_F4   : vc_case_sensitive = VC_CASE_SENSITIVE;
                                   search();
                                   hex_showfile();
                                   search_hilite_found_string();
                                   lib_flush();
                                   break;
                /* Search a string, case-insensitive */ 
                case 'S'         : vc_case_sensitive = VC_CASE_INSENSITIVE;
                                   search();
                                   hex_showfile();
                                   search_hilite_found_string();
                                   lib_flush();
                                   break;
                /* Search againg */
                case ' '         : 
                case VC_KEY_F5   : search_again();
                                   hex_showfile();
                                   search_hilite_found_string();
                                   lib_flush();
                                   break;
                /* Goto an offset */
                case 'g'         :
                case VC_KEY_F6   : filegoto();
                                   hex_showfile();
                                   lib_flush();
                                   break;
                /* Select file to edit */
                case VC_KEY_F7   : ll_file_browse();
                                   break;
                /* Show ASCII table */
                case VC_KEY_F8   : ascii_table();
                                   break;
                /* Show GNU GPL */
                case VC_KEY_F9   : show_gnu_license();
                                   break;
                /* Quit */
                case 'q'         : 
                case VC_KEY_F10  : do_exit( 0); 
                                   break; /* not reached */
                case VC_KEY_UP   : file_prev_line();
                                   lib_flush();
                                   break;
                case VC_KEY_DOWN : file_next_line();
                                   lib_flush();
                                   break;
                case VC_KEY_RIGHT: file_next_byte();
                                   lib_flush();
                                   break;
                case VC_KEY_LEFT : file_prev_byte();
                                   lib_flush();
                                   break;
                case VC_KEY_HOME : file_go_home(); 
                                   lib_flush();
                                   break;
                case VC_KEY_END  : file_go_end();
                                   lib_flush();
                                   break;
                case VC_KEY_PGUP : file_prev_block();
                                   lib_flush();
                                   break;
                case VC_KEY_PGDN : file_next_block();
                                   lib_flush();
                                   break;
        } /* end switch( c) */

 } /* end while( 1) */

}

void hex_showfile( void)
{
 long lfpos;
 int startxy;
 int size;
 int line;
 int pos;

 startxy = vc_cols - bytes_per_row;

 draw_offset_n_perc( fpos);

 lfpos = fpos;

 bread = read( fd, hbuffer, bytes_to_read);

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

 if( bread < bytes_to_read)
     memset( hbuffer + bread, 0, bytes_to_read - bread);

 for( pos = line = 0; pos < bread && lfpos >= 0; pos += bytes_per_row, line++) {

      hex_fill_offset_buffer( lfpos);

      lib_buffer_puts( 0, line, 10, offset_buffer, HEX_COLOR_BLUE);

      size = (bread == bytes_to_read) ? bytes_per_row : ((bread - pos) > bytes_per_row) ? bytes_per_row : bread - pos;

      if( !flags.nohex) {
          hex_fill_hex_buffer( hbuffer + pos, size);

          /* I need to write colors here, because of the edit routines */
          lib_buffer_puts( 12, line, bytes_per_row_hex, hex_buffer, HEX_COLOR_BLUE);
      }

#if defined(VCHE_VC)
      if( flags.mask) {
          hex_fill_ascii_buffer( hbuffer + pos, size);
          lib_buffer_puts( startxy, line, bytes_per_row, abuffer, HEX_COLOR_BLUE);
      } else if( flags.zero) {
                 hex_fill_zero_buffer( hbuffer + pos, size);
                 lib_buffer_puts( startxy, line, bytes_per_row, zbuffer      , HEX_COLOR_BLUE);
             } else
                 lib_buffer_puts( startxy, line, bytes_per_row, hbuffer + pos, HEX_COLOR_BLUE);
#elif defined(VCHE_RAW) || defined(VCHE_NC)
      hex_fill_ascii_buffer( hbuffer + pos, size);
      lib_buffer_puts( startxy, line, bytes_per_row, abuffer, HEX_COLOR_BLUE);
#endif
      lfpos += bytes_per_row;
 }

 while( line < vc_lines - 2)
        lib_buffer_puts( 0, line++, vc_cols, space_buffer, HEX_COLOR_BLUE);

 /* bread must be correct for editing functions, it is incorrect when
    devices are bigger than LONG_MAX, and we are viewing the end of
    the file, so I correct bread here */
 if( lfpos < 0)
#ifdef LONG_MAX
     bread = LONG_MAX - fpos;
#else
     bread = 2147483647 - fpos;
#endif

}

void hex_fill_hex_buffer( char *buf, int size)
{
 int j = 0, i = 0, sp = 1;

 while( j < size) {
        hex_buffer[ i++] = hex_trans_byte1[ (unsigned char) buf[ j  ]];
        hex_buffer[ i++] = hex_trans_byte2[ (unsigned char) buf[ j++]];
        if( sp == 4) {
             i += 2;
             sp = 1;
        } else {
             i++;
             sp++;
        }
 }

 while( j++ < bytes_per_row) {
        hex_buffer[ i++] = ' ';
        hex_buffer[ i++] = ' ';
        if( sp == 4) {
             i += 2;
             sp = 1;
        } else {
             i++;
             sp++;
        }
 }

}

void hex_fill_offset_buffer( long pos)
{
 register char *bp = offset_buffer + 10;

 /* I won't call sprintf, it is a slow function. */
 do {
     *--bp = hex_trans[ pos % 16];
 } while( (pos /= 16) != 0);

 /* pad with zeros */
 while( bp != offset_buffer)
        *--bp = '0';
}

void hex_fill_ascii_buffer( char *buf, int size)
{
 int i;

 for( i = 0; i < size; i++) 
      abuffer[ i] = buf[ i] > 31 && buf[ i] < 127 ? buf[ i] : '.';

 while( i < bytes_per_row)
        abuffer[ i++] = ' ';
}


#if defined(VCHE_VC)

void hex_fill_zero_buffer( char *buf, int size)
{
 int i;

 for( i = 0; i < size; i++)
      zbuffer[ i] = buf[ i] == 0 ? '.': buf[ i];

 while( i < bytes_per_row)
        zbuffer[ i++] = ' ';
}

#endif


Generated by  Doxygen 1.6.0   Back to index