Home | History | Annotate | Download | only in dbus
      1 /* -*- mode: C; c-file-style: "gnu" -*- */
      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  *
      6  * Licensed under the Academic Free License version 2.1
      7  *
      8  * This program is free software; you can redistribute it and/or modify
      9  * it under the terms of the GNU General Public License as published by
     10  * the Free Software Foundation; either version 2 of the License, or
     11  * (at your option) any later version.
     12  *
     13  * This program is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  * GNU General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU General Public License
     19  * along with this program; if not, write to the Free Software
     20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     21  *
     22  */
     23 
     24 #include "dbus-internals.h"
     25 #include "dbus-string.h"
     26 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
     27 #include "dbus-string-private.h"
     28 
     29 /**
     30  * @addtogroup DBusString
     31  * @{
     32  */
     33 
     34 /**
     35  * Returns whether a string ends with the given suffix
     36  *
     37  * @todo memcmp might make this faster.
     38  *
     39  * @param a the string
     40  * @param c_str the C-style string
     41  * @returns #TRUE if the string ends with the suffix
     42  */
     43 dbus_bool_t
     44 _dbus_string_ends_with_c_str (const DBusString *a,
     45                               const char       *c_str)
     46 {
     47   const unsigned char *ap;
     48   const unsigned char *bp;
     49   const unsigned char *a_end;
     50   unsigned long c_str_len;
     51   const DBusRealString *real_a = (const DBusRealString*) a;
     52   DBUS_GENERIC_STRING_PREAMBLE (real_a);
     53   _dbus_assert (c_str != NULL);
     54 
     55   c_str_len = strlen (c_str);
     56   if (((unsigned long)real_a->len) < c_str_len)
     57     return FALSE;
     58 
     59   ap = real_a->str + (real_a->len - c_str_len);
     60   bp = (const unsigned char*) c_str;
     61   a_end = real_a->str + real_a->len;
     62   while (ap != a_end)
     63     {
     64       if (*ap != *bp)
     65         return FALSE;
     66 
     67       ++ap;
     68       ++bp;
     69     }
     70 
     71   _dbus_assert (*ap == '\0');
     72   _dbus_assert (*bp == '\0');
     73 
     74   return TRUE;
     75 }
     76 
     77 /**
     78  * Find the given byte scanning backward from the given start.
     79  * Sets *found to -1 if the byte is not found.
     80  *
     81  * @param str the string
     82  * @param start the place to start scanning (will not find the byte at this point)
     83  * @param byte the byte to find
     84  * @param found return location for where it was found
     85  * @returns #TRUE if found
     86  */
     87 dbus_bool_t
     88 _dbus_string_find_byte_backward (const DBusString  *str,
     89                                  int                start,
     90                                  unsigned char      byte,
     91                                  int               *found)
     92 {
     93   int i;
     94   DBUS_CONST_STRING_PREAMBLE (str);
     95   _dbus_assert (start <= real->len);
     96   _dbus_assert (start >= 0);
     97   _dbus_assert (found != NULL);
     98 
     99   i = start - 1;
    100   while (i >= 0)
    101     {
    102       if (real->str[i] == byte)
    103         break;
    104 
    105       --i;
    106     }
    107 
    108   if (found)
    109     *found = i;
    110 
    111   return i >= 0;
    112 }
    113 
    114 /** @} */
    115 
    116 #ifdef DBUS_BUILD_TESTS
    117 #include "dbus-test.h"
    118 #include <stdio.h>
    119 
    120 static void
    121 test_max_len (DBusString *str,
    122               int         max_len)
    123 {
    124   if (max_len > 0)
    125     {
    126       if (!_dbus_string_set_length (str, max_len - 1))
    127         _dbus_assert_not_reached ("setting len to one less than max should have worked");
    128     }
    129 
    130   if (!_dbus_string_set_length (str, max_len))
    131     _dbus_assert_not_reached ("setting len to max len should have worked");
    132 
    133   if (_dbus_string_set_length (str, max_len + 1))
    134     _dbus_assert_not_reached ("setting len to one more than max len should not have worked");
    135 
    136   if (!_dbus_string_set_length (str, 0))
    137     _dbus_assert_not_reached ("setting len to zero should have worked");
    138 }
    139 
    140 static void
    141 test_hex_roundtrip (const unsigned char *data,
    142                     int                  len)
    143 {
    144   DBusString orig;
    145   DBusString encoded;
    146   DBusString decoded;
    147   int end;
    148 
    149   if (len < 0)
    150     len = strlen (data);
    151 
    152   if (!_dbus_string_init (&orig))
    153     _dbus_assert_not_reached ("could not init string");
    154 
    155   if (!_dbus_string_init (&encoded))
    156     _dbus_assert_not_reached ("could not init string");
    157 
    158   if (!_dbus_string_init (&decoded))
    159     _dbus_assert_not_reached ("could not init string");
    160 
    161   if (!_dbus_string_append_len (&orig, data, len))
    162     _dbus_assert_not_reached ("couldn't append orig data");
    163 
    164   if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))
    165     _dbus_assert_not_reached ("could not encode");
    166 
    167   if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0))
    168     _dbus_assert_not_reached ("could not decode");
    169 
    170   _dbus_assert (_dbus_string_get_length (&encoded) == end);
    171 
    172   if (!_dbus_string_equal (&orig, &decoded))
    173     {
    174       const char *s;
    175 
    176       printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
    177               _dbus_string_get_length (&orig),
    178               _dbus_string_get_length (&encoded),
    179               _dbus_string_get_length (&decoded));
    180       printf ("Original: %s\n", data);
    181       s = _dbus_string_get_const_data (&decoded);
    182       printf ("Decoded: %s\n", s);
    183       _dbus_assert_not_reached ("original string not the same as string decoded from hex");
    184     }
    185 
    186   _dbus_string_free (&orig);
    187   _dbus_string_free (&encoded);
    188   _dbus_string_free (&decoded);
    189 }
    190 
    191 typedef void (* TestRoundtripFunc) (const unsigned char *data,
    192                                     int                  len);
    193 static void
    194 test_roundtrips (TestRoundtripFunc func)
    195 {
    196   (* func) ("Hello this is a string\n", -1);
    197   (* func) ("Hello this is a string\n1", -1);
    198   (* func) ("Hello this is a string\n12", -1);
    199   (* func) ("Hello this is a string\n123", -1);
    200   (* func) ("Hello this is a string\n1234", -1);
    201   (* func) ("Hello this is a string\n12345", -1);
    202   (* func) ("", 0);
    203   (* func) ("1", 1);
    204   (* func) ("12", 2);
    205   (* func) ("123", 3);
    206   (* func) ("1234", 4);
    207   (* func) ("12345", 5);
    208   (* func) ("", 1);
    209   (* func) ("1", 2);
    210   (* func) ("12", 3);
    211   (* func) ("123", 4);
    212   (* func) ("1234", 5);
    213   (* func) ("12345", 6);
    214   {
    215     unsigned char buf[512];
    216     int i;
    217 
    218     i = 0;
    219     while (i < _DBUS_N_ELEMENTS (buf))
    220       {
    221         buf[i] = i;
    222         ++i;
    223       }
    224     i = 0;
    225     while (i < _DBUS_N_ELEMENTS (buf))
    226       {
    227         (* func) (buf, i);
    228         ++i;
    229       }
    230   }
    231 }
    232 
    233 #ifdef DBUS_BUILD_TESTS
    234 /* The max length thing is sort of a historical artifact
    235  * from a feature that turned out to be dumb; perhaps
    236  * we should purge it entirely. The problem with
    237  * the feature is that it looks like memory allocation
    238  * failure, but is not a transient or resolvable failure.
    239  */
    240 static void
    241 set_max_length (DBusString *str,
    242                 int         max_length)
    243 {
    244   DBusRealString *real;
    245 
    246   real = (DBusRealString*) str;
    247 
    248   real->max_length = max_length;
    249 }
    250 #endif /* DBUS_BUILD_TESTS */
    251 
    252 /**
    253  * @ingroup DBusStringInternals
    254  * Unit test for DBusString.
    255  *
    256  * @todo Need to write tests for _dbus_string_copy() and
    257  * _dbus_string_move() moving to/from each of start/middle/end of a
    258  * string. Also need tests for _dbus_string_move_len ()
    259  *
    260  * @returns #TRUE on success.
    261  */
    262 dbus_bool_t
    263 _dbus_string_test (void)
    264 {
    265   DBusString str;
    266   DBusString other;
    267   int i, end;
    268   long v;
    269   double d;
    270   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 };
    271   char *s;
    272   dbus_unichar_t ch;
    273 
    274   i = 0;
    275   while (i < _DBUS_N_ELEMENTS (lens))
    276     {
    277       if (!_dbus_string_init (&str))
    278         _dbus_assert_not_reached ("failed to init string");
    279 
    280       set_max_length (&str, lens[i]);
    281 
    282       test_max_len (&str, lens[i]);
    283       _dbus_string_free (&str);
    284 
    285       ++i;
    286     }
    287 
    288   /* Test shortening and setting length */
    289   i = 0;
    290   while (i < _DBUS_N_ELEMENTS (lens))
    291     {
    292       int j;
    293 
    294       if (!_dbus_string_init (&str))
    295         _dbus_assert_not_reached ("failed to init string");
    296 
    297       set_max_length (&str, lens[i]);
    298 
    299       if (!_dbus_string_set_length (&str, lens[i]))
    300         _dbus_assert_not_reached ("failed to set string length");
    301 
    302       j = lens[i];
    303       while (j > 0)
    304         {
    305           _dbus_assert (_dbus_string_get_length (&str) == j);
    306           if (j > 0)
    307             {
    308               _dbus_string_shorten (&str, 1);
    309               _dbus_assert (_dbus_string_get_length (&str) == (j - 1));
    310             }
    311           --j;
    312         }
    313 
    314       _dbus_string_free (&str);
    315 
    316       ++i;
    317     }
    318 
    319   /* Test equality */
    320   if (!_dbus_string_init (&str))
    321     _dbus_assert_not_reached ("oom");
    322 
    323   if (!_dbus_string_append (&str, "Hello World"))
    324     _dbus_assert_not_reached ("oom");
    325 
    326   _dbus_string_init_const (&other, "H");
    327   _dbus_assert (_dbus_string_equal_substring (&str, 0, 1, &other, 0));
    328   _dbus_assert (_dbus_string_equal_substring (&str, 1, 0, &other, 1));
    329   _dbus_string_init_const (&other, "Hello");
    330   _dbus_assert (_dbus_string_equal_substring (&str, 0, 5, &other, 0));
    331   _dbus_assert (_dbus_string_equal_substring (&str, 1, 4, &other, 1));
    332   _dbus_assert (_dbus_string_equal_substring (&str, 2, 3, &other, 2));
    333   _dbus_assert (_dbus_string_equal_substring (&str, 3, 2, &other, 3));
    334   _dbus_assert (_dbus_string_equal_substring (&str, 4, 1, &other, 4));
    335   _dbus_assert (_dbus_string_equal_substring (&str, 5, 0, &other, 5));
    336 
    337   _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 0));
    338   _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 1));
    339   _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 2));
    340   _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 3));
    341   _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 4));
    342   _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 5));
    343 
    344 
    345   _dbus_string_init_const (&other, "World");
    346   _dbus_assert (_dbus_string_equal_substring (&str, 6,  5, &other, 0));
    347   _dbus_assert (_dbus_string_equal_substring (&str, 7,  4, &other, 1));
    348   _dbus_assert (_dbus_string_equal_substring (&str, 8,  3, &other, 2));
    349   _dbus_assert (_dbus_string_equal_substring (&str, 9,  2, &other, 3));
    350   _dbus_assert (_dbus_string_equal_substring (&str, 10, 1, &other, 4));
    351   _dbus_assert (_dbus_string_equal_substring (&str, 11, 0, &other, 5));
    352 
    353   _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 6));
    354   _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 7));
    355   _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 8));
    356   _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 9));
    357   _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 10));
    358   _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 11));
    359 
    360   _dbus_string_free (&str);
    361 
    362   /* Test appending data */
    363   if (!_dbus_string_init (&str))
    364     _dbus_assert_not_reached ("failed to init string");
    365 
    366   i = 0;
    367   while (i < 10)
    368     {
    369       if (!_dbus_string_append (&str, "a"))
    370         _dbus_assert_not_reached ("failed to append string to string\n");
    371 
    372       _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1);
    373 
    374       if (!_dbus_string_append_byte (&str, 'b'))
    375         _dbus_assert_not_reached ("failed to append byte to string\n");
    376 
    377       _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2);
    378 
    379       ++i;
    380     }
    381 
    382   _dbus_string_free (&str);
    383 
    384   /* Check steal_data */
    385 
    386   if (!_dbus_string_init (&str))
    387     _dbus_assert_not_reached ("failed to init string");
    388 
    389   if (!_dbus_string_append (&str, "Hello World"))
    390     _dbus_assert_not_reached ("could not append to string");
    391 
    392   i = _dbus_string_get_length (&str);
    393 
    394   if (!_dbus_string_steal_data (&str, &s))
    395     _dbus_assert_not_reached ("failed to steal data");
    396 
    397   _dbus_assert (_dbus_string_get_length (&str) == 0);
    398   _dbus_assert (((int)strlen (s)) == i);
    399 
    400   dbus_free (s);
    401 
    402   /* Check move */
    403 
    404   if (!_dbus_string_append (&str, "Hello World"))
    405     _dbus_assert_not_reached ("could not append to string");
    406 
    407   i = _dbus_string_get_length (&str);
    408 
    409   if (!_dbus_string_init (&other))
    410     _dbus_assert_not_reached ("could not init string");
    411 
    412   if (!_dbus_string_move (&str, 0, &other, 0))
    413     _dbus_assert_not_reached ("could not move");
    414 
    415   _dbus_assert (_dbus_string_get_length (&str) == 0);
    416   _dbus_assert (_dbus_string_get_length (&other) == i);
    417 
    418   if (!_dbus_string_append (&str, "Hello World"))
    419     _dbus_assert_not_reached ("could not append to string");
    420 
    421   if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other)))
    422     _dbus_assert_not_reached ("could not move");
    423 
    424   _dbus_assert (_dbus_string_get_length (&str) == 0);
    425   _dbus_assert (_dbus_string_get_length (&other) == i * 2);
    426 
    427     if (!_dbus_string_append (&str, "Hello World"))
    428     _dbus_assert_not_reached ("could not append to string");
    429 
    430   if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2))
    431     _dbus_assert_not_reached ("could not move");
    432 
    433   _dbus_assert (_dbus_string_get_length (&str) == 0);
    434   _dbus_assert (_dbus_string_get_length (&other) == i * 3);
    435 
    436   _dbus_string_free (&other);
    437 
    438   /* Check copy */
    439 
    440   if (!_dbus_string_append (&str, "Hello World"))
    441     _dbus_assert_not_reached ("could not append to string");
    442 
    443   i = _dbus_string_get_length (&str);
    444 
    445   if (!_dbus_string_init (&other))
    446     _dbus_assert_not_reached ("could not init string");
    447 
    448   if (!_dbus_string_copy (&str, 0, &other, 0))
    449     _dbus_assert_not_reached ("could not copy");
    450 
    451   _dbus_assert (_dbus_string_get_length (&str) == i);
    452   _dbus_assert (_dbus_string_get_length (&other) == i);
    453 
    454   if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other)))
    455     _dbus_assert_not_reached ("could not copy");
    456 
    457   _dbus_assert (_dbus_string_get_length (&str) == i);
    458   _dbus_assert (_dbus_string_get_length (&other) == i * 2);
    459   _dbus_assert (_dbus_string_equal_c_str (&other,
    460                                           "Hello WorldHello World"));
    461 
    462   if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2))
    463     _dbus_assert_not_reached ("could not copy");
    464 
    465   _dbus_assert (_dbus_string_get_length (&str) == i);
    466   _dbus_assert (_dbus_string_get_length (&other) == i * 3);
    467   _dbus_assert (_dbus_string_equal_c_str (&other,
    468                                           "Hello WorldHello WorldHello World"));
    469 
    470   _dbus_string_free (&str);
    471   _dbus_string_free (&other);
    472 
    473   /* Check replace */
    474 
    475   if (!_dbus_string_init (&str))
    476     _dbus_assert_not_reached ("failed to init string");
    477 
    478   if (!_dbus_string_append (&str, "Hello World"))
    479     _dbus_assert_not_reached ("could not append to string");
    480 
    481   i = _dbus_string_get_length (&str);
    482 
    483   if (!_dbus_string_init (&other))
    484     _dbus_assert_not_reached ("could not init string");
    485 
    486   if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
    487                                  &other, 0, _dbus_string_get_length (&other)))
    488     _dbus_assert_not_reached ("could not replace");
    489 
    490   _dbus_assert (_dbus_string_get_length (&str) == i);
    491   _dbus_assert (_dbus_string_get_length (&other) == i);
    492   _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World"));
    493 
    494   if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
    495                                  &other, 5, 1))
    496     _dbus_assert_not_reached ("could not replace center space");
    497 
    498   _dbus_assert (_dbus_string_get_length (&str) == i);
    499   _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
    500   _dbus_assert (_dbus_string_equal_c_str (&other,
    501                                           "HelloHello WorldWorld"));
    502 
    503 
    504   if (!_dbus_string_replace_len (&str, 1, 1,
    505                                  &other,
    506                                  _dbus_string_get_length (&other) - 1,
    507                                  1))
    508     _dbus_assert_not_reached ("could not replace end character");
    509 
    510   _dbus_assert (_dbus_string_get_length (&str) == i);
    511   _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
    512   _dbus_assert (_dbus_string_equal_c_str (&other,
    513                                           "HelloHello WorldWorle"));
    514 
    515   _dbus_string_free (&str);
    516   _dbus_string_free (&other);
    517 
    518   /* Check append/get unichar */
    519 
    520   if (!_dbus_string_init (&str))
    521     _dbus_assert_not_reached ("failed to init string");
    522 
    523   ch = 0;
    524   if (!_dbus_string_append_unichar (&str, 0xfffc))
    525     _dbus_assert_not_reached ("failed to append unichar");
    526 
    527   _dbus_string_get_unichar (&str, 0, &ch, &i);
    528 
    529   _dbus_assert (ch == 0xfffc);
    530   _dbus_assert (i == _dbus_string_get_length (&str));
    531 
    532   _dbus_string_free (&str);
    533 
    534   /* Check insert/set/get byte */
    535 
    536   if (!_dbus_string_init (&str))
    537     _dbus_assert_not_reached ("failed to init string");
    538 
    539   if (!_dbus_string_append (&str, "Hello"))
    540     _dbus_assert_not_reached ("failed to append Hello");
    541 
    542   _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H');
    543   _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e');
    544   _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l');
    545   _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l');
    546   _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o');
    547 
    548   _dbus_string_set_byte (&str, 1, 'q');
    549   _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');
    550 
    551   if (!_dbus_string_insert_bytes (&str, 0, 1, 255))
    552     _dbus_assert_not_reached ("can't insert byte");
    553 
    554   if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z'))
    555     _dbus_assert_not_reached ("can't insert byte");
    556 
    557   if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W'))
    558     _dbus_assert_not_reached ("can't insert byte");
    559 
    560   _dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
    561   _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
    562   _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
    563   _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z');
    564   _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z');
    565   _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z');
    566   _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q');
    567   _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l');
    568   _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l');
    569   _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o');
    570   _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W');
    571 
    572   _dbus_string_free (&str);
    573 
    574   /* Check append/parse int/double */
    575 
    576   if (!_dbus_string_init (&str))
    577     _dbus_assert_not_reached ("failed to init string");
    578 
    579   if (!_dbus_string_append_int (&str, 27))
    580     _dbus_assert_not_reached ("failed to append int");
    581 
    582   i = _dbus_string_get_length (&str);
    583 
    584   if (!_dbus_string_parse_int (&str, 0, &v, &end))
    585     _dbus_assert_not_reached ("failed to parse int");
    586 
    587   _dbus_assert (v == 27);
    588   _dbus_assert (end == i);
    589 
    590   _dbus_string_free (&str);
    591 
    592   if (!_dbus_string_init (&str))
    593     _dbus_assert_not_reached ("failed to init string");
    594 
    595   if (!_dbus_string_append_double (&str, 50.3))
    596     _dbus_assert_not_reached ("failed to append float");
    597 
    598   i = _dbus_string_get_length (&str);
    599 
    600   if (!_dbus_string_parse_double (&str, 0, &d, &end))
    601     _dbus_assert_not_reached ("failed to parse float");
    602 
    603   _dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6));
    604   _dbus_assert (end == i);
    605 
    606   _dbus_string_free (&str);
    607 
    608   /* Test find */
    609   if (!_dbus_string_init (&str))
    610     _dbus_assert_not_reached ("failed to init string");
    611 
    612   if (!_dbus_string_append (&str, "Hello"))
    613     _dbus_assert_not_reached ("couldn't append to string");
    614 
    615   if (!_dbus_string_find (&str, 0, "He", &i))
    616     _dbus_assert_not_reached ("didn't find 'He'");
    617   _dbus_assert (i == 0);
    618 
    619   if (!_dbus_string_find (&str, 0, "Hello", &i))
    620     _dbus_assert_not_reached ("didn't find 'Hello'");
    621   _dbus_assert (i == 0);
    622 
    623   if (!_dbus_string_find (&str, 0, "ello", &i))
    624     _dbus_assert_not_reached ("didn't find 'ello'");
    625   _dbus_assert (i == 1);
    626 
    627   if (!_dbus_string_find (&str, 0, "lo", &i))
    628     _dbus_assert_not_reached ("didn't find 'lo'");
    629   _dbus_assert (i == 3);
    630 
    631   if (!_dbus_string_find (&str, 2, "lo", &i))
    632     _dbus_assert_not_reached ("didn't find 'lo'");
    633   _dbus_assert (i == 3);
    634 
    635   if (_dbus_string_find (&str, 4, "lo", &i))
    636     _dbus_assert_not_reached ("did find 'lo'");
    637 
    638   if (!_dbus_string_find (&str, 0, "l", &i))
    639     _dbus_assert_not_reached ("didn't find 'l'");
    640   _dbus_assert (i == 2);
    641 
    642   if (!_dbus_string_find (&str, 0, "H", &i))
    643     _dbus_assert_not_reached ("didn't find 'H'");
    644   _dbus_assert (i == 0);
    645 
    646   if (!_dbus_string_find (&str, 0, "", &i))
    647     _dbus_assert_not_reached ("didn't find ''");
    648   _dbus_assert (i == 0);
    649 
    650   if (_dbus_string_find (&str, 0, "Hello!", NULL))
    651     _dbus_assert_not_reached ("Did find 'Hello!'");
    652 
    653   if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
    654     _dbus_assert_not_reached ("Did find 'Oh, Hello'");
    655 
    656   if (_dbus_string_find (&str, 0, "ill", NULL))
    657     _dbus_assert_not_reached ("Did find 'ill'");
    658 
    659   if (_dbus_string_find (&str, 0, "q", NULL))
    660     _dbus_assert_not_reached ("Did find 'q'");
    661 
    662   if (!_dbus_string_find_to (&str, 0, 2, "He", NULL))
    663     _dbus_assert_not_reached ("Didn't find 'He'");
    664 
    665   if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL))
    666     _dbus_assert_not_reached ("Did find 'Hello'");
    667 
    668   if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i))
    669     _dbus_assert_not_reached ("Did not find 'H'");
    670   _dbus_assert (i == 0);
    671 
    672   if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i))
    673     _dbus_assert_not_reached ("Did not find 'o'");
    674   _dbus_assert (i == _dbus_string_get_length (&str) - 1);
    675 
    676   if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i))
    677     _dbus_assert_not_reached ("Did find 'o'");
    678   _dbus_assert (i == -1);
    679 
    680   if (_dbus_string_find_byte_backward (&str, 1, 'e', &i))
    681     _dbus_assert_not_reached ("Did find 'e'");
    682   _dbus_assert (i == -1);
    683 
    684   if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i))
    685     _dbus_assert_not_reached ("Didn't find 'e'");
    686   _dbus_assert (i == 1);
    687 
    688   _dbus_string_free (&str);
    689 
    690   /* Hex encoding */
    691   _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string");
    692   if (!_dbus_string_init (&other))
    693     _dbus_assert_not_reached ("could not init string");
    694 
    695   if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0))
    696     _dbus_assert_not_reached ("deccoded bogus hex string with no error");
    697 
    698   _dbus_assert (end == 8);
    699 
    700   _dbus_string_free (&other);
    701 
    702   test_roundtrips (test_hex_roundtrip);
    703 
    704   _dbus_string_free (&str);
    705 
    706   return TRUE;
    707 }
    708 
    709 #endif /* DBUS_BUILD_TESTS */
    710