+2008-10-06 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+
+ * docs/libs/gstreamer-libs-docs.sgml:
+ * docs/libs/gstreamer-libs-sections.txt:
+ * libs/gst/base/Makefile.am:
+ * libs/gst/base/gstbitreader.c: (gst_bit_reader_new),
+ (gst_bit_reader_new_from_buffer), (gst_bit_reader_free),
+ (gst_bit_reader_init), (gst_bit_reader_init_from_buffer),
+ (gst_bit_reader_set_pos), (gst_bit_reader_get_pos),
+ (gst_bit_reader_get_remaining), (gst_bit_reader_skip),
+ (gst_bit_reader_skip_to_byte):
+ * libs/gst/base/gstbitreader.h:
+ * libs/gst/base/gstbytereader.c: (GDOUBLE_SWAP_LE_BE),
+ (GFLOAT_SWAP_LE_BE), (gst_byte_reader_new),
+ (gst_byte_reader_new_from_buffer), (gst_byte_reader_free),
+ (gst_byte_reader_init), (gst_byte_reader_init_from_buffer),
+ (gst_byte_reader_set_pos), (gst_byte_reader_get_pos),
+ (gst_byte_reader_get_remaining), (gst_byte_reader_skip),
+ (gst_byte_reader_get_uint8), (gst_byte_reader_get_int8),
+ (gst_byte_reader_peek_uint8), (gst_byte_reader_peek_int8),
+ (gst_byte_reader_get_uint24_le), (gst_byte_reader_get_uint24_be),
+ (gst_byte_reader_get_int24_le), (gst_byte_reader_get_int24_be),
+ (gst_byte_reader_peek_uint24_le), (gst_byte_reader_peek_uint24_be),
+ (gst_byte_reader_peek_int24_le), (gst_byte_reader_peek_int24_be):
+ * libs/gst/base/gstbytereader.h:
+ * tests/check/Makefile.am:
+ * tests/check/libs/bitreader.c: (GST_START_TEST),
+ (gst_bit_reader_suite):
+ * tests/check/libs/bytereader.c: (GST_START_TEST),
+ (gst_byte_reader_suite):
+ Add bit reader and byte reader classes, including documentation
+ and an extensive unit test suite. Fixes bug #553554.
+
2008-10-06 Wim Taymans <wim.taymans@collabora.co.uk>
* libs/gst/base/gstbasesink.c: (gst_base_sink_get_position),
<!ENTITY GstBaseSrc SYSTEM "xml/gstbasesrc.xml">
<!ENTITY GstBaseSink SYSTEM "xml/gstbasesink.xml">
<!ENTITY GstBaseTransform SYSTEM "xml/gstbasetransform.xml">
+<!ENTITY GstBitReader SYSTEM "xml/gstbitreader.xml">
+<!ENTITY GstByteReader SYSTEM "xml/gstbytereader.xml">
<!ENTITY GstCollectPads SYSTEM "xml/gstcollectpads.xml">
<!ENTITY GstPushSrc SYSTEM "xml/gstpushsrc.xml">
<!ENTITY GstTypeFindHelper SYSTEM "xml/gsttypefindhelper.xml">
&GstPushSrc;
&GstAdapter;
+ &GstBitReader;
+ &GstByteReader;
&GstCollectPads;
&GstTypeFindHelper;
&GstDataQueue;
gst_adapter_get_type
</SECTION>
-
<SECTION>
<FILE>gstbasesrc</FILE>
<TITLE>GstBaseSrc</TITLE>
</SECTION>
+<SECTION>
+<FILE>gstbitreader</FILE>
+<TITLE>GstBitReader</TITLE>
+<INCLUDE>gst/base/gstbitreader.h</INCLUDE>
+GstBitReader
+
+GST_BIT_READER_INIT
+GST_BIT_READER_INIT_FROM_BUFFER
+
+gst_bit_reader_new
+gst_bit_reader_new_from_buffer
+gst_bit_reader_free
+
+gst_bit_reader_init
+gst_bit_reader_init_from_buffer
+
+gst_bit_reader_get_pos
+gst_bit_reader_get_remaining
+gst_bit_reader_set_pos
+gst_bit_reader_skip
+gst_bit_reader_skip_to_byte
+
+gst_bit_reader_get_bits_uint16
+gst_bit_reader_get_bits_uint32
+gst_bit_reader_get_bits_uint64
+gst_bit_reader_get_bits_uint8
+
+gst_bit_reader_peek_bits_uint16
+gst_bit_reader_peek_bits_uint32
+gst_bit_reader_peek_bits_uint64
+gst_bit_reader_peek_bits_uint8
+</SECTION>
+
+<SECTION>
+<FILE>gstbytereader</FILE>
+<TITLE>GstByteReader</TITLE>
+<INCLUDE>gst/base/gstbytereader.h</INCLUDE>
+GstByteReader
+
+GST_BYTE_READER_INIT
+GST_BYTE_READER_INIT_FROM_BUFFER
+
+gst_byte_reader_new
+gst_byte_reader_new_from_buffer
+gst_byte_reader_free
+
+gst_byte_reader_init
+gst_byte_reader_init_from_buffer
+
+gst_byte_reader_get_pos
+gst_byte_reader_get_remaining
+gst_byte_reader_set_pos
+gst_byte_reader_skip
+
+gst_byte_reader_get_int8
+gst_byte_reader_get_int16_be
+gst_byte_reader_get_int16_le
+gst_byte_reader_get_int24_be
+gst_byte_reader_get_int24_le
+gst_byte_reader_get_int32_be
+gst_byte_reader_get_int32_le
+gst_byte_reader_get_int64_be
+gst_byte_reader_get_int64_le
+
+gst_byte_reader_get_uint8
+gst_byte_reader_get_uint16_be
+gst_byte_reader_get_uint16_le
+gst_byte_reader_get_uint24_be
+gst_byte_reader_get_uint24_le
+gst_byte_reader_get_uint32_be
+gst_byte_reader_get_uint32_le
+gst_byte_reader_get_uint64_be
+gst_byte_reader_get_uint64_le
+
+gst_byte_reader_peek_int8
+gst_byte_reader_peek_int16_be
+gst_byte_reader_peek_int16_le
+gst_byte_reader_peek_int24_be
+gst_byte_reader_peek_int24_le
+gst_byte_reader_peek_int32_be
+gst_byte_reader_peek_int32_le
+gst_byte_reader_peek_int64_be
+gst_byte_reader_peek_int64_le
+
+gst_byte_reader_peek_uint8
+gst_byte_reader_peek_uint16_be
+gst_byte_reader_peek_uint16_le
+gst_byte_reader_peek_uint24_be
+gst_byte_reader_peek_uint24_le
+gst_byte_reader_peek_uint32_be
+gst_byte_reader_peek_uint32_le
+gst_byte_reader_peek_uint64_be
+gst_byte_reader_peek_uint64_le
+
+
+gst_byte_reader_get_float32_le
+gst_byte_reader_get_float32_be
+gst_byte_reader_get_float64_le
+gst_byte_reader_get_float64_be
+
+gst_byte_reader_peek_float32_le
+gst_byte_reader_peek_float32_be
+gst_byte_reader_peek_float64_le
+gst_byte_reader_peek_float64_be
+</SECTION>
+
<SECTION>
<FILE>gstcollectpads</FILE>
<TITLE>GstCollectPads</TITLE>
gstbasesink.c \
gstbasesrc.c \
gstbasetransform.c \
+ gstbitreader.c \
+ gstbytereader.c \
gstcollectpads.c \
gstpushsrc.c \
gsttypefindhelper.c \
gstbasesink.h \
gstbasesrc.h \
gstbasetransform.h \
+ gstbitreader.h \
+ gstbytereader.h \
gstcollectpads.h \
gstpushsrc.h \
gsttypefindhelper.h \
--- /dev/null
+/* GStreamer
+ *
+ * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstbitreader.h"
+
+#include <string.h>
+
+/**
+ * SECTION:gstbitreader
+ * @short_description: Reads any number of bits from a memory buffer
+ *
+ * #GstBitReader provides a bit reader that can read any number of bits
+ * from a memory buffer. It provides functions for reading any number of bits
+ * into 8, 16, 32 and 64 bit variables.
+ */
+
+/**
+ * gst_bit_reader_new:
+ * @data: Data from which the #GstBitReader should read
+ * @size: Size of @data in bytes
+ *
+ * Create a new #GstBitReader instance, which will read from @data.
+ *
+ * Returns: a new #GstBitReader instance
+ *
+ * Since: 0.10.22
+ */
+GstBitReader *
+gst_bit_reader_new (const guint8 * data, guint size)
+{
+ GstBitReader *ret = g_slice_new0 (GstBitReader);
+
+ ret->data = data;
+ ret->size = size;
+
+ return ret;
+}
+
+/**
+ * gst_bit_reader_new_from_buffer:
+ * @buffer: Buffer from which the #GstBitReader should read
+ *
+ * Create a new #GstBitReader instance, which will read from the
+ * #GstBuffer @buffer.
+ *
+ * Returns: a new #GstBitReader instance
+ *
+ * Since: 0.10.22
+ */
+GstBitReader *
+gst_bit_reader_new_from_buffer (const GstBuffer * buffer)
+{
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
+
+ return gst_bit_reader_new (GST_BUFFER_DATA (buffer),
+ GST_BUFFER_SIZE (buffer));
+}
+
+/**
+ * gst_bit_reader_free:
+ * @reader: a #GstBitReader instance
+ *
+ * Frees a #GstBitReader instance, which was previously allocated by
+ * gst_bit_reader_new() or gst_bit_reader_new_from_buffer().
+ *
+ * Since: 0.10.22
+ */
+void
+gst_bit_reader_free (GstBitReader * reader)
+{
+ g_return_if_fail (reader != NULL);
+
+ g_slice_free (GstBitReader, reader);
+}
+
+/**
+ * gst_bit_reader_init:
+ * @reader: a #GstBitReader instance
+ * @data: Data from which the #GstBitReader should read
+ * @size: Size of @data in bytes
+ *
+ * Initializes a #GstBitReader instance to read from @data. This function
+ * can be called on already initialized instances.
+ *
+ * Since: 0.10.22
+ */
+void
+gst_bit_reader_init (GstBitReader * reader, const guint8 * data, guint size)
+{
+ g_return_if_fail (reader != NULL);
+
+ reader->data = data;
+ reader->size = size;
+ reader->byte = reader->bit = 0;
+}
+
+/**
+ * gst_bit_reader_init:
+ * @reader: a #GstBitReader instance
+ * @buffer: Buffer from which the #GstBitReader should read
+ *
+ * Initializes a #GstBitReader instance to read from @buffer. This function
+ * can be called on already initialized instances.
+ *
+ * Since: 0.10.22
+ */
+void
+gst_bit_reader_init_from_buffer (GstBitReader * reader,
+ const GstBuffer * buffer)
+{
+ g_return_if_fail (GST_IS_BUFFER (buffer));
+
+ gst_bit_reader_init (reader, GST_BUFFER_DATA (buffer),
+ GST_BUFFER_SIZE (buffer));
+}
+
+/**
+ * gst_bit_reader_set_pos:
+ * @reader: a #GstBitReader instance
+ * @pos: The new position in bits
+ *
+ * Sets the new position of a #GstBitReader instance to @pos in bits.
+ *
+ * Returns: %TRUE if the position could be set successfully, %FALSE
+ * otherwise.
+ *
+ * Since: 0.10.22
+ */
+gboolean
+gst_bit_reader_set_pos (GstBitReader * reader, guint pos)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+
+ if (pos > reader->size * 8)
+ return FALSE;
+
+ reader->byte = pos / 8;
+ reader->bit = pos % 8;
+
+ return TRUE;
+}
+
+/**
+ * gst_bit_reader_get_pos:
+ * @reader: a #GstBitReader instance
+ *
+ * Returns the current position of a #GstBitReader instance in bits.
+ *
+ * Returns: The current position of @reader in bits.
+ *
+ * Since: 0.10.22
+ */
+guint
+gst_bit_reader_get_pos (const GstBitReader * reader)
+{
+ g_return_val_if_fail (reader != NULL, 0);
+
+ return reader->byte * 8 + reader->bit;
+}
+
+/**
+ * gst_bit_reader_get_remaining:
+ * @reader: a #GstBitReader instance
+ *
+ * Returns the remaining number of bits of a #GstBitReader instance.
+ *
+ * Returns: The remaining number of bits of @reader instance.
+ *
+ * Since: 0.10.22
+ */
+guint
+gst_bit_reader_get_remaining (const GstBitReader * reader)
+{
+ g_return_val_if_fail (reader != NULL, 0);
+
+ return reader->size * 8 - (reader->byte * 8 + reader->bit);
+}
+
+/**
+ * gst_bit_reader_skip:
+ * @reader: a #GstBitReader instance
+ * @nbits: the number of bits to skip
+ *
+ * Skips @nbits bits of the #GstBitReader instance.
+ *
+ * Returns: %TRUE if @nbits bits could be skipped, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+gboolean
+gst_bit_reader_skip (GstBitReader * reader, guint nbits)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+
+ if (gst_bit_reader_get_remaining (reader) < nbits)
+ return FALSE;
+
+ reader->bit += nbits;
+ reader->byte += reader->bit / 8;
+ reader->bit = reader->bit % 8;
+
+ return TRUE;
+}
+
+/**
+ * gst_bit_reader_skip_to_byte:
+ * @reader: a #GstBitReader instance
+ *
+ * Skips until the next byte.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+gboolean
+gst_bit_reader_skip_to_byte (GstBitReader * reader)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+
+ if (reader->byte > reader->size)
+ return FALSE;
+
+ if (reader->bit) {
+ reader->bit = 0;
+ reader->byte++;
+ }
+
+ return TRUE;
+}
+
+/**
+ * gst_bit_reader_get_bits_uint8:
+ * @reader: a #GstBitReader instance
+ * @val: Pointer to a #guint8 to store the result
+ * @nbits: number of bits to read
+ *
+ * Read @nbits bits into @val and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_bit_reader_get_bits_uint16:
+ * @reader: a #GstBitReader instance
+ * @val: Pointer to a #guint16 to store the result
+ * @nbits: number of bits to read
+ *
+ * Read @nbits bits into @val and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_bit_reader_get_bits_uint32:
+ * @reader: a #GstBitReader instance
+ * @val: Pointer to a #guint32 to store the result
+ * @nbits: number of bits to read
+ *
+ * Read @nbits bits into @val and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_bit_reader_get_bits_uint64:
+ * @reader: a #GstBitReader instance
+ * @val: Pointer to a #guint64 to store the result
+ * @nbits: number of bits to read
+ *
+ * Read @nbits bits into @val and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_bit_reader_peek_bits_uint8:
+ * @reader: a #GstBitReader instance
+ * @val: Pointer to a #guint8 to store the result
+ * @nbits: number of bits to read
+ *
+ * Read @nbits bits into @val but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_bit_reader_peek_bits_uint16:
+ * @reader: a #GstBitReader instance
+ * @val: Pointer to a #guint16 to store the result
+ * @nbits: number of bits to read
+ *
+ * Read @nbits bits into @val but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_bit_reader_peek_bits_uint32:
+ * @reader: a #GstBitReader instance
+ * @val: Pointer to a #guint32 to store the result
+ * @nbits: number of bits to read
+ *
+ * Read @nbits bits into @val but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_bit_reader_peek_bits_uint64:
+ * @reader: a #GstBitReader instance
+ * @val: Pointer to a #guint64 to store the result
+ * @nbits: number of bits to read
+ *
+ * Read @nbits bits into @val but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+#define GST_BIT_READER_READ_BITS(bits) \
+gboolean \
+gst_bit_reader_get_bits_uint##bits (GstBitReader *reader, guint##bits *val, guint nbits) \
+{ \
+ guint##bits ret = 0; \
+ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ g_return_val_if_fail (nbits <= bits, FALSE); \
+ \
+ if (reader->byte * 8 + reader->bit + nbits > reader->size * 8) \
+ return FALSE; \
+ \
+ while (nbits > 0) { \
+ guint toread = MIN (nbits, 8 - reader->bit); \
+ \
+ ret <<= toread; \
+ ret |= (reader->data[reader->byte] & (0xff >> reader->bit)) >> (8 - toread - reader->bit); \
+ \
+ reader->bit += toread; \
+ if (reader->bit >= 8) { \
+ reader->byte++; \
+ reader->bit = 0; \
+ } \
+ nbits -= toread; \
+ } \
+ \
+ *val = ret; \
+ return TRUE; \
+} \
+\
+gboolean \
+gst_bit_reader_peek_bits_uint##bits (const GstBitReader *reader, guint##bits *val, guint nbits) \
+{ \
+ GstBitReader tmp; \
+ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ tmp = *reader; \
+ return gst_bit_reader_get_bits_uint##bits (&tmp, val, nbits); \
+}
+
+GST_BIT_READER_READ_BITS (8);
+GST_BIT_READER_READ_BITS (16);
+GST_BIT_READER_READ_BITS (32);
+GST_BIT_READER_READ_BITS (64);
--- /dev/null
+/* GStreamer
+ *
+ * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_BIT_READER_H__
+#define __GST_BIT_READER_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GstBitReader:
+ * @data: Data from which the bit reader will read
+ * @size: Size of @data in bytes
+ * @byte: Current byte position
+ * @bit: Bit position in the current byte
+ *
+ * A bit reader instance.
+ */
+typedef struct {
+ const guint8 *data;
+ guint size;
+
+ guint byte; /* Byte position */
+ guint bit; /* Bit position in the current byte */
+} GstBitReader;
+
+GstBitReader * gst_bit_reader_new (const guint8 *data, guint size);
+GstBitReader * gst_bit_reader_new_from_buffer (const GstBuffer *buffer);
+void gst_bit_reader_free (GstBitReader *reader);
+
+void gst_bit_reader_init (GstBitReader *reader, const guint8 *data, guint size);
+void gst_bit_reader_init_from_buffer (GstBitReader *reader, const GstBuffer *buffer);
+
+gboolean gst_bit_reader_set_pos (GstBitReader *reader, guint pos);
+
+guint gst_bit_reader_get_pos (const GstBitReader *reader);
+guint gst_bit_reader_get_remaining (const GstBitReader *reader);
+
+gboolean gst_bit_reader_skip (GstBitReader *reader, guint nbits);
+gboolean gst_bit_reader_skip_to_byte (GstBitReader *reader);
+
+gboolean gst_bit_reader_get_bits_uint8 (GstBitReader *reader, guint8 *val, guint nbits);
+gboolean gst_bit_reader_get_bits_uint16 (GstBitReader *reader, guint16 *val, guint nbits);
+gboolean gst_bit_reader_get_bits_uint32 (GstBitReader *reader, guint32 *val, guint nbits);
+gboolean gst_bit_reader_get_bits_uint64 (GstBitReader *reader, guint64 *val, guint nbits);
+
+gboolean gst_bit_reader_peek_bits_uint8 (const GstBitReader *reader, guint8 *val, guint nbits);
+gboolean gst_bit_reader_peek_bits_uint16 (const GstBitReader *reader, guint16 *val, guint nbits);
+gboolean gst_bit_reader_peek_bits_uint32 (const GstBitReader *reader, guint32 *val, guint nbits);
+gboolean gst_bit_reader_peek_bits_uint64 (const GstBitReader *reader, guint64 *val, guint nbits);
+
+/**
+ * GST_BIT_READER_INIT:
+ * @data: Data from which the #GstBitReader should read
+ * @size: Size of @data in bytes
+ *
+ * A #GstBitReader must be initialized with this macro, before it can be
+ * used. This macro can used be to initialize a variable, but it cannot
+ * be assigned to a variable. In that case you have to use
+ * gst_bit_reader_init().
+ *
+ * Since: 0.10.22
+ */
+#define GST_BIT_READER_INIT(data, size) {data, size, 0, 0}
+
+/**
+ * GST_BIT_READER_INIT_FROM_BUFFER:
+ * @buffer: Buffer from which the #GstBitReader should read
+ *
+ * A #GstBitReader must be initialized with this macro, before it can be
+ * used. This macro can used be to initialize a variable, but it cannot
+ * be assigned to a variable. In that case you have to use
+ * gst_bit_reader_init().
+ *
+ * Since: 0.10.22
+ */
+#define GST_BIT_READER_INIT_FROM_BUFFER(buffer) {GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), 0, 0}
+
+G_END_DECLS
+
+#endif /* __GST_BIT_READER_H__ */
--- /dev/null
+/* GStreamer
+ *
+ * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstbytereader.h"
+
+#include <string.h>
+
+/**
+ * SECTION:gstbytereader
+ * @short_description: Reads different integer and floating point types from a memory buffer
+ *
+ * #GstByteReader provides a byte reader that can read different integer and
+ * floating point types from a memory buffer. It provides functions for reading
+ * signed/unsigned, little/big endian integers of 8, 16, 24, 32 and 64 bits
+ * and functions for reading little/big endian floating points numbers of
+ * 32 and 64 bits.
+ */
+
+
+/* Copied from gst/floatcast/floatcast.h as this is in gst-plugins-base */
+
+inline static gdouble
+GDOUBLE_SWAP_LE_BE (gdouble in)
+{
+ union
+ {
+ guint64 i;
+ gdouble d;
+ } u;
+
+ u.d = in;
+ u.i = GUINT64_SWAP_LE_BE (u.i);
+ return u.d;
+}
+
+inline static gfloat
+GFLOAT_SWAP_LE_BE (gfloat in)
+{
+ union
+ {
+ guint32 i;
+ gfloat f;
+ } u;
+
+ u.f = in;
+ u.i = GUINT32_SWAP_LE_BE (u.i);
+ return u.f;
+}
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define GFLOAT_TO_LE(val) ((gfloat) (val))
+#define GFLOAT_TO_BE(val) (GFLOAT_SWAP_LE_BE (val))
+#define GDOUBLE_TO_LE(val) ((gdouble) (val))
+#define GDOUBLE_TO_BE(val) (GDOUBLE_SWAP_LE_BE (val))
+
+#elif G_BYTE_ORDER == G_BIG_ENDIAN
+#define GFLOAT_TO_LE(val) (GFLOAT_SWAP_LE_BE (val))
+#define GFLOAT_TO_BE(val) ((gfloat) (val))
+#define GDOUBLE_TO_LE(val) (GDOUBLE_SWAP_LE_BE (val))
+#define GDOUBLE_TO_BE(val) ((gdouble) (val))
+
+#else /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
+#error unknown ENDIAN type
+#endif /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
+
+#define GFLOAT_FROM_LE(val) (GFLOAT_TO_LE (val))
+#define GFLOAT_FROM_BE(val) (GFLOAT_TO_BE (val))
+#define GDOUBLE_FROM_LE(val) (GDOUBLE_TO_LE (val))
+#define GDOUBLE_FROM_BE(val) (GDOUBLE_TO_BE (val))
+
+
+/**
+ * gst_byte_reader_new:
+ * @data: Data from which the #GstByteReader should read
+ * @size: Size of @data in bytes
+ *
+ * Create a new #GstByteReader instance, which will read from @data.
+ *
+ * Returns: a new #GstByteReader instance
+ *
+ * Since: 0.10.22
+ */
+GstByteReader *
+gst_byte_reader_new (const guint8 * data, guint size)
+{
+ GstByteReader *ret = g_slice_new0 (GstByteReader);
+
+ ret->data = data;
+ ret->size = size;
+
+ return ret;
+}
+
+/**
+ * gst_byte_reader_new_from_buffer:
+ * @buffer: Buffer from which the #GstByteReader should read
+ *
+ * Create a new #GstByteReader instance, which will read from the
+ * #GstBuffer @buffer.
+ *
+ * Returns: a new #GstByteReader instance
+ *
+ * Since: 0.10.22
+ */
+GstByteReader *
+gst_byte_reader_new_from_buffer (const GstBuffer * buffer)
+{
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
+
+ return gst_byte_reader_new (GST_BUFFER_DATA (buffer),
+ GST_BUFFER_SIZE (buffer));
+}
+
+/**
+ * gst_byte_reader_free:
+ * @reader: a #GstByteReader instance
+ *
+ * Frees a #GstByteReader instance, which was previously allocated by
+ * gst_byte_reader_new() or gst_byte_reader_new_from_buffer().
+ *
+ * Since: 0.10.22
+ */
+void
+gst_byte_reader_free (GstByteReader * reader)
+{
+ g_return_if_fail (reader != NULL);
+
+ g_slice_free (GstByteReader, reader);
+}
+
+/**
+ * gst_byte_reader_init:
+ * @reader: a #GstByteReader instance
+ * @data: Data from which the #GstByteReader should read
+ * @size: Size of @data in bytes
+ *
+ * Initializes a #GstByteReader instance to read from @data. This function
+ * can be called on already initialized instances.
+ *
+ * Since: 0.10.22
+ */
+void
+gst_byte_reader_init (GstByteReader * reader, const guint8 * data, guint size)
+{
+ g_return_if_fail (reader != NULL);
+
+ reader->data = data;
+ reader->size = size;
+ reader->byte = 0;
+}
+
+/**
+ * gst_byte_reader_init:
+ * @reader: a #GstByteReader instance
+ * @buffer: Buffer from which the #GstByteReader should read
+ *
+ * Initializes a #GstByteReader instance to read from @buffer. This function
+ * can be called on already initialized instances.
+ *
+ * Since: 0.10.22
+ */
+void
+gst_byte_reader_init_from_buffer (GstByteReader * reader,
+ const GstBuffer * buffer)
+{
+ g_return_if_fail (GST_IS_BUFFER (buffer));
+
+ gst_byte_reader_init (reader, GST_BUFFER_DATA (buffer),
+ GST_BUFFER_SIZE (buffer));
+}
+
+/**
+ * gst_byte_reader_set_pos:
+ * @reader: a #GstByteReader instance
+ * @pos: The new position in bytes
+ *
+ * Sets the new position of a #GstByteReader instance to @pos in bytes.
+ *
+ * Returns: %TRUE if the position could be set successfully, %FALSE
+ * otherwise.
+ *
+ * Since: 0.10.22
+ */
+gboolean
+gst_byte_reader_set_pos (GstByteReader * reader, guint pos)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+
+ if (pos > reader->size)
+ return FALSE;
+
+ reader->byte = pos;
+
+ return TRUE;
+}
+
+/**
+ * gst_byte_reader_get_pos:
+ * @reader: a #GstByteReader instance
+ *
+ * Returns the current position of a #GstByteReader instance in bytes.
+ *
+ * Returns: The current position of @reader in bytes.
+ *
+ * Since: 0.10.22
+ */
+guint
+gst_byte_reader_get_pos (const GstByteReader * reader)
+{
+ g_return_val_if_fail (reader != NULL, 0);
+
+ return reader->byte;
+}
+
+/**
+ * gst_byte_reader_get_remaining:
+ * @reader: a #GstByteReader instance
+ *
+ * Returns the remaining number of bytes of a #GstByteReader instance.
+ *
+ * Returns: The remaining number of bytes of @reader instance.
+ *
+ * Since: 0.10.22
+ */
+guint
+gst_byte_reader_get_remaining (const GstByteReader * reader)
+{
+ g_return_val_if_fail (reader != NULL, 0);
+
+ return reader->size - reader->byte;
+}
+
+/**
+ * gst_byte_reader_skip:
+ * @reader: a #GstByteReader instance
+ * @nbytes: the number of bytes to skip
+ *
+ * Skips @nbytes bytes of the #GstByteReader instance.
+ *
+ * Returns: %TRUE if @nbytes bytes could be skipped, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+gboolean
+gst_byte_reader_skip (GstByteReader * reader, guint nbytes)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+
+ if (gst_byte_reader_get_remaining (reader) < nbytes)
+ return FALSE;
+
+ reader->byte += nbytes;
+
+ return TRUE;
+}
+
+/**
+ * gst_byte_reader_get_uint8:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint8 to store the result
+ *
+ * Read an unsigned 8 bit integer into @val and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_int8:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint8 to store the result
+ *
+ * Read a signed 8 bit integer into @val and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_uint8:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint8 to store the result
+ *
+ * Read a signed 8 bit integer into @val but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_int8:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint8 to store the result
+ *
+ * Read a signed 8 bit integer into @val but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_uint16_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint16 to store the result
+ *
+ * Read an unsigned 16 bit little endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_int16_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint16 to store the result
+ *
+ * Read a signed 16 bit little endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_uint16_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint16 to store the result
+ *
+ * Read a signed 16 bit little endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_int16_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint16 to store the result
+ *
+ * Read a signed 16 bit little endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_uint16_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint16 to store the result
+ *
+ * Read an unsigned 16 bit big endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_int16_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint16 to store the result
+ *
+ * Read a signed 16 bit big endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_uint16_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint16 to store the result
+ *
+ * Read a signed 16 bit big endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_int16_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint16 to store the result
+ *
+ * Read a signed 16 bit big endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_uint24_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint32 to store the result
+ *
+ * Read an unsigned 24 bit little endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_int24_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint32 to store the result
+ *
+ * Read a signed 24 bit little endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_uint24_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint32 to store the result
+ *
+ * Read a signed 24 bit little endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_int24_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint32 to store the result
+ *
+ * Read a signed 24 bit little endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_uint24_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint32 to store the result
+ *
+ * Read an unsigned 24 bit big endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_int24_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint32 to store the result
+ *
+ * Read a signed 24 bit big endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_uint24_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint32 to store the result
+ *
+ * Read a signed 24 bit big endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_int24_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint32 to store the result
+ *
+ * Read a signed 24 bit big endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+
+/**
+ * gst_byte_reader_get_uint32_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint32 to store the result
+ *
+ * Read an unsigned 32 bit little endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_int32_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint32 to store the result
+ *
+ * Read a signed 32 bit little endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_uint32_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint32 to store the result
+ *
+ * Read a signed 32 bit little endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_int32_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint32 to store the result
+ *
+ * Read a signed 32 bit little endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_uint32_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint32 to store the result
+ *
+ * Read an unsigned 32 bit big endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_int32_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint32 to store the result
+ *
+ * Read a signed 32 bit big endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_uint32_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint32 to store the result
+ *
+ * Read a signed 32 bit big endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_int32_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint32 to store the result
+ *
+ * Read a signed 32 bit big endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_uint64_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint64 to store the result
+ *
+ * Read an unsigned 64 bit little endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_int64_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint64 to store the result
+ *
+ * Read a signed 64 bit little endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_uint64_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint64 to store the result
+ *
+ * Read a signed 64 bit little endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_int64_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint64 to store the result
+ *
+ * Read a signed 64 bit little endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_uint64_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint64 to store the result
+ *
+ * Read an unsigned 64 bit big endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_int64_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint64 to store the result
+ *
+ * Read a signed 64 bit big endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_uint64_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #guint64 to store the result
+ *
+ * Read a signed 64 bit big endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_int64_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gint64 to store the result
+ *
+ * Read a signed 64 bit big endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+#define GST_BYTE_READER_READ_INTS(bits) \
+gboolean \
+gst_byte_reader_get_uint##bits##_le (GstByteReader *reader, guint##bits *val) \
+{ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ \
+ if (reader->byte + bits / 8 > reader->size) \
+ return FALSE; \
+ \
+ *val = GST_READ_UINT##bits##_LE (&reader->data[reader->byte]); \
+ reader->byte += bits / 8; \
+ return TRUE; \
+} \
+\
+gboolean \
+gst_byte_reader_get_uint##bits##_be (GstByteReader *reader, guint##bits *val) \
+{ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ \
+ if (reader->byte + bits / 8 > reader->size) \
+ return FALSE; \
+ \
+ *val = GST_READ_UINT##bits##_BE (&reader->data[reader->byte]); \
+ reader->byte += bits / 8; \
+ return TRUE; \
+} \
+\
+gboolean \
+gst_byte_reader_get_int##bits##_le (GstByteReader *reader, gint##bits *val) \
+{ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ \
+ if (reader->byte + bits / 8 > reader->size) \
+ return FALSE; \
+ \
+ *val = GST_READ_UINT##bits##_LE (&reader->data[reader->byte]); \
+ reader->byte += bits / 8; \
+ return TRUE; \
+} \
+\
+gboolean \
+gst_byte_reader_get_int##bits##_be (GstByteReader *reader, gint##bits *val) \
+{ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ \
+ if (reader->byte + bits / 8 > reader->size) \
+ return FALSE; \
+ \
+ *val = GST_READ_UINT##bits##_BE (&reader->data[reader->byte]); \
+ reader->byte += bits / 8; \
+ return TRUE; \
+} \
+gboolean \
+gst_byte_reader_peek_uint##bits##_le (GstByteReader *reader, guint##bits *val) \
+{ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ \
+ if (reader->byte + bits / 8 > reader->size) \
+ return FALSE; \
+ \
+ *val = GST_READ_UINT##bits##_LE (&reader->data[reader->byte]); \
+ return TRUE; \
+} \
+\
+gboolean \
+gst_byte_reader_peek_uint##bits##_be (GstByteReader *reader, guint##bits *val) \
+{ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ \
+ if (reader->byte + bits / 8 > reader->size) \
+ return FALSE; \
+ \
+ *val = GST_READ_UINT##bits##_BE (&reader->data[reader->byte]); \
+ return TRUE; \
+} \
+\
+gboolean \
+gst_byte_reader_peek_int##bits##_le (GstByteReader *reader, gint##bits *val) \
+{ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ \
+ if (reader->byte + bits / 8 > reader->size) \
+ return FALSE; \
+ \
+ *val = GST_READ_UINT##bits##_LE (&reader->data[reader->byte]); \
+ return TRUE; \
+} \
+\
+gboolean \
+gst_byte_reader_peek_int##bits##_be (GstByteReader *reader, gint##bits *val) \
+{ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ \
+ if (reader->byte + bits / 8 > reader->size) \
+ return FALSE; \
+ \
+ *val = GST_READ_UINT##bits##_BE (&reader->data[reader->byte]); \
+ return TRUE; \
+}
+
+
+GST_BYTE_READER_READ_INTS (16);
+GST_BYTE_READER_READ_INTS (32);
+GST_BYTE_READER_READ_INTS (64);
+
+gboolean
+gst_byte_reader_get_uint8 (GstByteReader * reader, guint8 * val)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (val != NULL, FALSE);
+
+ if (reader->byte + 1 > reader->size)
+ return FALSE;
+
+ *val = GST_READ_UINT8 (&reader->data[reader->byte]);
+ reader->byte++;
+ return TRUE;
+}
+
+gboolean
+gst_byte_reader_get_int8 (GstByteReader * reader, gint8 * val)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (val != NULL, FALSE);
+
+ if (reader->byte + 1 > reader->size)
+ return FALSE;
+
+ *val = GST_READ_UINT8 (&reader->data[reader->byte]);
+ reader->byte++;
+ return TRUE;
+}
+
+gboolean
+gst_byte_reader_peek_uint8 (GstByteReader * reader, guint8 * val)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (val != NULL, FALSE);
+
+ if (reader->byte + 1 > reader->size)
+ return FALSE;
+
+ *val = GST_READ_UINT8 (&reader->data[reader->byte]);
+ return TRUE;
+}
+
+gboolean
+gst_byte_reader_peek_int8 (GstByteReader * reader, gint8 * val)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (val != NULL, FALSE);
+
+ if (reader->byte + 1 > reader->size)
+ return FALSE;
+
+ *val = GST_READ_UINT8 (&reader->data[reader->byte]);
+ return TRUE;
+}
+
+gboolean
+gst_byte_reader_get_uint24_le (GstByteReader * reader, guint32 * val)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (val != NULL, FALSE);
+
+ if (reader->byte + 3 > reader->size)
+ return FALSE;
+
+ *val =
+ (reader->data[reader->byte] | (reader->data[reader->byte +
+ 1] << 8) | (reader->data[reader->byte + 2] << 16));
+ reader->byte += 3;
+ return TRUE;
+}
+
+gboolean
+gst_byte_reader_get_uint24_be (GstByteReader * reader, guint32 * val)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (val != NULL, FALSE);
+
+ if (reader->byte + 3 > reader->size)
+ return FALSE;
+
+ *val =
+ (reader->data[reader->byte + 2] | (reader->data[reader->byte +
+ 1] << 8) | (reader->data[reader->byte] << 16));
+ reader->byte += 3;
+ return TRUE;
+}
+
+gboolean
+gst_byte_reader_get_int24_le (GstByteReader * reader, gint32 * val)
+{
+ guint32 ret;
+
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (val != NULL, FALSE);
+
+ if (reader->byte + 3 > reader->size)
+ return FALSE;
+
+ ret =
+ (reader->data[reader->byte] | (reader->data[reader->byte +
+ 1] << 8) | (reader->data[reader->byte + 2] << 16));
+
+ if (ret & 0x00800000)
+ ret |= 0xff000000;
+
+ reader->byte += 3;
+
+ *val = ret;
+ return TRUE;
+}
+
+gboolean
+gst_byte_reader_get_int24_be (GstByteReader * reader, gint32 * val)
+{
+ guint32 ret;
+
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (val != NULL, FALSE);
+
+ if (reader->byte + 3 > reader->size)
+ return FALSE;
+
+ ret =
+ (reader->data[reader->byte + 2] | (reader->data[reader->byte +
+ 1] << 8) | (reader->data[reader->byte] << 16));
+ if (ret & 0x00800000)
+ ret |= 0xff000000;
+
+ reader->byte += 3;
+
+ *val = ret;
+ return TRUE;
+}
+
+gboolean
+gst_byte_reader_peek_uint24_le (GstByteReader * reader, guint32 * val)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (val != NULL, FALSE);
+
+ if (reader->byte + 3 > reader->size)
+ return FALSE;
+
+ *val =
+ (reader->data[reader->byte] | (reader->data[reader->byte +
+ 1] << 8) | (reader->data[reader->byte + 2] << 16));
+ return TRUE;
+}
+
+gboolean
+gst_byte_reader_peek_uint24_be (GstByteReader * reader, guint32 * val)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (val != NULL, FALSE);
+
+ if (reader->byte + 3 > reader->size)
+ return FALSE;
+
+ *val =
+ (reader->data[reader->byte + 2] | (reader->data[reader->byte +
+ 1] << 8) | (reader->data[reader->byte] << 16));
+ return TRUE;
+}
+
+gboolean
+gst_byte_reader_peek_int24_le (GstByteReader * reader, gint32 * val)
+{
+ guint32 ret;
+
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (val != NULL, FALSE);
+
+ if (reader->byte + 3 > reader->size)
+ return FALSE;
+
+ ret =
+ (reader->data[reader->byte] | (reader->data[reader->byte +
+ 1] << 8) | (reader->data[reader->byte + 2] << 16));
+
+ if (ret & 0x00800000)
+ ret |= 0xff000000;
+
+ *val = ret;
+ return TRUE;
+}
+
+gboolean
+gst_byte_reader_peek_int24_be (GstByteReader * reader, gint32 * val)
+{
+ guint32 ret;
+
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (val != NULL, FALSE);
+
+ if (reader->byte + 3 > reader->size)
+ return FALSE;
+
+ ret =
+ (reader->data[reader->byte + 2] | (reader->data[reader->byte +
+ 1] << 8) | (reader->data[reader->byte] << 16));
+ if (ret & 0x00800000)
+ ret |= 0xff000000;
+
+ *val = ret;
+ return TRUE;
+}
+
+/**
+ * gst_byte_reader_get_float32_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gfloat to store the result
+ *
+ * Read a 32 bit little endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_float32_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gfloat to store the result
+ *
+ * Read a 32 bit little endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_float32_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gfloat to store the result
+ *
+ * Read a 32 bit big endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_float32_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gfloat to store the result
+ *
+ * Read a 32 bit big endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_float64_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gdouble to store the result
+ *
+ * Read a 64 bit little endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_float64_le:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gdouble to store the result
+ *
+ * Read a 64 bit little endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_get_float64_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gdouble to store the result
+ *
+ * Read a 64 bit big endian integer into @val
+ * and update the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+/**
+ * gst_byte_reader_peek_float64_be:
+ * @reader: a #GstByteReader instance
+ * @val: Pointer to a #gdouble to store the result
+ *
+ * Read a 64 bit big endian integer into @val
+ * but keep the current position.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 0.10.22
+ */
+
+#define GST_BYTE_READER_READ_FLOATS(bits, type, TYPE) \
+gboolean \
+gst_byte_reader_get_float##bits##_le (GstByteReader *reader, g##type *val) \
+{ \
+ g##type ret; \
+ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ \
+ if (reader->byte + bits / 8 > reader->size) \
+ return FALSE; \
+ \
+ memcpy (&ret, &reader->data[reader->byte], bits / 8); \
+ *val = G##TYPE##_FROM_LE (ret); \
+ reader->byte += bits / 8; \
+ return TRUE; \
+} \
+gboolean \
+gst_byte_reader_get_float##bits##_be (GstByteReader *reader, g##type *val) \
+{ \
+ g##type ret; \
+ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ \
+ if (reader->byte + bits / 8 > reader->size) \
+ return FALSE; \
+ \
+ memcpy (&ret, &reader->data[reader->byte], bits / 8); \
+ *val = G##TYPE##_FROM_BE (ret); \
+ reader->byte += bits / 8; \
+ return TRUE; \
+} \
+gboolean \
+gst_byte_reader_peek_float##bits##_le (GstByteReader *reader, g##type *val) \
+{ \
+ g##type ret; \
+ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ \
+ if (reader->byte + bits / 8 > reader->size) \
+ return FALSE; \
+ \
+ memcpy (&ret, &reader->data[reader->byte], bits / 8); \
+ *val = G##TYPE##_FROM_LE (ret); \
+ return TRUE; \
+} \
+gboolean \
+gst_byte_reader_peek_float##bits##_be (GstByteReader *reader, g##type *val) \
+{ \
+ g##type ret; \
+ \
+ g_return_val_if_fail (reader != NULL, FALSE); \
+ g_return_val_if_fail (val != NULL, FALSE); \
+ \
+ if (reader->byte + bits / 8 > reader->size) \
+ return FALSE; \
+ \
+ memcpy (&ret, &reader->data[reader->byte], bits / 8); \
+ *val = G##TYPE##_FROM_BE (ret); \
+ return TRUE; \
+}
+
+GST_BYTE_READER_READ_FLOATS (32, float, FLOAT);
+GST_BYTE_READER_READ_FLOATS (64, double, DOUBLE);
--- /dev/null
+/* GStreamer
+ *
+ * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_BYTE_READER_H__
+#define __GST_BYTE_READER_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GstByteReader:
+ * @data: Data from which the bit reader will read
+ * @size: Size of @data in bytes
+ * @byte: Current byte position
+ *
+ * A byte reader instance.
+ */
+typedef struct {
+ const guint8 *data;
+ guint size;
+
+ guint byte; /* Byte position */
+} GstByteReader;
+
+GstByteReader * gst_byte_reader_new (const guint8 *data, guint size);
+GstByteReader * gst_byte_reader_new_from_buffer (const GstBuffer *buffer);
+void gst_byte_reader_free (GstByteReader *reader);
+
+void gst_byte_reader_init (GstByteReader *reader, const guint8 *data, guint size);
+void gst_byte_reader_init_from_buffer (GstByteReader *reader, const GstBuffer *buffer);
+
+gboolean gst_byte_reader_set_pos (GstByteReader *reader, guint pos);
+
+guint gst_byte_reader_get_pos (const GstByteReader *reader);
+guint gst_byte_reader_get_remaining (const GstByteReader *reader);
+
+gboolean gst_byte_reader_skip (GstByteReader *reader, guint nbytes);
+
+gboolean gst_byte_reader_get_uint8 (GstByteReader *reader, guint8 *val);
+gboolean gst_byte_reader_get_int8 (GstByteReader *reader, gint8 *val);
+gboolean gst_byte_reader_get_uint16_le (GstByteReader *reader, guint16 *val);
+gboolean gst_byte_reader_get_int16_le (GstByteReader *reader, gint16 *val);
+gboolean gst_byte_reader_get_uint16_be (GstByteReader *reader, guint16 *val);
+gboolean gst_byte_reader_get_int16_be (GstByteReader *reader, gint16 *val);
+gboolean gst_byte_reader_get_uint24_le (GstByteReader *reader, guint32 *val);
+gboolean gst_byte_reader_get_int24_le (GstByteReader *reader, gint32 *val);
+gboolean gst_byte_reader_get_uint24_be (GstByteReader *reader, guint32 *val);
+gboolean gst_byte_reader_get_int24_be (GstByteReader *reader, gint32 *val);
+gboolean gst_byte_reader_get_uint32_le (GstByteReader *reader, guint32 *val);
+gboolean gst_byte_reader_get_int32_le (GstByteReader *reader, gint32 *val);
+gboolean gst_byte_reader_get_uint32_be (GstByteReader *reader, guint32 *val);
+gboolean gst_byte_reader_get_int32_be (GstByteReader *reader, gint32 *val);
+gboolean gst_byte_reader_get_uint64_le (GstByteReader *reader, guint64 *val);
+gboolean gst_byte_reader_get_int64_le (GstByteReader *reader, gint64 *val);
+gboolean gst_byte_reader_get_uint64_be (GstByteReader *reader, guint64 *val);
+gboolean gst_byte_reader_get_int64_be (GstByteReader *reader, gint64 *val);
+
+gboolean gst_byte_reader_peek_uint8 (GstByteReader *reader, guint8 *val);
+gboolean gst_byte_reader_peek_int8 (GstByteReader *reader, gint8 *val);
+gboolean gst_byte_reader_peek_uint16_le (GstByteReader *reader, guint16 *val);
+gboolean gst_byte_reader_peek_int16_le (GstByteReader *reader, gint16 *val);
+gboolean gst_byte_reader_peek_uint16_be (GstByteReader *reader, guint16 *val);
+gboolean gst_byte_reader_peek_int16_be (GstByteReader *reader, gint16 *val);
+gboolean gst_byte_reader_peek_uint24_le (GstByteReader *reader, guint32 *val);
+gboolean gst_byte_reader_peek_int24_le (GstByteReader *reader, gint32 *val);
+gboolean gst_byte_reader_peek_uint24_be (GstByteReader *reader, guint32 *val);
+gboolean gst_byte_reader_peek_int24_be (GstByteReader *reader, gint32 *val);
+gboolean gst_byte_reader_peek_uint32_le (GstByteReader *reader, guint32 *val);
+gboolean gst_byte_reader_peek_int32_le (GstByteReader *reader, gint32 *val);
+gboolean gst_byte_reader_peek_uint32_be (GstByteReader *reader, guint32 *val);
+gboolean gst_byte_reader_peek_int32_be (GstByteReader *reader, gint32 *val);
+gboolean gst_byte_reader_peek_uint64_le (GstByteReader *reader, guint64 *val);
+gboolean gst_byte_reader_peek_int64_le (GstByteReader *reader, gint64 *val);
+gboolean gst_byte_reader_peek_uint64_be (GstByteReader *reader, guint64 *val);
+gboolean gst_byte_reader_peek_int64_be (GstByteReader *reader, gint64 *val);
+
+gboolean gst_byte_reader_get_float32_le (GstByteReader *reader, gfloat *val);
+gboolean gst_byte_reader_get_float32_be (GstByteReader *reader, gfloat *val);
+gboolean gst_byte_reader_get_float64_le (GstByteReader *reader, gdouble *val);
+gboolean gst_byte_reader_get_float64_be (GstByteReader *reader, gdouble *val);
+
+gboolean gst_byte_reader_peek_float32_le (GstByteReader *reader, gfloat *val);
+gboolean gst_byte_reader_peek_float32_be (GstByteReader *reader, gfloat *val);
+gboolean gst_byte_reader_peek_float64_le (GstByteReader *reader, gdouble *val);
+gboolean gst_byte_reader_peek_float64_be (GstByteReader *reader, gdouble *val);
+
+/**
+ * GST_BYTE_READER_INIT:
+ * @data: Data from which the #GstByteReader should read
+ * @size: Size of @data in bytes
+ *
+ * A #GstByteReader must be initialized with this macro, before it can be
+ * used. This macro can used be to initialize a variable, but it cannot
+ * be assigned to a variable. In that case you have to use
+ * gst_byte_reader_init().
+ *
+ * Since: 0.10.22
+ */
+#define GST_BYTE_READER_INIT(data, size) {data, size, 0}
+
+/**
+ * GST_BYTE_READER_INIT_FROM_BUFFER:
+ * @buffer: Buffer from which the #GstByteReader should read
+ *
+ * A #GstByteReader must be initialized with this macro, before it can be
+ * used. This macro can used be to initialize a variable, but it cannot
+ * be assigned to a variable. In that case you have to use
+ * gst_byte_reader_init().
+ *
+ * Since: 0.10.22
+ */
+#define GST_BYTE_READER_INIT_FROM_BUFFER(buffer) {GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), 0}
+
+G_END_DECLS
+
+#endif /* __GST_BYTE_READER_H__ */
libs/libsabi \
libs/gdp \
libs/adapter \
+ libs/bitreader \
+ libs/bytereader \
libs/gstnetclientclock \
libs/gstnettimeprovider \
libs/transform1
libs_basesrc_LDADD = \
$(top_builddir)/libs/gst/base/libgstbase-@GST_MAJORMINOR@.la \
$(LDADD)
+libs_bitreader_LDADD = \
+ $(top_builddir)/libs/gst/base/libgstbase-@GST_MAJORMINOR@.la \
+ $(LDADD)
+libs_bytereader_LDADD = \
+ $(top_builddir)/libs/gst/base/libgstbase-@GST_MAJORMINOR@.la \
+ $(LDADD)
libs_adapter_LDADD = \
$(top_builddir)/libs/gst/base/libgstbase-@GST_MAJORMINOR@.la \
$(LDADD)
--- /dev/null
+/* GStreamer
+ *
+ * unit test for GstBitReader
+ *
+ * Copyright (C) <2008> Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/check/gstcheck.h>
+#include <gst/base/gstbitreader.h>
+
+#ifndef fail_unless_equals_int64
+#define fail_unless_equals_int64(a, b) \
+G_STMT_START { \
+ gint64 first = a; \
+ gint64 second = b; \
+ fail_unless(first == second, \
+ "'" #a "' (%" G_GINT64_FORMAT ") is not equal to '" #b"' (%" \
+ G_GINT64_FORMAT ")", first, second); \
+} G_STMT_END;
+#endif
+
+GST_START_TEST (test_initialization)
+{
+ guint8 data[] = { 0x01, 0x02, 0x03, 0x04 };
+ GstBuffer *buffer = gst_buffer_new ();
+ GstBitReader reader = GST_BIT_READER_INIT (data, 4);
+ GstBitReader *reader2;
+ guint8 x;
+
+ GST_BUFFER_DATA (buffer) = data;
+ GST_BUFFER_SIZE (buffer) = 4;
+
+ fail_unless (gst_bit_reader_get_bits_uint8 (&reader, &x, 8));
+ fail_unless_equals_int (x, 0x01);
+ fail_unless (gst_bit_reader_get_bits_uint8 (&reader, &x, 8));
+ fail_unless_equals_int (x, 0x02);
+
+ memset (&reader, 0, sizeof (GstBitReader));
+
+ gst_bit_reader_init (&reader, data, 4);
+ fail_unless (gst_bit_reader_get_bits_uint8 (&reader, &x, 8));
+ fail_unless_equals_int (x, 0x01);
+ fail_unless (gst_bit_reader_get_bits_uint8 (&reader, &x, 8));
+ fail_unless_equals_int (x, 0x02);
+
+ gst_bit_reader_init_from_buffer (&reader, buffer);
+ fail_unless (gst_bit_reader_get_bits_uint8 (&reader, &x, 8));
+ fail_unless_equals_int (x, 0x01);
+ fail_unless (gst_bit_reader_get_bits_uint8 (&reader, &x, 8));
+ fail_unless_equals_int (x, 0x02);
+
+ reader2 = gst_bit_reader_new (data, 4);
+ fail_unless (gst_bit_reader_get_bits_uint8 (reader2, &x, 8));
+ fail_unless_equals_int (x, 0x01);
+ fail_unless (gst_bit_reader_get_bits_uint8 (reader2, &x, 8));
+ fail_unless_equals_int (x, 0x02);
+ gst_bit_reader_free (reader2);
+
+ reader2 = gst_bit_reader_new_from_buffer (buffer);
+ fail_unless (gst_bit_reader_get_bits_uint8 (reader2, &x, 8));
+ fail_unless_equals_int (x, 0x01);
+ fail_unless (gst_bit_reader_get_bits_uint8 (reader2, &x, 8));
+ fail_unless_equals_int (x, 0x02);
+ gst_bit_reader_free (reader2);
+
+ gst_buffer_unref (buffer);
+}
+
+GST_END_TEST;
+
+#define GET_CHECK(reader, dest, bits, nbits, val) { \
+ fail_unless (gst_bit_reader_get_bits_uint##bits (reader, &dest, nbits)); \
+ fail_unless_equals_uint64 (dest, val); \
+}
+
+#define PEEK_CHECK(reader, dest, bits, nbits, val) { \
+ fail_unless (gst_bit_reader_peek_bits_uint##bits (reader, &dest, nbits)); \
+ fail_unless_equals_uint64 (dest, val); \
+}
+
+#define GET_CHECK_FAIL(reader, dest, bits, nbits) { \
+ fail_if (gst_bit_reader_get_bits_uint##bits (reader, &dest, nbits)); \
+}
+
+#define PEEK_CHECK_FAIL(reader, dest, bits, nbits) { \
+ fail_if (gst_bit_reader_peek_bits_uint##bits (reader, &dest, nbits)); \
+}
+
+GST_START_TEST (test_get_bits)
+{
+ guint8 data[] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef,
+ 0xfe, 0xdc, 0xba, 0x09, 0x87, 0x65, 0x43, 0x21
+ };
+ GstBitReader reader = GST_BIT_READER_INIT (data, 16);
+ guint8 a;
+ guint16 b;
+ guint32 c;
+ guint64 d;
+
+ /* 8 bit */
+ GET_CHECK (&reader, a, 8, 8, 0x12);
+ GET_CHECK (&reader, a, 8, 4, 0x03);
+ GET_CHECK (&reader, a, 8, 4, 0x04);
+ GET_CHECK (&reader, a, 8, 3, 0x02);
+ GET_CHECK (&reader, a, 8, 1, 0x01);
+ GET_CHECK (&reader, a, 8, 2, 0x01);
+ GET_CHECK (&reader, a, 8, 2, 0x02);
+
+ PEEK_CHECK (&reader, a, 8, 8, 0x78);
+ PEEK_CHECK (&reader, a, 8, 8, 0x78);
+ fail_unless (gst_bit_reader_skip (&reader, 8));
+
+ PEEK_CHECK (&reader, a, 8, 8, 0x90);
+ GET_CHECK (&reader, a, 8, 1, 0x01);
+ GET_CHECK (&reader, a, 8, 1, 0x00);
+ GET_CHECK (&reader, a, 8, 1, 0x00);
+ GET_CHECK (&reader, a, 8, 1, 0x01);
+ fail_unless (gst_bit_reader_skip (&reader, 4));
+
+ fail_unless (gst_bit_reader_skip (&reader, 10 * 8));
+ GET_CHECK (&reader, a, 8, 8, 0x21);
+ GET_CHECK_FAIL (&reader, a, 8, 1);
+ PEEK_CHECK_FAIL (&reader, a, 8, 1);
+
+ /* 16 bit */
+ gst_bit_reader_init (&reader, data, 16);
+
+ GET_CHECK (&reader, b, 16, 16, 0x1234);
+ PEEK_CHECK (&reader, b, 16, 13, 0x0acf);
+ GET_CHECK (&reader, b, 16, 8, 0x56);
+ GET_CHECK (&reader, b, 16, 4, 0x07);
+ GET_CHECK (&reader, b, 16, 2, 0x02);
+ GET_CHECK (&reader, b, 16, 2, 0x00);
+ PEEK_CHECK (&reader, b, 16, 8, 0x90);
+ fail_unless (gst_bit_reader_skip (&reader, 11 * 8));
+ GET_CHECK (&reader, b, 16, 8, 0x21);
+ GET_CHECK_FAIL (&reader, b, 16, 16);
+ PEEK_CHECK_FAIL (&reader, b, 16, 16);
+
+ /* 32 bit */
+ gst_bit_reader_init (&reader, data, 16);
+
+ GET_CHECK (&reader, c, 32, 32, 0x12345678);
+ GET_CHECK (&reader, c, 32, 24, 0x90abcd);
+ GET_CHECK (&reader, c, 32, 16, 0xeffe);
+ GET_CHECK (&reader, c, 32, 8, 0xdc);
+ GET_CHECK (&reader, c, 32, 4, 0x0b);
+ GET_CHECK (&reader, c, 32, 2, 0x02);
+ GET_CHECK (&reader, c, 32, 2, 0x02);
+ PEEK_CHECK (&reader, c, 32, 8, 0x09);
+ fail_unless (gst_bit_reader_skip (&reader, 3 * 8));
+ GET_CHECK (&reader, c, 32, 15, 0x2190);
+ GET_CHECK (&reader, c, 32, 1, 0x1);
+ GET_CHECK_FAIL (&reader, c, 32, 1);
+
+ /* 64 bit */
+ gst_bit_reader_init (&reader, data, 16);
+
+ GET_CHECK (&reader, d, 64, 64, G_GINT64_CONSTANT (0x1234567890abcdef));
+ GET_CHECK (&reader, d, 64, 7, 0xfe >> 1);
+ GET_CHECK (&reader, d, 64, 1, 0x00);
+ GET_CHECK (&reader, d, 64, 24, 0xdcba09);
+ GET_CHECK (&reader, d, 64, 32, 0x87654321);
+ GET_CHECK_FAIL (&reader, d, 64, 32);
+}
+
+GST_END_TEST;
+
+#undef GET_CHECK
+#undef PEEK_CHECK
+#undef GET_CHECK_FAIL
+#undef PEEK_CHECK_FAIL
+
+GST_START_TEST (test_position_tracking)
+{
+ guint8 data[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
+ GstBitReader reader = GST_BIT_READER_INIT (data, 16);
+ guint8 a;
+
+ fail_unless_equals_int (gst_bit_reader_get_pos (&reader), 0);
+ fail_unless_equals_int (gst_bit_reader_get_remaining (&reader), 16 * 8);
+
+ fail_unless (gst_bit_reader_get_bits_uint8 (&reader, &a, 3));
+ fail_unless_equals_int (gst_bit_reader_get_pos (&reader), 3);
+ fail_unless_equals_int (gst_bit_reader_get_remaining (&reader), 16 * 8 - 3);
+
+ fail_unless (gst_bit_reader_set_pos (&reader, 9));
+ fail_unless_equals_int (gst_bit_reader_get_pos (&reader), 9);
+ fail_unless_equals_int (gst_bit_reader_get_remaining (&reader), 16 * 8 - 9);
+
+ fail_unless (gst_bit_reader_skip (&reader, 3));
+ fail_unless_equals_int (gst_bit_reader_get_pos (&reader), 12);
+ fail_unless_equals_int (gst_bit_reader_get_remaining (&reader), 16 * 8 - 12);
+
+ fail_unless (gst_bit_reader_skip_to_byte (&reader));
+ fail_unless_equals_int (gst_bit_reader_get_pos (&reader), 16);
+ fail_unless_equals_int (gst_bit_reader_get_remaining (&reader), 16 * 8 - 16);
+
+ fail_unless (gst_bit_reader_set_pos (&reader, 16 * 8));
+ fail_unless_equals_int (gst_bit_reader_get_pos (&reader), 16 * 8);
+ fail_unless_equals_int (gst_bit_reader_get_remaining (&reader), 0);
+
+ fail_unless (gst_bit_reader_skip (&reader, 0));
+ fail_if (gst_bit_reader_skip (&reader, 1));
+ fail_unless (gst_bit_reader_skip_to_byte (&reader));
+}
+
+GST_END_TEST;
+
+static Suite *
+gst_bit_reader_suite (void)
+{
+ Suite *s = suite_create ("GstBitReader");
+ TCase *tc_chain = tcase_create ("general");
+
+ suite_add_tcase (s, tc_chain);
+
+ tcase_add_test (tc_chain, test_initialization);
+ tcase_add_test (tc_chain, test_get_bits);
+ tcase_add_test (tc_chain, test_position_tracking);
+
+ return s;
+}
+
+
+GST_CHECK_MAIN (gst_bit_reader);
--- /dev/null
+/* GStreamer
+ *
+ * unit test for GstByteReader
+ *
+ * Copyright (C) <2008> Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/check/gstcheck.h>
+#include <gst/base/gstbytereader.h>
+
+#ifndef fail_unless_equals_int64
+#define fail_unless_equals_int64(a, b) \
+G_STMT_START { \
+ gint64 first = a; \
+ gint64 second = b; \
+ fail_unless(first == second, \
+ "'" #a "' (%" G_GINT64_FORMAT ") is not equal to '" #b"' (%" \
+ G_GINT64_FORMAT ")", first, second); \
+} G_STMT_END;
+#endif
+
+GST_START_TEST (test_initialization)
+{
+ guint8 data[] = { 0x01, 0x02, 0x03, 0x04 };
+ GstBuffer *buffer = gst_buffer_new ();
+ GstByteReader reader = GST_BYTE_READER_INIT (data, 4);
+ GstByteReader *reader2;
+ guint8 x;
+
+ GST_BUFFER_DATA (buffer) = data;
+ GST_BUFFER_SIZE (buffer) = 4;
+
+ fail_unless (gst_byte_reader_get_uint8 (&reader, &x));
+ fail_unless_equals_int (x, 0x01);
+ fail_unless (gst_byte_reader_get_uint8 (&reader, &x));
+ fail_unless_equals_int (x, 0x02);
+
+ memset (&reader, 0, sizeof (GstByteReader));
+
+ gst_byte_reader_init (&reader, data, 4);
+ fail_unless (gst_byte_reader_get_uint8 (&reader, &x));
+ fail_unless_equals_int (x, 0x01);
+ fail_unless (gst_byte_reader_get_uint8 (&reader, &x));
+ fail_unless_equals_int (x, 0x02);
+
+ gst_byte_reader_init_from_buffer (&reader, buffer);
+ fail_unless (gst_byte_reader_get_uint8 (&reader, &x));
+ fail_unless_equals_int (x, 0x01);
+ fail_unless (gst_byte_reader_get_uint8 (&reader, &x));
+ fail_unless_equals_int (x, 0x02);
+
+ reader2 = gst_byte_reader_new (data, 4);
+ fail_unless (gst_byte_reader_get_uint8 (reader2, &x));
+ fail_unless_equals_int (x, 0x01);
+ fail_unless (gst_byte_reader_get_uint8 (reader2, &x));
+ fail_unless_equals_int (x, 0x02);
+ gst_byte_reader_free (reader2);
+
+ reader2 = gst_byte_reader_new_from_buffer (buffer);
+ fail_unless (gst_byte_reader_get_uint8 (reader2, &x));
+ fail_unless_equals_int (x, 0x01);
+ fail_unless (gst_byte_reader_get_uint8 (reader2, &x));
+ fail_unless_equals_int (x, 0x02);
+ gst_byte_reader_free (reader2);
+
+ gst_buffer_unref (buffer);
+}
+
+GST_END_TEST;
+
+#define GET_CHECK8(reader, dest, val) { \
+ fail_unless (gst_byte_reader_get_uint8 (reader, &dest)); \
+ fail_unless_equals_uint64 (dest, val); \
+}
+
+#define GET_CHECK(reader, dest, bits, endianness, val) { \
+ fail_unless (gst_byte_reader_get_uint##bits##_##endianness (reader, &dest)); \
+ fail_unless_equals_uint64 (dest, val); \
+}
+
+#define GET_CHECK_FAIL8(reader, dest) { \
+ fail_if (gst_byte_reader_get_uint8 (reader, &dest)); \
+}
+
+#define GET_CHECK_FAIL(reader, dest, bits, endianness) { \
+ fail_if (gst_byte_reader_get_uint##bits##_##endianness (reader, &dest)); \
+}
+
+#define PEEK_CHECK8(reader, dest, val) { \
+ fail_unless (gst_byte_reader_peek_uint8 (reader, &dest)); \
+ fail_unless_equals_uint64 (dest, val); \
+}
+
+#define PEEK_CHECK(reader, dest, bits, endianness, val) { \
+ fail_unless (gst_byte_reader_peek_uint##bits##_##endianness (reader, &dest)); \
+ fail_unless_equals_uint64 (dest, val); \
+}
+
+#define PEEK_CHECK_FAIL8(reader, dest) { \
+ fail_if (gst_byte_reader_peek_uint8 (reader, &dest)); \
+}
+
+#define PEEK_CHECK_FAIL(reader, dest, bits, endianness) { \
+ fail_if (gst_byte_reader_peek_uint##bits##_##endianness (reader, &dest)); \
+}
+
+GST_START_TEST (test_get_uint_le)
+{
+ guint8 data[] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef,
+ 0xfe, 0xdc, 0xba, 0x09, 0x87, 0x65, 0x43, 0x21
+ };
+ GstByteReader reader = GST_BYTE_READER_INIT (data, 16);
+ guint8 a;
+ guint16 b;
+ guint32 c;
+ guint64 d;
+
+ GET_CHECK8 (&reader, a, 0x12);
+ GET_CHECK (&reader, b, 16, le, 0x5634);
+ GET_CHECK (&reader, c, 24, le, 0xab9078);
+ GET_CHECK (&reader, c, 32, le, 0xdcfeefcd);
+ fail_unless (gst_byte_reader_set_pos (&reader, 0));
+ GET_CHECK (&reader, d, 64, le, G_GINT64_CONSTANT (0xefcdab9078563412));
+ GET_CHECK (&reader, d, 64, le, G_GINT64_CONSTANT (0x2143658709badcfe));
+
+ GET_CHECK_FAIL8 (&reader, a);
+ GET_CHECK_FAIL (&reader, b, 16, le);
+ GET_CHECK_FAIL (&reader, c, 24, le);
+ GET_CHECK_FAIL (&reader, c, 32, le);
+ GET_CHECK_FAIL (&reader, d, 64, le);
+
+ fail_unless (gst_byte_reader_set_pos (&reader, 0));
+
+ PEEK_CHECK8 (&reader, a, 0x12);
+ PEEK_CHECK (&reader, b, 16, le, 0x3412);
+ PEEK_CHECK (&reader, c, 24, le, 0x563412);
+ PEEK_CHECK (&reader, c, 32, le, 0x78563412);
+ PEEK_CHECK (&reader, d, 64, le, G_GINT64_CONSTANT (0xefcdab9078563412));
+
+ fail_unless (gst_byte_reader_set_pos (&reader, 16));
+ PEEK_CHECK_FAIL8 (&reader, a);
+ PEEK_CHECK_FAIL (&reader, b, 16, le);
+ PEEK_CHECK_FAIL (&reader, c, 24, le);
+ PEEK_CHECK_FAIL (&reader, c, 32, le);
+ PEEK_CHECK_FAIL (&reader, d, 64, le);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_get_uint_be)
+{
+ guint8 data[] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef,
+ 0xfe, 0xdc, 0xba, 0x09, 0x87, 0x65, 0x43, 0x21
+ };
+ GstByteReader reader = GST_BYTE_READER_INIT (data, 16);
+ guint8 a;
+ guint16 b;
+ guint32 c;
+ guint64 d;
+
+ GET_CHECK8 (&reader, a, 0x12);
+ GET_CHECK (&reader, b, 16, be, 0x3456);
+ GET_CHECK (&reader, c, 24, be, 0x7890ab);
+ GET_CHECK (&reader, c, 32, be, 0xcdeffedc);
+ fail_unless (gst_byte_reader_set_pos (&reader, 0));
+ GET_CHECK (&reader, d, 64, be, G_GINT64_CONSTANT (0x1234567890abcdef));
+ GET_CHECK (&reader, d, 64, be, G_GINT64_CONSTANT (0xfedcba0987654321));
+
+ GET_CHECK_FAIL8 (&reader, a);
+ GET_CHECK_FAIL (&reader, b, 16, be);
+ GET_CHECK_FAIL (&reader, c, 24, be);
+ GET_CHECK_FAIL (&reader, c, 32, be);
+ GET_CHECK_FAIL (&reader, d, 64, be);
+
+ fail_unless (gst_byte_reader_set_pos (&reader, 0));
+
+ PEEK_CHECK8 (&reader, a, 0x12);
+ PEEK_CHECK (&reader, b, 16, be, 0x1234);
+ PEEK_CHECK (&reader, c, 24, be, 0x123456);
+ PEEK_CHECK (&reader, c, 32, be, 0x12345678);
+ PEEK_CHECK (&reader, d, 64, be, G_GINT64_CONSTANT (0x1234567890abcdef));
+
+ fail_unless (gst_byte_reader_set_pos (&reader, 16));
+ PEEK_CHECK_FAIL8 (&reader, a);
+ PEEK_CHECK_FAIL (&reader, b, 16, be);
+ PEEK_CHECK_FAIL (&reader, c, 24, be);
+ PEEK_CHECK_FAIL (&reader, c, 32, be);
+ PEEK_CHECK_FAIL (&reader, d, 64, be);
+}
+
+GST_END_TEST;
+
+#undef GET_CHECK8
+#undef GET_CHECK
+#undef PEEK_CHECK8
+#undef PEEK_CHECK
+#undef GET_CHECK_FAIL8
+#undef GET_CHECK_FAIL
+#undef PEEK_CHECK_FAIL8
+#undef PEEK_CHECK_FAIL
+
+#define GET_CHECK8(reader, dest, val) { \
+ fail_unless (gst_byte_reader_get_int8 (reader, &dest)); \
+ fail_unless_equals_int64 (dest, val); \
+}
+
+#define GET_CHECK(reader, dest, bits, endianness, val) { \
+ fail_unless (gst_byte_reader_get_int##bits##_##endianness (reader, &dest)); \
+ fail_unless_equals_int64 (dest, val); \
+}
+
+#define GET_CHECK_FAIL8(reader, dest) { \
+ fail_if (gst_byte_reader_get_int8 (reader, &dest)); \
+}
+
+#define GET_CHECK_FAIL(reader, dest, bits, endianness) { \
+ fail_if (gst_byte_reader_get_int##bits##_##endianness (reader, &dest)); \
+}
+
+#define PEEK_CHECK8(reader, dest, val) { \
+ fail_unless (gst_byte_reader_peek_int8 (reader, &dest)); \
+ fail_unless_equals_int64 (dest, val); \
+}
+
+#define PEEK_CHECK(reader, dest, bits, endianness, val) { \
+ fail_unless (gst_byte_reader_peek_int##bits##_##endianness (reader, &dest)); \
+ fail_unless_equals_int64 (dest, val); \
+}
+
+#define PEEK_CHECK_FAIL8(reader, dest) { \
+ fail_if (gst_byte_reader_peek_int8 (reader, &dest)); \
+}
+
+#define PEEK_CHECK_FAIL(reader, dest, bits, endianness) { \
+ fail_if (gst_byte_reader_peek_int##bits##_##endianness (reader, &dest)); \
+}
+
+GST_START_TEST (test_get_int_le)
+{
+ guint8 data[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
+ GstByteReader reader = GST_BYTE_READER_INIT (data, 16);
+ gint8 a;
+ gint16 b;
+ gint32 c;
+ gint64 d;
+
+ GET_CHECK8 (&reader, a, -1);
+ GET_CHECK (&reader, b, 16, le, -1);
+ GET_CHECK (&reader, c, 24, le, -1);
+ GET_CHECK (&reader, c, 32, le, -1);
+ fail_unless (gst_byte_reader_set_pos (&reader, 0));
+ GET_CHECK (&reader, d, 64, le, G_GINT64_CONSTANT (-1));
+ GET_CHECK (&reader, d, 64, le, G_GINT64_CONSTANT (-1));
+
+ GET_CHECK_FAIL8 (&reader, a);
+ GET_CHECK_FAIL (&reader, b, 16, le);
+ GET_CHECK_FAIL (&reader, c, 24, le);
+ GET_CHECK_FAIL (&reader, c, 32, le);
+ GET_CHECK_FAIL (&reader, d, 64, le);
+
+ fail_unless (gst_byte_reader_set_pos (&reader, 0));
+
+ PEEK_CHECK8 (&reader, a, -1);
+ PEEK_CHECK (&reader, b, 16, le, -1);
+ PEEK_CHECK (&reader, c, 24, le, -1);
+ PEEK_CHECK (&reader, c, 32, le, -1);
+ PEEK_CHECK (&reader, d, 64, le, G_GINT64_CONSTANT (-1));
+
+ fail_unless (gst_byte_reader_set_pos (&reader, 16));
+ PEEK_CHECK_FAIL8 (&reader, a);
+ PEEK_CHECK_FAIL (&reader, b, 16, le);
+ PEEK_CHECK_FAIL (&reader, c, 24, le);
+ PEEK_CHECK_FAIL (&reader, c, 32, le);
+ PEEK_CHECK_FAIL (&reader, d, 64, le);
+
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_get_int_be)
+{
+ guint8 data[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
+ GstByteReader reader = GST_BYTE_READER_INIT (data, 16);
+ gint8 a;
+ gint16 b;
+ gint32 c;
+ gint64 d;
+
+ GET_CHECK8 (&reader, a, -1);
+ GET_CHECK (&reader, b, 16, be, -1);
+ GET_CHECK (&reader, c, 24, be, -1);
+ GET_CHECK (&reader, c, 32, be, -1);
+ fail_unless (gst_byte_reader_set_pos (&reader, 0));
+ GET_CHECK (&reader, d, 64, be, G_GINT64_CONSTANT (-1));
+ GET_CHECK (&reader, d, 64, be, G_GINT64_CONSTANT (-1));
+
+ GET_CHECK_FAIL8 (&reader, a);
+ GET_CHECK_FAIL (&reader, b, 16, be);
+ GET_CHECK_FAIL (&reader, c, 24, be);
+ GET_CHECK_FAIL (&reader, c, 32, be);
+ GET_CHECK_FAIL (&reader, d, 64, be);
+
+ fail_unless (gst_byte_reader_set_pos (&reader, 0));
+
+ PEEK_CHECK8 (&reader, a, -1);
+ PEEK_CHECK (&reader, b, 16, be, -1);
+ PEEK_CHECK (&reader, c, 24, be, -1);
+ PEEK_CHECK (&reader, c, 32, be, -1);
+ PEEK_CHECK (&reader, d, 64, be, G_GINT64_CONSTANT (-1));
+
+ fail_unless (gst_byte_reader_set_pos (&reader, 16));
+ PEEK_CHECK_FAIL8 (&reader, a);
+ PEEK_CHECK_FAIL (&reader, b, 16, be);
+ PEEK_CHECK_FAIL (&reader, c, 24, be);
+ PEEK_CHECK_FAIL (&reader, c, 32, be);
+ PEEK_CHECK_FAIL (&reader, d, 64, be);
+
+}
+
+GST_END_TEST;
+
+#undef GET_CHECK8
+#undef GET_CHECK
+#undef PEEK_CHECK8
+#undef PEEK_CHECK
+#undef GET_CHECK_FAIL8
+#undef GET_CHECK_FAIL
+#undef PEEK_CHECK_FAIL8
+#undef PEEK_CHECK_FAIL
+
+#define GET_CHECK(reader, dest, bits, endianness, val) { \
+ fail_unless (gst_byte_reader_get_float##bits##_##endianness (reader, &dest)); \
+ fail_unless_equals_float (dest, val); \
+}
+
+#define GET_CHECK_FAIL(reader, dest, bits, endianness) { \
+ fail_if (gst_byte_reader_get_float##bits##_##endianness (reader, &dest)); \
+}
+
+#define PEEK_CHECK(reader, dest, bits, endianness, val) { \
+ fail_unless (gst_byte_reader_peek_float##bits##_##endianness (reader, &dest)); \
+ fail_unless_equals_float (dest, val); \
+}
+
+#define PEEK_CHECK_FAIL(reader, dest, bits, endianness) { \
+ fail_if (gst_byte_reader_peek_float##bits##_##endianness (reader, &dest)); \
+}
+
+GST_START_TEST (test_get_float_le)
+{
+ guint8 data[] = {
+ 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x80, 0xbf,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xbf,
+ };
+ GstByteReader reader = GST_BYTE_READER_INIT (data, 24);
+ gfloat a;
+ gdouble b;
+
+ PEEK_CHECK (&reader, a, 32, le, 1.0);
+ GET_CHECK (&reader, a, 32, le, 1.0);
+ GET_CHECK (&reader, a, 32, le, -1.0);
+ PEEK_CHECK (&reader, b, 64, le, 1.0);
+ GET_CHECK (&reader, b, 64, le, 1.0);
+ GET_CHECK (&reader, b, 64, le, -1.0);
+ GET_CHECK_FAIL (&reader, a, 32, le);
+ GET_CHECK_FAIL (&reader, b, 64, le);
+ PEEK_CHECK_FAIL (&reader, a, 32, le);
+ PEEK_CHECK_FAIL (&reader, b, 64, le);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_get_float_be)
+{
+ guint8 data[] = {
+ 0x3f, 0x80, 0x00, 0x00,
+ 0xbf, 0x80, 0x00, 0x00,
+ 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xbf, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ GstByteReader reader = GST_BYTE_READER_INIT (data, 24);
+ gfloat a;
+ gdouble b;
+
+ PEEK_CHECK (&reader, a, 32, be, 1.0);
+ GET_CHECK (&reader, a, 32, be, 1.0);
+ GET_CHECK (&reader, a, 32, be, -1.0);
+ PEEK_CHECK (&reader, b, 64, be, 1.0);
+ GET_CHECK (&reader, b, 64, be, 1.0);
+ GET_CHECK (&reader, b, 64, be, -1.0);
+ GET_CHECK_FAIL (&reader, a, 32, be);
+ GET_CHECK_FAIL (&reader, b, 64, be);
+ PEEK_CHECK_FAIL (&reader, a, 32, be);
+ PEEK_CHECK_FAIL (&reader, b, 64, be);
+}
+
+GST_END_TEST;
+
+#undef GET_CHECK
+#undef PEEK_CHECK
+#undef GET_CHECK_FAIL
+#undef PEEK_CHECK_FAIL
+
+GST_START_TEST (test_position_tracking)
+{
+ guint8 data[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
+ GstByteReader reader = GST_BYTE_READER_INIT (data, 16);
+ guint8 a;
+
+ fail_unless_equals_int (gst_byte_reader_get_pos (&reader), 0);
+ fail_unless_equals_int (gst_byte_reader_get_remaining (&reader), 16);
+
+ fail_unless (gst_byte_reader_get_uint8 (&reader, &a));
+ fail_unless_equals_int (gst_byte_reader_get_pos (&reader), 1);
+ fail_unless_equals_int (gst_byte_reader_get_remaining (&reader), 16 - 1);
+
+ fail_unless (gst_byte_reader_set_pos (&reader, 8));
+ fail_unless_equals_int (gst_byte_reader_get_pos (&reader), 8);
+ fail_unless_equals_int (gst_byte_reader_get_remaining (&reader), 16 - 8);
+
+ fail_unless (gst_byte_reader_skip (&reader, 4));
+ fail_unless_equals_int (gst_byte_reader_get_pos (&reader), 12);
+ fail_unless_equals_int (gst_byte_reader_get_remaining (&reader), 16 - 12);
+
+ fail_unless (gst_byte_reader_set_pos (&reader, 16));
+ fail_unless_equals_int (gst_byte_reader_get_pos (&reader), 16);
+ fail_unless_equals_int (gst_byte_reader_get_remaining (&reader), 0);
+
+ fail_unless (gst_byte_reader_skip (&reader, 0));
+ fail_if (gst_byte_reader_skip (&reader, 1));
+}
+
+GST_END_TEST;
+
+static Suite *
+gst_byte_reader_suite (void)
+{
+ Suite *s = suite_create ("GstByteReader");
+ TCase *tc_chain = tcase_create ("general");
+
+ suite_add_tcase (s, tc_chain);
+
+ tcase_add_test (tc_chain, test_initialization);
+ tcase_add_test (tc_chain, test_get_uint_le);
+ tcase_add_test (tc_chain, test_get_uint_be);
+ tcase_add_test (tc_chain, test_get_int_le);
+ tcase_add_test (tc_chain, test_get_int_be);
+ tcase_add_test (tc_chain, test_get_float_le);
+ tcase_add_test (tc_chain, test_get_float_be);
+ tcase_add_test (tc_chain, test_position_tracking);
+
+ return s;
+}
+
+
+GST_CHECK_MAIN (gst_byte_reader);