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