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
|
#include <stdio.h>
#include <stdlib.h>
#include "libstring.h"
struct string *string_create(char *s)
{
if (!s)
{
struct string *r = calloc(1, sizeof(struct string));
char *data = calloc((BASE_STRING_SIZE + 1), sizeof(char));
if (!r || !data)
{
fprintf(stderr, "string_create: calloc failed.\n");
return NULL;
}
r->data = data;
r->capacity = BASE_STRING_SIZE;
return r;
}
struct string *str = malloc(1 * sizeof(struct string));
if (!str)
{
fprintf(stderr, "string_create: malloc failed.\n");
return NULL;
}
// Align the capacity on the string base size
size_t l = strlen(s);
size_t m = (l + 1) % BASE_STRING_SIZE;
str->length = l;
str->capacity = (l + 1) + (BASE_STRING_SIZE - m);
str->data = calloc(str->capacity, sizeof(char));
if (!str->data)
{
fprintf(stderr, "string_create: malloc failed.\n");
return NULL;
}
memcpy(str->data, s, l);
return str;
}
void string_free(struct string *str)
{
if (str)
{
free(str->data);
free(str);
}
}
static bool _resize_string(struct string *str, int p)
{
char *new_data = realloc(
str->data, ((p >= 0) ? str->capacity * 2 : str->capacity / 2) + 1);
if (!new_data)
{
fprintf(stderr, "_resize_string: realloc failed.\n");
return false;
}
str->data = new_data;
str->capacity = ((p >= 0) ? str->capacity * 2 : str->capacity / 2);
return true;
}
bool string_pushc(struct string *str, char c)
{
if (str->length == str->capacity)
{
if (!_resize_string(str, 1))
{
return false;
}
}
str->data[str->length] = c;
str->length++;
str->data[str->length] = 0;
return true;
}
bool string_pushstr(struct string *str, char *s)
{
if (!s || !s[0])
{
return true;
}
size_t l = strlen(s);
while (str->length + l >= str->capacity)
{
if (!_resize_string(str, 1))
{
return false;
}
}
memcpy(str->data + str->length, s, l);
str->length += l;
str->data[str->length] = 0;
return true;
}
bool string_catenate(struct string *dst, struct string *src)
{
if (!src)
{
return true;
}
if (!dst || !string_pushstr(dst, src->data))
{
return false;
}
string_free(src);
return true;
}
struct string *string_deepcopy(struct string *str)
{
return string_create(str->data);
}
|