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_hex_roundtrip(const unsigned char * data,int len)123 test_hex_roundtrip (const unsigned char *data,
124 int len)
125 {
126 DBusString orig;
127 DBusString encoded;
128 DBusString decoded;
129 int end;
130
131 if (len < 0)
132 len = strlen (data);
133
134 if (!_dbus_string_init (&orig))
135 _dbus_assert_not_reached ("could not init string");
136
137 if (!_dbus_string_init (&encoded))
138 _dbus_assert_not_reached ("could not init string");
139
140 if (!_dbus_string_init (&decoded))
141 _dbus_assert_not_reached ("could not init string");
142
143 if (!_dbus_string_append_len (&orig, data, len))
144 _dbus_assert_not_reached ("couldn't append orig data");
145
146 if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))
147 _dbus_assert_not_reached ("could not encode");
148
149 if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0))
150 _dbus_assert_not_reached ("could not decode");
151
152 _dbus_assert (_dbus_string_get_length (&encoded) == end);
153
154 if (!_dbus_string_equal (&orig, &decoded))
155 {
156 const char *s;
157
158 printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
159 _dbus_string_get_length (&orig),
160 _dbus_string_get_length (&encoded),
161 _dbus_string_get_length (&decoded));
162 printf ("Original: %s\n", data);
163 s = _dbus_string_get_const_data (&decoded);
164 printf ("Decoded: %s\n", s);
165 _dbus_assert_not_reached ("original string not the same as string decoded from hex");
166 }
167
168 _dbus_string_free (&orig);
169 _dbus_string_free (&encoded);
170 _dbus_string_free (&decoded);
171 }
172
173 typedef void (* TestRoundtripFunc) (const unsigned char *data,
174 int len);
175 static void
test_roundtrips(TestRoundtripFunc func)176 test_roundtrips (TestRoundtripFunc func)
177 {
178 (* func) ("Hello this is a string\n", -1);
179 (* func) ("Hello this is a string\n1", -1);
180 (* func) ("Hello this is a string\n12", -1);
181 (* func) ("Hello this is a string\n123", -1);
182 (* func) ("Hello this is a string\n1234", -1);
183 (* func) ("Hello this is a string\n12345", -1);
184 (* func) ("", 0);
185 (* func) ("1", 1);
186 (* func) ("12", 2);
187 (* func) ("123", 3);
188 (* func) ("1234", 4);
189 (* func) ("12345", 5);
190 (* func) ("", 1);
191 (* func) ("1", 2);
192 (* func) ("12", 3);
193 (* func) ("123", 4);
194 (* func) ("1234", 5);
195 (* func) ("12345", 6);
196 {
197 unsigned char buf[512];
198 int i;
199
200 i = 0;
201 while (i < _DBUS_N_ELEMENTS (buf))
202 {
203 buf[i] = i;
204 ++i;
205 }
206 i = 0;
207 while (i < _DBUS_N_ELEMENTS (buf))
208 {
209 (* func) (buf, i);
210 ++i;
211 }
212 }
213 }
214
215 /**
216 * @ingroup DBusStringInternals
217 * Unit test for DBusString.
218 *
219 * @todo Need to write tests for _dbus_string_copy() and
220 * _dbus_string_move() moving to/from each of start/middle/end of a
221 * string. Also need tests for _dbus_string_move_len ()
222 *
223 * @returns #TRUE on success.
224 */
225 dbus_bool_t
_dbus_string_test(void)226 _dbus_string_test (void)
227 {
228 DBusString str;
229 DBusString other;
230 int i, a, end;
231 long v;
232 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 };
233 char *s;
234
235 /* Test shortening and setting length */
236 i = 0;
237 while (i < _DBUS_N_ELEMENTS (lens))
238 {
239 int j;
240
241 if (!_dbus_string_init (&str))
242 _dbus_assert_not_reached ("failed to init string");
243
244 if (!_dbus_string_set_length (&str, lens[i]))
245 _dbus_assert_not_reached ("failed to set string length");
246
247 j = lens[i];
248 while (j > 0)
249 {
250 _dbus_assert (_dbus_string_get_length (&str) == j);
251 if (j > 0)
252 {
253 _dbus_string_shorten (&str, 1);
254 _dbus_assert (_dbus_string_get_length (&str) == (j - 1));
255 }
256 --j;
257 }
258
259 _dbus_string_free (&str);
260
261 ++i;
262 }
263
264 /* Test equality */
265 if (!_dbus_string_init (&str))
266 _dbus_assert_not_reached ("oom");
267
268 if (!_dbus_string_append (&str, "Hello World"))
269 _dbus_assert_not_reached ("oom");
270
271 _dbus_string_init_const (&other, "H");
272 _dbus_assert (_dbus_string_equal_substring (&str, 0, 1, &other, 0));
273 _dbus_assert (_dbus_string_equal_substring (&str, 1, 0, &other, 1));
274 _dbus_string_init_const (&other, "Hello");
275 _dbus_assert (_dbus_string_equal_substring (&str, 0, 5, &other, 0));
276 _dbus_assert (_dbus_string_equal_substring (&str, 1, 4, &other, 1));
277 _dbus_assert (_dbus_string_equal_substring (&str, 2, 3, &other, 2));
278 _dbus_assert (_dbus_string_equal_substring (&str, 3, 2, &other, 3));
279 _dbus_assert (_dbus_string_equal_substring (&str, 4, 1, &other, 4));
280 _dbus_assert (_dbus_string_equal_substring (&str, 5, 0, &other, 5));
281
282 _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 0));
283 _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 1));
284 _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 2));
285 _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 3));
286 _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 4));
287 _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 5));
288
289
290 _dbus_string_init_const (&other, "World");
291 _dbus_assert (_dbus_string_equal_substring (&str, 6, 5, &other, 0));
292 _dbus_assert (_dbus_string_equal_substring (&str, 7, 4, &other, 1));
293 _dbus_assert (_dbus_string_equal_substring (&str, 8, 3, &other, 2));
294 _dbus_assert (_dbus_string_equal_substring (&str, 9, 2, &other, 3));
295 _dbus_assert (_dbus_string_equal_substring (&str, 10, 1, &other, 4));
296 _dbus_assert (_dbus_string_equal_substring (&str, 11, 0, &other, 5));
297
298 _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 6));
299 _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 7));
300 _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 8));
301 _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 9));
302 _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 10));
303 _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 11));
304
305 _dbus_string_free (&str);
306
307 /* Test appending data */
308 if (!_dbus_string_init (&str))
309 _dbus_assert_not_reached ("failed to init string");
310
311 i = 0;
312 while (i < 10)
313 {
314 if (!_dbus_string_append (&str, "a"))
315 _dbus_assert_not_reached ("failed to append string to string\n");
316
317 _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1);
318
319 if (!_dbus_string_append_byte (&str, 'b'))
320 _dbus_assert_not_reached ("failed to append byte to string\n");
321
322 _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2);
323
324 ++i;
325 }
326
327 _dbus_string_free (&str);
328
329 /* Check steal_data */
330
331 if (!_dbus_string_init (&str))
332 _dbus_assert_not_reached ("failed to init string");
333
334 if (!_dbus_string_append (&str, "Hello World"))
335 _dbus_assert_not_reached ("could not append to string");
336
337 i = _dbus_string_get_length (&str);
338
339 if (!_dbus_string_steal_data (&str, &s))
340 _dbus_assert_not_reached ("failed to steal data");
341
342 _dbus_assert (_dbus_string_get_length (&str) == 0);
343 _dbus_assert (((int)strlen (s)) == i);
344
345 dbus_free (s);
346
347 /* Check move */
348
349 if (!_dbus_string_append (&str, "Hello World"))
350 _dbus_assert_not_reached ("could not append to string");
351
352 i = _dbus_string_get_length (&str);
353
354 if (!_dbus_string_init (&other))
355 _dbus_assert_not_reached ("could not init string");
356
357 if (!_dbus_string_move (&str, 0, &other, 0))
358 _dbus_assert_not_reached ("could not move");
359
360 _dbus_assert (_dbus_string_get_length (&str) == 0);
361 _dbus_assert (_dbus_string_get_length (&other) == i);
362
363 if (!_dbus_string_append (&str, "Hello World"))
364 _dbus_assert_not_reached ("could not append to string");
365
366 if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other)))
367 _dbus_assert_not_reached ("could not move");
368
369 _dbus_assert (_dbus_string_get_length (&str) == 0);
370 _dbus_assert (_dbus_string_get_length (&other) == i * 2);
371
372 if (!_dbus_string_append (&str, "Hello World"))
373 _dbus_assert_not_reached ("could not append to string");
374
375 if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2))
376 _dbus_assert_not_reached ("could not move");
377
378 _dbus_assert (_dbus_string_get_length (&str) == 0);
379 _dbus_assert (_dbus_string_get_length (&other) == i * 3);
380
381 _dbus_string_free (&other);
382
383 /* Check copy */
384
385 if (!_dbus_string_append (&str, "Hello World"))
386 _dbus_assert_not_reached ("could not append to string");
387
388 i = _dbus_string_get_length (&str);
389
390 if (!_dbus_string_init (&other))
391 _dbus_assert_not_reached ("could not init string");
392
393 if (!_dbus_string_copy (&str, 0, &other, 0))
394 _dbus_assert_not_reached ("could not copy");
395
396 _dbus_assert (_dbus_string_get_length (&str) == i);
397 _dbus_assert (_dbus_string_get_length (&other) == i);
398
399 if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other)))
400 _dbus_assert_not_reached ("could not copy");
401
402 _dbus_assert (_dbus_string_get_length (&str) == i);
403 _dbus_assert (_dbus_string_get_length (&other) == i * 2);
404 _dbus_assert (_dbus_string_equal_c_str (&other,
405 "Hello WorldHello World"));
406
407 if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2))
408 _dbus_assert_not_reached ("could not copy");
409
410 _dbus_assert (_dbus_string_get_length (&str) == i);
411 _dbus_assert (_dbus_string_get_length (&other) == i * 3);
412 _dbus_assert (_dbus_string_equal_c_str (&other,
413 "Hello WorldHello WorldHello World"));
414
415 _dbus_string_free (&str);
416 _dbus_string_free (&other);
417
418 /* Check replace */
419
420 if (!_dbus_string_init (&str))
421 _dbus_assert_not_reached ("failed to init string");
422
423 if (!_dbus_string_append (&str, "Hello World"))
424 _dbus_assert_not_reached ("could not append to string");
425
426 i = _dbus_string_get_length (&str);
427
428 if (!_dbus_string_init (&other))
429 _dbus_assert_not_reached ("could not init string");
430
431 if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
432 &other, 0, _dbus_string_get_length (&other)))
433 _dbus_assert_not_reached ("could not replace");
434
435 _dbus_assert (_dbus_string_get_length (&str) == i);
436 _dbus_assert (_dbus_string_get_length (&other) == i);
437 _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World"));
438
439 if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
440 &other, 5, 1))
441 _dbus_assert_not_reached ("could not replace center space");
442
443 _dbus_assert (_dbus_string_get_length (&str) == i);
444 _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
445 _dbus_assert (_dbus_string_equal_c_str (&other,
446 "HelloHello WorldWorld"));
447
448
449 if (!_dbus_string_replace_len (&str, 1, 1,
450 &other,
451 _dbus_string_get_length (&other) - 1,
452 1))
453 _dbus_assert_not_reached ("could not replace end character");
454
455 _dbus_assert (_dbus_string_get_length (&str) == i);
456 _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
457 _dbus_assert (_dbus_string_equal_c_str (&other,
458 "HelloHello WorldWorle"));
459
460 _dbus_string_free (&str);
461 _dbus_string_free (&other);
462
463 /* Different tests are provided because different behaviours are
464 * implemented in _dbus_string_replace_len() in function of replacing and
465 * replaced lengths
466 */
467
468 if (!_dbus_string_init (&str))
469 _dbus_assert_not_reached ("failed to init string");
470
471 if (!_dbus_string_append (&str, "Hello World"))
472 _dbus_assert_not_reached ("could not append to string");
473
474 i = _dbus_string_get_length (&str);
475
476 if (!_dbus_string_init (&other))
477 _dbus_assert_not_reached ("could not init string");
478
479 if (!_dbus_string_append (&other, "Foo String"))
480 _dbus_assert_not_reached ("could not append to string");
481
482 a = _dbus_string_get_length (&other);
483
484 if (!_dbus_string_replace_len (&str, 0, 6,
485 &other, 4, 0))
486 _dbus_assert_not_reached ("could not replace 0 length");
487
488 _dbus_assert (_dbus_string_get_length (&str) == i);
489 _dbus_assert (_dbus_string_get_length (&other) == a + 6);
490 _dbus_assert (_dbus_string_equal_c_str (&other,
491 "Foo Hello String"));
492
493 if (!_dbus_string_replace_len (&str, 5, 6,
494 &other,
495 _dbus_string_get_length (&other),
496 0))
497 _dbus_assert_not_reached ("could not replace at the end");
498
499 _dbus_assert (_dbus_string_get_length (&str) == i);
500 _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6);
501 _dbus_assert (_dbus_string_equal_c_str (&other,
502 "Foo Hello String World"));
503
504 if (!_dbus_string_replace_len (&str, 0, 5,
505 &other,
506 _dbus_string_get_length (&other) - 5,
507 5))
508 _dbus_assert_not_reached ("could not replace same length");
509
510 _dbus_assert (_dbus_string_get_length (&str) == i);
511 _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6);
512 _dbus_assert (_dbus_string_equal_c_str (&other,
513 "Foo Hello String Hello"));
514
515 if (!_dbus_string_replace_len (&str, 6, 5,
516 &other, 4, 12))
517 _dbus_assert_not_reached ("could not replace with shorter string");
518
519 _dbus_assert (_dbus_string_get_length (&str) == i);
520 _dbus_assert (_dbus_string_get_length (&other) == a + 5);
521 _dbus_assert (_dbus_string_equal_c_str (&other,
522 "Foo World Hello"));
523
524 if (!_dbus_string_replace_len (&str, 0, 1,
525 &other, 0, 3))
526 _dbus_assert_not_reached ("could not replace at the beginning");
527
528 _dbus_assert (_dbus_string_get_length (&str) == i);
529 _dbus_assert (_dbus_string_get_length (&other) == a + 3);
530 _dbus_assert (_dbus_string_equal_c_str (&other,
531 "H World Hello"));
532
533 if (!_dbus_string_replace_len (&str, 6, 5,
534 &other,
535 _dbus_string_get_length (&other) - 5,
536 5))
537 _dbus_assert_not_reached ("could not replace same length");
538
539 _dbus_assert (_dbus_string_get_length (&str) == i);
540 _dbus_assert (_dbus_string_get_length (&other) == a + 3);
541 _dbus_assert (_dbus_string_equal_c_str (&other,
542 "H World World"));
543
544 _dbus_string_free (&str);
545 _dbus_string_free (&other);
546
547 /* Check insert/set/get byte */
548
549 if (!_dbus_string_init (&str))
550 _dbus_assert_not_reached ("failed to init string");
551
552 if (!_dbus_string_append (&str, "Hello"))
553 _dbus_assert_not_reached ("failed to append Hello");
554
555 _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H');
556 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e');
557 _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l');
558 _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l');
559 _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o');
560
561 _dbus_string_set_byte (&str, 1, 'q');
562 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');
563
564 if (!_dbus_string_insert_bytes (&str, 0, 1, 255))
565 _dbus_assert_not_reached ("can't insert byte");
566
567 if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z'))
568 _dbus_assert_not_reached ("can't insert byte");
569
570 if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W'))
571 _dbus_assert_not_reached ("can't insert byte");
572
573 _dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
574 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
575 _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
576 _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z');
577 _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z');
578 _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z');
579 _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q');
580 _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l');
581 _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l');
582 _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o');
583 _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W');
584
585 _dbus_string_free (&str);
586
587 /* Check append/parse int/double */
588
589 if (!_dbus_string_init (&str))
590 _dbus_assert_not_reached ("failed to init string");
591
592 if (!_dbus_string_append_int (&str, 27))
593 _dbus_assert_not_reached ("failed to append int");
594
595 i = _dbus_string_get_length (&str);
596
597 if (!_dbus_string_parse_int (&str, 0, &v, &end))
598 _dbus_assert_not_reached ("failed to parse int");
599
600 _dbus_assert (v == 27);
601 _dbus_assert (end == i);
602
603 _dbus_string_free (&str);
604
605 /* Test find */
606 if (!_dbus_string_init (&str))
607 _dbus_assert_not_reached ("failed to init string");
608
609 if (!_dbus_string_append (&str, "Hello"))
610 _dbus_assert_not_reached ("couldn't append to string");
611
612 if (!_dbus_string_find (&str, 0, "He", &i))
613 _dbus_assert_not_reached ("didn't find 'He'");
614 _dbus_assert (i == 0);
615
616 if (!_dbus_string_find (&str, 0, "Hello", &i))
617 _dbus_assert_not_reached ("didn't find 'Hello'");
618 _dbus_assert (i == 0);
619
620 if (!_dbus_string_find (&str, 0, "ello", &i))
621 _dbus_assert_not_reached ("didn't find 'ello'");
622 _dbus_assert (i == 1);
623
624 if (!_dbus_string_find (&str, 0, "lo", &i))
625 _dbus_assert_not_reached ("didn't find 'lo'");
626 _dbus_assert (i == 3);
627
628 if (!_dbus_string_find (&str, 2, "lo", &i))
629 _dbus_assert_not_reached ("didn't find 'lo'");
630 _dbus_assert (i == 3);
631
632 if (_dbus_string_find (&str, 4, "lo", &i))
633 _dbus_assert_not_reached ("did find 'lo'");
634
635 if (!_dbus_string_find (&str, 0, "l", &i))
636 _dbus_assert_not_reached ("didn't find 'l'");
637 _dbus_assert (i == 2);
638
639 if (!_dbus_string_find (&str, 0, "H", &i))
640 _dbus_assert_not_reached ("didn't find 'H'");
641 _dbus_assert (i == 0);
642
643 if (!_dbus_string_find (&str, 0, "", &i))
644 _dbus_assert_not_reached ("didn't find ''");
645 _dbus_assert (i == 0);
646
647 if (_dbus_string_find (&str, 0, "Hello!", NULL))
648 _dbus_assert_not_reached ("Did find 'Hello!'");
649
650 if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
651 _dbus_assert_not_reached ("Did find 'Oh, Hello'");
652
653 if (_dbus_string_find (&str, 0, "ill", NULL))
654 _dbus_assert_not_reached ("Did find 'ill'");
655
656 if (_dbus_string_find (&str, 0, "q", NULL))
657 _dbus_assert_not_reached ("Did find 'q'");
658
659 if (!_dbus_string_find_to (&str, 0, 2, "He", NULL))
660 _dbus_assert_not_reached ("Didn't find 'He'");
661
662 if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL))
663 _dbus_assert_not_reached ("Did find 'Hello'");
664
665 if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i))
666 _dbus_assert_not_reached ("Did not find 'H'");
667 _dbus_assert (i == 0);
668
669 if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i))
670 _dbus_assert_not_reached ("Did not find 'o'");
671 _dbus_assert (i == _dbus_string_get_length (&str) - 1);
672
673 if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i))
674 _dbus_assert_not_reached ("Did find 'o'");
675 _dbus_assert (i == -1);
676
677 if (_dbus_string_find_byte_backward (&str, 1, 'e', &i))
678 _dbus_assert_not_reached ("Did find 'e'");
679 _dbus_assert (i == -1);
680
681 if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i))
682 _dbus_assert_not_reached ("Didn't find 'e'");
683 _dbus_assert (i == 1);
684
685 _dbus_string_free (&str);
686
687 /* Hex encoding */
688 _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string");
689 if (!_dbus_string_init (&other))
690 _dbus_assert_not_reached ("could not init string");
691
692 if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0))
693 _dbus_assert_not_reached ("deccoded bogus hex string with no error");
694
695 _dbus_assert (end == 8);
696
697 _dbus_string_free (&other);
698
699 test_roundtrips (test_hex_roundtrip);
700
701 _dbus_string_free (&str);
702
703 {
704 int found, found_len;
705
706 _dbus_string_init_const (&str, "012\r\n567\n90");
707
708 if (!_dbus_string_find_eol (&str, 0, &found, &found_len) || found != 3 || found_len != 2)
709 _dbus_assert_not_reached ("Did not find '\\r\\n'");
710 if (found != 3 || found_len != 2)
711 _dbus_assert_not_reached ("invalid return values");
712
713 if (!_dbus_string_find_eol (&str, 5, &found, &found_len))
714 _dbus_assert_not_reached ("Did not find '\\n'");
715 if (found != 8 || found_len != 1)
716 _dbus_assert_not_reached ("invalid return values");
717
718 if (_dbus_string_find_eol (&str, 9, &found, &found_len))
719 _dbus_assert_not_reached ("Found not expected '\\n'");
720 else if (found != 11 || found_len != 0)
721 _dbus_assert_not_reached ("invalid return values '\\n'");
722
723 found = -1;
724 found_len = -1;
725 _dbus_string_init_const (&str, "");
726 if (_dbus_string_find_eol (&str, 0, &found, &found_len))
727 _dbus_assert_not_reached ("found an eol in an empty string");
728 _dbus_assert (found == 0);
729 _dbus_assert (found_len == 0);
730
731 found = -1;
732 found_len = -1;
733 _dbus_string_init_const (&str, "foobar");
734 if (_dbus_string_find_eol (&str, 0, &found, &found_len))
735 _dbus_assert_not_reached ("found eol in string that lacks one");
736 _dbus_assert (found == 6);
737 _dbus_assert (found_len == 0);
738
739 found = -1;
740 found_len = -1;
741 _dbus_string_init_const (&str, "foobar\n");
742 if (!_dbus_string_find_eol (&str, 0, &found, &found_len))
743 _dbus_assert_not_reached ("did not find eol in string that has one at end");
744 _dbus_assert (found == 6);
745 _dbus_assert (found_len == 1);
746 }
747
748 {
749 DBusString line;
750
751 #define FIRST_LINE "this is a line"
752 #define SECOND_LINE "this is a second line"
753 /* third line is empty */
754 #define THIRD_LINE ""
755 #define FOURTH_LINE "this is a fourth line"
756
757 if (!_dbus_string_init (&str))
758 _dbus_assert_not_reached ("no memory");
759
760 if (!_dbus_string_append (&str, FIRST_LINE "\n" SECOND_LINE "\r\n" THIRD_LINE "\n" FOURTH_LINE))
761 _dbus_assert_not_reached ("no memory");
762
763 if (!_dbus_string_init (&line))
764 _dbus_assert_not_reached ("no memory");
765
766 if (!_dbus_string_pop_line (&str, &line))
767 _dbus_assert_not_reached ("failed to pop first line");
768
769 _dbus_assert (_dbus_string_equal_c_str (&line, FIRST_LINE));
770
771 if (!_dbus_string_pop_line (&str, &line))
772 _dbus_assert_not_reached ("failed to pop second line");
773
774 _dbus_assert (_dbus_string_equal_c_str (&line, SECOND_LINE));
775
776 if (!_dbus_string_pop_line (&str, &line))
777 _dbus_assert_not_reached ("failed to pop third line");
778
779 _dbus_assert (_dbus_string_equal_c_str (&line, THIRD_LINE));
780
781 if (!_dbus_string_pop_line (&str, &line))
782 _dbus_assert_not_reached ("failed to pop fourth line");
783
784 _dbus_assert (_dbus_string_equal_c_str (&line, FOURTH_LINE));
785
786 _dbus_string_free (&str);
787 _dbus_string_free (&line);
788 }
789
790 {
791 if (!_dbus_string_init (&str))
792 _dbus_assert_not_reached ("no memory");
793
794 for (i = 0; i < 10000; i++)
795 if (!_dbus_string_append (&str, "abcdefghijklmnopqrstuvwxyz"))
796 _dbus_assert_not_reached ("no memory");
797
798 if (!_dbus_string_set_length (&str, 10))
799 _dbus_assert_not_reached ("failed to set length");
800
801 /* actually compact */
802 if (!_dbus_string_compact (&str, 2048))
803 _dbus_assert_not_reached ("failed to compact after set_length");
804
805 /* peek inside to make sure it worked */
806 if (((DBusRealString *)&str)->allocated > 30)
807 _dbus_assert_not_reached ("compacting string didn't do anything");
808
809 if (!_dbus_string_equal_c_str (&str, "abcdefghij"))
810 _dbus_assert_not_reached ("unexpected content after compact");
811
812 /* compact nothing */
813 if (!_dbus_string_compact (&str, 2048))
814 _dbus_assert_not_reached ("failed to compact 2nd time");
815
816 if (!_dbus_string_equal_c_str (&str, "abcdefghij"))
817 _dbus_assert_not_reached ("unexpected content after 2nd compact");
818
819 /* and make sure it still works...*/
820 if (!_dbus_string_append (&str, "123456"))
821 _dbus_assert_not_reached ("failed to append after compact");
822
823 if (!_dbus_string_equal_c_str (&str, "abcdefghij123456"))
824 _dbus_assert_not_reached ("unexpected content after append");
825
826 /* after growing automatically, this should do nothing */
827 if (!_dbus_string_compact (&str, 20000))
828 _dbus_assert_not_reached ("failed to compact after grow");
829
830 /* but this one will do something */
831 if (!_dbus_string_compact (&str, 0))
832 _dbus_assert_not_reached ("failed to compact after grow");
833
834 if (!_dbus_string_equal_c_str (&str, "abcdefghij123456"))
835 _dbus_assert_not_reached ("unexpected content");
836
837 if (!_dbus_string_append (&str, "!@#$%"))
838 _dbus_assert_not_reached ("failed to append after compact");
839
840 if (!_dbus_string_equal_c_str (&str, "abcdefghij123456!@#$%"))
841 _dbus_assert_not_reached ("unexpected content");
842
843 _dbus_string_free (&str);
844 }
845
846 {
847 const char two_strings[] = "one\ttwo";
848
849 if (!_dbus_string_init (&str))
850 _dbus_assert_not_reached ("no memory");
851
852 if (!_dbus_string_init (&other))
853 _dbus_assert_not_reached ("no memory");
854
855 if (!_dbus_string_append (&str, two_strings))
856 _dbus_assert_not_reached ("no memory");
857
858 if (!_dbus_string_split_on_byte (&str, '\t', &other))
859 _dbus_assert_not_reached ("no memory or delimiter not found");
860
861 if (strcmp (_dbus_string_get_data (&str), "one") != 0)
862 _dbus_assert_not_reached ("left side after split on tab is wrong");
863
864 if (strcmp (_dbus_string_get_data (&other), "two") != 0)
865 _dbus_assert_not_reached ("right side after split on tab is wrong");
866
867 _dbus_string_free (&str);
868 _dbus_string_free (&other);
869 }
870
871 {
872 const char upper_string[] = "TOUPPERSTRING";
873 const char lower_string[] = "toupperstring";
874 const char lower2_string[] = "toupperSTRING";
875
876 if (!_dbus_string_init (&str))
877 _dbus_assert_not_reached ("no memory");
878
879 if (!_dbus_string_append (&str, upper_string))
880 _dbus_assert_not_reached ("no memory");
881
882 _dbus_string_tolower_ascii (&str, 0, _dbus_string_get_length(&str));
883
884 if (!_dbus_string_equal_c_str (&str, lower_string))
885 _dbus_assert_not_reached ("_dbus_string_tolower_ascii failed");
886
887 _dbus_string_free (&str);
888
889 if (!_dbus_string_init (&str))
890 _dbus_assert_not_reached ("no memory");
891
892 if (!_dbus_string_append (&str, upper_string))
893 _dbus_assert_not_reached ("no memory");
894
895 _dbus_string_tolower_ascii (&str, 0, 7);
896
897 if (!_dbus_string_equal_c_str (&str, lower2_string))
898 _dbus_assert_not_reached ("_dbus_string_tolower_ascii failed in partial conversion");
899
900 _dbus_string_free (&str);
901 }
902
903 {
904 const char lower_string[] = "toupperstring";
905 const char upper_string[] = "TOUPPERSTRING";
906 const char upper2_string[] = "TOUPPERstring";
907
908 if (!_dbus_string_init (&str))
909 _dbus_assert_not_reached ("no memory");
910
911 if (!_dbus_string_append (&str, lower_string))
912 _dbus_assert_not_reached ("no memory");
913
914 _dbus_string_toupper_ascii (&str, 0, _dbus_string_get_length(&str));
915
916 if (!_dbus_string_equal_c_str (&str, upper_string))
917 _dbus_assert_not_reached ("_dbus_string_toupper_ascii failed");
918
919 _dbus_string_free (&str);
920
921 if (!_dbus_string_init (&str))
922 _dbus_assert_not_reached ("no memory");
923
924 if (!_dbus_string_append (&str, lower_string))
925 _dbus_assert_not_reached ("no memory");
926
927 _dbus_string_toupper_ascii (&str, 0, 7);
928
929 if (!_dbus_string_equal_c_str (&str, upper2_string))
930 _dbus_assert_not_reached ("_dbus_string_toupper_ascii failed in partial conversion");
931
932 _dbus_string_free (&str);
933 }
934
935 return TRUE;
936 }
937
938 #endif /* DBUS_BUILD_TESTS */
939