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

Generated on Tue Jun 30 23:18:17 2009 for Heraia by  doxygen 1.5.8