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