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