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., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
25 #define GST_BYTE_WRITER_DISABLE_INLINES
26 #include "gstbytewriter.h"
29 * SECTION:gstbytewriter
30 * @short_description: Writes different integer, string and floating point
31 * types to a memory buffer and allows reading
33 * #GstByteWriter provides a byte writer and reader that can write/read different
34 * integer and floating point types to/from a memory buffer. It provides functions
35 * for writing/reading signed/unsigned, little/big endian integers of 8, 16, 24,
36 * 32 and 64 bits and functions for reading little/big endian floating points numbers of
37 * 32 and 64 bits. It also provides functions to write/read NUL-terminated strings
38 * in various character encodings.
42 * gst_byte_writer_new:
44 * Creates a new, empty #GstByteWriter instance
46 * Free-function: gst_byte_writer_free
48 * Returns: (transfer full): a new, empty #GstByteWriter instance
53 gst_byte_writer_new (void)
55 GstByteWriter *ret = g_slice_new0 (GstByteWriter);
62 * gst_byte_writer_new_with_size:
63 * @size: Initial size of data
64 * @fixed: If %TRUE the data can't be reallocated
66 * Creates a new #GstByteWriter instance with the given
69 * Free-function: gst_byte_writer_free
71 * Returns: (transfer full): a new #GstByteWriter instance
76 gst_byte_writer_new_with_size (guint size, gboolean fixed)
78 GstByteWriter *ret = gst_byte_writer_new ();
80 ret->alloc_size = size;
81 ret->parent.data = g_malloc (ret->alloc_size);
89 * gst_byte_writer_new_with_data:
90 * @data: Memory area for writing
91 * @size: Size of @data in bytes
92 * @initialized: If %TRUE the complete data can be read from the beginning
94 * Creates a new #GstByteWriter instance with the given
95 * memory area. If @initialized is %TRUE it is possible to
96 * read @size bytes from the #GstByteWriter from the beginning.
98 * Free-function: gst_byte_writer_free
100 * Returns: (transfer full): a new #GstByteWriter instance
105 gst_byte_writer_new_with_data (guint8 * data, guint size, gboolean initialized)
107 GstByteWriter *ret = gst_byte_writer_new ();
109 ret->parent.data = data;
110 ret->parent.size = (initialized) ? size : 0;
111 ret->alloc_size = size;
119 * gst_byte_writer_init:
120 * @writer: #GstByteWriter instance
122 * Initializes @writer to an empty instance
127 gst_byte_writer_init (GstByteWriter * writer)
129 g_return_if_fail (writer != NULL);
131 memset (writer, 0, sizeof (GstByteWriter));
133 writer->owned = TRUE;
137 * gst_byte_writer_init_with_size:
138 * @writer: #GstByteWriter instance
139 * @size: Initial size of data
140 * @fixed: If %TRUE the data can't be reallocated
142 * Initializes @writer with the given initial data size.
147 gst_byte_writer_init_with_size (GstByteWriter * writer, guint size,
150 g_return_if_fail (writer != NULL);
152 gst_byte_writer_init (writer);
154 writer->parent.data = g_malloc (size);
155 writer->alloc_size = size;
156 writer->fixed = fixed;
157 writer->owned = TRUE;
161 * gst_byte_writer_init_with_data:
162 * @writer: #GstByteWriter instance
163 * @data: (array length=size) (transfer none): Memory area for writing
164 * @size: Size of @data in bytes
165 * @initialized: If %TRUE the complete data can be read from the beginning
167 * Initializes @writer with the given
168 * memory area. If @initialized is %TRUE it is possible to
169 * read @size bytes from the #GstByteWriter from the beginning.
174 gst_byte_writer_init_with_data (GstByteWriter * writer, guint8 * data,
175 guint size, gboolean initialized)
177 g_return_if_fail (writer != NULL);
179 gst_byte_writer_init (writer);
181 writer->parent.data = data;
182 writer->parent.size = (initialized) ? size : 0;
183 writer->alloc_size = size;
184 writer->fixed = TRUE;
185 writer->owned = FALSE;
189 * gst_byte_writer_reset:
190 * @writer: #GstByteWriter instance
192 * Resets @writer and frees the data if it's
198 gst_byte_writer_reset (GstByteWriter * writer)
200 g_return_if_fail (writer != NULL);
203 g_free ((guint8 *) writer->parent.data);
204 memset (writer, 0, sizeof (GstByteWriter));
208 * gst_byte_writer_reset_and_get_data:
209 * @writer: #GstByteWriter instance
211 * Resets @writer and returns the current data.
213 * Free-function: g_free
215 * Returns: (transfer full): the current data. g_free() after usage.
220 gst_byte_writer_reset_and_get_data (GstByteWriter * writer)
224 g_return_val_if_fail (writer != NULL, NULL);
226 data = (guint8 *) writer->parent.data;
228 data = g_memdup (data, writer->parent.size);
229 writer->parent.data = NULL;
230 gst_byte_writer_reset (writer);
236 * gst_byte_writer_reset_and_get_buffer:
237 * @writer: #GstByteWriter instance
239 * Resets @writer and returns the current data as buffer.
241 * Free-function: gst_buffer_unref
243 * Returns: (transfer full): the current data as buffer. gst_buffer_unref()
249 gst_byte_writer_reset_and_get_buffer (GstByteWriter * writer)
255 g_return_val_if_fail (writer != NULL, NULL);
257 size = writer->parent.size;
258 data = gst_byte_writer_reset_and_get_data (writer);
260 buffer = gst_buffer_new ();
262 gst_buffer_append_memory (buffer,
263 gst_memory_new_wrapped (0, data, size, 0, size, data, g_free));
270 * gst_byte_writer_free:
271 * @writer: (in) (transfer full): #GstByteWriter instance
273 * Frees @writer and all memory allocated by it.
278 gst_byte_writer_free (GstByteWriter * writer)
280 g_return_if_fail (writer != NULL);
282 gst_byte_writer_reset (writer);
283 g_slice_free (GstByteWriter, writer);
287 * gst_byte_writer_free_and_get_data:
288 * @writer: (in) (transfer full): #GstByteWriter instance
290 * Frees @writer and all memory allocated by it except
291 * the current data, which is returned.
293 * Free-function: g_free
295 * Returns: (transfer full): the current data. g_free() after usage.
300 gst_byte_writer_free_and_get_data (GstByteWriter * writer)
304 g_return_val_if_fail (writer != NULL, NULL);
306 data = gst_byte_writer_reset_and_get_data (writer);
307 g_slice_free (GstByteWriter, writer);
313 * gst_byte_writer_free_and_get_buffer:
314 * @writer: (in) (transfer full): #GstByteWriter instance
316 * Frees @writer and all memory allocated by it except
317 * the current data, which is returned as #GstBuffer.
319 * Free-function: gst_buffer_unref
321 * Returns: (transfer full): the current data as buffer. gst_buffer_unref()
327 gst_byte_writer_free_and_get_buffer (GstByteWriter * writer)
331 g_return_val_if_fail (writer != NULL, NULL);
333 buffer = gst_byte_writer_reset_and_get_buffer (writer);
334 g_slice_free (GstByteWriter, writer);
340 * gst_byte_writer_get_remaining:
341 * @writer: #GstByteWriter instance
343 * Returns the remaining size of data that can still be written. If
344 * -1 is returned the remaining size is only limited by system resources.
346 * Returns: the remaining size of data that can still be written
351 gst_byte_writer_get_remaining (const GstByteWriter * writer)
353 g_return_val_if_fail (writer != NULL, -1);
358 return writer->alloc_size - writer->parent.byte;
362 * gst_byte_writer_ensure_free_space:
363 * @writer: #GstByteWriter instance
364 * @size: Number of bytes that should be available
366 * Checks if enough free space from the current write cursor is
367 * available and reallocates if necessary.
369 * Returns: %TRUE if at least @size bytes are still available
374 gst_byte_writer_ensure_free_space (GstByteWriter * writer, guint size)
376 return _gst_byte_writer_ensure_free_space_inline (writer, size);
380 #define CREATE_WRITE_FUNC(bits,type,name,write_func) \
382 gst_byte_writer_put_##name (GstByteWriter *writer, type val) \
384 return _gst_byte_writer_put_##name##_inline (writer, val); \
387 CREATE_WRITE_FUNC (8, guint8, uint8, GST_WRITE_UINT8);
388 CREATE_WRITE_FUNC (8, gint8, int8, GST_WRITE_UINT8);
389 CREATE_WRITE_FUNC (16, guint16, uint16_le, GST_WRITE_UINT16_LE);
390 CREATE_WRITE_FUNC (16, guint16, uint16_be, GST_WRITE_UINT16_BE);
391 CREATE_WRITE_FUNC (16, gint16, int16_le, GST_WRITE_UINT16_LE);
392 CREATE_WRITE_FUNC (16, gint16, int16_be, GST_WRITE_UINT16_BE);
393 CREATE_WRITE_FUNC (24, guint32, uint24_le, GST_WRITE_UINT24_LE);
394 CREATE_WRITE_FUNC (24, guint32, uint24_be, GST_WRITE_UINT24_BE);
395 CREATE_WRITE_FUNC (24, gint32, int24_le, GST_WRITE_UINT24_LE);
396 CREATE_WRITE_FUNC (24, gint32, int24_be, GST_WRITE_UINT24_BE);
397 CREATE_WRITE_FUNC (32, guint32, uint32_le, GST_WRITE_UINT32_LE);
398 CREATE_WRITE_FUNC (32, guint32, uint32_be, GST_WRITE_UINT32_BE);
399 CREATE_WRITE_FUNC (32, gint32, int32_le, GST_WRITE_UINT32_LE);
400 CREATE_WRITE_FUNC (32, gint32, int32_be, GST_WRITE_UINT32_BE);
401 CREATE_WRITE_FUNC (64, guint64, uint64_le, GST_WRITE_UINT64_LE);
402 CREATE_WRITE_FUNC (64, guint64, uint64_be, GST_WRITE_UINT64_BE);
403 CREATE_WRITE_FUNC (64, gint64, int64_le, GST_WRITE_UINT64_LE);
404 CREATE_WRITE_FUNC (64, gint64, int64_be, GST_WRITE_UINT64_BE);
406 CREATE_WRITE_FUNC (32, gfloat, float32_be, GST_WRITE_FLOAT_BE);
407 CREATE_WRITE_FUNC (32, gfloat, float32_le, GST_WRITE_FLOAT_LE);
408 CREATE_WRITE_FUNC (64, gdouble, float64_be, GST_WRITE_DOUBLE_BE);
409 CREATE_WRITE_FUNC (64, gdouble, float64_le, GST_WRITE_DOUBLE_LE);
412 gst_byte_writer_put_data (GstByteWriter * writer, const guint8 * data,
415 return _gst_byte_writer_put_data_inline (writer, data, size);
419 gst_byte_writer_fill (GstByteWriter * writer, guint8 value, guint size)
421 return _gst_byte_writer_fill_inline (writer, value, size);
424 #define CREATE_WRITE_STRING_FUNC(bits,type) \
426 gst_byte_writer_put_string_utf##bits (GstByteWriter *writer, const type * data) \
430 g_return_val_if_fail (writer != NULL, FALSE); \
432 /* endianness does not matter if we are looking for a NUL terminator */ \
433 while (data[size] != 0) { \
434 /* have prevent overflow */ \
435 if (G_UNLIKELY (size == G_MAXUINT)) \
441 if (G_UNLIKELY (!_gst_byte_writer_ensure_free_space_inline(writer, size * (bits / 8)))) \
444 _gst_byte_writer_put_data_inline (writer, (const guint8 *) data, size * (bits / 8)); \
449 CREATE_WRITE_STRING_FUNC (8, gchar);
450 CREATE_WRITE_STRING_FUNC (16, guint16);
451 CREATE_WRITE_STRING_FUNC (32, guint32);
453 * gst_byte_writer_put_uint8:
454 * @writer: #GstByteWriter instance
455 * @val: Value to write
457 * Writes a unsigned 8 bit integer to @writer.
459 * Returns: %TRUE if the value could be written
464 * gst_byte_writer_put_uint16_be:
465 * @writer: #GstByteWriter instance
466 * @val: Value to write
468 * Writes a unsigned big endian 16 bit integer to @writer.
470 * Returns: %TRUE if the value could be written
475 * gst_byte_writer_put_uint24_be:
476 * @writer: #GstByteWriter instance
477 * @val: Value to write
479 * Writes a unsigned big endian 24 bit integer to @writer.
481 * Returns: %TRUE if the value could be written
486 * gst_byte_writer_put_uint32_be:
487 * @writer: #GstByteWriter instance
488 * @val: Value to write
490 * Writes a unsigned big endian 32 bit integer to @writer.
492 * Returns: %TRUE if the value could be written
497 * gst_byte_writer_put_uint64_be:
498 * @writer: #GstByteWriter instance
499 * @val: Value to write
501 * Writes a unsigned big endian 64 bit integer to @writer.
503 * Returns: %TRUE if the value could be written
508 * gst_byte_writer_put_uint16_le:
509 * @writer: #GstByteWriter instance
510 * @val: Value to write
512 * Writes a unsigned little endian 16 bit integer to @writer.
514 * Returns: %TRUE if the value could be written
519 * gst_byte_writer_put_uint24_le:
520 * @writer: #GstByteWriter instance
521 * @val: Value to write
523 * Writes a unsigned little endian 24 bit integer to @writer.
525 * Returns: %TRUE if the value could be written
530 * gst_byte_writer_put_uint32_le:
531 * @writer: #GstByteWriter instance
532 * @val: Value to write
534 * Writes a unsigned little endian 32 bit integer to @writer.
536 * Returns: %TRUE if the value could be written
541 * gst_byte_writer_put_uint64_le:
542 * @writer: #GstByteWriter instance
543 * @val: Value to write
545 * Writes a unsigned little endian 64 bit integer to @writer.
547 * Returns: %TRUE if the value could be written
552 * gst_byte_writer_put_int8:
553 * @writer: #GstByteWriter instance
554 * @val: Value to write
556 * Writes a signed 8 bit integer to @writer.
558 * Returns: %TRUE if the value could be written
563 * gst_byte_writer_put_int16_be:
564 * @writer: #GstByteWriter instance
565 * @val: Value to write
567 * Writes a signed big endian 16 bit integer to @writer.
569 * Returns: %TRUE if the value could be written
574 * gst_byte_writer_put_int24_be:
575 * @writer: #GstByteWriter instance
576 * @val: Value to write
578 * Writes a signed big endian 24 bit integer to @writer.
580 * Returns: %TRUE if the value could be written
585 * gst_byte_writer_put_int32_be:
586 * @writer: #GstByteWriter instance
587 * @val: Value to write
589 * Writes a signed big endian 32 bit integer to @writer.
591 * Returns: %TRUE if the value could be written
596 * gst_byte_writer_put_int64_be:
597 * @writer: #GstByteWriter instance
598 * @val: Value to write
600 * Writes a signed big endian 64 bit integer to @writer.
602 * Returns: %TRUE if the value could be written
607 * gst_byte_writer_put_int16_le:
608 * @writer: #GstByteWriter instance
609 * @val: Value to write
611 * Writes a signed little endian 16 bit integer to @writer.
613 * Returns: %TRUE if the value could be written
618 * gst_byte_writer_put_int24_le:
619 * @writer: #GstByteWriter instance
620 * @val: Value to write
622 * Writes a signed little endian 24 bit integer to @writer.
624 * Returns: %TRUE if the value could be written
629 * gst_byte_writer_put_int32_le:
630 * @writer: #GstByteWriter instance
631 * @val: Value to write
633 * Writes a signed little endian 32 bit integer to @writer.
635 * Returns: %TRUE if the value could be written
640 * gst_byte_writer_put_int64_le:
641 * @writer: #GstByteWriter instance
642 * @val: Value to write
644 * Writes a signed little endian 64 bit integer to @writer.
646 * Returns: %TRUE if the value could be written
651 * gst_byte_writer_put_float32_be:
652 * @writer: #GstByteWriter instance
653 * @val: Value to write
655 * Writes a big endian 32 bit float to @writer.
657 * Returns: %TRUE if the value could be written
662 * gst_byte_writer_put_float64_be:
663 * @writer: #GstByteWriter instance
664 * @val: Value to write
666 * Writes a big endian 64 bit float to @writer.
668 * Returns: %TRUE if the value could be written
673 * gst_byte_writer_put_float32_le:
674 * @writer: #GstByteWriter instance
675 * @val: Value to write
677 * Writes a little endian 32 bit float to @writer.
679 * Returns: %TRUE if the value could be written
684 * gst_byte_writer_put_float64_le:
685 * @writer: #GstByteWriter instance
686 * @val: Value to write
688 * Writes a little endian 64 bit float to @writer.
690 * Returns: %TRUE if the value could be written
695 * gst_byte_writer_put_string_utf8:
696 * @writer: #GstByteWriter instance
697 * @data: (transfer none) (array zero-terminated=1) (type utf8): UTF8 string to
700 * Writes a NUL-terminated UTF8 string to @writer (including the terminator).
702 * Returns: %TRUE if the value could be written
707 * gst_byte_writer_put_string_utf16:
708 * @writer: #GstByteWriter instance
709 * @data: (transfer none) (array zero-terminated=1): UTF16 string to write
711 * Writes a NUL-terminated UTF16 string to @writer (including the terminator).
713 * Returns: %TRUE if the value could be written
718 * gst_byte_writer_put_string_utf32:
719 * @writer: #GstByteWriter instance
720 * @data: (transfer none) (array zero-terminated=1): UTF32 string to write
722 * Writes a NUL-terminated UTF32 string to @writer (including the terminator).
724 * Returns: %TRUE if the value could be written
729 * gst_byte_writer_put_data:
730 * @writer: #GstByteWriter instance
731 * @data: (transfer none) (array length=size): Data to write
732 * @size: Size of @data in bytes
734 * Writes @size bytes of @data to @writer.
736 * Returns: %TRUE if the value could be written
741 * gst_byte_writer_fill:
742 * @writer: #GstByteWriter instance
743 * @value: Value to be writen
744 * @size: Number of bytes to be writen
746 * Writes @size bytes containing @value to @writer.
748 * Returns: %TRUE if the value could be written
754 * gst_byte_writer_put_buffer:
755 * @writer: #GstByteWriter instance
756 * @buffer: (transfer none): source #GstBuffer
757 * @offset: offset to copy from
758 * @size: total size to copy. If -1, all data is copied
760 * Writes @size bytes of @data to @writer.
762 * Returns: %TRUE if the data could be written