Initialize Tizen 2.3
[framework/multimedia/gstreamer0.10.git] / mobile / libs / gst / base / gstbytereader.c
1 /* GStreamer byte reader
2  *
3  * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
4  * Copyright (C) 2009 Tim-Philipp Müller <tim centricular net>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #define GST_BYTE_READER_DISABLE_INLINES
27 #include "gstbytereader.h"
28
29 #include <string.h>
30
31 /**
32  * SECTION:gstbytereader
33  * @short_description: Reads different integer, string and floating point
34  *     types from a memory buffer
35  *
36  * #GstByteReader provides a byte reader that can read different integer and
37  * floating point types from a memory buffer. It provides functions for reading
38  * signed/unsigned, little/big endian integers of 8, 16, 24, 32 and 64 bits
39  * and functions for reading little/big endian floating points numbers of
40  * 32 and 64 bits. It also provides functions to read NUL-terminated strings
41  * in various character encodings.
42  */
43
44 /**
45  * gst_byte_reader_new:
46  * @data: (in) (transfer none) (array length=size): data from which the
47  *     #GstByteReader should read
48  * @size: Size of @data in bytes
49  *
50  * Create a new #GstByteReader instance, which will read from @data.
51  *
52  * Free-function: gst_byte_reader_free
53  *
54  * Returns: (transfer full): a new #GstByteReader instance
55  *
56  * Since: 0.10.22
57  */
58 GstByteReader *
59 gst_byte_reader_new (const guint8 * data, guint size)
60 {
61   GstByteReader *ret = g_slice_new0 (GstByteReader);
62
63   ret->data = data;
64   ret->size = size;
65
66   return ret;
67 }
68
69 /**
70  * gst_byte_reader_new_from_buffer:
71  * @buffer: (transfer none): Buffer from which the #GstByteReader should read
72  *
73  * Create a new #GstByteReader instance, which will read from the
74  * #GstBuffer @buffer.
75  *
76  * Free-function: gst_byte_reader_free
77  *
78  * Returns: (transfer full): a new #GstByteReader instance
79  *
80  * Since: 0.10.22
81  */
82 GstByteReader *
83 gst_byte_reader_new_from_buffer (const GstBuffer * buffer)
84 {
85   g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
86
87   return gst_byte_reader_new (GST_BUFFER_DATA (buffer),
88       GST_BUFFER_SIZE (buffer));
89 }
90
91 /**
92  * gst_byte_reader_free:
93  * @reader: (in) (transfer full): a #GstByteReader instance
94  *
95  * Frees a #GstByteReader instance, which was previously allocated by
96  * gst_byte_reader_new() or gst_byte_reader_new_from_buffer().
97  * 
98  * Since: 0.10.22
99  */
100 void
101 gst_byte_reader_free (GstByteReader * reader)
102 {
103   g_return_if_fail (reader != NULL);
104
105   g_slice_free (GstByteReader, reader);
106 }
107
108 /**
109  * gst_byte_reader_init:
110  * @reader: a #GstByteReader instance
111  * @data: (in) (transfer none) (array length=size): data from which
112  *     the #GstByteReader should read
113  * @size: Size of @data in bytes
114  *
115  * Initializes a #GstByteReader instance to read from @data. This function
116  * can be called on already initialized instances.
117  * 
118  * Since: 0.10.22
119  */
120 void
121 gst_byte_reader_init (GstByteReader * reader, const guint8 * data, guint size)
122 {
123   g_return_if_fail (reader != NULL);
124
125   reader->data = data;
126   reader->size = size;
127   reader->byte = 0;
128 }
129
130 /**
131  * gst_byte_reader_init_from_buffer:
132  * @reader: a #GstByteReader instance
133  * @buffer: (transfer none): Buffer from which the #GstByteReader should read
134  *
135  * Initializes a #GstByteReader instance to read from @buffer. This function
136  * can be called on already initialized instances.
137  * 
138  * Since: 0.10.22
139  */
140 void
141 gst_byte_reader_init_from_buffer (GstByteReader * reader,
142     const GstBuffer * buffer)
143 {
144   g_return_if_fail (GST_IS_BUFFER (buffer));
145
146   gst_byte_reader_init (reader, GST_BUFFER_DATA (buffer),
147       GST_BUFFER_SIZE (buffer));
148 }
149
150 /**
151  * gst_byte_reader_set_pos:
152  * @reader: a #GstByteReader instance
153  * @pos: The new position in bytes
154  *
155  * Sets the new position of a #GstByteReader instance to @pos in bytes.
156  *
157  * Returns: %TRUE if the position could be set successfully, %FALSE
158  * otherwise.
159  * 
160  * Since: 0.10.22
161  */
162 gboolean
163 gst_byte_reader_set_pos (GstByteReader * reader, guint pos)
164 {
165   g_return_val_if_fail (reader != NULL, FALSE);
166
167   if (pos > reader->size)
168     return FALSE;
169
170   reader->byte = pos;
171
172   return TRUE;
173 }
174
175 /**
176  * gst_byte_reader_get_pos:
177  * @reader: a #GstByteReader instance
178  *
179  * Returns the current position of a #GstByteReader instance in bytes.
180  *
181  * Returns: The current position of @reader in bytes.
182  * 
183  * Since: 0.10.22
184  */
185 guint
186 gst_byte_reader_get_pos (const GstByteReader * reader)
187 {
188   return _gst_byte_reader_get_pos_inline (reader);
189 }
190
191 /**
192  * gst_byte_reader_get_remaining:
193  * @reader: a #GstByteReader instance
194  *
195  * Returns the remaining number of bytes of a #GstByteReader instance.
196  *
197  * Returns: The remaining number of bytes of @reader instance.
198  * 
199  * Since: 0.10.22
200  */
201 guint
202 gst_byte_reader_get_remaining (const GstByteReader * reader)
203 {
204   return _gst_byte_reader_get_remaining_inline (reader);
205 }
206
207 /**
208  * gst_byte_reader_get_size:
209  * @reader: a #GstByteReader instance
210  *
211  * Returns the total number of bytes of a #GstByteReader instance.
212  *
213  * Returns: The total number of bytes of @reader instance.
214  * 
215  * Since: 0.10.26
216  */
217 guint
218 gst_byte_reader_get_size (const GstByteReader * reader)
219 {
220   return _gst_byte_reader_get_size_inline (reader);
221 }
222
223 #define gst_byte_reader_get_remaining _gst_byte_reader_get_remaining_inline
224 #define gst_byte_reader_get_size _gst_byte_reader_get_size_inline
225
226 /**
227  * gst_byte_reader_skip:
228  * @reader: a #GstByteReader instance
229  * @nbytes: the number of bytes to skip
230  *
231  * Skips @nbytes bytes of the #GstByteReader instance.
232  *
233  * Returns: %TRUE if @nbytes bytes could be skipped, %FALSE otherwise.
234  * 
235  * Since: 0.10.22
236  */
237 gboolean
238 gst_byte_reader_skip (GstByteReader * reader, guint nbytes)
239 {
240   return _gst_byte_reader_skip_inline (reader, nbytes);
241 }
242
243 /**
244  * gst_byte_reader_get_uint8:
245  * @reader: a #GstByteReader instance
246  * @val: (out): Pointer to a #guint8 to store the result
247  *
248  * Read an unsigned 8 bit integer into @val and update the current position.
249  *
250  * Returns: %TRUE if successful, %FALSE otherwise.
251  * 
252  * Since: 0.10.22
253  */
254
255 /**
256  * gst_byte_reader_get_int8:
257  * @reader: a #GstByteReader instance
258  * @val: (out): Pointer to a #gint8 to store the result
259  *
260  * Read a signed 8 bit integer into @val and update the current position.
261  *
262  * Returns: %TRUE if successful, %FALSE otherwise.
263  * 
264  * Since: 0.10.22
265  */
266
267 /**
268  * gst_byte_reader_peek_uint8:
269  * @reader: a #GstByteReader instance
270  * @val: (out): Pointer to a #guint8 to store the result
271  *
272  * Read an unsigned 8 bit integer into @val but keep the current position.
273  *
274  * Returns: %TRUE if successful, %FALSE otherwise.
275  * 
276  * Since: 0.10.22
277  */
278
279 /**
280  * gst_byte_reader_peek_int8:
281  * @reader: a #GstByteReader instance
282  * @val: (out): Pointer to a #gint8 to store the result
283  *
284  * Read a signed 8 bit integer into @val but keep the current position.
285  *
286  * Returns: %TRUE if successful, %FALSE otherwise.
287  * 
288  * Since: 0.10.22
289  */
290
291 /**
292  * gst_byte_reader_get_uint16_le:
293  * @reader: a #GstByteReader instance
294  * @val: (out): Pointer to a #guint16 to store the result
295  *
296  * Read an unsigned 16 bit little endian integer into @val
297  * and update the current position.
298  *
299  * Returns: %TRUE if successful, %FALSE otherwise.
300  * 
301  * Since: 0.10.22
302  */
303
304 /**
305  * gst_byte_reader_get_int16_le:
306  * @reader: a #GstByteReader instance
307  * @val: (out): Pointer to a #gint16 to store the result
308  *
309  * Read a signed 16 bit little endian integer into @val
310  * and update the current position.
311  *
312  * Returns: %TRUE if successful, %FALSE otherwise.
313  * 
314  * Since: 0.10.22
315  */
316
317 /**
318  * gst_byte_reader_peek_uint16_le:
319  * @reader: a #GstByteReader instance
320  * @val: (out): Pointer to a #guint16 to store the result
321  *
322  * Read an unsigned 16 bit little endian integer into @val
323  * but keep the current position.
324  *
325  * Returns: %TRUE if successful, %FALSE otherwise.
326  * 
327  * Since: 0.10.22
328  */
329
330 /**
331  * gst_byte_reader_peek_int16_le:
332  * @reader: a #GstByteReader instance
333  * @val: (out): Pointer to a #gint16 to store the result
334  *
335  * Read a signed 16 bit little endian integer into @val
336  * but keep the current position.
337  *
338  * Returns: %TRUE if successful, %FALSE otherwise.
339  * 
340  * Since: 0.10.22
341  */
342
343 /**
344  * gst_byte_reader_get_uint16_be:
345  * @reader: a #GstByteReader instance
346  * @val: (out): Pointer to a #guint16 to store the result
347  *
348  * Read an unsigned 16 bit big endian integer into @val
349  * and update the current position.
350  *
351  * Returns: %TRUE if successful, %FALSE otherwise.
352  * 
353  * Since: 0.10.22
354  */
355
356 /**
357  * gst_byte_reader_get_int16_be:
358  * @reader: a #GstByteReader instance
359  * @val: (out): Pointer to a #gint16 to store the result
360  *
361  * Read a signed 16 bit big endian integer into @val
362  * and update the current position.
363  *
364  * Returns: %TRUE if successful, %FALSE otherwise.
365  * 
366  * Since: 0.10.22
367  */
368
369 /**
370  * gst_byte_reader_peek_uint16_be:
371  * @reader: a #GstByteReader instance
372  * @val: (out): Pointer to a #guint16 to store the result
373  *
374  * Read an unsigned 16 bit big endian integer into @val
375  * but keep the current position.
376  *
377  * Returns: %TRUE if successful, %FALSE otherwise.
378  * 
379  * Since: 0.10.22
380  */
381
382 /**
383  * gst_byte_reader_peek_int16_be:
384  * @reader: a #GstByteReader instance
385  * @val: (out): Pointer to a #gint16 to store the result
386  *
387  * Read a signed 16 bit big endian integer into @val
388  * but keep the current position.
389  *
390  * Returns: %TRUE if successful, %FALSE otherwise.
391  * 
392  * Since: 0.10.22
393  */
394
395 /**
396  * gst_byte_reader_get_uint24_le:
397  * @reader: a #GstByteReader instance
398  * @val: (out): Pointer to a #guint32 to store the result
399  *
400  * Read an unsigned 24 bit little endian integer into @val
401  * and update the current position.
402  *
403  * Returns: %TRUE if successful, %FALSE otherwise.
404  * 
405  * Since: 0.10.22
406  */
407
408 /**
409  * gst_byte_reader_get_int24_le:
410  * @reader: a #GstByteReader instance
411  * @val: (out): Pointer to a #gint32 to store the result
412  *
413  * Read a signed 24 bit little endian integer into @val
414  * and update the current position.
415  *
416  * Returns: %TRUE if successful, %FALSE otherwise.
417  * 
418  * Since: 0.10.22
419  */
420
421 /**
422  * gst_byte_reader_peek_uint24_le:
423  * @reader: a #GstByteReader instance
424  * @val: (out): Pointer to a #guint32 to store the result
425  *
426  * Read an unsigned 24 bit little endian integer into @val
427  * but keep the current position.
428  *
429  * Returns: %TRUE if successful, %FALSE otherwise.
430  * 
431  * Since: 0.10.22
432  */
433
434 /**
435  * gst_byte_reader_peek_int24_le:
436  * @reader: a #GstByteReader instance
437  * @val: (out): Pointer to a #gint32 to store the result
438  *
439  * Read a signed 24 bit little endian integer into @val
440  * but keep the current position.
441  *
442  * Returns: %TRUE if successful, %FALSE otherwise.
443  * 
444  * Since: 0.10.22
445  */
446
447 /**
448  * gst_byte_reader_get_uint24_be:
449  * @reader: a #GstByteReader instance
450  * @val: (out): Pointer to a #guint32 to store the result
451  *
452  * Read an unsigned 24 bit big endian integer into @val
453  * and update the current position.
454  *
455  * Returns: %TRUE if successful, %FALSE otherwise.
456  * 
457  * Since: 0.10.22
458  */
459
460 /**
461  * gst_byte_reader_get_int24_be:
462  * @reader: a #GstByteReader instance
463  * @val: (out): Pointer to a #gint32 to store the result
464  *
465  * Read a signed 24 bit big endian integer into @val
466  * and update the current position.
467  *
468  * Returns: %TRUE if successful, %FALSE otherwise.
469  * 
470  * Since: 0.10.22
471  */
472
473 /**
474  * gst_byte_reader_peek_uint24_be:
475  * @reader: a #GstByteReader instance
476  * @val: (out): Pointer to a #guint32 to store the result
477  *
478  * Read an unsigned 24 bit big endian integer into @val
479  * but keep the current position.
480  *
481  * Returns: %TRUE if successful, %FALSE otherwise.
482  * 
483  * Since: 0.10.22
484  */
485
486 /**
487  * gst_byte_reader_peek_int24_be:
488  * @reader: a #GstByteReader instance
489  * @val: (out): Pointer to a #gint32 to store the result
490  *
491  * Read a signed 24 bit big endian integer into @val
492  * but keep the current position.
493  *
494  * Returns: %TRUE if successful, %FALSE otherwise.
495  * 
496  * Since: 0.10.22
497  */
498
499
500 /**
501  * gst_byte_reader_get_uint32_le:
502  * @reader: a #GstByteReader instance
503  * @val: (out): Pointer to a #guint32 to store the result
504  *
505  * Read an unsigned 32 bit little endian integer into @val
506  * and update the current position.
507  *
508  * Returns: %TRUE if successful, %FALSE otherwise.
509  * 
510  * Since: 0.10.22
511  */
512
513 /**
514  * gst_byte_reader_get_int32_le:
515  * @reader: a #GstByteReader instance
516  * @val: (out): Pointer to a #gint32 to store the result
517  *
518  * Read a signed 32 bit little endian integer into @val
519  * and update the current position.
520  *
521  * Returns: %TRUE if successful, %FALSE otherwise.
522  * 
523  * Since: 0.10.22
524  */
525
526 /**
527  * gst_byte_reader_peek_uint32_le:
528  * @reader: a #GstByteReader instance
529  * @val: (out): Pointer to a #guint32 to store the result
530  *
531  * Read an unsigned 32 bit little endian integer into @val
532  * but keep the current position.
533  *
534  * Returns: %TRUE if successful, %FALSE otherwise.
535  * 
536  * Since: 0.10.22
537  */
538
539 /**
540  * gst_byte_reader_peek_int32_le:
541  * @reader: a #GstByteReader instance
542  * @val: (out): Pointer to a #gint32 to store the result
543  *
544  * Read a signed 32 bit little endian integer into @val
545  * but keep the current position.
546  *
547  * Returns: %TRUE if successful, %FALSE otherwise.
548  * 
549  * Since: 0.10.22
550  */
551
552 /**
553  * gst_byte_reader_get_uint32_be:
554  * @reader: a #GstByteReader instance
555  * @val: (out): Pointer to a #guint32 to store the result
556  *
557  * Read an unsigned 32 bit big endian integer into @val
558  * and update the current position.
559  *
560  * Returns: %TRUE if successful, %FALSE otherwise.
561  * 
562  * Since: 0.10.22
563  */
564
565 /**
566  * gst_byte_reader_get_int32_be:
567  * @reader: a #GstByteReader instance
568  * @val: (out): Pointer to a #gint32 to store the result
569  *
570  * Read a signed 32 bit big endian integer into @val
571  * and update the current position.
572  *
573  * Returns: %TRUE if successful, %FALSE otherwise.
574  * 
575  * Since: 0.10.22
576  */
577
578 /**
579  * gst_byte_reader_peek_uint32_be:
580  * @reader: a #GstByteReader instance
581  * @val: (out): Pointer to a #guint32 to store the result
582  *
583  * Read an unsigned 32 bit big endian integer into @val
584  * but keep the current position.
585  *
586  * Returns: %TRUE if successful, %FALSE otherwise.
587  * 
588  * Since: 0.10.22
589  */
590
591 /**
592  * gst_byte_reader_peek_int32_be:
593  * @reader: a #GstByteReader instance
594  * @val: (out): Pointer to a #gint32 to store the result
595  *
596  * Read a signed 32 bit big endian integer into @val
597  * but keep the current position.
598  *
599  * Returns: %TRUE if successful, %FALSE otherwise.
600  * 
601  * Since: 0.10.22
602  */
603
604 /**
605  * gst_byte_reader_get_uint64_le:
606  * @reader: a #GstByteReader instance
607  * @val: (out): Pointer to a #guint64 to store the result
608  *
609  * Read an unsigned 64 bit little endian integer into @val
610  * and update the current position.
611  *
612  * Returns: %TRUE if successful, %FALSE otherwise.
613  * 
614  * Since: 0.10.22
615  */
616
617 /**
618  * gst_byte_reader_get_int64_le:
619  * @reader: a #GstByteReader instance
620  * @val: (out): Pointer to a #gint64 to store the result
621  *
622  * Read a signed 64 bit little endian integer into @val
623  * and update the current position.
624  *
625  * Returns: %TRUE if successful, %FALSE otherwise.
626  * 
627  * Since: 0.10.22
628  */
629
630 /**
631  * gst_byte_reader_peek_uint64_le:
632  * @reader: a #GstByteReader instance
633  * @val: (out): Pointer to a #guint64 to store the result
634  *
635  * Read an unsigned 64 bit little endian integer into @val
636  * but keep the current position.
637  *
638  * Returns: %TRUE if successful, %FALSE otherwise.
639  * 
640  * Since: 0.10.22
641  */
642
643 /**
644  * gst_byte_reader_peek_int64_le:
645  * @reader: a #GstByteReader instance
646  * @val: (out): Pointer to a #gint64 to store the result
647  *
648  * Read a signed 64 bit little endian integer into @val
649  * but keep the current position.
650  *
651  * Returns: %TRUE if successful, %FALSE otherwise.
652  * 
653  * Since: 0.10.22
654  */
655
656 /**
657  * gst_byte_reader_get_uint64_be:
658  * @reader: a #GstByteReader instance
659  * @val: (out): Pointer to a #guint64 to store the result
660  *
661  * Read an unsigned 64 bit big endian integer into @val
662  * and update the current position.
663  *
664  * Returns: %TRUE if successful, %FALSE otherwise.
665  * 
666  * Since: 0.10.22
667  */
668
669 /**
670  * gst_byte_reader_get_int64_be:
671  * @reader: a #GstByteReader instance
672  * @val: (out): Pointer to a #gint64 to store the result
673  *
674  * Read a signed 64 bit big endian integer into @val
675  * and update the current position.
676  *
677  * Returns: %TRUE if successful, %FALSE otherwise.
678  * 
679  * Since: 0.10.22
680  */
681
682 /**
683  * gst_byte_reader_peek_uint64_be:
684  * @reader: a #GstByteReader instance
685  * @val: (out): Pointer to a #guint64 to store the result
686  *
687  * Read an unsigned 64 bit big endian integer into @val
688  * but keep the current position.
689  *
690  * Returns: %TRUE if successful, %FALSE otherwise.
691  * 
692  * Since: 0.10.22
693  */
694
695 /**
696  * gst_byte_reader_peek_int64_be:
697  * @reader: a #GstByteReader instance
698  * @val: (out): Pointer to a #gint64 to store the result
699  *
700  * Read a signed 64 bit big endian integer into @val
701  * but keep the current position.
702  *
703  * Returns: %TRUE if successful, %FALSE otherwise.
704  * 
705  * Since: 0.10.22
706  */
707
708 #define GST_BYTE_READER_PEEK_GET(bits,type,name) \
709 gboolean \
710 gst_byte_reader_get_##name (GstByteReader * reader, type * val) \
711 { \
712   return _gst_byte_reader_get_##name##_inline (reader, val); \
713 } \
714 \
715 gboolean \
716 gst_byte_reader_peek_##name (const GstByteReader * reader, type * val) \
717 { \
718   return _gst_byte_reader_peek_##name##_inline (reader, val); \
719 }
720
721 /* *INDENT-OFF* */
722
723 GST_BYTE_READER_PEEK_GET(8,guint8,uint8)
724 GST_BYTE_READER_PEEK_GET(8,gint8,int8)
725
726 GST_BYTE_READER_PEEK_GET(16,guint16,uint16_le)
727 GST_BYTE_READER_PEEK_GET(16,guint16,uint16_be)
728 GST_BYTE_READER_PEEK_GET(16,gint16,int16_le)
729 GST_BYTE_READER_PEEK_GET(16,gint16,int16_be)
730
731 GST_BYTE_READER_PEEK_GET(24,guint32,uint24_le)
732 GST_BYTE_READER_PEEK_GET(24,guint32,uint24_be)
733 GST_BYTE_READER_PEEK_GET(24,gint32,int24_le)
734 GST_BYTE_READER_PEEK_GET(24,gint32,int24_be)
735
736 GST_BYTE_READER_PEEK_GET(32,guint32,uint32_le)
737 GST_BYTE_READER_PEEK_GET(32,guint32,uint32_be)
738 GST_BYTE_READER_PEEK_GET(32,gint32,int32_le)
739 GST_BYTE_READER_PEEK_GET(32,gint32,int32_be)
740
741 GST_BYTE_READER_PEEK_GET(64,guint64,uint64_le)
742 GST_BYTE_READER_PEEK_GET(64,guint64,uint64_be)
743 GST_BYTE_READER_PEEK_GET(64,gint64,int64_le)
744 GST_BYTE_READER_PEEK_GET(64,gint64,int64_be)
745
746 /**
747  * gst_byte_reader_get_float32_le:
748  * @reader: a #GstByteReader instance
749  * @val: (out): Pointer to a #gfloat to store the result
750  *
751  * Read a 32 bit little endian floating point value into @val
752  * and update the current position.
753  *
754  * Returns: %TRUE if successful, %FALSE otherwise.
755  * 
756  * Since: 0.10.22
757  */
758
759 /**
760  * gst_byte_reader_peek_float32_le:
761  * @reader: a #GstByteReader instance
762  * @val: (out): Pointer to a #gfloat to store the result
763  *
764  * Read a 32 bit little endian floating point value into @val
765  * but keep the current position.
766  *
767  * Returns: %TRUE if successful, %FALSE otherwise.
768  * 
769  * Since: 0.10.22
770  */
771
772 /**
773  * gst_byte_reader_get_float32_be:
774  * @reader: a #GstByteReader instance
775  * @val: (out): Pointer to a #gfloat to store the result
776  *
777  * Read a 32 bit big endian floating point value into @val
778  * and update the current position.
779  *
780  * Returns: %TRUE if successful, %FALSE otherwise.
781  * 
782  * Since: 0.10.22
783  */
784
785 /**
786  * gst_byte_reader_peek_float32_be:
787  * @reader: a #GstByteReader instance
788  * @val: (out): Pointer to a #gfloat to store the result
789  *
790  * Read a 32 bit big endian floating point value into @val
791  * but keep the current position.
792  *
793  * Returns: %TRUE if successful, %FALSE otherwise.
794  * 
795  * Since: 0.10.22
796  */
797
798 /**
799  * gst_byte_reader_get_float64_le:
800  * @reader: a #GstByteReader instance
801  * @val: (out): Pointer to a #gdouble to store the result
802  *
803  * Read a 64 bit little endian floating point value into @val
804  * and update the current position.
805  *
806  * Returns: %TRUE if successful, %FALSE otherwise.
807  * 
808  * Since: 0.10.22
809  */
810
811 /**
812  * gst_byte_reader_peek_float64_le:
813  * @reader: a #GstByteReader instance
814  * @val: (out): Pointer to a #gdouble to store the result
815  *
816  * Read a 64 bit little endian floating point value into @val
817  * but keep the current position.
818  *
819  * Returns: %TRUE if successful, %FALSE otherwise.
820  * 
821  * Since: 0.10.22
822  */
823
824 /**
825  * gst_byte_reader_get_float64_be:
826  * @reader: a #GstByteReader instance
827  * @val: (out): Pointer to a #gdouble to store the result
828  *
829  * Read a 64 bit big endian floating point value into @val
830  * and update the current position.
831  *
832  * Returns: %TRUE if successful, %FALSE otherwise.
833  * 
834  * Since: 0.10.22
835  */
836
837 /**
838  * gst_byte_reader_peek_float64_be:
839  * @reader: a #GstByteReader instance
840  * @val: (out): Pointer to a #gdouble to store the result
841  *
842  * Read a 64 bit big endian floating point value into @val
843  * but keep the current position.
844  *
845  * Returns: %TRUE if successful, %FALSE otherwise.
846  * 
847  * Since: 0.10.22
848  */
849
850 GST_BYTE_READER_PEEK_GET(32,gfloat,float32_le)
851 GST_BYTE_READER_PEEK_GET(32,gfloat,float32_be)
852 GST_BYTE_READER_PEEK_GET(64,gdouble,float64_le)
853 GST_BYTE_READER_PEEK_GET(64,gdouble,float64_be)
854
855 /* *INDENT-ON* */
856
857 /**
858  * gst_byte_reader_get_data:
859  * @reader: a #GstByteReader instance
860  * @size: Size in bytes
861  * @val: (out) (transfer none) (array length=size): address of a
862  *     #guint8 pointer variable in which to store the result
863  *
864  * Returns a constant pointer to the current data
865  * position if at least @size bytes are left and
866  * updates the current position.
867  *
868  *
869  * Returns: %TRUE if successful, %FALSE otherwise.
870  * 
871  * Since: 0.10.22
872  */
873 gboolean
874 gst_byte_reader_get_data (GstByteReader * reader, guint size,
875     const guint8 ** val)
876 {
877   return _gst_byte_reader_get_data_inline (reader, size, val);
878 }
879
880 /**
881  * gst_byte_reader_peek_data:
882  * @reader: a #GstByteReader instance
883  * @size: Size in bytes
884  * @val: (out) (transfer none) (array length=size): address of a
885  *     #guint8 pointer variable in which to store the result
886  *
887  * Returns a constant pointer to the current data
888  * position if at least @size bytes are left and
889  * keeps the current position.
890  *
891  *
892  * Returns: %TRUE if successful, %FALSE otherwise.
893  * 
894  * Since: 0.10.22
895  */
896 gboolean
897 gst_byte_reader_peek_data (const GstByteReader * reader, guint size,
898     const guint8 ** val)
899 {
900   return _gst_byte_reader_peek_data_inline (reader, size, val);
901 }
902
903 /**
904  * gst_byte_reader_dup_data:
905  * @reader: a #GstByteReader instance
906  * @size: Size in bytes
907  * @val: (out) (transfer full) (array length=size): address of a
908  *     #guint8 pointer variable in which to store the result
909  *
910  * Free-function: g_free
911  *
912  * Returns a newly-allocated copy of the current data
913  * position if at least @size bytes are left and
914  * updates the current position. Free with g_free() when no longer needed.
915  *
916  * Returns: %TRUE if successful, %FALSE otherwise.
917  *
918  * Since: 0.10.24
919  */
920 gboolean
921 gst_byte_reader_dup_data (GstByteReader * reader, guint size, guint8 ** val)
922 {
923   return _gst_byte_reader_dup_data_inline (reader, size, val);
924 }
925
926 /**
927  * gst_byte_reader_masked_scan_uint32:
928  * @reader: a #GstByteReader
929  * @mask: mask to apply to data before matching against @pattern
930  * @pattern: pattern to match (after mask is applied)
931  * @offset: offset from which to start scanning, relative to the current
932  *     position
933  * @size: number of bytes to scan from offset
934  *
935  * Scan for pattern @pattern with applied mask @mask in the byte reader data,
936  * starting from offset @offset relative to the current position.
937  *
938  * The bytes in @pattern and @mask are interpreted left-to-right, regardless
939  * of endianness.  All four bytes of the pattern must be present in the
940  * byte reader data for it to match, even if the first or last bytes are masked
941  * out.
942  *
943  * It is an error to call this function without making sure that there is
944  * enough data (offset+size bytes) in the byte reader.
945  *
946  * Returns: offset of the first match, or -1 if no match was found.
947  *
948  * Example:
949  * <programlisting>
950  * // Assume the reader contains 0x00 0x01 0x02 ... 0xfe 0xff
951  *
952  * gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0x00010203, 0, 256);
953  * // -> returns 0
954  * gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0x00010203, 1, 255);
955  * // -> returns -1
956  * gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0x01020304, 1, 255);
957  * // -> returns 1
958  * gst_byte_reader_masked_scan_uint32 (reader, 0xffff, 0x0001, 0, 256);
959  * // -> returns -1
960  * gst_byte_reader_masked_scan_uint32 (reader, 0xffff, 0x0203, 0, 256);
961  * // -> returns 0
962  * gst_byte_reader_masked_scan_uint32 (reader, 0xffff0000, 0x02030000, 0, 256);
963  * // -> returns 2
964  * gst_byte_reader_masked_scan_uint32 (reader, 0xffff0000, 0x02030000, 0, 4);
965  * // -> returns -1
966  * </programlisting>
967  *
968  * Since: 0.10.24
969  */
970 guint
971 gst_byte_reader_masked_scan_uint32 (const GstByteReader * reader, guint32 mask,
972     guint32 pattern, guint offset, guint size)
973 {
974   const guint8 *data;
975   guint32 state;
976   guint i;
977
978   g_return_val_if_fail (size > 0, -1);
979   g_return_val_if_fail ((guint64) offset + size <= reader->size - reader->byte,
980       -1);
981
982   /* we can't find the pattern with less than 4 bytes */
983   if (G_UNLIKELY (size < 4))
984     return -1;
985
986   data = reader->data + reader->byte + offset;
987
988   /* set the state to something that does not match */
989   state = ~pattern;
990
991   /* now find data */
992   for (i = 0; i < size; i++) {
993     /* throw away one byte and move in the next byte */
994     state = ((state << 8) | data[i]);
995     if (G_UNLIKELY ((state & mask) == pattern)) {
996       /* we have a match but we need to have skipped at
997        * least 4 bytes to fill the state. */
998       if (G_LIKELY (i >= 3))
999         return offset + i - 3;
1000     }
1001   }
1002
1003   /* nothing found */
1004   return -1;
1005 }
1006
1007 #define GST_BYTE_READER_SCAN_STRING(bits) \
1008 static guint \
1009 gst_byte_reader_scan_string_utf##bits (const GstByteReader * reader) \
1010 { \
1011   guint len, off, max_len; \
1012   \
1013   max_len = (reader->size - reader->byte) / sizeof (guint##bits); \
1014   \
1015   /* need at least a single NUL terminator */ \
1016   if (max_len < 1) \
1017     return 0; \
1018   \
1019   len = 0; \
1020   off = reader->byte; \
1021   /* endianness does not matter if we are looking for a NUL terminator */ \
1022   while (GST_READ_UINT##bits##_LE (&reader->data[off]) != 0) { \
1023     ++len; \
1024     off += sizeof (guint##bits); \
1025     /* have we reached the end without finding a NUL terminator? */ \
1026     if (len == max_len) \
1027       return 0; \
1028   } \
1029   /* return size in bytes including the NUL terminator (hence the +1) */ \
1030   return (len + 1) * sizeof (guint##bits); \
1031 }
1032
1033 #define GST_READ_UINT8_LE GST_READ_UINT8
1034 GST_BYTE_READER_SCAN_STRING (8);
1035 #undef GST_READ_UINT8_LE
1036 GST_BYTE_READER_SCAN_STRING (16);
1037 GST_BYTE_READER_SCAN_STRING (32);
1038
1039 #define GST_BYTE_READER_SKIP_STRING(bits) \
1040 gboolean \
1041 gst_byte_reader_skip_string_utf##bits (GstByteReader * reader) \
1042 { \
1043   guint size; /* size in bytes including the terminator */ \
1044   \
1045   g_return_val_if_fail (reader != NULL, FALSE); \
1046   \
1047   size = gst_byte_reader_scan_string_utf##bits (reader); \
1048   reader->byte += size; \
1049   return (size > 0); \
1050 }
1051
1052 /**
1053  * gst_byte_reader_skip_string:
1054  * @reader: a #GstByteReader instance
1055  *
1056  * Skips a NUL-terminated string in the #GstByteReader instance, advancing
1057  * the current position to the byte after the string. This will work for
1058  * any NUL-terminated string with a character width of 8 bits, so ASCII,
1059  * UTF-8, ISO-8859-N etc.
1060  *
1061  * This function will fail if no NUL-terminator was found in in the data.
1062  *
1063  * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
1064  *
1065  * Since: 0.10.24
1066  */
1067 /**
1068  * gst_byte_reader_skip_string_utf8:
1069  * @reader: a #GstByteReader instance
1070  *
1071  * Skips a NUL-terminated string in the #GstByteReader instance, advancing
1072  * the current position to the byte after the string. This will work for
1073  * any NUL-terminated string with a character width of 8 bits, so ASCII,
1074  * UTF-8, ISO-8859-N etc. No input checking for valid UTF-8 is done.
1075  *
1076  * This function will fail if no NUL-terminator was found in in the data.
1077  *
1078  * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
1079  *
1080  * Since: 0.10.24
1081  */
1082 GST_BYTE_READER_SKIP_STRING (8);
1083
1084 /**
1085  * gst_byte_reader_skip_string_utf16:
1086  * @reader: a #GstByteReader instance
1087  *
1088  * Skips a NUL-terminated UTF-16 string in the #GstByteReader instance,
1089  * advancing the current position to the byte after the string.
1090  *
1091  * No input checking for valid UTF-16 is done.
1092  *
1093  * This function will fail if no NUL-terminator was found in in the data.
1094  *
1095  * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
1096  *
1097  * Since: 0.10.24
1098  */
1099 GST_BYTE_READER_SKIP_STRING (16);
1100
1101 /**
1102  * gst_byte_reader_skip_string_utf32:
1103  * @reader: a #GstByteReader instance
1104  *
1105  * Skips a NUL-terminated UTF-32 string in the #GstByteReader instance,
1106  * advancing the current position to the byte after the string.
1107  *
1108  * No input checking for valid UTF-32 is done.
1109  *
1110  * This function will fail if no NUL-terminator was found in in the data.
1111  *
1112  * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
1113  *
1114  * Since: 0.10.24
1115  */
1116 GST_BYTE_READER_SKIP_STRING (32);
1117
1118 /**
1119  * gst_byte_reader_peek_string:
1120  * @reader: a #GstByteReader instance
1121  * @str: (out) (transfer none) (array zero-terminated=1): address of a
1122  *     #gchar pointer varieble in which to store the result
1123  *
1124  * Returns a constant pointer to the current data position if there is
1125  * a NUL-terminated string in the data (this could be just a NUL terminator).
1126  * The current position will be maintained. This will work for any
1127  * NUL-terminated string with a character width of 8 bits, so ASCII,
1128  * UTF-8, ISO-8859-N etc.
1129  *
1130  * This function will fail if no NUL-terminator was found in in the data.
1131  *
1132  * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
1133  *
1134  * Since: 0.10.24
1135  */
1136 /**
1137  * gst_byte_reader_peek_string_utf8:
1138  * @reader: a #GstByteReader instance
1139  * @str: (out) (transfer none) (array zero-terminated=1): address of a
1140  *     #gchar pointer varieble in which to store the result
1141  *
1142  * Returns a constant pointer to the current data position if there is
1143  * a NUL-terminated string in the data (this could be just a NUL terminator).
1144  * The current position will be maintained. This will work for any
1145  * NUL-terminated string with a character width of 8 bits, so ASCII,
1146  * UTF-8, ISO-8859-N etc.
1147  *
1148  * No input checking for valid UTF-8 is done.
1149  *
1150  * This function will fail if no NUL-terminator was found in in the data.
1151  *
1152  * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
1153  *
1154  * Since: 0.10.24
1155  */
1156 gboolean
1157 gst_byte_reader_peek_string_utf8 (const GstByteReader * reader,
1158     const gchar ** str)
1159 {
1160   g_return_val_if_fail (reader != NULL, FALSE);
1161   g_return_val_if_fail (str != NULL, FALSE);
1162
1163   if (gst_byte_reader_scan_string_utf8 (reader) > 0) {
1164     *str = (const gchar *) (reader->data + reader->byte);
1165   } else {
1166     *str = NULL;
1167   }
1168   return (*str != NULL);
1169 }
1170
1171 /**
1172  * gst_byte_reader_get_string_utf8:
1173  * @reader: a #GstByteReader instance
1174  * @str: (out) (transfer none) (array zero-terminated=1): address of a
1175  *     #gchar pointer varieble in which to store the result
1176  *
1177  * Returns a constant pointer to the current data position if there is
1178  * a NUL-terminated string in the data (this could be just a NUL terminator),
1179  * advancing the current position to the byte after the string. This will work
1180  * for any NUL-terminated string with a character width of 8 bits, so ASCII,
1181  * UTF-8, ISO-8859-N etc.
1182  *
1183  * No input checking for valid UTF-8 is done.
1184  *
1185  * This function will fail if no NUL-terminator was found in in the data.
1186  *
1187  * Returns: %TRUE if a string could be found, %FALSE otherwise.
1188  *
1189  * Since: 0.10.24
1190  */
1191 gboolean
1192 gst_byte_reader_get_string_utf8 (GstByteReader * reader, const gchar ** str)
1193 {
1194   guint size;                   /* size in bytes including the terminator */
1195
1196   g_return_val_if_fail (reader != NULL, FALSE);
1197   g_return_val_if_fail (str != NULL, FALSE);
1198
1199   size = gst_byte_reader_scan_string_utf8 (reader);
1200   if (size == 0) {
1201     *str = NULL;
1202     return FALSE;
1203   }
1204
1205   *str = (const gchar *) (reader->data + reader->byte);
1206   reader->byte += size;
1207   return TRUE;
1208 }
1209
1210 #define GST_BYTE_READER_DUP_STRING(bits,type) \
1211 gboolean \
1212 gst_byte_reader_dup_string_utf##bits (GstByteReader * reader, type ** str) \
1213 { \
1214   guint size; /* size in bytes including the terminator */ \
1215   \
1216   g_return_val_if_fail (reader != NULL, FALSE); \
1217   g_return_val_if_fail (str != NULL, FALSE); \
1218   \
1219   size = gst_byte_reader_scan_string_utf##bits (reader); \
1220   if (size == 0) { \
1221     *str = NULL; \
1222     return FALSE; \
1223   } \
1224   *str = g_memdup (reader->data + reader->byte, size); \
1225   reader->byte += size; \
1226   return TRUE; \
1227 }
1228
1229 /**
1230  * gst_byte_reader_dup_string_utf8:
1231  * @reader: a #GstByteReader instance
1232  * @str: (out) (transfer full) (array zero-terminated=1): address of a
1233  *     #gchar pointer varieble in which to store the result
1234  *
1235  * Free-function: g_free
1236  *
1237  * FIXME:Reads (copies) a NUL-terminated string in the #GstByteReader instance,
1238  * advancing the current position to the byte after the string. This will work
1239  * for any NUL-terminated string with a character width of 8 bits, so ASCII,
1240  * UTF-8, ISO-8859-N etc. No input checking for valid UTF-8 is done.
1241  *
1242  * This function will fail if no NUL-terminator was found in in the data.
1243  *
1244  * Returns: %TRUE if a string could be read into @str, %FALSE otherwise. The
1245  *     string put into @str must be freed with g_free() when no longer needed.
1246  *
1247  * Since: 0.10.24
1248  */
1249 GST_BYTE_READER_DUP_STRING (8, gchar);
1250
1251 /**
1252  * gst_byte_reader_dup_string_utf16:
1253  * @reader: a #GstByteReader instance
1254  * @str: (out) (transfer full) (array zero-terminated=1): address of a
1255  *     #guint16 pointer varieble in which to store the result
1256  *
1257  * Free-function: g_free
1258  *
1259  * Returns a newly-allocated copy of the current data position if there is
1260  * a NUL-terminated UTF-16 string in the data (this could be an empty string
1261  * as well), and advances the current position.
1262  *
1263  * No input checking for valid UTF-16 is done. This function is endianness
1264  * agnostic - you should not assume the UTF-16 characters are in host
1265  * endianness.
1266  *
1267  * This function will fail if no NUL-terminator was found in in the data.
1268  *
1269  * Note: there is no peek or get variant of this function to ensure correct
1270  * byte alignment of the UTF-16 string.
1271  *
1272  * Returns: %TRUE if a string could be read, %FALSE otherwise. The
1273  *     string put into @str must be freed with g_free() when no longer needed.
1274  *
1275  * Since: 0.10.24
1276  */
1277 GST_BYTE_READER_DUP_STRING (16, guint16);
1278
1279 /**
1280  * gst_byte_reader_dup_string_utf32:
1281  * @reader: a #GstByteReader instance
1282  * @str: (out) (transfer full) (array zero-terminated=1): address of a
1283  *     #guint32 pointer varieble in which to store the result
1284  *
1285  * Free-function: g_free
1286  *
1287  * Returns a newly-allocated copy of the current data position if there is
1288  * a NUL-terminated UTF-32 string in the data (this could be an empty string
1289  * as well), and advances the current position.
1290  *
1291  * No input checking for valid UTF-32 is done. This function is endianness
1292  * agnostic - you should not assume the UTF-32 characters are in host
1293  * endianness.
1294  *
1295  * This function will fail if no NUL-terminator was found in in the data.
1296  *
1297  * Note: there is no peek or get variant of this function to ensure correct
1298  * byte alignment of the UTF-32 string.
1299  *
1300  * Returns: %TRUE if a string could be read, %FALSE otherwise. The
1301  *     string put into @str must be freed with g_free() when no longer needed.
1302  *
1303  * Since: 0.10.24
1304  */
1305 GST_BYTE_READER_DUP_STRING (32, guint32);