fixed word-order issue in password set and password change.
[Samba.git] / source / lib / ustring.c
blobf754d0ba6bf80db313e871561756a5a0a9797cb2
1 /*
2 Dynamic Unicode Strings
3 Copyright (C) Elrond 2000
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "includes.h"
21 #include "ustring.h"
23 #define g_free(x) safe_free(x)
26 #define INITIAL_SIZE 32
29 UString *ustring_new(const char *init)
31 UString *str;
33 str = g_new(UString, 1);
34 if (str == NULL)
36 return str;
38 str->len = 0;
39 str->alloc = INITIAL_SIZE;
40 str->str = g_new(uint16, str->alloc);
41 if(str->str == NULL)
43 g_free(str);
44 return NULL;
46 str->str[0] = 0;
48 if (init)
50 ustring_assign_ascii_str(str, init);
53 return str;
56 void ustring_free(UString *str)
58 if (! str)
60 return;
62 g_free(str->str);
63 g_free(str);
66 static size_t nearest_pow(size_t n)
68 size_t i = 1;
69 while (i < n)
71 i *= 2;
73 return i;
76 UString *ustring_grow(UString *str, size_t new_alloc)
78 if(! str)
80 return str;
82 if(str->alloc >= new_alloc)
84 return str;
86 new_alloc = nearest_pow(new_alloc);
87 str->str = g_renew(uint16, str->str, new_alloc);
88 if (str->str == NULL)
90 new_alloc = 0;
91 str->len = 0;
93 str->alloc = new_alloc;
94 return str;
97 UString *ustring_shrink(UString *str)
99 size_t new_alloc;
101 if(! str)
103 return str;
105 new_alloc = str->len + 1;
106 if (new_alloc == str->alloc)
108 return str;
111 str->str = g_renew(uint16, str->str, new_alloc);
112 str->alloc = new_alloc;
113 return str;
116 UString *ustring_assign(UString *str, const uint16 *src, size_t len)
118 if (! str)
120 return str;
122 if ((src == NULL) || (len == 0))
124 str->len = 0;
125 str->str[0] = 0;
128 ustring_grow(str, len+1);
130 memcpy(str->str, src, len*sizeof(uint16));
132 str->str[len] = 0;
133 str->len = len;
135 return str;
138 UString *ustring_assign_ascii(UString *str, const char *src, size_t len)
140 uint16 *dest;
142 if (! str)
144 return str;
146 if ((src == NULL) || (len == 0))
148 str->len = 0;
149 str->str[0] = 0;
150 return str;
152 ustring_grow(str, len+1);
154 str->len = len;
156 dest = str->str;
158 while (len > 0)
160 char c = *src++;
161 *dest++ = c;
162 len--;
165 *dest = 0;
167 return str;
170 UString *ustring_assign_ascii_str(UString *str, const char *src)
172 return ustring_assign_ascii(str, src, (src ? strlen(src) : 0));
175 UString *ustring_dup(const UString *str)
177 UString *new;
179 if (! str)
181 return str;
183 new = ustring_new(NULL);
184 if (! new)
186 return new;
189 ustring_assign(new, str->str, str->len);
191 return new;
194 int ustring_compare(const UString *a, const UString *b)
196 uint16 *pa, *pb;
197 int ca, cb;
198 size_t len;
200 if (a == b) return 0;
201 if (!a) return 1;
202 if (!b) return -1;
204 pa = a->str;
205 pb = b->str;
206 len = MIN(a->len, b->len) + 1; /* include the final NUL */
208 while ((len > 0) && (*pa == *pb))
210 pa++;
211 pb++;
212 len--;
214 if (len == 0)
216 if (a->len == b->len) return 0;
217 if (a->len < b->len) return 1;
218 return 1;
221 ca = *pa;
222 cb = *pb;
224 return cb - ca;
227 int ustring_compare_case(const UString *a, const UString *b)
229 uint16 *pa, *pb;
230 int ca, cb;
231 size_t len;
233 if (a == b) return 0;
234 if (!a) return 1;
235 if (!b) return -1;
237 pa = a->str;
238 pb = b->str;
239 len = MIN(a->len, b->len) + 1; /* include the final NUL */
241 while ((len > 0) && (toupper(*pa) == toupper(*pb)))
243 pa++;
244 pb++;
245 len--;
247 if (len == 0)
249 if (a->len == b->len) return 0;
250 if (a->len < b->len) return 1;
251 return 1;
254 ca = toupper(*pa);
255 cb = toupper(*pb);
257 return cb - ca;
260 UString *ustring_append_c(UString *str, uint16 c)
262 if (! str)
264 return str;
266 ustring_grow(str, str->len + 2);
267 str->str[str->len] = c;
268 str->len++;
269 str->str[str->len] = 0;
271 return str;
274 UString *ustring_sync_len(UString *str)
276 uint16 *p, *a;
278 if (! str)
280 return str;
283 a = str->str;
284 p = a + str->len - 1;
285 while((p > a) && (*p == 0))
287 p--;
289 p++;
290 str->len = p - a;
292 return str;
295 UString *ustring_upper(UString *str)
297 uint16 *p, *e;
299 if (! str)
301 return str;
304 p = str->str;
305 e = p + str->len;
307 while (p < e)
309 *p = toupper(*p);
310 p++;
313 return str;
316 UString *ustring_lower(UString *str)
318 uint16 *p, *e;
320 if (! str)
322 return str;
325 p = str->str;
326 e = p + str->len;
328 while (p < e)
330 *p = tolower(*p);
331 p++;
334 return str;
337 BOOL ustring_equal(const UString *s1, const UString *s2)
339 UString *a;
340 UString *b;
341 BOOL ret;
343 a = ustring_sync_len(ustring_dup(s1));
344 b = ustring_sync_len(ustring_dup(s2));
345 ret = ustring_compare_case(a, b);
347 ustring_free(a);
348 ustring_free(b);
350 return ret;