GCC Code Coverage Report


Directory: ./
File: libfprint/fpi-byte-writer.c
Date: 2024-05-04 14:54:39
Exec Total Coverage
Lines: 24 98 24.5%
Functions: 4 39 10.3%
Branches: 8 52 15.4%

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 283 fpi_byte_writer_init (FpiByteWriter * writer)
122 {
123
1/2
✓ Branch 0 taken 283 times.
✗ Branch 1 not taken.
283 g_return_if_fail (writer != NULL);
124
125 283 memset (writer, 0, sizeof (FpiByteWriter));
126
127 283 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 279 fpi_byte_writer_init_with_size (FpiByteWriter * writer, guint size,
140 gboolean fixed)
141 {
142
1/2
✓ Branch 0 taken 279 times.
✗ Branch 1 not taken.
279 g_return_if_fail (writer != NULL);
143
144 279 fpi_byte_writer_init (writer);
145
146 279 writer->parent.data = g_malloc0 (size);
147 279 writer->parent.size = size;
148 279 writer->alloc_size = size;
149 279 writer->fixed = fixed;
150 279 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 844 fpi_byte_writer_reset (FpiByteWriter * writer)
188 {
189
1/2
✓ Branch 0 taken 844 times.
✗ Branch 1 not taken.
844 g_return_if_fail (writer != NULL);
190
191
2/2
✓ Branch 0 taken 283 times.
✓ Branch 1 taken 561 times.
844 if (writer->owned)
192 283 g_free ((guint8 *) writer->parent.data);
193 844 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 283 fpi_byte_writer_reset_and_get_data (FpiByteWriter * writer)
209 {
210 283 guint8 *data;
211
212
1/2
✓ Branch 0 taken 283 times.
✗ Branch 1 not taken.
283 g_return_val_if_fail (writer != NULL, NULL);
213
214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 283 times.
283 data = (guint8 *) g_steal_pointer (&writer->parent.data);
215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 283 times.
283 if (!writer->owned)
216 data = g_memdup2 (data, writer->parent.size);
217 283 fpi_byte_writer_reset (writer);
218
219 283 return data;
220 }
221
222 /**
223 * fpi_byte_writer_free:
224 * @writer: (in) (transfer full): #FpiByteWriter instance
225 *
226 * Frees @writer and all memory allocated by it.
227 */
228 void
229 fpi_byte_writer_free (FpiByteWriter * writer)
230 {
231 g_return_if_fail (writer != NULL);
232
233 fpi_byte_writer_reset (writer);
234 g_slice_free (FpiByteWriter, writer);
235 }
236
237 /**
238 * fpi_byte_writer_free_and_get_data:
239 * @writer: (in) (transfer full): #FpiByteWriter instance
240 *
241 * Frees @writer and all memory allocated by it except
242 * the current data, which is returned.
243 *
244 * Free-function: g_free
245 *
246 * Returns: (transfer full): the current data. g_free() after usage.
247 */
248 guint8 *
249 fpi_byte_writer_free_and_get_data (FpiByteWriter * writer)
250 {
251 guint8 *data;
252
253 g_return_val_if_fail (writer != NULL, NULL);
254
255 data = fpi_byte_writer_reset_and_get_data (writer);
256 g_slice_free (FpiByteWriter, writer);
257
258 return data;
259 }
260
261 /**
262 * fpi_byte_writer_get_remaining:
263 * @writer: #FpiByteWriter instance
264 *
265 * Returns the remaining size of data that can still be written. If
266 * -1 is returned the remaining size is only limited by system resources.
267 *
268 * Returns: the remaining size of data that can still be written
269 */
270 guint
271 fpi_byte_writer_get_remaining (const FpiByteWriter * writer)
272 {
273 g_return_val_if_fail (writer != NULL, -1);
274
275 if (!writer->fixed)
276 return -1;
277 else
278 return writer->alloc_size - writer->parent.byte;
279 }
280
281 /**
282 * fpi_byte_writer_ensure_free_space:
283 * @writer: #FpiByteWriter instance
284 * @size: Number of bytes that should be available
285 *
286 * Checks if enough free space from the current write cursor is
287 * available and reallocates if necessary.
288 *
289 * Returns: %TRUE if at least @size bytes are still available
290 */
291 gboolean
292 fpi_byte_writer_ensure_free_space (FpiByteWriter * writer, guint size)
293 {
294 return fpi_byte_writer_ensure_free_space_inline (writer, size);
295 }
296
297
298 #define CREATE_WRITE_FUNC(bits,type,name,write_func) \
299 gboolean \
300 fpi_byte_writer_put_##name (FpiByteWriter *writer, type val) \
301 { \
302 return fpi_byte_writer_put_##name##_inline (writer, val); \
303 }
304
305 CREATE_WRITE_FUNC (8, guint8, uint8, GST_WRITE_UINT8);
306 CREATE_WRITE_FUNC (8, gint8, int8, GST_WRITE_UINT8);
307 CREATE_WRITE_FUNC (16, guint16, uint16_le, GST_WRITE_UINT16_LE);
308 CREATE_WRITE_FUNC (16, guint16, uint16_be, GST_WRITE_UINT16_BE);
309 CREATE_WRITE_FUNC (16, gint16, int16_le, GST_WRITE_UINT16_LE);
310 CREATE_WRITE_FUNC (16, gint16, int16_be, GST_WRITE_UINT16_BE);
311 CREATE_WRITE_FUNC (24, guint32, uint24_le, GST_WRITE_UINT24_LE);
312 CREATE_WRITE_FUNC (24, guint32, uint24_be, GST_WRITE_UINT24_BE);
313 CREATE_WRITE_FUNC (24, gint32, int24_le, GST_WRITE_UINT24_LE);
314 CREATE_WRITE_FUNC (24, gint32, int24_be, GST_WRITE_UINT24_BE);
315 CREATE_WRITE_FUNC (32, guint32, uint32_le, GST_WRITE_UINT32_LE);
316 CREATE_WRITE_FUNC (32, guint32, uint32_be, GST_WRITE_UINT32_BE);
317 CREATE_WRITE_FUNC (32, gint32, int32_le, GST_WRITE_UINT32_LE);
318 CREATE_WRITE_FUNC (32, gint32, int32_be, GST_WRITE_UINT32_BE);
319 CREATE_WRITE_FUNC (64, guint64, uint64_le, GST_WRITE_UINT64_LE);
320 CREATE_WRITE_FUNC (64, guint64, uint64_be, GST_WRITE_UINT64_BE);
321 CREATE_WRITE_FUNC (64, gint64, int64_le, GST_WRITE_UINT64_LE);
322 CREATE_WRITE_FUNC (64, gint64, int64_be, GST_WRITE_UINT64_BE);
323
324 CREATE_WRITE_FUNC (32, gfloat, float32_be, GST_WRITE_FLOAT_BE);
325 CREATE_WRITE_FUNC (32, gfloat, float32_le, GST_WRITE_FLOAT_LE);
326 CREATE_WRITE_FUNC (64, gdouble, float64_be, GST_WRITE_DOUBLE_BE);
327 CREATE_WRITE_FUNC (64, gdouble, float64_le, GST_WRITE_DOUBLE_LE);
328
329 gboolean
330 fpi_byte_writer_put_data (FpiByteWriter * writer, const guint8 * data,
331 guint size)
332 {
333 return fpi_byte_writer_put_data_inline (writer, data, size);
334 }
335
336 gboolean
337 fpi_byte_writer_fill (FpiByteWriter * writer, guint8 value, guint size)
338 {
339 return fpi_byte_writer_fill_inline (writer, value, size);
340 }
341
342 #define CREATE_WRITE_STRING_FUNC(bits,type) \
343 gboolean \
344 fpi_byte_writer_put_string_utf##bits (FpiByteWriter *writer, const type * data) \
345 { \
346 guint size = 0; \
347 \
348 g_return_val_if_fail (writer != NULL, FALSE); \
349 \
350 /* endianness does not matter if we are looking for a NUL terminator */ \
351 while (data[size] != 0) { \
352 /* have prevent overflow */ \
353 if (G_UNLIKELY (size == G_MAXUINT)) \
354 return FALSE; \
355 ++size; \
356 } \
357 ++size; \
358 \
359 if (G_UNLIKELY (!fpi_byte_writer_ensure_free_space_inline(writer, size * (bits / 8)))) \
360 return FALSE; \
361 \
362 fpi_byte_writer_put_data_inline (writer, (const guint8 *) data, size * (bits / 8)); \
363 \
364 return TRUE; \
365 }
366
367 CREATE_WRITE_STRING_FUNC (8, gchar);
368 CREATE_WRITE_STRING_FUNC (16, guint16);
369 CREATE_WRITE_STRING_FUNC (32, guint32);
370 /**
371 * fpi_byte_writer_put_uint8:
372 * @writer: #FpiByteWriter instance
373 * @val: Value to write
374 *
375 * Writes a unsigned 8 bit integer to @writer.
376 *
377 * Returns: %TRUE if the value could be written
378 */
379 /**
380 * fpi_byte_writer_put_uint16_be:
381 * @writer: #FpiByteWriter instance
382 * @val: Value to write
383 *
384 * Writes a unsigned big endian 16 bit integer to @writer.
385 *
386 * Returns: %TRUE if the value could be written
387 */
388 /**
389 * fpi_byte_writer_put_uint24_be:
390 * @writer: #FpiByteWriter instance
391 * @val: Value to write
392 *
393 * Writes a unsigned big endian 24 bit integer to @writer.
394 *
395 * Returns: %TRUE if the value could be written
396 */
397 /**
398 * fpi_byte_writer_put_uint32_be:
399 * @writer: #FpiByteWriter instance
400 * @val: Value to write
401 *
402 * Writes a unsigned big endian 32 bit integer to @writer.
403 *
404 * Returns: %TRUE if the value could be written
405 */
406 /**
407 * fpi_byte_writer_put_uint64_be:
408 * @writer: #FpiByteWriter instance
409 * @val: Value to write
410 *
411 * Writes a unsigned big endian 64 bit integer to @writer.
412 *
413 * Returns: %TRUE if the value could be written
414 */
415 /**
416 * fpi_byte_writer_put_uint16_le:
417 * @writer: #FpiByteWriter instance
418 * @val: Value to write
419 *
420 * Writes a unsigned little endian 16 bit integer to @writer.
421 *
422 * Returns: %TRUE if the value could be written
423 */
424 /**
425 * fpi_byte_writer_put_uint24_le:
426 * @writer: #FpiByteWriter instance
427 * @val: Value to write
428 *
429 * Writes a unsigned little endian 24 bit integer to @writer.
430 *
431 * Returns: %TRUE if the value could be written
432 */
433 /**
434 * fpi_byte_writer_put_uint32_le:
435 * @writer: #FpiByteWriter instance
436 * @val: Value to write
437 *
438 * Writes a unsigned little endian 32 bit integer to @writer.
439 *
440 * Returns: %TRUE if the value could be written
441 */
442 /**
443 * fpi_byte_writer_put_uint64_le:
444 * @writer: #FpiByteWriter instance
445 * @val: Value to write
446 *
447 * Writes a unsigned little endian 64 bit integer to @writer.
448 *
449 * Returns: %TRUE if the value could be written
450 */
451 /**
452 * fpi_byte_writer_put_int8:
453 * @writer: #FpiByteWriter instance
454 * @val: Value to write
455 *
456 * Writes a signed 8 bit integer to @writer.
457 *
458 * Returns: %TRUE if the value could be written
459 */
460 /**
461 * fpi_byte_writer_put_int16_be:
462 * @writer: #FpiByteWriter instance
463 * @val: Value to write
464 *
465 * Writes a signed big endian 16 bit integer to @writer.
466 *
467 * Returns: %TRUE if the value could be written
468 */
469 /**
470 * fpi_byte_writer_put_int24_be:
471 * @writer: #FpiByteWriter instance
472 * @val: Value to write
473 *
474 * Writes a signed big endian 24 bit integer to @writer.
475 *
476 * Returns: %TRUE if the value could be written
477 */
478 /**
479 * fpi_byte_writer_put_int32_be:
480 * @writer: #FpiByteWriter instance
481 * @val: Value to write
482 *
483 * Writes a signed big endian 32 bit integer to @writer.
484 *
485 * Returns: %TRUE if the value could be written
486 */
487 /**
488 * fpi_byte_writer_put_int64_be:
489 * @writer: #FpiByteWriter instance
490 * @val: Value to write
491 *
492 * Writes a signed big endian 64 bit integer to @writer.
493 *
494 * Returns: %TRUE if the value could be written
495 */
496 /**
497 * fpi_byte_writer_put_int16_le:
498 * @writer: #FpiByteWriter instance
499 * @val: Value to write
500 *
501 * Writes a signed little endian 16 bit integer to @writer.
502 *
503 * Returns: %TRUE if the value could be written
504 */
505 /**
506 * fpi_byte_writer_put_int24_le:
507 * @writer: #FpiByteWriter instance
508 * @val: Value to write
509 *
510 * Writes a signed little endian 24 bit integer to @writer.
511 *
512 * Returns: %TRUE if the value could be written
513 */
514 /**
515 * fpi_byte_writer_put_int32_le:
516 * @writer: #FpiByteWriter instance
517 * @val: Value to write
518 *
519 * Writes a signed little endian 32 bit integer to @writer.
520 *
521 * Returns: %TRUE if the value could be written
522 */
523 /**
524 * fpi_byte_writer_put_int64_le:
525 * @writer: #FpiByteWriter instance
526 * @val: Value to write
527 *
528 * Writes a signed little endian 64 bit integer to @writer.
529 *
530 * Returns: %TRUE if the value could be written
531 */
532 /**
533 * fpi_byte_writer_put_float32_be:
534 * @writer: #FpiByteWriter instance
535 * @val: Value to write
536 *
537 * Writes a big endian 32 bit float to @writer.
538 *
539 * Returns: %TRUE if the value could be written
540 */
541 /**
542 * fpi_byte_writer_put_float64_be:
543 * @writer: #FpiByteWriter instance
544 * @val: Value to write
545 *
546 * Writes a big endian 64 bit float to @writer.
547 *
548 * Returns: %TRUE if the value could be written
549 */
550 /**
551 * fpi_byte_writer_put_float32_le:
552 * @writer: #FpiByteWriter instance
553 * @val: Value to write
554 *
555 * Writes a little endian 32 bit float to @writer.
556 *
557 * Returns: %TRUE if the value could be written
558 */
559 /**
560 * fpi_byte_writer_put_float64_le:
561 * @writer: #FpiByteWriter instance
562 * @val: Value to write
563 *
564 * Writes a little endian 64 bit float to @writer.
565 *
566 * Returns: %TRUE if the value could be written
567 */
568 /**
569 * fpi_byte_writer_put_string_utf8:
570 * @writer: #FpiByteWriter instance
571 * @data: (transfer none): UTF8 string to write
572 *
573 * Writes a NUL-terminated UTF8 string to @writer (including the terminator).
574 *
575 * Returns: %TRUE if the value could be written
576 */
577 /**
578 * fpi_byte_writer_put_string_utf16:
579 * @writer: #FpiByteWriter instance
580 * @data: (transfer none) (array zero-terminated=1): UTF16 string to write
581 *
582 * Writes a NUL-terminated UTF16 string to @writer (including the terminator).
583 *
584 * Returns: %TRUE if the value could be written
585 */
586 /**
587 * fpi_byte_writer_put_string_utf32:
588 * @writer: #FpiByteWriter instance
589 * @data: (transfer none) (array zero-terminated=1): UTF32 string to write
590 *
591 * Writes a NUL-terminated UTF32 string to @writer (including the terminator).
592 *
593 * Returns: %TRUE if the value could be written
594 */
595 /**
596 * fpi_byte_writer_put_data:
597 * @writer: #FpiByteWriter instance
598 * @data: (transfer none) (array length=size): Data to write
599 * @size: Size of @data in bytes
600 *
601 * Writes @size bytes of @data to @writer.
602 *
603 * Returns: %TRUE if the value could be written
604 */
605 /**
606 * fpi_byte_writer_fill:
607 * @writer: #FpiByteWriter instance
608 * @value: Value to be written
609 * @size: Number of bytes to be written
610 *
611 * Writes @size bytes containing @value to @writer.
612 *
613 * Returns: %TRUE if the value could be written
614 */
615
616