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