Port gtk-doc comments to their equivalent markdown syntax
[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 offset, 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 + offset);
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     guint ret = _scan_for_start_code (data, offset, size);
867     if (G_UNLIKELY (value))
868       *value = (1 << 8) | data[ret + 3];
869     return ret;
870   }
871
872   /* set the state to something that does not match */
873   state = ~pattern;
874
875   /* now find data */
876   for (i = 0; i < size; i++) {
877     /* throw away one byte and move in the next byte */
878     state = ((state << 8) | data[i]);
879     if (G_UNLIKELY ((state & mask) == pattern)) {
880       /* we have a match but we need to have skipped at
881        * least 4 bytes to fill the state. */
882       if (G_LIKELY (i >= 3)) {
883         if (value)
884           *value = state;
885         return offset + i - 3;
886       }
887     }
888   }
889
890   /* nothing found */
891   return -1;
892 }
893
894
895 /**
896  * gst_byte_reader_masked_scan_uint32:
897  * @reader: a #GstByteReader
898  * @mask: mask to apply to data before matching against @pattern
899  * @pattern: pattern to match (after mask is applied)
900  * @offset: offset from which to start scanning, relative to the current
901  *     position
902  * @size: number of bytes to scan from offset
903  *
904  * Scan for pattern @pattern with applied mask @mask in the byte reader data,
905  * starting from offset @offset relative to the current position.
906  *
907  * The bytes in @pattern and @mask are interpreted left-to-right, regardless
908  * of endianness.  All four bytes of the pattern must be present in the
909  * byte reader data for it to match, even if the first or last bytes are masked
910  * out.
911  *
912  * It is an error to call this function without making sure that there is
913  * enough data (offset+size bytes) in the byte reader.
914  *
915  * Returns: offset of the first match, or -1 if no match was found.
916  *
917  * Example:
918  * |[
919  * // Assume the reader contains 0x00 0x01 0x02 ... 0xfe 0xff
920  *
921  * gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0x00010203, 0, 256);
922  * // -> returns 0
923  * gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0x00010203, 1, 255);
924  * // -> returns -1
925  * gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0x01020304, 1, 255);
926  * // -> returns 1
927  * gst_byte_reader_masked_scan_uint32 (reader, 0xffff, 0x0001, 0, 256);
928  * // -> returns -1
929  * gst_byte_reader_masked_scan_uint32 (reader, 0xffff, 0x0203, 0, 256);
930  * // -> returns 0
931  * gst_byte_reader_masked_scan_uint32 (reader, 0xffff0000, 0x02030000, 0, 256);
932  * // -> returns 2
933  * gst_byte_reader_masked_scan_uint32 (reader, 0xffff0000, 0x02030000, 0, 4);
934  * // -> returns -1
935  * ]|
936  */
937 guint
938 gst_byte_reader_masked_scan_uint32 (const GstByteReader * reader, guint32 mask,
939     guint32 pattern, guint offset, guint size)
940 {
941   return _masked_scan_uint32_peek (reader, mask, pattern, offset, size, NULL);
942 }
943
944 /**
945  * gst_byte_reader_masked_scan_uint32_peek:
946  * @reader: a #GstByteReader
947  * @mask: mask to apply to data before matching against @pattern
948  * @pattern: pattern to match (after mask is applied)
949  * @offset: offset from which to start scanning, relative to the current
950  *     position
951  * @size: number of bytes to scan from offset
952  * @value: pointer to uint32 to return matching data
953  *
954  * Scan for pattern @pattern with applied mask @mask in the byte reader data,
955  * starting from offset @offset relative to the current position.
956  *
957  * The bytes in @pattern and @mask are interpreted left-to-right, regardless
958  * of endianness.  All four bytes of the pattern must be present in the
959  * byte reader data for it to match, even if the first or last bytes are masked
960  * out.
961  *
962  * It is an error to call this function without making sure that there is
963  * enough data (offset+size bytes) in the byte reader.
964  *
965  * Returns: offset of the first match, or -1 if no match was found.
966  *
967  * Since: 1.6
968  */
969 guint
970 gst_byte_reader_masked_scan_uint32_peek (const GstByteReader * reader,
971     guint32 mask, guint32 pattern, guint offset, guint size, guint32 * value)
972 {
973   return _masked_scan_uint32_peek (reader, mask, pattern, offset, size, value);
974 }
975
976 #define GST_BYTE_READER_SCAN_STRING(bits) \
977 static guint \
978 gst_byte_reader_scan_string_utf##bits (const GstByteReader * reader) \
979 { \
980   guint len, off, max_len; \
981   \
982   max_len = (reader->size - reader->byte) / sizeof (guint##bits); \
983   \
984   /* need at least a single NUL terminator */ \
985   if (max_len < 1) \
986     return 0; \
987   \
988   len = 0; \
989   off = reader->byte; \
990   /* endianness does not matter if we are looking for a NUL terminator */ \
991   while (GST_READ_UINT##bits##_LE (&reader->data[off]) != 0) { \
992     ++len; \
993     off += sizeof (guint##bits); \
994     /* have we reached the end without finding a NUL terminator? */ \
995     if (len == max_len) \
996       return 0; \
997   } \
998   /* return size in bytes including the NUL terminator (hence the +1) */ \
999   return (len + 1) * sizeof (guint##bits); \
1000 }
1001
1002 #define GST_READ_UINT8_LE GST_READ_UINT8
1003 GST_BYTE_READER_SCAN_STRING (8);
1004 #undef GST_READ_UINT8_LE
1005 GST_BYTE_READER_SCAN_STRING (16);
1006 GST_BYTE_READER_SCAN_STRING (32);
1007
1008 #define GST_BYTE_READER_SKIP_STRING(bits) \
1009 gboolean \
1010 gst_byte_reader_skip_string_utf##bits (GstByteReader * reader) \
1011 { \
1012   guint size; /* size in bytes including the terminator */ \
1013   \
1014   g_return_val_if_fail (reader != NULL, FALSE); \
1015   \
1016   size = gst_byte_reader_scan_string_utf##bits (reader); \
1017   reader->byte += size; \
1018   return (size > 0); \
1019 }
1020
1021 /**
1022  * gst_byte_reader_skip_string:
1023  * @reader: a #GstByteReader instance
1024  *
1025  * Skips a NUL-terminated string in the #GstByteReader instance, advancing
1026  * the current position to the byte after the string. This will work for
1027  * any NUL-terminated string with a character width of 8 bits, so ASCII,
1028  * UTF-8, ISO-8859-N etc.
1029  *
1030  * This function will fail if no NUL-terminator was found in in the data.
1031  *
1032  * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
1033  */
1034 /**
1035  * gst_byte_reader_skip_string_utf8:
1036  * @reader: a #GstByteReader instance
1037  *
1038  * Skips a NUL-terminated string in the #GstByteReader instance, advancing
1039  * the current position to the byte after the string. This will work for
1040  * any NUL-terminated string with a character width of 8 bits, so ASCII,
1041  * UTF-8, ISO-8859-N etc. No input checking for valid UTF-8 is done.
1042  *
1043  * This function will fail if no NUL-terminator was found in in the data.
1044  *
1045  * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
1046  */
1047 GST_BYTE_READER_SKIP_STRING (8);
1048
1049 /**
1050  * gst_byte_reader_skip_string_utf16:
1051  * @reader: a #GstByteReader instance
1052  *
1053  * Skips a NUL-terminated UTF-16 string in the #GstByteReader instance,
1054  * advancing the current position to the byte after the string.
1055  *
1056  * No input checking for valid UTF-16 is done.
1057  *
1058  * This function will fail if no NUL-terminator was found in in the data.
1059  *
1060  * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
1061  */
1062 GST_BYTE_READER_SKIP_STRING (16);
1063
1064 /**
1065  * gst_byte_reader_skip_string_utf32:
1066  * @reader: a #GstByteReader instance
1067  *
1068  * Skips a NUL-terminated UTF-32 string in the #GstByteReader instance,
1069  * advancing the current position to the byte after the string.
1070  *
1071  * No input checking for valid UTF-32 is done.
1072  *
1073  * This function will fail if no NUL-terminator was found in in the data.
1074  *
1075  * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
1076  */
1077 GST_BYTE_READER_SKIP_STRING (32);
1078
1079 /**
1080  * gst_byte_reader_peek_string:
1081  * @reader: a #GstByteReader instance
1082  * @str: (out) (transfer none) (array zero-terminated=1): address of a
1083  *     #gchar pointer variable in which to store the result
1084  *
1085  * Returns a constant pointer to the current data position if there is
1086  * a NUL-terminated string in the data (this could be just a NUL terminator).
1087  * The current position will be maintained. This will work for any
1088  * NUL-terminated string with a character width of 8 bits, so ASCII,
1089  * UTF-8, ISO-8859-N etc.
1090  *
1091  * This function will fail if no NUL-terminator was found in in the data.
1092  *
1093  * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
1094  */
1095 /**
1096  * gst_byte_reader_peek_string_utf8:
1097  * @reader: a #GstByteReader instance
1098  * @str: (out) (transfer none) (array zero-terminated=1): address of a
1099  *     #gchar pointer variable in which to store the result
1100  *
1101  * Returns a constant pointer to the current data position if there is
1102  * a NUL-terminated string in the data (this could be just a NUL terminator).
1103  * The current position will be maintained. This will work for any
1104  * NUL-terminated string with a character width of 8 bits, so ASCII,
1105  * UTF-8, ISO-8859-N etc.
1106  *
1107  * No input checking for valid UTF-8 is done.
1108  *
1109  * This function will fail if no NUL-terminator was found in in the data.
1110  *
1111  * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
1112  */
1113 gboolean
1114 gst_byte_reader_peek_string_utf8 (const GstByteReader * reader,
1115     const gchar ** str)
1116 {
1117   g_return_val_if_fail (reader != NULL, FALSE);
1118   g_return_val_if_fail (str != NULL, FALSE);
1119
1120   if (gst_byte_reader_scan_string_utf8 (reader) > 0) {
1121     *str = (const gchar *) (reader->data + reader->byte);
1122   } else {
1123     *str = NULL;
1124   }
1125   return (*str != NULL);
1126 }
1127
1128 /**
1129  * gst_byte_reader_get_string_utf8:
1130  * @reader: a #GstByteReader instance
1131  * @str: (out) (transfer none) (array zero-terminated=1): address of a
1132  *     #gchar pointer variable in which to store the result
1133  *
1134  * Returns a constant pointer to the current data position if there is
1135  * a NUL-terminated string in the data (this could be just a NUL terminator),
1136  * advancing the current position to the byte after the string. This will work
1137  * for any NUL-terminated string with a character width of 8 bits, so ASCII,
1138  * UTF-8, ISO-8859-N etc.
1139  *
1140  * No input checking for valid UTF-8 is done.
1141  *
1142  * This function will fail if no NUL-terminator was found in in the data.
1143  *
1144  * Returns: %TRUE if a string could be found, %FALSE otherwise.
1145  */
1146 gboolean
1147 gst_byte_reader_get_string_utf8 (GstByteReader * reader, const gchar ** str)
1148 {
1149   guint size;                   /* size in bytes including the terminator */
1150
1151   g_return_val_if_fail (reader != NULL, FALSE);
1152   g_return_val_if_fail (str != NULL, FALSE);
1153
1154   size = gst_byte_reader_scan_string_utf8 (reader);
1155   if (size == 0) {
1156     *str = NULL;
1157     return FALSE;
1158   }
1159
1160   *str = (const gchar *) (reader->data + reader->byte);
1161   reader->byte += size;
1162   return TRUE;
1163 }
1164
1165 #define GST_BYTE_READER_DUP_STRING(bits,type) \
1166 gboolean \
1167 gst_byte_reader_dup_string_utf##bits (GstByteReader * reader, type ** str) \
1168 { \
1169   guint size; /* size in bytes including the terminator */ \
1170   \
1171   g_return_val_if_fail (reader != NULL, FALSE); \
1172   g_return_val_if_fail (str != NULL, FALSE); \
1173   \
1174   size = gst_byte_reader_scan_string_utf##bits (reader); \
1175   if (size == 0) { \
1176     *str = NULL; \
1177     return FALSE; \
1178   } \
1179   *str = g_memdup (reader->data + reader->byte, size); \
1180   reader->byte += size; \
1181   return TRUE; \
1182 }
1183
1184 /**
1185  * gst_byte_reader_dup_string_utf8:
1186  * @reader: a #GstByteReader instance
1187  * @str: (out) (transfer full) (array zero-terminated=1): address of a
1188  *     #gchar pointer variable in which to store the result
1189  *
1190  * Free-function: g_free
1191  *
1192  * FIXME:Reads (copies) a NUL-terminated string in the #GstByteReader instance,
1193  * advancing the current position to the byte after the string. This will work
1194  * for any NUL-terminated string with a character width of 8 bits, so ASCII,
1195  * UTF-8, ISO-8859-N etc. No input checking for valid UTF-8 is done.
1196  *
1197  * This function will fail if no NUL-terminator was found in in the data.
1198  *
1199  * Returns: %TRUE if a string could be read into @str, %FALSE otherwise. The
1200  *     string put into @str must be freed with g_free() when no longer needed.
1201  */
1202 GST_BYTE_READER_DUP_STRING (8, gchar);
1203
1204 /**
1205  * gst_byte_reader_dup_string_utf16:
1206  * @reader: a #GstByteReader instance
1207  * @str: (out) (transfer full) (array zero-terminated=1): address of a
1208  *     #guint16 pointer variable in which to store the result
1209  *
1210  * Free-function: g_free
1211  *
1212  * Returns a newly-allocated copy of the current data position if there is
1213  * a NUL-terminated UTF-16 string in the data (this could be an empty string
1214  * as well), and advances the current position.
1215  *
1216  * No input checking for valid UTF-16 is done. This function is endianness
1217  * agnostic - you should not assume the UTF-16 characters are in host
1218  * endianness.
1219  *
1220  * This function will fail if no NUL-terminator was found in in the data.
1221  *
1222  * Note: there is no peek or get variant of this function to ensure correct
1223  * byte alignment of the UTF-16 string.
1224  *
1225  * Returns: %TRUE if a string could be read, %FALSE otherwise. The
1226  *     string put into @str must be freed with g_free() when no longer needed.
1227  */
1228 GST_BYTE_READER_DUP_STRING (16, guint16);
1229
1230 /**
1231  * gst_byte_reader_dup_string_utf32:
1232  * @reader: a #GstByteReader instance
1233  * @str: (out) (transfer full) (array zero-terminated=1): address of a
1234  *     #guint32 pointer variable in which to store the result
1235  *
1236  * Free-function: g_free
1237  *
1238  * Returns a newly-allocated copy of the current data position if there is
1239  * a NUL-terminated UTF-32 string in the data (this could be an empty string
1240  * as well), and advances the current position.
1241  *
1242  * No input checking for valid UTF-32 is done. This function is endianness
1243  * agnostic - you should not assume the UTF-32 characters are in host
1244  * endianness.
1245  *
1246  * This function will fail if no NUL-terminator was found in in the data.
1247  *
1248  * Note: there is no peek or get variant of this function to ensure correct
1249  * byte alignment of the UTF-32 string.
1250  *
1251  * Returns: %TRUE if a string could be read, %FALSE otherwise. The
1252  *     string put into @str must be freed with g_free() when no longer needed.
1253  */
1254 GST_BYTE_READER_DUP_STRING (32, guint32);