dyn_string.c
Raw
1#include <cutils/dyn_string.h>
2
3String* string_with_capacity(size_t capacity, bool null_terminated)
4{
5 String* string = malloc(sizeof(*string));
6 if(!string)
7 return NULL;
8 string->chars = malloc(capacity+(null_terminated?1:0));
9 if(!string->chars)
10 {
11 free(string);
12 return NULL;
13 }
14 if(null_terminated)
15 string->chars[0] = '\0';
16 string->length = 0;
17 string->capacity = capacity;
18 string->null_terminated = null_terminated;
19
20 return string;
21}
22
23void string_remove_range(String* string, size_t index, size_t length)
24{
25 memmove(string->chars+index, string->chars+index+length, (string->length-(index+length)+(string->null_terminated?1:0)));
26 string->length -= length;
27}
28
29size_t string_strip(String* string, char character)
30{
31 size_t i, last = 0, offset = 0;
32 bool first = true;
33
34 for(i = 0; i < string->length; i++)
35 {
36 if(string_at(string,i) == character)
37 {
38 if(first)
39 {
40 first = false;
41 } else {
42 memmove(string->chars+last-offset, string->chars+last+1, i-last-1);
43 offset++;
44 }
45
46 last = i;
47 }
48 }
49
50 memmove(string->chars+last-offset, string->chars+last+1, string->length-last-1+(string->null_terminated?1:0));
51
52 string->length -= offset+(first ? 0 : 1);
53 return offset;
54}
55
56bool string_insert(String* string, size_t index, char character)
57{
58 if(index > string->length || string->length == SIZE_MAX || !string_adjust_size(string, string->length+1))
59 return false;
60
61 memmove(string->chars+index+1, string->chars+index, (string->length-index+(string->null_terminated?1:0))*sizeof(*string->chars));
62 string->chars[index] = character;
63 string->length++;
64 return true;
65}
66
67char string_pop_at(String* string, size_t index)
68{
69 char tmp = string_at(string, index);
70 string_remove(string, index);
71 return tmp;
72}
73
74bool string_concat(String* string, const String* other)
75{
76 if(!string_adjust_size(string,string->length+other->length-1))
77 return false;
78 memcpy(string->chars+string->length,other->chars,other->length);
79 string->length += other->length;
80 string->chars[string->length] = '\0';
81 return true;
82}
83
84bool string_find_char(const String* haystack, const char needle, size_t* pos)
85{
86 size_t i;
87
88 for(i = 0; i < haystack->length; i++)
89 {
90 if(haystack->chars[i] == needle)
91 {
92 *pos = i;
93 return true;
94 }
95 }
96 return false;
97}
98
99size_t string_count(const String* string, char character)
100{
101 size_t i, ret = 0;
102 for(i = 0; i < string->length; i++)
103 {
104 if(string_at(string, i) == character)
105 ret++;
106 }
107 return ret;
108}
109
110bool string_adjust_size(String* string, size_t size)
111{
112 if(size == SIZE_MAX && string->null_terminated)
113 return false;
114
115 while(string->capacity < size+(string->null_terminated?1:0))
116 {
117 char* tmp = string->chars;
118 string->chars = cutil_reallocarray_inc(string->chars, sizeof(*string->chars), string->capacity, string->capacity);
119 if(!string->chars)
120 {
121 string->chars = tmp;
122 return false;
123 }
124 string->capacity *= 2;
125 }
126 return true;
127}
128
129
130void delete_string(String* string)
131{
132 free(string->chars);
133 free(string);
134}
135
136String* from_cstring(const char* cstring, bool null_terminated)
137{
138 String* string = string_with_capacity(strlen(cstring), null_terminated);
139 if(!string)
140 {
141 return NULL;
142 } else {
143 memcpy(string->chars, cstring, strlen(cstring));
144 string->length = strlen(cstring);
145 if(null_terminated)
146 string->chars[string->length] = '\0';
147 return string;
148 }
149}
150
151String* from_cstring_reuse(char* cstring, size_t capacity, bool null_terminated)
152{
153 String* string;
154
155 if(cstring)
156 return NULL;
157
158 string = malloc(sizeof(*string));
159 if(!string)
160 return NULL;
161
162 string->length = strlen(cstring);
163 string->capacity = capacity;
164
165 return string;
166}
167
168String* from_cstring_del(char* cstring, bool null_terminated)
169{
170 String* ret = from_cstring(cstring, null_terminated);
171 if(!ret)
172 return NULL;
173 free(cstring);
174 return ret;
175}
176
177char* to_cstring(const String* string)
178{
179 char* cstring = malloc(string->length+1);
180 memcpy(cstring, string->chars, string->length);
181 cstring[string->length] = '\0';
182
183 return cstring;
184}
185
186char* to_cstring_del(String* string)
187{
188 char* ret = to_cstring(string);
189 delete_string(string);
190 return ret;
191}
192
193void string_move(String* dest, String* src)
194{
195 free(dest->chars);
196 dest->chars = src->chars;
197 free(src);
198}
199