Port gtk-doc comments to their equivalent markdown syntax
[platform/upstream/gstreamer.git] / libs / gst / base / gstbytewriter.c
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 GST_BYTE_WRITER_DISABLE_INLINES
26 #include "gstbytewriter.h"
27
28 /**
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
33  *
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.
40  */
41
42 /**
43  * gst_byte_writer_new: (skip)
44  *
45  * Creates a new, empty #GstByteWriter instance
46  *
47  * Free-function: gst_byte_writer_free
48  *
49  * Returns: (transfer full): a new, empty #GstByteWriter instance
50  */
51 GstByteWriter *
52 gst_byte_writer_new (void)
53 {
54   GstByteWriter *ret = g_slice_new0 (GstByteWriter);
55
56   ret->owned = TRUE;
57   return ret;
58 }
59
60 /**
61  * gst_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 #GstByteWriter instance with the given
66  * initial data size.
67  *
68  * Free-function: gst_byte_writer_free
69  *
70  * Returns: (transfer full): a new #GstByteWriter instance
71  */
72 GstByteWriter *
73 gst_byte_writer_new_with_size (guint size, gboolean fixed)
74 {
75   GstByteWriter *ret = gst_byte_writer_new ();
76
77   ret->alloc_size = size;
78   ret->parent.data = g_malloc (ret->alloc_size);
79   ret->fixed = fixed;
80   ret->owned = TRUE;
81
82   return ret;
83 }
84
85 /**
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
90  *
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.
94  *
95  * Free-function: gst_byte_writer_free
96  *
97  * Returns: (transfer full): a new #GstByteWriter instance
98  */
99 GstByteWriter *
100 gst_byte_writer_new_with_data (guint8 * data, guint size, gboolean initialized)
101 {
102   GstByteWriter *ret = gst_byte_writer_new ();
103
104   ret->parent.data = data;
105   ret->parent.size = (initialized) ? size : 0;
106   ret->alloc_size = size;
107   ret->fixed = TRUE;
108   ret->owned = FALSE;
109
110   return ret;
111 }
112
113 /**
114  * gst_byte_writer_init:
115  * @writer: #GstByteWriter instance
116  *
117  * Initializes @writer to an empty instance
118  */
119 void
120 gst_byte_writer_init (GstByteWriter * writer)
121 {
122   g_return_if_fail (writer != NULL);
123
124   memset (writer, 0, sizeof (GstByteWriter));
125
126   writer->owned = TRUE;
127 }
128
129 /**
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
134  *
135  * Initializes @writer with the given initial data size.
136  */
137 void
138 gst_byte_writer_init_with_size (GstByteWriter * writer, guint size,
139     gboolean fixed)
140 {
141   g_return_if_fail (writer != NULL);
142
143   gst_byte_writer_init (writer);
144
145   writer->parent.data = g_malloc (size);
146   writer->alloc_size = size;
147   writer->fixed = fixed;
148   writer->owned = TRUE;
149 }
150
151 /**
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
157  *
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.
161  */
162 void
163 gst_byte_writer_init_with_data (GstByteWriter * writer, guint8 * data,
164     guint size, gboolean initialized)
165 {
166   g_return_if_fail (writer != NULL);
167
168   gst_byte_writer_init (writer);
169
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;
175 }
176
177 /**
178  * gst_byte_writer_reset:
179  * @writer: #GstByteWriter instance
180  *
181  * Resets @writer and frees the data if it's
182  * owned by @writer.
183  */
184 void
185 gst_byte_writer_reset (GstByteWriter * writer)
186 {
187   g_return_if_fail (writer != NULL);
188
189   if (writer->owned)
190     g_free ((guint8 *) writer->parent.data);
191   memset (writer, 0, sizeof (GstByteWriter));
192 }
193
194 /**
195  * gst_byte_writer_reset_and_get_data:
196  * @writer: #GstByteWriter instance
197  *
198  * Resets @writer and returns the current data.
199  *
200  * Free-function: g_free
201  *
202  * Returns: (array) (transfer full): the current data. g_free() after
203  * usage.
204  */
205 guint8 *
206 gst_byte_writer_reset_and_get_data (GstByteWriter * writer)
207 {
208   guint8 *data;
209
210   g_return_val_if_fail (writer != NULL, NULL);
211
212   data = (guint8 *) writer->parent.data;
213   if (!writer->owned)
214     data = g_memdup (data, writer->parent.size);
215   writer->parent.data = NULL;
216   gst_byte_writer_reset (writer);
217
218   return data;
219 }
220
221 /**
222  * gst_byte_writer_reset_and_get_buffer:
223  * @writer: #GstByteWriter instance
224  *
225  * Resets @writer and returns the current data as buffer.
226  *
227  * Free-function: gst_buffer_unref
228  *
229  * Returns: (transfer full): the current data as buffer. gst_buffer_unref()
230  *     after usage.
231  */
232 GstBuffer *
233 gst_byte_writer_reset_and_get_buffer (GstByteWriter * writer)
234 {
235   GstBuffer *buffer;
236   gpointer data;
237   gsize size;
238
239   g_return_val_if_fail (writer != NULL, NULL);
240
241   size = writer->parent.size;
242   data = gst_byte_writer_reset_and_get_data (writer);
243
244   buffer = gst_buffer_new ();
245   if (data != NULL) {
246     gst_buffer_append_memory (buffer,
247         gst_memory_new_wrapped (0, data, size, 0, size, data, g_free));
248   }
249
250   return buffer;
251 }
252
253 /**
254  * gst_byte_writer_free:
255  * @writer: (in) (transfer full): #GstByteWriter instance
256  *
257  * Frees @writer and all memory allocated by it.
258  */
259 void
260 gst_byte_writer_free (GstByteWriter * writer)
261 {
262   g_return_if_fail (writer != NULL);
263
264   gst_byte_writer_reset (writer);
265   g_slice_free (GstByteWriter, writer);
266 }
267
268 /**
269  * gst_byte_writer_free_and_get_data:
270  * @writer: (in) (transfer full): #GstByteWriter instance
271  *
272  * Frees @writer and all memory allocated by it except
273  * the current data, which is returned.
274  *
275  * Free-function: g_free
276  *
277  * Returns: (transfer full): the current data. g_free() after usage.
278  */
279 guint8 *
280 gst_byte_writer_free_and_get_data (GstByteWriter * writer)
281 {
282   guint8 *data;
283
284   g_return_val_if_fail (writer != NULL, NULL);
285
286   data = gst_byte_writer_reset_and_get_data (writer);
287   g_slice_free (GstByteWriter, writer);
288
289   return data;
290 }
291
292 /**
293  * gst_byte_writer_free_and_get_buffer:
294  * @writer: (in) (transfer full): #GstByteWriter instance
295  *
296  * Frees @writer and all memory allocated by it except
297  * the current data, which is returned as #GstBuffer.
298  *
299  * Free-function: gst_buffer_unref
300  *
301  * Returns: (transfer full): the current data as buffer. gst_buffer_unref()
302  *     after usage.
303  */
304 GstBuffer *
305 gst_byte_writer_free_and_get_buffer (GstByteWriter * writer)
306 {
307   GstBuffer *buffer;
308
309   g_return_val_if_fail (writer != NULL, NULL);
310
311   buffer = gst_byte_writer_reset_and_get_buffer (writer);
312   g_slice_free (GstByteWriter, writer);
313
314   return buffer;
315 }
316
317 /**
318  * gst_byte_writer_get_remaining:
319  * @writer: #GstByteWriter instance
320  *
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.
323  *
324  * Returns: the remaining size of data that can still be written
325  */
326 guint
327 gst_byte_writer_get_remaining (const GstByteWriter * writer)
328 {
329   g_return_val_if_fail (writer != NULL, -1);
330
331   if (!writer->fixed)
332     return -1;
333   else
334     return writer->alloc_size - writer->parent.byte;
335 }
336
337 /**
338  * gst_byte_writer_ensure_free_space:
339  * @writer: #GstByteWriter instance
340  * @size: Number of bytes that should be available
341  *
342  * Checks if enough free space from the current write cursor is
343  * available and reallocates if necessary.
344  *
345  * Returns: %TRUE if at least @size bytes are still available
346  */
347 gboolean
348 gst_byte_writer_ensure_free_space (GstByteWriter * writer, guint size)
349 {
350   return _gst_byte_writer_ensure_free_space_inline (writer, size);
351 }
352
353
354 #define CREATE_WRITE_FUNC(bits,type,name,write_func) \
355 gboolean \
356 gst_byte_writer_put_##name (GstByteWriter *writer, type val) \
357 { \
358   return _gst_byte_writer_put_##name##_inline (writer, val); \
359 }
360
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);
379
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);
384
385 gboolean
386 gst_byte_writer_put_data (GstByteWriter * writer, const guint8 * data,
387     guint size)
388 {
389   return _gst_byte_writer_put_data_inline (writer, data, size);
390 }
391
392 gboolean
393 gst_byte_writer_fill (GstByteWriter * writer, guint8 value, guint size)
394 {
395   return _gst_byte_writer_fill_inline (writer, value, size);
396 }
397
398 #define CREATE_WRITE_STRING_FUNC(bits,type) \
399 gboolean \
400 gst_byte_writer_put_string_utf##bits (GstByteWriter *writer, const type * data) \
401 { \
402   guint size = 0; \
403   \
404   g_return_val_if_fail (writer != NULL, FALSE); \
405   \
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)) \
410       return FALSE; \
411     ++size; \
412   } \
413   ++size; \
414   \
415   if (G_UNLIKELY (!_gst_byte_writer_ensure_free_space_inline(writer, size * (bits / 8)))) \
416     return FALSE; \
417   \
418   _gst_byte_writer_put_data_inline (writer, (const guint8 *) data, size * (bits / 8)); \
419   \
420   return TRUE; \
421 }
422
423 CREATE_WRITE_STRING_FUNC (8, gchar);
424 CREATE_WRITE_STRING_FUNC (16, guint16);
425 CREATE_WRITE_STRING_FUNC (32, guint32);
426 /**
427  * gst_byte_writer_put_uint8:
428  * @writer: #GstByteWriter instance
429  * @val: Value to write
430  *
431  * Writes a unsigned 8 bit integer to @writer.
432  *
433  * Returns: %TRUE if the value could be written
434  */
435 /**
436  * gst_byte_writer_put_uint16_be:
437  * @writer: #GstByteWriter instance
438  * @val: Value to write
439  *
440  * Writes a unsigned big endian 16 bit integer to @writer.
441  *
442  * Returns: %TRUE if the value could be written
443  */
444 /**
445  * gst_byte_writer_put_uint24_be:
446  * @writer: #GstByteWriter instance
447  * @val: Value to write
448  *
449  * Writes a unsigned big endian 24 bit integer to @writer.
450  *
451  * Returns: %TRUE if the value could be written
452  */
453 /**
454  * gst_byte_writer_put_uint32_be:
455  * @writer: #GstByteWriter instance
456  * @val: Value to write
457  *
458  * Writes a unsigned big endian 32 bit integer to @writer.
459  *
460  * Returns: %TRUE if the value could be written
461  */
462 /**
463  * gst_byte_writer_put_uint64_be:
464  * @writer: #GstByteWriter instance
465  * @val: Value to write
466  *
467  * Writes a unsigned big endian 64 bit integer to @writer.
468  *
469  * Returns: %TRUE if the value could be written
470  */
471 /**
472  * gst_byte_writer_put_uint16_le:
473  * @writer: #GstByteWriter instance
474  * @val: Value to write
475  *
476  * Writes a unsigned little endian 16 bit integer to @writer.
477  *
478  * Returns: %TRUE if the value could be written
479  */
480 /**
481  * gst_byte_writer_put_uint24_le:
482  * @writer: #GstByteWriter instance
483  * @val: Value to write
484  *
485  * Writes a unsigned little endian 24 bit integer to @writer.
486  *
487  * Returns: %TRUE if the value could be written
488  */
489 /**
490  * gst_byte_writer_put_uint32_le:
491  * @writer: #GstByteWriter instance
492  * @val: Value to write
493  *
494  * Writes a unsigned little endian 32 bit integer to @writer.
495  *
496  * Returns: %TRUE if the value could be written
497  */
498 /**
499  * gst_byte_writer_put_uint64_le:
500  * @writer: #GstByteWriter instance
501  * @val: Value to write
502  *
503  * Writes a unsigned little endian 64 bit integer to @writer.
504  *
505  * Returns: %TRUE if the value could be written
506  */
507 /**
508  * gst_byte_writer_put_int8:
509  * @writer: #GstByteWriter instance
510  * @val: Value to write
511  *
512  * Writes a signed 8 bit integer to @writer.
513  *
514  * Returns: %TRUE if the value could be written
515  */
516 /**
517  * gst_byte_writer_put_int16_be:
518  * @writer: #GstByteWriter instance
519  * @val: Value to write
520  *
521  * Writes a signed big endian 16 bit integer to @writer.
522  *
523  * Returns: %TRUE if the value could be written
524  */
525 /**
526  * gst_byte_writer_put_int24_be:
527  * @writer: #GstByteWriter instance
528  * @val: Value to write
529  *
530  * Writes a signed big endian 24 bit integer to @writer.
531  *
532  * Returns: %TRUE if the value could be written
533  */
534 /**
535  * gst_byte_writer_put_int32_be:
536  * @writer: #GstByteWriter instance
537  * @val: Value to write
538  *
539  * Writes a signed big endian 32 bit integer to @writer.
540  *
541  * Returns: %TRUE if the value could be written
542  */
543 /**
544  * gst_byte_writer_put_int64_be:
545  * @writer: #GstByteWriter instance
546  * @val: Value to write
547  *
548  * Writes a signed big endian 64 bit integer to @writer.
549  *
550  * Returns: %TRUE if the value could be written
551  */
552 /**
553  * gst_byte_writer_put_int16_le:
554  * @writer: #GstByteWriter instance
555  * @val: Value to write
556  *
557  * Writes a signed little endian 16 bit integer to @writer.
558  *
559  * Returns: %TRUE if the value could be written
560  */
561 /**
562  * gst_byte_writer_put_int24_le:
563  * @writer: #GstByteWriter instance
564  * @val: Value to write
565  *
566  * Writes a signed little endian 24 bit integer to @writer.
567  *
568  * Returns: %TRUE if the value could be written
569  */
570 /**
571  * gst_byte_writer_put_int32_le:
572  * @writer: #GstByteWriter instance
573  * @val: Value to write
574  *
575  * Writes a signed little endian 32 bit integer to @writer.
576  *
577  * Returns: %TRUE if the value could be written
578  */
579 /**
580  * gst_byte_writer_put_int64_le:
581  * @writer: #GstByteWriter instance
582  * @val: Value to write
583  *
584  * Writes a signed little endian 64 bit integer to @writer.
585  *
586  * Returns: %TRUE if the value could be written
587  */
588 /**
589  * gst_byte_writer_put_float32_be:
590  * @writer: #GstByteWriter instance
591  * @val: Value to write
592  *
593  * Writes a big endian 32 bit float to @writer.
594  *
595  * Returns: %TRUE if the value could be written
596  */
597 /**
598  * gst_byte_writer_put_float64_be:
599  * @writer: #GstByteWriter instance
600  * @val: Value to write
601  *
602  * Writes a big endian 64 bit float to @writer.
603  *
604  * Returns: %TRUE if the value could be written
605  */
606 /**
607  * gst_byte_writer_put_float32_le:
608  * @writer: #GstByteWriter instance
609  * @val: Value to write
610  *
611  * Writes a little endian 32 bit float to @writer.
612  *
613  * Returns: %TRUE if the value could be written
614  */
615 /**
616  * gst_byte_writer_put_float64_le:
617  * @writer: #GstByteWriter instance
618  * @val: Value to write
619  *
620  * Writes a little endian 64 bit float to @writer.
621  *
622  * Returns: %TRUE if the value could be written
623  */
624 /**
625  * gst_byte_writer_put_string_utf8:
626  * @writer: #GstByteWriter instance
627  * @data: (transfer none) (array zero-terminated=1) (type utf8): UTF8 string to
628  *     write
629  *
630  * Writes a NUL-terminated UTF8 string to @writer (including the terminator).
631  *
632  * Returns: %TRUE if the value could be written
633  */
634 /**
635  * gst_byte_writer_put_string_utf16:
636  * @writer: #GstByteWriter instance
637  * @data: (transfer none) (array zero-terminated=1): UTF16 string to write
638  *
639  * Writes a NUL-terminated UTF16 string to @writer (including the terminator).
640  *
641  * Returns: %TRUE if the value could be written
642  */
643 /**
644  * gst_byte_writer_put_string_utf32:
645  * @writer: #GstByteWriter instance
646  * @data: (transfer none) (array zero-terminated=1): UTF32 string to write
647  *
648  * Writes a NUL-terminated UTF32 string to @writer (including the terminator).
649  *
650  * Returns: %TRUE if the value could be written
651  */
652 /**
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
657  *
658  * Writes @size bytes of @data to @writer.
659  *
660  * Returns: %TRUE if the value could be written
661  */
662 /**
663  * gst_byte_writer_fill:
664  * @writer: #GstByteWriter instance
665  * @value: Value to be written
666  * @size: Number of bytes to be written
667  *
668  * Writes @size bytes containing @value to @writer.
669  *
670  * Returns: %TRUE if the value could be written
671  */
672
673 /**
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
679  *
680  * Writes @size bytes of @data to @writer.
681  *
682  * Returns: %TRUE if the data could be written
683  *
684  */