Last active
December 25, 2015 22:39
-
-
Save DrFrankenstein/7050843 to your computer and use it in GitHub Desktop.
C String Builder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "csb.h" | |
#include "csb_private.h" | |
#include "csb_elem.h" | |
#include <stdlib.h> | |
#include <string.h> | |
str_builder sb_init(const char* initstr) | |
{ | |
str_builder sb = (str_builder) malloc(sizeof(struct str_builder_impl)); | |
if(!sb) return NULL; | |
sb->start = sb->end = NULL; | |
sb->len = 0; | |
if(initstr) | |
{ | |
(void) sb_append(sb, initstr); | |
if(*initstr != '\0' && !sb->len) | |
{ /* Bail out if insertion fails. */ | |
sb_finish(sb); | |
return NULL; | |
} | |
} | |
return sb; | |
} | |
void sb_finish(str_builder sb) | |
{ | |
sb_clear(sb); | |
free(sb); | |
} | |
void sb_clear(str_builder sb) | |
{ | |
struct sb_elem* elem = sb->start; | |
while(elem) | |
{ | |
struct sb_elem* next = elem->next; | |
elem_free(elem); | |
elem = next; | |
} | |
sb->len = 0; | |
} | |
size_t sb_append(str_builder sb, const char* str) | |
{ | |
size_t len; | |
struct sb_elem* elem; | |
if(!sb || !str) return 0; | |
len = strlen(str); | |
elem = elem_init(str, len); | |
if(!elem) return 0; | |
sb->len += len; | |
append_elem(sb, elem); | |
return len; | |
} | |
static void append_elem(str_builder sb, struct sb_elem* elem) | |
{ | |
if(sb->end) | |
{ | |
sb->end->next = elem; | |
sb->end = elem; | |
} | |
else | |
{ | |
sb->start = sb->end = elem; | |
} | |
} | |
static struct sb_elem* elem_init(const char* str, const size_t len) | |
{ | |
struct sb_elem* elem = (struct sb_elem*) malloc(sizeof(struct sb_elem)); | |
char* copy; | |
if(!elem) return NULL; | |
copy = (char*) malloc(sizeof(char) * len + 1); | |
if(!copy) | |
{ | |
free(elem); | |
return NULL; | |
} | |
memcpy(copy, str, len); | |
elem->str = copy; | |
elem->next = NULL; | |
elem->len = len; | |
return elem; | |
} | |
static void elem_free(struct sb_elem* elem) | |
{ | |
free(elem->str); | |
free(elem); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef CSB_INCLUDED | |
#define CSB_INCLUDED | |
#include <stddef.h> | |
struct str_builder_impl; | |
typedef struct str_builder_impl* str_builder; | |
str_builder sb_init(const char* initstr); | |
void sb_finish(str_builder sb); | |
size_t sb_append(str_builder sb, const char* str); | |
void sb_clear(str_builder sb); | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef CSB_PRIVATE_INCLUDED | |
#define CSB_PRIVATE_INCLUDED | |
#include "csb_elem.h" | |
#include <stddef.h> | |
struct str_builder_impl | |
{ | |
size_t len; | |
struct sb_elem* start; | |
struct sb_elem* end; | |
}; | |
struct sb_elem | |
{ | |
char* str; | |
struct sb_elem* next; | |
size_t len; | |
/*char mine : 1;*/ | |
}; | |
static struct sb_elem* elem_init(const char* str, const size_t len); | |
static void elem_free(struct sb_elem* elem); | |
static void append_elem(str_builder sb, struct sb_elem* elem); | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment