1 /* -*- mode: C; c-file-style: "gnu" -*- */
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 *
6 * Licensed under the Academic Free License version 2.1
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24 #include "dbus-internals.h"
25 #include "dbus-string.h"
26 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
27 #include "dbus-string-private.h"
28
29 /**
30 * @addtogroup DBusString
31 * @{
32 */
33
34 /**
35 * Returns whether a string ends with the given suffix
36 *
37 * @todo memcmp might make this faster.
38 *
39 * @param a the string
40 * @param c_str the C-style string
41 * @returns #TRUE if the string ends with the suffix
42 */
43 dbus_bool_t
_dbus_string_ends_with_c_str(const DBusString * a,const char * c_str)44 _dbus_string_ends_with_c_str (const DBusString *a,
45 const char *c_str)
46 {
47 const unsigned char *ap;
48 const unsigned char *bp;
49 const unsigned char *a_end;
50 unsigned long c_str_len;
51 const DBusRealString *real_a = (const DBusRealString*) a;
52 DBUS_GENERIC_STRING_PREAMBLE (real_a);
53 _dbus_assert (c_str != NULL);
54
55 c_str_len = strlen (c_str);
56 if (((unsigned long)real_a->len) < c_str_len)
57 return FALSE;
58
59 ap = real_a->str + (real_a->len - c_str_len);
60 bp = (const unsigned char*) c_str;
61 a_end = real_a->str + real_a->len;
62 while (ap != a_end)
63 {
64 if (*ap != *bp)
65 return FALSE;
66
67 ++ap;
68 ++bp;
69 }
70
71 _dbus_assert (*ap == '\0');
72 _dbus_assert (*bp == '\0');
73
74 return TRUE;
75 }
76
77 /**
78 * Find the given byte scanning backward from the given start.
79 * Sets *found to -1 if the byte is not found.
80 *
81 * @param str the string
82 * @param start the place to start scanning (will not find the byte at this point)
83 * @param byte the byte to find
84 * @param found return location for where it was found
85 * @returns #TRUE if found
86 */
87 dbus_bool_t
_dbus_string_find_byte_backward(const DBusString * str,int start,unsigned char byte,int * found)88 _dbus_string_find_byte_backward (const DBusString *str,
89 int start,
90 unsigned char byte,
91 int *found)
92 {
93 int i;
94 DBUS_CONST_STRING_PREAMBLE (str);
95 _dbus_assert (start <= real->len);
96 _dbus_assert (start >= 0);
97 _dbus_assert (found != NULL);
98
99 i = start - 1;
100 while (i >= 0)
101 {
102 if (real->str[i] == byte)
103 break;
104
105 --i;
106 }
107
108 if (found)
109 *found = i;
110
111 return i >= 0;
112 }
113
114 /** @} */
115
116 #ifdef DBUS_BUILD_TESTS
117 #include "dbus-test.h"
118 #include <stdio.h>
119
120 static void
test_max_len(DBusString * str,int max_len)121 test_max_len (DBusString *str,
122 int max_len)
123 {
124 if (max_len > 0)
125 {
126 if (!_dbus_string_set_length (str, max_len - 1))
127 _dbus_assert_not_reached ("setting len to one less than max should have worked");
128 }
129
130 if (!_dbus_string_set_length (str, max_len))
131 _dbus_assert_not_reached ("setting len to max len should have worked");
132
133 if (_dbus_string_set_length (str, max_len + 1))
134 _dbus_assert_not_reached ("setting len to one more than max len should not have worked");
135
136 if (!_dbus_string_set_length (str, 0))
137 _dbus_assert_not_reached ("setting len to zero should have worked");
138 }
139
140 static void
test_hex_roundtrip(const unsigned char * data,int len)141 test_hex_roundtrip (const unsigned char *data,
142 int len)
143 {
144 DBusString orig;
145 DBusString encoded;
146 DBusString decoded;
147 int end;
148
149 if (len < 0)
150 len = strlen (data);
151
152 if (!_dbus_string_init (&orig))
153 _dbus_assert_not_reached ("could not init string");
154
155 if (!_dbus_string_init (&encoded))
156 _dbus_assert_not_reached ("could not init string");
157
158 if (!_dbus_string_init (&decoded))
159 _dbus_assert_not_reached ("could not init string");
160
161 if (!_dbus_string_append_len (&orig, data, len))
162 _dbus_assert_not_reached ("couldn't append orig data");
163
164 if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))
165 _dbus_assert_not_reached ("could not encode");
166
167 if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0))
168 _dbus_assert_not_reached ("could not decode");
169
170 _dbus_assert (_dbus_string_get_length (&encoded) == end);
171
172 if (!_dbus_string_equal (&orig, &decoded))
173 {
174 const char *s;
175
176 printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
177 _dbus_string_get_length (&orig),
178 _dbus_string_get_length (&encoded),
179 _dbus_string_get_length (&decoded));
180 printf ("Original: %s\n", data);
181 s = _dbus_string_get_const_data (&decoded);
182 printf ("Decoded: %s\n", s);
183 _dbus_assert_not_reached ("original string not the same as string decoded from hex");
184 }
185
186 _dbus_string_free (&orig);
187 _dbus_string_free (&encoded);
188 _dbus_string_free (&decoded);
189 }
190
191 typedef void (* TestRoundtripFunc) (const unsigned char *data,
192 int len);
193 static void
test_roundtrips(TestRoundtripFunc func)194 test_roundtrips (TestRoundtripFunc func)
195 {
196 (* func) ("Hello this is a string\n", -1);
197 (* func) ("Hello this is a string\n1", -1);
198 (* func) ("Hello this is a string\n12", -1);
199 (* func) ("Hello this is a string\n123", -1);
200 (* func) ("Hello this is a string\n1234", -1);
201 (* func) ("Hello this is a string\n12345", -1);
202 (* func) ("", 0);
203 (* func) ("1", 1);
204 (* func) ("12", 2);
205 (* func) ("123", 3);
206 (* func) ("1234", 4);
207 (* func) ("12345", 5);
208 (* func) ("", 1);
209 (* func) ("1", 2);
210 (* func) ("12", 3);
211 (* func) ("123", 4);
212 (* func) ("1234", 5);
213 (* func) ("12345", 6);
214 {
215 unsigned char buf[512];
216 int i;
217
218 i = 0;
219 while (i < _DBUS_N_ELEMENTS (buf))
220 {
221 buf[i] = i;
222 ++i;
223 }
224 i = 0;
225 while (i < _DBUS_N_ELEMENTS (buf))
226 {
227 (* func) (buf, i);
228 ++i;
229 }
230 }
231 }
232
233 #ifdef DBUS_BUILD_TESTS
234 /* The max length thing is sort of a historical artifact
235 * from a feature that turned out to be dumb; perhaps
236 * we should purge it entirely. The problem with
237 * the feature is that it looks like memory allocation
238 * failure, but is not a transient or resolvable failure.
239 */
240 static void
set_max_length(DBusString * str,int max_length)241 set_max_length (DBusString *str,
242 int max_length)
243 {
244 DBusRealString *real;
245
246 real = (DBusRealString*) str;
247
248 real->max_length = max_length;
249 }
250 #endif /* DBUS_BUILD_TESTS */
251
252 /**
253 * @ingroup DBusStringInternals
254 * Unit test for DBusString.
255 *
256 * @todo Need to write tests for _dbus_string_copy() and
257 * _dbus_string_move() moving to/from each of start/middle/end of a
258 * string. Also need tests for _dbus_string_move_len ()
259 *
260 * @returns #TRUE on success.
261 */
262 dbus_bool_t
_dbus_string_test(void)263 _dbus_string_test (void)
264 {
265 DBusString str;
266 DBusString other;
267 int i, end;
268 long v;
269 double d;
270 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 };
271 char *s;
272 dbus_unichar_t ch;
273
274 i = 0;
275 while (i < _DBUS_N_ELEMENTS (lens))
276 {
277 if (!_dbus_string_init (&str))
278 _dbus_assert_not_reached ("failed to init string");
279
280 set_max_length (&str, lens[i]);
281
282 test_max_len (&str, lens[i]);
283 _dbus_string_free (&str);
284
285 ++i;
286 }
287
288 /* Test shortening and setting length */
289 i = 0;
290 while (i < _DBUS_N_ELEMENTS (lens))
291 {
292 int j;
293
294 if (!_dbus_string_init (&str))
295 _dbus_assert_not_reached ("failed to init string");
296
297 set_max_length (&str, lens[i]);
298
299 if (!_dbus_string_set_length (&str, lens[i]))
300 _dbus_assert_not_reached ("failed to set string length");
301
302 j = lens[i];
303 while (j > 0)
304 {
305 _dbus_assert (_dbus_string_get_length (&str) == j);
306 if (j > 0)
307 {
308 _dbus_string_shorten (&str, 1);
309 _dbus_assert (_dbus_string_get_length (&str) == (j - 1));
310 }
311 --j;
312 }
313
314 _dbus_string_free (&str);
315
316 ++i;
317 }
318
319 /* Test equality */
320 if (!_dbus_string_init (&str))
321 _dbus_assert_not_reached ("oom");
322
323 if (!_dbus_string_append (&str, "Hello World"))
324 _dbus_assert_not_reached ("oom");
325
326 _dbus_string_init_const (&other, "H");
327 _dbus_assert (_dbus_string_equal_substring (&str, 0, 1, &other, 0));
328 _dbus_assert (_dbus_string_equal_substring (&str, 1, 0, &other, 1));
329 _dbus_string_init_const (&other, "Hello");
330 _dbus_assert (_dbus_string_equal_substring (&str, 0, 5, &other, 0));
331 _dbus_assert (_dbus_string_equal_substring (&str, 1, 4, &other, 1));
332 _dbus_assert (_dbus_string_equal_substring (&str, 2, 3, &other, 2));
333 _dbus_assert (_dbus_string_equal_substring (&str, 3, 2, &other, 3));
334 _dbus_assert (_dbus_string_equal_substring (&str, 4, 1, &other, 4));
335 _dbus_assert (_dbus_string_equal_substring (&str, 5, 0, &other, 5));
336
337 _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 0));
338 _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 1));
339 _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 2));
340 _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 3));
341 _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 4));
342 _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 5));
343
344
345 _dbus_string_init_const (&other, "World");
346 _dbus_assert (_dbus_string_equal_substring (&str, 6, 5, &other, 0));
347 _dbus_assert (_dbus_string_equal_substring (&str, 7, 4, &other, 1));
348 _dbus_assert (_dbus_string_equal_substring (&str, 8, 3, &other, 2));
349 _dbus_assert (_dbus_string_equal_substring (&str, 9, 2, &other, 3));
350 _dbus_assert (_dbus_string_equal_substring (&str, 10, 1, &other, 4));
351 _dbus_assert (_dbus_string_equal_substring (&str, 11, 0, &other, 5));
352
353 _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 6));
354 _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 7));
355 _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 8));
356 _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 9));
357 _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 10));
358 _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 11));
359
360 _dbus_string_free (&str);
361
362 /* Test appending data */
363 if (!_dbus_string_init (&str))
364 _dbus_assert_not_reached ("failed to init string");
365
366 i = 0;
367 while (i < 10)
368 {
369 if (!_dbus_string_append (&str, "a"))
370 _dbus_assert_not_reached ("failed to append string to string\n");
371
372 _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1);
373
374 if (!_dbus_string_append_byte (&str, 'b'))
375 _dbus_assert_not_reached ("failed to append byte to string\n");
376
377 _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2);
378
379 ++i;
380 }
381
382 _dbus_string_free (&str);
383
384 /* Check steal_data */
385
386 if (!_dbus_string_init (&str))
387 _dbus_assert_not_reached ("failed to init string");
388
389 if (!_dbus_string_append (&str, "Hello World"))
390 _dbus_assert_not_reached ("could not append to string");
391
392 i = _dbus_string_get_length (&str);
393
394 if (!_dbus_string_steal_data (&str, &s))
395 _dbus_assert_not_reached ("failed to steal data");
396
397 _dbus_assert (_dbus_string_get_length (&str) == 0);
398 _dbus_assert (((int)strlen (s)) == i);
399
400 dbus_free (s);
401
402 /* Check move */
403
404 if (!_dbus_string_append (&str, "Hello World"))
405 _dbus_assert_not_reached ("could not append to string");
406
407 i = _dbus_string_get_length (&str);
408
409 if (!_dbus_string_init (&other))
410 _dbus_assert_not_reached ("could not init string");
411
412 if (!_dbus_string_move (&str, 0, &other, 0))
413 _dbus_assert_not_reached ("could not move");
414
415 _dbus_assert (_dbus_string_get_length (&str) == 0);
416 _dbus_assert (_dbus_string_get_length (&other) == i);
417
418 if (!_dbus_string_append (&str, "Hello World"))
419 _dbus_assert_not_reached ("could not append to string");
420
421 if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other)))
422 _dbus_assert_not_reached ("could not move");
423
424 _dbus_assert (_dbus_string_get_length (&str) == 0);
425 _dbus_assert (_dbus_string_get_length (&other) == i * 2);
426
427 if (!_dbus_string_append (&str, "Hello World"))
428 _dbus_assert_not_reached ("could not append to string");
429
430 if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2))
431 _dbus_assert_not_reached ("could not move");
432
433 _dbus_assert (_dbus_string_get_length (&str) == 0);
434 _dbus_assert (_dbus_string_get_length (&other) == i * 3);
435
436 _dbus_string_free (&other);
437
438 /* Check copy */
439
440 if (!_dbus_string_append (&str, "Hello World"))
441 _dbus_assert_not_reached ("could not append to string");
442
443 i = _dbus_string_get_length (&str);
444
445 if (!_dbus_string_init (&other))
446 _dbus_assert_not_reached ("could not init string");
447
448 if (!_dbus_string_copy (&str, 0, &other, 0))
449 _dbus_assert_not_reached ("could not copy");
450
451 _dbus_assert (_dbus_string_get_length (&str) == i);
452 _dbus_assert (_dbus_string_get_length (&other) == i);
453
454 if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other)))
455 _dbus_assert_not_reached ("could not copy");
456
457 _dbus_assert (_dbus_string_get_length (&str) == i);
458 _dbus_assert (_dbus_string_get_length (&other) == i * 2);
459 _dbus_assert (_dbus_string_equal_c_str (&other,
460 "Hello WorldHello World"));
461
462 if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2))
463 _dbus_assert_not_reached ("could not copy");
464
465 _dbus_assert (_dbus_string_get_length (&str) == i);
466 _dbus_assert (_dbus_string_get_length (&other) == i * 3);
467 _dbus_assert (_dbus_string_equal_c_str (&other,
468 "Hello WorldHello WorldHello World"));
469
470 _dbus_string_free (&str);
471 _dbus_string_free (&other);
472
473 /* Check replace */
474
475 if (!_dbus_string_init (&str))
476 _dbus_assert_not_reached ("failed to init string");
477
478 if (!_dbus_string_append (&str, "Hello World"))
479 _dbus_assert_not_reached ("could not append to string");
480
481 i = _dbus_string_get_length (&str);
482
483 if (!_dbus_string_init (&other))
484 _dbus_assert_not_reached ("could not init string");
485
486 if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
487 &other, 0, _dbus_string_get_length (&other)))
488 _dbus_assert_not_reached ("could not replace");
489
490 _dbus_assert (_dbus_string_get_length (&str) == i);
491 _dbus_assert (_dbus_string_get_length (&other) == i);
492 _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World"));
493
494 if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
495 &other, 5, 1))
496 _dbus_assert_not_reached ("could not replace center space");
497
498 _dbus_assert (_dbus_string_get_length (&str) == i);
499 _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
500 _dbus_assert (_dbus_string_equal_c_str (&other,
501 "HelloHello WorldWorld"));
502
503
504 if (!_dbus_string_replace_len (&str, 1, 1,
505 &other,
506 _dbus_string_get_length (&other) - 1,
507 1))
508 _dbus_assert_not_reached ("could not replace end character");
509
510 _dbus_assert (_dbus_string_get_length (&str) == i);
511 _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
512 _dbus_assert (_dbus_string_equal_c_str (&other,
513 "HelloHello WorldWorle"));
514
515 _dbus_string_free (&str);
516 _dbus_string_free (&other);
517
518 /* Check append/get unichar */
519
520 if (!_dbus_string_init (&str))
521 _dbus_assert_not_reached ("failed to init string");
522
523 ch = 0;
524 if (!_dbus_string_append_unichar (&str, 0xfffc))
525 _dbus_assert_not_reached ("failed to append unichar");
526
527 _dbus_string_get_unichar (&str, 0, &ch, &i);
528
529 _dbus_assert (ch == 0xfffc);
530 _dbus_assert (i == _dbus_string_get_length (&str));
531
532 _dbus_string_free (&str);
533
534 /* Check insert/set/get byte */
535
536 if (!_dbus_string_init (&str))
537 _dbus_assert_not_reached ("failed to init string");
538
539 if (!_dbus_string_append (&str, "Hello"))
540 _dbus_assert_not_reached ("failed to append Hello");
541
542 _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H');
543 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e');
544 _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l');
545 _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l');
546 _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o');
547
548 _dbus_string_set_byte (&str, 1, 'q');
549 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');
550
551 if (!_dbus_string_insert_bytes (&str, 0, 1, 255))
552 _dbus_assert_not_reached ("can't insert byte");
553
554 if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z'))
555 _dbus_assert_not_reached ("can't insert byte");
556
557 if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W'))
558 _dbus_assert_not_reached ("can't insert byte");
559
560 _dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
561 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
562 _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
563 _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z');
564 _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z');
565 _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z');
566 _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q');
567 _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l');
568 _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l');
569 _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o');
570 _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W');
571
572 _dbus_string_free (&str);
573
574 /* Check append/parse int/double */
575
576 if (!_dbus_string_init (&str))
577 _dbus_assert_not_reached ("failed to init string");
578
579 if (!_dbus_string_append_int (&str, 27))
580 _dbus_assert_not_reached ("failed to append int");
581
582 i = _dbus_string_get_length (&str);
583
584 if (!_dbus_string_parse_int (&str, 0, &v, &end))
585 _dbus_assert_not_reached ("failed to parse int");
586
587 _dbus_assert (v == 27);
588 _dbus_assert (end == i);
589
590 _dbus_string_free (&str);
591
592 if (!_dbus_string_init (&str))
593 _dbus_assert_not_reached ("failed to init string");
594
595 if (!_dbus_string_append_double (&str, 50.3))
596 _dbus_assert_not_reached ("failed to append float");
597
598 i = _dbus_string_get_length (&str);
599
600 if (!_dbus_string_parse_double (&str, 0, &d, &end))
601 _dbus_assert_not_reached ("failed to parse float");
602
603 _dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6));
604 _dbus_assert (end == i);
605
606 _dbus_string_free (&str);
607
608 /* Test find */
609 if (!_dbus_string_init (&str))
610 _dbus_assert_not_reached ("failed to init string");
611
612 if (!_dbus_string_append (&str, "Hello"))
613 _dbus_assert_not_reached ("couldn't append to string");
614
615 if (!_dbus_string_find (&str, 0, "He", &i))
616 _dbus_assert_not_reached ("didn't find 'He'");
617 _dbus_assert (i == 0);
618
619 if (!_dbus_string_find (&str, 0, "Hello", &i))
620 _dbus_assert_not_reached ("didn't find 'Hello'");
621 _dbus_assert (i == 0);
622
623 if (!_dbus_string_find (&str, 0, "ello", &i))
624 _dbus_assert_not_reached ("didn't find 'ello'");
625 _dbus_assert (i == 1);
626
627 if (!_dbus_string_find (&str, 0, "lo", &i))
628 _dbus_assert_not_reached ("didn't find 'lo'");
629 _dbus_assert (i == 3);
630
631 if (!_dbus_string_find (&str, 2, "lo", &i))
632 _dbus_assert_not_reached ("didn't find 'lo'");
633 _dbus_assert (i == 3);
634
635 if (_dbus_string_find (&str, 4, "lo", &i))
636 _dbus_assert_not_reached ("did find 'lo'");
637
638 if (!_dbus_string_find (&str, 0, "l", &i))
639 _dbus_assert_not_reached ("didn't find 'l'");
640 _dbus_assert (i == 2);
641
642 if (!_dbus_string_find (&str, 0, "H", &i))
643 _dbus_assert_not_reached ("didn't find 'H'");
644 _dbus_assert (i == 0);
645
646 if (!_dbus_string_find (&str, 0, "", &i))
647 _dbus_assert_not_reached ("didn't find ''");
648 _dbus_assert (i == 0);
649
650 if (_dbus_string_find (&str, 0, "Hello!", NULL))
651 _dbus_assert_not_reached ("Did find 'Hello!'");
652
653 if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
654 _dbus_assert_not_reached ("Did find 'Oh, Hello'");
655
656 if (_dbus_string_find (&str, 0, "ill", NULL))
657 _dbus_assert_not_reached ("Did find 'ill'");
658
659 if (_dbus_string_find (&str, 0, "q", NULL))
660 _dbus_assert_not_reached ("Did find 'q'");
661
662 if (!_dbus_string_find_to (&str, 0, 2, "He", NULL))
663 _dbus_assert_not_reached ("Didn't find 'He'");
664
665 if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL))
666 _dbus_assert_not_reached ("Did find 'Hello'");
667
668 if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i))
669 _dbus_assert_not_reached ("Did not find 'H'");
670 _dbus_assert (i == 0);
671
672 if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i))
673 _dbus_assert_not_reached ("Did not find 'o'");
674 _dbus_assert (i == _dbus_string_get_length (&str) - 1);
675
676 if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i))
677 _dbus_assert_not_reached ("Did find 'o'");
678 _dbus_assert (i == -1);
679
680 if (_dbus_string_find_byte_backward (&str, 1, 'e', &i))
681 _dbus_assert_not_reached ("Did find 'e'");
682 _dbus_assert (i == -1);
683
684 if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i))
685 _dbus_assert_not_reached ("Didn't find 'e'");
686 _dbus_assert (i == 1);
687
688 _dbus_string_free (&str);
689
690 /* Hex encoding */
691 _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string");
692 if (!_dbus_string_init (&other))
693 _dbus_assert_not_reached ("could not init string");
694
695 if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0))
696 _dbus_assert_not_reached ("deccoded bogus hex string with no error");
697
698 _dbus_assert (end == 8);
699
700 _dbus_string_free (&other);
701
702 test_roundtrips (test_hex_roundtrip);
703
704 _dbus_string_free (&str);
705
706 return TRUE;
707 }
708
709 #endif /* DBUS_BUILD_TESTS */
710