1 : /* -*- Mode: C; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
2 : /*
3 : ghex_heraia_interface.c
4 : heraia - an hexadecimal file editor and analyser based on ghex
5 :
6 : (C) Copyright 2005 - 2008 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 :
24 : #include "heraia_types.h"
25 :
26 :
27 : /**
28 : * Removes the old document if it exists and adds a new one
29 : * from the filename 'filename'
30 : */
31 : HERAIA_ERROR heraia_hex_document_new(heraia_window_t *main_window, char *filename)
32 2 : {
33 2 : if (main_window->current_doc != NULL)
34 : {
35 1 : hex_document_remove_view(main_window->current_doc, main_window->current_DW->current_hexwidget);
36 : }
37 :
38 2 : if (main_window->current_DW->current_hexwidget != NULL )
39 : {
40 1 : gtk_widget_destroy(main_window->current_DW->current_hexwidget);
41 : }
42 :
43 2 : main_window->current_doc = hex_document_new_from_file(filename);
44 2 : main_window->current_DW->current_hexwidget = hex_document_add_view(main_window->current_doc);
45 :
46 2 : connect_cursor_moved_signal(main_window);
47 :
48 2 : return HERAIA_NOERR;
49 : }
50 :
51 :
52 : /**
53 : * Retrieves the filename of a document which ever it is !
54 : */
55 : gchar *heraia_hex_document_get_filename(Heraia_Document *doc)
56 0 : {
57 0 : return doc->file_name;
58 : }
59 :
60 :
61 : /**
62 : * Saves an open and edited document
63 : */
64 : HERAIA_ERROR heraia_hex_document_save(heraia_window_t *main_window)
65 0 : {
66 0 : gint return_value = FALSE;
67 :
68 0 : if (main_window->current_doc != NULL)
69 : {
70 0 : return_value = hex_document_write(main_window->current_doc);
71 : }
72 :
73 0 : if (return_value != FALSE)
74 : {
75 0 : return HERAIA_NOERR;
76 : }
77 : else
78 : {
79 0 : return HERAIA_FILE_ERROR;
80 : }
81 : }
82 :
83 : /**
84 : * Saves an opened and edited document to a new file
85 : */
86 : HERAIA_ERROR heraia_hex_document_save_as(heraia_window_t *main_window, gchar *filename)
87 1 : {
88 1 : gint return_value = FALSE;
89 1 : FILE *fp = NULL;
90 1 : gint i = 0;
91 1 : gchar *path_end = NULL;
92 :
93 1 : if (main_window->current_doc != NULL && filename != NULL)
94 : {
95 1 : fp = fopen(filename, "w");
96 1 : if (fp != NULL)
97 : {
98 1 : return_value = hex_document_write_to_file(main_window->current_doc, fp);
99 1 : fclose(fp);
100 1 : if (main_window->current_doc->file_name)
101 : {
102 1 : g_free(main_window->current_doc->file_name);
103 : }
104 1 : main_window->current_doc->file_name = filename;
105 :
106 : /* This may disappear as it duplicates structures */
107 1 : if (main_window->filename != NULL)
108 : {
109 1 : g_free(main_window->filename);
110 : }
111 1 : main_window->filename = g_strdup_printf("%s", main_window->current_doc->file_name);
112 :
113 : /* path_end stuff from ghex-window.c from ghex project !!! */
114 1 : for(i = strlen(main_window->current_doc->file_name);
115 8 : (i >= 0) && (main_window->current_doc->file_name[i] != '/');
116 6 : i--);
117 1 : if (main_window->current_doc->file_name[i] == '/')
118 1 : path_end = &main_window->current_doc->file_name[i+1];
119 : else
120 0 : path_end = main_window->current_doc->file_name;
121 :
122 1 : main_window->current_doc->path_end = g_filename_to_utf8(path_end, -1, NULL, NULL, NULL);
123 : }
124 : }
125 :
126 1 : if (return_value != FALSE)
127 : {
128 1 : return HERAIA_NOERR;
129 : }
130 : else
131 : {
132 0 : return HERAIA_FILE_ERROR;
133 : }
134 : }
135 :
136 : /**
137 : * Deals with the endianness of 'len' bytes located in 'result'
138 : * for BIG_ENDIAN we only swap bytes if we have two or more of them
139 : * if we have only one byte, we reverse its order
140 : * if endianness is MIDDLE_ENDIAN we swap only four or more bytes
141 : * Here we might have funny things with len corresponding to 24 or 56 bits
142 : * for example
143 : * Assumption is made that the default order is LITTLE_ENDIAN (which may
144 : * not be true on some systems !)
145 : * We fo assume that 'result' really contains 'len' bytes of data previously
146 : * gmalloc'ed
147 : */
148 : static void change_endianness(guint len, guint endianness, guchar *result)
149 : {
150 14 : if (endianness == H_DI_BIG_ENDIAN)
151 : {
152 0 : if (len > 1) /* We swap bytes only if we have two or more */
153 : {
154 0 : swap_bytes(result, 0, len-1);
155 : }
156 : else
157 : {
158 0 : reverse_byte_order(result); /* Only one byte and big endian requested */
159 : }
160 : }
161 14 : else if (endianness == H_DI_MIDDLE_ENDIAN && len >= 4)
162 : {
163 0 : swap_bytes(result, 0, (len/2)-1);
164 0 : swap_bytes(result, (len/2), len-1);
165 : }
166 : }
167 :
168 :
169 : /**
170 : * Returns 'len' number of bytes located at 'pos' in the GtkHex
171 : * document and puts it in the result variable
172 : *
173 : * We assume that a previous g_malloc has been done in order to
174 : * use the function. Here we need the "swap_bytes" function
175 : * defined in the decode.h header in order to take the endianness
176 : * into account
177 : */
178 : gboolean ghex_memcpy(GtkHex *gh, guint pos, guint len, guint endianness, guchar *result)
179 14 : {
180 : guint i;
181 :
182 14 : if (result == NULL || gh == NULL)
183 : {
184 0 : return FALSE;
185 : }
186 28 : else if ((pos < 0) || ((pos+len) > ghex_file_size(gh))) /* pos located in the file limits ! */
187 : {
188 0 : return FALSE;
189 : }
190 : else
191 : {
192 : /* Extracts len bytes from the Ghex widget */
193 66 : for (i=0; i<len ; i++)
194 : {
195 52 : result[i] = gtk_hex_get_byte(gh, pos+i);
196 : }
197 :
198 : /* Deals with endianness to rearrange datas */
199 : change_endianness(len, endianness, result);
200 :
201 14 : return TRUE;
202 : }
203 : }
204 :
205 :
206 :
207 : /**
208 : * Gets the data from the hexwidget, a wrapper to the ghex_memcpy
209 : * function. guchar *c MUST have been pre allocated BEFORE the call.
210 : * endianness == H_DI_BIG_ENDIAN, H_DI_MIDDLE_ENDIAN or H_DI_LITTLE_ENDIAN
211 : * length can be anything but MUST be strictly less than the size allocated
212 : * to *c
213 : */
214 : gboolean ghex_get_data(data_window_t *data_window, guint length, guint endianness, guchar *c)
215 14 : {
216 14 : GtkHex *gh = NULL;
217 14 : gboolean result = FALSE;
218 :
219 14 : gh = GTK_HEX(data_window->current_hexwidget);
220 :
221 14 : if (gh != NULL)
222 : {
223 14 : result = ghex_memcpy(gh, gtk_hex_get_cursor(gh), length, endianness, c);
224 : }
225 : else
226 : {
227 0 : result = FALSE;
228 : }
229 14 : return result;
230 : }
231 :
232 :
233 : /**
234 : * Returns the file size of an opened GtkHex document.
235 : */
236 : guint64 ghex_file_size(GtkHex *gh)
237 0 : {
238 14 : if (gh != NULL && gh->document != NULL)
239 : {
240 14 : return gh->document->file_size;
241 : }
242 : else
243 : {
244 0 : return 0;
245 : }
246 : }
247 :
248 :
|