add dynamic buffers

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2583 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale
2006-09-08 18:57:24 +00:00
parent 4960fbc73f
commit f689b62fb6
9 changed files with 143 additions and 14 deletions

View File

@@ -34,10 +34,17 @@
static uint32_t buffer_id = 0;
typedef enum {
SWITCH_BUFFER_FLAG_DYNAMIC = (1 << 0)
} switch_buffer_flag_t;
struct switch_buffer {
unsigned char *data;
switch_size_t used;
switch_size_t datalen;
switch_size_t max_len;
switch_size_t blocksize;
uint32_t flags;
uint32_t id;
};
@@ -55,6 +62,37 @@ SWITCH_DECLARE(switch_status_t) switch_buffer_create(switch_memory_pool_t *pool,
return SWITCH_STATUS_MEMERR;
}
SWITCH_DECLARE(switch_status_t) switch_buffer_create_dynamic(switch_buffer_t **buffer,
switch_size_t blocksize,
switch_size_t start_len,
switch_size_t max_len)
{
switch_buffer_t *new_buffer;
if ((new_buffer = malloc(sizeof(*new_buffer)))) {
memset(new_buffer, 0, sizeof(*new_buffer));
if (start_len) {
if (!(new_buffer->data = malloc(start_len))) {
free(new_buffer);
return SWITCH_STATUS_MEMERR;
}
memset(new_buffer->data, 0, start_len);
}
new_buffer->max_len = max_len;
new_buffer->datalen = start_len;
new_buffer->id = buffer_id++;
new_buffer->blocksize = blocksize;
switch_set_flag(new_buffer, SWITCH_BUFFER_FLAG_DYNAMIC);
*buffer = new_buffer;
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_MEMERR;
}
SWITCH_DECLARE(switch_size_t) switch_buffer_len(switch_buffer_t *buffer)
{
@@ -69,7 +107,15 @@ SWITCH_DECLARE(switch_size_t) switch_buffer_freespace(switch_buffer_t *buffer)
{
assert(buffer != NULL);
if (switch_test_flag(buffer, SWITCH_BUFFER_FLAG_DYNAMIC)) {
if (buffer->max_len) {
return (switch_size_t) (buffer->max_len - buffer->used);
}
return 1000000;
}
return (switch_size_t) (buffer->datalen - buffer->used);
}
SWITCH_DECLARE(switch_size_t) switch_buffer_inuse(switch_buffer_t *buffer)
@@ -131,8 +177,30 @@ SWITCH_DECLARE(switch_size_t) switch_buffer_write(switch_buffer_t *buffer, void
assert(buffer != NULL);
assert(data != NULL);
assert(buffer->data != NULL);
freespace = buffer->datalen - buffer->used;
if (switch_test_flag(buffer, SWITCH_BUFFER_FLAG_DYNAMIC)) {
if (freespace < datalen) {
switch_size_t new_size, new_block_size;
new_size = buffer->datalen + datalen;
new_block_size = buffer->datalen + buffer->blocksize;
if (new_block_size > new_size) {
new_size = new_block_size;
}
if (!(buffer->data = realloc(buffer->data, new_size))) {
return 0;
}
buffer->datalen = new_size;
}
}
freespace = buffer->datalen - buffer->used;
if (freespace < datalen) {
return 0;
} else {
@@ -152,3 +220,13 @@ SWITCH_DECLARE(void) switch_buffer_zero(switch_buffer_t *buffer)
buffer->used = 0;
}
SWITCH_DECLARE(void) switch_buffer_destroy(switch_buffer_t **buffer)
{
if (*buffer && switch_test_flag((*buffer), SWITCH_BUFFER_FLAG_DYNAMIC)) {
free((*buffer)->data);
free(*buffer);
}
*buffer = NULL;
}