API: add gst_buffer_try_new_and_alloc() plus unit test (#431940).

Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gstbuffer.c: (gst_buffer_try_new_and_alloc):
* gst/gstbuffer.h:
* tests/check/gst/gstbuffer.c: (GST_START_TEST),
(gst_buffer_suite):
API: add gst_buffer_try_new_and_alloc() plus unit test (#431940).
This commit is contained in:
Tim-Philipp Müller 2007-04-26 10:00:49 +00:00
parent 14999bf0f5
commit 2c5a8cdb31
5 changed files with 108 additions and 5 deletions

View file

@ -1,3 +1,12 @@
2007-04-26 Tim-Philipp Müller <tim at centricular dot net>
* docs/gst/gstreamer-sections.txt:
* gst/gstbuffer.c: (gst_buffer_try_new_and_alloc):
* gst/gstbuffer.h:
* tests/check/gst/gstbuffer.c: (GST_START_TEST),
(gst_buffer_suite):
API: add gst_buffer_try_new_and_alloc() plus unit test (#431940).
2007-04-26 Stefan Kost <ensonic@users.sf.net>
* gst/gstregistrybinary.c: (gst_registry_binary_write_cache),

View file

@ -157,6 +157,7 @@ GST_BUFFER_TRACE_NAME
gst_buffer_new
gst_buffer_new_and_alloc
gst_buffer_try_new_and_alloc
gst_buffer_ref
gst_buffer_unref

View file

@ -305,7 +305,12 @@ gst_buffer_new (void)
* @size: the size of the new buffer's data.
*
* Creates a newly allocated buffer with data of the given size.
* The buffer memory is not cleared.
* The buffer memory is not cleared. If the requested amount of
* memory can't be allocated, the program will abort. Use
* gst_buffer_try_new_and_alloc() if you want to handle this case
* gracefully or have gotten the size to allocate from an untrusted
* source such as a media stream.
*
*
* Note that when @size == 0, the buffer data pointer will be NULL.
*
@ -328,6 +333,48 @@ gst_buffer_new_and_alloc (guint size)
return newbuf;
}
/**
* gst_buffer_try_new_and_alloc:
* @size: the size of the new buffer's data.
*
* Tries to create a newly allocated buffer with data of the given size. If
* the requested amount of memory can't be allocated, NULL will be returned.
* The buffer memory is not cleared.
*
* Note that when @size == 0, the buffer data pointer will be NULL.
*
* MT safe.
*
* Returns: a new #GstBuffer, or NULL if the memory couldn't be allocated.
*
* Since: 0.10.13
*/
GstBuffer *
gst_buffer_try_new_and_alloc (guint size)
{
GstBuffer *newbuf;
guint8 *malloc_data;
malloc_data = g_try_malloc (size);
if (G_UNLIKELY (malloc_data == NULL && size != 0)) {
GST_CAT_WARNING (GST_CAT_BUFFER, "failed to allocate %d bytes", size);
return NULL;
}
/* FIXME: there's no g_type_try_create_instance() in GObject yet, so this
* will still abort if a new GstBuffer structure can't be allocated */
newbuf = gst_buffer_new ();
GST_BUFFER_MALLOCDATA (newbuf) = malloc_data;
GST_BUFFER_DATA (newbuf) = malloc_data;
GST_BUFFER_SIZE (newbuf) = size;
GST_CAT_LOG (GST_CAT_BUFFER, "new %p of size %d", newbuf, size);
return newbuf;
}
/**
* gst_buffer_get_caps:
* @buffer: a #GstBuffer.

View file

@ -267,10 +267,12 @@ struct _GstBufferClass {
GstMiniObjectClass mini_object_class;
};
GType gst_buffer_get_type (void);
/* allocation */
GType gst_buffer_get_type (void);
GstBuffer* gst_buffer_new (void);
GstBuffer* gst_buffer_new_and_alloc (guint size);
GstBuffer * gst_buffer_new (void);
GstBuffer * gst_buffer_new_and_alloc (guint size);
GstBuffer * gst_buffer_try_new_and_alloc (guint size);
/**
* gst_buffer_set_data:

View file

@ -20,6 +20,16 @@
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_VALGRIND
# include <valgrind/valgrind.h>
#else
# define RUNNING_ON_VALGRIND FALSE
#endif
#include <gst/check/gstcheck.h>
GST_START_TEST (test_caps)
@ -401,7 +411,40 @@ GST_START_TEST (test_copy)
GST_END_TEST;
Suite *
GST_START_TEST (test_try_new_and_alloc)
{
GstBuffer *buf;
/* special case: alloc of 0 bytes results in new buffer with NULL data */
buf = gst_buffer_try_new_and_alloc (0);
fail_unless (buf != NULL);
fail_unless (GST_IS_BUFFER (buf));
fail_unless (GST_BUFFER_SIZE (buf) == 0);
fail_unless (GST_BUFFER_DATA (buf) == NULL);
fail_unless (GST_BUFFER_MALLOCDATA (buf) == NULL);
gst_buffer_unref (buf);
/* normal alloc should still work */
buf = gst_buffer_try_new_and_alloc (640 * 480 * 4);
fail_unless (buf != NULL);
fail_unless (GST_IS_BUFFER (buf));
fail_unless (GST_BUFFER_SIZE (buf) == (640 * 480 * 4));
fail_unless (GST_BUFFER_DATA (buf) != NULL);
fail_unless (GST_BUFFER_MALLOCDATA (buf) != NULL);
GST_BUFFER_DATA (buf)[640 * 479 * 4 + 479] = 0xff;
gst_buffer_unref (buf);
/* now this better fail (don't run in valgrind, it will abort
* or warn when passing silly arguments to malloc) */
if (!RUNNING_ON_VALGRIND) {
buf = gst_buffer_try_new_and_alloc ((guint) - 1);
fail_unless (buf == NULL);
}
}
GST_END_TEST;
static Suite *
gst_buffer_suite (void)
{
Suite *s = suite_create ("GstBuffer");
@ -416,6 +459,7 @@ gst_buffer_suite (void)
tcase_add_test (tc_chain, test_span);
tcase_add_test (tc_chain, test_metadata_writable);
tcase_add_test (tc_chain, test_copy);
tcase_add_test (tc_chain, test_try_new_and_alloc);
return s;
}