GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 22.2% 24 / 0 / 108
Functions: 10.0% 4 / 0 / 40
Branches: 14.3% 8 / 0 / 56

libfprint/fpi-byte-writer.c
Line Branch Exec Source
1 /* GStreamer byte writer
2 *
3 * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
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 GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #define FPI_BYTE_WRITER_DISABLE_INLINES
26 #include "fpi-byte-writer.h"
27
28 /**
29 * SECTION:fpi-byte-writer
30 * @title: FpiByteWriter
31 * @short_description: Writes different integer, string and floating point
32 * types to a memory buffer and allows reading
33 *
34 * #FpiByteWriter provides a byte writer and reader that can write/read different
35 * integer and floating point types to/from a memory buffer. It provides functions
36 * for writing/reading signed/unsigned, little/big endian integers of 8, 16, 24,
37 * 32 and 64 bits and functions for reading little/big endian floating points numbers of
38 * 32 and 64 bits. It also provides functions to write/read NUL-terminated strings
39 * in various character encodings.
40 */
41
42 /**
43 * fpi_byte_writer_new: (skip)
44 *
45 * Creates a new, empty #FpiByteWriter instance
46 *
47 * Free-function: fpi_byte_writer_free
48 *
49 * Returns: (transfer full): a new, empty #FpiByteWriter instance
50 */
51 FpiByteWriter *
52 fpi_byte_writer_new (void)
53 {
54 FpiByteWriter *ret = g_slice_new0 (FpiByteWriter);
55
56 ret->owned = TRUE;
57 return ret;
58 }
59
60 /**
61 * fpi_byte_writer_new_with_size: (skip)
62 * @size: Initial size of data
63 * @fixed: If %TRUE the data can't be reallocated
64 *
65 * Creates a new #FpiByteWriter instance with the given
66 * initial data size.
67 *
68 * Free-function: fpi_byte_writer_free
69 *
70 * Returns: (transfer full): a new #FpiByteWriter instance
71 */
72 FpiByteWriter *
73 fpi_byte_writer_new_with_size (guint size, gboolean fixed)
74 {
75 FpiByteWriter *ret = fpi_byte_writer_new ();
76
77 ret->alloc_size = size;
78 ret->parent.data = g_malloc0 (ret->alloc_size);
79 ret->parent.size = size;
80 ret->fixed = fixed;
81 ret->owned = TRUE;
82
83 return ret;
84 }
85
86 /**
87 * fpi_byte_writer_new_with_data: (skip)
88 * @data: Memory area for writing
89 * @size: Size of @data in bytes
90 * @initialized: If %TRUE the complete data can be read from the beginning
91 *
92 * Creates a new #FpiByteWriter instance with the given
93 * memory area. If @initialized is %TRUE it is possible to
94 * read @size bytes from the #FpiByteWriter from the beginning.
95 *
96 * Free-function: fpi_byte_writer_free
97 *
98 * Returns: (transfer full): a new #FpiByteWriter instance
99 */
100 FpiByteWriter *
101 fpi_byte_writer_new_with_data (guint8 * data, guint size, gboolean initialized)
102 {
103 FpiByteWriter *ret = fpi_byte_writer_new ();
104
105 ret->parent.data = data;
106 ret->parent.size = (initialized) ? size : 0;
107 ret->alloc_size = size;
108 ret->fixed = TRUE;
109 ret->owned = FALSE;
110
111 return ret;
112 }
113
114 /**
115 * fpi_byte_writer_init:
116 * @writer: #FpiByteWriter instance
117 *
118 * Initializes @writer to an empty instance
119 */
120 void
121 732 fpi_byte_writer_init (FpiByteWriter * writer)
122 {
123
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 732 times.
732 g_return_if_fail (writer != NULL);
124
125 732 memset (writer, 0, sizeof (FpiByteWriter));
126
127 732 writer->owned = TRUE;
128 }
129
130 /**
131 * fpi_byte_writer_init_with_size:
132 * @writer: #FpiByteWriter instance
133 * @size: Initial size of data
134 * @fixed: If %TRUE the data can't be reallocated
135 *
136 * Initializes @writer with the given initial data size.
137 */
138 void
139 723 fpi_byte_writer_init_with_size (FpiByteWriter * writer, guint size,
140 gboolean fixed)
141 {
142
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 723 times.
723 g_return_if_fail (writer != NULL);
143
144 723 fpi_byte_writer_init (writer);
145
146 723 writer->parent.data = g_malloc0 (size);
147 723 writer->parent.size = size;
148 723 writer->alloc_size = size;
149 723 writer->fixed = fixed;
150 723 writer->owned = TRUE;
151 }
152
153 /**
154 * fpi_byte_writer_init_with_data:
155 * @writer: #FpiByteWriter instance
156 * @data: (array length=size) (transfer none): Memory area for writing
157 * @size: Size of @data in bytes
158 * @initialized: If %TRUE the complete data can be read from the beginning
159 *
160 * Initializes @writer with the given
161 * memory area. If @initialized is %TRUE it is possible to
162 * read @size bytes from the #FpiByteWriter from the beginning.
163 */
164 void
165 fpi_byte_writer_init_with_data (FpiByteWriter * writer, guint8 * data,
166 guint size, gboolean initialized)
167 {
168 g_return_if_fail (writer != NULL);
169
170 fpi_byte_writer_init (writer);
171
172 writer->parent.data = data;
173 writer->parent.size = (initialized) ? size : 0;
174 writer->alloc_size = size;
175 writer->fixed = TRUE;
176 writer->owned = FALSE;
177 }
178
179 /**
180 * fpi_byte_writer_reset:
181 * @writer: #FpiByteWriter instance
182 *
183 * Resets @writer and frees the data if it's
184 * owned by @writer.
185 */
186 void
187 2209 fpi_byte_writer_reset (FpiByteWriter * writer)
188 {
189
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 2209 times.
2209 g_return_if_fail (writer != NULL);
190
191
2/2
✓ Branch 4 → 5 taken 732 times.
✓ Branch 4 → 6 taken 1477 times.
2209 if (writer->owned)
192 732 g_free ((guint8 *) writer->parent.data);
193 2209 memset (writer, 0, sizeof (FpiByteWriter));
194 }
195
196 /**
197 * fpi_byte_writer_reset_and_get_data:
198 * @writer: #FpiByteWriter instance
199 *
200 * Resets @writer and returns the current data.
201 *
202 * Free-function: g_free
203 *
204 * Returns: (array) (transfer full): the current data. g_free() after
205 * usage.
206 */
207 guint8 *
208 732 fpi_byte_writer_reset_and_get_data (FpiByteWriter * writer)
209 {
210 732 guint8 *data;
211
212
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 732 times.
732 g_return_val_if_fail (writer != NULL, NULL);
213
214
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 732 times.
732 data = (guint8 *) g_steal_pointer (&writer->parent.data);
215
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 732 times.
732 if (!writer->owned)
216 data = g_memdup2 (data, writer->parent.size);
217 732 fpi_byte_writer_reset (writer);
218
219 732 return data;
220 }
221
222 /**
223 * fpi_byte_writer_reset_and_get_bytes:
224 * @writer: #FpiByteWriter instance
225 *
226 * Resets @writer and returns the current data as a #GBytes.
227 *
228 * Returns: (transfer full): the current data as a #GBytes.
229 */
230 GBytes *
231 fpi_byte_writer_reset_and_get_bytes (FpiByteWriter * writer)
232 {
233 GBytes *bytes;
234
235 g_return_val_if_fail (writer != NULL, NULL);
236
237 if (!writer->owned)
238 {
239 bytes = g_bytes_new (g_steal_pointer (&writer->parent.data),
240 writer->parent.size);
241 }
242 else
243 {
244 bytes = g_bytes_new_take ((gpointer) g_steal_pointer (&writer->parent.data),
245 writer->parent.size);
246 }
247
248 fpi_byte_writer_reset (writer);
249 return g_steal_pointer (&bytes);
250 }
251
252 /**
253 * fpi_byte_writer_free:
254 * @writer: (in) (transfer full): #FpiByteWriter instance
255 *
256 * Frees @writer and all memory allocated by it.
257 */
258 void
259 fpi_byte_writer_free (FpiByteWriter * writer)
260 {
261 g_return_if_fail (writer != NULL);
262
263 fpi_byte_writer_reset (writer);
264 g_slice_free (FpiByteWriter, writer);
265 }
266
267 /**
268 * fpi_byte_writer_free_and_get_data:
269 * @writer: (in) (transfer full): #FpiByteWriter instance
270 *
271 * Frees @writer and all memory allocated by it except
272 * the current data, which is returned.
273 *
274 * Free-function: g_free
275 *
276 * Returns: (transfer full): the current data. g_free() after usage.
277 */
278 guint8 *
279 fpi_byte_writer_free_and_get_data (FpiByteWriter * writer)
280 {
281 guint8 *data;
282
283 g_return_val_if_fail (writer != NULL, NULL);
284
285 data = fpi_byte_writer_reset_and_get_data (writer);
286 g_slice_free (FpiByteWriter, writer);
287
288 return data;
289 }
290
291 /**
292 * fpi_byte_writer_get_remaining:
293 * @writer: #FpiByteWriter instance
294 *
295 * Returns the remaining size of data that can still be written. If
296 * -1 is returned the remaining size is only limited by system resources.
297 *
298 * Returns: the remaining size of data that can still be written
299 */
300 guint
301 fpi_byte_writer_get_remaining (const FpiByteWriter * writer)
302 {
303 g_return_val_if_fail (writer != NULL, -1);
304
305 if (!writer->fixed)
306 return -1;
307 else
308 return writer->alloc_size - writer->parent.byte;
309 }
310
311 /**
312 * fpi_byte_writer_ensure_free_space:
313 * @writer: #FpiByteWriter instance
314 * @size: Number of bytes that should be available
315 *
316 * Checks if enough free space from the current write cursor is
317 * available and reallocates if necessary.
318 *
319 * Returns: %TRUE if at least @size bytes are still available
320 */
321 gboolean
322 fpi_byte_writer_ensure_free_space (FpiByteWriter * writer, guint size)
323 {
324 return fpi_byte_writer_ensure_free_space_inline (writer, size);
325 }
326
327
328 #define CREATE_WRITE_FUNC(bits,type,name,write_func) \
329 gboolean \
330 fpi_byte_writer_put_##name (FpiByteWriter *writer, type val) \
331 { \
332 return fpi_byte_writer_put_##name##_inline (writer, val); \
333 }
334
335 CREATE_WRITE_FUNC (8, guint8, uint8, GST_WRITE_UINT8);
336 CREATE_WRITE_FUNC (8, gint8, int8, GST_WRITE_UINT8);
337 CREATE_WRITE_FUNC (16, guint16, uint16_le, GST_WRITE_UINT16_LE);
338 CREATE_WRITE_FUNC (16, guint16, uint16_be, GST_WRITE_UINT16_BE);
339 CREATE_WRITE_FUNC (16, gint16, int16_le, GST_WRITE_UINT16_LE);
340 CREATE_WRITE_FUNC (16, gint16, int16_be, GST_WRITE_UINT16_BE);
341 CREATE_WRITE_FUNC (24, guint32, uint24_le, GST_WRITE_UINT24_LE);
342 CREATE_WRITE_FUNC (24, guint32, uint24_be, GST_WRITE_UINT24_BE);
343 CREATE_WRITE_FUNC (24, gint32, int24_le, GST_WRITE_UINT24_LE);
344 CREATE_WRITE_FUNC (24, gint32, int24_be, GST_WRITE_UINT24_BE);
345 CREATE_WRITE_FUNC (32, guint32, uint32_le, GST_WRITE_UINT32_LE);
346 CREATE_WRITE_FUNC (32, guint32, uint32_be, GST_WRITE_UINT32_BE);
347 CREATE_WRITE_FUNC (32, gint32, int32_le, GST_WRITE_UINT32_LE);
348 CREATE_WRITE_FUNC (32, gint32, int32_be, GST_WRITE_UINT32_BE);
349 CREATE_WRITE_FUNC (64, guint64, uint64_le, GST_WRITE_UINT64_LE);
350 CREATE_WRITE_FUNC (64, guint64, uint64_be, GST_WRITE_UINT64_BE);
351 CREATE_WRITE_FUNC (64, gint64, int64_le, GST_WRITE_UINT64_LE);
352 CREATE_WRITE_FUNC (64, gint64, int64_be, GST_WRITE_UINT64_BE);
353
354 CREATE_WRITE_FUNC (32, gfloat, float32_be, GST_WRITE_FLOAT_BE);
355 CREATE_WRITE_FUNC (32, gfloat, float32_le, GST_WRITE_FLOAT_LE);
356 CREATE_WRITE_FUNC (64, gdouble, float64_be, GST_WRITE_DOUBLE_BE);
357 CREATE_WRITE_FUNC (64, gdouble, float64_le, GST_WRITE_DOUBLE_LE);
358
359 gboolean
360 fpi_byte_writer_put_data (FpiByteWriter * writer, const guint8 * data,
361 guint size)
362 {
363 return fpi_byte_writer_put_data_inline (writer, data, size);
364 }
365
366 gboolean
367 fpi_byte_writer_fill (FpiByteWriter * writer, guint8 value, guint size)
368 {
369 return fpi_byte_writer_fill_inline (writer, value, size);
370 }
371
372 #define CREATE_WRITE_STRING_FUNC(bits,type) \
373 gboolean \
374 fpi_byte_writer_put_string_utf##bits (FpiByteWriter *writer, const type * data) \
375 { \
376 guint size = 0; \
377 \
378 g_return_val_if_fail (writer != NULL, FALSE); \
379 \
380 /* endianness does not matter if we are looking for a NUL terminator */ \
381 while (data[size] != 0) { \
382 /* have prevent overflow */ \
383 if (G_UNLIKELY (size == G_MAXUINT)) \
384 return FALSE; \
385 ++size; \
386 } \
387 ++size; \
388 \
389 if (G_UNLIKELY (!fpi_byte_writer_ensure_free_space_inline(writer, size * (bits / 8)))) \
390 return FALSE; \
391 \
392 fpi_byte_writer_put_data_inline (writer, (const guint8 *) data, size * (bits / 8)); \
393 \
394 return TRUE; \
395 }
396
397 CREATE_WRITE_STRING_FUNC (8, gchar);
398 CREATE_WRITE_STRING_FUNC (16, guint16);
399 CREATE_WRITE_STRING_FUNC (32, guint32);
400 /**
401 * fpi_byte_writer_put_uint8:
402 * @writer: #FpiByteWriter instance
403 * @val: Value to write
404 *
405 * Writes a unsigned 8 bit integer to @writer.
406 *
407 * Returns: %TRUE if the value could be written
408 */
409 /**
410 * fpi_byte_writer_put_uint16_be:
411 * @writer: #FpiByteWriter instance
412 * @val: Value to write
413 *
414 * Writes a unsigned big endian 16 bit integer to @writer.
415 *
416 * Returns: %TRUE if the value could be written
417 */
418 /**
419 * fpi_byte_writer_put_uint24_be:
420 * @writer: #FpiByteWriter instance
421 * @val: Value to write
422 *
423 * Writes a unsigned big endian 24 bit integer to @writer.
424 *
425 * Returns: %TRUE if the value could be written
426 */
427 /**
428 * fpi_byte_writer_put_uint32_be:
429 * @writer: #FpiByteWriter instance
430 * @val: Value to write
431 *
432 * Writes a unsigned big endian 32 bit integer to @writer.
433 *
434 * Returns: %TRUE if the value could be written
435 */
436 /**
437 * fpi_byte_writer_put_uint64_be:
438 * @writer: #FpiByteWriter instance
439 * @val: Value to write
440 *
441 * Writes a unsigned big endian 64 bit integer to @writer.
442 *
443 * Returns: %TRUE if the value could be written
444 */
445 /**
446 * fpi_byte_writer_put_uint16_le:
447 * @writer: #FpiByteWriter instance
448 * @val: Value to write
449 *
450 * Writes a unsigned little endian 16 bit integer to @writer.
451 *
452 * Returns: %TRUE if the value could be written
453 */
454 /**
455 * fpi_byte_writer_put_uint24_le:
456 * @writer: #FpiByteWriter instance
457 * @val: Value to write
458 *
459 * Writes a unsigned little endian 24 bit integer to @writer.
460 *
461 * Returns: %TRUE if the value could be written
462 */
463 /**
464 * fpi_byte_writer_put_uint32_le:
465 * @writer: #FpiByteWriter instance
466 * @val: Value to write
467 *
468 * Writes a unsigned little endian 32 bit integer to @writer.
469 *
470 * Returns: %TRUE if the value could be written
471 */
472 /**
473 * fpi_byte_writer_put_uint64_le:
474 * @writer: #FpiByteWriter instance
475 * @val: Value to write
476 *
477 * Writes a unsigned little endian 64 bit integer to @writer.
478 *
479 * Returns: %TRUE if the value could be written
480 */
481 /**
482 * fpi_byte_writer_put_int8:
483 * @writer: #FpiByteWriter instance
484 * @val: Value to write
485 *
486 * Writes a signed 8 bit integer to @writer.
487 *
488 * Returns: %TRUE if the value could be written
489 */
490 /**
491 * fpi_byte_writer_put_int16_be:
492 * @writer: #FpiByteWriter instance
493 * @val: Value to write
494 *
495 * Writes a signed big endian 16 bit integer to @writer.
496 *
497 * Returns: %TRUE if the value could be written
498 */
499 /**
500 * fpi_byte_writer_put_int24_be:
501 * @writer: #FpiByteWriter instance
502 * @val: Value to write
503 *
504 * Writes a signed big endian 24 bit integer to @writer.
505 *
506 * Returns: %TRUE if the value could be written
507 */
508 /**
509 * fpi_byte_writer_put_int32_be:
510 * @writer: #FpiByteWriter instance
511 * @val: Value to write
512 *
513 * Writes a signed big endian 32 bit integer to @writer.
514 *
515 * Returns: %TRUE if the value could be written
516 */
517 /**
518 * fpi_byte_writer_put_int64_be:
519 * @writer: #FpiByteWriter instance
520 * @val: Value to write
521 *
522 * Writes a signed big endian 64 bit integer to @writer.
523 *
524 * Returns: %TRUE if the value could be written
525 */
526 /**
527 * fpi_byte_writer_put_int16_le:
528 * @writer: #FpiByteWriter instance
529 * @val: Value to write
530 *
531 * Writes a signed little endian 16 bit integer to @writer.
532 *
533 * Returns: %TRUE if the value could be written
534 */
535 /**
536 * fpi_byte_writer_put_int24_le:
537 * @writer: #FpiByteWriter instance
538 * @val: Value to write
539 *
540 * Writes a signed little endian 24 bit integer to @writer.
541 *
542 * Returns: %TRUE if the value could be written
543 */
544 /**
545 * fpi_byte_writer_put_int32_le:
546 * @writer: #FpiByteWriter instance
547 * @val: Value to write
548 *
549 * Writes a signed little endian 32 bit integer to @writer.
550 *
551 * Returns: %TRUE if the value could be written
552 */
553 /**
554 * fpi_byte_writer_put_int64_le:
555 * @writer: #FpiByteWriter instance
556 * @val: Value to write
557 *
558 * Writes a signed little endian 64 bit integer to @writer.
559 *
560 * Returns: %TRUE if the value could be written
561 */
562 /**
563 * fpi_byte_writer_put_float32_be:
564 * @writer: #FpiByteWriter instance
565 * @val: Value to write
566 *
567 * Writes a big endian 32 bit float to @writer.
568 *
569 * Returns: %TRUE if the value could be written
570 */
571 /**
572 * fpi_byte_writer_put_float64_be:
573 * @writer: #FpiByteWriter instance
574 * @val: Value to write
575 *
576 * Writes a big endian 64 bit float to @writer.
577 *
578 * Returns: %TRUE if the value could be written
579 */
580 /**
581 * fpi_byte_writer_put_float32_le:
582 * @writer: #FpiByteWriter instance
583 * @val: Value to write
584 *
585 * Writes a little endian 32 bit float to @writer.
586 *
587 * Returns: %TRUE if the value could be written
588 */
589 /**
590 * fpi_byte_writer_put_float64_le:
591 * @writer: #FpiByteWriter instance
592 * @val: Value to write
593 *
594 * Writes a little endian 64 bit float to @writer.
595 *
596 * Returns: %TRUE if the value could be written
597 */
598 /**
599 * fpi_byte_writer_put_string_utf8:
600 * @writer: #FpiByteWriter instance
601 * @data: (transfer none): UTF8 string to write
602 *
603 * Writes a NUL-terminated UTF8 string to @writer (including the terminator).
604 *
605 * Returns: %TRUE if the value could be written
606 */
607 /**
608 * fpi_byte_writer_put_string_utf16:
609 * @writer: #FpiByteWriter instance
610 * @data: (transfer none) (array zero-terminated=1): UTF16 string to write
611 *
612 * Writes a NUL-terminated UTF16 string to @writer (including the terminator).
613 *
614 * Returns: %TRUE if the value could be written
615 */
616 /**
617 * fpi_byte_writer_put_string_utf32:
618 * @writer: #FpiByteWriter instance
619 * @data: (transfer none) (array zero-terminated=1): UTF32 string to write
620 *
621 * Writes a NUL-terminated UTF32 string to @writer (including the terminator).
622 *
623 * Returns: %TRUE if the value could be written
624 */
625 /**
626 * fpi_byte_writer_put_data:
627 * @writer: #FpiByteWriter instance
628 * @data: (transfer none) (array length=size): Data to write
629 * @size: Size of @data in bytes
630 *
631 * Writes @size bytes of @data to @writer.
632 *
633 * Returns: %TRUE if the value could be written
634 */
635 /**
636 * fpi_byte_writer_put_bytes:
637 * @writer: #FpiByteWriter instance
638 * @bytes: (transfer none): Data to write
639 *
640 * Writes the contents of @bytes to @writer.
641 *
642 * Returns: %TRUE if the value could be written
643 */
644 /**
645 * fpi_byte_writer_fill:
646 * @writer: #FpiByteWriter instance
647 * @value: Value to be written
648 * @size: Number of bytes to be written
649 *
650 * Writes @size bytes containing @value to @writer.
651 *
652 * Returns: %TRUE if the value could be written
653 */
654
655