Heraia  0.1.8
data_interpretor.c
Go to the documentation of this file.
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /*
3  data_interpretor.c
4  heraia - an hexadecimal file editor and analyser based on ghex
5 
6  (C) Copyright 2005 - 2011 Olivier Delhomme
7  e-mail : heraia@delhomme.org
8  URL : http://heraia.tuxfamily.org
9 
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2, or (at your option)
13  any later version.
14 
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program; if not, write to the Free Software
22  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
23 /**
24  * @file data_interpretor.c
25  * Here one may find tools to manage the data_interpretor window
26  */
27 #include <libheraia.h>
28 
29 static void interpret(doc_t *doc, decode_t *decode_struct, decode_parameters_t *decode_parameters, guint length);
30 static void connect_data_interpretor_signals(heraia_struct_t *main_struct);
31 static void refresh_one_row(doc_t *doc, decode_generic_t *row, guint nb_cols, decode_parameters_t *decode_parameters);
32 static void refresh_one_tab(doc_t *doc, data_window_t *dw, tab_t *tab, decode_parameters_t *decode_parameters);
33 static void refresh_all_tabs(doc_t *doc, data_window_t *dw, decode_parameters_t *decode_parameters);
34 static void add_default_tabs(heraia_struct_t *main_struct);
35 
36 
37 /**
38  * @fn guint which_endianness(heraia_struct_t *main_struct)
39  * Determines which endianness is selected that is to say
40  * which radio button is active in the window
41  * @param main_struct : main structure
42  * @return Something of the following, depending on what selected the user :
43  * - H_DI_LITTLE_ENDIAN for little endian encoding (default answer)
44  * - H_DI_BIG_ENDIAN for big endian encoding
45  * - H_DI_MIDDLE_ENDIAN for middle endian encoding
46  */
47 guint which_endianness(heraia_struct_t *main_struct)
48 {
49  gint endianness = -1;
50 
51  endianness = di_get_endianness(main_struct);
52 
53  if (endianness > 0)
54  {
55  return endianness; /* Here everything went ok */
56  }
57  else
58  {
59  return H_DI_LITTLE_ENDIAN; /* default interpretation case */
60  }
61 }
62 
63 
64 /**
65  * returns stream size as selected in the spin button
66  * @param main_struct : main structure
67  * @return returns the value of the spin button or 1 if this value is not valid
68  */
70 {
71  guint stream_size = 1;
72 
73  stream_size = di_get_stream_size(main_struct);
74 
75  if (stream_size >= 1)
76  {
77  return stream_size;
78  }
79  else
80  {
81  return 1; /* Minimum stream_size */
82  }
83 }
84 
85 
86 /**
87  * Here we do interpret a something according to the decode_it function and we
88  * write down the result in a widget designated "entry"
89  * @warning We are assuming that main_struct != NULL and main_struct->xml != NULL
90  *
91  * @param main_struct : main structure
92  * @param decode : a decode_t structure that contains function, entry and error message
93  * @param decode_parameters : structure that passes some arguments to the
94  * decoding functions
95  * @param length : the length of the data to be decoded (guint)
96  */
97 static void interpret(doc_t *doc, decode_t *decode_struct, decode_parameters_t *decode_parameters, guint length)
98 {
99  gint result = 0; /** used to test different results of function calls */
100  guchar *c = NULL; /** the character under the cursor */
101  gchar *text = NULL; /** decoded text */
102  DecodeFunc decode_it = NULL; /** A DecodeFunc which is a function to be called to decode the stream */
103 
104  c = (guchar *) g_malloc0(sizeof(guchar) * length);
105 
106  result = ghex_get_data(doc->hex_widget, length, decode_parameters->endianness, c);
107 
108  if (result == TRUE)
109  {
110  decode_it = decode_struct->func;
111 
112  text = decode_it(c, (gpointer) decode_parameters);
113 
114  if (text != NULL)
115  {
116  gtk_entry_set_text(GTK_ENTRY(decode_struct->entry), text);
117  }
118  else
119  {
120  text = g_strdup_printf(Q_("Something's wrong!"));
121  gtk_entry_set_text(GTK_ENTRY(decode_struct->entry), text);
122  }
123  }
124  else
125  {
126  if (decode_struct->err_msg != NULL)
127  {
128  text = g_strdup_printf(decode_struct->err_msg, length);
129  }
130  else
131  {
132  text = g_strdup_printf(Q_("Cannot interpret as a %d byte(s)"), length);
133  }
134 
135  gtk_entry_set_text(GTK_ENTRY(decode_struct->entry), text);
136  }
137 
138  g_free(c);
139  g_free(text);
140 }
141 
142 
143 /**
144  * This function refreshes one row of the tab
145  * @param dw : current data window
146  * @param row : the row that we want to refresh
147  * @param nb_cols : number of columns in this particular row (this IS the same
148  * for all rows in that tab
149  * @param decode_parameters : structure that passes some arguments to the
150  * decoding functions
151  */
152 static void refresh_one_row(doc_t *doc, decode_generic_t *row, guint nb_cols, decode_parameters_t *decode_parameters)
153 {
154  decode_t *decode = NULL; /**< entry, function and message */
155  guint i = 0 ;
156 
157  while ( i < nb_cols)
158  {
159  decode = g_ptr_array_index(row->decode_array, i);
160 
161  if (row->fixed_size == FALSE)
162  {
163  row->data_size = decode_parameters->stream_size;
164  }
165 
166  interpret(doc, decode, decode_parameters, row->data_size);
167  i++;
168  }
169 }
170 
171 
172 /**
173  * This function refreshes one entire tab (row by row)
174  * @param dw : current data window
175  * @param tab : the tab to refresh
176  * @param decode_parameters : structure that passes some arguments to the
177  * decoding functions
178  */
179 static void refresh_one_tab(doc_t *doc, data_window_t *dw, tab_t *tab, decode_parameters_t *decode_parameters)
180 {
181  decode_generic_t *row = NULL; /**< the row we want to refresh */
182  guint i = 0;
183 
184  while (i < tab->nb_rows)
185  {
186  row = g_ptr_array_index(tab->rows, i);
187  refresh_one_row(doc, row, tab->nb_cols - 1, decode_parameters);
188  i++;
189  }
190 }
191 
192 
193 /**
194  * Refreshes all tabs
195  * @param dw : current data window
196  * @param decode_parameters : structure that passes some arguments to the
197  * decoding functions
198  */
199 static void refresh_all_tabs(doc_t *doc, data_window_t *dw, decode_parameters_t *decode_parameters)
200 {
201  tab_t *tab = NULL;
202  guint i = 0;
203 
204  while (i < dw->nb_tabs)
205  {
206  tab = g_ptr_array_index(dw->tabs, i);
207  refresh_one_tab(doc, dw, tab, decode_parameters);
208  i++;
209  }
210 
211 }
212 
213 
214 /**
215  * @fn void refresh_data_interpretor_window(GtkWidget *widget, gpointer data)
216  * Refreshes the data interpretor window with the new values
217  * @param widget : the widget caller (may be NULL here)
218  * @param data : a gpointer to the main structure : main_struct, this must NOT
219  * be NULL !
220  * @todo if speed is a matter, think about taking off this decode_parameters
221  * structure from here.
222  */
223 void refresh_data_interpretor_window(GtkWidget *widget, gpointer data)
224 {
225  heraia_struct_t *main_struct = (heraia_struct_t *) data; /** data interpretor window structure */
226  decode_parameters_t *decode_parameters = NULL;
227  guint endianness = 0;
228  guint stream_size = 0;
229 
230  if (main_struct != NULL &&
231  main_struct->current_doc != NULL &&
232  main_struct->current_DW != NULL &&
233  main_struct->win_prop->main_dialog->displayed == TRUE)
234  {
235  endianness = which_endianness(main_struct); /** Endianness is computed only once here */
236  stream_size = which_stream_size(main_struct); /** stream size is computed only once here */
237 
238  decode_parameters = new_decode_parameters_t(endianness, stream_size);
239 
240  refresh_all_tabs(main_struct->current_doc, main_struct->current_DW, decode_parameters);
241 
242  g_free(decode_parameters);
243  }
244 }
245 
246 
247 /**
248  * @fn void connect_data_interpretor_signals(heraia_struct_t *main_struct)
249  * Connects data interpretor window's signals to the
250  * right functions
251  * @param main_struct : main structure
252  */
254 {
255  /* When data interpretor's window is killed or destroyed */
256  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "data_interpretor_window")), "delete_event",
257  G_CALLBACK(delete_dt_window_event), main_struct);
258 
259  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "data_interpretor_window")), "destroy",
260  G_CALLBACK(destroy_dt_window), main_struct);
261 
262  /* Radio Button "Little Endian" */
263  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "diw_rb_little_endian")), "toggled",
264  G_CALLBACK(refresh_data_interpretor_window), main_struct);
265 
266  /* Radio Button "Big Endian" */
267  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "diw_rb_big_endian")), "toggled",
268  G_CALLBACK(refresh_data_interpretor_window), main_struct);
269 
270  /* Radio Button "Middle Endian" */
271  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "diw_rb_middle_endian")), "toggled",
272  G_CALLBACK(refresh_data_interpretor_window), main_struct);
273 
274  /* Spin button */
275  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "stream_size_spin_button")), "value-changed",
276  G_CALLBACK(refresh_data_interpretor_window), main_struct);
277 }
278 
279 
280 /**
281  * @fn void data_interpretor_init_interface(heraia_struct_t *main_struct)
282  * Inits the data interpretor structure and window with default values
283  * @warning Should be called only once at program's beginning
284  */
286 {
287  data_window_t *dw = NULL;
288 
289  if (main_struct != NULL)
290  {
291  /* Signals connections */
293 
294  dw = main_struct->current_DW;
295 
296  if (dw != NULL)
297  {
298  dw->diw = heraia_get_widget(main_struct->xmls->main, "data_interpretor_window");
299 
300  /* Here init all defaults tabs */
301  add_default_tabs(main_struct);
302  }
303  }
304 }
305 
306 
307 /**
308  * Adds a new tab in the data interpretor window
309  * @param notebook : the notebook to which we want to add this new tab
310  * @param index : index of this new tab. If you rely on this make sure it's
311  * a primary key !
312  * @param label : label of the tab
313  * @param nb_cols : number of columns (including the first column of labels)
314  * @param ... : nb_cols arguments that will be the labels of the columns
315  * @return a newly malloced tab_t variable that remember everything about that
316  * new tab.
317  */
318 tab_t *add_new_tab_in_data_interpretor(GtkNotebook *notebook, guint index, const gchar *label, guint nb_cols, ...)
319 {
320  tab_t *tab = NULL; /**< tab structure that will remember everything ! */
321  va_list args; /**< va_list arguments passed to create a new tab with those columns */
322  guint i = 0;
323  gchar *va_label = NULL; /**< used to fetch arguments */
324  GPtrArray *col_labels = NULL; /**< used to remember the columns labels (the arguments in GtkWidgets) */
325  GPtrArray *vboxes = NULL; /**< used to remember vboxes (in order to be able to pack things later */
326  GtkWidget *child = NULL; /**< notebook tab's child container */
327  GtkWidget *hpaned = NULL; /**< used for hpaned creation */
328  GtkWidget *hpaned2 = NULL; /**< in case that we have more than 2 arguments */
329  GtkWidget *vbox = NULL; /**< used for vbox creation */
330  GtkWidget *vbox_label = NULL; /**< used for label creation in the new vboxes */
331 
332  col_labels = g_ptr_array_new();
333  vboxes = g_ptr_array_new();
334 
335  va_start(args, nb_cols);
336  for (i = 0 ; i < nb_cols ; i++)
337  {
338  va_label = va_arg(args, gchar *);
339  if (va_label != NULL)
340  {
341  vbox_label = gtk_label_new(va_label);
342  gtk_misc_set_padding(GTK_MISC(vbox_label), 3, 3); /* properties for the labels */
343  gtk_misc_set_alignment(GTK_MISC(vbox_label), 0.5, 0.5);
344  g_ptr_array_add(col_labels, (gpointer) vbox_label); /* Keeping a pointer to the label */
345  }
346  }
347  va_end(args);
348 
349  tab = (tab_t *) g_malloc0(sizeof(tab_t));
350 
351  i = 0;
352 
353  #if GTK_MAJOR_VERSION < 3
354  /* valid in GTK+ 2.x */
355  hpaned = gtk_hpaned_new();
356  #endif
357  #if GTK_MAJOR_VERSION >= 3
358  #if GTK_MINOR_VERSION <= 1
359  /* valid in GTK+ 3.0 and 3.1 */
360  hpaned = gtk_hpaned_new();
361  #endif
362  #if GTK_MINOR_VERSION >= 2
363  /* only valid from GTK 3.2 */
364  hpaned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
365  #endif
366  #endif
367 
368  gtk_container_set_border_width(GTK_CONTAINER(hpaned), 2); /* properties for the hpaned */
369  child = hpaned;
370 
371  #if GTK_MAJOR_VERSION < 3
372  /* valid in GTK+ 2.x */
373  vbox = gtk_vbox_new(FALSE, 2);
374  #endif
375  #if GTK_MAJOR_VERSION >= 3
376  #if GTK_MINOR_VERSION <= 1
377  /* valid in GTK+ 3.0 and 3.1 */
378  vbox = gtk_vbox_new(FALSE, 2);
379  #endif
380  #if GTK_MINOR_VERSION >= 2
381  /* only valid from GTK 3.2 */
382  vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
383  #endif
384  #endif
385 
386  gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
387  g_ptr_array_add(vboxes, vbox);
388  gtk_paned_add1(GTK_PANED(hpaned), (gpointer) vbox);
389  vbox_label = g_ptr_array_index(col_labels, i);
390  gtk_box_pack_start(GTK_BOX(vbox), vbox_label, FALSE, FALSE, 3);
391 
392  i++;
393  while (i < nb_cols-1)
394  {
395  #if GTK_MAJOR_VERSION < 3
396  /* valid in GTK+ 2.x */
397  hpaned2 = gtk_hpaned_new();
398  #endif
399  #if GTK_MAJOR_VERSION >= 3
400  #if GTK_MINOR_VERSION <= 1
401  /* valid in GTK+ 3.0 and 3.1 */
402  hpaned2 = gtk_hpaned_new();
403  #endif
404  #if GTK_MINOR_VERSION >= 2
405  /* only valid from GTK 3.2 */
406  hpaned2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
407  #endif
408  #endif
409 
410  gtk_container_set_border_width(GTK_CONTAINER(hpaned2), 2); /* properties for the hpaned */
411  gtk_paned_add2(GTK_PANED(hpaned), hpaned2);
412  hpaned = hpaned2; /* translation */
413 
414  #if GTK_MAJOR_VERSION < 3
415  /* valid in GTK+ 2.x */
416  vbox = gtk_vbox_new(FALSE, 2);
417  #endif
418  #if GTK_MAJOR_VERSION >= 3
419  #if GTK_MINOR_VERSION <= 1
420  /* valid in GTK+ 3.0 and 3.1 */
421  vbox = gtk_vbox_new(FALSE, 2);
422  #endif
423  #if GTK_MINOR_VERSION >= 2
424  /* only valid from GTK 3.2 */
425  vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
426  #endif
427  #endif
428 
429  gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
430  g_ptr_array_add(vboxes, (gpointer) vbox);
431  gtk_paned_add1(GTK_PANED(hpaned), vbox);
432  vbox_label = g_ptr_array_index(col_labels, i);
433  gtk_box_pack_start(GTK_BOX(vbox), vbox_label, FALSE, FALSE, 3);
434  i++;
435  }
436 
437  #if GTK_MAJOR_VERSION < 3
438  /* valid in GTK+ 2.x */
439  vbox = gtk_vbox_new(FALSE, 2);
440  #endif
441  #if GTK_MAJOR_VERSION >= 3
442  #if GTK_MINOR_VERSION <= 1
443  /* valid in GTK+ 3.0 and 3.1 */
444  vbox = gtk_vbox_new(FALSE, 2);
445  #endif
446  #if GTK_MINOR_VERSION >= 2
447  /* only valid from GTK 3.2 */
448  vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
449  #endif
450  #endif
451 
452  g_ptr_array_add(vboxes, (gpointer) vbox);
453  gtk_paned_add2(GTK_PANED(hpaned), vbox);
454  gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
455  vbox_label = g_ptr_array_index(col_labels, i);
456  gtk_box_pack_start(GTK_BOX(vbox), vbox_label, FALSE, FALSE, 3);
457 
458  tab->index = index;
459  tab->nb_cols = nb_cols;
460  tab->nb_rows = 0;
461  tab->label = gtk_label_new(label); /* tab's label */
462  gtk_misc_set_padding(GTK_MISC(tab->label), 2, 2);
463  gtk_misc_set_alignment(GTK_MISC(tab->label), 0.5, 0.5);
464  tab->col_labels = col_labels;
465  tab->vboxes = vboxes;
466  tab->rows = NULL;
467 
468  gtk_widget_show_all(child);
469  gtk_notebook_append_page(notebook, child, tab->label);
470 
471  return tab;
472 }
473 
474 
475 /**
476  * Adds a row to a particular tab
477  * @param tab : the tab to which we want to add the row
478  * @param row : the row we want to add (make sure it has been initialized)
479  */
481 {
482  GtkWidget *vbox = NULL; /**< the vbox to which we want to pack */
483  decode_t *couple = NULL; /**< couple from which we want to pack the entry */
484  guint i = 0;
485  guint j = 0;
486 
487  if (tab != NULL && row != NULL)
488  {
489 
490  if (tab->rows == NULL)
491  {
492  tab->rows = g_ptr_array_new();
493  }
494 
495  g_ptr_array_add(tab->rows, (gpointer) row);
496  tab->nb_rows++;
497 
498  /* label packing */
499  vbox = g_ptr_array_index(tab->vboxes, 0);
500  gtk_box_pack_start(GTK_BOX(vbox), row->label, FALSE, FALSE, 3);
501 
502  j = 0;
503  i = 1; /* first column is for labels (0) */
504 
505  while (i < tab->nb_cols)
506  {
507  vbox = g_ptr_array_index(tab->vboxes, i);
508  couple = g_ptr_array_index(row->decode_array, j);
509  gtk_box_pack_start(GTK_BOX(vbox), couple->entry, FALSE, FALSE, 1);
510  gtk_widget_show(couple->entry);
511  j++;
512  i++;
513  }
514  }
515 }
516 
517 
518 /**
519  * Inits data interpretor with default tabs
520  * Must be called only once at bootime
521  * @param main_struct : main structure
522  * */
523 static void add_default_tabs(heraia_struct_t *main_struct)
524 {
525  GtkWidget *notebook = NULL;
526  tab_t *tab = NULL;
527  decode_generic_t *row = NULL;
528  data_window_t *dw = NULL;
529 
530  dw = main_struct->current_DW;
531  notebook = heraia_get_widget(main_struct->xmls->main, "diw_notebook");
532 
533  dw->tabs = g_ptr_array_new();
534 
535  /** Adding a tab for numbers */
536  tab = add_new_tab_in_data_interpretor(GTK_NOTEBOOK(notebook), 0, Q_("Numbers"), 3, Q_("Length"), Q_("Value unsigned"), Q_("Value signed"));
537 
538  if (tab != NULL)
539  {
540  g_ptr_array_add(dw->tabs, (gpointer) tab);
541  dw->nb_tabs++;
542  row = new_decode_generic_t("8 bits", 1, TRUE, Q_("Can not interpret %d byte as a 8 bits number"), 2, decode_8bits_unsigned, decode_8bits_signed);
543  add_new_row_to_tab(tab, row);
544  row = new_decode_generic_t("16 bits", 2, TRUE, Q_("Can not interpret %d bytes as a 16 bits number"), 2, decode_16bits_unsigned, decode_16bits_signed);
545  add_new_row_to_tab(tab, row);
546  row = new_decode_generic_t("32 bits", 4, TRUE, Q_("Can not interpret %d bytes as a 32 bits number"), 2, decode_32bits_unsigned, decode_32bits_signed);
547  add_new_row_to_tab(tab, row);
548  row = new_decode_generic_t("64 bits", 8, TRUE, Q_("Can not interpret %d bytes as a 64 bits number"), 2, decode_64bits_unsigned, decode_64bits_signed);
549  add_new_row_to_tab(tab, row);
550  }
551 
552  /** Adding a tab for floting numbers */
553  tab = add_new_tab_in_data_interpretor(GTK_NOTEBOOK(notebook), 1, Q_("Floats"), 3, Q_("Length"), Q_("Normal Notation"), Q_("Exponential notation"));
554 
555  if (tab != NULL)
556  {
557  g_ptr_array_add(dw->tabs, (gpointer) tab);
558  dw->nb_tabs++;
559  row = new_decode_generic_t(Q_("Float (32 bits)"), 4, TRUE, Q_("Can not interpret %d bytes as a float number"), 2, decode_float_normal, decode_float_scientific);
560  add_new_row_to_tab(tab, row);
561  row = new_decode_generic_t(Q_("Double (64 bits)"), 8, TRUE, Q_("Can not interpret %d bytes as a double number"), 2, decode_double_normal, decode_double_scientific);
562  add_new_row_to_tab(tab, row);
563  }
564 
565  /** Adding a tab for date and time */
566  tab = add_new_tab_in_data_interpretor(GTK_NOTEBOOK(notebook), 2, Q_("Dates and Times"), 2, Q_("Type"), Q_("Value"));
567 
568  if (tab != NULL)
569  {
570  g_ptr_array_add(dw->tabs, (gpointer) tab);
571  dw->nb_tabs++;
572  row = new_decode_generic_t("MS-DOS", 4, TRUE, Q_("Can not interpret %d bytes as a DOS date"), 1, decode_dos_date);
573  add_new_row_to_tab(tab, row);
574  row = new_decode_generic_t("Filetime", 8, TRUE, Q_("Can not interpret %d bytes as a filetime date"), 1, decode_filetime_date);
575  add_new_row_to_tab(tab, row);
576  row = new_decode_generic_t("C", 4, TRUE, Q_("Can not interpret %d bytes as a C date"), 1, decode_C_date);
577  add_new_row_to_tab(tab, row);
578  row = new_decode_generic_t("HFS", 4, TRUE, Q_("Can not interpret %d bytes as a HFS date"), 1, decode_HFS_date);
579  add_new_row_to_tab(tab, row);
580  }
581 
582  /** Adding a tab for binary based conversions */
583  tab = add_new_tab_in_data_interpretor(GTK_NOTEBOOK(notebook), 3, Q_("Binary based"), 2, Q_("Type"), Q_("Value"));
584 
585  if (tab != NULL)
586  {
587  g_ptr_array_add(dw->tabs, (gpointer) tab);
588  dw->nb_tabs++;
589  row = new_decode_generic_t("Bits", 1, FALSE, Q_("Can not decode %d byte(s) to bits"), 1, decode_to_bits);
590  add_new_row_to_tab(tab, row);
591  row = new_decode_generic_t(Q_("Packed BCD"), 1, FALSE, Q_("Can not interpret %d byte(s) as packed BCD string"), 1, decode_packed_BCD);
592  add_new_row_to_tab(tab, row);
593  }
594 }
595 
596 
597 /**
598  * Gets the selected tab (if any) from data interpretor's notebook
599  * @param main_struct : main structure
600  * @return A gint that represents the selected tab : >=0 if any < 0 otherwise
601  */
603 {
604  GtkNotebook *notebook = NULL; /**< data interpretor's notebook */
605  gint selected_tab = -1; /**< Selected tab in data interpretor's window */
606 
607  notebook = GTK_NOTEBOOK(heraia_get_widget(main_struct->xmls->main, "diw_notebook"));
608 
609  if (notebook != NULL)
610  {
611  selected_tab = gtk_notebook_get_current_page(notebook);
612  }
613 
614  return selected_tab;
615 }
616 
617 
618 /**
619  * Sets the selected tab (if possible) to data interpretor's notebook
620  * @param main_struct : main structure
621  * @param selected_tab : the saved selected tab
622  */
623 void di_set_selected_tab(heraia_struct_t *main_struct, gint selected_tab)
624 {
625  GtkNotebook *notebook = NULL; /**< data interpretor's notebook */
626 
627  if (selected_tab >= 0)
628  {
629  notebook = GTK_NOTEBOOK(heraia_get_widget(main_struct->xmls->main, "diw_notebook"));
630 
631  if (notebook != NULL)
632  {
633  gtk_notebook_set_current_page(notebook, selected_tab);
634  main_struct->current_DW->tab_displayed = selected_tab;
635  }
636  }
637 }
638 
639 
640 /**
641  * Gets the stream_size (if any) from data interpretor's window
642  * @param main_struct : main structure
643  * @return A gint that represents the stream size : >=0 if any < 0 otherwise
644  */
646 {
647  GtkSpinButton *spin_button = NULL; /**< data interpretor's spin button */
648  gint stream_size = -1; /**< stream size sat by the user */
649 
650  spin_button = GTK_SPIN_BUTTON(heraia_get_widget(main_struct->xmls->main, "stream_size_spin_button"));
651 
652  if (spin_button != NULL)
653  {
654  stream_size = gtk_spin_button_get_value_as_int(spin_button);
655  }
656 
657  return stream_size;
658 }
659 
660 
661 /**
662  * Sets the stream size (if possible) to data interpretor's notebook
663  * @param main_struct : main structure
664  * @param stream_size : the saved stream_size
665  */
666 void di_set_stream_size(heraia_struct_t *main_struct, gint stream_size)
667 {
668  GtkSpinButton *spin_button = NULL; /**< data interpretor's spin button */
669 
670  if (stream_size >= 0)
671  {
672  spin_button = GTK_SPIN_BUTTON(heraia_get_widget(main_struct->xmls->main, "stream_size_spin_button"));
673 
674  if (spin_button != NULL)
675  {
676  gtk_spin_button_set_value(spin_button, (gdouble) stream_size);
677  }
678  }
679 }
680 
681 
682 /**
683  * Gets the endianness as selected in the radio group button
684  * @param main_struct : main structure
685  * @return a gint that represents the endianness (H_DI_LITTLE_ENDIAN,
686  * H_DI_MIDDLE_ENDIAN, H_DI_BIG_ENDIAN) or -1 if nothing was correct
687  */
689 {
690  GtkWidget *rb = NULL;
691  GtkWidget *activated = NULL;
692  const gchar *widget_name = NULL;
693 
694  rb = heraia_get_widget(main_struct->xmls->main, "diw_rb_little_endian");
695 
696  if (rb != NULL)
697  {
698  activated = gtk_radio_button_get_active_from_widget(GTK_RADIO_BUTTON(rb));
699 
700  if (activated != NULL)
701  {
702  widget_name = gtk_buildable_get_name(GTK_BUILDABLE(activated));
703  }
704  }
705 
706  if (widget_name != NULL)
707  {
708  if (g_ascii_strcasecmp(widget_name, "diw_rb_little_endian") == 0)
709  {
710  return H_DI_LITTLE_ENDIAN;
711  }
712  else if (g_ascii_strcasecmp(widget_name, "diw_rb_big_endian") == 0)
713  {
714  return H_DI_BIG_ENDIAN;
715  }
716  else if (g_ascii_strcasecmp(widget_name, "diw_rb_middle_endian") == 0)
717  {
718  return H_DI_MIDDLE_ENDIAN;
719  }
720  else
721  {
722  return -1;
723  }
724  }
725  else
726  {
727  return -1;
728  }
729 }
730 
731 
732 /**
733  * Sets the endianness as stated by the second parameter
734  * @param main_struct : main structure
735  * @param endianness : the endianness to be sat. Must be one of the following :
736  * (H_DI_LITTLE_ENDIAN, H_DI_MIDDLE_ENDIAN, H_DI_BIG_ENDIAN)
737  */
738 extern void di_set_endianness(heraia_struct_t *main_struct, gint endianness)
739 {
740  GtkWidget *rb = NULL;
741 
742  switch (endianness)
743  {
744  case H_DI_BIG_ENDIAN:
745  rb = heraia_get_widget(main_struct->xmls->main, "diw_rb_big_endian");
746  gtk_radio_button_set_active(GTK_RADIO_BUTTON(rb));
747  break;
748 
749  case H_DI_MIDDLE_ENDIAN:
750  rb = heraia_get_widget(main_struct->xmls->main, "diw_rb_middle_endian");
751  gtk_radio_button_set_active(GTK_RADIO_BUTTON(rb));
752  break;
753 
754  case H_DI_LITTLE_ENDIAN:
755  default:
756  rb = heraia_get_widget(main_struct->xmls->main, "diw_rb_little_endian");
757  gtk_radio_button_set_active(GTK_RADIO_BUTTON(rb));
758  }
759 
760 }
This is the main structure.
Definition: libheraia.h:332
gchar * decode_16bits_unsigned(guchar *data, gpointer data_struct)
general purpose of this function is to take a 2 byte data stream and convert it as if it is a 16 bits...
Definition: decode.c:118
static void interpret(doc_t *doc, decode_t *decode_struct, decode_parameters_t *decode_parameters, guint length)
Here we do interpret a something according to the decode_it function and we write down the result in ...
gboolean fixed_size
says whether we can modify data_size or not
Definition: libheraia.h:181
gchar * err_msg
error message if something went wrong when decoding expects a d somewhere in the message to represent...
Definition: libheraia.h:164
#define H_DI_MIDDLE_ENDIAN
Stands for middle endian representation (http://en.wikipedia.org/wiki/Endianness#Middle-endian) ...
Tabulation structure to be used in the GtkNoteBook of data_interpretor's window.
Definition: libheraia.h:190
gint tab_displayed
keeps the last displayed tab's number before closing
Definition: libheraia.h:209
static void add_default_tabs(heraia_struct_t *main_struct)
Inits data interpretor with default tabs Must be called only once at bootime.
gchar * decode_double_scientific(guchar *data, gpointer data_struct)
general purpose of this function is to take a 8 byte data stream and convert it as if it is a float n...
Definition: decode.c:302
void gtk_radio_button_set_active(GtkRadioButton *radio_button)
Sets the radio button active.
Definition: heraia_ui.c:2115
window_prop_t * main_dialog
heraia's main window
Definition: libheraia.h:264
gboolean displayed
TRUE if displayed, FALSE otherwise.
Definition: libheraia.h:249
gchar * decode_32bits_unsigned(guchar *data, gpointer data_struct)
general purpose of this function is to take a 4 byte data stream and convert it as if it is a 32 bits...
Definition: decode.c:164
guint data_size
size of what we may decode
Definition: libheraia.h:180
gboolean delete_dt_window_event(GtkWidget *widget, GdkEvent *event, gpointer data)
call back function for the data interpretor window destruction
Definition: heraia_ui.c:1200
DecodeFunc func
a function to decode into something
Definition: libheraia.h:162
guint nb_rows
number of rows in this tab - this is automatically updated
Definition: libheraia.h:194
all_window_prop_t * win_prop
Keeps window properties.
Definition: libheraia.h:342
gint di_get_stream_size(heraia_struct_t *main_struct)
Gets the stream_size (if any) from data interpretor's window.
gchar * decode_float_scientific(guchar *data, gpointer data_struct)
general purpose of this function is to take a 4 byte data stream and convert it as if it is a float n...
Definition: decode.c:256
GtkWidget * label
label for this tab
Definition: libheraia.h:195
Data interpretor window structure.
Definition: libheraia.h:206
#define H_DI_BIG_ENDIAN
Stands for big endian representation.
gchar * decode_dos_date(guchar *data, gpointer data_struct)
general purpose of this function is to take a 4 byte data stream and convert it as if it is a dos dat...
Definition: decode.c:563
Proposal for a structure that will group all informations about a single document.
Definition: libheraia.h:293
gchar * decode_filetime_date(guchar *data, gpointer data_struct)
general purpose of this function is to take a 8 byte data stream and convert it as if it is a filetim...
Definition: decode.c:628
#define H_DI_LITTLE_ENDIAN
Stands for little endian representation (this is the default)
gchar * decode_8bits_unsigned(guchar *data, gpointer data_struct)
general purpose of this function is to take a 1 byte data stream and convert it as if it is an 8 bits...
Definition: decode.c:72
xml_t * xmls
All the xmls used in the program, loaded at running time.
Definition: libheraia.h:337
gchar * decode_32bits_signed(guchar *data, gpointer data_struct)
general purpose of this function is to take a 4 byte data stream and convert it as if it is a 32 bits...
Definition: decode.c:141
gchar * decode_to_bits(guchar *data, gpointer data_struct)
decodes the stream represented by *data (one byte) to a string containing eight 0 or 1 (Little Endian...
Definition: decode.c:739
guint which_stream_size(heraia_struct_t *main_struct)
returns stream size as selected in the spin button
gchar * decode_8bits_signed(guchar *data, gpointer data_struct)
General purpose of this function is to take a 1 byte data stream and convert it as if it is an 8 bits...
Definition: decode.c:49
void di_set_selected_tab(heraia_struct_t *main_struct, gint selected_tab)
Sets the selected tab (if possible) to data interpretor's notebook.
void refresh_data_interpretor_window(GtkWidget *widget, gpointer data)
Refreshes the data interpretor window with the new values.
GPtrArray * vboxes
array of vboxes where we will pack label and entry widgets
Definition: libheraia.h:197
Basic way to associate a decode function and an entry that will receive the result.
Definition: libheraia.h:160
GtkWidget * hex_widget
hexwidget corresponding to the document
Definition: libheraia.h:296
decode_parameters_t * new_decode_parameters_t(guint endianness, guint stream_size)
Make an new decode_parameters_t in order to pass to the functions.
Definition: decode.c:961
GtkBuilder * main
the main interface xml description
Definition: libheraia.h:222
gchar * decode_double_normal(guchar *data, gpointer data_struct)
general purpose of this function is to take a 8 byte data stream and convert it as if it is a float n...
Definition: decode.c:279
tab_t * add_new_tab_in_data_interpretor(GtkNotebook *notebook, guint index, const gchar *label, guint nb_cols,...)
Adds a new tab in the data interpretor window.
gchar *(* DecodeFunc)(guchar *, gpointer)
Templates for the decoding functions.
Definition: libheraia.h:139
void di_set_stream_size(heraia_struct_t *main_struct, gint stream_size)
Sets the stream size (if possible) to data interpretor's notebook.
GPtrArray * decode_array
Pointer Array of decode_t functions and corresponding entries.
Definition: libheraia.h:178
gchar * decode_64bits_signed(guchar *data, gpointer data_struct)
general purpose of this function is to take a 8 byte data stream and convert it as if it is a 64 bits...
Definition: decode.c:187
gchar * decode_HFS_date(guchar *data, gpointer data_struct)
general purpose of this function is to take a 4 byte data stream and convert it as if it is a HFS dat...
Definition: decode.c:690
data_window_t * current_DW
data_interpretor pointer
Definition: libheraia.h:338
gchar * decode_float_normal(guchar *data, gpointer data_struct)
general purpose of this function is to take a 4 byte data stream and convert it as if it is a float n...
Definition: decode.c:233
void di_set_endianness(heraia_struct_t *main_struct, gint endianness)
Sets the endianness as stated by the second parameter.
GPtrArray * tabs
an array of tabs displayed in data interpretor's notebook (tab_t)
Definition: libheraia.h:211
GPtrArray * col_labels
array of GtkWidgets of columns labels
Definition: libheraia.h:196
This file contains all the definitions and includes all other .h files.
gchar * decode_packed_BCD(guchar *data, gpointer data_struct)
Decode one byte as a Packed BCD (Binary Coded Decimal) and return a gchar* that may be freed when no ...
Definition: decode.c:872
static void refresh_one_tab(doc_t *doc, data_window_t *dw, tab_t *tab, decode_parameters_t *decode_parameters)
This function refreshes one entire tab (row by row)
GtkWidget * diw
data interpretor window
Definition: libheraia.h:208
guint nb_tabs
keeps Number of tabs in the GPtrArray
Definition: libheraia.h:210
doc_t * current_doc
This is a pointer to the current edited document.
Definition: libheraia.h:335
GtkWidget * heraia_get_widget(GtkBuilder *xml, gchar *widget_name)
This is a wrapper to the GtkBuilder xml get widget.
Definition: heraia_ui.c:2184
void data_interpretor_init_interface(heraia_struct_t *main_struct)
Inits the data interpretor structure and window with default values.
gint di_get_endianness(heraia_struct_t *main_struct)
Gets the endianness as selected in the radio group button.
gboolean ghex_get_data(GtkWidget *hex_widget, guint length, guint endianness, guchar *c)
Gets the data from the hexwidget under the cursor, a wrapper to the ghex_memcpy function.
GtkWidget * entry
the widget that will receive the result
Definition: libheraia.h:163
gchar * decode_64bits_unsigned(guchar *data, gpointer data_struct)
general purpose of this function is to take a 8 byte data stream and convert it as if it is a 64 bits...
Definition: decode.c:210
guint index
number for this tab
Definition: libheraia.h:192
guint stream_size
stream_size
Definition: libheraia.h:150
gchar * decode_C_date(guchar *data, gpointer data_struct)
general purpose of this function is to take a 4 byte data stream and convert it as if it is a C date...
Definition: decode.c:659
gint di_get_selected_tab(heraia_struct_t *main_struct)
Gets the selected tab (if any) from data interpretor's notebook.
guint endianness
endianness
Definition: libheraia.h:149
decode_generic_t * new_decode_generic_t(const gchar *label, guint data_size, gboolean fixed_size, const gchar *err_msg, guint nb_cols,...)
Make a new decode_generic_t structure and creates the associated widgets.
Definition: decode.c:1018
static void refresh_all_tabs(doc_t *doc, data_window_t *dw, decode_parameters_t *decode_parameters)
Refreshes all tabs.
Basic way to have as many as we want decoding functions corresponding to one label.
Definition: libheraia.h:176
GtkWidget * gtk_radio_button_get_active_from_widget(GtkRadioButton *radio_button)
gets the active radio button from a radio group
Definition: heraia_ui.c:2098
void add_new_row_to_tab(tab_t *tab, decode_generic_t *row)
Adds a row to a particular tab.
static void connect_data_interpretor_signals(heraia_struct_t *main_struct)
Connects data interpretor window's signals to the right functions.
static void refresh_one_row(doc_t *doc, decode_generic_t *row, guint nb_cols, decode_parameters_t *decode_parameters)
This function refreshes one row of the tab.
void destroy_dt_window(GtkWidget *widget, GdkEvent *event, gpointer data)
call back function for the data interpretor window destruction
Definition: heraia_ui.c:1217
Used to pass decoding options to the functions.
Definition: libheraia.h:147
guint which_endianness(heraia_struct_t *main_struct)
Determines which endianness is selected that is to say which radio button is active in the window...
GPtrArray * rows
array of pointers to decode_generic_t variables.
Definition: libheraia.h:198
guint nb_cols
number of columns in this tab - this MUST NOT change in any way
Definition: libheraia.h:193
gchar * decode_16bits_signed(guchar *data, gpointer data_struct)
general purpose of this function is to take a 2 byte data stream and convert it as if it is a 16 bits...
Definition: decode.c:95