summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim@centricular.com>2014-08-06 14:01:09 +0100
committerTim-Philipp Müller <tim@centricular.com>2014-08-15 10:03:26 +0100
commit86d7a597f00b7e1a6619cf566bfb27adb7f3f8c2 (patch)
tree21d001b20b8f144cd1df9a3fe76407e3eab73753
parentb9fa37f074665c1610749ff2a898fc42f3522c3a (diff)
bytereader: add gst_byte_reader_peek_sub_reader() and _get_sub_reader()
Adds API to get or peek a sub-reader of a certain size from a given byte reader. This is useful when parsing nested chunks, one can easily get a byte reader for a sub-chunk and make sure one never reads beyond the sub-chunk boundary. API: gst_byte_reader_peek_sub_reader() API: gst_byte_reader_get_sub_reader()
-rw-r--r--docs/libs/gstreamer-libs-sections.txt3
-rw-r--r--libs/gst/base/gstbytereader.c52
-rw-r--r--libs/gst/base/gstbytereader.h34
-rw-r--r--tests/check/libs/bytereader.c82
-rw-r--r--win32/common/libgstbase.def2
5 files changed, 172 insertions, 1 deletions
diff --git a/docs/libs/gstreamer-libs-sections.txt b/docs/libs/gstreamer-libs-sections.txt
index 83b19db701..a27b372a38 100644
--- a/docs/libs/gstreamer-libs-sections.txt
+++ b/docs/libs/gstreamer-libs-sections.txt
@@ -442,6 +442,9 @@ gst_byte_reader_free
gst_byte_reader_init
+gst_byte_reader_peek_sub_reader
+gst_byte_reader_get_sub_reader
+
gst_byte_reader_get_pos
gst_byte_reader_get_remaining
gst_byte_reader_set_pos
diff --git a/libs/gst/base/gstbytereader.c b/libs/gst/base/gstbytereader.c
index 6931841199..75dfd08db0 100644
--- a/libs/gst/base/gstbytereader.c
+++ b/libs/gst/base/gstbytereader.c
@@ -1,7 +1,7 @@
/* GStreamer byte reader
*
* Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
- * Copyright (C) 2009 Tim-Philipp Müller <tim centricular net>
+ * Copyright (C) 2009,2014 Tim-Philipp Müller <tim centricular net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -100,6 +100,56 @@ gst_byte_reader_init (GstByteReader * reader, const guint8 * data, guint size)
}
/**
+ * gst_byte_reader_peek_sub_reader: (skip)
+ * @reader: an existing and initialized #GstByteReader instance
+ * @sub_reader: a #GstByteReader instance to initialize as sub-reader
+ * @size: size of @sub_reader in bytes
+ *
+ * Initializes a #GstByteReader sub-reader instance to contain @size bytes of
+ * data from the current position of @reader. This is useful to read chunked
+ * formats and make sure that one doesn't read beyond the size of the sub-chunk.
+ *
+ * Unlike gst_byte_reader_get_sub_reader(), this function does not modify the
+ * current position of @reader.
+ *
+ * Returns: FALSE on error or if @reader does not contain @size more bytes from
+ * the current position, and otherwise TRUE
+ *
+ * Since: 1.6
+ */
+gboolean
+gst_byte_reader_peek_sub_reader (GstByteReader * reader,
+ GstByteReader * sub_reader, guint size)
+{
+ return _gst_byte_reader_peek_sub_reader_inline (reader, sub_reader, size);
+}
+
+/**
+ * gst_byte_reader_get_sub_reader: (skip)
+ * @reader: an existing and initialized #GstByteReader instance
+ * @sub_reader: a #GstByteReader instance to initialize as sub-reader
+ * @size: size of @sub_reader in bytes
+ *
+ * Initializes a #GstByteReader sub-reader instance to contain @size bytes of
+ * data from the current position of @reader. This is useful to read chunked
+ * formats and make sure that one doesn't read beyond the size of the sub-chunk.
+ *
+ * Unlike gst_byte_reader_peek_sub_reader(), this function also modifies the
+ * position of @reader and moves it forward by @size bytes.
+ *
+ * Returns: FALSE on error or if @reader does not contain @size more bytes from
+ * the current position, and otherwise TRUE
+ *
+ * Since: 1.6
+ */
+gboolean
+gst_byte_reader_get_sub_reader (GstByteReader * reader,
+ GstByteReader * sub_reader, guint size)
+{
+ return _gst_byte_reader_get_sub_reader_inline (reader, sub_reader, size);
+}
+
+/**
* gst_byte_reader_set_pos:
* @reader: a #GstByteReader instance
* @pos: The new position in bytes
diff --git a/libs/gst/base/gstbytereader.h b/libs/gst/base/gstbytereader.h
index 5b68837439..dd66011a96 100644
--- a/libs/gst/base/gstbytereader.h
+++ b/libs/gst/base/gstbytereader.h
@@ -52,6 +52,14 @@ void gst_byte_reader_free (GstByteReader *reader);
void gst_byte_reader_init (GstByteReader *reader, const guint8 *data, guint size);
+gboolean gst_byte_reader_peek_sub_reader (GstByteReader * reader,
+ GstByteReader * sub_reader,
+ guint size);
+
+gboolean gst_byte_reader_get_sub_reader (GstByteReader * reader,
+ GstByteReader * sub_reader,
+ guint size);
+
gboolean gst_byte_reader_set_pos (GstByteReader *reader, guint pos);
guint gst_byte_reader_get_pos (const GstByteReader *reader);
@@ -456,6 +464,32 @@ _gst_byte_reader_init_inline (GstByteReader * reader, const guint8 * data, guint
}
static inline gboolean
+_gst_byte_reader_peek_sub_reader_inline (GstByteReader * reader,
+ GstByteReader * sub_reader, guint size)
+{
+ g_return_val_if_fail (reader != NULL, FALSE);
+ g_return_val_if_fail (sub_reader != NULL, FALSE);
+
+ if (_gst_byte_reader_get_remaining_unchecked (reader) < size)
+ return FALSE;
+
+ sub_reader->data = reader->data + reader->byte;
+ sub_reader->byte = 0;
+ sub_reader->size = size;
+ return TRUE;
+}
+
+static inline gboolean
+_gst_byte_reader_get_sub_reader_inline (GstByteReader * reader,
+ GstByteReader * sub_reader, guint size)
+{
+ if (!_gst_byte_reader_peek_sub_reader_inline (reader, sub_reader, size))
+ return FALSE;
+ gst_byte_reader_skip_unchecked (reader, size);
+ return TRUE;
+}
+
+static inline gboolean
_gst_byte_reader_dup_data_inline (GstByteReader * reader, guint size, guint8 ** val)
{
g_return_val_if_fail (reader != NULL, FALSE);
diff --git a/tests/check/libs/bytereader.c b/tests/check/libs/bytereader.c
index d2a63cc11f..471e6a64b4 100644
--- a/tests/check/libs/bytereader.c
+++ b/tests/check/libs/bytereader.c
@@ -696,6 +696,87 @@ GST_START_TEST (test_dup_string)
GST_END_TEST;
+GST_START_TEST (test_sub_reader)
+{
+ const guint8 memdata[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
+ };
+ GstByteReader reader = GST_BYTE_READER_INIT (memdata, sizeof (memdata));
+ GstByteReader sub;
+ const guint8 *data = NULL, *sub_data = NULL;
+ guint16 v = 0;
+
+ /* init sub reader */
+ fail_if (gst_byte_reader_peek_sub_reader (&reader, &sub, 17));
+ fail_unless (gst_byte_reader_peek_sub_reader (&reader, &sub, 16));
+ fail_unless_equals_int (gst_byte_reader_get_remaining (&sub), 16);
+ fail_unless (gst_byte_reader_peek_data (&reader, 16, &data));
+ fail_unless (gst_byte_reader_peek_data (&sub, 16, &sub_data));
+ fail_unless (memcmp (data, sub_data, 16) == 0);
+
+ fail_unless_equals_int (gst_byte_reader_get_remaining (&reader), 16);
+ fail_unless (gst_byte_reader_skip (&reader, 3));
+ fail_if (gst_byte_reader_peek_sub_reader (&reader, &sub, 14));
+ fail_unless (gst_byte_reader_peek_sub_reader (&reader, &sub, 13));
+ fail_unless_equals_int (gst_byte_reader_get_remaining (&sub), 13);
+ fail_unless (gst_byte_reader_peek_data (&reader, 13, &data));
+ fail_unless (gst_byte_reader_peek_data (&sub, 13, &sub_data));
+ fail_unless (memcmp (data, sub_data, 16) == 0);
+
+ fail_unless_equals_int (gst_byte_reader_get_remaining (&reader), 13);
+ fail_unless (gst_byte_reader_peek_sub_reader (&reader, &sub, 3));
+ fail_unless_equals_int (gst_byte_reader_get_remaining (&sub), 3);
+ fail_if (gst_byte_reader_peek_data (&sub, 10, &sub_data));
+ fail_unless (gst_byte_reader_get_uint16_be (&sub, &v));
+ fail_unless_equals_int (v, 0x0304);
+ fail_if (gst_byte_reader_get_uint16_be (&sub, &v));
+ fail_unless_equals_int (gst_byte_reader_get_remaining (&sub), 1);
+
+ fail_unless (gst_byte_reader_get_uint16_be (&reader, &v));
+ fail_unless_equals_int (v, 0x0304);
+ fail_unless (gst_byte_reader_get_uint16_be (&reader, &v));
+ fail_unless_equals_int (v, 0x0506);
+ fail_unless_equals_int (gst_byte_reader_get_remaining (&reader), 9);
+
+ /* get sub reader */
+ gst_byte_reader_init (&reader, memdata, sizeof (memdata));
+ fail_if (gst_byte_reader_get_sub_reader (&reader, &sub, 17));
+ fail_unless (gst_byte_reader_get_sub_reader (&reader, &sub, 16));
+ fail_if (gst_byte_reader_get_sub_reader (&reader, &sub, 1));
+ fail_unless (gst_byte_reader_get_sub_reader (&reader, &sub, 0));
+
+ gst_byte_reader_init (&reader, memdata, sizeof (memdata));
+ fail_unless (gst_byte_reader_get_sub_reader (&reader, &sub, 2));
+ fail_unless (gst_byte_reader_get_uint16_be (&sub, &v));
+ fail_unless_equals_int (v, 0x0001);
+ fail_if (gst_byte_reader_get_uint16_be (&sub, &v));
+ fail_unless (gst_byte_reader_get_sub_reader (&reader, &sub, 3));
+ fail_unless (gst_byte_reader_get_uint16_be (&sub, &v));
+ fail_unless_equals_int (v, 0x0203);
+ fail_if (gst_byte_reader_get_uint16_be (&sub, &v));
+ fail_unless_equals_int (gst_byte_reader_get_uint8_unchecked (&sub), 0x04);
+ fail_unless (gst_byte_reader_get_sub_reader (&reader, &sub, 9));
+ fail_unless (gst_byte_reader_get_uint16_be (&sub, &v));
+ fail_unless_equals_int (v, 0x0506);
+ fail_unless (gst_byte_reader_get_uint16_be (&sub, &v));
+ fail_unless_equals_int (v, 0x0708);
+ fail_unless (gst_byte_reader_get_uint16_be (&sub, &v));
+ fail_unless_equals_int (v, 0x090a);
+ fail_unless (gst_byte_reader_get_uint16_be (&sub, &v));
+ fail_unless_equals_int (v, 0x0b0c);
+ fail_if (gst_byte_reader_get_uint16_be (&sub, &v));
+ fail_unless_equals_int (gst_byte_reader_get_uint8_unchecked (&sub), 0x0d);
+ fail_if (gst_byte_reader_get_sub_reader (&reader, &sub, 3));
+ fail_unless (gst_byte_reader_get_sub_reader (&reader, &sub, 2));
+ fail_unless (gst_byte_reader_get_uint16_be (&sub, &v));
+ fail_unless_equals_int (v, 0x0e0f);
+ fail_if (gst_byte_reader_get_uint16_be (&sub, &v));
+ fail_if (gst_byte_reader_get_uint16_be (&reader, &v));
+}
+
+GST_END_TEST;
+
static Suite *
gst_byte_reader_suite (void)
{
@@ -715,6 +796,7 @@ gst_byte_reader_suite (void)
tcase_add_test (tc_chain, test_scan);
tcase_add_test (tc_chain, test_string_funcs);
tcase_add_test (tc_chain, test_dup_string);
+ tcase_add_test (tc_chain, test_sub_reader);
return s;
}
diff --git a/win32/common/libgstbase.def b/win32/common/libgstbase.def
index bd31d95bd9..92c35007ab 100644
--- a/win32/common/libgstbase.def
+++ b/win32/common/libgstbase.def
@@ -142,6 +142,7 @@ EXPORTS
gst_byte_reader_get_remaining
gst_byte_reader_get_size
gst_byte_reader_get_string_utf8
+ gst_byte_reader_get_sub_reader
gst_byte_reader_get_uint16_be
gst_byte_reader_get_uint16_le
gst_byte_reader_get_uint24_be
@@ -170,6 +171,7 @@ EXPORTS
gst_byte_reader_peek_int64_le
gst_byte_reader_peek_int8
gst_byte_reader_peek_string_utf8
+ gst_byte_reader_peek_sub_reader
gst_byte_reader_peek_uint16_be
gst_byte_reader_peek_uint16_le
gst_byte_reader_peek_uint24_be