ghex_heraia_interface.c

Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
00002 /*
00003   ghex_heraia_interface.c
00004   heraia - an hexadecimal file editor and analyser based on ghex
00005  
00006   (C) Copyright 2005 - 2009 Olivier Delhomme
00007   e-mail : heraia@delhomme.org
00008   URL    : http://heraia.tuxfamily.org
00009  
00010   This program is free software; you can redistribute it and/or modify
00011   it under the terms of the GNU General Public License as published by
00012   the Free Software Foundation; either version 2, or  (at your option) 
00013   any later version.
00014  
00015   This program is distributed in the hope that it will be useful,
00016   but WITHOUT ANY WARRANTY;  without even the implied warranty of
00017   MERCHANTABILITY  or  FITNESS FOR A PARTICULAR PURPOSE.  See the
00018   GNU General Public License for more details.
00019  
00020   You should have received a copy of the GNU General Public License
00021   along with this program; if not, write to the Free Software
00022   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
00023 /**
00024  * @file ghex_heraia_interface.c
00025  * An interface to the ghex library -> this adds an abstract layer.
00026  */
00027 #include <libheraia.h>
00028 
00029 /**
00030  * @fn HERAIA_ERROR heraia_hex_document_new(heraia_window_t *main_window, char *filename) 
00031  *  Removes the old document if it exists and adds a new one
00032  *  from the filename 'filename'
00033  * @param main_window : main structure
00034  * @param filename : a char * representing an existing file named "filename"
00035  * @return Always returns HERAIA_NOERR; @todo : do something to take errors into
00036  *         account
00037  */
00038 HERAIA_ERROR heraia_hex_document_new(heraia_window_t *main_window, char *filename) 
00039 {
00040         if (main_window->current_doc != NULL)
00041                 {
00042                         hex_document_remove_view(main_window->current_doc, main_window->current_DW->current_hexwidget);
00043                 }
00044         
00045         if (main_window->current_DW->current_hexwidget != NULL )
00046                 {
00047                         gtk_widget_destroy(main_window->current_DW->current_hexwidget);
00048                 }
00049         
00050         main_window->current_doc = hex_document_new_from_file(filename);
00051         if (main_window->current_doc != NULL)
00052          {
00053                 main_window->current_DW->current_hexwidget = hex_document_add_view(main_window->current_doc);
00054                 connect_cursor_moved_signal(main_window);
00055                 return HERAIA_NOERR;
00056          }
00057          else
00058          {
00059                  return HERAIA_FILE_ERROR;
00060          }
00061 }
00062 
00063 
00064 /**
00065  * @fn gchar *heraia_hex_document_get_filename(Heraia_Document *doc)
00066  * Retrieves the filename of a document which ever it is !
00067  * @param doc : an existing Heraia_Document @todo : do something if
00068  *        the document does not exist.
00069  * @return returns the filename of that document.
00070  */
00071 gchar *heraia_hex_document_get_filename(Heraia_Document *doc)
00072 {
00073         return doc->file_name;
00074 }
00075 
00076 
00077 /**
00078  * @fn HERAIA_ERROR heraia_hex_document_save(heraia_window_t *main_window)
00079  * Saves an open and edited document
00080  * @param main_window : main structure, @todo may be we only need main_window->current_doc here
00081  * @return returns HERAIA_NOERR if everything went ok or HERAIA_FILE_ERROR in case of an error
00082  */
00083 HERAIA_ERROR heraia_hex_document_save(heraia_window_t *main_window)
00084 {
00085         gint return_value = FALSE;
00086         
00087         if (main_window->current_doc != NULL)
00088            {
00089                                 return_value = hex_document_write(main_window->current_doc);
00090                 }
00091         
00092         if (return_value != FALSE)
00093            {
00094                                 return HERAIA_NOERR;
00095                 }
00096          else
00097            {    
00098                                 return HERAIA_FILE_ERROR;
00099            }
00100 }
00101 
00102 /**
00103  * @fn HERAIA_ERROR heraia_hex_document_save_as(heraia_window_t *main_window, gchar *filename)
00104  * Saves an opened and edited document to a new file
00105  * @param main_window : main structure
00106  * @param filename : the new filename where to save the file
00107  * @return returns HERAIA_NOERR if everything went ok or HERAIA_FILE_ERROR in case of an error
00108  */
00109 HERAIA_ERROR heraia_hex_document_save_as(heraia_window_t *main_window, gchar *filename)
00110 {
00111         gint return_value = FALSE;
00112         FILE *fp = NULL;
00113         gint i = 0;
00114         gchar *path_end = NULL; /**< to make libghex happy ! */
00115         
00116         if (main_window->current_doc != NULL && filename != NULL)
00117            {
00118                         fp = fopen(filename, "w");
00119                         if (fp != NULL)
00120                         {
00121                                 return_value = hex_document_write_to_file(main_window->current_doc, fp);
00122                                 fclose(fp);
00123                                 
00124                                 if (main_window->current_doc->file_name)
00125                                  {
00126                                          g_free(main_window->current_doc->file_name);
00127                                  }
00128                                 main_window->current_doc->file_name = filename;
00129                                 
00130                                 /* This may disappear as it duplicates structures */
00131                                 if (main_window->filename != NULL)
00132                                 {
00133                                          g_free(main_window->filename);
00134                                 }
00135                                 main_window->filename = g_strdup_printf("%s", main_window->current_doc->file_name);
00136                                 
00137                                 /* path_end stuff from ghex-window.c from ghex project !!! */
00138                                 for(i = strlen(main_window->current_doc->file_name);
00139                         (i >= 0) && (main_window->current_doc->file_name[i] != '/');
00140                         i--);
00141                                 if (main_window->current_doc->file_name[i] == '/')
00142                 path_end = &main_window->current_doc->file_name[i+1];
00143                                 else
00144                path_end = main_window->current_doc->file_name;
00145             
00146                                 main_window->current_doc->path_end = g_filename_to_utf8(path_end, -1, NULL, NULL, NULL);
00147                         }
00148                 }
00149         
00150         if (return_value != FALSE)
00151            {
00152                                 return HERAIA_NOERR;
00153                 }
00154          else
00155            {    
00156                                 return HERAIA_FILE_ERROR;
00157            }
00158 }
00159 
00160 /**
00161  * @fn void change_endianness(guint len, guint endianness, guchar *result)
00162  *  Deals with the endianness of 'len' bytes located in 'result'
00163  *  for BIG_ENDIAN we only swap bytes if we have two or more of them
00164  *  if we have only one byte, we reverse its order
00165  *  if endianness is MIDDLE_ENDIAN we swap only four or more bytes
00166  *  Here we might have funny things with len corresponding to 24 or 56 bits
00167  *  for example
00168  *  @warning Assumption is made that the default order is LITTLE_ENDIAN (which may
00169  *           not be true on some systems !)
00170  *  @warning We do assume that 'result' really contains 'len' bytes of data previously
00171  *           gmalloc'ed
00172  *  @param len : len bytes to change endianness
00173  *  @param endianness : H_DI_BIG_ENDIAN or H_DI_MIDDLE_ENDIAN we consider that there
00174  *         is nothing to do with H_DI_LITTLE_ENDIAN
00175  *  @param[in,out] result : contains the bytes to be swaped and at the end, contains 
00176  *                 the result.
00177  */
00178 static void change_endianness(guint len, guint endianness, guchar *result)
00179 {
00180         if (endianness == H_DI_BIG_ENDIAN)
00181                 {
00182                         if (len > 1) /* We swap bytes only if we have two or more */
00183                                 {
00184                                         swap_bytes(result, 0, len-1);
00185                                 }
00186                         else
00187                                 {
00188                                         reverse_byte_order(result);  /* Only one byte and big endian requested */
00189                                 } 
00190                 }
00191         else if (endianness == H_DI_MIDDLE_ENDIAN && len >= 4)
00192                 {
00193                         swap_bytes(result, 0, (len/2)-1);
00194                         swap_bytes(result, (len/2), len-1);
00195                 }
00196 }
00197 
00198 
00199 /**
00200  * @fn gboolean ghex_memcpy(GtkHex *gh, guint pos, guint len, guint endianness, guchar *result) 
00201  *  Returns 'len' number of bytes located at 'pos' in the GtkHex 
00202  *  document and puts it in the result variable
00203  *
00204  *  @warning We assume that a previous g_malloc has been done in order to
00205  *           use the function. Here we need the "swap_bytes" function
00206  *           defined in the decode.h header in order to take the endianness
00207  *           into account
00208  *  @param gh : A GtkHex document.
00209  *  @param pos : position where we want to begin to copy bytes
00210  *  @param len : number of bytes we want to copy
00211  *  @param endianness : endianness we want to apply to the bytes we want to copy
00212  *  @param[out] result : a previously g_malloc'ed gchar * string that will contain
00213  *              copied bytes.
00214  *  @return TRUE if everything went ok, FALSE otherwise
00215  */
00216 gboolean ghex_memcpy(GtkHex *gh, guint pos, guint len, guint endianness, guchar *result) 
00217 {
00218         guint i;
00219         
00220         if (result == NULL || gh == NULL)
00221                 {
00222                         return FALSE;
00223                 }
00224         else if ((pos < 0) || ((pos+len) > ghex_file_size(gh))) /* pos located in the file limits ! */ 
00225                 {
00226                         return FALSE;
00227                 }
00228         else
00229                 {
00230                         /* Extracts len bytes from the Ghex widget */
00231                         for (i=0; i<len ; i++)
00232                                 {
00233                                                 result[i] = gtk_hex_get_byte(gh, pos+i);
00234                                 }
00235                         
00236                         /* Deals with endianness to rearrange datas */
00237                         change_endianness(len, endianness, result);
00238 
00239                         return TRUE;
00240                 }
00241 }
00242 
00243 
00244 
00245 /**
00246  * @fn ghex_get_data(data_window_t *data_window, guint length, guint endianness, guchar *c)
00247  *  Gets the data from the hexwidget, a wrapper to the ghex_memcpy
00248  *  function. 
00249  *  @warning guchar *c MUST have been pre allocated BEFORE the call.
00250  *           
00251  * @param data_window : data interpretor window structure
00252  * @param length : can be anything but MUST be strictly less than the size allocated 
00253  *        to *c
00254  * @param endianness : H_DI_BIG_ENDIAN, H_DI_MIDDLE_ENDIAN or H_DI_LITTLE_ENDIAN
00255  * @param c : a previously g_malloc'ed gchar * string that will contain
00256  *              copied bytes.
00257  */
00258 gboolean ghex_get_data(data_window_t *data_window, guint length, guint endianness, guchar *c)
00259 {
00260         GtkHex *gh = NULL;
00261         gboolean result = FALSE;
00262 
00263         gh = GTK_HEX(data_window->current_hexwidget);
00264 
00265         if (gh != NULL)
00266                 {
00267                         result = ghex_memcpy(gh, gtk_hex_get_cursor(gh), length, endianness, c);
00268                 }
00269         else
00270                 {
00271                         result = FALSE;
00272                 }
00273         
00274         return result;
00275 }
00276 
00277 
00278 /**
00279  * @fn guint64 ghex_file_size(GtkHex *gh)
00280  *  Returns the file size of an opened GtkHex document.
00281  * @param gh : an opened GtkHex document
00282  * @return resturns the file size of that document
00283  */
00284 guint64 ghex_file_size(GtkHex *gh)
00285 {
00286         if (gh != NULL && gh->document != NULL)
00287                 {
00288                         return gh->document->file_size;
00289                 }
00290         else
00291                 {
00292                         return 0;
00293                 }
00294 }
00295 
00296 /**
00297  * @fn guint64 ghex_get_cursor_position(data_window_t *data_window)
00298  *  Retrieves the cursor's position from the current hexwidget
00299  * @param data_window : data interpretor window structure
00300  * @return returns the cursor's position
00301  */
00302 guint64 ghex_get_cursor_position(data_window_t *data_window)
00303 {
00304         GtkHex *gh = NULL;
00305         
00306         gh = GTK_HEX(data_window->current_hexwidget);
00307         
00308         if (gh != NULL)
00309         {
00310                   return gtk_hex_get_cursor(gh);
00311         }
00312         else
00313         {
00314                   return 0;
00315         }
00316 }

Generated on Sat Mar 14 13:44:29 2009 for Heraia by  doxygen 1.5.6