D-Bus 1.4.0

dbus-string-util.c

00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
00002 /* dbus-string-util.c Would be in dbus-string.c, but not used in libdbus
00003  * 
00004  * Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
00005  * Copyright (C) 2006 Ralf Habacker <ralf.habacker@freenet.de>
00006  *
00007  * Licensed under the Academic Free License version 2.1
00008  * 
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  * 
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  */
00024 
00025 #include <config.h>
00026 #include "dbus-internals.h"
00027 #include "dbus-string.h"
00028 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
00029 #include "dbus-string-private.h"
00030 
00045 dbus_bool_t
00046 _dbus_string_ends_with_c_str (const DBusString *a,
00047                               const char       *c_str)
00048 {
00049   const unsigned char *ap;
00050   const unsigned char *bp;
00051   const unsigned char *a_end;
00052   unsigned long c_str_len;
00053   const DBusRealString *real_a = (const DBusRealString*) a;
00054   DBUS_GENERIC_STRING_PREAMBLE (real_a);
00055   _dbus_assert (c_str != NULL);
00056   
00057   c_str_len = strlen (c_str);
00058   if (((unsigned long)real_a->len) < c_str_len)
00059     return FALSE;
00060   
00061   ap = real_a->str + (real_a->len - c_str_len);
00062   bp = (const unsigned char*) c_str;
00063   a_end = real_a->str + real_a->len;
00064   while (ap != a_end)
00065     {
00066       if (*ap != *bp)
00067         return FALSE;
00068       
00069       ++ap;
00070       ++bp;
00071     }
00072 
00073   _dbus_assert (*ap == '\0');
00074   _dbus_assert (*bp == '\0');
00075   
00076   return TRUE;
00077 }
00078 
00089 dbus_bool_t
00090 _dbus_string_find_byte_backward (const DBusString  *str,
00091                                  int                start,
00092                                  unsigned char      byte,
00093                                  int               *found)
00094 {
00095   int i;
00096   DBUS_CONST_STRING_PREAMBLE (str);
00097   _dbus_assert (start <= real->len);
00098   _dbus_assert (start >= 0);
00099   _dbus_assert (found != NULL);
00100 
00101   i = start - 1;
00102   while (i >= 0)
00103     {
00104       if (real->str[i] == byte)
00105         break;
00106       
00107       --i;
00108     }
00109 
00110   if (found)
00111     *found = i;
00112 
00113   return i >= 0;
00114 }
00115 
00118 #ifdef DBUS_BUILD_TESTS
00119 #include "dbus-test.h"
00120 #include <stdio.h>
00121 
00122 static void
00123 test_max_len (DBusString *str,
00124               int         max_len)
00125 {
00126   if (max_len > 0)
00127     {
00128       if (!_dbus_string_set_length (str, max_len - 1))
00129         _dbus_assert_not_reached ("setting len to one less than max should have worked");
00130     }
00131 
00132   if (!_dbus_string_set_length (str, max_len))
00133     _dbus_assert_not_reached ("setting len to max len should have worked");
00134 
00135   if (_dbus_string_set_length (str, max_len + 1))
00136     _dbus_assert_not_reached ("setting len to one more than max len should not have worked");
00137 
00138   if (!_dbus_string_set_length (str, 0))
00139     _dbus_assert_not_reached ("setting len to zero should have worked");
00140 }
00141 
00142 static void
00143 test_hex_roundtrip (const unsigned char *data,
00144                     int                  len)
00145 {
00146   DBusString orig;
00147   DBusString encoded;
00148   DBusString decoded;
00149   int end;
00150 
00151   if (len < 0)
00152     len = strlen (data);
00153   
00154   if (!_dbus_string_init (&orig))
00155     _dbus_assert_not_reached ("could not init string");
00156 
00157   if (!_dbus_string_init (&encoded))
00158     _dbus_assert_not_reached ("could not init string");
00159   
00160   if (!_dbus_string_init (&decoded))
00161     _dbus_assert_not_reached ("could not init string");
00162 
00163   if (!_dbus_string_append_len (&orig, data, len))
00164     _dbus_assert_not_reached ("couldn't append orig data");
00165 
00166   if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))
00167     _dbus_assert_not_reached ("could not encode");
00168 
00169   if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0))
00170     _dbus_assert_not_reached ("could not decode");
00171     
00172   _dbus_assert (_dbus_string_get_length (&encoded) == end);
00173 
00174   if (!_dbus_string_equal (&orig, &decoded))
00175     {
00176       const char *s;
00177       
00178       printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
00179               _dbus_string_get_length (&orig),
00180               _dbus_string_get_length (&encoded),
00181               _dbus_string_get_length (&decoded));
00182       printf ("Original: %s\n", data);
00183       s = _dbus_string_get_const_data (&decoded);
00184       printf ("Decoded: %s\n", s);
00185       _dbus_assert_not_reached ("original string not the same as string decoded from hex");
00186     }
00187   
00188   _dbus_string_free (&orig);
00189   _dbus_string_free (&encoded);
00190   _dbus_string_free (&decoded);  
00191 }
00192 
00193 typedef void (* TestRoundtripFunc) (const unsigned char *data,
00194                                     int                  len);
00195 static void
00196 test_roundtrips (TestRoundtripFunc func)
00197 {
00198   (* func) ("Hello this is a string\n", -1);
00199   (* func) ("Hello this is a string\n1", -1);
00200   (* func) ("Hello this is a string\n12", -1);
00201   (* func) ("Hello this is a string\n123", -1);
00202   (* func) ("Hello this is a string\n1234", -1);
00203   (* func) ("Hello this is a string\n12345", -1);
00204   (* func) ("", 0);
00205   (* func) ("1", 1);
00206   (* func) ("12", 2);
00207   (* func) ("123", 3);
00208   (* func) ("1234", 4);
00209   (* func) ("12345", 5);
00210   (* func) ("", 1);
00211   (* func) ("1", 2);
00212   (* func) ("12", 3);
00213   (* func) ("123", 4);
00214   (* func) ("1234", 5);
00215   (* func) ("12345", 6);
00216   {
00217     unsigned char buf[512];
00218     int i;
00219     
00220     i = 0;
00221     while (i < _DBUS_N_ELEMENTS (buf))
00222       {
00223         buf[i] = i;
00224         ++i;
00225       }
00226     i = 0;
00227     while (i < _DBUS_N_ELEMENTS (buf))
00228       {
00229         (* func) (buf, i);
00230         ++i;
00231       }
00232   }
00233 }
00234 
00235 #ifdef DBUS_BUILD_TESTS
00236 /* The max length thing is sort of a historical artifact
00237  * from a feature that turned out to be dumb; perhaps
00238  * we should purge it entirely. The problem with
00239  * the feature is that it looks like memory allocation
00240  * failure, but is not a transient or resolvable failure.
00241  */
00242 static void
00243 set_max_length (DBusString *str,
00244                 int         max_length)
00245 {
00246   DBusRealString *real;
00247   
00248   real = (DBusRealString*) str;
00249 
00250   real->max_length = max_length;
00251 }
00252 #endif /* DBUS_BUILD_TESTS */
00253 
00264 dbus_bool_t
00265 _dbus_string_test (void)
00266 {
00267   DBusString str;
00268   DBusString other;
00269   int i, end;
00270   long v;
00271   double d;
00272   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 };
00273   char *s;
00274   dbus_unichar_t ch;
00275   
00276   i = 0;
00277   while (i < _DBUS_N_ELEMENTS (lens))
00278     {
00279       if (!_dbus_string_init (&str))
00280         _dbus_assert_not_reached ("failed to init string");
00281 
00282       set_max_length (&str, lens[i]);
00283       
00284       test_max_len (&str, lens[i]);
00285       _dbus_string_free (&str);
00286 
00287       ++i;
00288     }
00289 
00290   /* Test shortening and setting length */
00291   i = 0;
00292   while (i < _DBUS_N_ELEMENTS (lens))
00293     {
00294       int j;
00295       
00296       if (!_dbus_string_init (&str))
00297         _dbus_assert_not_reached ("failed to init string");
00298 
00299       set_max_length (&str, lens[i]);
00300       
00301       if (!_dbus_string_set_length (&str, lens[i]))
00302         _dbus_assert_not_reached ("failed to set string length");
00303 
00304       j = lens[i];
00305       while (j > 0)
00306         {
00307           _dbus_assert (_dbus_string_get_length (&str) == j);
00308           if (j > 0)
00309             {
00310               _dbus_string_shorten (&str, 1);
00311               _dbus_assert (_dbus_string_get_length (&str) == (j - 1));
00312             }
00313           --j;
00314         }
00315       
00316       _dbus_string_free (&str);
00317 
00318       ++i;
00319     }
00320 
00321   /* Test equality */
00322   if (!_dbus_string_init (&str))
00323     _dbus_assert_not_reached ("oom");
00324 
00325   if (!_dbus_string_append (&str, "Hello World"))
00326     _dbus_assert_not_reached ("oom");
00327 
00328   _dbus_string_init_const (&other, "H");
00329   _dbus_assert (_dbus_string_equal_substring (&str, 0, 1, &other, 0));
00330   _dbus_assert (_dbus_string_equal_substring (&str, 1, 0, &other, 1));
00331   _dbus_string_init_const (&other, "Hello");
00332   _dbus_assert (_dbus_string_equal_substring (&str, 0, 5, &other, 0));
00333   _dbus_assert (_dbus_string_equal_substring (&str, 1, 4, &other, 1));
00334   _dbus_assert (_dbus_string_equal_substring (&str, 2, 3, &other, 2));
00335   _dbus_assert (_dbus_string_equal_substring (&str, 3, 2, &other, 3));
00336   _dbus_assert (_dbus_string_equal_substring (&str, 4, 1, &other, 4));
00337   _dbus_assert (_dbus_string_equal_substring (&str, 5, 0, &other, 5));
00338 
00339   _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 0));
00340   _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 1));
00341   _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 2));
00342   _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 3));
00343   _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 4));
00344   _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 5));
00345 
00346   
00347   _dbus_string_init_const (&other, "World");
00348   _dbus_assert (_dbus_string_equal_substring (&str, 6,  5, &other, 0));
00349   _dbus_assert (_dbus_string_equal_substring (&str, 7,  4, &other, 1));
00350   _dbus_assert (_dbus_string_equal_substring (&str, 8,  3, &other, 2));
00351   _dbus_assert (_dbus_string_equal_substring (&str, 9,  2, &other, 3));
00352   _dbus_assert (_dbus_string_equal_substring (&str, 10, 1, &other, 4));
00353   _dbus_assert (_dbus_string_equal_substring (&str, 11, 0, &other, 5));
00354 
00355   _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 6));
00356   _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 7));
00357   _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 8));
00358   _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 9));
00359   _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 10));
00360   _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 11));
00361   
00362   _dbus_string_free (&str);
00363   
00364   /* Test appending data */
00365   if (!_dbus_string_init (&str))
00366     _dbus_assert_not_reached ("failed to init string");
00367 
00368   i = 0;
00369   while (i < 10)
00370     {
00371       if (!_dbus_string_append (&str, "a"))
00372         _dbus_assert_not_reached ("failed to append string to string\n");
00373 
00374       _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1);
00375 
00376       if (!_dbus_string_append_byte (&str, 'b'))
00377         _dbus_assert_not_reached ("failed to append byte to string\n");
00378 
00379       _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2);
00380                     
00381       ++i;
00382     }
00383 
00384   _dbus_string_free (&str);
00385 
00386   /* Check steal_data */
00387   
00388   if (!_dbus_string_init (&str))
00389     _dbus_assert_not_reached ("failed to init string");
00390 
00391   if (!_dbus_string_append (&str, "Hello World"))
00392     _dbus_assert_not_reached ("could not append to string");
00393 
00394   i = _dbus_string_get_length (&str);
00395   
00396   if (!_dbus_string_steal_data (&str, &s))
00397     _dbus_assert_not_reached ("failed to steal data");
00398 
00399   _dbus_assert (_dbus_string_get_length (&str) == 0);
00400   _dbus_assert (((int)strlen (s)) == i);
00401 
00402   dbus_free (s);
00403 
00404   /* Check move */
00405   
00406   if (!_dbus_string_append (&str, "Hello World"))
00407     _dbus_assert_not_reached ("could not append to string");
00408 
00409   i = _dbus_string_get_length (&str);
00410 
00411   if (!_dbus_string_init (&other))
00412     _dbus_assert_not_reached ("could not init string");
00413   
00414   if (!_dbus_string_move (&str, 0, &other, 0))
00415     _dbus_assert_not_reached ("could not move");
00416 
00417   _dbus_assert (_dbus_string_get_length (&str) == 0);
00418   _dbus_assert (_dbus_string_get_length (&other) == i);
00419 
00420   if (!_dbus_string_append (&str, "Hello World"))
00421     _dbus_assert_not_reached ("could not append to string");
00422   
00423   if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other)))
00424     _dbus_assert_not_reached ("could not move");
00425 
00426   _dbus_assert (_dbus_string_get_length (&str) == 0);
00427   _dbus_assert (_dbus_string_get_length (&other) == i * 2);
00428 
00429     if (!_dbus_string_append (&str, "Hello World"))
00430     _dbus_assert_not_reached ("could not append to string");
00431   
00432   if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2))
00433     _dbus_assert_not_reached ("could not move");
00434 
00435   _dbus_assert (_dbus_string_get_length (&str) == 0);
00436   _dbus_assert (_dbus_string_get_length (&other) == i * 3);
00437   
00438   _dbus_string_free (&other);
00439 
00440   /* Check copy */
00441   
00442   if (!_dbus_string_append (&str, "Hello World"))
00443     _dbus_assert_not_reached ("could not append to string");
00444 
00445   i = _dbus_string_get_length (&str);
00446   
00447   if (!_dbus_string_init (&other))
00448     _dbus_assert_not_reached ("could not init string");
00449   
00450   if (!_dbus_string_copy (&str, 0, &other, 0))
00451     _dbus_assert_not_reached ("could not copy");
00452 
00453   _dbus_assert (_dbus_string_get_length (&str) == i);
00454   _dbus_assert (_dbus_string_get_length (&other) == i);
00455 
00456   if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other)))
00457     _dbus_assert_not_reached ("could not copy");
00458 
00459   _dbus_assert (_dbus_string_get_length (&str) == i);
00460   _dbus_assert (_dbus_string_get_length (&other) == i * 2);
00461   _dbus_assert (_dbus_string_equal_c_str (&other,
00462                                           "Hello WorldHello World"));
00463 
00464   if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2))
00465     _dbus_assert_not_reached ("could not copy");
00466 
00467   _dbus_assert (_dbus_string_get_length (&str) == i);
00468   _dbus_assert (_dbus_string_get_length (&other) == i * 3);
00469   _dbus_assert (_dbus_string_equal_c_str (&other,
00470                                           "Hello WorldHello WorldHello World"));
00471   
00472   _dbus_string_free (&str);
00473   _dbus_string_free (&other);
00474 
00475   /* Check replace */
00476 
00477   if (!_dbus_string_init (&str))
00478     _dbus_assert_not_reached ("failed to init string");
00479   
00480   if (!_dbus_string_append (&str, "Hello World"))
00481     _dbus_assert_not_reached ("could not append to string");
00482 
00483   i = _dbus_string_get_length (&str);
00484   
00485   if (!_dbus_string_init (&other))
00486     _dbus_assert_not_reached ("could not init string");
00487   
00488   if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
00489                                  &other, 0, _dbus_string_get_length (&other)))
00490     _dbus_assert_not_reached ("could not replace");
00491 
00492   _dbus_assert (_dbus_string_get_length (&str) == i);
00493   _dbus_assert (_dbus_string_get_length (&other) == i);
00494   _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World"));
00495   
00496   if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
00497                                  &other, 5, 1))
00498     _dbus_assert_not_reached ("could not replace center space");
00499 
00500   _dbus_assert (_dbus_string_get_length (&str) == i);
00501   _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
00502   _dbus_assert (_dbus_string_equal_c_str (&other,
00503                                           "HelloHello WorldWorld"));
00504 
00505   
00506   if (!_dbus_string_replace_len (&str, 1, 1,
00507                                  &other,
00508                                  _dbus_string_get_length (&other) - 1,
00509                                  1))
00510     _dbus_assert_not_reached ("could not replace end character");
00511   
00512   _dbus_assert (_dbus_string_get_length (&str) == i);
00513   _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
00514   _dbus_assert (_dbus_string_equal_c_str (&other,
00515                                           "HelloHello WorldWorle"));
00516   
00517   _dbus_string_free (&str);
00518   _dbus_string_free (&other);
00519   
00520   /* Check append/get unichar */
00521   
00522   if (!_dbus_string_init (&str))
00523     _dbus_assert_not_reached ("failed to init string");
00524 
00525   ch = 0;
00526   if (!_dbus_string_append_unichar (&str, 0xfffc))
00527     _dbus_assert_not_reached ("failed to append unichar");
00528 
00529   _dbus_string_get_unichar (&str, 0, &ch, &i);
00530 
00531   _dbus_assert (ch == 0xfffc);
00532   _dbus_assert (i == _dbus_string_get_length (&str));
00533 
00534   _dbus_string_free (&str);
00535 
00536   /* Check insert/set/get byte */
00537   
00538   if (!_dbus_string_init (&str))
00539     _dbus_assert_not_reached ("failed to init string");
00540 
00541   if (!_dbus_string_append (&str, "Hello"))
00542     _dbus_assert_not_reached ("failed to append Hello");
00543 
00544   _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H');
00545   _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e');
00546   _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l');
00547   _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l');
00548   _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o');
00549 
00550   _dbus_string_set_byte (&str, 1, 'q');
00551   _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');
00552 
00553   if (!_dbus_string_insert_bytes (&str, 0, 1, 255))
00554     _dbus_assert_not_reached ("can't insert byte");
00555 
00556   if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z'))
00557     _dbus_assert_not_reached ("can't insert byte");
00558 
00559   if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W'))
00560     _dbus_assert_not_reached ("can't insert byte");
00561   
00562   _dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
00563   _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
00564   _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
00565   _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z');
00566   _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z');
00567   _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z');
00568   _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q');
00569   _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l');
00570   _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l');
00571   _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o');
00572   _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W');
00573 
00574   _dbus_string_free (&str);
00575   
00576   /* Check append/parse int/double */
00577   
00578   if (!_dbus_string_init (&str))
00579     _dbus_assert_not_reached ("failed to init string");
00580 
00581   if (!_dbus_string_append_int (&str, 27))
00582     _dbus_assert_not_reached ("failed to append int");
00583 
00584   i = _dbus_string_get_length (&str);
00585 
00586   if (!_dbus_string_parse_int (&str, 0, &v, &end))
00587     _dbus_assert_not_reached ("failed to parse int");
00588 
00589   _dbus_assert (v == 27);
00590   _dbus_assert (end == i);
00591 
00592   _dbus_string_free (&str);
00593   
00594   if (!_dbus_string_init (&str))
00595     _dbus_assert_not_reached ("failed to init string");
00596   
00597   if (!_dbus_string_append_double (&str, 50.3))
00598     _dbus_assert_not_reached ("failed to append float");
00599 
00600   i = _dbus_string_get_length (&str);
00601 
00602   if (!_dbus_string_parse_double (&str, 0, &d, &end))
00603     _dbus_assert_not_reached ("failed to parse float");
00604 
00605   _dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6));
00606   _dbus_assert (end == i);
00607 
00608   _dbus_string_free (&str);
00609 
00610   /* Test find */
00611   if (!_dbus_string_init (&str))
00612     _dbus_assert_not_reached ("failed to init string");
00613 
00614   if (!_dbus_string_append (&str, "Hello"))
00615     _dbus_assert_not_reached ("couldn't append to string");
00616   
00617   if (!_dbus_string_find (&str, 0, "He", &i))
00618     _dbus_assert_not_reached ("didn't find 'He'");
00619   _dbus_assert (i == 0);
00620 
00621   if (!_dbus_string_find (&str, 0, "Hello", &i))
00622     _dbus_assert_not_reached ("didn't find 'Hello'");
00623   _dbus_assert (i == 0);
00624   
00625   if (!_dbus_string_find (&str, 0, "ello", &i))
00626     _dbus_assert_not_reached ("didn't find 'ello'");
00627   _dbus_assert (i == 1);
00628 
00629   if (!_dbus_string_find (&str, 0, "lo", &i))
00630     _dbus_assert_not_reached ("didn't find 'lo'");
00631   _dbus_assert (i == 3);
00632 
00633   if (!_dbus_string_find (&str, 2, "lo", &i))
00634     _dbus_assert_not_reached ("didn't find 'lo'");
00635   _dbus_assert (i == 3);
00636 
00637   if (_dbus_string_find (&str, 4, "lo", &i))
00638     _dbus_assert_not_reached ("did find 'lo'");
00639   
00640   if (!_dbus_string_find (&str, 0, "l", &i))
00641     _dbus_assert_not_reached ("didn't find 'l'");
00642   _dbus_assert (i == 2);
00643 
00644   if (!_dbus_string_find (&str, 0, "H", &i))
00645     _dbus_assert_not_reached ("didn't find 'H'");
00646   _dbus_assert (i == 0);
00647 
00648   if (!_dbus_string_find (&str, 0, "", &i))
00649     _dbus_assert_not_reached ("didn't find ''");
00650   _dbus_assert (i == 0);
00651   
00652   if (_dbus_string_find (&str, 0, "Hello!", NULL))
00653     _dbus_assert_not_reached ("Did find 'Hello!'");
00654 
00655   if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
00656     _dbus_assert_not_reached ("Did find 'Oh, Hello'");
00657   
00658   if (_dbus_string_find (&str, 0, "ill", NULL))
00659     _dbus_assert_not_reached ("Did find 'ill'");
00660 
00661   if (_dbus_string_find (&str, 0, "q", NULL))
00662     _dbus_assert_not_reached ("Did find 'q'");
00663 
00664   if (!_dbus_string_find_to (&str, 0, 2, "He", NULL))
00665     _dbus_assert_not_reached ("Didn't find 'He'");
00666 
00667   if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL))
00668     _dbus_assert_not_reached ("Did find 'Hello'");
00669 
00670   if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i))
00671     _dbus_assert_not_reached ("Did not find 'H'");
00672   _dbus_assert (i == 0);
00673 
00674   if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i))
00675     _dbus_assert_not_reached ("Did not find 'o'");
00676   _dbus_assert (i == _dbus_string_get_length (&str) - 1);
00677 
00678   if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i))
00679     _dbus_assert_not_reached ("Did find 'o'");
00680   _dbus_assert (i == -1);
00681 
00682   if (_dbus_string_find_byte_backward (&str, 1, 'e', &i))
00683     _dbus_assert_not_reached ("Did find 'e'");
00684   _dbus_assert (i == -1);
00685 
00686   if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i))
00687     _dbus_assert_not_reached ("Didn't find 'e'");
00688   _dbus_assert (i == 1);
00689   
00690   _dbus_string_free (&str);
00691 
00692   /* Hex encoding */
00693   _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string");
00694   if (!_dbus_string_init (&other))
00695     _dbus_assert_not_reached ("could not init string");
00696 
00697   if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0))
00698     _dbus_assert_not_reached ("deccoded bogus hex string with no error");
00699 
00700   _dbus_assert (end == 8);
00701 
00702   _dbus_string_free (&other);
00703 
00704   test_roundtrips (test_hex_roundtrip);
00705   
00706   _dbus_string_free (&str);
00707 
00708   {                                                                                           
00709     int found, found_len;  
00710 
00711     _dbus_string_init_const (&str, "012\r\n567\n90");
00712     
00713     if (!_dbus_string_find_eol (&str, 0, &found, &found_len) || found != 3 || found_len != 2)
00714       _dbus_assert_not_reached ("Did not find '\\r\\n'");                                       
00715     if (found != 3 || found_len != 2)                                                           
00716       _dbus_assert_not_reached ("invalid return values");                                       
00717     
00718     if (!_dbus_string_find_eol (&str, 5, &found, &found_len))                                    
00719       _dbus_assert_not_reached ("Did not find '\\n'");                                          
00720     if (found != 8 || found_len != 1)                                                           
00721       _dbus_assert_not_reached ("invalid return values");                                       
00722     
00723     if (_dbus_string_find_eol (&str, 9, &found, &found_len))                                     
00724       _dbus_assert_not_reached ("Found not expected '\\n'");                                    
00725     else if (found != 11 || found_len != 0)                                                     
00726       _dbus_assert_not_reached ("invalid return values '\\n'");                                 
00727 
00728     found = -1;
00729     found_len = -1;
00730     _dbus_string_init_const (&str, "");
00731     if (_dbus_string_find_eol (&str, 0, &found, &found_len))
00732       _dbus_assert_not_reached ("found an eol in an empty string");
00733     _dbus_assert (found == 0);
00734     _dbus_assert (found_len == 0);
00735     
00736     found = -1;
00737     found_len = -1;
00738     _dbus_string_init_const (&str, "foobar");
00739     if (_dbus_string_find_eol (&str, 0, &found, &found_len))
00740       _dbus_assert_not_reached ("found eol in string that lacks one");
00741     _dbus_assert (found == 6);
00742     _dbus_assert (found_len == 0);
00743 
00744     found = -1;
00745     found_len = -1;
00746     _dbus_string_init_const (&str, "foobar\n");
00747     if (!_dbus_string_find_eol (&str, 0, &found, &found_len))
00748       _dbus_assert_not_reached ("did not find eol in string that has one at end");
00749     _dbus_assert (found == 6);
00750     _dbus_assert (found_len == 1);
00751   }
00752 
00753   {
00754     DBusString line;
00755 
00756 #define FIRST_LINE "this is a line"
00757 #define SECOND_LINE "this is a second line"
00758     /* third line is empty */
00759 #define THIRD_LINE ""
00760 #define FOURTH_LINE "this is a fourth line"
00761     
00762     if (!_dbus_string_init (&str))
00763       _dbus_assert_not_reached ("no memory");
00764 
00765     if (!_dbus_string_append (&str, FIRST_LINE "\n" SECOND_LINE "\r\n" THIRD_LINE "\n" FOURTH_LINE))
00766       _dbus_assert_not_reached ("no memory");
00767     
00768     if (!_dbus_string_init (&line))
00769       _dbus_assert_not_reached ("no memory");
00770     
00771     if (!_dbus_string_pop_line (&str, &line))
00772       _dbus_assert_not_reached ("failed to pop first line");
00773 
00774     _dbus_assert (_dbus_string_equal_c_str (&line, FIRST_LINE));
00775     
00776     if (!_dbus_string_pop_line (&str, &line))
00777       _dbus_assert_not_reached ("failed to pop second line");
00778 
00779     _dbus_assert (_dbus_string_equal_c_str (&line, SECOND_LINE));
00780     
00781     if (!_dbus_string_pop_line (&str, &line))
00782       _dbus_assert_not_reached ("failed to pop third line");
00783 
00784     _dbus_assert (_dbus_string_equal_c_str (&line, THIRD_LINE));
00785     
00786     if (!_dbus_string_pop_line (&str, &line))
00787       _dbus_assert_not_reached ("failed to pop fourth line");
00788 
00789     _dbus_assert (_dbus_string_equal_c_str (&line, FOURTH_LINE));
00790     
00791     _dbus_string_free (&str);
00792     _dbus_string_free (&line);
00793   }
00794 
00795   {
00796     if (!_dbus_string_init (&str))
00797       _dbus_assert_not_reached ("no memory");
00798 
00799     for (i = 0; i < 10000; i++)
00800       if (!_dbus_string_append (&str, "abcdefghijklmnopqrstuvwxyz"))
00801         _dbus_assert_not_reached ("no memory");
00802 
00803     if (!_dbus_string_set_length (&str, 10))
00804       _dbus_assert_not_reached ("failed to set length");
00805 
00806     /* actually compact */
00807     if (!_dbus_string_compact (&str, 2048))
00808       _dbus_assert_not_reached ("failed to compact after set_length");
00809 
00810     /* peek inside to make sure it worked */
00811     if (((DBusRealString *)&str)->allocated > 30)
00812       _dbus_assert_not_reached ("compacting string didn't do anything");
00813 
00814     if (!_dbus_string_equal_c_str (&str, "abcdefghij"))
00815       _dbus_assert_not_reached ("unexpected content after compact");
00816 
00817     /* compact nothing */
00818     if (!_dbus_string_compact (&str, 2048))
00819       _dbus_assert_not_reached ("failed to compact 2nd time");
00820 
00821     if (!_dbus_string_equal_c_str (&str, "abcdefghij"))
00822       _dbus_assert_not_reached ("unexpected content after 2nd compact");
00823 
00824     /* and make sure it still works...*/
00825     if (!_dbus_string_append (&str, "123456"))
00826       _dbus_assert_not_reached ("failed to append after compact");
00827 
00828     if (!_dbus_string_equal_c_str (&str, "abcdefghij123456"))
00829       _dbus_assert_not_reached ("unexpected content after append");
00830 
00831     /* after growing automatically, this should do nothing */
00832     if (!_dbus_string_compact (&str, 20000))
00833       _dbus_assert_not_reached ("failed to compact after grow");
00834 
00835     /* but this one will do something */
00836     if (!_dbus_string_compact (&str, 0))
00837       _dbus_assert_not_reached ("failed to compact after grow");
00838 
00839     if (!_dbus_string_equal_c_str (&str, "abcdefghij123456"))
00840       _dbus_assert_not_reached ("unexpected content");
00841 
00842     if (!_dbus_string_append (&str, "!@#$%"))
00843       _dbus_assert_not_reached ("failed to append after compact");
00844 
00845     if (!_dbus_string_equal_c_str (&str, "abcdefghij123456!@#$%"))
00846       _dbus_assert_not_reached ("unexpected content");
00847 
00848     _dbus_string_free (&str);
00849   }
00850 
00851   {
00852     const char two_strings[] = "one\ttwo";
00853 
00854     if (!_dbus_string_init (&str))
00855       _dbus_assert_not_reached ("no memory");
00856 
00857     if (!_dbus_string_init (&other))
00858       _dbus_assert_not_reached ("no memory");
00859 
00860     if (!_dbus_string_append (&str, two_strings))
00861       _dbus_assert_not_reached ("no memory");
00862 
00863     if (!_dbus_string_split_on_byte (&str, '\t', &other))
00864       _dbus_assert_not_reached ("no memory or delimiter not found");
00865 
00866     if (strcmp (_dbus_string_get_data (&str), "one") != 0)
00867       _dbus_assert_not_reached ("left side after split on tab is wrong");
00868 
00869     if (strcmp (_dbus_string_get_data (&other), "two") != 0)
00870       _dbus_assert_not_reached ("right side after split on tab is wrong");
00871 
00872     _dbus_string_free (&str);
00873     _dbus_string_free (&other);
00874   }
00875 
00876   {
00877     const char upper_string[] = "TOUPPERSTRING";
00878     const char lower_string[] = "toupperstring";
00879     const char lower2_string[] = "toupperSTRING";
00880 
00881     if (!_dbus_string_init (&str))
00882       _dbus_assert_not_reached ("no memory");
00883 
00884     if (!_dbus_string_append (&str, upper_string))
00885       _dbus_assert_not_reached ("no memory");
00886 
00887     _dbus_string_tolower_ascii (&str, 0, _dbus_string_get_length(&str));
00888 
00889     if (!_dbus_string_equal_c_str (&str, lower_string))
00890       _dbus_assert_not_reached ("_dbus_string_tolower_ascii failed");
00891 
00892     _dbus_string_free (&str);
00893 
00894     if (!_dbus_string_init (&str))
00895       _dbus_assert_not_reached ("no memory");
00896 
00897     if (!_dbus_string_append (&str, upper_string))
00898       _dbus_assert_not_reached ("no memory");
00899 
00900     _dbus_string_tolower_ascii (&str, 0, 7);
00901 
00902     if (!_dbus_string_equal_c_str (&str, lower2_string))
00903       _dbus_assert_not_reached ("_dbus_string_tolower_ascii failed in partial conversion");
00904 
00905     _dbus_string_free (&str);
00906   }
00907 
00908   {
00909     const char lower_string[] = "toupperstring";
00910     const char upper_string[] = "TOUPPERSTRING";
00911     const char upper2_string[] = "TOUPPERstring";
00912 
00913     if (!_dbus_string_init (&str))
00914       _dbus_assert_not_reached ("no memory");
00915 
00916     if (!_dbus_string_append (&str, lower_string))
00917       _dbus_assert_not_reached ("no memory");
00918 
00919     _dbus_string_toupper_ascii (&str, 0, _dbus_string_get_length(&str));
00920 
00921     if (!_dbus_string_equal_c_str (&str, upper_string))
00922       _dbus_assert_not_reached ("_dbus_string_toupper_ascii failed");
00923 
00924     _dbus_string_free (&str);
00925 
00926     if (!_dbus_string_init (&str))
00927       _dbus_assert_not_reached ("no memory");
00928 
00929     if (!_dbus_string_append (&str, lower_string))
00930       _dbus_assert_not_reached ("no memory");
00931 
00932     _dbus_string_toupper_ascii (&str, 0, 7);
00933 
00934     if (!_dbus_string_equal_c_str (&str, upper2_string))
00935       _dbus_assert_not_reached ("_dbus_string_toupper_ascii failed in partial conversion");
00936 
00937     _dbus_string_free (&str);
00938   }
00939 
00940   return TRUE;
00941 }
00942 
00943 #endif /* DBUS_BUILD_TESTS */