1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
/* A really basic expanding/appendable string type */
#include <stdlib.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <time.h>
#include <assert.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <getopt.h>
#include <errno.h>
#include "cstring.h"
#define INITIAL_SIZE 1024
#define INCREMENT 1024
#define CHECKER_WORD 0xbcd6712a
struct cstring_header
{
size_t checker;
size_t allocated;
size_t used;
char the_string[];
};
cstring_t cstring_alloc(void)
{
char *cstring = malloc(INITIAL_SIZE);
if (cstring) {
struct cstring_header *h = (struct cstring_header *)cstring;
h->checker = CHECKER_WORD;
h->allocated = INITIAL_SIZE;
h->used = 0;
h->the_string[0] = '\0';
return cstring;
} else {
return NULL;
}
}
char *cstring_to_chars(cstring_t cstring)
{
struct cstring_header *h = (struct cstring_header *)cstring;
if (!h) {
return NULL;
}
assert(h->checker == CHECKER_WORD);
return strdup(h->the_string);
}
size_t cstring_len(cstring_t cstring)
{
struct cstring_header *h = (struct cstring_header *)cstring;
if (!h) {
return 0;
}
assert(h->checker == CHECKER_WORD);
return h->used;
}
cstring_t cstring_append_chars(cstring_t cstring, const char *newstring)
{
struct cstring_header *h = (struct cstring_header *)cstring;
size_t newlen;
if (!h) {
return NULL;
}
assert(h->checker == CHECKER_WORD);
if (!newstring) {
return NULL;
}
newlen = h->used + strlen(newstring)+1 + sizeof(struct cstring_header);
if (newlen > h->allocated) {
size_t new_allocsize = (newlen + 2048) & 0xFFFFFC00;
char *tmp = realloc(cstring, new_allocsize);
if (!tmp) {
return cstring;
}
cstring = tmp;
h = (struct cstring_header *)cstring;
h->allocated = new_allocsize;
}
strncat(h->the_string, newstring, h->allocated - h->used -1);
h->used += strlen(newstring);
return cstring;
}
cstring_t cstring_append_cstring(cstring_t cstring, cstring_t newstring)
{
/* Just check the newstring - cstring_append_chars() will check the target */
struct cstring_header *h = (struct cstring_header *)newstring;
if (!h) {
return NULL;
}
assert(h->checker == CHECKER_WORD);
return cstring_append_chars(cstring, h->the_string);
}
cstring_t cstring_from_chars(const char* chars)
{
cstring_t new_string = cstring_alloc();
if (!new_string) {
return NULL;
}
return cstring_append_chars(new_string, chars);
}
void cstring_free(cstring_t cstring)
{
struct cstring_header *h = (struct cstring_header *)cstring;
if (!h) {
return;
}
assert(h->checker == CHECKER_WORD);
free(cstring);
}
|