ghex_heraia_interface.c

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