#include "string_buffer.h" #include #include #include #include void string_buffer_init(struct string_buffer *s_b, char *b_buff, size_t b_len) { s_b->b_buff = b_buff; s_b->b_len = b_len; s_b->b_alloc = 0; memset(s_b->b_buff,0,b_len); } bool string_buffer_add_str(struct string_buffer *s_b, char *str) { int len= strlen(str); //if str doesn't fit, return false; if(len+s_b->b_alloc + 1 > s_b->b_len) { return false; } //defensive memmove(&s_b->b_buff[s_b->b_alloc],str,len); s_b->b_alloc+=len; s_b->b_buff[s_b->b_alloc]='\0'; return true; } bool string_buffer_add_fmt(struct string_buffer *s_b, char *fmt, ...) { va_list v_a; /* Determine required size. */ va_start(v_a, fmt); int len = vsnprintf(NULL, 0, fmt, v_a); va_end(v_a); if (len < 0 || len+s_b->b_alloc + 1 > s_b->b_len) return false; /* work around to not call vsnprintf directly on s_b->b_buff[s_b->b_alloc] not sure if strictly necessary but it ensures the buffers are distinct */ char str[len+1]; va_start(v_a, fmt); len = vsnprintf(str, len+1, fmt, v_a); va_end(v_a); if (len < 0) { return false; } //defensive memmove(&s_b->b_buff[s_b->b_alloc],str,len); s_b->b_alloc+=len; return true; } void string_buffer_clear(struct string_buffer *s_b) { s_b->b_alloc = 0; memset(s_b->b_buff,0,s_b->b_len); } void string_buffer_resize(struct string_buffer *s_b, char *n_buff, size_t n_len) { memset(n_buff,0,n_len); if(n_len >= s_b->b_alloc) { strcpy(n_buff,s_b->b_buff); s_b->b_buff = n_buff; s_b->b_len = n_len; } } int run_sb(void) { char big_buf[1024]; struct string_buffer s_b; string_buffer_init(&s_b,big_buf,1024); string_buffer_add_str(&s_b,"Hello World!\n"); for(int i=0;i<100;i++) { printf("%d:%d ",i,string_buffer_add_fmt(&s_b,"Num: %d\n",i)); } printf("\n"); printf("%s",s_b.b_buff); printf("b_alloc:%zu\n",s_b.b_alloc); return 0; }