[asterisk-commits] twilson: branch twilson/sip_binarification r314548 - in /team/twilson/sip_bin...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Apr 20 18:01:08 CDT 2011
Author: twilson
Date: Wed Apr 20 18:01:06 2011
New Revision: 314548
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=314548
Log:
Add an alloca'd version of buffers, rename another ast_buf member
I have to make the size of the opaque struct known to do this. It is a little
ugly, but it works.
Modified:
team/twilson/sip_binarification/include/asterisk/buffers.h
team/twilson/sip_binarification/main/buffers.c
team/twilson/sip_binarification/tests/test_buffers.c
Modified: team/twilson/sip_binarification/include/asterisk/buffers.h
URL: http://svnview.digium.com/svn/asterisk/team/twilson/sip_binarification/include/asterisk/buffers.h?view=diff&rev=314548&r1=314547&r2=314548
==============================================================================
--- team/twilson/sip_binarification/include/asterisk/buffers.h (original)
+++ team/twilson/sip_binarification/include/asterisk/buffers.h Wed Apr 20 18:01:06 2011
@@ -164,6 +164,8 @@
struct ast_threadstorage;
+extern size_t __ast_buf_struct_size;
+
#if !defined(DEBUG_THREADLOCALS)
struct ast_buf *ast_buf_thread_get(struct ast_threadstorage *ts, size_t init_len);
#else /* defined(DEBUG_THREADLOCALS) */
@@ -183,4 +185,14 @@
/*!\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);
+#define ast_buf_alloca(init_len) \
+ ({ \
+ struct ast_buf *__ast_buf_buf; \
+ __ast_buf_buf = alloca(__ast_buf_struct_size + init_len + 1); \
+ __ast_buf_alloca_init(__ast_buf_buf, init_len); \
+ (__ast_buf_buf); \
+ })
+
+/*!\brief Allocate an ast_buf with temporary storage */
+void __ast_buf_alloca_init(struct ast_buf *buf, size_t init_len);
#endif /* _ASTERISK_BUFFERS_H */
Modified: team/twilson/sip_binarification/main/buffers.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/sip_binarification/main/buffers.c?view=diff&rev=314548&r1=314547&r2=314548
==============================================================================
--- team/twilson/sip_binarification/main/buffers.c (original)
+++ team/twilson/sip_binarification/main/buffers.c Wed Apr 20 18:01:06 2011
@@ -37,13 +37,15 @@
struct ast_buf {
size_t size; /*!< The current maximum length of the buffer */
size_t used; /*!< Amount of space used */
- struct ast_threadstorage *__AST_BUF_TS; /*!< What kind of storage is this ? */
+ struct ast_threadstorage *storage; /*!< 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 buffer[0]; /*!< The buffer buffer */
};
+size_t __ast_buf_struct_size = sizeof(struct ast_buf);
+
static int __ast_buf_helper(struct ast_buf **buf, ssize_t maxlen, const unsigned char *src, size_t srclen, int append)
{
int dynamic = 0;
@@ -55,7 +57,9 @@
srclen = MIN(srclen, left);
break;
case 0 :
- dynamic = 1;
+ if ((*buf)->storage == DS_MALLOC) {
+ dynamic = 1;
+ }
break;
default :
srclen = MIN(srclen, maxlen);
@@ -86,7 +90,7 @@
buf->size = init_len;
buf->used = 0;
- buf->__AST_BUF_TS = DS_MALLOC;
+ buf->storage = DS_MALLOC;
buf->buffer[init_len] = '\0';
return buf;
@@ -102,7 +106,7 @@
buf->size = init_len;
buf->used = 0;
- buf->__AST_BUF_TS = DS_MALLOC;
+ buf->storage = DS_MALLOC;
buf->buffer[init_len] = '\0';
return buf;
@@ -157,15 +161,15 @@
if (new_len <= (*buf)->size)
return 0; /* success */
- if ((*buf)->__AST_BUF_TS == DS_ALLOCA || (*buf)->__AST_BUF_TS == DS_STATIC)
+ if ((*buf)->storage == DS_ALLOCA || (*buf)->storage == 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 ((*buf)->storage != DS_MALLOC) {
+ pthread_setspecific((*buf)->storage->key, *buf);
#if defined(DEBUG_THREADLOCALS)
__ast_threadstorage_object_replace(old_buf, *buf, new_len + sizeof(struct ast_buf) + 1);
#endif /* defined(DEBUG_THREADLOCALS) */
@@ -183,15 +187,15 @@
if (new_len <= (*buf)->size)
return 0; /* success */
- if ((*buf)->__AST_BUF_TS == DS_ALLOCA || (*buf)->__AST_BUF_TS == DS_STATIC)
+ if ((*buf)->storage == DS_ALLOCA || (*buf)->storage == 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 ((*buf)->storage != DS_MALLOC) {
+ pthread_setspecific((*buf)->storage->key, *buf);
#if defined(DEBUG_THREADLOCALS)
__ast_threadstorage_object_replace(old_buf, *buf, new_len + sizeof(struct ast_buf) + 1);
#endif /* defined(DEBUG_THREADLOCALS) */
@@ -235,7 +239,7 @@
if (!buf->size) {
buf->size = init_len;
buf->used = 0;
- buf->__AST_BUF_TS = ts;
+ buf->storage = ts;
buf->buffer[init_len] = '\0';
}
@@ -254,7 +258,7 @@
if (!buf->size) {
buf->size = init_len;
buf->used = 0;
- buf->__AST_BUF_TS = ts;
+ buf->storage = storage;
buf->AST_BUF_BUFFER[init_len] = '\0';
}
@@ -273,3 +277,11 @@
{
return __ast_buf_helper(buf, maxlen, src, srclen, 1);
}
+
+void __ast_buf_alloca_init(struct ast_buf *buf, size_t init_len)
+{
+ buf->size = init_len;
+ buf->used = 0;
+ buf->storage = DS_ALLOCA;
+ buf->buffer[init_len] = '\0';
+}
Modified: team/twilson/sip_binarification/tests/test_buffers.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/sip_binarification/tests/test_buffers.c?view=diff&rev=314548&r1=314547&r2=314548
==============================================================================
--- team/twilson/sip_binarification/tests/test_buffers.c (original)
+++ team/twilson/sip_binarification/tests/test_buffers.c Wed Apr 20 18:01:06 2011
@@ -39,10 +39,16 @@
#include "asterisk/buffers.h"
#include "asterisk/module.h"
+#define fail_with_message(test, res, label, args...) ({ \
+ ast_test_status_update(test, args); \
+ res = AST_TEST_FAIL; \
+ goto label; \
+})
+
#define TEST_BUF_INITIAL_SIZE 30
AST_TEST_DEFINE(buf_test)
{
- struct ast_buf *buf = NULL, *bufcopy = NULL;
+ struct ast_buf *buf = NULL, *bufcopy = NULL, *tmpbuf, *tmpbufcopy;
/* 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 };
@@ -62,165 +68,113 @@
}
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;
+ fail_with_message(test, res, cleanup, "Failed to allocate an ast_buf on the heap\n");
}
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;
+ fail_with_message(test, res, cleanup, "Newly created buffer has non-zero length\n");
}
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;
+ fail_with_message(test, res, cleanup, "Newly created buffer has incorrect size\n");
}
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;
+ fail_with_message(test, res, cleanup, "Safety NULL at end of buffer is missing after create!\n");
}
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;
+ fail_with_message(test, res, cleanup, "Error setting buffer\n");
}
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;
+ fail_with_message(test, res, cleanup, "Buffer length not updated properly after set\n");
}
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;
+ fail_with_message(test, res, cleanup, "ast_buf_set failed for buffer\n");
}
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;
+ fail_with_message(test, res, cleanup, "Safety NULL at end of buffer is missing after set!\n");
}
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;
+ fail_with_message(test, res, cleanup, "Error appending buffer\n");
}
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;
+ fail_with_message(test, res, cleanup, "Error with test. buf_both is the wrong size!\n");
}
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;
+ fail_with_message(test, res, cleanup, "Buffer length not update properly after append\n");
}
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;
+ fail_with_message(test, res, cleanup, "ast_buf_append failed for buffer\n");
}
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;
+ fail_with_message(test, res, cleanup, "Safety NULL at end of buffer is missing after append!\n");
}
if (!ast_buf_truncate(buf, sizeof(buf_one))) {
- ast_test_status_update(test, "Failed to truncate buffer!\n");
- res = AST_TEST_FAIL;
- goto cleanup;
+ fail_with_message(test, res, cleanup, "Failed to truncate buffer!\n");
}
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;
+ fail_with_message(test, res, cleanup, "Truncate resulted in buffer of wrong length\n");
}
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;
+ fail_with_message(test, res, cleanup, "Truncate caused buffer corruption\n");
}
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;
+ fail_with_message(test, res, cleanup, "Rest buffer has non-zero length\n");
}
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;
+ fail_with_message(test, res, cleanup, "Failed to append in loop\n");
}
}
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;
+ fail_with_message(test, res, cleanup, "Multiple appends result in wrong length\n");
}
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;
+ fail_with_message(test, res, cleanup, "Multiple appends resulted in buffer corruption\n");
}
}
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;
+ fail_with_message(test, res, cleanup, "Safety NULL at end of buffer is missing after append causes expansion!\n");
}
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;
+ fail_with_message(test, res, cleanup, "Failed to allocate bufcopy on the heap\n");
}
if (ast_buf_copy_buffer(&bufcopy, buf)) {
- ast_test_status_update(test, "Buffer copy failed\n");
- res = AST_TEST_FAIL;
- goto cleanup;
+ fail_with_message(test, res, cleanup, "Buffer copy failed\n");
}
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;
+ fail_with_message(test, res, cleanup, "Copied buffer has different length. Expected %zu got %zu\n", ast_buf_len(buf), ast_buf_len(bufcopy));
}
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;
+ fail_with_message(test, res, cleanup, "Copied buffer has corrupted data\n");
}
if (ast_buf_cmp(buf, bufcopy)) {
- ast_test_status_update(test, "ast_buf_cmp returned different result from memcmp\n");
- res = AST_TEST_FAIL;
- goto cleanup;
+ fail_with_message(test, res, cleanup, "ast_buf_cmp returned different result from memcmp\n");
}
ast_buf_reset(buf);
@@ -228,22 +182,128 @@
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;
+ fail_with_message(test, res, cleanup, "ast_buf_zero failed to set all bytes to 0\n");
}
}
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;
+ fail_with_message(test, res, cleanup, "Error setting buffer\n");
}
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;
+ fail_with_message(test, res, cleanup, "Copied more bytes to buffer than limit\n");
+ }
+
+ /* alloca'd tests */
+ if (!(tmpbuf = ast_buf_alloca(TEST_BUF_INITIAL_SIZE))) {
+ fail_with_message(test, res, cleanup, "Couldn't alloca a buf\n");
+ }
+
+ if (!(tmpbuf = ast_buf_create(TEST_BUF_INITIAL_SIZE))) {
+ fail_with_message(test, res, cleanup, "Failed to allocate an ast_buf on the heap\n");
+ }
+
+ if (ast_buf_len(tmpbuf) != 0) {
+ fail_with_message(test, res, cleanup, "Newly created buffer has non-zero length\n");
+ }
+
+ if (ast_buf_size(tmpbuf) != TEST_BUF_INITIAL_SIZE) {
+ fail_with_message(test, res, cleanup, "Newly created buffer has incorrect size\n");
+ }
+
+ if (ast_buf_buffer(tmpbuf)[ast_buf_size(tmpbuf)] != '\0') {
+ fail_with_message(test, res, cleanup, "Safety NULL at end of buffer is missing after create!\n");
+ }
+
+ if (ast_buf_set(&tmpbuf, 0, buf_one, sizeof(buf_one)) < 0) {
+ fail_with_message(test, res, cleanup, "Error setting buffer\n");
+ }
+
+ if (ast_buf_len(tmpbuf) != sizeof(buf_one)) {
+ fail_with_message(test, res, cleanup, "Buffer length not updated properly after set\n");
+ }
+
+ if (memcmp(ast_buf_buffer(tmpbuf), buf_one, MIN(sizeof(buf_one), ast_buf_len(tmpbuf)))) {
+ fail_with_message(test, res, cleanup, "ast_buf_set failed for buffer\n");
+ }
+
+ if (ast_buf_buffer(tmpbuf)[ast_buf_size(tmpbuf)] != '\0') {
+ fail_with_message(test, res, cleanup, "Safety NULL at end of buffer is missing after set!\n");
+ }
+
+ if (ast_buf_append(&tmpbuf, 0, buf_two, sizeof(buf_two)) < 0) {
+ fail_with_message(test, res, cleanup, "Error appending buffer\n");
+ }
+
+ if (sizeof(buf_both) != sizeof(buf_one) + sizeof(buf_two)) {
+ fail_with_message(test, res, cleanup, "Error with test. buf_both is the wrong size!\n");
+ }
+
+ if (ast_buf_len(tmpbuf) != sizeof(buf_both)) {
+ fail_with_message(test, res, cleanup, "Buffer length not update properly after append\n");
+ }
+
+ if (memcmp(ast_buf_buffer(tmpbuf), buf_both, sizeof(buf_both))) {
+ fail_with_message(test, res, cleanup, "ast_buf_append failed for buffer\n");
+ }
+
+ if (ast_buf_buffer(tmpbuf)[ast_buf_size(tmpbuf)] != '\0') {
+ fail_with_message(test, res, cleanup, "Safety NULL at end of buffer is missing after append!\n");
+ }
+
+ if (!ast_buf_truncate(tmpbuf, sizeof(buf_one))) {
+ fail_with_message(test, res, cleanup, "Failed to truncate buffer!\n");
+ }
+
+ if (ast_buf_len(tmpbuf) != sizeof(buf_one)) {
+ fail_with_message(test, res, cleanup, "Truncate resulted in buffer of wrong length\n");
+ }
+
+ if (memcmp(ast_buf_buffer(tmpbuf), buf_one, sizeof(buf_one))) {
+ fail_with_message(test, res, cleanup, "Truncate caused buffer corruption\n");
+ }
+
+ ast_buf_reset(tmpbuf);
+
+ if (ast_buf_len(tmpbuf) != 0) {
+ fail_with_message(test, res, cleanup, "Rest buffer has non-zero length\n");
+ }
+
+ if (!(tmpbufcopy = ast_buf_alloca(TEST_BUF_INITIAL_SIZE))) {
+ fail_with_message(test, res, cleanup, "Failed to allocate bufcopy on the heap\n");
+ }
+
+ if (ast_buf_copy_buffer(&tmpbufcopy, tmpbuf)) {
+ fail_with_message(test, res, cleanup, "Buffer copy failed\n");
+ }
+
+ if (ast_buf_len(tmpbuf) != ast_buf_len(tmpbufcopy)) {
+ fail_with_message(test, res, cleanup, "Copied buffer has different length. Expected %zu got %zu\n", ast_buf_len(tmpbuf), ast_buf_len(tmpbufcopy));
+ }
+
+ if (memcmp(ast_buf_buffer(tmpbuf), ast_buf_buffer(tmpbufcopy), ast_buf_len(tmpbuf))) {
+ fail_with_message(test, res, cleanup, "Copied buffer has corrupted data\n");
+ }
+
+ if (ast_buf_cmp(tmpbuf, tmpbufcopy)) {
+ fail_with_message(test, res, cleanup, "ast_buf_cmp returned different result from memcmp\n");
+ }
+
+ ast_buf_reset(tmpbuf);
+ ast_buf_zero(tmpbuf);
+
+ for (x = 0; x < ast_buf_size(tmpbuf); x++) {
+ if (ast_buf_buffer(tmpbuf)[x] != '\0') {
+ fail_with_message(test, res, cleanup, "ast_buf_zero failed to set all bytes to 0\n");
+ }
+ }
+
+ if (ast_buf_set(&tmpbuf, 3, buf_one, sizeof(buf_one)) < 0) {
+ fail_with_message(test, res, cleanup, "Error setting buffer\n");
+ }
+
+ if (ast_buf_buffer(tmpbuf)[4] != '\0') {
+ fail_with_message(test, res, cleanup, "Copied more bytes to buffer than limit\n");
}
cleanup:
More information about the asterisk-commits
mailing list