ADAPT / plugins / SayHello / string_buffer.c
string_buffer.c
Raw
#include "string_buffer.h"

#include <string.h>
#include <stdio.h>
#include<stdarg.h>
#include <stdlib.h>

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;
}