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_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
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
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
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
265 _dbus_string_test (void)
266 {
267   DBusString str;
268   DBusString other;
269   int i, a, 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   /* Different tests are provided because different behaviours are
521    * implemented in _dbus_string_replace_len() in function of replacing and
522    * replaced lengths
523    */
524
525   if (!_dbus_string_init (&str))
526     _dbus_assert_not_reached ("failed to init string");
527   
528   if (!_dbus_string_append (&str, "Hello World"))
529     _dbus_assert_not_reached ("could not append to string");
530
531   i = _dbus_string_get_length (&str);
532   
533   if (!_dbus_string_init (&other))
534     _dbus_assert_not_reached ("could not init string");
535
536   if (!_dbus_string_append (&other, "Foo String"))
537     _dbus_assert_not_reached ("could not append to string");
538
539   a = _dbus_string_get_length (&other);
540
541   if (!_dbus_string_replace_len (&str, 0, 6,
542                                  &other, 4, 0))
543     _dbus_assert_not_reached ("could not replace 0 length");
544
545   _dbus_assert (_dbus_string_get_length (&str) == i);
546   _dbus_assert (_dbus_string_get_length (&other) == a + 6);
547   _dbus_assert (_dbus_string_equal_c_str (&other,
548                                           "Foo Hello String"));
549
550   if (!_dbus_string_replace_len (&str, 5, 6,
551                                  &other,
552                                  _dbus_string_get_length (&other),
553                                  0))
554     _dbus_assert_not_reached ("could not replace at the end");
555
556   _dbus_assert (_dbus_string_get_length (&str) == i);
557   _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6);
558   _dbus_assert (_dbus_string_equal_c_str (&other,
559                                           "Foo Hello String World"));
560
561   if (!_dbus_string_replace_len (&str, 0, 5,
562                                  &other,
563                                  _dbus_string_get_length (&other) - 5,
564                                  5))
565     _dbus_assert_not_reached ("could not replace same length");
566
567   _dbus_assert (_dbus_string_get_length (&str) == i);
568   _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6);
569   _dbus_assert (_dbus_string_equal_c_str (&other,
570                                           "Foo Hello String Hello"));
571
572   if (!_dbus_string_replace_len (&str, 6, 5,
573                                  &other, 4, 12))
574     _dbus_assert_not_reached ("could not replace with shorter string");
575
576   _dbus_assert (_dbus_string_get_length (&str) == i);
577   _dbus_assert (_dbus_string_get_length (&other) == a + 5);
578   _dbus_assert (_dbus_string_equal_c_str (&other,
579                                           "Foo World Hello"));
580
581   if (!_dbus_string_replace_len (&str, 0, 1,
582                                  &other, 0, 3))
583     _dbus_assert_not_reached ("could not replace at the beginning");
584
585   _dbus_assert (_dbus_string_get_length (&str) == i);
586   _dbus_assert (_dbus_string_get_length (&other) == a + 3);
587   _dbus_assert (_dbus_string_equal_c_str (&other,
588                                           "H World Hello"));
589
590   if (!_dbus_string_replace_len (&str, 6, 5,
591                                  &other,
592                                  _dbus_string_get_length (&other) - 5,
593                                  5))
594     _dbus_assert_not_reached ("could not replace same length");
595
596   _dbus_assert (_dbus_string_get_length (&str) == i);
597   _dbus_assert (_dbus_string_get_length (&other) == a + 3);
598   _dbus_assert (_dbus_string_equal_c_str (&other,
599                                           "H World World"));
600
601   _dbus_string_free (&str);
602   _dbus_string_free (&other);
603
604   /* Check append/get unichar */
605   
606   if (!_dbus_string_init (&str))
607     _dbus_assert_not_reached ("failed to init string");
608
609   ch = 0;
610   if (!_dbus_string_append_unichar (&str, 0xfffc))
611     _dbus_assert_not_reached ("failed to append unichar");
612
613   _dbus_string_get_unichar (&str, 0, &ch, &i);
614
615   _dbus_assert (ch == 0xfffc);
616   _dbus_assert (i == _dbus_string_get_length (&str));
617
618   _dbus_string_free (&str);
619
620   /* Check insert/set/get byte */
621   
622   if (!_dbus_string_init (&str))
623     _dbus_assert_not_reached ("failed to init string");
624
625   if (!_dbus_string_append (&str, "Hello"))
626     _dbus_assert_not_reached ("failed to append Hello");
627
628   _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H');
629   _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e');
630   _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l');
631   _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l');
632   _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o');
633
634   _dbus_string_set_byte (&str, 1, 'q');
635   _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');
636
637   if (!_dbus_string_insert_bytes (&str, 0, 1, 255))
638     _dbus_assert_not_reached ("can't insert byte");
639
640   if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z'))
641     _dbus_assert_not_reached ("can't insert byte");
642
643   if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W'))
644     _dbus_assert_not_reached ("can't insert byte");
645   
646   _dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
647   _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
648   _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
649   _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z');
650   _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z');
651   _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z');
652   _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q');
653   _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l');
654   _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l');
655   _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o');
656   _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W');
657
658   _dbus_string_free (&str);
659   
660   /* Check append/parse int/double */
661   
662   if (!_dbus_string_init (&str))
663     _dbus_assert_not_reached ("failed to init string");
664
665   if (!_dbus_string_append_int (&str, 27))
666     _dbus_assert_not_reached ("failed to append int");
667
668   i = _dbus_string_get_length (&str);
669
670   if (!_dbus_string_parse_int (&str, 0, &v, &end))
671     _dbus_assert_not_reached ("failed to parse int");
672
673   _dbus_assert (v == 27);
674   _dbus_assert (end == i);
675
676   _dbus_string_free (&str);
677   
678   if (!_dbus_string_init (&str))
679     _dbus_assert_not_reached ("failed to init string");
680   
681   if (!_dbus_string_append_double (&str, 50.3))
682     _dbus_assert_not_reached ("failed to append float");
683
684   i = _dbus_string_get_length (&str);
685
686   if (!_dbus_string_parse_double (&str, 0, &d, &end))
687     _dbus_assert_not_reached ("failed to parse float");
688
689   _dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6));
690   _dbus_assert (end == i);
691
692   _dbus_string_free (&str);
693
694   /* Test find */
695   if (!_dbus_string_init (&str))
696     _dbus_assert_not_reached ("failed to init string");
697
698   if (!_dbus_string_append (&str, "Hello"))
699     _dbus_assert_not_reached ("couldn't append to string");
700   
701   if (!_dbus_string_find (&str, 0, "He", &i))
702     _dbus_assert_not_reached ("didn't find 'He'");
703   _dbus_assert (i == 0);
704
705   if (!_dbus_string_find (&str, 0, "Hello", &i))
706     _dbus_assert_not_reached ("didn't find 'Hello'");
707   _dbus_assert (i == 0);
708   
709   if (!_dbus_string_find (&str, 0, "ello", &i))
710     _dbus_assert_not_reached ("didn't find 'ello'");
711   _dbus_assert (i == 1);
712
713   if (!_dbus_string_find (&str, 0, "lo", &i))
714     _dbus_assert_not_reached ("didn't find 'lo'");
715   _dbus_assert (i == 3);
716
717   if (!_dbus_string_find (&str, 2, "lo", &i))
718     _dbus_assert_not_reached ("didn't find 'lo'");
719   _dbus_assert (i == 3);
720
721   if (_dbus_string_find (&str, 4, "lo", &i))
722     _dbus_assert_not_reached ("did find 'lo'");
723   
724   if (!_dbus_string_find (&str, 0, "l", &i))
725     _dbus_assert_not_reached ("didn't find 'l'");
726   _dbus_assert (i == 2);
727
728   if (!_dbus_string_find (&str, 0, "H", &i))
729     _dbus_assert_not_reached ("didn't find 'H'");
730   _dbus_assert (i == 0);
731
732   if (!_dbus_string_find (&str, 0, "", &i))
733     _dbus_assert_not_reached ("didn't find ''");
734   _dbus_assert (i == 0);
735   
736   if (_dbus_string_find (&str, 0, "Hello!", NULL))
737     _dbus_assert_not_reached ("Did find 'Hello!'");
738
739   if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
740     _dbus_assert_not_reached ("Did find 'Oh, Hello'");
741   
742   if (_dbus_string_find (&str, 0, "ill", NULL))
743     _dbus_assert_not_reached ("Did find 'ill'");
744
745   if (_dbus_string_find (&str, 0, "q", NULL))
746     _dbus_assert_not_reached ("Did find 'q'");
747
748   if (!_dbus_string_find_to (&str, 0, 2, "He", NULL))
749     _dbus_assert_not_reached ("Didn't find 'He'");
750
751   if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL))
752     _dbus_assert_not_reached ("Did find 'Hello'");
753
754   if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i))
755     _dbus_assert_not_reached ("Did not find 'H'");
756   _dbus_assert (i == 0);
757
758   if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i))
759     _dbus_assert_not_reached ("Did not find 'o'");
760   _dbus_assert (i == _dbus_string_get_length (&str) - 1);
761
762   if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i))
763     _dbus_assert_not_reached ("Did find 'o'");
764   _dbus_assert (i == -1);
765
766   if (_dbus_string_find_byte_backward (&str, 1, 'e', &i))
767     _dbus_assert_not_reached ("Did find 'e'");
768   _dbus_assert (i == -1);
769
770   if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i))
771     _dbus_assert_not_reached ("Didn't find 'e'");
772   _dbus_assert (i == 1);
773   
774   _dbus_string_free (&str);
775
776   /* Hex encoding */
777   _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string");
778   if (!_dbus_string_init (&other))
779     _dbus_assert_not_reached ("could not init string");
780
781   if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0))
782     _dbus_assert_not_reached ("deccoded bogus hex string with no error");
783
784   _dbus_assert (end == 8);
785
786   _dbus_string_free (&other);
787
788   test_roundtrips (test_hex_roundtrip);
789   
790   _dbus_string_free (&str);
791
792   {                                                                                           
793     int found, found_len;  
794
795     _dbus_string_init_const (&str, "012\r\n567\n90");
796     
797     if (!_dbus_string_find_eol (&str, 0, &found, &found_len) || found != 3 || found_len != 2)
798       _dbus_assert_not_reached ("Did not find '\\r\\n'");                                       
799     if (found != 3 || found_len != 2)                                                           
800       _dbus_assert_not_reached ("invalid return values");                                       
801     
802     if (!_dbus_string_find_eol (&str, 5, &found, &found_len))                                    
803       _dbus_assert_not_reached ("Did not find '\\n'");                                          
804     if (found != 8 || found_len != 1)                                                           
805       _dbus_assert_not_reached ("invalid return values");                                       
806     
807     if (_dbus_string_find_eol (&str, 9, &found, &found_len))                                     
808       _dbus_assert_not_reached ("Found not expected '\\n'");                                    
809     else if (found != 11 || found_len != 0)                                                     
810       _dbus_assert_not_reached ("invalid return values '\\n'");                                 
811
812     found = -1;
813     found_len = -1;
814     _dbus_string_init_const (&str, "");
815     if (_dbus_string_find_eol (&str, 0, &found, &found_len))
816       _dbus_assert_not_reached ("found an eol in an empty string");
817     _dbus_assert (found == 0);
818     _dbus_assert (found_len == 0);
819     
820     found = -1;
821     found_len = -1;
822     _dbus_string_init_const (&str, "foobar");
823     if (_dbus_string_find_eol (&str, 0, &found, &found_len))
824       _dbus_assert_not_reached ("found eol in string that lacks one");
825     _dbus_assert (found == 6);
826     _dbus_assert (found_len == 0);
827
828     found = -1;
829     found_len = -1;
830     _dbus_string_init_const (&str, "foobar\n");
831     if (!_dbus_string_find_eol (&str, 0, &found, &found_len))
832       _dbus_assert_not_reached ("did not find eol in string that has one at end");
833     _dbus_assert (found == 6);
834     _dbus_assert (found_len == 1);
835   }
836
837   {
838     DBusString line;
839
840 #define FIRST_LINE "this is a line"
841 #define SECOND_LINE "this is a second line"
842     /* third line is empty */
843 #define THIRD_LINE ""
844 #define FOURTH_LINE "this is a fourth line"
845     
846     if (!_dbus_string_init (&str))
847       _dbus_assert_not_reached ("no memory");
848
849     if (!_dbus_string_append (&str, FIRST_LINE "\n" SECOND_LINE "\r\n" THIRD_LINE "\n" FOURTH_LINE))
850       _dbus_assert_not_reached ("no memory");
851     
852     if (!_dbus_string_init (&line))
853       _dbus_assert_not_reached ("no memory");
854     
855     if (!_dbus_string_pop_line (&str, &line))
856       _dbus_assert_not_reached ("failed to pop first line");
857
858     _dbus_assert (_dbus_string_equal_c_str (&line, FIRST_LINE));
859     
860     if (!_dbus_string_pop_line (&str, &line))
861       _dbus_assert_not_reached ("failed to pop second line");
862
863     _dbus_assert (_dbus_string_equal_c_str (&line, SECOND_LINE));
864     
865     if (!_dbus_string_pop_line (&str, &line))
866       _dbus_assert_not_reached ("failed to pop third line");
867
868     _dbus_assert (_dbus_string_equal_c_str (&line, THIRD_LINE));
869     
870     if (!_dbus_string_pop_line (&str, &line))
871       _dbus_assert_not_reached ("failed to pop fourth line");
872
873     _dbus_assert (_dbus_string_equal_c_str (&line, FOURTH_LINE));
874     
875     _dbus_string_free (&str);
876     _dbus_string_free (&line);
877   }
878
879   {
880     if (!_dbus_string_init (&str))
881       _dbus_assert_not_reached ("no memory");
882
883     for (i = 0; i < 10000; i++)
884       if (!_dbus_string_append (&str, "abcdefghijklmnopqrstuvwxyz"))
885         _dbus_assert_not_reached ("no memory");
886
887     if (!_dbus_string_set_length (&str, 10))
888       _dbus_assert_not_reached ("failed to set length");
889
890     /* actually compact */
891     if (!_dbus_string_compact (&str, 2048))
892       _dbus_assert_not_reached ("failed to compact after set_length");
893
894     /* peek inside to make sure it worked */
895     if (((DBusRealString *)&str)->allocated > 30)
896       _dbus_assert_not_reached ("compacting string didn't do anything");
897
898     if (!_dbus_string_equal_c_str (&str, "abcdefghij"))
899       _dbus_assert_not_reached ("unexpected content after compact");
900
901     /* compact nothing */
902     if (!_dbus_string_compact (&str, 2048))
903       _dbus_assert_not_reached ("failed to compact 2nd time");
904
905     if (!_dbus_string_equal_c_str (&str, "abcdefghij"))
906       _dbus_assert_not_reached ("unexpected content after 2nd compact");
907
908     /* and make sure it still works...*/
909     if (!_dbus_string_append (&str, "123456"))
910       _dbus_assert_not_reached ("failed to append after compact");
911
912     if (!_dbus_string_equal_c_str (&str, "abcdefghij123456"))
913       _dbus_assert_not_reached ("unexpected content after append");
914
915     /* after growing automatically, this should do nothing */
916     if (!_dbus_string_compact (&str, 20000))
917       _dbus_assert_not_reached ("failed to compact after grow");
918
919     /* but this one will do something */
920     if (!_dbus_string_compact (&str, 0))
921       _dbus_assert_not_reached ("failed to compact after grow");
922
923     if (!_dbus_string_equal_c_str (&str, "abcdefghij123456"))
924       _dbus_assert_not_reached ("unexpected content");
925
926     if (!_dbus_string_append (&str, "!@#$%"))
927       _dbus_assert_not_reached ("failed to append after compact");
928
929     if (!_dbus_string_equal_c_str (&str, "abcdefghij123456!@#$%"))
930       _dbus_assert_not_reached ("unexpected content");
931
932     _dbus_string_free (&str);
933   }
934
935   {
936     const char two_strings[] = "one\ttwo";
937
938     if (!_dbus_string_init (&str))
939       _dbus_assert_not_reached ("no memory");
940
941     if (!_dbus_string_init (&other))
942       _dbus_assert_not_reached ("no memory");
943
944     if (!_dbus_string_append (&str, two_strings))
945       _dbus_assert_not_reached ("no memory");
946
947     if (!_dbus_string_split_on_byte (&str, '\t', &other))
948       _dbus_assert_not_reached ("no memory or delimiter not found");
949
950     if (strcmp (_dbus_string_get_data (&str), "one") != 0)
951       _dbus_assert_not_reached ("left side after split on tab is wrong");
952
953     if (strcmp (_dbus_string_get_data (&other), "two") != 0)
954       _dbus_assert_not_reached ("right side after split on tab is wrong");
955
956     _dbus_string_free (&str);
957     _dbus_string_free (&other);
958   }
959
960   {
961     const char upper_string[] = "TOUPPERSTRING";
962     const char lower_string[] = "toupperstring";
963     const char lower2_string[] = "toupperSTRING";
964
965     if (!_dbus_string_init (&str))
966       _dbus_assert_not_reached ("no memory");
967
968     if (!_dbus_string_append (&str, upper_string))
969       _dbus_assert_not_reached ("no memory");
970
971     _dbus_string_tolower_ascii (&str, 0, _dbus_string_get_length(&str));
972
973     if (!_dbus_string_equal_c_str (&str, lower_string))
974       _dbus_assert_not_reached ("_dbus_string_tolower_ascii failed");
975
976     _dbus_string_free (&str);
977
978     if (!_dbus_string_init (&str))
979       _dbus_assert_not_reached ("no memory");
980
981     if (!_dbus_string_append (&str, upper_string))
982       _dbus_assert_not_reached ("no memory");
983
984     _dbus_string_tolower_ascii (&str, 0, 7);
985
986     if (!_dbus_string_equal_c_str (&str, lower2_string))
987       _dbus_assert_not_reached ("_dbus_string_tolower_ascii failed in partial conversion");
988
989     _dbus_string_free (&str);
990   }
991
992   {
993     const char lower_string[] = "toupperstring";
994     const char upper_string[] = "TOUPPERSTRING";
995     const char upper2_string[] = "TOUPPERstring";
996
997     if (!_dbus_string_init (&str))
998       _dbus_assert_not_reached ("no memory");
999
1000     if (!_dbus_string_append (&str, lower_string))
1001       _dbus_assert_not_reached ("no memory");
1002
1003     _dbus_string_toupper_ascii (&str, 0, _dbus_string_get_length(&str));
1004
1005     if (!_dbus_string_equal_c_str (&str, upper_string))
1006       _dbus_assert_not_reached ("_dbus_string_toupper_ascii failed");
1007
1008     _dbus_string_free (&str);
1009
1010     if (!_dbus_string_init (&str))
1011       _dbus_assert_not_reached ("no memory");
1012
1013     if (!_dbus_string_append (&str, lower_string))
1014       _dbus_assert_not_reached ("no memory");
1015
1016     _dbus_string_toupper_ascii (&str, 0, 7);
1017
1018     if (!_dbus_string_equal_c_str (&str, upper2_string))
1019       _dbus_assert_not_reached ("_dbus_string_toupper_ascii failed in partial conversion");
1020
1021     _dbus_string_free (&str);
1022   }
1023
1024   return TRUE;
1025 }
1026
1027 #endif /* DBUS_BUILD_TESTS */