Line | Branch | Exec | Source |
---|---|---|---|
1 | /* GStreamer byte reader | ||
2 | * | ||
3 | * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>. | ||
4 | * Copyright (C) 2009,2014 Tim-Philipp Müller <tim centricular net> | ||
5 | * | ||
6 | * This library is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU Library General Public | ||
8 | * License as published by the Free Software Foundation; either | ||
9 | * version 2 of the License, or (at your option) any later version. | ||
10 | * | ||
11 | * This library is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * Library General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU Library General Public | ||
17 | * License along with this library; if not, write to the | ||
18 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, | ||
19 | * Boston, MA 02110-1301, USA. | ||
20 | */ | ||
21 | |||
22 | #ifdef HAVE_CONFIG_H | ||
23 | #include "config.h" | ||
24 | #endif | ||
25 | |||
26 | #define FPI_BYTE_READER_DISABLE_INLINES | ||
27 | #include "fpi-byte-reader.h" | ||
28 | |||
29 | #include <string.h> | ||
30 | |||
31 | /** | ||
32 | * SECTION:fpi-byte-reader | ||
33 | * @title: FpiByteReader | ||
34 | * @short_description: Reads different integer, string and floating point | ||
35 | * types from a memory buffer | ||
36 | * | ||
37 | * #FpiByteReader provides a byte reader that can read different integer and | ||
38 | * floating point types from a memory buffer. It provides functions for reading | ||
39 | * signed/unsigned, little/big endian integers of 8, 16, 24, 32 and 64 bits | ||
40 | * and functions for reading little/big endian floating points numbers of | ||
41 | * 32 and 64 bits. It also provides functions to read NUL-terminated strings | ||
42 | * in various character encodings. | ||
43 | */ | ||
44 | |||
45 | /** | ||
46 | * fpi_byte_reader_new: (skip) | ||
47 | * @data: (in) (transfer none) (array length=size): data from which the | ||
48 | * #FpiByteReader should read | ||
49 | * @size: Size of @data in bytes | ||
50 | * | ||
51 | * Create a new #FpiByteReader instance, which will read from @data. | ||
52 | * | ||
53 | * Free-function: fpi_byte_reader_free | ||
54 | * | ||
55 | * Returns: (transfer full): a new #FpiByteReader instance | ||
56 | */ | ||
57 | FpiByteReader * | ||
58 | ✗ | fpi_byte_reader_new (const guint8 * data, guint size) | |
59 | { | ||
60 | ✗ | FpiByteReader *ret = g_slice_new0 (FpiByteReader); | |
61 | |||
62 | ✗ | ret->data = data; | |
63 | ✗ | ret->size = size; | |
64 | |||
65 | ✗ | return ret; | |
66 | } | ||
67 | |||
68 | /** | ||
69 | * fpi_byte_reader_free: | ||
70 | * @reader: (in) (transfer full): a #FpiByteReader instance | ||
71 | * | ||
72 | * Frees a #FpiByteReader instance, which was previously allocated by | ||
73 | * fpi_byte_reader_new(). | ||
74 | */ | ||
75 | void | ||
76 | ✗ | fpi_byte_reader_free (FpiByteReader * reader) | |
77 | { | ||
78 | ✗ | g_return_if_fail (reader != NULL); | |
79 | |||
80 | ✗ | g_slice_free (FpiByteReader, reader); | |
81 | } | ||
82 | |||
83 | /** | ||
84 | * fpi_byte_reader_init: | ||
85 | * @reader: a #FpiByteReader instance | ||
86 | * @data: (in) (transfer none) (array length=size): data from which | ||
87 | * the #FpiByteReader should read | ||
88 | * @size: Size of @data in bytes | ||
89 | * | ||
90 | * Initializes a #FpiByteReader instance to read from @data. This function | ||
91 | * can be called on already initialized instances. | ||
92 | */ | ||
93 | void | ||
94 | ✗ | fpi_byte_reader_init (FpiByteReader * reader, const guint8 * data, guint size) | |
95 | { | ||
96 | ✗ | g_return_if_fail (reader != NULL); | |
97 | |||
98 | ✗ | reader->data = data; | |
99 | ✗ | reader->size = size; | |
100 | ✗ | reader->byte = 0; | |
101 | } | ||
102 | |||
103 | /** | ||
104 | * fpi_byte_reader_peek_sub_reader: (skip) | ||
105 | * @reader: an existing and initialized #FpiByteReader instance | ||
106 | * @sub_reader: a #FpiByteReader instance to initialize as sub-reader | ||
107 | * @size: size of @sub_reader in bytes | ||
108 | * | ||
109 | * Initializes a #FpiByteReader sub-reader instance to contain @size bytes of | ||
110 | * data from the current position of @reader. This is useful to read chunked | ||
111 | * formats and make sure that one doesn't read beyond the size of the sub-chunk. | ||
112 | * | ||
113 | * Unlike fpi_byte_reader_get_sub_reader(), this function does not modify the | ||
114 | * current position of @reader. | ||
115 | * | ||
116 | * Returns: FALSE on error or if @reader does not contain @size more bytes from | ||
117 | * the current position, and otherwise TRUE | ||
118 | * | ||
119 | * Since: 1.6 | ||
120 | */ | ||
121 | gboolean | ||
122 | ✗ | fpi_byte_reader_peek_sub_reader (FpiByteReader * reader, | |
123 | FpiByteReader * sub_reader, guint size) | ||
124 | { | ||
125 | ✗ | return fpi_byte_reader_peek_sub_reader_inline (reader, sub_reader, size); | |
126 | } | ||
127 | |||
128 | /** | ||
129 | * fpi_byte_reader_get_sub_reader: (skip) | ||
130 | * @reader: an existing and initialized #FpiByteReader instance | ||
131 | * @sub_reader: a #FpiByteReader instance to initialize as sub-reader | ||
132 | * @size: size of @sub_reader in bytes | ||
133 | * | ||
134 | * Initializes a #FpiByteReader sub-reader instance to contain @size bytes of | ||
135 | * data from the current position of @reader. This is useful to read chunked | ||
136 | * formats and make sure that one doesn't read beyond the size of the sub-chunk. | ||
137 | * | ||
138 | * Unlike fpi_byte_reader_peek_sub_reader(), this function also modifies the | ||
139 | * position of @reader and moves it forward by @size bytes. | ||
140 | * | ||
141 | * Returns: FALSE on error or if @reader does not contain @size more bytes from | ||
142 | * the current position, and otherwise TRUE | ||
143 | * | ||
144 | * Since: 1.6 | ||
145 | */ | ||
146 | gboolean | ||
147 | ✗ | fpi_byte_reader_get_sub_reader (FpiByteReader * reader, | |
148 | FpiByteReader * sub_reader, guint size) | ||
149 | { | ||
150 | ✗ | return fpi_byte_reader_get_sub_reader_inline (reader, sub_reader, size); | |
151 | } | ||
152 | |||
153 | /** | ||
154 | * fpi_byte_reader_set_pos: | ||
155 | * @reader: a #FpiByteReader instance | ||
156 | * @pos: The new position in bytes | ||
157 | * | ||
158 | * Sets the new position of a #FpiByteReader instance to @pos in bytes. | ||
159 | * | ||
160 | * Returns: %TRUE if the position could be set successfully, %FALSE | ||
161 | * otherwise. | ||
162 | */ | ||
163 | gboolean | ||
164 | 2051 | fpi_byte_reader_set_pos (FpiByteReader * reader, guint pos) | |
165 | { | ||
166 |
1/2✓ Branch 0 taken 2051 times.
✗ Branch 1 not taken.
|
2051 | g_return_val_if_fail (reader != NULL, FALSE); |
167 | |||
168 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2051 times.
|
2051 | if (pos > reader->size) |
169 | return FALSE; | ||
170 | |||
171 | 2051 | reader->byte = pos; | |
172 | |||
173 | 2051 | return TRUE; | |
174 | } | ||
175 | |||
176 | /** | ||
177 | * fpi_byte_reader_get_pos: | ||
178 | * @reader: a #FpiByteReader instance | ||
179 | * | ||
180 | * Returns the current position of a #FpiByteReader instance in bytes. | ||
181 | * | ||
182 | * Returns: The current position of @reader in bytes. | ||
183 | */ | ||
184 | guint | ||
185 | ✗ | fpi_byte_reader_get_pos (const FpiByteReader * reader) | |
186 | { | ||
187 | ✗ | return fpi_byte_reader_get_pos_inline (reader); | |
188 | } | ||
189 | |||
190 | /** | ||
191 | * fpi_byte_reader_get_remaining: | ||
192 | * @reader: a #FpiByteReader instance | ||
193 | * | ||
194 | * Returns the remaining number of bytes of a #FpiByteReader instance. | ||
195 | * | ||
196 | * Returns: The remaining number of bytes of @reader instance. | ||
197 | */ | ||
198 | guint | ||
199 | ✗ | fpi_byte_reader_get_remaining (const FpiByteReader * reader) | |
200 | { | ||
201 | ✗ | return fpi_byte_reader_get_remaining_inline (reader); | |
202 | } | ||
203 | |||
204 | /** | ||
205 | * fpi_byte_reader_get_size: | ||
206 | * @reader: a #FpiByteReader instance | ||
207 | * | ||
208 | * Returns the total number of bytes of a #FpiByteReader instance. | ||
209 | * | ||
210 | * Returns: The total number of bytes of @reader instance. | ||
211 | */ | ||
212 | guint | ||
213 | ✗ | fpi_byte_reader_get_size (const FpiByteReader * reader) | |
214 | { | ||
215 | ✗ | return fpi_byte_reader_get_size_inline (reader); | |
216 | } | ||
217 | |||
218 | #define fpi_byte_reader_get_remaining fpi_byte_reader_get_remaining_inline | ||
219 | #define fpi_byte_reader_get_size fpi_byte_reader_get_size_inline | ||
220 | |||
221 | /** | ||
222 | * fpi_byte_reader_skip: | ||
223 | * @reader: a #FpiByteReader instance | ||
224 | * @nbytes: the number of bytes to skip | ||
225 | * | ||
226 | * Skips @nbytes bytes of the #FpiByteReader instance. | ||
227 | * | ||
228 | * Returns: %TRUE if @nbytes bytes could be skipped, %FALSE otherwise. | ||
229 | */ | ||
230 | gboolean | ||
231 | ✗ | fpi_byte_reader_skip (FpiByteReader * reader, guint nbytes) | |
232 | { | ||
233 | ✗ | return fpi_byte_reader_skip_inline (reader, nbytes); | |
234 | } | ||
235 | |||
236 | /** | ||
237 | * fpi_byte_reader_get_uint8: | ||
238 | * @reader: a #FpiByteReader instance | ||
239 | * @val: (out): Pointer to a #guint8 to store the result | ||
240 | * | ||
241 | * Read an unsigned 8 bit integer into @val and update the current position. | ||
242 | * | ||
243 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
244 | */ | ||
245 | |||
246 | /** | ||
247 | * fpi_byte_reader_get_int8: | ||
248 | * @reader: a #FpiByteReader instance | ||
249 | * @val: (out): Pointer to a #gint8 to store the result | ||
250 | * | ||
251 | * Read a signed 8 bit integer into @val and update the current position. | ||
252 | * | ||
253 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
254 | */ | ||
255 | |||
256 | /** | ||
257 | * fpi_byte_reader_peek_uint8: | ||
258 | * @reader: a #FpiByteReader instance | ||
259 | * @val: (out): Pointer to a #guint8 to store the result | ||
260 | * | ||
261 | * Read an unsigned 8 bit integer into @val but keep the current position. | ||
262 | * | ||
263 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
264 | */ | ||
265 | |||
266 | /** | ||
267 | * fpi_byte_reader_peek_int8: | ||
268 | * @reader: a #FpiByteReader instance | ||
269 | * @val: (out): Pointer to a #gint8 to store the result | ||
270 | * | ||
271 | * Read a signed 8 bit integer into @val but keep the current position. | ||
272 | * | ||
273 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
274 | */ | ||
275 | |||
276 | /** | ||
277 | * fpi_byte_reader_get_uint16_le: | ||
278 | * @reader: a #FpiByteReader instance | ||
279 | * @val: (out): Pointer to a #guint16 to store the result | ||
280 | * | ||
281 | * Read an unsigned 16 bit little endian integer into @val | ||
282 | * and update the current position. | ||
283 | * | ||
284 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
285 | */ | ||
286 | |||
287 | /** | ||
288 | * fpi_byte_reader_get_int16_le: | ||
289 | * @reader: a #FpiByteReader instance | ||
290 | * @val: (out): Pointer to a #gint16 to store the result | ||
291 | * | ||
292 | * Read a signed 16 bit little endian integer into @val | ||
293 | * and update the current position. | ||
294 | * | ||
295 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
296 | */ | ||
297 | |||
298 | /** | ||
299 | * fpi_byte_reader_peek_uint16_le: | ||
300 | * @reader: a #FpiByteReader instance | ||
301 | * @val: (out): Pointer to a #guint16 to store the result | ||
302 | * | ||
303 | * Read an unsigned 16 bit little endian integer into @val | ||
304 | * but keep the current position. | ||
305 | * | ||
306 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
307 | */ | ||
308 | |||
309 | /** | ||
310 | * fpi_byte_reader_peek_int16_le: | ||
311 | * @reader: a #FpiByteReader instance | ||
312 | * @val: (out): Pointer to a #gint16 to store the result | ||
313 | * | ||
314 | * Read a signed 16 bit little endian integer into @val | ||
315 | * but keep the current position. | ||
316 | * | ||
317 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
318 | */ | ||
319 | |||
320 | /** | ||
321 | * fpi_byte_reader_get_uint16_be: | ||
322 | * @reader: a #FpiByteReader instance | ||
323 | * @val: (out): Pointer to a #guint16 to store the result | ||
324 | * | ||
325 | * Read an unsigned 16 bit big endian integer into @val | ||
326 | * and update the current position. | ||
327 | * | ||
328 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
329 | */ | ||
330 | |||
331 | /** | ||
332 | * fpi_byte_reader_get_int16_be: | ||
333 | * @reader: a #FpiByteReader instance | ||
334 | * @val: (out): Pointer to a #gint16 to store the result | ||
335 | * | ||
336 | * Read a signed 16 bit big endian integer into @val | ||
337 | * and update the current position. | ||
338 | * | ||
339 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
340 | */ | ||
341 | |||
342 | /** | ||
343 | * fpi_byte_reader_peek_uint16_be: | ||
344 | * @reader: a #FpiByteReader instance | ||
345 | * @val: (out): Pointer to a #guint16 to store the result | ||
346 | * | ||
347 | * Read an unsigned 16 bit big endian integer into @val | ||
348 | * but keep the current position. | ||
349 | * | ||
350 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
351 | */ | ||
352 | |||
353 | /** | ||
354 | * fpi_byte_reader_peek_int16_be: | ||
355 | * @reader: a #FpiByteReader instance | ||
356 | * @val: (out): Pointer to a #gint16 to store the result | ||
357 | * | ||
358 | * Read a signed 16 bit big endian integer into @val | ||
359 | * but keep the current position. | ||
360 | * | ||
361 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
362 | */ | ||
363 | |||
364 | /** | ||
365 | * fpi_byte_reader_get_uint24_le: | ||
366 | * @reader: a #FpiByteReader instance | ||
367 | * @val: (out): Pointer to a #guint32 to store the result | ||
368 | * | ||
369 | * Read an unsigned 24 bit little endian integer into @val | ||
370 | * and update the current position. | ||
371 | * | ||
372 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
373 | */ | ||
374 | |||
375 | /** | ||
376 | * fpi_byte_reader_get_int24_le: | ||
377 | * @reader: a #FpiByteReader instance | ||
378 | * @val: (out): Pointer to a #gint32 to store the result | ||
379 | * | ||
380 | * Read a signed 24 bit little endian integer into @val | ||
381 | * and update the current position. | ||
382 | * | ||
383 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
384 | */ | ||
385 | |||
386 | /** | ||
387 | * fpi_byte_reader_peek_uint24_le: | ||
388 | * @reader: a #FpiByteReader instance | ||
389 | * @val: (out): Pointer to a #guint32 to store the result | ||
390 | * | ||
391 | * Read an unsigned 24 bit little endian integer into @val | ||
392 | * but keep the current position. | ||
393 | * | ||
394 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
395 | */ | ||
396 | |||
397 | /** | ||
398 | * fpi_byte_reader_peek_int24_le: | ||
399 | * @reader: a #FpiByteReader instance | ||
400 | * @val: (out): Pointer to a #gint32 to store the result | ||
401 | * | ||
402 | * Read a signed 24 bit little endian integer into @val | ||
403 | * but keep the current position. | ||
404 | * | ||
405 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
406 | */ | ||
407 | |||
408 | /** | ||
409 | * fpi_byte_reader_get_uint24_be: | ||
410 | * @reader: a #FpiByteReader instance | ||
411 | * @val: (out): Pointer to a #guint32 to store the result | ||
412 | * | ||
413 | * Read an unsigned 24 bit big endian integer into @val | ||
414 | * and update the current position. | ||
415 | * | ||
416 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
417 | */ | ||
418 | |||
419 | /** | ||
420 | * fpi_byte_reader_get_int24_be: | ||
421 | * @reader: a #FpiByteReader instance | ||
422 | * @val: (out): Pointer to a #gint32 to store the result | ||
423 | * | ||
424 | * Read a signed 24 bit big endian integer into @val | ||
425 | * and update the current position. | ||
426 | * | ||
427 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
428 | */ | ||
429 | |||
430 | /** | ||
431 | * fpi_byte_reader_peek_uint24_be: | ||
432 | * @reader: a #FpiByteReader instance | ||
433 | * @val: (out): Pointer to a #guint32 to store the result | ||
434 | * | ||
435 | * Read an unsigned 24 bit big endian integer into @val | ||
436 | * but keep the current position. | ||
437 | * | ||
438 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
439 | */ | ||
440 | |||
441 | /** | ||
442 | * fpi_byte_reader_peek_int24_be: | ||
443 | * @reader: a #FpiByteReader instance | ||
444 | * @val: (out): Pointer to a #gint32 to store the result | ||
445 | * | ||
446 | * Read a signed 24 bit big endian integer into @val | ||
447 | * but keep the current position. | ||
448 | * | ||
449 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
450 | */ | ||
451 | |||
452 | |||
453 | /** | ||
454 | * fpi_byte_reader_get_uint32_le: | ||
455 | * @reader: a #FpiByteReader instance | ||
456 | * @val: (out): Pointer to a #guint32 to store the result | ||
457 | * | ||
458 | * Read an unsigned 32 bit little endian integer into @val | ||
459 | * and update the current position. | ||
460 | * | ||
461 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
462 | */ | ||
463 | |||
464 | /** | ||
465 | * fpi_byte_reader_get_int32_le: | ||
466 | * @reader: a #FpiByteReader instance | ||
467 | * @val: (out): Pointer to a #gint32 to store the result | ||
468 | * | ||
469 | * Read a signed 32 bit little endian integer into @val | ||
470 | * and update the current position. | ||
471 | * | ||
472 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
473 | */ | ||
474 | |||
475 | /** | ||
476 | * fpi_byte_reader_peek_uint32_le: | ||
477 | * @reader: a #FpiByteReader instance | ||
478 | * @val: (out): Pointer to a #guint32 to store the result | ||
479 | * | ||
480 | * Read an unsigned 32 bit little endian integer into @val | ||
481 | * but keep the current position. | ||
482 | * | ||
483 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
484 | */ | ||
485 | |||
486 | /** | ||
487 | * fpi_byte_reader_peek_int32_le: | ||
488 | * @reader: a #FpiByteReader instance | ||
489 | * @val: (out): Pointer to a #gint32 to store the result | ||
490 | * | ||
491 | * Read a signed 32 bit little endian integer into @val | ||
492 | * but keep the current position. | ||
493 | * | ||
494 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
495 | */ | ||
496 | |||
497 | /** | ||
498 | * fpi_byte_reader_get_uint32_be: | ||
499 | * @reader: a #FpiByteReader instance | ||
500 | * @val: (out): Pointer to a #guint32 to store the result | ||
501 | * | ||
502 | * Read an unsigned 32 bit big endian integer into @val | ||
503 | * and update the current position. | ||
504 | * | ||
505 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
506 | */ | ||
507 | |||
508 | /** | ||
509 | * fpi_byte_reader_get_int32_be: | ||
510 | * @reader: a #FpiByteReader instance | ||
511 | * @val: (out): Pointer to a #gint32 to store the result | ||
512 | * | ||
513 | * Read a signed 32 bit big endian integer into @val | ||
514 | * and update the current position. | ||
515 | * | ||
516 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
517 | */ | ||
518 | |||
519 | /** | ||
520 | * fpi_byte_reader_peek_uint32_be: | ||
521 | * @reader: a #FpiByteReader instance | ||
522 | * @val: (out): Pointer to a #guint32 to store the result | ||
523 | * | ||
524 | * Read an unsigned 32 bit big endian integer into @val | ||
525 | * but keep the current position. | ||
526 | * | ||
527 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
528 | */ | ||
529 | |||
530 | /** | ||
531 | * fpi_byte_reader_peek_int32_be: | ||
532 | * @reader: a #FpiByteReader instance | ||
533 | * @val: (out): Pointer to a #gint32 to store the result | ||
534 | * | ||
535 | * Read a signed 32 bit big endian integer into @val | ||
536 | * but keep the current position. | ||
537 | * | ||
538 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
539 | */ | ||
540 | |||
541 | /** | ||
542 | * fpi_byte_reader_get_uint64_le: | ||
543 | * @reader: a #FpiByteReader instance | ||
544 | * @val: (out): Pointer to a #guint64 to store the result | ||
545 | * | ||
546 | * Read an unsigned 64 bit little endian integer into @val | ||
547 | * and update the current position. | ||
548 | * | ||
549 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
550 | */ | ||
551 | |||
552 | /** | ||
553 | * fpi_byte_reader_get_int64_le: | ||
554 | * @reader: a #FpiByteReader instance | ||
555 | * @val: (out): Pointer to a #gint64 to store the result | ||
556 | * | ||
557 | * Read a signed 64 bit little endian integer into @val | ||
558 | * and update the current position. | ||
559 | * | ||
560 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
561 | */ | ||
562 | |||
563 | /** | ||
564 | * fpi_byte_reader_peek_uint64_le: | ||
565 | * @reader: a #FpiByteReader instance | ||
566 | * @val: (out): Pointer to a #guint64 to store the result | ||
567 | * | ||
568 | * Read an unsigned 64 bit little endian integer into @val | ||
569 | * but keep the current position. | ||
570 | * | ||
571 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
572 | */ | ||
573 | |||
574 | /** | ||
575 | * fpi_byte_reader_peek_int64_le: | ||
576 | * @reader: a #FpiByteReader instance | ||
577 | * @val: (out): Pointer to a #gint64 to store the result | ||
578 | * | ||
579 | * Read a signed 64 bit little endian integer into @val | ||
580 | * but keep the current position. | ||
581 | * | ||
582 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
583 | */ | ||
584 | |||
585 | /** | ||
586 | * fpi_byte_reader_get_uint64_be: | ||
587 | * @reader: a #FpiByteReader instance | ||
588 | * @val: (out): Pointer to a #guint64 to store the result | ||
589 | * | ||
590 | * Read an unsigned 64 bit big endian integer into @val | ||
591 | * and update the current position. | ||
592 | * | ||
593 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
594 | */ | ||
595 | |||
596 | /** | ||
597 | * fpi_byte_reader_get_int64_be: | ||
598 | * @reader: a #FpiByteReader instance | ||
599 | * @val: (out): Pointer to a #gint64 to store the result | ||
600 | * | ||
601 | * Read a signed 64 bit big endian integer into @val | ||
602 | * and update the current position. | ||
603 | * | ||
604 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
605 | */ | ||
606 | |||
607 | /** | ||
608 | * fpi_byte_reader_peek_uint64_be: | ||
609 | * @reader: a #FpiByteReader instance | ||
610 | * @val: (out): Pointer to a #guint64 to store the result | ||
611 | * | ||
612 | * Read an unsigned 64 bit big endian integer into @val | ||
613 | * but keep the current position. | ||
614 | * | ||
615 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
616 | */ | ||
617 | |||
618 | /** | ||
619 | * fpi_byte_reader_peek_int64_be: | ||
620 | * @reader: a #FpiByteReader instance | ||
621 | * @val: (out): Pointer to a #gint64 to store the result | ||
622 | * | ||
623 | * Read a signed 64 bit big endian integer into @val | ||
624 | * but keep the current position. | ||
625 | * | ||
626 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
627 | */ | ||
628 | |||
629 | #define FPI_BYTE_READER_PEEK_GET(bits,type,name) \ | ||
630 | gboolean \ | ||
631 | fpi_byte_reader_get_##name (FpiByteReader * reader, type * val) \ | ||
632 | { \ | ||
633 | return fpi_byte_reader_get_##name##_inline (reader, val); \ | ||
634 | } \ | ||
635 | \ | ||
636 | gboolean \ | ||
637 | fpi_byte_reader_peek_##name (const FpiByteReader * reader, type * val) \ | ||
638 | { \ | ||
639 | return fpi_byte_reader_peek_##name##_inline (reader, val); \ | ||
640 | } | ||
641 | |||
642 | /* *INDENT-OFF* */ | ||
643 | |||
644 | ✗ | FPI_BYTE_READER_PEEK_GET(8,guint8,uint8) | |
645 | ✗ | FPI_BYTE_READER_PEEK_GET(8,gint8,int8) | |
646 | |||
647 | ✗ | FPI_BYTE_READER_PEEK_GET(16,guint16,uint16_le) | |
648 | ✗ | FPI_BYTE_READER_PEEK_GET(16,guint16,uint16_be) | |
649 | ✗ | FPI_BYTE_READER_PEEK_GET(16,gint16,int16_le) | |
650 | ✗ | FPI_BYTE_READER_PEEK_GET(16,gint16,int16_be) | |
651 | |||
652 | ✗ | FPI_BYTE_READER_PEEK_GET(24,guint32,uint24_le) | |
653 | ✗ | FPI_BYTE_READER_PEEK_GET(24,guint32,uint24_be) | |
654 | ✗ | FPI_BYTE_READER_PEEK_GET(24,gint32,int24_le) | |
655 | ✗ | FPI_BYTE_READER_PEEK_GET(24,gint32,int24_be) | |
656 | |||
657 | ✗ | FPI_BYTE_READER_PEEK_GET(32,guint32,uint32_le) | |
658 | ✗ | FPI_BYTE_READER_PEEK_GET(32,guint32,uint32_be) | |
659 | ✗ | FPI_BYTE_READER_PEEK_GET(32,gint32,int32_le) | |
660 | ✗ | FPI_BYTE_READER_PEEK_GET(32,gint32,int32_be) | |
661 | |||
662 | ✗ | FPI_BYTE_READER_PEEK_GET(64,guint64,uint64_le) | |
663 | ✗ | FPI_BYTE_READER_PEEK_GET(64,guint64,uint64_be) | |
664 | ✗ | FPI_BYTE_READER_PEEK_GET(64,gint64,int64_le) | |
665 | ✗ | FPI_BYTE_READER_PEEK_GET(64,gint64,int64_be) | |
666 | |||
667 | /** | ||
668 | * fpi_byte_reader_get_float32_le: | ||
669 | * @reader: a #FpiByteReader instance | ||
670 | * @val: (out): Pointer to a #gfloat to store the result | ||
671 | * | ||
672 | * Read a 32 bit little endian floating point value into @val | ||
673 | * and update the current position. | ||
674 | * | ||
675 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
676 | */ | ||
677 | |||
678 | /** | ||
679 | * fpi_byte_reader_peek_float32_le: | ||
680 | * @reader: a #FpiByteReader instance | ||
681 | * @val: (out): Pointer to a #gfloat to store the result | ||
682 | * | ||
683 | * Read a 32 bit little endian floating point value into @val | ||
684 | * but keep the current position. | ||
685 | * | ||
686 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
687 | */ | ||
688 | |||
689 | /** | ||
690 | * fpi_byte_reader_get_float32_be: | ||
691 | * @reader: a #FpiByteReader instance | ||
692 | * @val: (out): Pointer to a #gfloat to store the result | ||
693 | * | ||
694 | * Read a 32 bit big endian floating point value into @val | ||
695 | * and update the current position. | ||
696 | * | ||
697 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
698 | */ | ||
699 | |||
700 | /** | ||
701 | * fpi_byte_reader_peek_float32_be: | ||
702 | * @reader: a #FpiByteReader instance | ||
703 | * @val: (out): Pointer to a #gfloat to store the result | ||
704 | * | ||
705 | * Read a 32 bit big endian floating point value into @val | ||
706 | * but keep the current position. | ||
707 | * | ||
708 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
709 | */ | ||
710 | |||
711 | /** | ||
712 | * fpi_byte_reader_get_float64_le: | ||
713 | * @reader: a #FpiByteReader instance | ||
714 | * @val: (out): Pointer to a #gdouble to store the result | ||
715 | * | ||
716 | * Read a 64 bit little endian floating point value into @val | ||
717 | * and update the current position. | ||
718 | * | ||
719 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
720 | */ | ||
721 | |||
722 | /** | ||
723 | * fpi_byte_reader_peek_float64_le: | ||
724 | * @reader: a #FpiByteReader instance | ||
725 | * @val: (out): Pointer to a #gdouble to store the result | ||
726 | * | ||
727 | * Read a 64 bit little endian floating point value into @val | ||
728 | * but keep the current position. | ||
729 | * | ||
730 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
731 | */ | ||
732 | |||
733 | /** | ||
734 | * fpi_byte_reader_get_float64_be: | ||
735 | * @reader: a #FpiByteReader instance | ||
736 | * @val: (out): Pointer to a #gdouble to store the result | ||
737 | * | ||
738 | * Read a 64 bit big endian floating point value into @val | ||
739 | * and update the current position. | ||
740 | * | ||
741 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
742 | */ | ||
743 | |||
744 | /** | ||
745 | * fpi_byte_reader_peek_float64_be: | ||
746 | * @reader: a #FpiByteReader instance | ||
747 | * @val: (out): Pointer to a #gdouble to store the result | ||
748 | * | ||
749 | * Read a 64 bit big endian floating point value into @val | ||
750 | * but keep the current position. | ||
751 | * | ||
752 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
753 | */ | ||
754 | |||
755 | ✗ | FPI_BYTE_READER_PEEK_GET(32,gfloat,float32_le) | |
756 | ✗ | FPI_BYTE_READER_PEEK_GET(32,gfloat,float32_be) | |
757 | ✗ | FPI_BYTE_READER_PEEK_GET(64,gdouble,float64_le) | |
758 | ✗ | FPI_BYTE_READER_PEEK_GET(64,gdouble,float64_be) | |
759 | |||
760 | /* *INDENT-ON* */ | ||
761 | |||
762 | /** | ||
763 | * fpi_byte_reader_get_data: | ||
764 | * @reader: a #FpiByteReader instance | ||
765 | * @size: Size in bytes | ||
766 | * @val: (out) (transfer none) (array length=size): address of a | ||
767 | * #guint8 pointer variable in which to store the result | ||
768 | * | ||
769 | * Returns a constant pointer to the current data | ||
770 | * position if at least @size bytes are left and | ||
771 | * updates the current position. | ||
772 | * | ||
773 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
774 | */ | ||
775 | gboolean | ||
776 | ✗ | fpi_byte_reader_get_data (FpiByteReader * reader, guint size, | |
777 | const guint8 ** val) | ||
778 | { | ||
779 | ✗ | return fpi_byte_reader_get_data_inline (reader, size, val); | |
780 | } | ||
781 | |||
782 | /** | ||
783 | * fpi_byte_reader_peek_data: | ||
784 | * @reader: a #FpiByteReader instance | ||
785 | * @size: Size in bytes | ||
786 | * @val: (out) (transfer none) (array length=size): address of a | ||
787 | * #guint8 pointer variable in which to store the result | ||
788 | * | ||
789 | * Returns a constant pointer to the current data | ||
790 | * position if at least @size bytes are left and | ||
791 | * keeps the current position. | ||
792 | * | ||
793 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
794 | */ | ||
795 | gboolean | ||
796 | ✗ | fpi_byte_reader_peek_data (const FpiByteReader * reader, guint size, | |
797 | const guint8 ** val) | ||
798 | { | ||
799 | ✗ | return fpi_byte_reader_peek_data_inline (reader, size, val); | |
800 | } | ||
801 | |||
802 | /** | ||
803 | * fpi_byte_reader_dup_data: | ||
804 | * @reader: a #FpiByteReader instance | ||
805 | * @size: Size in bytes | ||
806 | * @val: (out) (transfer full) (array length=size): address of a | ||
807 | * #guint8 pointer variable in which to store the result | ||
808 | * | ||
809 | * Free-function: g_free | ||
810 | * | ||
811 | * Returns a newly-allocated copy of the current data | ||
812 | * position if at least @size bytes are left and | ||
813 | * updates the current position. Free with g_free() when no longer needed. | ||
814 | * | ||
815 | * Returns: %TRUE if successful, %FALSE otherwise. | ||
816 | */ | ||
817 | gboolean | ||
818 | ✗ | fpi_byte_reader_dup_data (FpiByteReader * reader, guint size, guint8 ** val) | |
819 | { | ||
820 | ✗ | return fpi_byte_reader_dup_data_inline (reader, size, val); | |
821 | } | ||
822 | |||
823 | /* Special optimized scan for mask 0xffffff00 and pattern 0x00000100 */ | ||
824 | static inline gint | ||
825 | ✗ | _scan_for_start_code (const guint8 * data, guint size) | |
826 | { | ||
827 | ✗ | guint8 *pdata = (guint8 *) data; | |
828 | ✗ | guint8 *pend = (guint8 *) (data + size - 4); | |
829 | |||
830 | ✗ | while (pdata <= pend) { | |
831 | ✗ | if (pdata[2] > 1) { | |
832 | ✗ | pdata += 3; | |
833 | ✗ | } else if (pdata[1]) { | |
834 | ✗ | pdata += 2; | |
835 | ✗ | } else if (pdata[0] || pdata[2] != 1) { | |
836 | ✗ | pdata++; | |
837 | } else { | ||
838 | ✗ | return (pdata - data); | |
839 | } | ||
840 | } | ||
841 | |||
842 | /* nothing found */ | ||
843 | return -1; | ||
844 | } | ||
845 | |||
846 | static inline guint | ||
847 | ✗ | _masked_scan_uint32_peek (const FpiByteReader * reader, | |
848 | guint32 mask, guint32 pattern, guint offset, guint size, guint32 * value) | ||
849 | { | ||
850 | ✗ | const guint8 *data; | |
851 | ✗ | guint32 state; | |
852 | ✗ | guint i; | |
853 | |||
854 | ✗ | g_return_val_if_fail (size > 0, -1); | |
855 | ✗ | g_return_val_if_fail ((guint64) offset + size <= reader->size - reader->byte, | |
856 | -1); | ||
857 | |||
858 | /* we can't find the pattern with less than 4 bytes */ | ||
859 | ✗ | if (G_UNLIKELY (size < 4)) | |
860 | return -1; | ||
861 | |||
862 | ✗ | data = reader->data + reader->byte + offset; | |
863 | |||
864 | /* Handle special case found in MPEG and H264 */ | ||
865 | ✗ | if ((pattern == 0x00000100) && (mask == 0xffffff00)) { | |
866 | ✗ | gint ret = _scan_for_start_code (data, size); | |
867 | |||
868 | ✗ | if (ret == -1) | |
869 | return ret; | ||
870 | |||
871 | ✗ | if (value != NULL) | |
872 | ✗ | *value = (1 << 8) | data[ret + 3]; | |
873 | |||
874 | ✗ | return ret + offset; | |
875 | } | ||
876 | |||
877 | /* set the state to something that does not match */ | ||
878 | ✗ | state = ~pattern; | |
879 | |||
880 | /* now find data */ | ||
881 | ✗ | for (i = 0; i < size; i++) { | |
882 | /* throw away one byte and move in the next byte */ | ||
883 | ✗ | state = ((state << 8) | data[i]); | |
884 | ✗ | if (G_UNLIKELY ((state & mask) == pattern)) { | |
885 | /* we have a match but we need to have skipped at | ||
886 | * least 4 bytes to fill the state. */ | ||
887 | ✗ | if (G_LIKELY (i >= 3)) { | |
888 | ✗ | if (value) | |
889 | ✗ | *value = state; | |
890 | ✗ | return offset + i - 3; | |
891 | } | ||
892 | } | ||
893 | } | ||
894 | |||
895 | /* nothing found */ | ||
896 | return -1; | ||
897 | } | ||
898 | |||
899 | |||
900 | /** | ||
901 | * fpi_byte_reader_masked_scan_uint32: | ||
902 | * @reader: a #FpiByteReader | ||
903 | * @mask: mask to apply to data before matching against @pattern | ||
904 | * @pattern: pattern to match (after mask is applied) | ||
905 | * @offset: offset from which to start scanning, relative to the current | ||
906 | * position | ||
907 | * @size: number of bytes to scan from offset | ||
908 | * | ||
909 | * Scan for pattern @pattern with applied mask @mask in the byte reader data, | ||
910 | * starting from offset @offset relative to the current position. | ||
911 | * | ||
912 | * The bytes in @pattern and @mask are interpreted left-to-right, regardless | ||
913 | * of endianness. All four bytes of the pattern must be present in the | ||
914 | * byte reader data for it to match, even if the first or last bytes are masked | ||
915 | * out. | ||
916 | * | ||
917 | * It is an error to call this function without making sure that there is | ||
918 | * enough data (offset+size bytes) in the byte reader. | ||
919 | * | ||
920 | * Returns: offset of the first match, or -1 if no match was found. | ||
921 | * | ||
922 | * Example: | ||
923 | * |[ | ||
924 | * // Assume the reader contains 0x00 0x01 0x02 ... 0xfe 0xff | ||
925 | * | ||
926 | * fpi_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0x00010203, 0, 256); | ||
927 | * // -> returns 0 | ||
928 | * fpi_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0x00010203, 1, 255); | ||
929 | * // -> returns -1 | ||
930 | * fpi_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0x01020304, 1, 255); | ||
931 | * // -> returns 1 | ||
932 | * fpi_byte_reader_masked_scan_uint32 (reader, 0xffff, 0x0001, 0, 256); | ||
933 | * // -> returns -1 | ||
934 | * fpi_byte_reader_masked_scan_uint32 (reader, 0xffff, 0x0203, 0, 256); | ||
935 | * // -> returns 0 | ||
936 | * fpi_byte_reader_masked_scan_uint32 (reader, 0xffff0000, 0x02030000, 0, 256); | ||
937 | * // -> returns 2 | ||
938 | * fpi_byte_reader_masked_scan_uint32 (reader, 0xffff0000, 0x02030000, 0, 4); | ||
939 | * // -> returns -1 | ||
940 | * ]| | ||
941 | */ | ||
942 | guint | ||
943 | ✗ | fpi_byte_reader_masked_scan_uint32 (const FpiByteReader * reader, guint32 mask, | |
944 | guint32 pattern, guint offset, guint size) | ||
945 | { | ||
946 | ✗ | return _masked_scan_uint32_peek (reader, mask, pattern, offset, size, NULL); | |
947 | } | ||
948 | |||
949 | /** | ||
950 | * fpi_byte_reader_masked_scan_uint32_peek: | ||
951 | * @reader: a #FpiByteReader | ||
952 | * @mask: mask to apply to data before matching against @pattern | ||
953 | * @pattern: pattern to match (after mask is applied) | ||
954 | * @offset: offset from which to start scanning, relative to the current | ||
955 | * position | ||
956 | * @size: number of bytes to scan from offset | ||
957 | * @value: (out): pointer to uint32 to return matching data | ||
958 | * | ||
959 | * Scan for pattern @pattern with applied mask @mask in the byte reader data, | ||
960 | * starting from offset @offset relative to the current position. | ||
961 | * | ||
962 | * The bytes in @pattern and @mask are interpreted left-to-right, regardless | ||
963 | * of endianness. All four bytes of the pattern must be present in the | ||
964 | * byte reader data for it to match, even if the first or last bytes are masked | ||
965 | * out. | ||
966 | * | ||
967 | * It is an error to call this function without making sure that there is | ||
968 | * enough data (offset+size bytes) in the byte reader. | ||
969 | * | ||
970 | * Returns: offset of the first match, or -1 if no match was found. | ||
971 | * | ||
972 | * Since: 1.6 | ||
973 | */ | ||
974 | guint | ||
975 | ✗ | fpi_byte_reader_masked_scan_uint32_peek (const FpiByteReader * reader, | |
976 | guint32 mask, guint32 pattern, guint offset, guint size, guint32 * value) | ||
977 | { | ||
978 | ✗ | return _masked_scan_uint32_peek (reader, mask, pattern, offset, size, value); | |
979 | } | ||
980 | |||
981 | #define FPI_BYTE_READER_SCAN_STRING(bits) \ | ||
982 | static guint \ | ||
983 | fpi_byte_reader_scan_string_utf##bits (const FpiByteReader * reader) \ | ||
984 | { \ | ||
985 | guint len, off, max_len; \ | ||
986 | \ | ||
987 | max_len = (reader->size - reader->byte) / sizeof (guint##bits); \ | ||
988 | \ | ||
989 | /* need at least a single NUL terminator */ \ | ||
990 | if (max_len < 1) \ | ||
991 | return 0; \ | ||
992 | \ | ||
993 | len = 0; \ | ||
994 | off = reader->byte; \ | ||
995 | /* endianness does not matter if we are looking for a NUL terminator */ \ | ||
996 | while (FP_READ_UINT##bits##_LE (&reader->data[off]) != 0) { \ | ||
997 | ++len; \ | ||
998 | off += sizeof (guint##bits); \ | ||
999 | /* have we reached the end without finding a NUL terminator? */ \ | ||
1000 | if (len == max_len) \ | ||
1001 | return 0; \ | ||
1002 | } \ | ||
1003 | /* return size in bytes including the NUL terminator (hence the +1) */ \ | ||
1004 | return (len + 1) * sizeof (guint##bits); \ | ||
1005 | } | ||
1006 | |||
1007 | #define FP_READ_UINT8_LE FP_READ_UINT8 | ||
1008 | ✗ | FPI_BYTE_READER_SCAN_STRING (8); | |
1009 | #undef FP_READ_UINT8_LE | ||
1010 | ✗ | FPI_BYTE_READER_SCAN_STRING (16); | |
1011 | ✗ | FPI_BYTE_READER_SCAN_STRING (32); | |
1012 | |||
1013 | #define FPI_BYTE_READER_SKIP_STRING(bits) \ | ||
1014 | gboolean \ | ||
1015 | fpi_byte_reader_skip_string_utf##bits (FpiByteReader * reader) \ | ||
1016 | { \ | ||
1017 | guint size; /* size in bytes including the terminator */ \ | ||
1018 | \ | ||
1019 | g_return_val_if_fail (reader != NULL, FALSE); \ | ||
1020 | \ | ||
1021 | size = fpi_byte_reader_scan_string_utf##bits (reader); \ | ||
1022 | reader->byte += size; \ | ||
1023 | return (size > 0); \ | ||
1024 | } | ||
1025 | |||
1026 | /** | ||
1027 | * fpi_byte_reader_skip_string: | ||
1028 | * @reader: a #FpiByteReader instance | ||
1029 | * | ||
1030 | * Skips a NUL-terminated string in the #FpiByteReader instance, advancing | ||
1031 | * the current position to the byte after the string. This will work for | ||
1032 | * any NUL-terminated string with a character width of 8 bits, so ASCII, | ||
1033 | * UTF-8, ISO-8859-N etc. | ||
1034 | * | ||
1035 | * This function will fail if no NUL-terminator was found in in the data. | ||
1036 | * | ||
1037 | * Returns: %TRUE if a string could be skipped, %FALSE otherwise. | ||
1038 | */ | ||
1039 | /** | ||
1040 | * fpi_byte_reader_skip_string_utf8: | ||
1041 | * @reader: a #FpiByteReader instance | ||
1042 | * | ||
1043 | * Skips a NUL-terminated string in the #FpiByteReader instance, advancing | ||
1044 | * the current position to the byte after the string. This will work for | ||
1045 | * any NUL-terminated string with a character width of 8 bits, so ASCII, | ||
1046 | * UTF-8, ISO-8859-N etc. No input checking for valid UTF-8 is done. | ||
1047 | * | ||
1048 | * This function will fail if no NUL-terminator was found in in the data. | ||
1049 | * | ||
1050 | * Returns: %TRUE if a string could be skipped, %FALSE otherwise. | ||
1051 | */ | ||
1052 | ✗ | FPI_BYTE_READER_SKIP_STRING (8); | |
1053 | |||
1054 | /** | ||
1055 | * fpi_byte_reader_skip_string_utf16: | ||
1056 | * @reader: a #FpiByteReader instance | ||
1057 | * | ||
1058 | * Skips a NUL-terminated UTF-16 string in the #FpiByteReader instance, | ||
1059 | * advancing the current position to the byte after the string. | ||
1060 | * | ||
1061 | * No input checking for valid UTF-16 is done. | ||
1062 | * | ||
1063 | * This function will fail if no NUL-terminator was found in in the data. | ||
1064 | * | ||
1065 | * Returns: %TRUE if a string could be skipped, %FALSE otherwise. | ||
1066 | */ | ||
1067 | ✗ | FPI_BYTE_READER_SKIP_STRING (16); | |
1068 | |||
1069 | /** | ||
1070 | * fpi_byte_reader_skip_string_utf32: | ||
1071 | * @reader: a #FpiByteReader instance | ||
1072 | * | ||
1073 | * Skips a NUL-terminated UTF-32 string in the #FpiByteReader instance, | ||
1074 | * advancing the current position to the byte after the string. | ||
1075 | * | ||
1076 | * No input checking for valid UTF-32 is done. | ||
1077 | * | ||
1078 | * This function will fail if no NUL-terminator was found in in the data. | ||
1079 | * | ||
1080 | * Returns: %TRUE if a string could be skipped, %FALSE otherwise. | ||
1081 | */ | ||
1082 | ✗ | FPI_BYTE_READER_SKIP_STRING (32); | |
1083 | |||
1084 | /** | ||
1085 | * fpi_byte_reader_peek_string: | ||
1086 | * @reader: a #FpiByteReader instance | ||
1087 | * @str: (out) (transfer none) (array zero-terminated=1): address of a | ||
1088 | * #gchar pointer variable in which to store the result | ||
1089 | * | ||
1090 | * Returns a constant pointer to the current data position if there is | ||
1091 | * a NUL-terminated string in the data (this could be just a NUL terminator). | ||
1092 | * The current position will be maintained. This will work for any | ||
1093 | * NUL-terminated string with a character width of 8 bits, so ASCII, | ||
1094 | * UTF-8, ISO-8859-N etc. | ||
1095 | * | ||
1096 | * This function will fail if no NUL-terminator was found in in the data. | ||
1097 | * | ||
1098 | * Returns: %TRUE if a string could be skipped, %FALSE otherwise. | ||
1099 | */ | ||
1100 | /** | ||
1101 | * fpi_byte_reader_peek_string_utf8: | ||
1102 | * @reader: a #FpiByteReader instance | ||
1103 | * @str: (out) (transfer none) (array zero-terminated=1): address of a | ||
1104 | * #gchar pointer variable in which to store the result | ||
1105 | * | ||
1106 | * Returns a constant pointer to the current data position if there is | ||
1107 | * a NUL-terminated string in the data (this could be just a NUL terminator). | ||
1108 | * The current position will be maintained. This will work for any | ||
1109 | * NUL-terminated string with a character width of 8 bits, so ASCII, | ||
1110 | * UTF-8, ISO-8859-N etc. | ||
1111 | * | ||
1112 | * No input checking for valid UTF-8 is done. | ||
1113 | * | ||
1114 | * This function will fail if no NUL-terminator was found in in the data. | ||
1115 | * | ||
1116 | * Returns: %TRUE if a string could be skipped, %FALSE otherwise. | ||
1117 | */ | ||
1118 | gboolean | ||
1119 | ✗ | fpi_byte_reader_peek_string_utf8 (const FpiByteReader * reader, | |
1120 | const gchar ** str) | ||
1121 | { | ||
1122 | ✗ | g_return_val_if_fail (reader != NULL, FALSE); | |
1123 | ✗ | g_return_val_if_fail (str != NULL, FALSE); | |
1124 | |||
1125 | ✗ | if (fpi_byte_reader_scan_string_utf8 (reader) > 0) { | |
1126 | ✗ | *str = (const gchar *) (reader->data + reader->byte); | |
1127 | } else { | ||
1128 | ✗ | *str = NULL; | |
1129 | } | ||
1130 | ✗ | return (*str != NULL); | |
1131 | } | ||
1132 | |||
1133 | /** | ||
1134 | * fpi_byte_reader_get_string_utf8: | ||
1135 | * @reader: a #FpiByteReader instance | ||
1136 | * @str: (out) (transfer none) (array zero-terminated=1): address of a | ||
1137 | * #gchar pointer variable in which to store the result | ||
1138 | * | ||
1139 | * Returns a constant pointer to the current data position if there is | ||
1140 | * a NUL-terminated string in the data (this could be just a NUL terminator), | ||
1141 | * advancing the current position to the byte after the string. This will work | ||
1142 | * for any NUL-terminated string with a character width of 8 bits, so ASCII, | ||
1143 | * UTF-8, ISO-8859-N etc. | ||
1144 | * | ||
1145 | * No input checking for valid UTF-8 is done. | ||
1146 | * | ||
1147 | * This function will fail if no NUL-terminator was found in in the data. | ||
1148 | * | ||
1149 | * Returns: %TRUE if a string could be found, %FALSE otherwise. | ||
1150 | */ | ||
1151 | gboolean | ||
1152 | ✗ | fpi_byte_reader_get_string_utf8 (FpiByteReader * reader, const gchar ** str) | |
1153 | { | ||
1154 | ✗ | guint size; /* size in bytes including the terminator */ | |
1155 | |||
1156 | ✗ | g_return_val_if_fail (reader != NULL, FALSE); | |
1157 | ✗ | g_return_val_if_fail (str != NULL, FALSE); | |
1158 | |||
1159 | ✗ | size = fpi_byte_reader_scan_string_utf8 (reader); | |
1160 | ✗ | if (size == 0) { | |
1161 | ✗ | *str = NULL; | |
1162 | ✗ | return FALSE; | |
1163 | } | ||
1164 | |||
1165 | ✗ | *str = (const gchar *) (reader->data + reader->byte); | |
1166 | ✗ | reader->byte += size; | |
1167 | ✗ | return TRUE; | |
1168 | } | ||
1169 | |||
1170 | #define FPI_BYTE_READER_DUP_STRING(bits,type) \ | ||
1171 | gboolean \ | ||
1172 | fpi_byte_reader_dup_string_utf##bits (FpiByteReader * reader, type ** str) \ | ||
1173 | { \ | ||
1174 | guint size; /* size in bytes including the terminator */ \ | ||
1175 | \ | ||
1176 | g_return_val_if_fail (reader != NULL, FALSE); \ | ||
1177 | g_return_val_if_fail (str != NULL, FALSE); \ | ||
1178 | \ | ||
1179 | size = fpi_byte_reader_scan_string_utf##bits (reader); \ | ||
1180 | if (size == 0) { \ | ||
1181 | *str = NULL; \ | ||
1182 | return FALSE; \ | ||
1183 | } \ | ||
1184 | *str = g_memdup2 (reader->data + reader->byte, size); \ | ||
1185 | reader->byte += size; \ | ||
1186 | return TRUE; \ | ||
1187 | } | ||
1188 | |||
1189 | /** | ||
1190 | * fpi_byte_reader_dup_string_utf8: | ||
1191 | * @reader: a #FpiByteReader instance | ||
1192 | * @str: (out) (transfer full) (array zero-terminated=1): address of a | ||
1193 | * #gchar pointer variable in which to store the result | ||
1194 | * | ||
1195 | * Free-function: g_free | ||
1196 | * | ||
1197 | * FIXME:Reads (copies) a NUL-terminated string in the #FpiByteReader instance, | ||
1198 | * advancing the current position to the byte after the string. This will work | ||
1199 | * for any NUL-terminated string with a character width of 8 bits, so ASCII, | ||
1200 | * UTF-8, ISO-8859-N etc. No input checking for valid UTF-8 is done. | ||
1201 | * | ||
1202 | * This function will fail if no NUL-terminator was found in in the data. | ||
1203 | * | ||
1204 | * Returns: %TRUE if a string could be read into @str, %FALSE otherwise. The | ||
1205 | * string put into @str must be freed with g_free() when no longer needed. | ||
1206 | */ | ||
1207 | ✗ | FPI_BYTE_READER_DUP_STRING (8, gchar); | |
1208 | |||
1209 | /** | ||
1210 | * fpi_byte_reader_dup_string_utf16: | ||
1211 | * @reader: a #FpiByteReader instance | ||
1212 | * @str: (out) (transfer full) (array zero-terminated=1): address of a | ||
1213 | * #guint16 pointer variable in which to store the result | ||
1214 | * | ||
1215 | * Free-function: g_free | ||
1216 | * | ||
1217 | * Returns a newly-allocated copy of the current data position if there is | ||
1218 | * a NUL-terminated UTF-16 string in the data (this could be an empty string | ||
1219 | * as well), and advances the current position. | ||
1220 | * | ||
1221 | * No input checking for valid UTF-16 is done. This function is endianness | ||
1222 | * agnostic - you should not assume the UTF-16 characters are in host | ||
1223 | * endianness. | ||
1224 | * | ||
1225 | * This function will fail if no NUL-terminator was found in in the data. | ||
1226 | * | ||
1227 | * Note: there is no peek or get variant of this function to ensure correct | ||
1228 | * byte alignment of the UTF-16 string. | ||
1229 | * | ||
1230 | * Returns: %TRUE if a string could be read, %FALSE otherwise. The | ||
1231 | * string put into @str must be freed with g_free() when no longer needed. | ||
1232 | */ | ||
1233 | ✗ | FPI_BYTE_READER_DUP_STRING (16, guint16); | |
1234 | |||
1235 | /** | ||
1236 | * fpi_byte_reader_dup_string_utf32: | ||
1237 | * @reader: a #FpiByteReader instance | ||
1238 | * @str: (out) (transfer full) (array zero-terminated=1): address of a | ||
1239 | * #guint32 pointer variable in which to store the result | ||
1240 | * | ||
1241 | * Free-function: g_free | ||
1242 | * | ||
1243 | * Returns a newly-allocated copy of the current data position if there is | ||
1244 | * a NUL-terminated UTF-32 string in the data (this could be an empty string | ||
1245 | * as well), and advances the current position. | ||
1246 | * | ||
1247 | * No input checking for valid UTF-32 is done. This function is endianness | ||
1248 | * agnostic - you should not assume the UTF-32 characters are in host | ||
1249 | * endianness. | ||
1250 | * | ||
1251 | * This function will fail if no NUL-terminator was found in in the data. | ||
1252 | * | ||
1253 | * Note: there is no peek or get variant of this function to ensure correct | ||
1254 | * byte alignment of the UTF-32 string. | ||
1255 | * | ||
1256 | * Returns: %TRUE if a string could be read, %FALSE otherwise. The | ||
1257 | * string put into @str must be freed with g_free() when no longer needed. | ||
1258 | */ | ||
1259 | ✗ | FPI_BYTE_READER_DUP_STRING (32, guint32); | |
1260 |