1 /* |
1 /* |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 * |
3 * |
4 * Copyright 2013 Olaf Wintermann. All rights reserved. |
4 * Copyright 2014 Olaf Wintermann. All rights reserved. |
5 * |
5 * |
6 * Redistribution and use in source and binary forms, with or without |
6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions are met: |
7 * modification, are permitted provided that the following conditions are met: |
8 * |
8 * |
9 * 1. Redistributions of source code must retain the above copyright |
9 * 1. Redistributions of source code must retain the above copyright |
59 va_end(ap); |
59 va_end(ap); |
60 |
60 |
61 return size; |
61 return size; |
62 } |
62 } |
63 |
63 |
64 sstr_t sstrncat(sstr_t s, size_t n, sstr_t c1, ...) { |
64 static sstr_t sstrvcat_a( |
|
65 UcxAllocator *a, |
|
66 size_t count, |
|
67 sstr_t s1, |
|
68 sstr_t s2, |
|
69 va_list ap) { |
|
70 sstr_t str; |
|
71 str.ptr = NULL; |
|
72 str.length = 0; |
|
73 if(count < 2) { |
|
74 return str; |
|
75 } |
|
76 |
|
77 sstr_t *strings = (sstr_t*) calloc(count, sizeof(sstr_t)); |
|
78 if(!strings) { |
|
79 return str; |
|
80 } |
|
81 |
|
82 // get all args and overall length |
|
83 strings[0] = s1; |
|
84 strings[1] = s2; |
|
85 size_t strlen = s1.length + s2.length; |
|
86 for (size_t i=2;i<count;i++) { |
|
87 sstr_t s = va_arg (ap, sstr_t); |
|
88 strings[i] = s; |
|
89 strlen += s.length; |
|
90 } |
|
91 |
|
92 // create new string |
|
93 str.ptr = (char*) almalloc(a, strlen + 1); |
|
94 str.length = strlen; |
|
95 if(!str.ptr) { |
|
96 free(strings); |
|
97 str.length = 0; |
|
98 return str; |
|
99 } |
|
100 |
|
101 // concatenate strings |
|
102 size_t pos = 0; |
|
103 for (size_t i=0;i<count;i++) { |
|
104 sstr_t s = strings[i]; |
|
105 memcpy(str.ptr + pos, s.ptr, s.length); |
|
106 pos += s.length; |
|
107 } |
|
108 |
|
109 str.ptr[str.length] = '\0'; |
|
110 |
|
111 free(strings); |
|
112 |
|
113 return str; |
|
114 } |
|
115 |
|
116 sstr_t sstrcat(size_t count, sstr_t s1, sstr_t s2, ...) { |
65 va_list ap; |
117 va_list ap; |
66 va_start(ap, c1); |
118 va_start(ap, s2); |
67 s.ptr[0] = 0; |
119 sstr_t s = sstrvcat_a(ucx_default_allocator(), count, s1, s2, ap); |
68 |
|
69 size_t len = s.length; |
|
70 size_t cplen = c1.length > len ? len : c1.length; |
|
71 char *ptr = s.ptr; |
|
72 |
|
73 memcpy(ptr, c1.ptr, cplen); |
|
74 len -= cplen; |
|
75 ptr += cplen; |
|
76 for (size_t i = 1 ; i < n ; i++) { |
|
77 sstr_t str = va_arg (ap, sstr_t); |
|
78 cplen = str.length > len ? len : str.length; |
|
79 if(cplen <= 0) { |
|
80 va_end(ap); |
|
81 return s; |
|
82 } |
|
83 memcpy(ptr, str.ptr, cplen); |
|
84 len -= cplen; |
|
85 ptr += cplen; |
|
86 } |
|
87 va_end(ap); |
120 va_end(ap); |
88 s.length = ptr - s.ptr; |
121 return s; |
89 |
122 } |
|
123 |
|
124 sstr_t sstrcat_a(UcxAllocator *a, size_t count, sstr_t s1, sstr_t s2, ...) { |
|
125 va_list ap; |
|
126 va_start(ap, s2); |
|
127 sstr_t s = sstrvcat_a(a, count, s1, s2, ap); |
|
128 va_end(ap); |
90 return s; |
129 return s; |
91 } |
130 } |
92 |
131 |
93 sstr_t sstrsubs(sstr_t s, size_t start) { |
132 sstr_t sstrsubs(sstr_t s, size_t start) { |
94 return sstrsubsl (s, start, s.length-start); |
133 return sstrsubsl (s, start, s.length-start); |
95 } |
134 } |
96 |
135 |
97 sstr_t sstrsubsl(sstr_t s, size_t start, size_t length) { |
136 sstr_t sstrsubsl(sstr_t s, size_t start, size_t length) { |
98 sstr_t new_sstr; |
137 sstr_t new_sstr; |
99 if (start >= s.length) { |
138 if (start >= s.length) { |
100 //return s; |
|
101 new_sstr.ptr = NULL; |
139 new_sstr.ptr = NULL; |
102 new_sstr.length = 0; |
140 new_sstr.length = 0; |
103 return new_sstr; |
141 } else { |
104 } |
142 if (length > s.length-start) { |
105 if (length > s.length-start) { |
143 length = s.length-start; |
106 length = s.length-start; |
144 } |
107 } |
145 new_sstr.ptr = &s.ptr[start]; |
108 new_sstr.ptr = &s.ptr[start]; |
146 new_sstr.length = length; |
109 new_sstr.length = length; |
147 } |
110 return new_sstr; |
148 return new_sstr; |
111 } |
149 } |
112 |
150 |
113 sstr_t sstrchr(sstr_t s, int c) { |
151 sstr_t sstrchr(sstr_t s, int c) { |
114 for(size_t i=0;i<s.length;i++) { |
152 for(size_t i=0;i<s.length;i++) { |
134 n.ptr = NULL; |
172 n.ptr = NULL; |
135 n.length = 0; |
173 n.length = 0; |
136 return n; |
174 return n; |
137 } |
175 } |
138 |
176 |
139 sstr_t* sstrsplit(sstr_t s, sstr_t d, size_t *n) { |
177 sstr_t* sstrsplit(sstr_t s, sstr_t d, ssize_t *n) { |
140 return sstrsplit_a(ucx_default_allocator(), s, d, n); |
178 return sstrsplit_a(ucx_default_allocator(), s, d, n); |
141 } |
179 } |
142 |
180 |
143 sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t s, sstr_t d, size_t *n) { |
181 sstr_t* sstrsplit_a(UcxAllocator *allocator, sstr_t s, sstr_t d, ssize_t *n) { |
144 if (s.length == 0 || d.length == 0) { |
182 if (s.length == 0 || d.length == 0) { |
145 *n = 0; |
183 *n = -1; |
146 return NULL; |
184 return NULL; |
147 } |
185 } |
148 |
186 |
149 sstr_t* result; |
187 sstr_t* result; |
150 size_t nmax = *n; |
188 ssize_t nmax = *n; |
151 *n = 1; |
189 *n = 1; |
152 |
190 |
153 /* special case: exact match - no processing needed */ |
191 /* special case: exact match - no processing needed */ |
154 if (sstrcmp(s, d) == 0) { |
192 if (sstrcmp(s, d) == 0) { |
155 *n = 0; |
193 *n = 0; |
180 i += d.length; |
218 i += d.length; |
181 } |
219 } |
182 } |
220 } |
183 if ((*n) == nmax) break; |
221 if ((*n) == nmax) break; |
184 } |
222 } |
185 result = (sstr_t*) allocator->malloc(allocator->pool, sizeof(sstr_t)*(*n)); |
223 result = (sstr_t*) almalloc(allocator, sizeof(sstr_t)*(*n)); |
186 |
224 |
187 if (result) { |
225 if (result) { |
188 char *pptr = sv.ptr; |
226 char *pptr = sv.ptr; |
189 for (size_t i = 0 ; i < *n ; i++) { |
227 for (ssize_t i = 0 ; i < *n ; i++) { |
190 size_t l = strlen(pptr); |
228 size_t l = strlen(pptr); |
191 char* ptr = (char*) allocator->malloc(allocator->pool, l + 1); |
229 char* ptr = (char*) almalloc(allocator, l + 1); |
192 memcpy(ptr, pptr, l); |
230 if (ptr) { |
193 ptr[l] = 0; |
231 memcpy(ptr, pptr, l); |
194 |
232 ptr[l] = 0; |
195 result[i] = sstrn(ptr, l); |
233 |
196 pptr += l + d.length; |
234 result[i] = sstrn(ptr, l); |
|
235 pptr += l + d.length; |
|
236 } else { |
|
237 for (ssize_t j = i-1 ; j >= 0 ; j--) { |
|
238 alfree(allocator, result[j].ptr); |
|
239 } |
|
240 alfree(allocator, result); |
|
241 *n = -2; |
|
242 break; |
|
243 } |
197 } |
244 } |
198 } else { |
245 } else { |
199 *n = -2; |
246 *n = -2; |
200 } |
247 } |
201 |
248 |
232 return sstrdup_a(ucx_default_allocator(), s); |
279 return sstrdup_a(ucx_default_allocator(), s); |
233 } |
280 } |
234 |
281 |
235 sstr_t sstrdup_a(UcxAllocator *allocator, sstr_t s) { |
282 sstr_t sstrdup_a(UcxAllocator *allocator, sstr_t s) { |
236 sstr_t newstring; |
283 sstr_t newstring; |
237 newstring.ptr = (char*)allocator->malloc(allocator->pool, s.length + 1); |
284 newstring.ptr = (char*)almalloc(allocator, s.length + 1); |
238 if (newstring.ptr) { |
285 if (newstring.ptr) { |
239 newstring.length = s.length; |
286 newstring.length = s.length; |
240 newstring.ptr[newstring.length] = 0; |
287 newstring.ptr[newstring.length] = 0; |
241 |
288 |
242 memcpy(newstring.ptr, s.ptr, s.length); |
289 memcpy(newstring.ptr, s.ptr, s.length); |