mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-29 21:21:12 +00:00
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()
This commit is contained in:
parent
b9fa37f074
commit
86d7a597f0
5 changed files with 172 additions and 1 deletions
|
@ -442,6 +442,9 @@ gst_byte_reader_free
|
||||||
|
|
||||||
gst_byte_reader_init
|
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_pos
|
||||||
gst_byte_reader_get_remaining
|
gst_byte_reader_get_remaining
|
||||||
gst_byte_reader_set_pos
|
gst_byte_reader_set_pos
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* GStreamer byte reader
|
/* GStreamer byte reader
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
|
* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -99,6 +99,56 @@ gst_byte_reader_init (GstByteReader * reader, const guint8 * data, guint size)
|
||||||
reader->byte = 0;
|
reader->byte = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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:
|
* gst_byte_reader_set_pos:
|
||||||
* @reader: a #GstByteReader instance
|
* @reader: a #GstByteReader instance
|
||||||
|
|
|
@ -52,6 +52,14 @@ void gst_byte_reader_free (GstByteReader *reader);
|
||||||
|
|
||||||
void gst_byte_reader_init (GstByteReader *reader, const guint8 *data, guint size);
|
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);
|
gboolean gst_byte_reader_set_pos (GstByteReader *reader, guint pos);
|
||||||
guint gst_byte_reader_get_pos (const GstByteReader *reader);
|
guint gst_byte_reader_get_pos (const GstByteReader *reader);
|
||||||
|
|
||||||
|
@ -455,6 +463,32 @@ _gst_byte_reader_init_inline (GstByteReader * reader, const guint8 * data, guint
|
||||||
reader->byte = 0;
|
reader->byte = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static inline gboolean
|
||||||
_gst_byte_reader_dup_data_inline (GstByteReader * reader, guint size, guint8 ** val)
|
_gst_byte_reader_dup_data_inline (GstByteReader * reader, guint size, guint8 ** val)
|
||||||
{
|
{
|
||||||
|
|
|
@ -696,6 +696,87 @@ GST_START_TEST (test_dup_string)
|
||||||
|
|
||||||
GST_END_TEST;
|
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 *
|
static Suite *
|
||||||
gst_byte_reader_suite (void)
|
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_scan);
|
||||||
tcase_add_test (tc_chain, test_string_funcs);
|
tcase_add_test (tc_chain, test_string_funcs);
|
||||||
tcase_add_test (tc_chain, test_dup_string);
|
tcase_add_test (tc_chain, test_dup_string);
|
||||||
|
tcase_add_test (tc_chain, test_sub_reader);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,6 +142,7 @@ EXPORTS
|
||||||
gst_byte_reader_get_remaining
|
gst_byte_reader_get_remaining
|
||||||
gst_byte_reader_get_size
|
gst_byte_reader_get_size
|
||||||
gst_byte_reader_get_string_utf8
|
gst_byte_reader_get_string_utf8
|
||||||
|
gst_byte_reader_get_sub_reader
|
||||||
gst_byte_reader_get_uint16_be
|
gst_byte_reader_get_uint16_be
|
||||||
gst_byte_reader_get_uint16_le
|
gst_byte_reader_get_uint16_le
|
||||||
gst_byte_reader_get_uint24_be
|
gst_byte_reader_get_uint24_be
|
||||||
|
@ -170,6 +171,7 @@ EXPORTS
|
||||||
gst_byte_reader_peek_int64_le
|
gst_byte_reader_peek_int64_le
|
||||||
gst_byte_reader_peek_int8
|
gst_byte_reader_peek_int8
|
||||||
gst_byte_reader_peek_string_utf8
|
gst_byte_reader_peek_string_utf8
|
||||||
|
gst_byte_reader_peek_sub_reader
|
||||||
gst_byte_reader_peek_uint16_be
|
gst_byte_reader_peek_uint16_be
|
||||||
gst_byte_reader_peek_uint16_le
|
gst_byte_reader_peek_uint16_le
|
||||||
gst_byte_reader_peek_uint24_be
|
gst_byte_reader_peek_uint24_be
|
||||||
|
|
Loading…
Reference in a new issue