data_interpretor.c

Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
00002 /*
00003   data_interpretor.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 data_interpretor.c
00025  * Here one may find tools to manage the data_interpretor window
00026  */
00027 #include <libheraia.h>
00028 
00029 static guint which_endianness(heraia_window_t *main_window);
00030 static void interpret_as_date(heraia_window_t *main_window, DecodeDateFunc decode_it, gchar *widget_name, guint length, guint endianness);
00031 static void interpret_as_number(heraia_window_t *main_window, DecodeFunc decode_it, gchar *widget_name, guint length, guint endianness);
00032 static void close_data_interpretor_window(GtkWidget *widget, gpointer data);
00033 static void connect_data_interpretor_signals(heraia_window_t *main_window);
00034 
00035 /**
00036  * @fn guint which_endianness(heraia_window_t *main_window)
00037  *  Determines which endianness is selected that is to say
00038  *  which radio button is active in the window
00039  * @param main_window : main structure
00040  * @return Something of the following, depending on what selected the user :
00041  *         - H_DI_LITTLE_ENDIAN for little endian encoding (default answer)
00042  *         - H_DI_BIG_ENDIAN for big endian encoding
00043  *         - H_DI_MIDDLE_ENDIAN for middle endian encoding
00044  */
00045 static guint which_endianness(heraia_window_t *main_window)
00046 {
00047         GtkRadioButton *rb = GTK_RADIO_BUTTON(heraia_get_widget(main_window->xmls->main, "diw_rb_little_endian"));
00048         GtkWidget *activated = NULL;
00049         const gchar *widget_name = NULL;
00050 
00051         activated = gtk_radio_button_get_active_from_widget(rb);
00052         widget_name = gtk_widget_get_name(activated);
00053 
00054         if (g_ascii_strcasecmp(widget_name, "diw_rb_little_endian") == 0)
00055                 {
00056                         return H_DI_LITTLE_ENDIAN;
00057                 }
00058         else if (g_ascii_strcasecmp(widget_name, "diw_rb_big_endian") == 0)
00059                 {
00060                         return H_DI_BIG_ENDIAN;
00061                 }
00062         else if (g_ascii_strcasecmp(widget_name, "diw_rb_middle_endian") == 0)
00063                 {
00064                         return H_DI_MIDDLE_ENDIAN;
00065                 }
00066         else
00067                 return H_DI_LITTLE_ENDIAN;  /* default interpretation case */
00068 }
00069 
00070 
00071 /**
00072  * @fn void interpret_as_date(heraia_window_t *main_window, DecodeDateFunc decode_it, gchar *widget_name, guint length, guint endianness)
00073  *   Here we do interpret a date according to the decode_it function and we 
00074  *   write down the result in a widget name named "widget_name".
00075  * @warning We are assuming that main_window != NULL and main_window->xml != NULL
00076  *
00077  *    @param main_window : main structure
00078  *    @param decode_it : a DecodeDateFunc which is a function to be called to 
00079  *                               decode the stream
00080  *    @param widget_name : a gchar * containing the name of the widget where 
00081  *                               the result may go
00082  *    @param length : the length of the data to be decoded (guint)
00083  *    @param endianness : the endianness to be applied to the datas (as 
00084  *                       returned by function which_endianness)
00085  */
00086 static void interpret_as_date(heraia_window_t *main_window, DecodeDateFunc decode_it, gchar *widget_name, guint length, guint endianness)
00087 {
00088         gint result = 0;       /**< used to test different results of function calls */
00089         guchar *c = NULL;      /**< the character under the cursor                   */
00090         gchar *text = NULL;
00091         data_window_t *data_window = main_window->current_DW;
00092         GtkWidget *entry = heraia_get_widget(main_window->xmls->main, widget_name);
00093         date_and_time_t *mydate = NULL; /**< date resulting of interpretation        */
00094 
00095         c = (guchar *) g_malloc0 (sizeof(guchar) * length);
00096         mydate = (date_and_time_t *) g_malloc0 (sizeof(date_and_time_t));
00097 
00098         result = ghex_get_data(data_window, length, endianness, c);
00099 
00100         if (result == TRUE)
00101                 {
00102                         text = decode_it(c, mydate);
00103 
00104                         if (text != NULL)
00105                                 {
00106                                         gtk_entry_set_text(GTK_ENTRY(entry), text);
00107                                 }
00108                         else
00109                                 {
00110                                         text = g_strdup_printf("Something's wrong!");
00111                                         gtk_entry_set_text(GTK_ENTRY(entry), text);
00112                                 }
00113                 }
00114         else
00115                 {
00116                         text = g_strdup_printf("Cannot interpret as a %d byte(s) date", length);
00117                         gtk_entry_set_text(GTK_ENTRY(entry), text);
00118                 }
00119 
00120         g_free(c);
00121         g_free(text);
00122 }
00123 
00124 
00125 /**
00126  * @fn void interpret_as_number(heraia_window_t *main_window, DecodeFunc decode_it, gchar *widget_name, guint length, guint endianness)
00127  *   Here we do interpret a number according to the decode_it function and we 
00128  *   write down the result in a widget name named "widget_name".
00129  * @warning We are assuming that main_window != NULL and main_window->xml != NULL
00130 *
00131  *    @param main_window : main structure
00132  *    @param decode_it : a DecodeDateFunc which is a function to be called to 
00133  *                               decode the stream
00134  *    @param widget_name : a gchar * containing the name of the widget where 
00135  *                               the result may go
00136  *    @param length : the length of the data to be decoded (guint)
00137  *    @param endianness : the endianness to be applied to the datas (as 
00138  *                       returned by function which_endianness)
00139  */
00140 static void interpret_as_number(heraia_window_t *main_window, DecodeFunc decode_it, gchar *widget_name, guint length, guint endianness)
00141 {
00142         gint result = 0;       /**< used to test different results of function calls */
00143         guchar *c = NULL;      /**< the character under the cursor                   */
00144         gchar *text = NULL;
00145         data_window_t *data_window = main_window->current_DW;   /**< We already know that it's not NULL (we hope so) */
00146         GtkWidget *entry = heraia_get_widget(main_window->xmls->main, widget_name);  /**< @todo we might test the result as this is user input */
00147 
00148         c = (guchar *) g_malloc0(sizeof(guchar) * length);
00149 
00150         result = ghex_get_data(data_window, length, endianness, c);
00151 
00152         if (result == TRUE)
00153                 {
00154                         text = decode_it(c);
00155 
00156                         if (text != NULL)
00157                                 {
00158                                         gtk_entry_set_text(GTK_ENTRY(entry), text);
00159                                 }
00160                         else
00161                                 {
00162                                         text = g_strdup_printf("Something's wrong!");
00163                                         gtk_entry_set_text(GTK_ENTRY(entry), text);
00164                                 }
00165                 }
00166         else
00167                 {
00168                         text = g_strdup_printf("Cannot interpret as a %d byte(s) number", length);
00169                         gtk_entry_set_text(GTK_ENTRY(entry), text);
00170                 }
00171 
00172         g_free(c);
00173         g_free(text);
00174 }
00175 
00176 
00177 /**
00178  * @fn void close_data_interpretor_window(GtkWidget *widget, gpointer data)
00179  *  "Emulates" the user click on the main window menu entry called DIMenu
00180  *  whose aim is to display or hide the data interpretor window
00181  * @param widget : the widget caller (may be NULL here)
00182  * @param data : a gpointer to the main structure : main_window, this must NOT
00183  *        be NULL !
00184  */
00185 static void close_data_interpretor_window(GtkWidget *widget, gpointer data)
00186 {
00187         heraia_window_t *main_window = (heraia_window_t *) data;
00188 
00189         if (main_window != NULL && main_window->xmls != NULL  && main_window->xmls->main)
00190                 {
00191                         g_signal_emit_by_name(heraia_get_widget(main_window->xmls->main, "DIMenu"), "activate");
00192                 }
00193 }
00194 
00195 /**
00196  * @fn void refresh_data_interpretor_window(GtkWidget *widget, gpointer data)
00197  *  Refreshes the data interpretor window with the new values
00198  * @param widget : the widget caller (may be NULL here)
00199  * @param data : a gpointer to the main structure : main_window, this must NOT
00200  *        be NULL !
00201  */
00202 void refresh_data_interpretor_window(GtkWidget *widget, gpointer data)
00203 {
00204         heraia_window_t *main_window = (heraia_window_t *) data;  /**< data interpretor window structure */
00205         guint endianness = 0;
00206 
00207         if (main_window != NULL && main_window->current_DW != NULL && main_window->win_prop->main_dialog->displayed == TRUE)
00208                 {
00209                         endianness = which_endianness(main_window);  /**< Endianness is computed only once here */
00210                         interpret_as_number(main_window, decode_8bits_unsigned, "diw_8bits_us", 1, endianness);
00211                         interpret_as_number(main_window, decode_8bits_signed, "diw_8bits_s", 1, endianness);
00212                         interpret_as_number(main_window, decode_16bits_unsigned, "diw_16bits_us", 2, endianness);
00213                         interpret_as_number(main_window, decode_16bits_signed, "diw_16bits_s", 2, endianness);
00214                         interpret_as_number(main_window, decode_32bits_unsigned, "diw_32bits_us", 4, endianness);
00215                         interpret_as_number(main_window, decode_32bits_signed, "diw_32bits_s", 4, endianness);
00216                         interpret_as_number(main_window, decode_64bits_unsigned, "diw_64bits_us", 8, endianness);
00217                         interpret_as_number(main_window, decode_64bits_signed, "diw_64bits_s", 8, endianness);
00218                         interpret_as_number(main_window, decode_to_bits, "diw_base_bits", 1, endianness);
00219                         interpret_as_number(main_window, decode_packed_BCD, "diw_base_bcd", 1, endianness);
00220 
00221                         interpret_as_date(main_window, decode_C_date, "diw_C_date", 4, endianness);
00222                         interpret_as_date(main_window, decode_dos_date, "diw_msdos_date", 4, endianness);
00223                         interpret_as_date(main_window, decode_filetime_date, "diw_filetime_date", 8, endianness);
00224                         interpret_as_date(main_window, decode_HFS_date, "diw_HFS_date", 4, endianness);
00225 
00226                         refresh_all_ud_data_interpretor(main_window, endianness);
00227                 }
00228 }
00229 
00230 
00231 /**
00232  * @fn void connect_data_interpretor_signals(heraia_window_t *main_window)
00233  *  Connects data interpretor window's signals to the
00234  *  right functions
00235  * @param main_window : main structure
00236  */
00237 static void connect_data_interpretor_signals(heraia_window_t *main_window)
00238 {
00239         /* When data interpretor's window is killed or destroyed */
00240         g_signal_connect(G_OBJECT(heraia_get_widget(main_window->xmls->main, "data_interpretor_window")), "delete_event",
00241                                                   G_CALLBACK(delete_dt_window_event), main_window);
00242 
00243         g_signal_connect(G_OBJECT(heraia_get_widget(main_window->xmls->main, "data_interpretor_window")), "destroy",
00244                                                   G_CALLBACK(destroy_dt_window), main_window);
00245 
00246         /* Menu "close" */
00247         g_signal_connect(G_OBJECT(heraia_get_widget(main_window->xmls->main, "diw_close_menu")), "activate",
00248                                                   G_CALLBACK(close_data_interpretor_window), main_window);
00249 
00250         /* Radio Button "Little Endian" */
00251         g_signal_connect(G_OBJECT(heraia_get_widget(main_window->xmls->main, "diw_rb_little_endian")), "toggled",
00252                                                   G_CALLBACK(refresh_data_interpretor_window), main_window);
00253 
00254         /* Radio Button "Big Endian" */
00255         g_signal_connect(G_OBJECT(heraia_get_widget(main_window->xmls->main, "diw_rb_big_endian")), "toggled",
00256                                                   G_CALLBACK(refresh_data_interpretor_window), main_window);
00257 
00258         /* Radio Button "Middle Endian" */
00259         g_signal_connect(G_OBJECT(heraia_get_widget(main_window->xmls->main, "diw_rb_middle_endian")), "toggled",
00260                                                   G_CALLBACK(refresh_data_interpretor_window), main_window);
00261 }
00262 
00263 /**
00264  * @fn void data_interpretor_init_interface(heraia_window_t *main_window)
00265  *  Inits the data interpretor structure and window with default values
00266  *  @warning Should be called only once at program's beginning
00267  */
00268 void data_interpretor_init_interface(heraia_window_t *main_window)
00269 {
00270         data_window_t *dw = NULL;
00271 
00272         if (main_window != NULL)
00273                 {
00274                         /* Signals connections */
00275                         connect_data_interpretor_signals(main_window);
00276 
00277                         dw = main_window->current_DW;
00278 
00279                         if (dw != NULL)
00280                                 {
00281                                         dw->diw = heraia_get_widget(main_window->xmls->main, "data_interpretor_window");
00282                                         dw->tab_displayed = 0; /* the first tab (Numbers) */
00283                                 }
00284                 }
00285 }

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