[asterisk-commits] twilson: branch twilson/sip_binarification r314470 - in /team/twilson/sip_bin...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Apr 20 14:30:31 CDT 2011
Author: twilson
Date: Wed Apr 20 14:30:29 2011
New Revision: 314470
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=314470
Log:
Add a binary buffer API similar to ast_str_
Added:
team/twilson/sip_binarification/include/asterisk/buffers.h (with props)
team/twilson/sip_binarification/main/buffers.c (with props)
team/twilson/sip_binarification/tests/test_buffers.c (with props)
Added: team/twilson/sip_binarification/include/asterisk/buffers.h
URL: http://svnview.digium.com/svn/asterisk/team/twilson/sip_binarification/include/asterisk/buffers.h?view=auto&rev=314470
==============================================================================
--- team/twilson/sip_binarification/include/asterisk/buffers.h (added)
+++ team/twilson/sip_binarification/include/asterisk/buffers.h Wed Apr 20 14:30:29 2011
@@ -1,0 +1,176 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2011, Digium, Inc.
+ *
+ * Mark Spencer <markster at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Buffer manipulation functions
+ */
+
+#ifndef _ASTERISK_BUFFERS_H
+#define _ASTERISK_BUFFERS_H
+
+/*!
+ * Support for dynamic buffers.
+ *
+ * A dynamic buffer is just a allocated prefixed by a few control fields
+ * that help setting/appending/extending it.
+ *
+ * One should never declare a variable with this type, but only a pointer
+ * to it, e.g.
+ *
+ * struct ast_buf *buf;
+ *
+ * The pointer can be initialized with the following:
+ *
+ * buf = ast_buf_create(init_len);
+ * creates a malloc()'ed dynamic buffer;
+ *
+ * buf = ast_buf_thread_get(ts, init_len)
+ * creates a malloc()'ed dynamic buffer associated to
+ * the thread-local storage key ts
+ *
+ * Finally, the buffer can be manipulated with the following:
+ *
+ * ast_buf_set(&buf, max_len, src, src_len)
+ * ast_buf_append(&buf, max_len, src, src_len)
+ *
+ * \param max_len The maximum allowed capacity of the ast_buf. Note that
+ * 0 means unlimited, -1 means "at most the available space"
+ *
+ * \return All the functions return < 0 in case of error, or the
+ * length of the buffer added to the buffer otherwise. Note that
+ * in most cases where an error is returned, characters ARE written
+ * to the ast_buf.
+ */
+
+struct ast_buf;
+
+/*!
+ * \brief Create a malloc'ed dynamic length buffer
+ *
+ * \param init_len This is the initial length of the buffer buffer
+ *
+ * \return This function returns a pointer to the dynamic buffer length. The
+ * result will be NULL in the case of a memory allocation error.
+ *
+ * \note The result of this function is dynamically allocated memory, and must
+ * be free()'d after it is no longer needed.
+ */
+#if (defined(MALLOC_DEBUG) && !defined(STANDALONE))
+#define ast_buf_create(a) _ast_buf_create(a,__FILE__,__LINE__,__PRETTY_FUNCTION__)
+struct ast_buf * attribute_malloc _ast_buf_create(size_t init_len,
+ const char *file, int lineno, const char *func);
+#else
+struct ast_buf * attribute_malloc ast_buf_create(size_t init_len);
+#endif
+
+/*!\brief Resets the buffer length to 0
+ * \note Contents are then invalid, but not zeroed out.
+ */
+void ast_buf_reset(struct ast_buf *buf);
+
+/*!\brief Returns the current length of the buffer stored within buf.
+ * \param buf A pointer to the ast_buf structure.
+ * \return Number of bytes used
+ */
+size_t attribute_pure ast_buf_len(const struct ast_buf *buf);
+
+/*!\brief Returns the current maximum length (without reallocation) of the current buffer.
+ * \param buf A pointer to the ast_buf structure.
+ * \return Current maximum length of the buffer.
+ */
+size_t attribute_pure ast_buf_size(const struct ast_buf *buf);
+
+/*!\brief Returns the buffer buffer within the ast_buf buf.
+ * \param buf A pointer to the ast_buf structure.
+ * \return A pointer to the enclosed buffer contents.
+ */
+const unsigned char * attribute_pure ast_buf_buffer(const struct ast_buf *buf);
+
+/*!\brief Truncates the enclosed buffer to the given length.
+ * \param buf A pointer to the ast_buf structure.
+ * \param len Maximum length of the buffer. If negative, the number of bytes to remove.
+ * \return A pointer to the resulting buffer.
+ */
+unsigned char *ast_buf_truncate(struct ast_buf *buf, ssize_t len);
+
+/*!
+ * Make space in a new buffer (e.g. to read in data from a file)
+ */
+#if (defined(MALLOC_DEBUG) && !defined(STANDALONE))
+int _ast_buf_make_space(struct ast_buf **buf, size_t new_len, const char *file, int lineno, const char *function);
+#define ast_buf_make_space(a,b) _ast_buf_make_space(a,b,__FILE__,__LINE__,__PRETTY_FUNCTION__)
+#else
+int ast_buf_make_space(struct ast_buf **buf, size_t new_len);
+#endif
+
+int ast_buf_copy_buffer(struct ast_buf **dst, struct ast_buf *src);
+
+/*!
+ * \brief Retrieve a thread locally stored dynamic buffer
+ *
+ * \param ts This is a pointer to the thread storage structure declared by using
+ * the AST_THREADSTORAGE macro. If declared with
+ * AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be
+ * (&my_buf).
+ * \param init_len This is the initial length of the thread's dynamic buffer. The
+ * current length may be bigger if previous operations in this thread have
+ * caused it to increase.
+ *
+ * \return This function will return the thread locally stored dynamic buffer
+ * associated with the thread storage management variable passed as the
+ * first argument.
+ * The result will be NULL in the case of a memory allocation error.
+ *
+ * Example usage:
+ * \code
+ * AST_THREADSTORAGE(my_buf, my_buf_init);
+ * #define MY_BUF_INIT_SIZE 128
+ * ...
+ * void my_func(const char *fmt, ...)
+ * {
+ * struct ast_buf *buf;
+ *
+ * if (!(buf = ast_buf_thread_get(&my_buf, MY_BUF_INIT_SIZE)))
+ * return;
+ * ...
+ * }
+ * \endcode
+ */
+
+struct ast_threadstorage;
+
+#if !defined(DEBUG_THREADLOCALS)
+struct ast_buf *ast_buf_thread_get(struct ast_threadstorage *ts, size_t init_len);
+#else /* defined(DEBUG_THREADLOCALS) */
+struct ast_buf *__ast_buf_thread_get(struct ast_threadstorage *ts,
+ size_t init_len, const char *file, const char *function, unsigned int line);
+
+#define ast_buf_thread_get(ts, init_len) __ast_buf_thread_get(ts, init_len, __FILE__, __PRETTY_FUNCTION__, __LINE__)
+#endif /* defined(DEBUG_THREADLOCALS) */
+
+/*!\brief Set a dynamic buffer to a non-NULL terminated subbuffer. */
+int ast_buf_set(struct ast_buf **buf, ssize_t maxlen, const unsigned char *src, size_t maxsrc);
+
+/*!\brief Set all bytes in a buffer to zero
+ */
+void ast_buf_zero(struct ast_buf *buf);
+
+/*!\brief Append a non-NULL terminated subbuffer to the end of a dynamic buffer. */
+int ast_buf_append(struct ast_buf **buf, ssize_t maxlen, const unsigned char *src, size_t maxsrc);
+
+#endif /* _ASTERISK_BUFFERS_H */
Propchange: team/twilson/sip_binarification/include/asterisk/buffers.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/twilson/sip_binarification/include/asterisk/buffers.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/twilson/sip_binarification/include/asterisk/buffers.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/twilson/sip_binarification/main/buffers.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/sip_binarification/main/buffers.c?view=auto&rev=314470
==============================================================================
--- team/twilson/sip_binarification/main/buffers.c (added)
+++ team/twilson/sip_binarification/main/buffers.c Wed Apr 20 14:30:29 2011
@@ -1,0 +1,270 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2011, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+* the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief Buffer manipulation API
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/buffers.h"
+#include "asterisk/utils.h"
+#include "asterisk/threadstorage.h"
+
+/*! \brief The descriptor of a dynamic buffer
+ * XXX storage will be optimized later if needed
+ * We use the ts field to indicate the type of storage.
+ * Three special constants indicate malloc, alloca() or static
+ * variables, all other values indicate a
+ * struct ast_threadstorage pointer.
+ */
+struct ast_buf {
+ size_t __AST_BUF_SIZE; /*!< The current maximum length of the buffer */
+ size_t __AST_BUF_USED; /*!< Amount of space used */
+ struct ast_threadstorage *__AST_BUF_TS; /*!< What kind of storage is this ? */
+#define DS_MALLOC ((struct ast_threadstorage *)1)
+#define DS_ALLOCA ((struct ast_threadstorage *)2)
+#define DS_STATIC ((struct ast_threadstorage *)3) /* not supported yet */
+ unsigned char __AST_BUF_BUFFER[0]; /*!< The buffer buffer */
+};
+
+static int __ast_buf_helper(struct ast_buf **buf, ssize_t maxlen, const unsigned char *src, size_t srclen, int append)
+{
+ int dynamic = 0;
+ size_t left = (*buf)->__AST_BUF_SIZE - (*buf)->__AST_BUF_USED;
+ unsigned char *ptr;
+
+ switch (maxlen) {
+ case -1 :
+ srclen = MIN(srclen, left);
+ break;
+ case 0 :
+ dynamic = 1;
+ break;
+ default :
+ srclen = MIN(srclen, maxlen);
+ }
+
+ if (left < srclen && dynamic) {
+ if (ast_buf_make_space(buf, MAX((*buf)->__AST_BUF_SIZE * 2, srclen - left + (*buf)->__AST_BUF_SIZE))) {
+ return -1;
+ }
+ }
+
+ ptr = append ? &((*buf)->__AST_BUF_BUFFER[(*buf)->__AST_BUF_USED]) : (*buf)->__AST_BUF_BUFFER;
+ memcpy(ptr, src, srclen);
+ (*buf)->__AST_BUF_USED += srclen;
+
+ return 0;
+}
+
+#if (defined(MALLOC_DEBUG) && !defined(STANDALONE))
+struct ast_buf * attribute_malloc _ast_buf_create(size_t init_len,
+ const char *file, int lineno, const char *func)
+{
+ struct ast_buf *buf;
+
+ buf = (struct ast_buf *)__ast_malloc(sizeof(*buf) + init_len + 1, file, lineno, func);
+ if (buf == NULL)
+ return NULL;
+
+ buf->__AST_BUF_SIZE = init_len;
+ buf->__AST_BUF_USED = 0;
+ buf->__AST_BUF_TS = DS_MALLOC;
+ buf->__AST_BUF_BUFFER[init_len] = '\0';
+
+ return buf;
+}
+#else
+struct ast_buf * attribute_malloc ast_buf_create(size_t init_len)
+{
+ struct ast_buf *buf;
+
+ buf = (struct ast_buf *)ast_malloc(sizeof(*buf) + init_len + 1);
+ if (buf == NULL)
+ return NULL;
+
+ buf->__AST_BUF_SIZE = init_len;
+ buf->__AST_BUF_USED = 0;
+ buf->__AST_BUF_TS = DS_MALLOC;
+ buf->__AST_BUF_BUFFER[init_len] = '\0';
+
+ return buf;
+}
+#endif
+
+void ast_buf_reset(struct ast_buf *buf)
+{
+ if (buf) {
+ buf->__AST_BUF_USED = 0;
+ }
+}
+
+void ast_buf_zero(struct ast_buf *buf)
+{
+ size_t x;
+
+ for (x = 0; x < buf->__AST_BUF_SIZE; x++) {
+ buf->__AST_BUF_BUFFER[x] = '\0';
+ }
+}
+
+size_t attribute_pure ast_buf_len(const struct ast_buf *buf)
+{
+ return buf->__AST_BUF_USED;
+}
+
+size_t attribute_pure ast_buf_size(const struct ast_buf *buf)
+{
+ return buf->__AST_BUF_SIZE;
+}
+
+const unsigned char * attribute_pure ast_buf_buffer(const struct ast_buf *buf)
+{
+ return buf->__AST_BUF_BUFFER;
+}
+
+unsigned char *ast_buf_truncate(struct ast_buf *buf, ssize_t len)
+{
+ if (len < 0) {
+ buf->__AST_BUF_USED += ((ssize_t) abs(len)) > (ssize_t) buf->__AST_BUF_USED ? -buf->__AST_BUF_USED : len;
+ } else {
+ buf->__AST_BUF_USED = len;
+ }
+ return buf->__AST_BUF_BUFFER;
+}
+
+#if (defined(MALLOC_DEBUG) && !defined(STANDALONE))
+int _ast_buf_make_space(struct ast_buf **buf, size_t new_len, const char *file, int lineno, const char *function)
+{
+ struct ast_buf *old_buf = *buf;
+
+ if (new_len <= (*buf)->__AST_BUF_SIZE)
+ return 0; /* success */
+ if ((*buf)->__AST_BUF_TS == DS_ALLOCA || (*buf)->__AST_BUF_TS == DS_STATIC)
+ return -1; /* cannot extend */
+ *buf = (struct ast_buf *)__ast_realloc(*buf, new_len + sizeof(struct ast_buf) + 1, file, lineno, function);
+ if (*buf == NULL) {
+ *buf = old_buf;
+ return -1;
+ }
+ if ((*buf)->__AST_BUF_TS != DS_MALLOC) {
+ pthread_setspecific((*buf)->__AST_BUF_TS->key, *buf);
+#if defined(DEBUG_THREADLOCALS)
+ __ast_threadstorage_object_replace(old_buf, *buf, new_len + sizeof(struct ast_buf) + 1);
+#endif /* defined(DEBUG_THREADLOCALS) */
+ }
+
+ (*buf)->__AST_BUF_SIZE = new_len;
+ (*buf)->__AST_BUF_BUFFER[new_len] = '\0';
+ return 0;
+}
+#define ast_buf_make_space(a,b) _ast_buf_make_space(a,b,__FILE__,__LINE__,__PRETTY_FUNCTION__)
+#else
+int ast_buf_make_space(struct ast_buf **buf, size_t new_len)
+{
+ struct ast_buf *old_buf = *buf;
+
+ if (new_len <= (*buf)->__AST_BUF_SIZE)
+ return 0; /* success */
+ if ((*buf)->__AST_BUF_TS == DS_ALLOCA || (*buf)->__AST_BUF_TS == DS_STATIC)
+ return -1; /* cannot extend */
+ *buf = (struct ast_buf *)ast_realloc(*buf, new_len + sizeof(struct ast_buf) + 1);
+ if (*buf == NULL) {
+ *buf = old_buf;
+ return -1;
+ }
+ if ((*buf)->__AST_BUF_TS != DS_MALLOC) {
+ pthread_setspecific((*buf)->__AST_BUF_TS->key, *buf);
+#if defined(DEBUG_THREADLOCALS)
+ __ast_threadstorage_object_replace(old_buf, *buf, new_len + sizeof(struct ast_buf) + 1);
+#endif /* defined(DEBUG_THREADLOCALS) */
+ }
+
+ (*buf)->__AST_BUF_SIZE = new_len;
+ (*buf)->__AST_BUF_BUFFER[new_len] = '\0';
+ return 0;
+}
+#endif
+
+int ast_buf_copy_buffer(struct ast_buf **dst, struct ast_buf *src)
+{
+
+ /* make sure our destination is large enough */
+ if (src->__AST_BUF_USED > (*dst)->__AST_BUF_SIZE) {
+ if (ast_buf_make_space(dst, src->__AST_BUF_USED)) {
+ return -1;
+ }
+ }
+
+ memcpy((*dst)->__AST_BUF_BUFFER, src->__AST_BUF_BUFFER, src->__AST_BUF_USED);
+ (*dst)->__AST_BUF_USED = src->__AST_BUF_USED;
+ return 0;
+}
+
+#if !defined(DEBUG_THREADLOCALS)
+struct ast_buf *ast_buf_thread_get(struct ast_threadstorage *ts, size_t init_len)
+{
+ struct ast_buf *buf;
+
+ buf = (struct ast_buf *)ast_threadstorage_get(ts, sizeof(*buf) + init_len + 1);
+ if (buf == NULL)
+ return NULL;
+
+ if (!buf->__AST_BUF_SIZE) {
+ buf->__AST_BUF_SIZE = init_len;
+ buf->__AST_BUF_USED = 0;
+ buf->__AST_BUF_TS = ts;
+ buf->__AST_BUF_BUFFER[init_len] = '\0';
+ }
+
+ return buf;
+}
+#else /* defined(DEBUG_THREADLOCALS) */
+struct ast_buf *__ast_buf_thread_get(struct ast_threadstorage *ts,
+ size_t init_len, const char *file, const char *function, unsigned int line)
+{
+ struct ast_buf *buf;
+
+ buf = (struct ast_buf *)__ast_threadstorage_get(ts, sizeof(*buf) + init_len + 1, file, function, line);
+ if (buf == NULL)
+ return NULL;
+
+ if (!buf->__AST_BUF_SIZE) {
+ buf->__AST_BUF_SIZE = init_len;
+ buf->__AST_BUF_USED = 0;
+ buf->__AST_BUF_TS = ts;
+ buf->AST_BUF_BUFFER[init_len] = '\0';
+ }
+
+ return buf;
+}
+#endif
+
+/*!\brief Set a dynamic buffer to a non-NULL terminated subbuffer. */
+int ast_buf_set(struct ast_buf **buf, ssize_t maxlen, const unsigned char *src, size_t srclen)
+{
+ return __ast_buf_helper(buf, maxlen, src, srclen, 0);
+}
+
+/*!\brief Append a non-NULL terminated subbuffer to the end of a dynamic buffer. */
+int ast_buf_append(struct ast_buf **buf, ssize_t maxlen, const unsigned char *src, size_t srclen)
+{
+ return __ast_buf_helper(buf, maxlen, src, srclen, 1);
+}
Propchange: team/twilson/sip_binarification/main/buffers.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/twilson/sip_binarification/main/buffers.c
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/twilson/sip_binarification/main/buffers.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/twilson/sip_binarification/tests/test_buffers.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/sip_binarification/tests/test_buffers.c?view=auto&rev=314470
==============================================================================
--- team/twilson/sip_binarification/tests/test_buffers.c (added)
+++ team/twilson/sip_binarification/tests/test_buffers.c Wed Apr 20 14:30:29 2011
@@ -1,0 +1,261 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Dynamic buffer tests
+ *
+ * \author Terry Wilson <twilson at digium.com>
+ *
+ * This module will run some dyanmic buffer tests.
+ *
+ * \ingroup tests
+ */
+
+/*** MODULEINFO
+ <depend>TEST_FRAMEWORK</depend>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/test.h"
+#include "asterisk/buffers.h"
+#include "asterisk/module.h"
+
+#define TEST_BUF_INITIAL_SIZE 30
+AST_TEST_DEFINE(buf_test)
+{
+ struct ast_buf *buf = NULL, *bufcopy = NULL;
+ /* Do not change the contents of these buffers or certain tests will fail */
+ const unsigned char buf_one[] = { 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245 };
+ const unsigned char buf_two[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ const unsigned char buf_both[] = { 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ enum ast_test_result_state res = AST_TEST_PASS;
+ size_t x;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "buf_test";
+ info->category = "/main/buffers/";
+ info->summary = "Test dynamic buffer operations";
+ info->description = "Test setting and appending heap-allocated dynamic buffers";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ if (!(buf = ast_buf_create(TEST_BUF_INITIAL_SIZE))) {
+ ast_test_status_update(test, "Failed to allocate an ast_buf on the heap\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (ast_buf_len(buf) != 0) {
+ ast_test_status_update(test, "Newly created buffer has non-zero length\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (ast_buf_size(buf) != TEST_BUF_INITIAL_SIZE) {
+ ast_test_status_update(test, "Newly created buffer has incorrect size\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (ast_buf_buffer(buf)[ast_buf_size(buf)] != '\0') {
+ ast_test_status_update(test, "Safety NULL at end of buffer is missing after create!\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (ast_buf_set(&buf, 0, buf_one, sizeof(buf_one)) < 0) {
+ ast_test_status_update(test, "Error setting buffer\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (ast_buf_len(buf) != sizeof(buf_one)) {
+ ast_test_status_update(test, "Buffer length not updated properly after set\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (memcmp(ast_buf_buffer(buf), buf_one, MIN(sizeof(buf_one), ast_buf_len(buf)))) {
+ ast_test_status_update(test, "ast_buf_set failed for buffer\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (ast_buf_buffer(buf)[ast_buf_size(buf)] != '\0') {
+ ast_test_status_update(test, "Safety NULL at end of buffer is missing after set!\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (ast_buf_append(&buf, 0, buf_two, sizeof(buf_two)) < 0) {
+ ast_test_status_update(test, "Error appending buffer\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (sizeof(buf_both) != sizeof(buf_one) + sizeof(buf_two)) {
+ ast_test_status_update(test, "Error with test. buf_both is the wrong size!\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (ast_buf_len(buf) != sizeof(buf_both)) {
+ ast_test_status_update(test, "Buffer length not update properly after append\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (memcmp(ast_buf_buffer(buf), buf_both, sizeof(buf_both))) {
+ ast_test_status_update(test, "ast_buf_append failed for buffer\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (ast_buf_buffer(buf)[ast_buf_size(buf)] != '\0') {
+ ast_test_status_update(test, "Safety NULL at end of buffer is missing after append!\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (!ast_buf_truncate(buf, sizeof(buf_one))) {
+ ast_test_status_update(test, "Failed to truncate buffer!\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (ast_buf_len(buf) != sizeof(buf_one)) {
+ ast_test_status_update(test, "Truncate resulted in buffer of wrong length\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (memcmp(ast_buf_buffer(buf), buf_one, sizeof(buf_one))) {
+ ast_test_status_update(test, "Truncate caused buffer corruption\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ ast_buf_reset(buf);
+
+ if (ast_buf_len(buf) != 0) {
+ ast_test_status_update(test, "Rest buffer has non-zero length\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ for (x = ast_buf_size(buf); x >= ast_buf_size(buf); /* nothing */) {
+ if (ast_buf_append(&buf, 0, buf_two, sizeof(buf_two)) < 0) {
+ ast_test_status_update(test, "Failed to append in loop\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+ }
+
+ if (ast_buf_len(buf) % sizeof(buf_two) != 0) {
+ ast_test_status_update(test, "Multiple appends result in wrong length\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ for (x = 0; x < ast_buf_len(buf) / sizeof(buf_two); x++) {
+ if (memcmp(ast_buf_buffer(buf) + (x * sizeof(buf_two)) , buf_two, sizeof(buf_two))) {
+ ast_test_status_update(test, "Multiple appends resulted in buffer corruption\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+ }
+
+ if (ast_buf_buffer(buf)[ast_buf_size(buf)] != '\0') {
+ ast_test_status_update(test, "Safety NULL at end of buffer is missing after append causes expansion!\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (!(bufcopy = ast_buf_create(TEST_BUF_INITIAL_SIZE))) {
+ ast_test_status_update(test, "Failed to allocate bufcopy on the heap\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (ast_buf_copy_buffer(&bufcopy, buf)) {
+ ast_test_status_update(test, "Buffer copy failed\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (ast_buf_len(buf) != ast_buf_len(bufcopy)) {
+ ast_test_status_update(test, "Copied buffer has different length. Expected %zu got %zu\n", ast_buf_len(buf), ast_buf_len(bufcopy));
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (memcmp(ast_buf_buffer(buf), ast_buf_buffer(bufcopy), ast_buf_len(buf))) {
+ ast_test_status_update(test, "Copied buffer has corrupted data\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ ast_buf_reset(buf);
+ ast_buf_zero(buf);
+
+ for (x = 0; x < ast_buf_size(buf); x++) {
+ if (ast_buf_buffer(buf)[x] != '\0') {
+ ast_test_status_update(test, "ast_buf_zero failed to set all bytes to 0\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+ }
+
+ if (ast_buf_set(&buf, 3, buf_one, sizeof(buf_one)) < 0) {
+ ast_test_status_update(test, "Error setting buffer\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (ast_buf_buffer(buf)[4] != '\0') {
+ ast_test_status_update(test, "Copied more bytes to buffer than limit\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+cleanup:
+ ast_free(buf);
+ ast_free(bufcopy);
+ return res;
+}
+
+static int unload_module(void)
+{
+ AST_TEST_UNREGISTER(buf_test);
+ return 0;
+}
+
+static int load_module(void)
+{
+ AST_TEST_REGISTER(buf_test);
+ return AST_MODULE_LOAD_SUCCESS;
+}
+
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dynamic string test module");
Propchange: team/twilson/sip_binarification/tests/test_buffers.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/twilson/sip_binarification/tests/test_buffers.c
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/twilson/sip_binarification/tests/test_buffers.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the asterisk-commits
mailing list