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