Merge branch 'master' into 0.11
[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., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, 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  * @short_description: Writes different integer, string and floating point
31  *     types to a memory buffer and allows reading
32  *
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.
39  */
40
41 /**
42  * gst_byte_writer_new:
43  *
44  * Creates a new, empty #GstByteWriter instance
45  *
46  * Free-function: gst_byte_writer_free
47  *
48  * Returns: (transfer full): a new, empty #GstByteWriter instance
49  *
50  * Since: 0.10.26
51  */
52 GstByteWriter *
53 gst_byte_writer_new (void)
54 {
55   GstByteWriter *ret = g_slice_new0 (GstByteWriter);
56
57   ret->owned = TRUE;
58   return ret;
59 }
60
61 /**
62  * gst_byte_writer_new_with_size:
63  * @size: Initial size of data
64  * @fixed: If %TRUE the data can't be reallocated
65  *
66  * Creates a new #GstByteWriter instance with the given
67  * initial data size.
68  *
69  * Free-function: gst_byte_writer_free
70  *
71  * Returns: (transfer full): a new #GstByteWriter instance
72  *
73  * Since: 0.10.26
74  */
75 GstByteWriter *
76 gst_byte_writer_new_with_size (guint size, gboolean fixed)
77 {
78   GstByteWriter *ret = gst_byte_writer_new ();
79
80   ret->alloc_size = size;
81   ret->parent.data = g_malloc (ret->alloc_size);
82   ret->fixed = fixed;
83   ret->owned = TRUE;
84
85   return ret;
86 }
87
88 /**
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
93  *
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.
97  *
98  * Free-function: gst_byte_writer_free
99  *
100  * Returns: (transfer full): a new #GstByteWriter instance
101  *
102  * Since: 0.10.26
103  */
104 GstByteWriter *
105 gst_byte_writer_new_with_data (guint8 * data, guint size, gboolean initialized)
106 {
107   GstByteWriter *ret = gst_byte_writer_new ();
108
109   ret->parent.data = data;
110   ret->parent.size = (initialized) ? size : 0;
111   ret->alloc_size = size;
112   ret->fixed = TRUE;
113   ret->owned = FALSE;
114
115   return ret;
116 }
117
118 /**
119  * gst_byte_writer_init:
120  * @writer: #GstByteWriter instance
121  *
122  * Initializes @writer to an empty instance
123  *
124  * Since: 0.10.26
125  */
126 void
127 gst_byte_writer_init (GstByteWriter * writer)
128 {
129   g_return_if_fail (writer != NULL);
130
131   memset (writer, 0, sizeof (GstByteWriter));
132
133   writer->owned = TRUE;
134 }
135
136 /**
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
141  *
142  * Initializes @writer with the given initial data size.
143  *
144  * Since: 0.10.26
145  */
146 void
147 gst_byte_writer_init_with_size (GstByteWriter * writer, guint size,
148     gboolean fixed)
149 {
150   g_return_if_fail (writer != NULL);
151
152   gst_byte_writer_init (writer);
153
154   writer->parent.data = g_malloc (size);
155   writer->alloc_size = size;
156   writer->fixed = fixed;
157   writer->owned = TRUE;
158 }
159
160 /**
161  * gst_byte_writer_init_with_data:
162  * @writer: #GstByteWriter instance
163  * @data: (in callee-allocated) (array length=size) (transfer none): Memory
164  *     area for writing
165  * @size: Size of @data in bytes
166  * @initialized: If %TRUE the complete data can be read from the beginning
167  *
168  * Initializes @writer with the given
169  * memory area. If @initialized is %TRUE it is possible to
170  * read @size bytes from the #GstByteWriter from the beginning.
171  *
172  * Since: 0.10.26
173  */
174 void
175 gst_byte_writer_init_with_data (GstByteWriter * writer, guint8 * data,
176     guint size, gboolean initialized)
177 {
178   g_return_if_fail (writer != NULL);
179
180   gst_byte_writer_init (writer);
181
182   writer->parent.data = data;
183   writer->parent.size = (initialized) ? size : 0;
184   writer->alloc_size = size;
185   writer->fixed = TRUE;
186   writer->owned = FALSE;
187 }
188
189 /**
190  * gst_byte_writer_reset:
191  * @writer: #GstByteWriter instance
192  *
193  * Resets @writer and frees the data if it's
194  * owned by @writer.
195  *
196  * Since: 0.10.26
197  */
198 void
199 gst_byte_writer_reset (GstByteWriter * writer)
200 {
201   g_return_if_fail (writer != NULL);
202
203   if (writer->owned)
204     g_free ((guint8 *) writer->parent.data);
205   memset (writer, 0, sizeof (GstByteWriter));
206 }
207
208 /**
209  * gst_byte_writer_reset_and_get_data:
210  * @writer: #GstByteWriter instance
211  *
212  * Resets @writer and returns the current data.
213  *
214  * Free-function: g_free
215  *
216  * Returns: (transfer full): the current data. g_free() after usage.
217  *
218  * Since: 0.10.26
219  */
220 guint8 *
221 gst_byte_writer_reset_and_get_data (GstByteWriter * writer)
222 {
223   guint8 *data;
224
225   g_return_val_if_fail (writer != NULL, NULL);
226
227   data = (guint8 *) writer->parent.data;
228   if (!writer->owned)
229     data = g_memdup (data, writer->parent.size);
230   writer->parent.data = NULL;
231   gst_byte_writer_reset (writer);
232
233   return data;
234 }
235
236 /**
237  * gst_byte_writer_reset_and_get_buffer:
238  * @writer: #GstByteWriter instance
239  *
240  * Resets @writer and returns the current data as buffer.
241  *
242  * Free-function: gst_buffer_unref
243  *
244  * Returns: (transfer full): the current data as buffer. gst_buffer_unref()
245  *     after usage.
246  *
247  * Since: 0.10.26
248  */
249 GstBuffer *
250 gst_byte_writer_reset_and_get_buffer (GstByteWriter * writer)
251 {
252   GstBuffer *buffer;
253   gpointer data;
254   gsize size;
255
256   g_return_val_if_fail (writer != NULL, NULL);
257
258   size = writer->parent.size;
259   data = gst_byte_writer_reset_and_get_data (writer);
260
261   buffer = gst_buffer_new ();
262   if (data != NULL) {
263     gst_buffer_take_memory (buffer, -1,
264         gst_memory_new_wrapped (0, data, g_free, size, 0, size));
265   }
266
267   return buffer;
268 }
269
270 /**
271  * gst_byte_writer_free:
272  * @writer: (in) (transfer full): #GstByteWriter instance
273  *
274  * Frees @writer and all memory allocated by it.
275  *
276  * Since: 0.10.26
277  */
278 void
279 gst_byte_writer_free (GstByteWriter * writer)
280 {
281   g_return_if_fail (writer != NULL);
282
283   gst_byte_writer_reset (writer);
284   g_slice_free (GstByteWriter, writer);
285 }
286
287 /**
288  * gst_byte_writer_free_and_get_data:
289  * @writer: (in) (transfer full): #GstByteWriter instance
290  *
291  * Frees @writer and all memory allocated by it except
292  * the current data, which is returned.
293  *
294  * Free-function: g_free
295  *
296  * Returns: (transfer full): the current data. g_free() after usage.
297  *
298  * Since: 0.10.26
299  */
300 guint8 *
301 gst_byte_writer_free_and_get_data (GstByteWriter * writer)
302 {
303   guint8 *data;
304
305   g_return_val_if_fail (writer != NULL, NULL);
306
307   data = gst_byte_writer_reset_and_get_data (writer);
308   g_slice_free (GstByteWriter, writer);
309
310   return data;
311 }
312
313 /**
314  * gst_byte_writer_free_and_get_buffer:
315  * @writer: (in) (transfer full): #GstByteWriter instance
316  *
317  * Frees @writer and all memory allocated by it except
318  * the current data, which is returned as #GstBuffer.
319  *
320  * Free-function: gst_buffer_unref
321  *
322  * Returns: (transfer full): the current data as buffer. gst_buffer_unref()
323  *     after usage.
324  *
325  * Since: 0.10.26
326  */
327 GstBuffer *
328 gst_byte_writer_free_and_get_buffer (GstByteWriter * writer)
329 {
330   GstBuffer *buffer;
331
332   g_return_val_if_fail (writer != NULL, NULL);
333
334   buffer = gst_byte_writer_reset_and_get_buffer (writer);
335   g_slice_free (GstByteWriter, writer);
336
337   return buffer;
338 }
339
340 /**
341  * gst_byte_writer_get_remaining:
342  * @writer: #GstByteWriter instance
343  *
344  * Returns the remaining size of data that can still be written. If
345  * -1 is returned the remaining size is only limited by system resources.
346  *
347  * Returns: the remaining size of data that can still be written
348  *
349  * Since: 0.10.26
350  */
351 guint
352 gst_byte_writer_get_remaining (const GstByteWriter * writer)
353 {
354   g_return_val_if_fail (writer != NULL, -1);
355
356   if (!writer->fixed)
357     return -1;
358   else
359     return writer->alloc_size - writer->parent.byte;
360 }
361
362 /**
363  * gst_byte_writer_ensure_free_space:
364  * @writer: #GstByteWriter instance
365  * @size: Number of bytes that should be available
366  *
367  * Checks if enough free space from the current write cursor is
368  * available and reallocates if necessary.
369  *
370  * Returns: %TRUE if at least @size bytes are still available
371  *
372  * Since: 0.10.26
373  */
374 gboolean
375 gst_byte_writer_ensure_free_space (GstByteWriter * writer, guint size)
376 {
377   return _gst_byte_writer_ensure_free_space_inline (writer, size);
378 }
379
380
381 #define CREATE_WRITE_FUNC(bits,type,name,write_func) \
382 gboolean \
383 gst_byte_writer_put_##name (GstByteWriter *writer, type val) \
384 { \
385   return _gst_byte_writer_put_##name##_inline (writer, val); \
386 }
387
388 CREATE_WRITE_FUNC (8, guint8, uint8, GST_WRITE_UINT8);
389 CREATE_WRITE_FUNC (8, gint8, int8, GST_WRITE_UINT8);
390 CREATE_WRITE_FUNC (16, guint16, uint16_le, GST_WRITE_UINT16_LE);
391 CREATE_WRITE_FUNC (16, guint16, uint16_be, GST_WRITE_UINT16_BE);
392 CREATE_WRITE_FUNC (16, gint16, int16_le, GST_WRITE_UINT16_LE);
393 CREATE_WRITE_FUNC (16, gint16, int16_be, GST_WRITE_UINT16_BE);
394 CREATE_WRITE_FUNC (24, guint32, uint24_le, GST_WRITE_UINT24_LE);
395 CREATE_WRITE_FUNC (24, guint32, uint24_be, GST_WRITE_UINT24_BE);
396 CREATE_WRITE_FUNC (24, gint32, int24_le, GST_WRITE_UINT24_LE);
397 CREATE_WRITE_FUNC (24, gint32, int24_be, GST_WRITE_UINT24_BE);
398 CREATE_WRITE_FUNC (32, guint32, uint32_le, GST_WRITE_UINT32_LE);
399 CREATE_WRITE_FUNC (32, guint32, uint32_be, GST_WRITE_UINT32_BE);
400 CREATE_WRITE_FUNC (32, gint32, int32_le, GST_WRITE_UINT32_LE);
401 CREATE_WRITE_FUNC (32, gint32, int32_be, GST_WRITE_UINT32_BE);
402 CREATE_WRITE_FUNC (64, guint64, uint64_le, GST_WRITE_UINT64_LE);
403 CREATE_WRITE_FUNC (64, guint64, uint64_be, GST_WRITE_UINT64_BE);
404 CREATE_WRITE_FUNC (64, gint64, int64_le, GST_WRITE_UINT64_LE);
405 CREATE_WRITE_FUNC (64, gint64, int64_be, GST_WRITE_UINT64_BE);
406
407 CREATE_WRITE_FUNC (32, gfloat, float32_be, GST_WRITE_FLOAT_BE);
408 CREATE_WRITE_FUNC (32, gfloat, float32_le, GST_WRITE_FLOAT_LE);
409 CREATE_WRITE_FUNC (64, gdouble, float64_be, GST_WRITE_DOUBLE_BE);
410 CREATE_WRITE_FUNC (64, gdouble, float64_le, GST_WRITE_DOUBLE_LE);
411
412 gboolean
413 gst_byte_writer_put_data (GstByteWriter * writer, const guint8 * data,
414     guint size)
415 {
416   return _gst_byte_writer_put_data_inline (writer, data, size);
417 }
418
419 gboolean
420 gst_byte_writer_fill (GstByteWriter * writer, guint8 value, guint size)
421 {
422   return _gst_byte_writer_fill_inline (writer, value, size);
423 }
424
425 #define CREATE_WRITE_STRING_FUNC(bits,type) \
426 gboolean \
427 gst_byte_writer_put_string_utf##bits (GstByteWriter *writer, const type * data) \
428 { \
429   guint size = 0; \
430   \
431   g_return_val_if_fail (writer != NULL, FALSE); \
432   \
433   /* endianness does not matter if we are looking for a NUL terminator */ \
434   while (data[size] != 0) { \
435     /* have prevent overflow */ \
436     if (G_UNLIKELY (size == G_MAXUINT)) \
437       return FALSE; \
438     ++size; \
439   } \
440   ++size; \
441   \
442   if (G_UNLIKELY (!_gst_byte_writer_ensure_free_space_inline(writer, size * (bits / 8)))) \
443     return FALSE; \
444   \
445   _gst_byte_writer_put_data_inline (writer, (const guint8 *) data, size * (bits / 8)); \
446   \
447   return TRUE; \
448 }
449
450 CREATE_WRITE_STRING_FUNC (8, gchar);
451 CREATE_WRITE_STRING_FUNC (16, guint16);
452 CREATE_WRITE_STRING_FUNC (32, guint32);
453 /**
454  * gst_byte_writer_put_uint8:
455  * @writer: #GstByteWriter instance
456  * @val: Value to write
457  *
458  * Writes a unsigned 8 bit integer to @writer.
459  *
460  * Returns: %TRUE if the value could be written
461  *
462  * Since: 0.10.26
463  */
464 /**
465  * gst_byte_writer_put_uint16_be:
466  * @writer: #GstByteWriter instance
467  * @val: Value to write
468  *
469  * Writes a unsigned big endian 16 bit integer to @writer.
470  *
471  * Returns: %TRUE if the value could be written
472  *
473  * Since: 0.10.26
474  */
475 /**
476  * gst_byte_writer_put_uint24_be:
477  * @writer: #GstByteWriter instance
478  * @val: Value to write
479  *
480  * Writes a unsigned big endian 24 bit integer to @writer.
481  *
482  * Returns: %TRUE if the value could be written
483  *
484  * Since: 0.10.26
485  */
486 /**
487  * gst_byte_writer_put_uint32_be:
488  * @writer: #GstByteWriter instance
489  * @val: Value to write
490  *
491  * Writes a unsigned big endian 32 bit integer to @writer.
492  *
493  * Returns: %TRUE if the value could be written
494  *
495  * Since: 0.10.26
496  */
497 /**
498  * gst_byte_writer_put_uint64_be:
499  * @writer: #GstByteWriter instance
500  * @val: Value to write
501  *
502  * Writes a unsigned big endian 64 bit integer to @writer.
503  *
504  * Returns: %TRUE if the value could be written
505  *
506  * Since: 0.10.26
507  */
508 /**
509  * gst_byte_writer_put_uint16_le:
510  * @writer: #GstByteWriter instance
511  * @val: Value to write
512  *
513  * Writes a unsigned little endian 16 bit integer to @writer.
514  *
515  * Returns: %TRUE if the value could be written
516  *
517  * Since: 0.10.26
518  */
519 /**
520  * gst_byte_writer_put_uint24_le:
521  * @writer: #GstByteWriter instance
522  * @val: Value to write
523  *
524  * Writes a unsigned little endian 24 bit integer to @writer.
525  *
526  * Returns: %TRUE if the value could be written
527  *
528  * Since: 0.10.26
529  */
530 /**
531  * gst_byte_writer_put_uint32_le:
532  * @writer: #GstByteWriter instance
533  * @val: Value to write
534  *
535  * Writes a unsigned little endian 32 bit integer to @writer.
536  *
537  * Returns: %TRUE if the value could be written
538  *
539  * Since: 0.10.26
540  */
541 /**
542  * gst_byte_writer_put_uint64_le:
543  * @writer: #GstByteWriter instance
544  * @val: Value to write
545  *
546  * Writes a unsigned little endian 64 bit integer to @writer.
547  *
548  * Returns: %TRUE if the value could be written
549  *
550  * Since: 0.10.26
551  */
552 /**
553  * gst_byte_writer_put_int8:
554  * @writer: #GstByteWriter instance
555  * @val: Value to write
556  *
557  * Writes a signed 8 bit integer to @writer.
558  *
559  * Returns: %TRUE if the value could be written
560  *
561  * Since: 0.10.26
562  */
563 /**
564  * gst_byte_writer_put_int16_be:
565  * @writer: #GstByteWriter instance
566  * @val: Value to write
567  *
568  * Writes a signed big endian 16 bit integer to @writer.
569  *
570  * Returns: %TRUE if the value could be written
571  *
572  * Since: 0.10.26
573  */
574 /**
575  * gst_byte_writer_put_int24_be:
576  * @writer: #GstByteWriter instance
577  * @val: Value to write
578  *
579  * Writes a signed big endian 24 bit integer to @writer.
580  *
581  * Returns: %TRUE if the value could be written
582  *
583  * Since: 0.10.26
584  */
585 /**
586  * gst_byte_writer_put_int32_be:
587  * @writer: #GstByteWriter instance
588  * @val: Value to write
589  *
590  * Writes a signed big endian 32 bit integer to @writer.
591  *
592  * Returns: %TRUE if the value could be written
593  *
594  * Since: 0.10.26
595  */
596 /**
597  * gst_byte_writer_put_int64_be:
598  * @writer: #GstByteWriter instance
599  * @val: Value to write
600  *
601  * Writes a signed big endian 64 bit integer to @writer.
602  *
603  * Returns: %TRUE if the value could be written
604  *
605  * Since: 0.10.26
606  */
607 /**
608  * gst_byte_writer_put_int16_le:
609  * @writer: #GstByteWriter instance
610  * @val: Value to write
611  *
612  * Writes a signed little endian 16 bit integer to @writer.
613  *
614  * Returns: %TRUE if the value could be written
615  *
616  * Since: 0.10.26
617  */
618 /**
619  * gst_byte_writer_put_int24_le:
620  * @writer: #GstByteWriter instance
621  * @val: Value to write
622  *
623  * Writes a signed little endian 24 bit integer to @writer.
624  *
625  * Returns: %TRUE if the value could be written
626  *
627  * Since: 0.10.26
628  */
629 /**
630  * gst_byte_writer_put_int32_le:
631  * @writer: #GstByteWriter instance
632  * @val: Value to write
633  *
634  * Writes a signed little endian 32 bit integer to @writer.
635  *
636  * Returns: %TRUE if the value could be written
637  *
638  * Since: 0.10.26
639  */
640 /**
641  * gst_byte_writer_put_int64_le:
642  * @writer: #GstByteWriter instance
643  * @val: Value to write
644  *
645  * Writes a signed little endian 64 bit integer to @writer.
646  *
647  * Returns: %TRUE if the value could be written
648  *
649  * Since: 0.10.26
650  */
651 /**
652  * gst_byte_writer_put_float32_be:
653  * @writer: #GstByteWriter instance
654  * @val: Value to write
655  *
656  * Writes a big endian 32 bit float to @writer.
657  *
658  * Returns: %TRUE if the value could be written
659  *
660  * Since: 0.10.27
661  */
662 /**
663  * gst_byte_writer_put_float64_be:
664  * @writer: #GstByteWriter instance
665  * @val: Value to write
666  *
667  * Writes a big endian 64 bit float to @writer.
668  *
669  * Returns: %TRUE if the value could be written
670  *
671  * Since: 0.10.27
672  */
673 /**
674  * gst_byte_writer_put_float32_le:
675  * @writer: #GstByteWriter instance
676  * @val: Value to write
677  *
678  * Writes a little endian 32 bit float to @writer.
679  *
680  * Returns: %TRUE if the value could be written
681  *
682  * Since: 0.10.27
683  */
684 /**
685  * gst_byte_writer_put_float64_le:
686  * @writer: #GstByteWriter instance
687  * @val: Value to write
688  *
689  * Writes a little endian 64 bit float to @writer.
690  *
691  * Returns: %TRUE if the value could be written
692  *
693  * Since: 0.10.27
694  */
695 /**
696  * gst_byte_writer_put_string_utf8:
697  * @writer: #GstByteWriter instance
698  * @data: (transfer none) (array zero-terminated=1) (type utf8): UTF8 string to
699  *     write
700  *
701  * Writes a NUL-terminated UTF8 string to @writer (including the terminator).
702  *
703  * Returns: %TRUE if the value could be written
704  *
705  * Since: 0.10.26
706  */
707 /**
708  * gst_byte_writer_put_string_utf16:
709  * @writer: #GstByteWriter instance
710  * @data: (transfer none) (array zero-terminated=1): UTF16 string to write
711  *
712  * Writes a NUL-terminated UTF16 string to @writer (including the terminator).
713  *
714  * Returns: %TRUE if the value could be written
715  *
716  * Since: 0.10.26
717  */
718 /**
719  * gst_byte_writer_put_string_utf32:
720  * @writer: #GstByteWriter instance
721  * @data: (transfer none) (array zero-terminated=1): UTF32 string to write
722  *
723  * Writes a NUL-terminated UTF32 string to @writer (including the terminator).
724  *
725  * Returns: %TRUE if the value could be written
726  *
727  * Since: 0.10.26
728  */
729 /**
730  * gst_byte_writer_put_data:
731  * @writer: #GstByteWriter instance
732  * @data: (transfer none) (array length=size): Data to write
733  * @size: Size of @data in bytes
734  *
735  * Writes @size bytes of @data to @writer.
736  *
737  * Returns: %TRUE if the value could be written
738  *
739  * Since: 0.10.26
740  */
741 /**
742  * gst_byte_writer_fill:
743  * @writer: #GstByteWriter instance
744  * @value: Value to be writen
745  * @size: Number of bytes to be writen
746  *
747  * Writes @size bytes containing @value to @writer.
748  *
749  * Returns: %TRUE if the value could be written
750  *
751  * Since: 0.10.27
752  */