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         main_window->current_DW->current_hexwidget = hex_document_add_view(main_window->current_doc);
00052         
00053         connect_cursor_moved_signal(main_window);
00054 
00055         return HERAIA_NOERR;
00056 }
00057 
00058 
00059 /**
00060  * @fn gchar *heraia_hex_document_get_filename(Heraia_Document *doc)
00061  * Retrieves the filename of a document which ever it is !
00062  * @param doc : an existing Heraia_Document @todo : do something if
00063  *        the document does not exist.
00064  * @return returns the filename of that document.
00065  */
00066 gchar *heraia_hex_document_get_filename(Heraia_Document *doc)
00067 {
00068         return doc->file_name;
00069 }
00070 
00071 
00072 /**
00073  * @fn HERAIA_ERROR heraia_hex_document_save(heraia_window_t *main_window)
00074  * Saves an open and edited document
00075  * @param main_window : main structure, @todo may be we only need main_window->current_doc here
00076  * @return returns HERAIA_NOERR if everything went ok or HERAIA_FILE_ERROR in case of an error
00077  */
00078 HERAIA_ERROR heraia_hex_document_save(heraia_window_t *main_window)
00079 {
00080         gint return_value = FALSE;
00081         
00082         if (main_window->current_doc != NULL)
00083            {
00084                                 return_value = hex_document_write(main_window->current_doc);
00085                 }
00086         
00087         if (return_value != FALSE)
00088            {
00089                                 return HERAIA_NOERR;
00090                 }
00091          else
00092            {    
00093                                 return HERAIA_FILE_ERROR;
00094            }
00095 }
00096 
00097 /**
00098  * @fn HERAIA_ERROR heraia_hex_document_save_as(heraia_window_t *main_window, gchar *filename)
00099  * Saves an opened and edited document to a new file
00100  * @param main_window : main structure
00101  * @param filename : the new filename where to save the file
00102  * @return returns HERAIA_NOERR if everything went ok or HERAIA_FILE_ERROR in case of an error
00103  */
00104 HERAIA_ERROR heraia_hex_document_save_as(heraia_window_t *main_window, gchar *filename)
00105 {
00106         gint return_value = FALSE;
00107         FILE *fp = NULL;
00108         gint i = 0;
00109         gchar *path_end = NULL; /**< to make libghex happy ! */
00110         
00111         if (main_window->current_doc != NULL && filename != NULL)
00112            {
00113                         fp = fopen(filename, "w");
00114                         if (fp != NULL)
00115                         {
00116                                 return_value = hex_document_write_to_file(main_window->current_doc, fp);
00117                                 fclose(fp);
00118                                 
00119                                 if (main_window->current_doc->file_name)
00120                                  {
00121                                          g_free(main_window->current_doc->file_name);
00122                                  }
00123                                 main_window->current_doc->file_name = filename;
00124                                 
00125                                 /* This may disappear as it duplicates structures */
00126                                 if (main_window->filename != NULL)
00127                                 {
00128                                          g_free(main_window->filename);
00129                                 }
00130                                 main_window->filename = g_strdup_printf("%s", main_window->current_doc->file_name);
00131                                 
00132                                 /* path_end stuff from ghex-window.c from ghex project !!! */
00133                                 for(i = strlen(main_window->current_doc->file_name);
00134                         (i >= 0) && (main_window->current_doc->file_name[i] != '/');
00135                         i--);
00136                                 if (main_window->current_doc->file_name[i] == '/')
00137                 path_end = &main_window->current_doc->file_name[i+1];
00138                                 else
00139                path_end = main_window->current_doc->file_name;
00140             
00141                                 main_window->current_doc->path_end = g_filename_to_utf8(path_end, -1, NULL, NULL, NULL);
00142                         }
00143                 }
00144         
00145         if (return_value != FALSE)
00146            {
00147                                 return HERAIA_NOERR;
00148                 }
00149          else
00150            {    
00151                                 return HERAIA_FILE_ERROR;
00152            }
00153 }
00154 
00155 /**
00156  * @fn void change_endianness(guint len, guint endianness, guchar *result)
00157  *  Deals with the endianness of 'len' bytes located in 'result'
00158  *  for BIG_ENDIAN we only swap bytes if we have two or more of them
00159  *  if we have only one byte, we reverse its order
00160  *  if endianness is MIDDLE_ENDIAN we swap only four or more bytes
00161  *  Here we might have funny things with len corresponding to 24 or 56 bits
00162  *  for example
00163  *  @warning Assumption is made that the default order is LITTLE_ENDIAN (which may
00164  *           not be true on some systems !)
00165  *  @warning We do assume that 'result' really contains 'len' bytes of data previously
00166  *           gmalloc'ed
00167  *  @param len : len bytes to change endianness
00168  *  @param endianness : H_DI_BIG_ENDIAN or H_DI_MIDDLE_ENDIAN we consider that there
00169  *         is nothing to do with H_DI_LITTLE_ENDIAN
00170  *  @param[in,out] result : contains the bytes to be swaped and at the end, contains 
00171  *                 the result.
00172  */
00173 static void change_endianness(guint len, guint endianness, guchar *result)
00174 {
00175         if (endianness == H_DI_BIG_ENDIAN)
00176                 {
00177                         if (len > 1) /* We swap bytes only if we have two or more */
00178                                 {
00179                                         swap_bytes(result, 0, len-1);
00180                                 }
00181                         else
00182                                 {
00183                                         reverse_byte_order(result);  /* Only one byte and big endian requested */
00184                                 } 
00185                 }
00186         else if (endianness == H_DI_MIDDLE_ENDIAN && len >= 4)
00187                 {
00188                         swap_bytes(result, 0, (len/2)-1);
00189                         swap_bytes(result, (len/2), len-1);
00190                 }
00191 }
00192 
00193 
00194 /**
00195  * @fn gboolean ghex_memcpy(GtkHex *gh, guint pos, guint len, guint endianness, guchar *result) 
00196  *  Returns 'len' number of bytes located at 'pos' in the GtkHex 
00197  *  document and puts it in the result variable
00198  *
00199  *  @warning We assume that a previous g_malloc has been done in order to
00200  *           use the function. Here we need the "swap_bytes" function
00201  *           defined in the decode.h header in order to take the endianness
00202  *           into account
00203  *  @param gh : A GtkHex document.
00204  *  @param pos : position where we want to begin to copy bytes
00205  *  @param len : number of bytes we want to copy
00206  *  @param endianness : endianness we want to apply to the bytes we want to copy
00207  *  @param[out] result : a previously g_malloc'ed gchar * string that will contain
00208  *              copied bytes.
00209  *  @return TRUE if everything went ok, FALSE otherwise
00210  */
00211 gboolean ghex_memcpy(GtkHex *gh, guint pos, guint len, guint endianness, guchar *result) 
00212 {
00213         guint i;
00214         
00215         if (result == NULL || gh == NULL)
00216                 {
00217                         return FALSE;
00218                 }
00219         else if ((pos < 0) || ((pos+len) > ghex_file_size(gh))) /* pos located in the file limits ! */ 
00220                 {
00221                         return FALSE;
00222                 }
00223         else
00224                 {
00225                         /* Extracts len bytes from the Ghex widget */
00226                         for (i=0; i<len ; i++)
00227                                 {
00228                                                 result[i] = gtk_hex_get_byte(gh, pos+i);
00229                                 }
00230                         
00231                         /* Deals with endianness to rearrange datas */
00232                         change_endianness(len, endianness, result);
00233 
00234                         return TRUE;
00235                 }
00236 }
00237 
00238 
00239 
00240 /**
00241  * @fn ghex_get_data(data_window_t *data_window, guint length, guint endianness, guchar *c)
00242  *  Gets the data from the hexwidget, a wrapper to the ghex_memcpy
00243  *  function. 
00244  *  @warning guchar *c MUST have been pre allocated BEFORE the call.
00245  *           
00246  * @param data_window : data interpretor window structure
00247  * @param length : can be anything but MUST be strictly less than the size allocated 
00248  *        to *c
00249  * @param endianness : H_DI_BIG_ENDIAN, H_DI_MIDDLE_ENDIAN or H_DI_LITTLE_ENDIAN
00250  * @param c : a previously g_malloc'ed gchar * string that will contain
00251  *              copied bytes.
00252  */
00253 gboolean ghex_get_data(data_window_t *data_window, guint length, guint endianness, guchar *c)
00254 {
00255         GtkHex *gh = NULL;
00256         gboolean result = FALSE;
00257 
00258         gh = GTK_HEX(data_window->current_hexwidget);
00259 
00260         if (gh != NULL)
00261                 {
00262                         result = ghex_memcpy(gh, gtk_hex_get_cursor(gh), length, endianness, c);
00263                 }
00264         else
00265                 {
00266                         result = FALSE;
00267                 }
00268         
00269         return result;
00270 }
00271 
00272 
00273 /**
00274  * @fn guint64 ghex_file_size(GtkHex *gh)
00275  *  Returns the file size of an opened GtkHex document.
00276  * @param gh : an opened GtkHex document
00277  * @return resturns the file size of that document
00278  */
00279 guint64 ghex_file_size(GtkHex *gh)
00280 {
00281         if (gh != NULL && gh->document != NULL)
00282                 {
00283                         return gh->document->file_size;
00284                 }
00285         else
00286                 {
00287                         return 0;
00288                 }
00289 }
00290 
00291 /**
00292  * @fn guint64 ghex_get_cursor_position(data_window_t *data_window)
00293  *  Retrieves the cursor's position from the current hexwidget
00294  * @param data_window : data interpretor window structure
00295  * @return returns the cursor's position
00296  */
00297 guint64 ghex_get_cursor_position(data_window_t *data_window)
00298 {
00299         GtkHex *gh = NULL;
00300         
00301         gh = GTK_HEX(data_window->current_hexwidget);
00302         
00303         if (gh != NULL)
00304         {
00305                   return gtk_hex_get_cursor(gh);
00306         }
00307         else
00308         {
00309                   return 0;
00310         }
00311 }

Generated on Sat Feb 14 11:44:16 2009 for Heraia by  doxygen 1.5.6