1 /* GStreamer byte writer
3 * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
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.
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.
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.
25 #define GST_BYTE_WRITER_DISABLE_INLINES
26 #include "gstbytewriter.h"
29 * SECTION:gstbytewriter
30 * @title: GstByteWriter
31 * @short_description: Writes different integer, string and floating point
32 * types to a memory buffer and allows reading
34 * #GstByteWriter 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.
43 * gst_byte_writer_new: (skip)
45 * Creates a new, empty #GstByteWriter instance
47 * Free-function: gst_byte_writer_free
49 * Returns: (transfer full): a new, empty #GstByteWriter instance
52 gst_byte_writer_new (void)
54 GstByteWriter *ret = g_slice_new0 (GstByteWriter);
61 * gst_byte_writer_new_with_size: (skip)
62 * @size: Initial size of data
63 * @fixed: If %TRUE the data can't be reallocated
65 * Creates a new #GstByteWriter instance with the given
68 * Free-function: gst_byte_writer_free
70 * Returns: (transfer full): a new #GstByteWriter instance
73 gst_byte_writer_new_with_size (guint size, gboolean fixed)
75 GstByteWriter *ret = gst_byte_writer_new ();
77 ret->alloc_size = size;
78 ret->parent.data = g_malloc (ret->alloc_size);
86 * gst_byte_writer_new_with_data: (skip)
87 * @data: Memory area for writing
88 * @size: Size of @data in bytes
89 * @initialized: If %TRUE the complete data can be read from the beginning
91 * Creates a new #GstByteWriter instance with the given
92 * memory area. If @initialized is %TRUE it is possible to
93 * read @size bytes from the #GstByteWriter from the beginning.
95 * Free-function: gst_byte_writer_free
97 * Returns: (transfer full): a new #GstByteWriter instance
100 gst_byte_writer_new_with_data (guint8 * data, guint size, gboolean initialized)
102 GstByteWriter *ret = gst_byte_writer_new ();
104 ret->parent.data = data;
105 ret->parent.size = (initialized) ? size : 0;
106 ret->alloc_size = size;
114 * gst_byte_writer_init:
115 * @writer: #GstByteWriter instance
117 * Initializes @writer to an empty instance
120 gst_byte_writer_init (GstByteWriter * writer)
122 g_return_if_fail (writer != NULL);
124 memset (writer, 0, sizeof (GstByteWriter));
126 writer->owned = TRUE;
130 * gst_byte_writer_init_with_size:
131 * @writer: #GstByteWriter instance
132 * @size: Initial size of data
133 * @fixed: If %TRUE the data can't be reallocated
135 * Initializes @writer with the given initial data size.
138 gst_byte_writer_init_with_size (GstByteWriter * writer, guint size,
141 g_return_if_fail (writer != NULL);
143 gst_byte_writer_init (writer);
145 writer->parent.data = g_malloc (size);
146 writer->alloc_size = size;
147 writer->fixed = fixed;
148 writer->owned = TRUE;
152 * gst_byte_writer_init_with_data:
153 * @writer: #GstByteWriter instance
154 * @data: (array length=size) (transfer none): Memory area for writing
155 * @size: Size of @data in bytes
156 * @initialized: If %TRUE the complete data can be read from the beginning
158 * Initializes @writer with the given
159 * memory area. If @initialized is %TRUE it is possible to
160 * read @size bytes from the #GstByteWriter from the beginning.
163 gst_byte_writer_init_with_data (GstByteWriter * writer, guint8 * data,
164 guint size, gboolean initialized)
166 g_return_if_fail (writer != NULL);
168 gst_byte_writer_init (writer);
170 writer->parent.data = data;
171 writer->parent.size = (initialized) ? size : 0;
172 writer->alloc_size = size;
173 writer->fixed = TRUE;
174 writer->owned = FALSE;
178 * gst_byte_writer_reset:
179 * @writer: #GstByteWriter instance
181 * Resets @writer and frees the data if it's
185 gst_byte_writer_reset (GstByteWriter * writer)
187 g_return_if_fail (writer != NULL);
190 g_free ((guint8 *) writer->parent.data);
191 memset (writer, 0, sizeof (GstByteWriter));
195 * gst_byte_writer_reset_and_get_data:
196 * @writer: #GstByteWriter instance
198 * Resets @writer and returns the current data.
200 * Free-function: g_free
202 * Returns: (array) (transfer full): the current data. g_free() after
206 gst_byte_writer_reset_and_get_data (GstByteWriter * writer)
210 g_return_val_if_fail (writer != NULL, NULL);
212 data = (guint8 *) writer->parent.data;
214 data = g_memdup (data, writer->parent.size);
215 writer->parent.data = NULL;
216 gst_byte_writer_reset (writer);
222 * gst_byte_writer_reset_and_get_buffer:
223 * @writer: #GstByteWriter instance
225 * Resets @writer and returns the current data as buffer.
227 * Free-function: gst_buffer_unref
229 * Returns: (transfer full): the current data as buffer. gst_buffer_unref()
233 gst_byte_writer_reset_and_get_buffer (GstByteWriter * writer)
239 g_return_val_if_fail (writer != NULL, NULL);
241 size = writer->parent.size;
242 data = gst_byte_writer_reset_and_get_data (writer);
244 buffer = gst_buffer_new ();
246 gst_buffer_append_memory (buffer,
247 gst_memory_new_wrapped (0, data, size, 0, size, data, g_free));
254 * gst_byte_writer_free:
255 * @writer: (in) (transfer full): #GstByteWriter instance
257 * Frees @writer and all memory allocated by it.
260 gst_byte_writer_free (GstByteWriter * writer)
262 g_return_if_fail (writer != NULL);
264 gst_byte_writer_reset (writer);
265 g_slice_free (GstByteWriter, writer);
269 * gst_byte_writer_free_and_get_data:
270 * @writer: (in) (transfer full): #GstByteWriter instance
272 * Frees @writer and all memory allocated by it except
273 * the current data, which is returned.
275 * Free-function: g_free
277 * Returns: (transfer full): the current data. g_free() after usage.
280 gst_byte_writer_free_and_get_data (GstByteWriter * writer)
284 g_return_val_if_fail (writer != NULL, NULL);
286 data = gst_byte_writer_reset_and_get_data (writer);
287 g_slice_free (GstByteWriter, writer);
293 * gst_byte_writer_free_and_get_buffer:
294 * @writer: (in) (transfer full): #GstByteWriter instance
296 * Frees @writer and all memory allocated by it except
297 * the current data, which is returned as #GstBuffer.
299 * Free-function: gst_buffer_unref
301 * Returns: (transfer full): the current data as buffer. gst_buffer_unref()
305 gst_byte_writer_free_and_get_buffer (GstByteWriter * writer)
309 g_return_val_if_fail (writer != NULL, NULL);
311 buffer = gst_byte_writer_reset_and_get_buffer (writer);
312 g_slice_free (GstByteWriter, writer);
318 * gst_byte_writer_get_remaining:
319 * @writer: #GstByteWriter instance
321 * Returns the remaining size of data that can still be written. If
322 * -1 is returned the remaining size is only limited by system resources.
324 * Returns: the remaining size of data that can still be written
327 gst_byte_writer_get_remaining (const GstByteWriter * writer)
329 g_return_val_if_fail (writer != NULL, -1);
334 return writer->alloc_size - writer->parent.byte;
338 * gst_byte_writer_ensure_free_space:
339 * @writer: #GstByteWriter instance
340 * @size: Number of bytes that should be available
342 * Checks if enough free space from the current write cursor is
343 * available and reallocates if necessary.
345 * Returns: %TRUE if at least @size bytes are still available
348 gst_byte_writer_ensure_free_space (GstByteWriter * writer, guint size)
350 return _gst_byte_writer_ensure_free_space_inline (writer, size);
354 #define CREATE_WRITE_FUNC(bits,type,name,write_func) \
356 gst_byte_writer_put_##name (GstByteWriter *writer, type val) \
358 return _gst_byte_writer_put_##name##_inline (writer, val); \
361 CREATE_WRITE_FUNC (8, guint8, uint8, GST_WRITE_UINT8);
362 CREATE_WRITE_FUNC (8, gint8, int8, GST_WRITE_UINT8);
363 CREATE_WRITE_FUNC (16, guint16, uint16_le, GST_WRITE_UINT16_LE);
364 CREATE_WRITE_FUNC (16, guint16, uint16_be, GST_WRITE_UINT16_BE);
365 CREATE_WRITE_FUNC (16, gint16, int16_le, GST_WRITE_UINT16_LE);
366 CREATE_WRITE_FUNC (16, gint16, int16_be, GST_WRITE_UINT16_BE);
367 CREATE_WRITE_FUNC (24, guint32, uint24_le, GST_WRITE_UINT24_LE);
368 CREATE_WRITE_FUNC (24, guint32, uint24_be, GST_WRITE_UINT24_BE);
369 CREATE_WRITE_FUNC (24, gint32, int24_le, GST_WRITE_UINT24_LE);
370 CREATE_WRITE_FUNC (24, gint32, int24_be, GST_WRITE_UINT24_BE);
371 CREATE_WRITE_FUNC (32, guint32, uint32_le, GST_WRITE_UINT32_LE);
372 CREATE_WRITE_FUNC (32, guint32, uint32_be, GST_WRITE_UINT32_BE);
373 CREATE_WRITE_FUNC (32, gint32, int32_le, GST_WRITE_UINT32_LE);
374 CREATE_WRITE_FUNC (32, gint32, int32_be, GST_WRITE_UINT32_BE);
375 CREATE_WRITE_FUNC (64, guint64, uint64_le, GST_WRITE_UINT64_LE);
376 CREATE_WRITE_FUNC (64, guint64, uint64_be, GST_WRITE_UINT64_BE);
377 CREATE_WRITE_FUNC (64, gint64, int64_le, GST_WRITE_UINT64_LE);
378 CREATE_WRITE_FUNC (64, gint64, int64_be, GST_WRITE_UINT64_BE);
380 CREATE_WRITE_FUNC (32, gfloat, float32_be, GST_WRITE_FLOAT_BE);
381 CREATE_WRITE_FUNC (32, gfloat, float32_le, GST_WRITE_FLOAT_LE);
382 CREATE_WRITE_FUNC (64, gdouble, float64_be, GST_WRITE_DOUBLE_BE);
383 CREATE_WRITE_FUNC (64, gdouble, float64_le, GST_WRITE_DOUBLE_LE);
386 gst_byte_writer_put_data (GstByteWriter * writer, const guint8 * data,
389 return _gst_byte_writer_put_data_inline (writer, data, size);
393 gst_byte_writer_fill (GstByteWriter * writer, guint8 value, guint size)
395 return _gst_byte_writer_fill_inline (writer, value, size);
398 #define CREATE_WRITE_STRING_FUNC(bits,type) \
400 gst_byte_writer_put_string_utf##bits (GstByteWriter *writer, const type * data) \
404 g_return_val_if_fail (writer != NULL, FALSE); \
406 /* endianness does not matter if we are looking for a NUL terminator */ \
407 while (data[size] != 0) { \
408 /* have prevent overflow */ \
409 if (G_UNLIKELY (size == G_MAXUINT)) \
415 if (G_UNLIKELY (!_gst_byte_writer_ensure_free_space_inline(writer, size * (bits / 8)))) \
418 _gst_byte_writer_put_data_inline (writer, (const guint8 *) data, size * (bits / 8)); \
423 CREATE_WRITE_STRING_FUNC (8, gchar);
424 CREATE_WRITE_STRING_FUNC (16, guint16);
425 CREATE_WRITE_STRING_FUNC (32, guint32);
427 * gst_byte_writer_put_uint8:
428 * @writer: #GstByteWriter instance
429 * @val: Value to write
431 * Writes a unsigned 8 bit integer to @writer.
433 * Returns: %TRUE if the value could be written
436 * gst_byte_writer_put_uint16_be:
437 * @writer: #GstByteWriter instance
438 * @val: Value to write
440 * Writes a unsigned big endian 16 bit integer to @writer.
442 * Returns: %TRUE if the value could be written
445 * gst_byte_writer_put_uint24_be:
446 * @writer: #GstByteWriter instance
447 * @val: Value to write
449 * Writes a unsigned big endian 24 bit integer to @writer.
451 * Returns: %TRUE if the value could be written
454 * gst_byte_writer_put_uint32_be:
455 * @writer: #GstByteWriter instance
456 * @val: Value to write
458 * Writes a unsigned big endian 32 bit integer to @writer.
460 * Returns: %TRUE if the value could be written
463 * gst_byte_writer_put_uint64_be:
464 * @writer: #GstByteWriter instance
465 * @val: Value to write
467 * Writes a unsigned big endian 64 bit integer to @writer.
469 * Returns: %TRUE if the value could be written
472 * gst_byte_writer_put_uint16_le:
473 * @writer: #GstByteWriter instance
474 * @val: Value to write
476 * Writes a unsigned little endian 16 bit integer to @writer.
478 * Returns: %TRUE if the value could be written
481 * gst_byte_writer_put_uint24_le:
482 * @writer: #GstByteWriter instance
483 * @val: Value to write
485 * Writes a unsigned little endian 24 bit integer to @writer.
487 * Returns: %TRUE if the value could be written
490 * gst_byte_writer_put_uint32_le:
491 * @writer: #GstByteWriter instance
492 * @val: Value to write
494 * Writes a unsigned little endian 32 bit integer to @writer.
496 * Returns: %TRUE if the value could be written
499 * gst_byte_writer_put_uint64_le:
500 * @writer: #GstByteWriter instance
501 * @val: Value to write
503 * Writes a unsigned little endian 64 bit integer to @writer.
505 * Returns: %TRUE if the value could be written
508 * gst_byte_writer_put_int8:
509 * @writer: #GstByteWriter instance
510 * @val: Value to write
512 * Writes a signed 8 bit integer to @writer.
514 * Returns: %TRUE if the value could be written
517 * gst_byte_writer_put_int16_be:
518 * @writer: #GstByteWriter instance
519 * @val: Value to write
521 * Writes a signed big endian 16 bit integer to @writer.
523 * Returns: %TRUE if the value could be written
526 * gst_byte_writer_put_int24_be:
527 * @writer: #GstByteWriter instance
528 * @val: Value to write
530 * Writes a signed big endian 24 bit integer to @writer.
532 * Returns: %TRUE if the value could be written
535 * gst_byte_writer_put_int32_be:
536 * @writer: #GstByteWriter instance
537 * @val: Value to write
539 * Writes a signed big endian 32 bit integer to @writer.
541 * Returns: %TRUE if the value could be written
544 * gst_byte_writer_put_int64_be:
545 * @writer: #GstByteWriter instance
546 * @val: Value to write
548 * Writes a signed big endian 64 bit integer to @writer.
550 * Returns: %TRUE if the value could be written
553 * gst_byte_writer_put_int16_le:
554 * @writer: #GstByteWriter instance
555 * @val: Value to write
557 * Writes a signed little endian 16 bit integer to @writer.
559 * Returns: %TRUE if the value could be written
562 * gst_byte_writer_put_int24_le:
563 * @writer: #GstByteWriter instance
564 * @val: Value to write
566 * Writes a signed little endian 24 bit integer to @writer.
568 * Returns: %TRUE if the value could be written
571 * gst_byte_writer_put_int32_le:
572 * @writer: #GstByteWriter instance
573 * @val: Value to write
575 * Writes a signed little endian 32 bit integer to @writer.
577 * Returns: %TRUE if the value could be written
580 * gst_byte_writer_put_int64_le:
581 * @writer: #GstByteWriter instance
582 * @val: Value to write
584 * Writes a signed little endian 64 bit integer to @writer.
586 * Returns: %TRUE if the value could be written
589 * gst_byte_writer_put_float32_be:
590 * @writer: #GstByteWriter instance
591 * @val: Value to write
593 * Writes a big endian 32 bit float to @writer.
595 * Returns: %TRUE if the value could be written
598 * gst_byte_writer_put_float64_be:
599 * @writer: #GstByteWriter instance
600 * @val: Value to write
602 * Writes a big endian 64 bit float to @writer.
604 * Returns: %TRUE if the value could be written
607 * gst_byte_writer_put_float32_le:
608 * @writer: #GstByteWriter instance
609 * @val: Value to write
611 * Writes a little endian 32 bit float to @writer.
613 * Returns: %TRUE if the value could be written
616 * gst_byte_writer_put_float64_le:
617 * @writer: #GstByteWriter instance
618 * @val: Value to write
620 * Writes a little endian 64 bit float to @writer.
622 * Returns: %TRUE if the value could be written
625 * gst_byte_writer_put_string_utf8:
626 * @writer: #GstByteWriter instance
627 * @data: (transfer none) (array zero-terminated=1) (type utf8): UTF8 string to
630 * Writes a NUL-terminated UTF8 string to @writer (including the terminator).
632 * Returns: %TRUE if the value could be written
635 * gst_byte_writer_put_string_utf16:
636 * @writer: #GstByteWriter instance
637 * @data: (transfer none) (array zero-terminated=1): UTF16 string to write
639 * Writes a NUL-terminated UTF16 string to @writer (including the terminator).
641 * Returns: %TRUE if the value could be written
644 * gst_byte_writer_put_string_utf32:
645 * @writer: #GstByteWriter instance
646 * @data: (transfer none) (array zero-terminated=1): UTF32 string to write
648 * Writes a NUL-terminated UTF32 string to @writer (including the terminator).
650 * Returns: %TRUE if the value could be written
653 * gst_byte_writer_put_data:
654 * @writer: #GstByteWriter instance
655 * @data: (transfer none) (array length=size): Data to write
656 * @size: Size of @data in bytes
658 * Writes @size bytes of @data to @writer.
660 * Returns: %TRUE if the value could be written
663 * gst_byte_writer_fill:
664 * @writer: #GstByteWriter instance
665 * @value: Value to be written
666 * @size: Number of bytes to be written
668 * Writes @size bytes containing @value to @writer.
670 * Returns: %TRUE if the value could be written
674 * gst_byte_writer_put_buffer:
675 * @writer: #GstByteWriter instance
676 * @buffer: (transfer none): source #GstBuffer
677 * @offset: offset to copy from
678 * @size: total size to copy. If -1, all data is copied
680 * Writes @size bytes of @data to @writer.
682 * Returns: %TRUE if the data could be written