1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-string-util.c Would be in dbus-string.c, but not used in libdbus
3 *
4 * Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
5 * Copyright (C) 2006 Ralf Habacker <ralf.habacker@freenet.de>
6 *
7 * Licensed under the Academic Free License version 2.1
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 */
24
25 #include <config.h>
26 #include "dbus-internals.h"
27 #include "dbus-string.h"
28 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
29 #include "dbus-string-private.h"
30
31 /**
32 * @addtogroup DBusString
33 * @{
34 */
35
36 /**
37 * Returns whether a string ends with the given suffix
38 *
39 * @todo memcmp might make this faster.
40 *
41 * @param a the string
42 * @param c_str the C-style string
43 * @returns #TRUE if the string ends with the suffix
44 */
45 dbus_bool_t
_dbus_string_ends_with_c_str(const DBusString * a,const char * c_str)46 _dbus_string_ends_with_c_str (const DBusString *a,
47 const char *c_str)
48 {
49 const unsigned char *ap;
50 const unsigned char *bp;
51 const unsigned char *a_end;
52 unsigned long c_str_len;
53 const DBusRealString *real_a = (const DBusRealString*) a;
54 DBUS_GENERIC_STRING_PREAMBLE (real_a);
55 _dbus_assert (c_str != NULL);
56
57 c_str_len = strlen (c_str);
58 if (((unsigned long)real_a->len) < c_str_len)
59 return FALSE;
60
61 ap = real_a->str + (real_a->len - c_str_len);
62 bp = (const unsigned char*) c_str;
63 a_end = real_a->str + real_a->len;
64 while (ap != a_end)
65 {
66 if (*ap != *bp)
67 return FALSE;
68
69 ++ap;
70 ++bp;
71 }
72
73 _dbus_assert (*ap == '\0');
74 _dbus_assert (*bp == '\0');
75
76 return TRUE;
77 }
78
79 /**
80 * Find the given byte scanning backward from the given start.
81 * Sets *found to -1 if the byte is not found.
82 *
83 * @param str the string
84 * @param start the place to start scanning (will not find the byte at this point)
85 * @param byte the byte to find
86 * @param found return location for where it was found
87 * @returns #TRUE if found
88 */
89 dbus_bool_t
_dbus_string_find_byte_backward(const DBusString * str,int start,unsigned char byte,int * found)90 _dbus_string_find_byte_backward (const DBusString *str,
91 int start,
92 unsigned char byte,
93 int *found)
94 {
95 int i;
96 DBUS_CONST_STRING_PREAMBLE (str);
97 _dbus_assert (start <= real->len);
98 _dbus_assert (start >= 0);
99 _dbus_assert (found != NULL);
100
101 i = start - 1;
102 while (i >= 0)
103 {
104 if (real->str[i] == byte)
105 break;
106
107 --i;
108 }
109
110 if (found)
111 *found = i;
112
113 return i >= 0;
114 }
115
116 /** @} */
117
118 #ifdef DBUS_BUILD_TESTS
119 #include "dbus-test.h"
120 #include <stdio.h>
121
122 static void
test_max_len(DBusString * str,int max_len)123 test_max_len (DBusString *str,
124 int max_len)
125 {
126 if (max_len > 0)
127 {
128 if (!_dbus_string_set_length (str, max_len - 1))
129 _dbus_assert_not_reached ("setting len to one less than max should have worked");
130 }
131
132 if (!_dbus_string_set_length (str, max_len))
133 _dbus_assert_not_reached ("setting len to max len should have worked");
134
135 if (_dbus_string_set_length (str, max_len + 1))
136 _dbus_assert_not_reached ("setting len to one more than max len should not have worked");
137
138 if (!_dbus_string_set_length (str, 0))
139 _dbus_assert_not_reached ("setting len to zero should have worked");
140 }
141
142 static void
test_hex_roundtrip(const unsigned char * data,int len)143 test_hex_roundtrip (const unsigned char *data,
144 int len)
145 {
146 DBusString orig;
147 DBusString encoded;
148 DBusString decoded;
149 int end;
150
151 if (len < 0)
152 len = strlen (data);
153
154 if (!_dbus_string_init (&orig))
155 _dbus_assert_not_reached ("could not init string");
156
157 if (!_dbus_string_init (&encoded))
158 _dbus_assert_not_reached ("could not init string");
159
160 if (!_dbus_string_init (&decoded))
161 _dbus_assert_not_reached ("could not init string");
162
163 if (!_dbus_string_append_len (&orig, data, len))
164 _dbus_assert_not_reached ("couldn't append orig data");
165
166 if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))
167 _dbus_assert_not_reached ("could not encode");
168
169 if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0))
170 _dbus_assert_not_reached ("could not decode");
171
172 _dbus_assert (_dbus_string_get_length (&encoded) == end);
173
174 if (!_dbus_string_equal (&orig, &decoded))
175 {
176 const char *s;
177
178 printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
179 _dbus_string_get_length (&orig),
180 _dbus_string_get_length (&encoded),
181 _dbus_string_get_length (&decoded));
182 printf ("Original: %s\n", data);
183 s = _dbus_string_get_const_data (&decoded);
184 printf ("Decoded: %s\n", s);
185 _dbus_assert_not_reached ("original string not the same as string decoded from hex");
186 }
187
188 _dbus_string_free (&orig);
189 _dbus_string_free (&encoded);
190 _dbus_string_free (&decoded);
191 }
192
193 typedef void (* TestRoundtripFunc) (const unsigned char *data,
194 int len);
195 static void
test_roundtrips(TestRoundtripFunc func)196 test_roundtrips (TestRoundtripFunc func)
197 {
198 (* func) ("Hello this is a string\n", -1);
199 (* func) ("Hello this is a string\n1", -1);
200 (* func) ("Hello this is a string\n12", -1);
201 (* func) ("Hello this is a string\n123", -1);
202 (* func) ("Hello this is a string\n1234", -1);
203 (* func) ("Hello this is a string\n12345", -1);
204 (* func) ("", 0);
205 (* func) ("1", 1);
206 (* func) ("12", 2);
207 (* func) ("123", 3);
208 (* func) ("1234", 4);
209 (* func) ("12345", 5);
210 (* func) ("", 1);
211 (* func) ("1", 2);
212 (* func) ("12", 3);
213 (* func) ("123", 4);
214 (* func) ("1234", 5);
215 (* func) ("12345", 6);
216 {
217 unsigned char buf[512];
218 int i;
219
220 i = 0;
221 while (i < _DBUS_N_ELEMENTS (buf))
222 {
223 buf[i] = i;
224 ++i;
225 }
226 i = 0;
227 while (i < _DBUS_N_ELEMENTS (buf))
228 {
229 (* func) (buf, i);
230 ++i;
231 }
232 }
233 }
234
235 #ifdef DBUS_BUILD_TESTS
236 /* The max length thing is sort of a historical artifact
237 * from a feature that turned out to be dumb; perhaps
238 * we should purge it entirely. The problem with
239 * the feature is that it looks like memory allocation
240 * failure, but is not a transient or resolvable failure.
241 */
242 static void
set_max_length(DBusString * str,int max_length)243 set_max_length (DBusString *str,
244 int max_length)
245 {
246 DBusRealString *real;
247
248 real = (DBusRealString*) str;
249
250 real->max_length = max_length;
251 }
252 #endif /* DBUS_BUILD_TESTS */
253
254 /**
255 * @ingroup DBusStringInternals
256 * Unit test for DBusString.
257 *
258 * @todo Need to write tests for _dbus_string_copy() and
259 * _dbus_string_move() moving to/from each of start/middle/end of a
260 * string. Also need tests for _dbus_string_move_len ()
261 *
262 * @returns #TRUE on success.
263 */
264 dbus_bool_t
_dbus_string_test(void)265 _dbus_string_test (void)
266 {
267 DBusString str;
268 DBusString other;
269 int i, end;
270 long v;
271 double d;
272 int lens[] = { 0, 1, 2, 3, 4, 5, 10, 16, 17, 18, 25, 31, 32, 33, 34, 35, 63, 64, 65, 66, 67, 68, 69, 70, 71, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136 };
273 char *s;
274 dbus_unichar_t ch;
275
276 i = 0;
277 while (i < _DBUS_N_ELEMENTS (lens))
278 {
279 if (!_dbus_string_init (&str))
280 _dbus_assert_not_reached ("failed to init string");
281
282 set_max_length (&str, lens[i]);
283
284 test_max_len (&str, lens[i]);
285 _dbus_string_free (&str);
286
287 ++i;
288 }
289
290 /* Test shortening and setting length */
291 i = 0;
292 while (i < _DBUS_N_ELEMENTS (lens))
293 {
294 int j;
295
296 if (!_dbus_string_init (&str))
297 _dbus_assert_not_reached ("failed to init string");
298
299 set_max_length (&str, lens[i]);
300
301 if (!_dbus_string_set_length (&str, lens[i]))
302 _dbus_assert_not_reached ("failed to set string length");
303
304 j = lens[i];
305 while (j > 0)
306 {
307 _dbus_assert (_dbus_string_get_length (&str) == j);
308 if (j > 0)
309 {
310 _dbus_string_shorten (&str, 1);
311 _dbus_assert (_dbus_string_get_length (&str) == (j - 1));
312 }
313 --j;
314 }
315
316 _dbus_string_free (&str);
317
318 ++i;
319 }
320
321 /* Test equality */
322 if (!_dbus_string_init (&str))
323 _dbus_assert_not_reached ("oom");
324
325 if (!_dbus_string_append (&str, "Hello World"))
326 _dbus_assert_not_reached ("oom");
327
328 _dbus_string_init_const (&other, "H");
329 _dbus_assert (_dbus_string_equal_substring (&str, 0, 1, &other, 0));
330 _dbus_assert (_dbus_string_equal_substring (&str, 1, 0, &other, 1));
331 _dbus_string_init_const (&other, "Hello");
332 _dbus_assert (_dbus_string_equal_substring (&str, 0, 5, &other, 0));
333 _dbus_assert (_dbus_string_equal_substring (&str, 1, 4, &other, 1));
334 _dbus_assert (_dbus_string_equal_substring (&str, 2, 3, &other, 2));
335 _dbus_assert (_dbus_string_equal_substring (&str, 3, 2, &other, 3));
336 _dbus_assert (_dbus_string_equal_substring (&str, 4, 1, &other, 4));
337 _dbus_assert (_dbus_string_equal_substring (&str, 5, 0, &other, 5));
338
339 _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 0));
340 _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 1));
341 _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 2));
342 _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 3));
343 _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 4));
344 _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 5));
345
346
347 _dbus_string_init_const (&other, "World");
348 _dbus_assert (_dbus_string_equal_substring (&str, 6, 5, &other, 0));
349 _dbus_assert (_dbus_string_equal_substring (&str, 7, 4, &other, 1));
350 _dbus_assert (_dbus_string_equal_substring (&str, 8, 3, &other, 2));
351 _dbus_assert (_dbus_string_equal_substring (&str, 9, 2, &other, 3));
352 _dbus_assert (_dbus_string_equal_substring (&str, 10, 1, &other, 4));
353 _dbus_assert (_dbus_string_equal_substring (&str, 11, 0, &other, 5));
354
355 _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 6));
356 _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 7));
357 _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 8));
358 _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 9));
359 _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 10));
360 _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 11));
361
362 _dbus_string_free (&str);
363
364 /* Test appending data */
365 if (!_dbus_string_init (&str))
366 _dbus_assert_not_reached ("failed to init string");
367
368 i = 0;
369 while (i < 10)
370 {
371 if (!_dbus_string_append (&str, "a"))
372 _dbus_assert_not_reached ("failed to append string to string\n");
373
374 _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1);
375
376 if (!_dbus_string_append_byte (&str, 'b'))
377 _dbus_assert_not_reached ("failed to append byte to string\n");
378
379 _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2);
380
381 ++i;
382 }
383
384 _dbus_string_free (&str);
385
386 /* Check steal_data */
387
388 if (!_dbus_string_init (&str))
389 _dbus_assert_not_reached ("failed to init string");
390
391 if (!_dbus_string_append (&str, "Hello World"))
392 _dbus_assert_not_reached ("could not append to string");
393
394 i = _dbus_string_get_length (&str);
395
396 if (!_dbus_string_steal_data (&str, &s))
397 _dbus_assert_not_reached ("failed to steal data");
398
399 _dbus_assert (_dbus_string_get_length (&str) == 0);
400 _dbus_assert (((int)strlen (s)) == i);
401
402 dbus_free (s);
403
404 /* Check move */
405
406 if (!_dbus_string_append (&str, "Hello World"))
407 _dbus_assert_not_reached ("could not append to string");
408
409 i = _dbus_string_get_length (&str);
410
411 if (!_dbus_string_init (&other))
412 _dbus_assert_not_reached ("could not init string");
413
414 if (!_dbus_string_move (&str, 0, &other, 0))
415 _dbus_assert_not_reached ("could not move");
416
417 _dbus_assert (_dbus_string_get_length (&str) == 0);
418 _dbus_assert (_dbus_string_get_length (&other) == i);
419
420 if (!_dbus_string_append (&str, "Hello World"))
421 _dbus_assert_not_reached ("could not append to string");
422
423 if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other)))
424 _dbus_assert_not_reached ("could not move");
425
426 _dbus_assert (_dbus_string_get_length (&str) == 0);
427 _dbus_assert (_dbus_string_get_length (&other) == i * 2);
428
429 if (!_dbus_string_append (&str, "Hello World"))
430 _dbus_assert_not_reached ("could not append to string");
431
432 if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2))
433 _dbus_assert_not_reached ("could not move");
434
435 _dbus_assert (_dbus_string_get_length (&str) == 0);
436 _dbus_assert (_dbus_string_get_length (&other) == i * 3);
437
438 _dbus_string_free (&other);
439
440 /* Check copy */
441
442 if (!_dbus_string_append (&str, "Hello World"))
443 _dbus_assert_not_reached ("could not append to string");
444
445 i = _dbus_string_get_length (&str);
446
447 if (!_dbus_string_init (&other))
448 _dbus_assert_not_reached ("could not init string");
449
450 if (!_dbus_string_copy (&str, 0, &other, 0))
451 _dbus_assert_not_reached ("could not copy");
452
453 _dbus_assert (_dbus_string_get_length (&str) == i);
454 _dbus_assert (_dbus_string_get_length (&other) == i);
455
456 if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other)))
457 _dbus_assert_not_reached ("could not copy");
458
459 _dbus_assert (_dbus_string_get_length (&str) == i);
460 _dbus_assert (_dbus_string_get_length (&other) == i * 2);
461 _dbus_assert (_dbus_string_equal_c_str (&other,
462 "Hello WorldHello World"));
463
464 if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2))
465 _dbus_assert_not_reached ("could not copy");
466
467 _dbus_assert (_dbus_string_get_length (&str) == i);
468 _dbus_assert (_dbus_string_get_length (&other) == i * 3);
469 _dbus_assert (_dbus_string_equal_c_str (&other,
470 "Hello WorldHello WorldHello World"));
471
472 _dbus_string_free (&str);
473 _dbus_string_free (&other);
474
475 /* Check replace */
476
477 if (!_dbus_string_init (&str))
478 _dbus_assert_not_reached ("failed to init string");
479
480 if (!_dbus_string_append (&str, "Hello World"))
481 _dbus_assert_not_reached ("could not append to string");
482
483 i = _dbus_string_get_length (&str);
484
485 if (!_dbus_string_init (&other))
486 _dbus_assert_not_reached ("could not init string");
487
488 if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
489 &other, 0, _dbus_string_get_length (&other)))
490 _dbus_assert_not_reached ("could not replace");
491
492 _dbus_assert (_dbus_string_get_length (&str) == i);
493 _dbus_assert (_dbus_string_get_length (&other) == i);
494 _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World"));
495
496 if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
497 &other, 5, 1))
498 _dbus_assert_not_reached ("could not replace center space");
499
500 _dbus_assert (_dbus_string_get_length (&str) == i);
501 _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
502 _dbus_assert (_dbus_string_equal_c_str (&other,
503 "HelloHello WorldWorld"));
504
505
506 if (!_dbus_string_replace_len (&str, 1, 1,
507 &other,
508 _dbus_string_get_length (&other) - 1,
509 1))
510 _dbus_assert_not_reached ("could not replace end character");
511
512 _dbus_assert (_dbus_string_get_length (&str) == i);
513 _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
514 _dbus_assert (_dbus_string_equal_c_str (&other,
515 "HelloHello WorldWorle"));
516
517 _dbus_string_free (&str);
518 _dbus_string_free (&other);
519
520 /* Check append/get unichar */
521
522 if (!_dbus_string_init (&str))
523 _dbus_assert_not_reached ("failed to init string");
524
525 ch = 0;
526 if (!_dbus_string_append_unichar (&str, 0xfffc))
527 _dbus_assert_not_reached ("failed to append unichar");
528
529 _dbus_string_get_unichar (&str, 0, &ch, &i);
530
531 _dbus_assert (ch == 0xfffc);
532 _dbus_assert (i == _dbus_string_get_length (&str));
533
534 _dbus_string_free (&str);
535
536 /* Check insert/set/get byte */
537
538 if (!_dbus_string_init (&str))
539 _dbus_assert_not_reached ("failed to init string");
540
541 if (!_dbus_string_append (&str, "Hello"))
542 _dbus_assert_not_reached ("failed to append Hello");
543
544 _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H');
545 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e');
546 _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l');
547 _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l');
548 _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o');
549
550 _dbus_string_set_byte (&str, 1, 'q');
551 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');
552
553 if (!_dbus_string_insert_bytes (&str, 0, 1, 255))
554 _dbus_assert_not_reached ("can't insert byte");
555
556 if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z'))
557 _dbus_assert_not_reached ("can't insert byte");
558
559 if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W'))
560 _dbus_assert_not_reached ("can't insert byte");
561
562 _dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
563 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
564 _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
565 _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z');
566 _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z');
567 _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z');
568 _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q');
569 _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l');
570 _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l');
571 _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o');
572 _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W');
573
574 _dbus_string_free (&str);
575
576 /* Check append/parse int/double */
577
578 if (!_dbus_string_init (&str))
579 _dbus_assert_not_reached ("failed to init string");
580
581 if (!_dbus_string_append_int (&str, 27))
582 _dbus_assert_not_reached ("failed to append int");
583
584 i = _dbus_string_get_length (&str);
585
586 if (!_dbus_string_parse_int (&str, 0, &v, &end))
587 _dbus_assert_not_reached ("failed to parse int");
588
589 _dbus_assert (v == 27);
590 _dbus_assert (end == i);
591
592 _dbus_string_free (&str);
593
594 if (!_dbus_string_init (&str))
595 _dbus_assert_not_reached ("failed to init string");
596
597 if (!_dbus_string_append_double (&str, 50.3))
598 _dbus_assert_not_reached ("failed to append float");
599
600 i = _dbus_string_get_length (&str);
601
602 if (!_dbus_string_parse_double (&str, 0, &d, &end))
603 _dbus_assert_not_reached ("failed to parse float");
604
605 _dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6));
606 _dbus_assert (end == i);
607
608 _dbus_string_free (&str);
609
610 /* Test find */
611 if (!_dbus_string_init (&str))
612 _dbus_assert_not_reached ("failed to init string");
613
614 if (!_dbus_string_append (&str, "Hello"))
615 _dbus_assert_not_reached ("couldn't append to string");
616
617 if (!_dbus_string_find (&str, 0, "He", &i))
618 _dbus_assert_not_reached ("didn't find 'He'");
619 _dbus_assert (i == 0);
620
621 if (!_dbus_string_find (&str, 0, "Hello", &i))
622 _dbus_assert_not_reached ("didn't find 'Hello'");
623 _dbus_assert (i == 0);
624
625 if (!_dbus_string_find (&str, 0, "ello", &i))
626 _dbus_assert_not_reached ("didn't find 'ello'");
627 _dbus_assert (i == 1);
628
629 if (!_dbus_string_find (&str, 0, "lo", &i))
630 _dbus_assert_not_reached ("didn't find 'lo'");
631 _dbus_assert (i == 3);
632
633 if (!_dbus_string_find (&str, 2, "lo", &i))
634 _dbus_assert_not_reached ("didn't find 'lo'");
635 _dbus_assert (i == 3);
636
637 if (_dbus_string_find (&str, 4, "lo", &i))
638 _dbus_assert_not_reached ("did find 'lo'");
639
640 if (!_dbus_string_find (&str, 0, "l", &i))
641 _dbus_assert_not_reached ("didn't find 'l'");
642 _dbus_assert (i == 2);
643
644 if (!_dbus_string_find (&str, 0, "H", &i))
645 _dbus_assert_not_reached ("didn't find 'H'");
646 _dbus_assert (i == 0);
647
648 if (!_dbus_string_find (&str, 0, "", &i))
649 _dbus_assert_not_reached ("didn't find ''");
650 _dbus_assert (i == 0);
651
652 if (_dbus_string_find (&str, 0, "Hello!", NULL))
653 _dbus_assert_not_reached ("Did find 'Hello!'");
654
655 if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
656 _dbus_assert_not_reached ("Did find 'Oh, Hello'");
657
658 if (_dbus_string_find (&str, 0, "ill", NULL))
659 _dbus_assert_not_reached ("Did find 'ill'");
660
661 if (_dbus_string_find (&str, 0, "q", NULL))
662 _dbus_assert_not_reached ("Did find 'q'");
663
664 if (!_dbus_string_find_to (&str, 0, 2, "He", NULL))
665 _dbus_assert_not_reached ("Didn't find 'He'");
666
667 if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL))
668 _dbus_assert_not_reached ("Did find 'Hello'");
669
670 if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i))
671 _dbus_assert_not_reached ("Did not find 'H'");
672 _dbus_assert (i == 0);
673
674 if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i))
675 _dbus_assert_not_reached ("Did not find 'o'");
676 _dbus_assert (i == _dbus_string_get_length (&str) - 1);
677
678 if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i))
679 _dbus_assert_not_reached ("Did find 'o'");
680 _dbus_assert (i == -1);
681
682 if (_dbus_string_find_byte_backward (&str, 1, 'e', &i))
683 _dbus_assert_not_reached ("Did find 'e'");
684 _dbus_assert (i == -1);
685
686 if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i))
687 _dbus_assert_not_reached ("Didn't find 'e'");
688 _dbus_assert (i == 1);
689
690 _dbus_string_free (&str);
691
692 /* Hex encoding */
693 _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string");
694 if (!_dbus_string_init (&other))
695 _dbus_assert_not_reached ("could not init string");
696
697 if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0))
698 _dbus_assert_not_reached ("deccoded bogus hex string with no error");
699
700 _dbus_assert (end == 8);
701
702 _dbus_string_free (&other);
703
704 test_roundtrips (test_hex_roundtrip);
705
706 _dbus_string_free (&str);
707
708 {
709 int found, found_len;
710
711 _dbus_string_init_const (&str, "012\r\n567\n90");
712
713 if (!_dbus_string_find_eol (&str, 0, &found, &found_len) || found != 3 || found_len != 2)
714 _dbus_assert_not_reached ("Did not find '\\r\\n'");
715 if (found != 3 || found_len != 2)
716 _dbus_assert_not_reached ("invalid return values");
717
718 if (!_dbus_string_find_eol (&str, 5, &found, &found_len))
719 _dbus_assert_not_reached ("Did not find '\\n'");
720 if (found != 8 || found_len != 1)
721 _dbus_assert_not_reached ("invalid return values");
722
723 if (_dbus_string_find_eol (&str, 9, &found, &found_len))
724 _dbus_assert_not_reached ("Found not expected '\\n'");
725 else if (found != 11 || found_len != 0)
726 _dbus_assert_not_reached ("invalid return values '\\n'");
727
728 found = -1;
729 found_len = -1;
730 _dbus_string_init_const (&str, "");
731 if (_dbus_string_find_eol (&str, 0, &found, &found_len))
732 _dbus_assert_not_reached ("found an eol in an empty string");
733 _dbus_assert (found == 0);
734 _dbus_assert (found_len == 0);
735
736 found = -1;
737 found_len = -1;
738 _dbus_string_init_const (&str, "foobar");
739 if (_dbus_string_find_eol (&str, 0, &found, &found_len))
740 _dbus_assert_not_reached ("found eol in string that lacks one");
741 _dbus_assert (found == 6);
742 _dbus_assert (found_len == 0);
743
744 found = -1;
745 found_len = -1;
746 _dbus_string_init_const (&str, "foobar\n");
747 if (!_dbus_string_find_eol (&str, 0, &found, &found_len))
748 _dbus_assert_not_reached ("did not find eol in string that has one at end");
749 _dbus_assert (found == 6);
750 _dbus_assert (found_len == 1);
751 }
752
753 {
754 DBusString line;
755
756 #define FIRST_LINE "this is a line"
757 #define SECOND_LINE "this is a second line"
758 /* third line is empty */
759 #define THIRD_LINE ""
760 #define FOURTH_LINE "this is a fourth line"
761
762 if (!_dbus_string_init (&str))
763 _dbus_assert_not_reached ("no memory");
764
765 if (!_dbus_string_append (&str, FIRST_LINE "\n" SECOND_LINE "\r\n" THIRD_LINE "\n" FOURTH_LINE))
766 _dbus_assert_not_reached ("no memory");
767
768 if (!_dbus_string_init (&line))
769 _dbus_assert_not_reached ("no memory");
770
771 if (!_dbus_string_pop_line (&str, &line))
772 _dbus_assert_not_reached ("failed to pop first line");
773
774 _dbus_assert (_dbus_string_equal_c_str (&line, FIRST_LINE));
775
776 if (!_dbus_string_pop_line (&str, &line))
777 _dbus_assert_not_reached ("failed to pop second line");
778
779 _dbus_assert (_dbus_string_equal_c_str (&line, SECOND_LINE));
780
781 if (!_dbus_string_pop_line (&str, &line))
782 _dbus_assert_not_reached ("failed to pop third line");
783
784 _dbus_assert (_dbus_string_equal_c_str (&line, THIRD_LINE));
785
786 if (!_dbus_string_pop_line (&str, &line))
787 _dbus_assert_not_reached ("failed to pop fourth line");
788
789 _dbus_assert (_dbus_string_equal_c_str (&line, FOURTH_LINE));
790
791 _dbus_string_free (&str);
792 _dbus_string_free (&line);
793 }
794
795 {
796 if (!_dbus_string_init (&str))
797 _dbus_assert_not_reached ("no memory");
798
799 for (i = 0; i < 10000; i++)
800 if (!_dbus_string_append (&str, "abcdefghijklmnopqrstuvwxyz"))
801 _dbus_assert_not_reached ("no memory");
802
803 if (!_dbus_string_set_length (&str, 10))
804 _dbus_assert_not_reached ("failed to set length");
805
806 /* actually compact */
807 if (!_dbus_string_compact (&str, 2048))
808 _dbus_assert_not_reached ("failed to compact after set_length");
809
810 /* peek inside to make sure it worked */
811 if (((DBusRealString *)&str)->allocated > 30)
812 _dbus_assert_not_reached ("compacting string didn't do anything");
813
814 if (!_dbus_string_equal_c_str (&str, "abcdefghij"))
815 _dbus_assert_not_reached ("unexpected content after compact");
816
817 /* compact nothing */
818 if (!_dbus_string_compact (&str, 2048))
819 _dbus_assert_not_reached ("failed to compact 2nd time");
820
821 if (!_dbus_string_equal_c_str (&str, "abcdefghij"))
822 _dbus_assert_not_reached ("unexpected content after 2nd compact");
823
824 /* and make sure it still works...*/
825 if (!_dbus_string_append (&str, "123456"))
826 _dbus_assert_not_reached ("failed to append after compact");
827
828 if (!_dbus_string_equal_c_str (&str, "abcdefghij123456"))
829 _dbus_assert_not_reached ("unexpected content after append");
830
831 /* after growing automatically, this should do nothing */
832 if (!_dbus_string_compact (&str, 20000))
833 _dbus_assert_not_reached ("failed to compact after grow");
834
835 /* but this one will do something */
836 if (!_dbus_string_compact (&str, 0))
837 _dbus_assert_not_reached ("failed to compact after grow");
838
839 if (!_dbus_string_equal_c_str (&str, "abcdefghij123456"))
840 _dbus_assert_not_reached ("unexpected content");
841
842 if (!_dbus_string_append (&str, "!@#$%"))
843 _dbus_assert_not_reached ("failed to append after compact");
844
845 if (!_dbus_string_equal_c_str (&str, "abcdefghij123456!@#$%"))
846 _dbus_assert_not_reached ("unexpected content");
847
848 _dbus_string_free (&str);
849 }
850
851 {
852 const char two_strings[] = "one\ttwo";
853
854 if (!_dbus_string_init (&str))
855 _dbus_assert_not_reached ("no memory");
856
857 if (!_dbus_string_init (&other))
858 _dbus_assert_not_reached ("no memory");
859
860 if (!_dbus_string_append (&str, two_strings))
861 _dbus_assert_not_reached ("no memory");
862
863 if (!_dbus_string_split_on_byte (&str, '\t', &other))
864 _dbus_assert_not_reached ("no memory or delimiter not found");
865
866 if (strcmp (_dbus_string_get_data (&str), "one") != 0)
867 _dbus_assert_not_reached ("left side after split on tab is wrong");
868
869 if (strcmp (_dbus_string_get_data (&other), "two") != 0)
870 _dbus_assert_not_reached ("right side after split on tab is wrong");
871
872 _dbus_string_free (&str);
873 _dbus_string_free (&other);
874 }
875
876 {
877 const char upper_string[] = "TOUPPERSTRING";
878 const char lower_string[] = "toupperstring";
879 const char lower2_string[] = "toupperSTRING";
880
881 if (!_dbus_string_init (&str))
882 _dbus_assert_not_reached ("no memory");
883
884 if (!_dbus_string_append (&str, upper_string))
885 _dbus_assert_not_reached ("no memory");
886
887 _dbus_string_tolower_ascii (&str, 0, _dbus_string_get_length(&str));
888
889 if (!_dbus_string_equal_c_str (&str, lower_string))
890 _dbus_assert_not_reached ("_dbus_string_tolower_ascii failed");
891
892 _dbus_string_free (&str);
893
894 if (!_dbus_string_init (&str))
895 _dbus_assert_not_reached ("no memory");
896
897 if (!_dbus_string_append (&str, upper_string))
898 _dbus_assert_not_reached ("no memory");
899
900 _dbus_string_tolower_ascii (&str, 0, 7);
901
902 if (!_dbus_string_equal_c_str (&str, lower2_string))
903 _dbus_assert_not_reached ("_dbus_string_tolower_ascii failed in partial conversion");
904
905 _dbus_string_free (&str);
906 }
907
908 {
909 const char lower_string[] = "toupperstring";
910 const char upper_string[] = "TOUPPERSTRING";
911 const char upper2_string[] = "TOUPPERstring";
912
913 if (!_dbus_string_init (&str))
914 _dbus_assert_not_reached ("no memory");
915
916 if (!_dbus_string_append (&str, lower_string))
917 _dbus_assert_not_reached ("no memory");
918
919 _dbus_string_toupper_ascii (&str, 0, _dbus_string_get_length(&str));
920
921 if (!_dbus_string_equal_c_str (&str, upper_string))
922 _dbus_assert_not_reached ("_dbus_string_toupper_ascii failed");
923
924 _dbus_string_free (&str);
925
926 if (!_dbus_string_init (&str))
927 _dbus_assert_not_reached ("no memory");
928
929 if (!_dbus_string_append (&str, lower_string))
930 _dbus_assert_not_reached ("no memory");
931
932 _dbus_string_toupper_ascii (&str, 0, 7);
933
934 if (!_dbus_string_equal_c_str (&str, upper2_string))
935 _dbus_assert_not_reached ("_dbus_string_toupper_ascii failed in partial conversion");
936
937 _dbus_string_free (&str);
938 }
939
940 return TRUE;
941 }
942
943 #endif /* DBUS_BUILD_TESTS */
944