1 /* GStreamer byte reader
3 * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
4 * Copyright (C) 2009 Tim-Philipp Müller <tim centricular net>
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.
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.
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.
26 #define GST_BYTE_READER_DISABLE_INLINES
27 #include "gstbytereader.h"
32 * SECTION:gstbytereader
33 * @short_description: Reads different integer, string and floating point
34 * types from a memory buffer
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.
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
50 * Create a new #GstByteReader instance, which will read from @data.
52 * Free-function: gst_byte_reader_free
54 * Returns: (transfer full): a new #GstByteReader instance
57 gst_byte_reader_new (const guint8 * data, guint size)
59 GstByteReader *ret = g_slice_new0 (GstByteReader);
68 * gst_byte_reader_free:
69 * @reader: (in) (transfer full): a #GstByteReader instance
71 * Frees a #GstByteReader instance, which was previously allocated by
72 * gst_byte_reader_new().
75 gst_byte_reader_free (GstByteReader * reader)
77 g_return_if_fail (reader != NULL);
79 g_slice_free (GstByteReader, reader);
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
89 * Initializes a #GstByteReader instance to read from @data. This function
90 * can be called on already initialized instances.
93 gst_byte_reader_init (GstByteReader * reader, const guint8 * data, guint size)
95 g_return_if_fail (reader != NULL);
103 * gst_byte_reader_set_pos:
104 * @reader: a #GstByteReader instance
105 * @pos: The new position in bytes
107 * Sets the new position of a #GstByteReader instance to @pos in bytes.
109 * Returns: %TRUE if the position could be set successfully, %FALSE
113 gst_byte_reader_set_pos (GstByteReader * reader, guint pos)
115 g_return_val_if_fail (reader != NULL, FALSE);
117 if (pos > reader->size)
126 * gst_byte_reader_get_pos:
127 * @reader: a #GstByteReader instance
129 * Returns the current position of a #GstByteReader instance in bytes.
131 * Returns: The current position of @reader in bytes.
134 gst_byte_reader_get_pos (const GstByteReader * reader)
136 return _gst_byte_reader_get_pos_inline (reader);
140 * gst_byte_reader_get_remaining:
141 * @reader: a #GstByteReader instance
143 * Returns the remaining number of bytes of a #GstByteReader instance.
145 * Returns: The remaining number of bytes of @reader instance.
148 gst_byte_reader_get_remaining (const GstByteReader * reader)
150 return _gst_byte_reader_get_remaining_inline (reader);
154 * gst_byte_reader_get_size:
155 * @reader: a #GstByteReader instance
157 * Returns the total number of bytes of a #GstByteReader instance.
159 * Returns: The total number of bytes of @reader instance.
162 gst_byte_reader_get_size (const GstByteReader * reader)
164 return _gst_byte_reader_get_size_inline (reader);
167 #define gst_byte_reader_get_remaining _gst_byte_reader_get_remaining_inline
168 #define gst_byte_reader_get_size _gst_byte_reader_get_size_inline
171 * gst_byte_reader_skip:
172 * @reader: a #GstByteReader instance
173 * @nbytes: the number of bytes to skip
175 * Skips @nbytes bytes of the #GstByteReader instance.
177 * Returns: %TRUE if @nbytes bytes could be skipped, %FALSE otherwise.
180 gst_byte_reader_skip (GstByteReader * reader, guint nbytes)
182 return _gst_byte_reader_skip_inline (reader, nbytes);
186 * gst_byte_reader_get_uint8:
187 * @reader: a #GstByteReader instance
188 * @val: (out): Pointer to a #guint8 to store the result
190 * Read an unsigned 8 bit integer into @val and update the current position.
192 * Returns: %TRUE if successful, %FALSE otherwise.
196 * gst_byte_reader_get_int8:
197 * @reader: a #GstByteReader instance
198 * @val: (out): Pointer to a #gint8 to store the result
200 * Read a signed 8 bit integer into @val and update the current position.
202 * Returns: %TRUE if successful, %FALSE otherwise.
206 * gst_byte_reader_peek_uint8:
207 * @reader: a #GstByteReader instance
208 * @val: (out): Pointer to a #guint8 to store the result
210 * Read an unsigned 8 bit integer into @val but keep the current position.
212 * Returns: %TRUE if successful, %FALSE otherwise.
216 * gst_byte_reader_peek_int8:
217 * @reader: a #GstByteReader instance
218 * @val: (out): Pointer to a #gint8 to store the result
220 * Read a signed 8 bit integer into @val but keep the current position.
222 * Returns: %TRUE if successful, %FALSE otherwise.
226 * gst_byte_reader_get_uint16_le:
227 * @reader: a #GstByteReader instance
228 * @val: (out): Pointer to a #guint16 to store the result
230 * Read an unsigned 16 bit little endian integer into @val
231 * and update the current position.
233 * Returns: %TRUE if successful, %FALSE otherwise.
237 * gst_byte_reader_get_int16_le:
238 * @reader: a #GstByteReader instance
239 * @val: (out): Pointer to a #gint16 to store the result
241 * Read a signed 16 bit little endian integer into @val
242 * and update the current position.
244 * Returns: %TRUE if successful, %FALSE otherwise.
248 * gst_byte_reader_peek_uint16_le:
249 * @reader: a #GstByteReader instance
250 * @val: (out): Pointer to a #guint16 to store the result
252 * Read an unsigned 16 bit little endian integer into @val
253 * but keep the current position.
255 * Returns: %TRUE if successful, %FALSE otherwise.
259 * gst_byte_reader_peek_int16_le:
260 * @reader: a #GstByteReader instance
261 * @val: (out): Pointer to a #gint16 to store the result
263 * Read a signed 16 bit little endian integer into @val
264 * but keep the current position.
266 * Returns: %TRUE if successful, %FALSE otherwise.
270 * gst_byte_reader_get_uint16_be:
271 * @reader: a #GstByteReader instance
272 * @val: (out): Pointer to a #guint16 to store the result
274 * Read an unsigned 16 bit big endian integer into @val
275 * and update the current position.
277 * Returns: %TRUE if successful, %FALSE otherwise.
281 * gst_byte_reader_get_int16_be:
282 * @reader: a #GstByteReader instance
283 * @val: (out): Pointer to a #gint16 to store the result
285 * Read a signed 16 bit big endian integer into @val
286 * and update the current position.
288 * Returns: %TRUE if successful, %FALSE otherwise.
292 * gst_byte_reader_peek_uint16_be:
293 * @reader: a #GstByteReader instance
294 * @val: (out): Pointer to a #guint16 to store the result
296 * Read an unsigned 16 bit big endian integer into @val
297 * but keep the current position.
299 * Returns: %TRUE if successful, %FALSE otherwise.
303 * gst_byte_reader_peek_int16_be:
304 * @reader: a #GstByteReader instance
305 * @val: (out): Pointer to a #gint16 to store the result
307 * Read a signed 16 bit big endian integer into @val
308 * but keep the current position.
310 * Returns: %TRUE if successful, %FALSE otherwise.
314 * gst_byte_reader_get_uint24_le:
315 * @reader: a #GstByteReader instance
316 * @val: (out): Pointer to a #guint32 to store the result
318 * Read an unsigned 24 bit little endian integer into @val
319 * and update the current position.
321 * Returns: %TRUE if successful, %FALSE otherwise.
325 * gst_byte_reader_get_int24_le:
326 * @reader: a #GstByteReader instance
327 * @val: (out): Pointer to a #gint32 to store the result
329 * Read a signed 24 bit little endian integer into @val
330 * and update the current position.
332 * Returns: %TRUE if successful, %FALSE otherwise.
336 * gst_byte_reader_peek_uint24_le:
337 * @reader: a #GstByteReader instance
338 * @val: (out): Pointer to a #guint32 to store the result
340 * Read an unsigned 24 bit little endian integer into @val
341 * but keep the current position.
343 * Returns: %TRUE if successful, %FALSE otherwise.
347 * gst_byte_reader_peek_int24_le:
348 * @reader: a #GstByteReader instance
349 * @val: (out): Pointer to a #gint32 to store the result
351 * Read a signed 24 bit little endian integer into @val
352 * but keep the current position.
354 * Returns: %TRUE if successful, %FALSE otherwise.
358 * gst_byte_reader_get_uint24_be:
359 * @reader: a #GstByteReader instance
360 * @val: (out): Pointer to a #guint32 to store the result
362 * Read an unsigned 24 bit big endian integer into @val
363 * and update the current position.
365 * Returns: %TRUE if successful, %FALSE otherwise.
369 * gst_byte_reader_get_int24_be:
370 * @reader: a #GstByteReader instance
371 * @val: (out): Pointer to a #gint32 to store the result
373 * Read a signed 24 bit big endian integer into @val
374 * and update the current position.
376 * Returns: %TRUE if successful, %FALSE otherwise.
380 * gst_byte_reader_peek_uint24_be:
381 * @reader: a #GstByteReader instance
382 * @val: (out): Pointer to a #guint32 to store the result
384 * Read an unsigned 24 bit big endian integer into @val
385 * but keep the current position.
387 * Returns: %TRUE if successful, %FALSE otherwise.
391 * gst_byte_reader_peek_int24_be:
392 * @reader: a #GstByteReader instance
393 * @val: (out): Pointer to a #gint32 to store the result
395 * Read a signed 24 bit big endian integer into @val
396 * but keep the current position.
398 * Returns: %TRUE if successful, %FALSE otherwise.
403 * gst_byte_reader_get_uint32_le:
404 * @reader: a #GstByteReader instance
405 * @val: (out): Pointer to a #guint32 to store the result
407 * Read an unsigned 32 bit little endian integer into @val
408 * and update the current position.
410 * Returns: %TRUE if successful, %FALSE otherwise.
414 * gst_byte_reader_get_int32_le:
415 * @reader: a #GstByteReader instance
416 * @val: (out): Pointer to a #gint32 to store the result
418 * Read a signed 32 bit little endian integer into @val
419 * and update the current position.
421 * Returns: %TRUE if successful, %FALSE otherwise.
425 * gst_byte_reader_peek_uint32_le:
426 * @reader: a #GstByteReader instance
427 * @val: (out): Pointer to a #guint32 to store the result
429 * Read an unsigned 32 bit little endian integer into @val
430 * but keep the current position.
432 * Returns: %TRUE if successful, %FALSE otherwise.
436 * gst_byte_reader_peek_int32_le:
437 * @reader: a #GstByteReader instance
438 * @val: (out): Pointer to a #gint32 to store the result
440 * Read a signed 32 bit little endian integer into @val
441 * but keep the current position.
443 * Returns: %TRUE if successful, %FALSE otherwise.
447 * gst_byte_reader_get_uint32_be:
448 * @reader: a #GstByteReader instance
449 * @val: (out): Pointer to a #guint32 to store the result
451 * Read an unsigned 32 bit big endian integer into @val
452 * and update the current position.
454 * Returns: %TRUE if successful, %FALSE otherwise.
458 * gst_byte_reader_get_int32_be:
459 * @reader: a #GstByteReader instance
460 * @val: (out): Pointer to a #gint32 to store the result
462 * Read a signed 32 bit big endian integer into @val
463 * and update the current position.
465 * Returns: %TRUE if successful, %FALSE otherwise.
469 * gst_byte_reader_peek_uint32_be:
470 * @reader: a #GstByteReader instance
471 * @val: (out): Pointer to a #guint32 to store the result
473 * Read an unsigned 32 bit big endian integer into @val
474 * but keep the current position.
476 * Returns: %TRUE if successful, %FALSE otherwise.
480 * gst_byte_reader_peek_int32_be:
481 * @reader: a #GstByteReader instance
482 * @val: (out): Pointer to a #gint32 to store the result
484 * Read a signed 32 bit big endian integer into @val
485 * but keep the current position.
487 * Returns: %TRUE if successful, %FALSE otherwise.
491 * gst_byte_reader_get_uint64_le:
492 * @reader: a #GstByteReader instance
493 * @val: (out): Pointer to a #guint64 to store the result
495 * Read an unsigned 64 bit little endian integer into @val
496 * and update the current position.
498 * Returns: %TRUE if successful, %FALSE otherwise.
502 * gst_byte_reader_get_int64_le:
503 * @reader: a #GstByteReader instance
504 * @val: (out): Pointer to a #gint64 to store the result
506 * Read a signed 64 bit little endian integer into @val
507 * and update the current position.
509 * Returns: %TRUE if successful, %FALSE otherwise.
513 * gst_byte_reader_peek_uint64_le:
514 * @reader: a #GstByteReader instance
515 * @val: (out): Pointer to a #guint64 to store the result
517 * Read an unsigned 64 bit little endian integer into @val
518 * but keep the current position.
520 * Returns: %TRUE if successful, %FALSE otherwise.
524 * gst_byte_reader_peek_int64_le:
525 * @reader: a #GstByteReader instance
526 * @val: (out): Pointer to a #gint64 to store the result
528 * Read a signed 64 bit little endian integer into @val
529 * but keep the current position.
531 * Returns: %TRUE if successful, %FALSE otherwise.
535 * gst_byte_reader_get_uint64_be:
536 * @reader: a #GstByteReader instance
537 * @val: (out): Pointer to a #guint64 to store the result
539 * Read an unsigned 64 bit big endian integer into @val
540 * and update the current position.
542 * Returns: %TRUE if successful, %FALSE otherwise.
546 * gst_byte_reader_get_int64_be:
547 * @reader: a #GstByteReader instance
548 * @val: (out): Pointer to a #gint64 to store the result
550 * Read a signed 64 bit big endian integer into @val
551 * and update the current position.
553 * Returns: %TRUE if successful, %FALSE otherwise.
557 * gst_byte_reader_peek_uint64_be:
558 * @reader: a #GstByteReader instance
559 * @val: (out): Pointer to a #guint64 to store the result
561 * Read an unsigned 64 bit big endian integer into @val
562 * but keep the current position.
564 * Returns: %TRUE if successful, %FALSE otherwise.
568 * gst_byte_reader_peek_int64_be:
569 * @reader: a #GstByteReader instance
570 * @val: (out): Pointer to a #gint64 to store the result
572 * Read a signed 64 bit big endian integer into @val
573 * but keep the current position.
575 * Returns: %TRUE if successful, %FALSE otherwise.
578 #define GST_BYTE_READER_PEEK_GET(bits,type,name) \
580 gst_byte_reader_get_##name (GstByteReader * reader, type * val) \
582 return _gst_byte_reader_get_##name##_inline (reader, val); \
586 gst_byte_reader_peek_##name (const GstByteReader * reader, type * val) \
588 return _gst_byte_reader_peek_##name##_inline (reader, val); \
593 GST_BYTE_READER_PEEK_GET(8,guint8,uint8)
594 GST_BYTE_READER_PEEK_GET(8,gint8,int8)
596 GST_BYTE_READER_PEEK_GET(16,guint16,uint16_le)
597 GST_BYTE_READER_PEEK_GET(16,guint16,uint16_be)
598 GST_BYTE_READER_PEEK_GET(16,gint16,int16_le)
599 GST_BYTE_READER_PEEK_GET(16,gint16,int16_be)
601 GST_BYTE_READER_PEEK_GET(24,guint32,uint24_le)
602 GST_BYTE_READER_PEEK_GET(24,guint32,uint24_be)
603 GST_BYTE_READER_PEEK_GET(24,gint32,int24_le)
604 GST_BYTE_READER_PEEK_GET(24,gint32,int24_be)
606 GST_BYTE_READER_PEEK_GET(32,guint32,uint32_le)
607 GST_BYTE_READER_PEEK_GET(32,guint32,uint32_be)
608 GST_BYTE_READER_PEEK_GET(32,gint32,int32_le)
609 GST_BYTE_READER_PEEK_GET(32,gint32,int32_be)
611 GST_BYTE_READER_PEEK_GET(64,guint64,uint64_le)
612 GST_BYTE_READER_PEEK_GET(64,guint64,uint64_be)
613 GST_BYTE_READER_PEEK_GET(64,gint64,int64_le)
614 GST_BYTE_READER_PEEK_GET(64,gint64,int64_be)
617 * gst_byte_reader_get_float32_le:
618 * @reader: a #GstByteReader instance
619 * @val: (out): Pointer to a #gfloat to store the result
621 * Read a 32 bit little endian floating point value into @val
622 * and update the current position.
624 * Returns: %TRUE if successful, %FALSE otherwise.
628 * gst_byte_reader_peek_float32_le:
629 * @reader: a #GstByteReader instance
630 * @val: (out): Pointer to a #gfloat to store the result
632 * Read a 32 bit little endian floating point value into @val
633 * but keep the current position.
635 * Returns: %TRUE if successful, %FALSE otherwise.
639 * gst_byte_reader_get_float32_be:
640 * @reader: a #GstByteReader instance
641 * @val: (out): Pointer to a #gfloat to store the result
643 * Read a 32 bit big endian floating point value into @val
644 * and update the current position.
646 * Returns: %TRUE if successful, %FALSE otherwise.
650 * gst_byte_reader_peek_float32_be:
651 * @reader: a #GstByteReader instance
652 * @val: (out): Pointer to a #gfloat to store the result
654 * Read a 32 bit big endian floating point value into @val
655 * but keep the current position.
657 * Returns: %TRUE if successful, %FALSE otherwise.
661 * gst_byte_reader_get_float64_le:
662 * @reader: a #GstByteReader instance
663 * @val: (out): Pointer to a #gdouble to store the result
665 * Read a 64 bit little endian floating point value into @val
666 * and update the current position.
668 * Returns: %TRUE if successful, %FALSE otherwise.
672 * gst_byte_reader_peek_float64_le:
673 * @reader: a #GstByteReader instance
674 * @val: (out): Pointer to a #gdouble to store the result
676 * Read a 64 bit little endian floating point value into @val
677 * but keep the current position.
679 * Returns: %TRUE if successful, %FALSE otherwise.
683 * gst_byte_reader_get_float64_be:
684 * @reader: a #GstByteReader instance
685 * @val: (out): Pointer to a #gdouble to store the result
687 * Read a 64 bit big endian floating point value into @val
688 * and update the current position.
690 * Returns: %TRUE if successful, %FALSE otherwise.
694 * gst_byte_reader_peek_float64_be:
695 * @reader: a #GstByteReader instance
696 * @val: (out): Pointer to a #gdouble to store the result
698 * Read a 64 bit big endian floating point value into @val
699 * but keep the current position.
701 * Returns: %TRUE if successful, %FALSE otherwise.
704 GST_BYTE_READER_PEEK_GET(32,gfloat,float32_le)
705 GST_BYTE_READER_PEEK_GET(32,gfloat,float32_be)
706 GST_BYTE_READER_PEEK_GET(64,gdouble,float64_le)
707 GST_BYTE_READER_PEEK_GET(64,gdouble,float64_be)
712 * gst_byte_reader_get_data:
713 * @reader: a #GstByteReader instance
714 * @size: Size in bytes
715 * @val: (out) (transfer none) (array length=size): address of a
716 * #guint8 pointer variable in which to store the result
718 * Returns a constant pointer to the current data
719 * position if at least @size bytes are left and
720 * updates the current position.
723 * Returns: %TRUE if successful, %FALSE otherwise.
726 gst_byte_reader_get_data (GstByteReader * reader, guint size,
729 return _gst_byte_reader_get_data_inline (reader, size, val);
733 * gst_byte_reader_peek_data:
734 * @reader: a #GstByteReader instance
735 * @size: Size in bytes
736 * @val: (out) (transfer none) (array length=size): address of a
737 * #guint8 pointer variable in which to store the result
739 * Returns a constant pointer to the current data
740 * position if at least @size bytes are left and
741 * keeps the current position.
744 * Returns: %TRUE if successful, %FALSE otherwise.
747 gst_byte_reader_peek_data (const GstByteReader * reader, guint size,
750 return _gst_byte_reader_peek_data_inline (reader, size, val);
754 * gst_byte_reader_dup_data:
755 * @reader: a #GstByteReader instance
756 * @size: Size in bytes
757 * @val: (out) (transfer full) (array length=size): address of a
758 * #guint8 pointer variable in which to store the result
760 * Free-function: g_free
762 * Returns a newly-allocated copy of the current data
763 * position if at least @size bytes are left and
764 * updates the current position. Free with g_free() when no longer needed.
766 * Returns: %TRUE if successful, %FALSE otherwise.
769 gst_byte_reader_dup_data (GstByteReader * reader, guint size, guint8 ** val)
771 return _gst_byte_reader_dup_data_inline (reader, size, val);
775 * gst_byte_reader_masked_scan_uint32:
776 * @reader: a #GstByteReader
777 * @mask: mask to apply to data before matching against @pattern
778 * @pattern: pattern to match (after mask is applied)
779 * @offset: offset from which to start scanning, relative to the current
781 * @size: number of bytes to scan from offset
783 * Scan for pattern @pattern with applied mask @mask in the byte reader data,
784 * starting from offset @offset relative to the current position.
786 * The bytes in @pattern and @mask are interpreted left-to-right, regardless
787 * of endianness. All four bytes of the pattern must be present in the
788 * byte reader data for it to match, even if the first or last bytes are masked
791 * It is an error to call this function without making sure that there is
792 * enough data (offset+size bytes) in the byte reader.
794 * Returns: offset of the first match, or -1 if no match was found.
798 * // Assume the reader contains 0x00 0x01 0x02 ... 0xfe 0xff
800 * gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0x00010203, 0, 256);
802 * gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0x00010203, 1, 255);
804 * gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0x01020304, 1, 255);
806 * gst_byte_reader_masked_scan_uint32 (reader, 0xffff, 0x0001, 0, 256);
808 * gst_byte_reader_masked_scan_uint32 (reader, 0xffff, 0x0203, 0, 256);
810 * gst_byte_reader_masked_scan_uint32 (reader, 0xffff0000, 0x02030000, 0, 256);
812 * gst_byte_reader_masked_scan_uint32 (reader, 0xffff0000, 0x02030000, 0, 4);
817 gst_byte_reader_masked_scan_uint32 (const GstByteReader * reader, guint32 mask,
818 guint32 pattern, guint offset, guint size)
824 g_return_val_if_fail (size > 0, -1);
825 g_return_val_if_fail ((guint64) offset + size <= reader->size - reader->byte,
828 /* we can't find the pattern with less than 4 bytes */
829 if (G_UNLIKELY (size < 4))
832 data = reader->data + reader->byte + offset;
834 /* set the state to something that does not match */
838 for (i = 0; i < size; i++) {
839 /* throw away one byte and move in the next byte */
840 state = ((state << 8) | data[i]);
841 if (G_UNLIKELY ((state & mask) == pattern)) {
842 /* we have a match but we need to have skipped at
843 * least 4 bytes to fill the state. */
844 if (G_LIKELY (i >= 3))
845 return offset + i - 3;
853 #define GST_BYTE_READER_SCAN_STRING(bits) \
855 gst_byte_reader_scan_string_utf##bits (const GstByteReader * reader) \
857 guint len, off, max_len; \
859 max_len = (reader->size - reader->byte) / sizeof (guint##bits); \
861 /* need at least a single NUL terminator */ \
866 off = reader->byte; \
867 /* endianness does not matter if we are looking for a NUL terminator */ \
868 while (GST_READ_UINT##bits##_LE (&reader->data[off]) != 0) { \
870 off += sizeof (guint##bits); \
871 /* have we reached the end without finding a NUL terminator? */ \
872 if (len == max_len) \
875 /* return size in bytes including the NUL terminator (hence the +1) */ \
876 return (len + 1) * sizeof (guint##bits); \
879 #define GST_READ_UINT8_LE GST_READ_UINT8
880 GST_BYTE_READER_SCAN_STRING (8);
881 #undef GST_READ_UINT8_LE
882 GST_BYTE_READER_SCAN_STRING (16);
883 GST_BYTE_READER_SCAN_STRING (32);
885 #define GST_BYTE_READER_SKIP_STRING(bits) \
887 gst_byte_reader_skip_string_utf##bits (GstByteReader * reader) \
889 guint size; /* size in bytes including the terminator */ \
891 g_return_val_if_fail (reader != NULL, FALSE); \
893 size = gst_byte_reader_scan_string_utf##bits (reader); \
894 reader->byte += size; \
899 * gst_byte_reader_skip_string:
900 * @reader: a #GstByteReader instance
902 * Skips a NUL-terminated string in the #GstByteReader instance, advancing
903 * the current position to the byte after the string. This will work for
904 * any NUL-terminated string with a character width of 8 bits, so ASCII,
905 * UTF-8, ISO-8859-N etc.
907 * This function will fail if no NUL-terminator was found in in the data.
909 * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
912 * gst_byte_reader_skip_string_utf8:
913 * @reader: a #GstByteReader instance
915 * Skips a NUL-terminated string in the #GstByteReader instance, advancing
916 * the current position to the byte after the string. This will work for
917 * any NUL-terminated string with a character width of 8 bits, so ASCII,
918 * UTF-8, ISO-8859-N etc. No input checking for valid UTF-8 is done.
920 * This function will fail if no NUL-terminator was found in in the data.
922 * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
924 GST_BYTE_READER_SKIP_STRING (8);
927 * gst_byte_reader_skip_string_utf16:
928 * @reader: a #GstByteReader instance
930 * Skips a NUL-terminated UTF-16 string in the #GstByteReader instance,
931 * advancing the current position to the byte after the string.
933 * No input checking for valid UTF-16 is done.
935 * This function will fail if no NUL-terminator was found in in the data.
937 * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
939 GST_BYTE_READER_SKIP_STRING (16);
942 * gst_byte_reader_skip_string_utf32:
943 * @reader: a #GstByteReader instance
945 * Skips a NUL-terminated UTF-32 string in the #GstByteReader instance,
946 * advancing the current position to the byte after the string.
948 * No input checking for valid UTF-32 is done.
950 * This function will fail if no NUL-terminator was found in in the data.
952 * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
954 GST_BYTE_READER_SKIP_STRING (32);
957 * gst_byte_reader_peek_string:
958 * @reader: a #GstByteReader instance
959 * @str: (out) (transfer none) (array zero-terminated=1): address of a
960 * #gchar pointer varieble in which to store the result
962 * Returns a constant pointer to the current data position if there is
963 * a NUL-terminated string in the data (this could be just a NUL terminator).
964 * The current position will be maintained. This will work for any
965 * NUL-terminated string with a character width of 8 bits, so ASCII,
966 * UTF-8, ISO-8859-N etc.
968 * This function will fail if no NUL-terminator was found in in the data.
970 * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
973 * gst_byte_reader_peek_string_utf8:
974 * @reader: a #GstByteReader instance
975 * @str: (out) (transfer none) (array zero-terminated=1): address of a
976 * #gchar pointer varieble in which to store the result
978 * Returns a constant pointer to the current data position if there is
979 * a NUL-terminated string in the data (this could be just a NUL terminator).
980 * The current position will be maintained. This will work for any
981 * NUL-terminated string with a character width of 8 bits, so ASCII,
982 * UTF-8, ISO-8859-N etc.
984 * No input checking for valid UTF-8 is done.
986 * This function will fail if no NUL-terminator was found in in the data.
988 * Returns: %TRUE if a string could be skipped, %FALSE otherwise.
991 gst_byte_reader_peek_string_utf8 (const GstByteReader * reader,
994 g_return_val_if_fail (reader != NULL, FALSE);
995 g_return_val_if_fail (str != NULL, FALSE);
997 if (gst_byte_reader_scan_string_utf8 (reader) > 0) {
998 *str = (const gchar *) (reader->data + reader->byte);
1002 return (*str != NULL);
1006 * gst_byte_reader_get_string_utf8:
1007 * @reader: a #GstByteReader instance
1008 * @str: (out) (transfer none) (array zero-terminated=1): address of a
1009 * #gchar pointer varieble in which to store the result
1011 * Returns a constant pointer to the current data position if there is
1012 * a NUL-terminated string in the data (this could be just a NUL terminator),
1013 * advancing the current position to the byte after the string. This will work
1014 * for any NUL-terminated string with a character width of 8 bits, so ASCII,
1015 * UTF-8, ISO-8859-N etc.
1017 * No input checking for valid UTF-8 is done.
1019 * This function will fail if no NUL-terminator was found in in the data.
1021 * Returns: %TRUE if a string could be found, %FALSE otherwise.
1024 gst_byte_reader_get_string_utf8 (GstByteReader * reader, const gchar ** str)
1026 guint size; /* size in bytes including the terminator */
1028 g_return_val_if_fail (reader != NULL, FALSE);
1029 g_return_val_if_fail (str != NULL, FALSE);
1031 size = gst_byte_reader_scan_string_utf8 (reader);
1037 *str = (const gchar *) (reader->data + reader->byte);
1038 reader->byte += size;
1042 #define GST_BYTE_READER_DUP_STRING(bits,type) \
1044 gst_byte_reader_dup_string_utf##bits (GstByteReader * reader, type ** str) \
1046 guint size; /* size in bytes including the terminator */ \
1048 g_return_val_if_fail (reader != NULL, FALSE); \
1049 g_return_val_if_fail (str != NULL, FALSE); \
1051 size = gst_byte_reader_scan_string_utf##bits (reader); \
1056 *str = g_memdup (reader->data + reader->byte, size); \
1057 reader->byte += size; \
1062 * gst_byte_reader_dup_string_utf8:
1063 * @reader: a #GstByteReader instance
1064 * @str: (out) (transfer full) (array zero-terminated=1): address of a
1065 * #gchar pointer varieble in which to store the result
1067 * Free-function: g_free
1069 * FIXME:Reads (copies) a NUL-terminated string in the #GstByteReader instance,
1070 * advancing the current position to the byte after the string. This will work
1071 * for any NUL-terminated string with a character width of 8 bits, so ASCII,
1072 * UTF-8, ISO-8859-N etc. No input checking for valid UTF-8 is done.
1074 * This function will fail if no NUL-terminator was found in in the data.
1076 * Returns: %TRUE if a string could be read into @str, %FALSE otherwise. The
1077 * string put into @str must be freed with g_free() when no longer needed.
1079 GST_BYTE_READER_DUP_STRING (8, gchar);
1082 * gst_byte_reader_dup_string_utf16:
1083 * @reader: a #GstByteReader instance
1084 * @str: (out) (transfer full) (array zero-terminated=1): address of a
1085 * #guint16 pointer varieble in which to store the result
1087 * Free-function: g_free
1089 * Returns a newly-allocated copy of the current data position if there is
1090 * a NUL-terminated UTF-16 string in the data (this could be an empty string
1091 * as well), and advances the current position.
1093 * No input checking for valid UTF-16 is done. This function is endianness
1094 * agnostic - you should not assume the UTF-16 characters are in host
1097 * This function will fail if no NUL-terminator was found in in the data.
1099 * Note: there is no peek or get variant of this function to ensure correct
1100 * byte alignment of the UTF-16 string.
1102 * Returns: %TRUE if a string could be read, %FALSE otherwise. The
1103 * string put into @str must be freed with g_free() when no longer needed.
1105 GST_BYTE_READER_DUP_STRING (16, guint16);
1108 * gst_byte_reader_dup_string_utf32:
1109 * @reader: a #GstByteReader instance
1110 * @str: (out) (transfer full) (array zero-terminated=1): address of a
1111 * #guint32 pointer varieble in which to store the result
1113 * Free-function: g_free
1115 * Returns a newly-allocated copy of the current data position if there is
1116 * a NUL-terminated UTF-32 string in the data (this could be an empty string
1117 * as well), and advances the current position.
1119 * No input checking for valid UTF-32 is done. This function is endianness
1120 * agnostic - you should not assume the UTF-32 characters are in host
1123 * This function will fail if no NUL-terminator was found in in the data.
1125 * Note: there is no peek or get variant of this function to ensure correct
1126 * byte alignment of the UTF-32 string.
1128 * Returns: %TRUE if a string could be read, %FALSE otherwise. The
1129 * string put into @str must be freed with g_free() when no longer needed.
1131 GST_BYTE_READER_DUP_STRING (32, guint32);