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