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 main_window : main structure, @todo may be we only need main_window->current_doc here
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(heraia_window_t *main_window)
00125 {
00126         gint return_value = FALSE;
00127 
00128         if (main_window->current_doc != NULL)
00129         {
00130                 if (main_window->current_doc->hex_doc != NULL)
00131                 {
00132                         return_value = hex_document_write(main_window->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 main_window : main 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(heraia_window_t *main_window, 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 (main_window->current_doc != NULL && main_window->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(main_window->current_doc->hex_doc, fp);
00165                                 fclose(fp);
00166 
00167                                 /* This may not be necessary any more as we have separated docs
00168                                  if (main_window->current_doc->file_name)
00169                                  {
00170                                          g_free(main_window->current_doc->file_name);
00171                                  }
00172                                 main_window->current_doc->file_name = filename;
00173                                 */
00174 
00175                                 /* This may disappear as it duplicates structures */
00176                                 /* if (main_window->filename != NULL)
00177                                  {
00178                                          g_free(main_window->filename);
00179                                  }
00180                                  main_window->filename = g_strdup_printf("%s", main_window->current_doc->file_name);
00181                                 */
00182 
00183                                 /* path_end stuff from ghex-window.c from ghex project !!! */
00184                                 for(i = strlen(main_window->current_doc->hex_doc->file_name);
00185                         (i >= 0) && (main_window->current_doc->hex_doc->file_name[i] != '/');
00186                         i--);
00187                                 if (main_window->current_doc->hex_doc->file_name[i] == '/')
00188                                         path_end = &main_window->current_doc->hex_doc->file_name[i+1];
00189                                 else
00190                                         path_end = main_window->current_doc->hex_doc->file_name;
00191 
00192                                 main_window->current_doc->hex_doc->path_end = g_filename_to_utf8(path_end, -1, NULL, NULL, NULL);
00193                         }
00194                 }
00195 
00196         if (return_value != FALSE)
00197         {
00198                 return HERAIA_NOERR;
00199         }
00200         else
00201         {
00202                 return HERAIA_FILE_ERROR;
00203         }
00204 }
00205 
00206 /**
00207  *  Deals with the endianness of 'len' bytes located in 'result'
00208  *  for BIG_ENDIAN we only swap bytes if we have two or more of them
00209  *  if we have only one byte, we reverse its order
00210  *  if endianness is MIDDLE_ENDIAN we swap only four or more bytes
00211  *  Here we might have funny things with len corresponding to 24 or 56 bits
00212  *  for example
00213  *  @warning Assumption is made that the default order is LITTLE_ENDIAN (which may
00214  *           not be true on some systems !)
00215  *  @warning We do assume that 'result' really contains 'len' bytes of data previously
00216  *           gmalloc'ed
00217  *  @param len : len bytes to change endianness
00218  *  @param endianness : H_DI_BIG_ENDIAN or H_DI_MIDDLE_ENDIAN we consider that there
00219  *         is nothing to do with H_DI_LITTLE_ENDIAN
00220  *  @param[in,out] result : contains the bytes to be swaped and at the end, contains
00221  *                 the result.
00222  */
00223 static void change_endianness(guint len, guint endianness, guchar *result)
00224 {
00225         if (endianness == H_DI_BIG_ENDIAN)
00226                 {
00227                         if (len > 1) /* We swap bytes only if we have two or more */
00228                                 {
00229                                         swap_bytes(result, 0, len-1);
00230                                 }
00231                         else
00232                                 {
00233                                         reverse_byte_order(result);  /* Only one byte and big endian requested */
00234                                 }
00235                 }
00236         else if (endianness == H_DI_MIDDLE_ENDIAN && len >= 4)
00237                 {
00238                         swap_bytes(result, 0, (len/2)-1);
00239                         swap_bytes(result, (len/2), len-1);
00240                 }
00241 }
00242 
00243 
00244 /**
00245  *  Returns 'len' number of bytes located at 'pos' in the GtkHex
00246  *  document and puts it in the result variable
00247  *
00248  *  @warning We assume that a previous g_malloc has been done in order to
00249  *           use the function. Here we need the "swap_bytes" function
00250  *           defined in the decode.h header in order to take the endianness
00251  *           into account
00252  *  @param gh : A GtkHex document.
00253  *  @param pos : position where we want to begin to copy bytes
00254  *  @param len : number of bytes we want to copy
00255  *  @param endianness : endianness we want to apply to the bytes we want to copy
00256  *  @param[out] result : a previously g_malloc'ed gchar * string that will contain
00257  *              copied bytes.
00258  *  @return TRUE if everything went ok, FALSE otherwise
00259  */
00260 gboolean ghex_memcpy(GtkHex *gh, guint pos, guint len, guint endianness, guchar *result)
00261 {
00262         guint i;
00263 
00264         if (result == NULL || gh == NULL)
00265                 {
00266                         return FALSE;
00267                 }
00268         else if ((pos < 0) || ((pos+len) > ghex_file_size(gh))) /* pos located in the file limits ! */
00269                 {
00270                         return FALSE;
00271                 }
00272         else
00273                 {
00274                         /* Extracts len bytes from the Ghex widget */
00275                         for (i=0; i<len ; i++)
00276                                 {
00277                                                 result[i] = gtk_hex_get_byte(gh, pos+i);
00278                                 }
00279 
00280                         /* Deals with endianness to rearrange datas */
00281                         change_endianness(len, endianness, result);
00282 
00283                         return TRUE;
00284                 }
00285 }
00286 
00287 
00288 
00289 /**
00290  *  Gets the data from the hexwidget, a wrapper to the ghex_memcpy
00291  *  function.
00292  *  @warning guchar *c MUST have been pre allocated BEFORE the call.
00293  *
00294  * @param data_window : data interpretor window structure
00295  * @param length : can be anything but MUST be strictly less than the size allocated
00296  *        to *c
00297  * @param endianness : H_DI_BIG_ENDIAN, H_DI_MIDDLE_ENDIAN or H_DI_LITTLE_ENDIAN
00298  * @param c : a previously g_malloc'ed gchar * string that will contain
00299  *              copied bytes.
00300  */
00301 gboolean ghex_get_data(GtkWidget *hex_widget, guint length, guint endianness, guchar *c)
00302 {
00303         gboolean result = FALSE;
00304         GtkHex *gh = GTK_HEX(hex_widget);
00305 
00306         if (gh != NULL)
00307                 {
00308                         result = ghex_memcpy(gh, gtk_hex_get_cursor(gh), length, endianness, c);
00309                 }
00310         else
00311                 {
00312                         result = FALSE;
00313                 }
00314 
00315         return result;
00316 }
00317 
00318 
00319 /**
00320  *  Returns the file size of an opened GtkHex document.
00321  * @param gh : an opened GtkHex document
00322  * @return resturns the file size of that document
00323  */
00324 guint64 ghex_file_size(GtkHex *gh)
00325 {
00326         if (gh != NULL && gh->document != NULL)
00327                 {
00328                         return gh->document->file_size;
00329                 }
00330         else
00331                 {
00332                         return 0;
00333                 }
00334 }
00335 
00336 /**
00337  *  Retrieves the cursor's position from the current hexwidget
00338  * @param data_window : data interpretor window structure
00339  * @return returns the cursor's position
00340  */
00341 guint64 ghex_get_cursor_position(GtkWidget *hex_widget)
00342 {
00343         GtkHex *gh = GTK_HEX(hex_widget);
00344 
00345         if (gh != NULL)
00346         {
00347                   return gtk_hex_get_cursor(gh);
00348         }
00349         else
00350         {
00351                   return 0;
00352         }
00353 }
00354 
00355 
00356 /**
00357  * Inits a doc_t structure
00358  * @param doc : hex_document but encapsulated in Heraia_Document
00359  *              structure
00360  * @param hexwidget : Widget to display an hexadecimal view of the file
00361  * @return returns a newly allocated doc_t structure
00362  */
00363 doc_t *new_doc_t(Heraia_Document *hex_doc, GtkWidget *hex_widget)
00364 {
00365         doc_t *new_doc;
00366 
00367         new_doc = (doc_t *) g_malloc0(sizeof(doc_t));
00368 
00369         new_doc->hex_doc = hex_doc;
00370         new_doc->hex_widget = hex_widget;
00371 
00372         return new_doc;
00373 }

Generated on Tue May 19 20:01:37 2009 for Heraia by  doxygen 1.5.8