From b6eb0e20dadb80cc110712d6f06faea8fe783e5d Mon Sep 17 00:00:00 2001 From: Yu Qing Date: Fri, 13 Nov 2015 15:13:28 +0800 Subject: [PATCH] add fast_buffer --- HISTORY | 3 +- src/Makefile.in | 9 ++- src/fast_buffer.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++ src/fast_buffer.h | 53 ++++++++++++++++ 4 files changed, 217 insertions(+), 4 deletions(-) create mode 100644 src/fast_buffer.c create mode 100644 src/fast_buffer.h diff --git a/HISTORY b/HISTORY index 2ae0a41..d031265 100644 --- a/HISTORY +++ b/HISTORY @@ -1,5 +1,5 @@ -Version 1.23 2015-11-06 +Version 1.23 2015-11-13 * sched_thread.c: task can execute in a new thread * sched_thread.c: support delay tasks * add function get_current_time_us and get_current_time_ms @@ -9,6 +9,7 @@ Version 1.23 2015-11-06 * delay task can execute in a new thread * fast_mblock reclaimed object pool * add fast_allocator + * add fast_buffer Version 1.22 2015-10-10 * export php function: fastcommon_get_first_local_ip diff --git a/src/Makefile.in b/src/Makefile.in index d724fab..095c9c5 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -10,21 +10,24 @@ FAST_SHARED_OBJS = hash.lo chain.lo shared_func.lo ini_file_reader.lo \ http_func.lo md5.lo pthread_func.lo local_ip_func.lo \ avl_tree.lo ioevent.lo ioevent_loop.lo fast_task_queue.lo \ fast_timer.lo process_ctrl.lo fast_mblock.lo \ - connection_pool.lo fast_mpool.lo fast_allocator.lo + connection_pool.lo fast_mpool.lo fast_allocator.lo \ + fast_buffer.lo FAST_STATIC_OBJS = hash.o chain.o shared_func.o ini_file_reader.o \ logger.o sockopt.o base64.o sched_thread.o \ http_func.o md5.o pthread_func.o local_ip_func.o \ avl_tree.o ioevent.o ioevent_loop.o fast_task_queue.o \ fast_timer.o process_ctrl.o fast_mblock.o \ - connection_pool.o fast_mpool.o fast_allocator.o + connection_pool.o fast_mpool.o fast_allocator.o \ + fast_buffer.o HEADER_FILES = common_define.h hash.h chain.h logger.h base64.h \ shared_func.h pthread_func.h ini_file_reader.h _os_define.h \ sockopt.h sched_thread.h http_func.h md5.h local_ip_func.h \ avl_tree.h ioevent.h ioevent_loop.h fast_task_queue.h \ fast_timer.h process_ctrl.h fast_mblock.h \ - connection_pool.h fast_mpool.h fast_allocator.h + connection_pool.h fast_mpool.h fast_allocator.h \ + fast_buffer.h ALL_OBJS = $(FAST_STATIC_OBJS) $(FAST_SHARED_OBJS) diff --git a/src/fast_buffer.c b/src/fast_buffer.c new file mode 100644 index 0000000..663c50e --- /dev/null +++ b/src/fast_buffer.c @@ -0,0 +1,156 @@ +#include +#include +#include +#include +#include +#include +#include +#include "logger.h" +#include "fast_buffer.h" + +int fast_buffer_init_ex(FastBuffer *buffer, const int init_capacity) +{ + buffer->length = 0; + if (init_capacity > 0) + { + buffer->alloc_size = init_capacity; + } + else + { + buffer->alloc_size = 256; + } + buffer->data = (char *)malloc(buffer->alloc_size); + if (buffer->data == NULL) + { + logError("file: "__FILE__", line: %d, " + "malloc %d bytes fail", __LINE__, buffer->alloc_size); + return ENOMEM; + } + *(buffer->data) = '\0'; + return 0; +} + +void fast_buffer_destroy(FastBuffer *buffer) +{ + if (buffer->data != NULL) + { + free(buffer->data); + buffer->data = NULL; + buffer->length = 0; + } +} + +static int fast_buffer_check(FastBuffer *buffer, const int inc_len) +{ + int alloc_size; + char *buff; + + if (buffer->alloc_size > buffer->length + inc_len) + { + return 0; + } + alloc_size = buffer->alloc_size * 2; + while (alloc_size <= buffer->length + inc_len) + { + alloc_size *= 2; + } + + buff = (char *)malloc(alloc_size); + if (buff == NULL) + { + logError("file: "__FILE__", line: %d, " + "malloc %d bytes fail", __LINE__, alloc_size); + return ENOMEM; + } + + if (buffer->length > 0) + { + memcpy(buff, buffer->data, buffer->length); + } + +printf("alloc size: %d\n", alloc_size); + + free(buffer->data); + buffer->data = buff; + buffer->alloc_size = alloc_size; + return 0; +} + +int fast_buffer_append(FastBuffer *buffer, const char *format, ...) +{ + va_list ap; + int result; + int len; + + if ((result=fast_buffer_check(buffer, 10)) != 0) + { + return result; + } + + va_start(ap, format); + len = vsnprintf(buffer->data + buffer->length, + buffer->alloc_size - buffer->length, format, ap); + va_end(ap); + if (len < buffer->alloc_size - buffer->length) + { + buffer->length += len; + } + else //maybe full, realloc and try again + { + printf("len: %d, alloc size: %d, remain: %d\n", len, buffer->alloc_size, buffer->alloc_size - buffer->length); + if ((result=fast_buffer_check(buffer, len)) == 0) + { + va_start(ap, format); + buffer->length += vsnprintf(buffer->data + buffer->length, + buffer->alloc_size - buffer->length, format, ap); + va_end(ap); + } + } + return 0; +} + +int fast_buffer_append_buff(FastBuffer *buffer, const char *data, const int len) +{ + int result; + + if (len <= 0) + { + return 0; + } + if ((result=fast_buffer_check(buffer, len)) != 0) + { + return result; + } + + memcpy(buffer->data + buffer->length, data, len); + buffer->length += len; + *(buffer->data + buffer->length) = '\0'; + return 0; +} + +int fast_buffer_append_int(FastBuffer *buffer, const int n) +{ + int result; + + if ((result=fast_buffer_check(buffer, 16)) != 0) + { + return result; + } + + buffer->length += sprintf(buffer->data + buffer->length, "%d", n); + return 0; +} + +int fast_buffer_append_int64(FastBuffer *buffer, const int64_t n) +{ + int result; + + if ((result=fast_buffer_check(buffer, 32)) != 0) + { + return result; + } + + buffer->length += sprintf(buffer->data + buffer->length, "%"PRId64, n); + return 0; +} + diff --git a/src/fast_buffer.h b/src/fast_buffer.h new file mode 100644 index 0000000..6b46d74 --- /dev/null +++ b/src/fast_buffer.h @@ -0,0 +1,53 @@ +#ifndef __FAST_BUFFER_H__ +#define __FAST_BUFFER_H__ + +#include + +typedef struct fast_buffer { + char *data; + int alloc_size; + int length; +} FastBuffer; + +#ifdef __cplusplus +extern "C" { +#endif + +static inline int fast_buffer_length(FastBuffer *buffer) +{ + return buffer->length; +} + +static inline char *fast_buffer_data(FastBuffer *buffer) +{ + return buffer->data; +} + +int fast_buffer_init_ex(FastBuffer *buffer, const int init_capacity); + +static inline int fast_buffer_init(FastBuffer *buffer) +{ + return fast_buffer_init_ex(buffer, 0); +} + +void fast_buffer_destroy(FastBuffer *buffer); + +int fast_buffer_append(FastBuffer *buffer, const char *format, ...); + +int fast_buffer_append_buff(FastBuffer *buffer, const char *data, const int len); + +int fast_buffer_append_int(FastBuffer *buffer, const int n); + +int fast_buffer_append_int64(FastBuffer *buffer, const int64_t n); + +static inline int fast_buffer_append_string(FastBuffer *buffer, const char *str) +{ + return fast_buffer_append_buff(buffer, str, strlen(str)); +} + +#ifdef __cplusplus +} +#endif + +#endif +