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