D-Bus  1.5.8
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_hex_roundtrip (const unsigned char *data,
00124                     int                  len)
00125 {
00126   DBusString orig;
00127   DBusString encoded;
00128   DBusString decoded;
00129   int end;
00130 
00131   if (len < 0)
00132     len = strlen (data);
00133   
00134   if (!_dbus_string_init (&orig))
00135     _dbus_assert_not_reached ("could not init string");
00136 
00137   if (!_dbus_string_init (&encoded))
00138     _dbus_assert_not_reached ("could not init string");
00139   
00140   if (!_dbus_string_init (&decoded))
00141     _dbus_assert_not_reached ("could not init string");
00142 
00143   if (!_dbus_string_append_len (&orig, data, len))
00144     _dbus_assert_not_reached ("couldn't append orig data");
00145 
00146   if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))
00147     _dbus_assert_not_reached ("could not encode");
00148 
00149   if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0))
00150     _dbus_assert_not_reached ("could not decode");
00151     
00152   _dbus_assert (_dbus_string_get_length (&encoded) == end);
00153 
00154   if (!_dbus_string_equal (&orig, &decoded))
00155     {
00156       const char *s;
00157       
00158       printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
00159               _dbus_string_get_length (&orig),
00160               _dbus_string_get_length (&encoded),
00161               _dbus_string_get_length (&decoded));
00162       printf ("Original: %s\n", data);
00163       s = _dbus_string_get_const_data (&decoded);
00164       printf ("Decoded: %s\n", s);
00165       _dbus_assert_not_reached ("original string not the same as string decoded from hex");
00166     }
00167   
00168   _dbus_string_free (&orig);
00169   _dbus_string_free (&encoded);
00170   _dbus_string_free (&decoded);  
00171 }
00172 
00173 typedef void (* TestRoundtripFunc) (const unsigned char *data,
00174                                     int                  len);
00175 static void
00176 test_roundtrips (TestRoundtripFunc func)
00177 {
00178   (* func) ("Hello this is a string\n", -1);
00179   (* func) ("Hello this is a string\n1", -1);
00180   (* func) ("Hello this is a string\n12", -1);
00181   (* func) ("Hello this is a string\n123", -1);
00182   (* func) ("Hello this is a string\n1234", -1);
00183   (* func) ("Hello this is a string\n12345", -1);
00184   (* func) ("", 0);
00185   (* func) ("1", 1);
00186   (* func) ("12", 2);
00187   (* func) ("123", 3);
00188   (* func) ("1234", 4);
00189   (* func) ("12345", 5);
00190   (* func) ("", 1);
00191   (* func) ("1", 2);
00192   (* func) ("12", 3);
00193   (* func) ("123", 4);
00194   (* func) ("1234", 5);
00195   (* func) ("12345", 6);
00196   {
00197     unsigned char buf[512];
00198     int i;
00199     
00200     i = 0;
00201     while (i < _DBUS_N_ELEMENTS (buf))
00202       {
00203         buf[i] = i;
00204         ++i;
00205       }
00206     i = 0;
00207     while (i < _DBUS_N_ELEMENTS (buf))
00208       {
00209         (* func) (buf, i);
00210         ++i;
00211       }
00212   }
00213 }
00214 
00225 dbus_bool_t
00226 _dbus_string_test (void)
00227 {
00228   DBusString str;
00229   DBusString other;
00230   int i, a, end;
00231   long v;
00232   double d;
00233   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 };
00234   char *s;
00235   dbus_unichar_t ch;
00236 
00237   /* Test shortening and setting length */
00238   i = 0;
00239   while (i < _DBUS_N_ELEMENTS (lens))
00240     {
00241       int j;
00242       
00243       if (!_dbus_string_init (&str))
00244         _dbus_assert_not_reached ("failed to init string");
00245 
00246       if (!_dbus_string_set_length (&str, lens[i]))
00247         _dbus_assert_not_reached ("failed to set string length");
00248 
00249       j = lens[i];
00250       while (j > 0)
00251         {
00252           _dbus_assert (_dbus_string_get_length (&str) == j);
00253           if (j > 0)
00254             {
00255               _dbus_string_shorten (&str, 1);
00256               _dbus_assert (_dbus_string_get_length (&str) == (j - 1));
00257             }
00258           --j;
00259         }
00260       
00261       _dbus_string_free (&str);
00262 
00263       ++i;
00264     }
00265 
00266   /* Test equality */
00267   if (!_dbus_string_init (&str))
00268     _dbus_assert_not_reached ("oom");
00269 
00270   if (!_dbus_string_append (&str, "Hello World"))
00271     _dbus_assert_not_reached ("oom");
00272 
00273   _dbus_string_init_const (&other, "H");
00274   _dbus_assert (_dbus_string_equal_substring (&str, 0, 1, &other, 0));
00275   _dbus_assert (_dbus_string_equal_substring (&str, 1, 0, &other, 1));
00276   _dbus_string_init_const (&other, "Hello");
00277   _dbus_assert (_dbus_string_equal_substring (&str, 0, 5, &other, 0));
00278   _dbus_assert (_dbus_string_equal_substring (&str, 1, 4, &other, 1));
00279   _dbus_assert (_dbus_string_equal_substring (&str, 2, 3, &other, 2));
00280   _dbus_assert (_dbus_string_equal_substring (&str, 3, 2, &other, 3));
00281   _dbus_assert (_dbus_string_equal_substring (&str, 4, 1, &other, 4));
00282   _dbus_assert (_dbus_string_equal_substring (&str, 5, 0, &other, 5));
00283 
00284   _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 0));
00285   _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 1));
00286   _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 2));
00287   _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 3));
00288   _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 4));
00289   _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 5));
00290 
00291   
00292   _dbus_string_init_const (&other, "World");
00293   _dbus_assert (_dbus_string_equal_substring (&str, 6,  5, &other, 0));
00294   _dbus_assert (_dbus_string_equal_substring (&str, 7,  4, &other, 1));
00295   _dbus_assert (_dbus_string_equal_substring (&str, 8,  3, &other, 2));
00296   _dbus_assert (_dbus_string_equal_substring (&str, 9,  2, &other, 3));
00297   _dbus_assert (_dbus_string_equal_substring (&str, 10, 1, &other, 4));
00298   _dbus_assert (_dbus_string_equal_substring (&str, 11, 0, &other, 5));
00299 
00300   _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 6));
00301   _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 7));
00302   _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 8));
00303   _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 9));
00304   _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 10));
00305   _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 11));
00306   
00307   _dbus_string_free (&str);
00308   
00309   /* Test appending data */
00310   if (!_dbus_string_init (&str))
00311     _dbus_assert_not_reached ("failed to init string");
00312 
00313   i = 0;
00314   while (i < 10)
00315     {
00316       if (!_dbus_string_append (&str, "a"))
00317         _dbus_assert_not_reached ("failed to append string to string\n");
00318 
00319       _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1);
00320 
00321       if (!_dbus_string_append_byte (&str, 'b'))
00322         _dbus_assert_not_reached ("failed to append byte to string\n");
00323 
00324       _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2);
00325                     
00326       ++i;
00327     }
00328 
00329   _dbus_string_free (&str);
00330 
00331   /* Check steal_data */
00332   
00333   if (!_dbus_string_init (&str))
00334     _dbus_assert_not_reached ("failed to init string");
00335 
00336   if (!_dbus_string_append (&str, "Hello World"))
00337     _dbus_assert_not_reached ("could not append to string");
00338 
00339   i = _dbus_string_get_length (&str);
00340   
00341   if (!_dbus_string_steal_data (&str, &s))
00342     _dbus_assert_not_reached ("failed to steal data");
00343 
00344   _dbus_assert (_dbus_string_get_length (&str) == 0);
00345   _dbus_assert (((int)strlen (s)) == i);
00346 
00347   dbus_free (s);
00348 
00349   /* Check move */
00350   
00351   if (!_dbus_string_append (&str, "Hello World"))
00352     _dbus_assert_not_reached ("could not append to string");
00353 
00354   i = _dbus_string_get_length (&str);
00355 
00356   if (!_dbus_string_init (&other))
00357     _dbus_assert_not_reached ("could not init string");
00358   
00359   if (!_dbus_string_move (&str, 0, &other, 0))
00360     _dbus_assert_not_reached ("could not move");
00361 
00362   _dbus_assert (_dbus_string_get_length (&str) == 0);
00363   _dbus_assert (_dbus_string_get_length (&other) == i);
00364 
00365   if (!_dbus_string_append (&str, "Hello World"))
00366     _dbus_assert_not_reached ("could not append to string");
00367   
00368   if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other)))
00369     _dbus_assert_not_reached ("could not move");
00370 
00371   _dbus_assert (_dbus_string_get_length (&str) == 0);
00372   _dbus_assert (_dbus_string_get_length (&other) == i * 2);
00373 
00374     if (!_dbus_string_append (&str, "Hello World"))
00375     _dbus_assert_not_reached ("could not append to string");
00376   
00377   if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2))
00378     _dbus_assert_not_reached ("could not move");
00379 
00380   _dbus_assert (_dbus_string_get_length (&str) == 0);
00381   _dbus_assert (_dbus_string_get_length (&other) == i * 3);
00382   
00383   _dbus_string_free (&other);
00384 
00385   /* Check copy */
00386   
00387   if (!_dbus_string_append (&str, "Hello World"))
00388     _dbus_assert_not_reached ("could not append to string");
00389 
00390   i = _dbus_string_get_length (&str);
00391   
00392   if (!_dbus_string_init (&other))
00393     _dbus_assert_not_reached ("could not init string");
00394   
00395   if (!_dbus_string_copy (&str, 0, &other, 0))
00396     _dbus_assert_not_reached ("could not copy");
00397 
00398   _dbus_assert (_dbus_string_get_length (&str) == i);
00399   _dbus_assert (_dbus_string_get_length (&other) == i);
00400 
00401   if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other)))
00402     _dbus_assert_not_reached ("could not copy");
00403 
00404   _dbus_assert (_dbus_string_get_length (&str) == i);
00405   _dbus_assert (_dbus_string_get_length (&other) == i * 2);
00406   _dbus_assert (_dbus_string_equal_c_str (&other,
00407                                           "Hello WorldHello World"));
00408 
00409   if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2))
00410     _dbus_assert_not_reached ("could not copy");
00411 
00412   _dbus_assert (_dbus_string_get_length (&str) == i);
00413   _dbus_assert (_dbus_string_get_length (&other) == i * 3);
00414   _dbus_assert (_dbus_string_equal_c_str (&other,
00415                                           "Hello WorldHello WorldHello World"));
00416   
00417   _dbus_string_free (&str);
00418   _dbus_string_free (&other);
00419 
00420   /* Check replace */
00421 
00422   if (!_dbus_string_init (&str))
00423     _dbus_assert_not_reached ("failed to init string");
00424   
00425   if (!_dbus_string_append (&str, "Hello World"))
00426     _dbus_assert_not_reached ("could not append to string");
00427 
00428   i = _dbus_string_get_length (&str);
00429   
00430   if (!_dbus_string_init (&other))
00431     _dbus_assert_not_reached ("could not init string");
00432   
00433   if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
00434                                  &other, 0, _dbus_string_get_length (&other)))
00435     _dbus_assert_not_reached ("could not replace");
00436 
00437   _dbus_assert (_dbus_string_get_length (&str) == i);
00438   _dbus_assert (_dbus_string_get_length (&other) == i);
00439   _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World"));
00440   
00441   if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
00442                                  &other, 5, 1))
00443     _dbus_assert_not_reached ("could not replace center space");
00444 
00445   _dbus_assert (_dbus_string_get_length (&str) == i);
00446   _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
00447   _dbus_assert (_dbus_string_equal_c_str (&other,
00448                                           "HelloHello WorldWorld"));
00449 
00450   
00451   if (!_dbus_string_replace_len (&str, 1, 1,
00452                                  &other,
00453                                  _dbus_string_get_length (&other) - 1,
00454                                  1))
00455     _dbus_assert_not_reached ("could not replace end character");
00456   
00457   _dbus_assert (_dbus_string_get_length (&str) == i);
00458   _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
00459   _dbus_assert (_dbus_string_equal_c_str (&other,
00460                                           "HelloHello WorldWorle"));
00461 
00462   _dbus_string_free (&str);
00463   _dbus_string_free (&other);
00464 
00465   /* Different tests are provided because different behaviours are
00466    * implemented in _dbus_string_replace_len() in function of replacing and
00467    * replaced lengths
00468    */
00469 
00470   if (!_dbus_string_init (&str))
00471     _dbus_assert_not_reached ("failed to init string");
00472   
00473   if (!_dbus_string_append (&str, "Hello World"))
00474     _dbus_assert_not_reached ("could not append to string");
00475 
00476   i = _dbus_string_get_length (&str);
00477   
00478   if (!_dbus_string_init (&other))
00479     _dbus_assert_not_reached ("could not init string");
00480 
00481   if (!_dbus_string_append (&other, "Foo String"))
00482     _dbus_assert_not_reached ("could not append to string");
00483 
00484   a = _dbus_string_get_length (&other);
00485 
00486   if (!_dbus_string_replace_len (&str, 0, 6,
00487                                  &other, 4, 0))
00488     _dbus_assert_not_reached ("could not replace 0 length");
00489 
00490   _dbus_assert (_dbus_string_get_length (&str) == i);
00491   _dbus_assert (_dbus_string_get_length (&other) == a + 6);
00492   _dbus_assert (_dbus_string_equal_c_str (&other,
00493                                           "Foo Hello String"));
00494 
00495   if (!_dbus_string_replace_len (&str, 5, 6,
00496                                  &other,
00497                                  _dbus_string_get_length (&other),
00498                                  0))
00499     _dbus_assert_not_reached ("could not replace at the end");
00500 
00501   _dbus_assert (_dbus_string_get_length (&str) == i);
00502   _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6);
00503   _dbus_assert (_dbus_string_equal_c_str (&other,
00504                                           "Foo Hello String World"));
00505 
00506   if (!_dbus_string_replace_len (&str, 0, 5,
00507                                  &other,
00508                                  _dbus_string_get_length (&other) - 5,
00509                                  5))
00510     _dbus_assert_not_reached ("could not replace same length");
00511 
00512   _dbus_assert (_dbus_string_get_length (&str) == i);
00513   _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6);
00514   _dbus_assert (_dbus_string_equal_c_str (&other,
00515                                           "Foo Hello String Hello"));
00516 
00517   if (!_dbus_string_replace_len (&str, 6, 5,
00518                                  &other, 4, 12))
00519     _dbus_assert_not_reached ("could not replace with shorter string");
00520 
00521   _dbus_assert (_dbus_string_get_length (&str) == i);
00522   _dbus_assert (_dbus_string_get_length (&other) == a + 5);
00523   _dbus_assert (_dbus_string_equal_c_str (&other,
00524                                           "Foo World Hello"));
00525 
00526   if (!_dbus_string_replace_len (&str, 0, 1,
00527                                  &other, 0, 3))
00528     _dbus_assert_not_reached ("could not replace at the beginning");
00529 
00530   _dbus_assert (_dbus_string_get_length (&str) == i);
00531   _dbus_assert (_dbus_string_get_length (&other) == a + 3);
00532   _dbus_assert (_dbus_string_equal_c_str (&other,
00533                                           "H World Hello"));
00534 
00535   if (!_dbus_string_replace_len (&str, 6, 5,
00536                                  &other,
00537                                  _dbus_string_get_length (&other) - 5,
00538                                  5))
00539     _dbus_assert_not_reached ("could not replace same length");
00540 
00541   _dbus_assert (_dbus_string_get_length (&str) == i);
00542   _dbus_assert (_dbus_string_get_length (&other) == a + 3);
00543   _dbus_assert (_dbus_string_equal_c_str (&other,
00544                                           "H World World"));
00545 
00546   _dbus_string_free (&str);
00547   _dbus_string_free (&other);
00548 
00549   /* Check append/get unichar */
00550   
00551   if (!_dbus_string_init (&str))
00552     _dbus_assert_not_reached ("failed to init string");
00553 
00554   ch = 0;
00555   if (!_dbus_string_append_unichar (&str, 0xfffc))
00556     _dbus_assert_not_reached ("failed to append unichar");
00557 
00558   _dbus_string_get_unichar (&str, 0, &ch, &i);
00559 
00560   _dbus_assert (ch == 0xfffc);
00561   _dbus_assert (i == _dbus_string_get_length (&str));
00562 
00563   _dbus_string_free (&str);
00564 
00565   /* Check insert/set/get byte */
00566   
00567   if (!_dbus_string_init (&str))
00568     _dbus_assert_not_reached ("failed to init string");
00569 
00570   if (!_dbus_string_append (&str, "Hello"))
00571     _dbus_assert_not_reached ("failed to append Hello");
00572 
00573   _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H');
00574   _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e');
00575   _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l');
00576   _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l');
00577   _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o');
00578 
00579   _dbus_string_set_byte (&str, 1, 'q');
00580   _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');
00581 
00582   if (!_dbus_string_insert_bytes (&str, 0, 1, 255))
00583     _dbus_assert_not_reached ("can't insert byte");
00584 
00585   if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z'))
00586     _dbus_assert_not_reached ("can't insert byte");
00587 
00588   if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W'))
00589     _dbus_assert_not_reached ("can't insert byte");
00590   
00591   _dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
00592   _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
00593   _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
00594   _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z');
00595   _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z');
00596   _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z');
00597   _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q');
00598   _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l');
00599   _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l');
00600   _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o');
00601   _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W');
00602 
00603   _dbus_string_free (&str);
00604   
00605   /* Check append/parse int/double */
00606   
00607   if (!_dbus_string_init (&str))
00608     _dbus_assert_not_reached ("failed to init string");
00609 
00610   if (!_dbus_string_append_int (&str, 27))
00611     _dbus_assert_not_reached ("failed to append int");
00612 
00613   i = _dbus_string_get_length (&str);
00614 
00615   if (!_dbus_string_parse_int (&str, 0, &v, &end))
00616     _dbus_assert_not_reached ("failed to parse int");
00617 
00618   _dbus_assert (v == 27);
00619   _dbus_assert (end == i);
00620 
00621   _dbus_string_free (&str);
00622   
00623   if (!_dbus_string_init (&str))
00624     _dbus_assert_not_reached ("failed to init string");
00625   
00626   if (!_dbus_string_append_double (&str, 50.3))
00627     _dbus_assert_not_reached ("failed to append float");
00628 
00629   i = _dbus_string_get_length (&str);
00630 
00631   if (!_dbus_string_parse_double (&str, 0, &d, &end))
00632     _dbus_assert_not_reached ("failed to parse float");
00633 
00634   _dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6));
00635   _dbus_assert (end == i);
00636 
00637   _dbus_string_free (&str);
00638 
00639   /* Test find */
00640   if (!_dbus_string_init (&str))
00641     _dbus_assert_not_reached ("failed to init string");
00642 
00643   if (!_dbus_string_append (&str, "Hello"))
00644     _dbus_assert_not_reached ("couldn't append to string");
00645   
00646   if (!_dbus_string_find (&str, 0, "He", &i))
00647     _dbus_assert_not_reached ("didn't find 'He'");
00648   _dbus_assert (i == 0);
00649 
00650   if (!_dbus_string_find (&str, 0, "Hello", &i))
00651     _dbus_assert_not_reached ("didn't find 'Hello'");
00652   _dbus_assert (i == 0);
00653   
00654   if (!_dbus_string_find (&str, 0, "ello", &i))
00655     _dbus_assert_not_reached ("didn't find 'ello'");
00656   _dbus_assert (i == 1);
00657 
00658   if (!_dbus_string_find (&str, 0, "lo", &i))
00659     _dbus_assert_not_reached ("didn't find 'lo'");
00660   _dbus_assert (i == 3);
00661 
00662   if (!_dbus_string_find (&str, 2, "lo", &i))
00663     _dbus_assert_not_reached ("didn't find 'lo'");
00664   _dbus_assert (i == 3);
00665 
00666   if (_dbus_string_find (&str, 4, "lo", &i))
00667     _dbus_assert_not_reached ("did find 'lo'");
00668   
00669   if (!_dbus_string_find (&str, 0, "l", &i))
00670     _dbus_assert_not_reached ("didn't find 'l'");
00671   _dbus_assert (i == 2);
00672 
00673   if (!_dbus_string_find (&str, 0, "H", &i))
00674     _dbus_assert_not_reached ("didn't find 'H'");
00675   _dbus_assert (i == 0);
00676 
00677   if (!_dbus_string_find (&str, 0, "", &i))
00678     _dbus_assert_not_reached ("didn't find ''");
00679   _dbus_assert (i == 0);
00680   
00681   if (_dbus_string_find (&str, 0, "Hello!", NULL))
00682     _dbus_assert_not_reached ("Did find 'Hello!'");
00683 
00684   if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
00685     _dbus_assert_not_reached ("Did find 'Oh, Hello'");
00686   
00687   if (_dbus_string_find (&str, 0, "ill", NULL))
00688     _dbus_assert_not_reached ("Did find 'ill'");
00689 
00690   if (_dbus_string_find (&str, 0, "q", NULL))
00691     _dbus_assert_not_reached ("Did find 'q'");
00692 
00693   if (!_dbus_string_find_to (&str, 0, 2, "He", NULL))
00694     _dbus_assert_not_reached ("Didn't find 'He'");
00695 
00696   if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL))
00697     _dbus_assert_not_reached ("Did find 'Hello'");
00698 
00699   if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i))
00700     _dbus_assert_not_reached ("Did not find 'H'");
00701   _dbus_assert (i == 0);
00702 
00703   if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i))
00704     _dbus_assert_not_reached ("Did not find 'o'");
00705   _dbus_assert (i == _dbus_string_get_length (&str) - 1);
00706 
00707   if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i))
00708     _dbus_assert_not_reached ("Did find 'o'");
00709   _dbus_assert (i == -1);
00710 
00711   if (_dbus_string_find_byte_backward (&str, 1, 'e', &i))
00712     _dbus_assert_not_reached ("Did find 'e'");
00713   _dbus_assert (i == -1);
00714 
00715   if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i))
00716     _dbus_assert_not_reached ("Didn't find 'e'");
00717   _dbus_assert (i == 1);
00718   
00719   _dbus_string_free (&str);
00720 
00721   /* Hex encoding */
00722   _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string");
00723   if (!_dbus_string_init (&other))
00724     _dbus_assert_not_reached ("could not init string");
00725 
00726   if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0))
00727     _dbus_assert_not_reached ("deccoded bogus hex string with no error");
00728 
00729   _dbus_assert (end == 8);
00730 
00731   _dbus_string_free (&other);
00732 
00733   test_roundtrips (test_hex_roundtrip);
00734   
00735   _dbus_string_free (&str);
00736 
00737   {                                                                                           
00738     int found, found_len;  
00739 
00740     _dbus_string_init_const (&str, "012\r\n567\n90");
00741     
00742     if (!_dbus_string_find_eol (&str, 0, &found, &found_len) || found != 3 || found_len != 2)
00743       _dbus_assert_not_reached ("Did not find '\\r\\n'");                                       
00744     if (found != 3 || found_len != 2)                                                           
00745       _dbus_assert_not_reached ("invalid return values");                                       
00746     
00747     if (!_dbus_string_find_eol (&str, 5, &found, &found_len))                                    
00748       _dbus_assert_not_reached ("Did not find '\\n'");                                          
00749     if (found != 8 || found_len != 1)                                                           
00750       _dbus_assert_not_reached ("invalid return values");                                       
00751     
00752     if (_dbus_string_find_eol (&str, 9, &found, &found_len))                                     
00753       _dbus_assert_not_reached ("Found not expected '\\n'");                                    
00754     else if (found != 11 || found_len != 0)                                                     
00755       _dbus_assert_not_reached ("invalid return values '\\n'");                                 
00756 
00757     found = -1;
00758     found_len = -1;
00759     _dbus_string_init_const (&str, "");
00760     if (_dbus_string_find_eol (&str, 0, &found, &found_len))
00761       _dbus_assert_not_reached ("found an eol in an empty string");
00762     _dbus_assert (found == 0);
00763     _dbus_assert (found_len == 0);
00764     
00765     found = -1;
00766     found_len = -1;
00767     _dbus_string_init_const (&str, "foobar");
00768     if (_dbus_string_find_eol (&str, 0, &found, &found_len))
00769       _dbus_assert_not_reached ("found eol in string that lacks one");
00770     _dbus_assert (found == 6);
00771     _dbus_assert (found_len == 0);
00772 
00773     found = -1;
00774     found_len = -1;
00775     _dbus_string_init_const (&str, "foobar\n");
00776     if (!_dbus_string_find_eol (&str, 0, &found, &found_len))
00777       _dbus_assert_not_reached ("did not find eol in string that has one at end");
00778     _dbus_assert (found == 6);
00779     _dbus_assert (found_len == 1);
00780   }
00781 
00782   {
00783     DBusString line;
00784 
00785 #define FIRST_LINE "this is a line"
00786 #define SECOND_LINE "this is a second line"
00787     /* third line is empty */
00788 #define THIRD_LINE ""
00789 #define FOURTH_LINE "this is a fourth line"
00790     
00791     if (!_dbus_string_init (&str))
00792       _dbus_assert_not_reached ("no memory");
00793 
00794     if (!_dbus_string_append (&str, FIRST_LINE "\n" SECOND_LINE "\r\n" THIRD_LINE "\n" FOURTH_LINE))
00795       _dbus_assert_not_reached ("no memory");
00796     
00797     if (!_dbus_string_init (&line))
00798       _dbus_assert_not_reached ("no memory");
00799     
00800     if (!_dbus_string_pop_line (&str, &line))
00801       _dbus_assert_not_reached ("failed to pop first line");
00802 
00803     _dbus_assert (_dbus_string_equal_c_str (&line, FIRST_LINE));
00804     
00805     if (!_dbus_string_pop_line (&str, &line))
00806       _dbus_assert_not_reached ("failed to pop second line");
00807 
00808     _dbus_assert (_dbus_string_equal_c_str (&line, SECOND_LINE));
00809     
00810     if (!_dbus_string_pop_line (&str, &line))
00811       _dbus_assert_not_reached ("failed to pop third line");
00812 
00813     _dbus_assert (_dbus_string_equal_c_str (&line, THIRD_LINE));
00814     
00815     if (!_dbus_string_pop_line (&str, &line))
00816       _dbus_assert_not_reached ("failed to pop fourth line");
00817 
00818     _dbus_assert (_dbus_string_equal_c_str (&line, FOURTH_LINE));
00819     
00820     _dbus_string_free (&str);
00821     _dbus_string_free (&line);
00822   }
00823 
00824   {
00825     if (!_dbus_string_init (&str))
00826       _dbus_assert_not_reached ("no memory");
00827 
00828     for (i = 0; i < 10000; i++)
00829       if (!_dbus_string_append (&str, "abcdefghijklmnopqrstuvwxyz"))
00830         _dbus_assert_not_reached ("no memory");
00831 
00832     if (!_dbus_string_set_length (&str, 10))
00833       _dbus_assert_not_reached ("failed to set length");
00834 
00835     /* actually compact */
00836     if (!_dbus_string_compact (&str, 2048))
00837       _dbus_assert_not_reached ("failed to compact after set_length");
00838 
00839     /* peek inside to make sure it worked */
00840     if (((DBusRealString *)&str)->allocated > 30)
00841       _dbus_assert_not_reached ("compacting string didn't do anything");
00842 
00843     if (!_dbus_string_equal_c_str (&str, "abcdefghij"))
00844       _dbus_assert_not_reached ("unexpected content after compact");
00845 
00846     /* compact nothing */
00847     if (!_dbus_string_compact (&str, 2048))
00848       _dbus_assert_not_reached ("failed to compact 2nd time");
00849 
00850     if (!_dbus_string_equal_c_str (&str, "abcdefghij"))
00851       _dbus_assert_not_reached ("unexpected content after 2nd compact");
00852 
00853     /* and make sure it still works...*/
00854     if (!_dbus_string_append (&str, "123456"))
00855       _dbus_assert_not_reached ("failed to append after compact");
00856 
00857     if (!_dbus_string_equal_c_str (&str, "abcdefghij123456"))
00858       _dbus_assert_not_reached ("unexpected content after append");
00859 
00860     /* after growing automatically, this should do nothing */
00861     if (!_dbus_string_compact (&str, 20000))
00862       _dbus_assert_not_reached ("failed to compact after grow");
00863 
00864     /* but this one will do something */
00865     if (!_dbus_string_compact (&str, 0))
00866       _dbus_assert_not_reached ("failed to compact after grow");
00867 
00868     if (!_dbus_string_equal_c_str (&str, "abcdefghij123456"))
00869       _dbus_assert_not_reached ("unexpected content");
00870 
00871     if (!_dbus_string_append (&str, "!@#$%"))
00872       _dbus_assert_not_reached ("failed to append after compact");
00873 
00874     if (!_dbus_string_equal_c_str (&str, "abcdefghij123456!@#$%"))
00875       _dbus_assert_not_reached ("unexpected content");
00876 
00877     _dbus_string_free (&str);
00878   }
00879 
00880   {
00881     const char two_strings[] = "one\ttwo";
00882 
00883     if (!_dbus_string_init (&str))
00884       _dbus_assert_not_reached ("no memory");
00885 
00886     if (!_dbus_string_init (&other))
00887       _dbus_assert_not_reached ("no memory");
00888 
00889     if (!_dbus_string_append (&str, two_strings))
00890       _dbus_assert_not_reached ("no memory");
00891 
00892     if (!_dbus_string_split_on_byte (&str, '\t', &other))
00893       _dbus_assert_not_reached ("no memory or delimiter not found");
00894 
00895     if (strcmp (_dbus_string_get_data (&str), "one") != 0)
00896       _dbus_assert_not_reached ("left side after split on tab is wrong");
00897 
00898     if (strcmp (_dbus_string_get_data (&other), "two") != 0)
00899       _dbus_assert_not_reached ("right side after split on tab is wrong");
00900 
00901     _dbus_string_free (&str);
00902     _dbus_string_free (&other);
00903   }
00904 
00905   {
00906     const char upper_string[] = "TOUPPERSTRING";
00907     const char lower_string[] = "toupperstring";
00908     const char lower2_string[] = "toupperSTRING";
00909 
00910     if (!_dbus_string_init (&str))
00911       _dbus_assert_not_reached ("no memory");
00912 
00913     if (!_dbus_string_append (&str, upper_string))
00914       _dbus_assert_not_reached ("no memory");
00915 
00916     _dbus_string_tolower_ascii (&str, 0, _dbus_string_get_length(&str));
00917 
00918     if (!_dbus_string_equal_c_str (&str, lower_string))
00919       _dbus_assert_not_reached ("_dbus_string_tolower_ascii failed");
00920 
00921     _dbus_string_free (&str);
00922 
00923     if (!_dbus_string_init (&str))
00924       _dbus_assert_not_reached ("no memory");
00925 
00926     if (!_dbus_string_append (&str, upper_string))
00927       _dbus_assert_not_reached ("no memory");
00928 
00929     _dbus_string_tolower_ascii (&str, 0, 7);
00930 
00931     if (!_dbus_string_equal_c_str (&str, lower2_string))
00932       _dbus_assert_not_reached ("_dbus_string_tolower_ascii failed in partial conversion");
00933 
00934     _dbus_string_free (&str);
00935   }
00936 
00937   {
00938     const char lower_string[] = "toupperstring";
00939     const char upper_string[] = "TOUPPERSTRING";
00940     const char upper2_string[] = "TOUPPERstring";
00941 
00942     if (!_dbus_string_init (&str))
00943       _dbus_assert_not_reached ("no memory");
00944 
00945     if (!_dbus_string_append (&str, lower_string))
00946       _dbus_assert_not_reached ("no memory");
00947 
00948     _dbus_string_toupper_ascii (&str, 0, _dbus_string_get_length(&str));
00949 
00950     if (!_dbus_string_equal_c_str (&str, upper_string))
00951       _dbus_assert_not_reached ("_dbus_string_toupper_ascii failed");
00952 
00953     _dbus_string_free (&str);
00954 
00955     if (!_dbus_string_init (&str))
00956       _dbus_assert_not_reached ("no memory");
00957 
00958     if (!_dbus_string_append (&str, lower_string))
00959       _dbus_assert_not_reached ("no memory");
00960 
00961     _dbus_string_toupper_ascii (&str, 0, 7);
00962 
00963     if (!_dbus_string_equal_c_str (&str, upper2_string))
00964       _dbus_assert_not_reached ("_dbus_string_toupper_ascii failed in partial conversion");
00965 
00966     _dbus_string_free (&str);
00967   }
00968 
00969   return TRUE;
00970 }
00971 
00972 #endif /* DBUS_BUILD_TESTS */