1 /*
2 * libInstPatch
3 * Copyright (C) 1999-2014 Element Green <element@elementsofsound.org>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; version 2.1
8 * of the License only.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA or on the web at http://www.gnu.org.
19 */
20 /*
21 * IpatchFile.c - File buffer and integer read/write funcs
22 */
23 #include <stdio.h>
24 #include <string.h>
25 #include <glib.h>
26 #include <glib-object.h>
27 #include "IpatchFile.h"
28
29 /* Defined in IpatchFile.c */
30 extern gboolean
31 _ipatch_file_read_no_pos_update(IpatchFileHandle *handle, gpointer buf,
32 guint size, GError **err);
33 extern gboolean
34 _ipatch_file_write_no_pos_update(IpatchFileHandle *handle, gconstpointer buf,
35 guint size, GError **err);
36
37 /**
38 * ipatch_file_read_u8:
39 * @handle: File handle
40 * @val: Location to store value
41 * @err: Location to store error info or %NULL
42 *
43 * Read an unsigned 8 bit integer from a file.
44 *
45 * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set).
46 */
47 gboolean
ipatch_file_read_u8(IpatchFileHandle * handle,guint8 * val,GError ** err)48 ipatch_file_read_u8(IpatchFileHandle *handle, guint8 *val, GError **err)
49 {
50 return (ipatch_file_read(handle, val, sizeof(guint8), err));
51 }
52
53 /**
54 * ipatch_file_read_u16:
55 * @handle: File handle
56 * @val: Location to store value
57 * @err: Location to store error info or %NULL
58 *
59 * Read an unsigned 16 bit integer from a file and performs endian
60 * byte swapping if necessary.
61 *
62 * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set).
63 */
64 gboolean
ipatch_file_read_u16(IpatchFileHandle * handle,guint16 * val,GError ** err)65 ipatch_file_read_u16(IpatchFileHandle *handle, guint16 *val, GError **err)
66 {
67 if(!ipatch_file_read(handle, val, sizeof(guint16), err))
68 {
69 return (FALSE);
70 }
71
72 *val = IPATCH_FILE_SWAP16(handle->file, val);
73 return (TRUE);
74 }
75
76 /**
77 * ipatch_file_read_u32:
78 * @handle: File handle
79 * @val: Location to store value
80 * @err: Location to store error info or %NULL
81 *
82 * Read an unsigned 32 bit integer from a file and performs endian
83 * byte swapping if necessary.
84 *
85 * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set).
86 */
87 gboolean
ipatch_file_read_u32(IpatchFileHandle * handle,guint32 * val,GError ** err)88 ipatch_file_read_u32(IpatchFileHandle *handle, guint32 *val, GError **err)
89 {
90 if(!ipatch_file_read(handle, val, sizeof(guint32), err))
91 {
92 return (FALSE);
93 }
94
95 *val = IPATCH_FILE_SWAP32(handle->file, val);
96 return (TRUE);
97 }
98
99 /**
100 * ipatch_file_read_u64:
101 * @handle: File handle
102 * @val: Location to store value
103 * @err: Location to store error info or %NULL
104 *
105 * Read an unsigned 64 bit integer from a file and performs endian
106 * byte swapping if necessary.
107 *
108 * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set).
109 */
110 gboolean
ipatch_file_read_u64(IpatchFileHandle * handle,guint64 * val,GError ** err)111 ipatch_file_read_u64(IpatchFileHandle *handle, guint64 *val, GError **err)
112 {
113 if(!ipatch_file_read(handle, val, sizeof(guint64), err))
114 {
115 return (FALSE);
116 }
117
118 *val = IPATCH_FILE_SWAP64(handle->file, val);
119 return (TRUE);
120 }
121
122 /**
123 * ipatch_file_read_s8:
124 * @handle: File handle
125 * @val: Location to store value
126 * @err: Location to store error info or %NULL
127 *
128 * Read a signed 8 bit integer from a file.
129 *
130 * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set).
131 */
132 gboolean
ipatch_file_read_s8(IpatchFileHandle * handle,gint8 * val,GError ** err)133 ipatch_file_read_s8(IpatchFileHandle *handle, gint8 *val, GError **err)
134 {
135 return (ipatch_file_read(handle, val, sizeof(gint8), err));
136 }
137
138 /**
139 * ipatch_file_read_s16:
140 * @handle: File handle
141 * @val: Location to store value
142 * @err: Location to store error info or %NULL
143 *
144 * Read a signed 16 bit integer from a file and performs endian
145 * byte swapping if necessary.
146 *
147 * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set).
148 */
149 gboolean
ipatch_file_read_s16(IpatchFileHandle * handle,gint16 * val,GError ** err)150 ipatch_file_read_s16(IpatchFileHandle *handle, gint16 *val, GError **err)
151 {
152 if(!ipatch_file_read(handle, val, sizeof(gint16), err))
153 {
154 return (FALSE);
155 }
156
157 *val = IPATCH_FILE_SWAP16(handle->file, val);
158 return (TRUE);
159 }
160
161 /**
162 * ipatch_file_read_s32:
163 * @handle: File handle
164 * @val: Location to store value
165 * @err: Location to store error info or %NULL
166 *
167 * Read a signed 32 bit integer from a file and performs endian
168 * byte swapping if necessary.
169 *
170 * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set).
171 */
172 gboolean
ipatch_file_read_s32(IpatchFileHandle * handle,gint32 * val,GError ** err)173 ipatch_file_read_s32(IpatchFileHandle *handle, gint32 *val, GError **err)
174 {
175 if(!ipatch_file_read(handle, val, sizeof(gint32), err))
176 {
177 return (FALSE);
178 }
179
180 *val = IPATCH_FILE_SWAP32(handle->file, val);
181 return (TRUE);
182 }
183
184 /**
185 * ipatch_file_read_s64:
186 * @handle: File handle
187 * @val: Location to store value
188 * @err: Location to store error info or %NULL
189 *
190 * Read a signed 64 bit integer from a file and performs endian
191 * byte swapping if necessary.
192 *
193 * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set).
194 */
195 gboolean
ipatch_file_read_s64(IpatchFileHandle * handle,gint64 * val,GError ** err)196 ipatch_file_read_s64(IpatchFileHandle *handle, gint64 *val, GError **err)
197 {
198 if(!ipatch_file_read(handle, val, sizeof(gint64), err))
199 {
200 return (FALSE);
201 }
202
203 *val = IPATCH_FILE_SWAP64(handle->file, val);
204 return (TRUE);
205 }
206
207 /**
208 * ipatch_file_write_u8:
209 * @handle: File handle
210 * @val: Value to store
211 * @err: Location to store error info or %NULL
212 *
213 * Write an unsigned 8 bit integer to a file.
214 *
215 * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set).
216 */
217 gboolean
ipatch_file_write_u8(IpatchFileHandle * handle,guint8 val,GError ** err)218 ipatch_file_write_u8(IpatchFileHandle *handle, guint8 val, GError **err)
219 {
220 return (ipatch_file_write(handle, &val, sizeof(guint8), err));
221 }
222
223 /**
224 * ipatch_file_write_u16:
225 * @handle: File handle
226 * @val: Value to store
227 * @err: Location to store error info or %NULL
228 *
229 * Write an unsigned 16 bit integer to a file and performs endian
230 * byte swapping if necessary.
231 *
232 * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set).
233 */
234 gboolean
ipatch_file_write_u16(IpatchFileHandle * handle,guint16 val,GError ** err)235 ipatch_file_write_u16(IpatchFileHandle *handle, guint16 val, GError **err)
236 {
237 g_return_val_if_fail(handle != NULL, FALSE);
238 g_return_val_if_fail(IPATCH_IS_FILE(handle->file), FALSE);
239
240 val = IPATCH_FILE_SWAP16(handle->file, &val);
241
242 if(!ipatch_file_write(handle, &val, sizeof(guint16), err))
243 {
244 return (FALSE);
245 }
246
247 return (TRUE);
248 }
249
250 /**
251 * ipatch_file_write_u32:
252 * @handle: File handle
253 * @val: Value to store
254 * @err: Location to store error info or %NULL
255 *
256 * Write an unsigned 32 bit integer to a file and performs endian
257 * byte swapping if necessary.
258 *
259 * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set).
260 */
261 gboolean
ipatch_file_write_u32(IpatchFileHandle * handle,guint32 val,GError ** err)262 ipatch_file_write_u32(IpatchFileHandle *handle, guint32 val, GError **err)
263 {
264 g_return_val_if_fail(handle != NULL, FALSE);
265 g_return_val_if_fail(IPATCH_IS_FILE(handle->file), FALSE);
266
267 val = IPATCH_FILE_SWAP32(handle->file, &val);
268
269 if(!ipatch_file_write(handle, &val, sizeof(guint32), err))
270 {
271 return (FALSE);
272 }
273
274 return (TRUE);
275 }
276
277 /**
278 * ipatch_file_write_u64:
279 * @handle: File handle
280 * @val: Value to store
281 * @err: Location to store error info or %NULL
282 *
283 * Write an unsigned 64 bit integer to a file and performs endian
284 * byte swapping if necessary.
285 *
286 * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set).
287 */
288 gboolean
ipatch_file_write_u64(IpatchFileHandle * handle,guint64 val,GError ** err)289 ipatch_file_write_u64(IpatchFileHandle *handle, guint64 val, GError **err)
290 {
291 g_return_val_if_fail(handle != NULL, FALSE);
292 g_return_val_if_fail(IPATCH_IS_FILE(handle->file), FALSE);
293
294 val = IPATCH_FILE_SWAP64(handle->file, &val);
295
296 if(!ipatch_file_write(handle, &val, sizeof(guint64), err))
297 {
298 return (FALSE);
299 }
300
301 return (TRUE);
302 }
303
304 /**
305 * ipatch_file_write_s8:
306 * @handle: File handle
307 * @val: Value to store
308 * @err: Location to store error info or %NULL
309 *
310 * Write a signed 8 bit integer to a file.
311 *
312 * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set).
313 */
314 gboolean
ipatch_file_write_s8(IpatchFileHandle * handle,gint8 val,GError ** err)315 ipatch_file_write_s8(IpatchFileHandle *handle, gint8 val, GError **err)
316 {
317 return (ipatch_file_write(handle, &val, sizeof(gint8), err));
318 }
319
320 /**
321 * ipatch_file_write_s16:
322 * @handle: File handle
323 * @val: Value to store
324 * @err: Location to store error info or %NULL
325 *
326 * Write a signed 16 bit integer to a file and performs endian
327 * byte swapping if necessary.
328 *
329 * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set).
330 */
331 gboolean
ipatch_file_write_s16(IpatchFileHandle * handle,gint16 val,GError ** err)332 ipatch_file_write_s16(IpatchFileHandle *handle, gint16 val, GError **err)
333 {
334 g_return_val_if_fail(handle != NULL, FALSE);
335 g_return_val_if_fail(IPATCH_IS_FILE(handle->file), FALSE);
336
337 val = IPATCH_FILE_SWAP16(handle->file, &val);
338
339 if(!ipatch_file_write(handle, &val, sizeof(gint16), err))
340 {
341 return (FALSE);
342 }
343
344 return (TRUE);
345 }
346
347 /**
348 * ipatch_file_write_s32:
349 * @handle: File handle
350 * @val: Value to store
351 * @err: Location to store error info or %NULL
352 *
353 * Write a signed 32 bit integer to a file and performs endian
354 * byte swapping if necessary.
355 *
356 * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set).
357 */
358 gboolean
ipatch_file_write_s32(IpatchFileHandle * handle,gint32 val,GError ** err)359 ipatch_file_write_s32(IpatchFileHandle *handle, gint32 val, GError **err)
360 {
361 g_return_val_if_fail(handle != NULL, FALSE);
362 g_return_val_if_fail(IPATCH_IS_FILE(handle->file), FALSE);
363
364 val = IPATCH_FILE_SWAP32(handle->file, &val);
365
366 if(!ipatch_file_write(handle, &val, sizeof(gint32), err))
367 {
368 return (FALSE);
369 }
370
371 return (TRUE);
372 }
373
374 /**
375 * ipatch_file_write_s64:
376 * @handle: File handle
377 * @val: Value to store
378 * @err: Location to store error info or %NULL
379 *
380 * Write a signed 64 bit integer to a file and performs endian
381 * byte swapping if necessary.
382 *
383 * Returns: %TRUE on success, %FALSE otherwise (in which case @err may be set).
384 */
385 gboolean
ipatch_file_write_s64(IpatchFileHandle * handle,gint64 val,GError ** err)386 ipatch_file_write_s64(IpatchFileHandle *handle, gint64 val, GError **err)
387 {
388 g_return_val_if_fail(handle != NULL, FALSE);
389 g_return_val_if_fail(IPATCH_IS_FILE(handle->file), FALSE);
390
391 val = IPATCH_FILE_SWAP64(handle->file, &val);
392
393 if(!ipatch_file_write(handle, &val, sizeof(gint64), err))
394 {
395 return (FALSE);
396 }
397
398 return (TRUE);
399 }
400
401 /**
402 * ipatch_file_buf_load:
403 * @handle: File handle
404 * @size: Size of data to load
405 * @err: Location to store error info or %NULL
406 *
407 * Load data from a file into a buffer for error checking convenience.
408 * I/O errors need only be checked on this function and not on the subsequent
409 * buffered read function calls. It is an error if an end of file is
410 * encountered before all the requested data is read.
411 *
412 * Returns: %TRUE on success, %FALSE on error.
413 */
414 gboolean
ipatch_file_buf_load(IpatchFileHandle * handle,guint size,GError ** err)415 ipatch_file_buf_load(IpatchFileHandle *handle, guint size, GError **err)
416 {
417 g_return_val_if_fail(handle != NULL, FALSE);
418 g_return_val_if_fail(size != 0, FALSE);
419
420 /* If there is still buffered data, flush it (add to file position) */
421 if(handle->buf_position < handle->buf->len)
422 {
423 handle->position += handle->buf->len - handle->buf_position;
424 }
425
426 g_byte_array_set_size(handle->buf, size);
427 handle->buf_position = 0;
428
429 if(!_ipatch_file_read_no_pos_update(handle, handle->buf->data, size, err))
430 {
431 return (FALSE);
432 }
433
434 return (TRUE);
435 }
436
437 /**
438 * ipatch_file_buf_read:
439 * @handle: File handle with loaded data to read from
440 * @buf: Buffer to copy data to
441 * @size: Amount of data to copy in bytes
442 *
443 * Read data from a file handle's buffer and advance the buffer's current
444 * position. A call to ipatch_file_buf_load() must have been previously
445 * executed and there must be enough remaining data in the buffer for the read.
446 */
447 void
ipatch_file_buf_read(IpatchFileHandle * handle,gpointer buf,guint size)448 ipatch_file_buf_read(IpatchFileHandle *handle, gpointer buf, guint size)
449 {
450 g_return_if_fail(handle != NULL);
451 g_return_if_fail(handle->buf_position + size <= handle->buf->len);
452
453 memcpy(buf, handle->buf->data + handle->buf_position, size);
454 handle->buf_position += size;
455 handle->position += size;
456 }
457
458 /**
459 * ipatch_file_buf_write:
460 * @handle: File handle to append buffered data to
461 * @buf: Buffer to copy data from
462 * @size: Amount of data to copy in bytes
463 *
464 * Write data to a file handle's buffer and advance the buffer's current
465 * position. Buffer is expanded if necessary (since version 1.1.0).
466 * Data will not actually be written to file till ipatch_file_buf_commit() is
467 * called.
468 */
469 void
ipatch_file_buf_write(IpatchFileHandle * handle,gconstpointer buf,guint size)470 ipatch_file_buf_write(IpatchFileHandle *handle, gconstpointer buf, guint size)
471 {
472 g_return_if_fail(handle != NULL);
473
474 if(size == 0)
475 {
476 return;
477 }
478
479 if(handle->buf_position + size > handle->buf->len)
480 {
481 g_byte_array_set_size(handle->buf, handle->buf_position + size);
482 }
483
484 memcpy(handle->buf->data + handle->buf_position, buf, size);
485 handle->buf_position += size;
486 handle->position += size;
487 }
488
489 /**
490 * ipatch_file_buf_memset:
491 * @handle: File handle to set buffered data of
492 * @c: Character to write
493 * @size: Size of data to set
494 *
495 * Sets the given @size in bytes to the character @c and advances the
496 * current position. Buffer is expanded if necessary.
497 */
498 void
ipatch_file_buf_memset(IpatchFileHandle * handle,unsigned char c,guint size)499 ipatch_file_buf_memset(IpatchFileHandle *handle, unsigned char c, guint size)
500 {
501 g_return_if_fail(handle != NULL);
502
503 if(size == 0)
504 {
505 return;
506 }
507
508 if(handle->buf_position + size > handle->buf->len)
509 {
510 g_byte_array_set_size(handle->buf, handle->buf_position + size);
511 }
512
513 memset(handle->buf->data + handle->buf_position, c, size);
514 handle->buf_position += size;
515 handle->position += size;
516 }
517
518 /**
519 * ipatch_file_buf_set_size:
520 * @handle: File handle to adjust buffer of
521 * @size: New size of buffer
522 *
523 * Sets the size of the buffer of @handle to @size bytes. The buffer is
524 * expanded without initializing the newly allocated part or truncated
525 * as necessary discarding any content over the new size. The current position
526 * is updated to point to the end of the buffer if it would point outside the
527 * new size of the buffer after truncating it.
528 *
529 * Since: 1.1.0
530 */
531 void
ipatch_file_buf_set_size(IpatchFileHandle * handle,guint size)532 ipatch_file_buf_set_size(IpatchFileHandle *handle, guint size)
533 {
534 g_return_if_fail(handle != NULL);
535
536 if(size == handle->buf->len)
537 {
538 return;
539 }
540
541 g_byte_array_set_size(handle->buf, size);
542
543 if(handle->buf_position > size)
544 {
545 handle->position += size - handle->buf_position;
546 handle->buf_position = size;
547 }
548 }
549
550 /**
551 * ipatch_file_buf_commit:
552 * @handle: File handle with buffered data to write
553 * @err: Location to store error info or %NULL
554 *
555 * Writes all data in a file handle's buffer to the file and resets the
556 * buffer to empty.
557 *
558 * Returns: %TRUE on success, %FALSE otherwise
559 */
560 gboolean
ipatch_file_buf_commit(IpatchFileHandle * handle,GError ** err)561 ipatch_file_buf_commit(IpatchFileHandle *handle, GError **err)
562 {
563 g_return_val_if_fail(handle != NULL, FALSE);
564
565 if(handle->buf->len == 0)
566 {
567 return (TRUE); /* no data? */
568 }
569
570 if(!_ipatch_file_write_no_pos_update(handle, handle->buf->data, handle->buf->len, err))
571 {
572 return (FALSE);
573 }
574
575 g_byte_array_set_size(handle->buf, 0);
576 handle->buf_position = 0;
577
578 return (TRUE);
579 }
580
581 /**
582 * ipatch_file_buf_seek:
583 * @handle: File handle
584 * @offset: Offset to seek
585 * @type: Seek type
586 *
587 * Seeks the current position in a file handle's buffer specified by an @offset
588 * and seek @type. It is an error to seek outside of the current size of
589 * buffered data (loaded or written). The @offset is relative to the buffer,
590 * not the file position.
591 */
592 void
ipatch_file_buf_seek(IpatchFileHandle * handle,int offset,GSeekType type)593 ipatch_file_buf_seek(IpatchFileHandle *handle, int offset, GSeekType type)
594 {
595 g_return_if_fail(handle != NULL);
596
597 if(type == G_SEEK_CUR)
598 {
599 g_return_if_fail(handle->buf_position + offset >= 0);
600 g_return_if_fail(handle->buf_position + offset < handle->buf->len);
601 handle->buf_position += offset;
602 handle->position += offset;
603 }
604 else if(type == G_SEEK_SET)
605 {
606 g_return_if_fail(offset >= 0 && (guint)offset < handle->buf->len);
607 handle->position += offset - handle->buf_position;
608 handle->buf_position = offset;
609 }
610 else if(type == G_SEEK_END)
611 {
612 g_return_if_fail(handle->buf->len + offset >= 0);
613 g_return_if_fail(handle->buf->len + offset < handle->buf->len);
614 handle->position = (handle->buf->len + offset) - handle->buf_position;
615 handle->buf_position = handle->buf->len + offset;
616 }
617 }
618
619 /**
620 * ipatch_file_buf_read_u8:
621 * @handle: File handle with loaded data
622 *
623 * Reads an unsigned byte from a file buffer and advances the buffer's
624 * current position.
625 *
626 * Returns: The value.
627 */
628 guint8
ipatch_file_buf_read_u8(IpatchFileHandle * handle)629 ipatch_file_buf_read_u8(IpatchFileHandle *handle)
630 {
631 guint8 *val;
632
633 g_return_val_if_fail(handle != NULL, 0);
634 g_return_val_if_fail(handle->buf_position + 1 <= handle->buf->len, 0);
635
636 val = (guint8 *)(handle->buf->data + handle->buf_position);
637 handle->buf_position++;
638 handle->position++;
639 return (*val);
640 }
641
642 /**
643 * ipatch_file_buf_read_u16:
644 * @handle: File handle with loaded data
645 *
646 * Reads an unsigned 16 bit word from a file buffer and advances the buffer's
647 * current position. Performs endian byte swapping if necessary.
648 *
649 * Returns: The value.
650 */
651 guint16
ipatch_file_buf_read_u16(IpatchFileHandle * handle)652 ipatch_file_buf_read_u16(IpatchFileHandle *handle)
653 {
654 guint16 *val;
655
656 g_return_val_if_fail(handle != NULL, 0);
657 g_return_val_if_fail(handle->buf_position + 2 <= handle->buf->len, 0);
658
659 val = (guint16 *)(handle->buf->data + handle->buf_position);
660 handle->buf_position += 2;
661 handle->position += 2;
662 return (IPATCH_FILE_SWAP16(handle->file, val));
663 }
664
665 /**
666 * ipatch_file_buf_read_u32:
667 * @handle: File handle with loaded data
668 *
669 * Reads an unsigned 32 bit word from a file buffer and advances the buffer's
670 * current position. Performs endian byte swapping if necessary.
671 *
672 * Returns: The value.
673 */
674 guint32
ipatch_file_buf_read_u32(IpatchFileHandle * handle)675 ipatch_file_buf_read_u32(IpatchFileHandle *handle)
676 {
677 guint32 *val;
678
679 g_return_val_if_fail(handle != NULL, 0);
680 g_return_val_if_fail(handle->buf_position + 4 <= handle->buf->len, 0);
681
682 val = (guint32 *)(handle->buf->data + handle->buf_position);
683 handle->buf_position += 4;
684 handle->position += 4;
685 return (IPATCH_FILE_SWAP32(handle->file, val));
686 }
687
688 /**
689 * ipatch_file_buf_read_u64:
690 * @handle: File handle with loaded data
691 *
692 * Reads an unsigned 64 bit word from a file buffer and advances the buffer's
693 * current position. Performs endian byte swapping if necessary.
694 *
695 * Returns: The value.
696 */
697 guint64
ipatch_file_buf_read_u64(IpatchFileHandle * handle)698 ipatch_file_buf_read_u64(IpatchFileHandle *handle)
699 {
700 guint64 *val;
701
702 g_return_val_if_fail(handle != NULL, 0);
703 g_return_val_if_fail(handle->buf_position + 8 <= handle->buf->len, 0);
704
705 val = (guint64 *)(handle->buf->data + handle->buf_position);
706 handle->buf_position += 8;
707 handle->position += 8;
708 return (IPATCH_FILE_SWAP64(handle->file, val));
709 }
710
711 /**
712 * ipatch_file_buf_read_s8:
713 * @handle: File handle with loaded data
714 *
715 * Reads a signed byte from a file buffer and advances the buffer's
716 * current position.
717 *
718 * Returns: The value.
719 */
720 gint8
ipatch_file_buf_read_s8(IpatchFileHandle * handle)721 ipatch_file_buf_read_s8(IpatchFileHandle *handle)
722 {
723 gint8 *val;
724
725 g_return_val_if_fail(handle != NULL, 0);
726 g_return_val_if_fail(handle->buf_position + 1 <= handle->buf->len, 0);
727
728 val = (gint8 *)(handle->buf->data + handle->buf_position);
729 handle->buf_position++;
730 handle->position++;
731 return (*val);
732 }
733
734 /**
735 * ipatch_file_buf_read_s16:
736 * @handle: File handle with loaded data
737 *
738 * Reads a signed 16 bit word from a file buffer and advances the buffer's
739 * current position. Performs endian byte swapping if necessary.
740 *
741 * Returns: The value.
742 */
743 gint16
ipatch_file_buf_read_s16(IpatchFileHandle * handle)744 ipatch_file_buf_read_s16(IpatchFileHandle *handle)
745 {
746 gint16 *val;
747
748 g_return_val_if_fail(handle != NULL, 0);
749 g_return_val_if_fail(handle->buf_position + 2 <= handle->buf->len, 0);
750
751 val = (gint16 *)(handle->buf->data + handle->buf_position);
752 handle->buf_position += 2;
753 handle->position += 2;
754 return (IPATCH_FILE_SWAP16(handle->file, val));
755 }
756
757 /**
758 * ipatch_file_buf_read_s32:
759 * @handle: File handle with loaded data
760 *
761 * Reads a signed 32 bit word from a file buffer and advances the buffer's
762 * current position. Performs endian byte swapping if necessary.
763 *
764 * Returns: The value.
765 */
766 gint32
ipatch_file_buf_read_s32(IpatchFileHandle * handle)767 ipatch_file_buf_read_s32(IpatchFileHandle *handle)
768 {
769 gint32 *val;
770
771 g_return_val_if_fail(handle != NULL, 0);
772 g_return_val_if_fail(handle->buf_position + 4 <= handle->buf->len, 0);
773
774 val = (gint32 *)(handle->buf->data + handle->buf_position);
775 handle->buf_position += 4;
776 handle->position += 4;
777 return (IPATCH_FILE_SWAP32(handle->file, val));
778 }
779
780 /**
781 * ipatch_file_buf_read_s64:
782 * @handle: File handle with loaded data
783 *
784 * Reads a signed 64 bit word from a file buffer and advances the buffer's
785 * current position. Performs endian byte swapping if necessary.
786 *
787 * Returns: The value.
788 */
789 gint64
ipatch_file_buf_read_s64(IpatchFileHandle * handle)790 ipatch_file_buf_read_s64(IpatchFileHandle *handle)
791 {
792 gint64 *val;
793
794 g_return_val_if_fail(handle != NULL, 0);
795 g_return_val_if_fail(handle->buf_position + 8 <= handle->buf->len, 0);
796
797 val = (gint64 *)(handle->buf->data + handle->buf_position);
798 handle->buf_position += 8;
799 handle->position += 8;
800 return (IPATCH_FILE_SWAP64(handle->file, val));
801 }
802
803 /**
804 * ipatch_file_buf_write_u8:
805 * @handle: File handle
806 * @val: Value to write into file buffer
807 *
808 * Writes an unsigned byte to a file buffer and advances the buffer's
809 * current position. The file buffer is expanded if needed.
810 */
811 void
ipatch_file_buf_write_u8(IpatchFileHandle * handle,guint8 val)812 ipatch_file_buf_write_u8(IpatchFileHandle *handle, guint8 val)
813 {
814 g_return_if_fail(handle != NULL);
815
816 if(handle->buf_position + 1 > handle->buf->len)
817 {
818 g_byte_array_set_size(handle->buf, handle->buf_position + 1);
819 }
820
821 *(guint8 *)(handle->buf->data + handle->buf_position) = val;
822 handle->buf_position++;
823 handle->position++;
824 }
825
826 /**
827 * ipatch_file_buf_write_u16:
828 * @handle: File handle
829 * @val: Value to write into file buffer
830 *
831 * Writes an unsigned 16 bit word to a file buffer and advances the buffer's
832 * current position. Performs endian byte swapping if necessary.
833 * The file buffer is expanded if needed.
834 */
835 void
ipatch_file_buf_write_u16(IpatchFileHandle * handle,guint16 val)836 ipatch_file_buf_write_u16(IpatchFileHandle *handle, guint16 val)
837 {
838 g_return_if_fail(handle != NULL);
839
840 if(handle->buf_position + 2 > handle->buf->len)
841 {
842 g_byte_array_set_size(handle->buf, handle->buf_position + 2);
843 }
844
845 *(guint16 *)(handle->buf->data + handle->buf_position)
846 = IPATCH_FILE_SWAP16(handle->file, &val);
847 handle->buf_position += 2;
848 handle->position += 2;
849 }
850
851 /**
852 * ipatch_file_buf_write_u32:
853 * @handle: File handle
854 * @val: Value to write into file buffer
855 *
856 * Writes an unsigned 32 bit word to a file buffer and advances the buffer's
857 * current position. Performs endian byte swapping if necessary.
858 * The file buffer is expanded if needed.
859 */
860 void
ipatch_file_buf_write_u32(IpatchFileHandle * handle,guint32 val)861 ipatch_file_buf_write_u32(IpatchFileHandle *handle, guint32 val)
862 {
863 g_return_if_fail(handle != NULL);
864
865 if(handle->buf_position + 4 > handle->buf->len)
866 {
867 g_byte_array_set_size(handle->buf, handle->buf_position + 4);
868 }
869
870 *(guint32 *)(handle->buf->data + handle->buf_position)
871 = IPATCH_FILE_SWAP32(handle->file, &val);
872 handle->buf_position += 4;
873 handle->position += 4;
874 }
875
876 /**
877 * ipatch_file_buf_write_u64:
878 * @handle: File handle
879 * @val: Value to write into file buffer
880 *
881 * Writes an unsigned 64 bit word to a file buffer and advances the buffer's
882 * current position. Performs endian byte swapping if necessary.
883 * The file buffer is expanded if needed.
884 */
885 void
ipatch_file_buf_write_u64(IpatchFileHandle * handle,guint64 val)886 ipatch_file_buf_write_u64(IpatchFileHandle *handle, guint64 val)
887 {
888 g_return_if_fail(handle != NULL);
889
890 if(handle->buf_position + 8 > handle->buf->len)
891 {
892 g_byte_array_set_size(handle->buf, handle->buf_position + 8);
893 }
894
895 *(guint64 *)(handle->buf->data + handle->buf_position)
896 = IPATCH_FILE_SWAP64(handle->file, &val);
897 handle->buf_position += 8;
898 handle->position += 8;
899 }
900
901 /**
902 * ipatch_file_buf_write_s8:
903 * @handle: File handle
904 * @val: Value to write into file buffer
905 *
906 * Writes a signed byte to a file buffer and advances the buffer's
907 * current position. The file buffer is expanded if needed.
908 */
909 void
ipatch_file_buf_write_s8(IpatchFileHandle * handle,gint8 val)910 ipatch_file_buf_write_s8(IpatchFileHandle *handle, gint8 val)
911 {
912 g_return_if_fail(handle != NULL);
913
914 if(handle->buf_position + 1 > handle->buf->len)
915 {
916 g_byte_array_set_size(handle->buf, handle->buf_position + 1);
917 }
918
919 *(gint8 *)(handle->buf->data + handle->buf_position) = val;
920 handle->buf_position++;
921 handle->position++;
922 }
923
924 /**
925 * ipatch_file_buf_write_s16:
926 * @handle: File handle
927 * @val: Value to write into file buffer
928 *
929 * Writes a signed 16 bit word to a file buffer and advances the buffer's
930 * current position. Performs endian byte swapping if necessary.
931 * The file buffer is expanded if needed.
932 */
933 void
ipatch_file_buf_write_s16(IpatchFileHandle * handle,gint16 val)934 ipatch_file_buf_write_s16(IpatchFileHandle *handle, gint16 val)
935 {
936 g_return_if_fail(handle != NULL);
937
938 if(handle->buf_position + 2 > handle->buf->len)
939 {
940 g_byte_array_set_size(handle->buf, handle->buf_position + 2);
941 }
942
943 *(gint16 *)(handle->buf->data + handle->buf_position)
944 = IPATCH_FILE_SWAP16(handle->file, &val);
945 handle->buf_position += 2;
946 handle->position += 2;
947 }
948
949 /**
950 * ipatch_file_buf_write_s32:
951 * @handle: File handle
952 * @val: Value to write into file buffer
953 *
954 * Writes a signed 32 bit word to a file buffer and advances the buffer's
955 * current position. Performs endian byte swapping if necessary.
956 * The file buffer is expanded if needed.
957 */
958 void
ipatch_file_buf_write_s32(IpatchFileHandle * handle,gint32 val)959 ipatch_file_buf_write_s32(IpatchFileHandle *handle, gint32 val)
960 {
961 g_return_if_fail(handle != NULL);
962
963 if(handle->buf_position + 4 > handle->buf->len)
964 {
965 g_byte_array_set_size(handle->buf, handle->buf_position + 4);
966 }
967
968 *(gint32 *)(handle->buf->data + handle->buf_position)
969 = IPATCH_FILE_SWAP32(handle->file, &val);
970 handle->buf_position += 4;
971 handle->position += 4;
972 }
973
974 /**
975 * ipatch_file_buf_write_s64:
976 * @handle: File handle
977 * @val: Value to write into file buffer
978 *
979 * Writes a signed 64 bit word to a file buffer and advances the buffer's
980 * current position. Performs endian byte swapping if necessary.
981 * The file buffer is expanded if needed.
982 */
983 void
ipatch_file_buf_write_s64(IpatchFileHandle * handle,gint64 val)984 ipatch_file_buf_write_s64(IpatchFileHandle *handle, gint64 val)
985 {
986 g_return_if_fail(handle != NULL);
987
988 if(handle->buf_position + 8 > handle->buf->len)
989 {
990 g_byte_array_set_size(handle->buf, handle->buf_position + 8);
991 }
992
993 *(gint64 *)(handle->buf->data + handle->buf_position)
994 = IPATCH_FILE_SWAP64(handle->file, &val);
995 handle->buf_position += 8;
996 handle->position += 8;
997 }
998