Home | History | Annotate | Download | only in dbus
      1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
      2 /* dbus-string-util.c Would be in dbus-string.c, but not used in libdbus
      3  *
      4  * Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
      5  * Copyright (C) 2006 Ralf Habacker <ralf.habacker (at) freenet.de>
      6  *
      7  * Licensed under the Academic Free License version 2.1
      8  *
      9  * This program is free software; you can redistribute it and/or modify
     10  * it under the terms of the GNU General Public License as published by
     11  * the Free Software Foundation; either version 2 of the License, or
     12  * (at your option) any later version.
     13  *
     14  * This program is distributed in the hope that it will be useful,
     15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17  * GNU General Public License for more details.
     18  *
     19  * You should have received a copy of the GNU General Public License
     20  * along with this program; if not, write to the Free Software
     21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     22  *
     23  */
     24 
     25 #include <config.h>
     26 #include "dbus-internals.h"
     27 #include "dbus-string.h"
     28 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
     29 #include "dbus-string-private.h"
     30 
     31 /**
     32  * @addtogroup DBusString
     33  * @{
     34  */
     35 
     36 /**
     37  * Returns whether a string ends with the given suffix
     38  *
     39  * @todo memcmp might make this faster.
     40  *
     41  * @param a the string
     42  * @param c_str the C-style string
     43  * @returns #TRUE if the string ends with the suffix
     44  */
     45 dbus_bool_t
     46 _dbus_string_ends_with_c_str (const DBusString *a,
     47                               const char       *c_str)
     48 {
     49   const unsigned char *ap;
     50   const unsigned char *bp;
     51   const unsigned char *a_end;
     52   unsigned long c_str_len;
     53   const DBusRealString *real_a = (const DBusRealString*) a;
     54   DBUS_GENERIC_STRING_PREAMBLE (real_a);
     55   _dbus_assert (c_str != NULL);
     56 
     57   c_str_len = strlen (c_str);
     58   if (((unsigned long)real_a->len) < c_str_len)
     59     return FALSE;
     60 
     61   ap = real_a->str + (real_a->len - c_str_len);
     62   bp = (const unsigned char*) c_str;
     63   a_end = real_a->str + real_a->len;
     64   while (ap != a_end)
     65     {
     66       if (*ap != *bp)
     67         return FALSE;
     68 
     69       ++ap;
     70       ++bp;
     71     }
     72 
     73   _dbus_assert (*ap == '\0');
     74   _dbus_assert (*bp == '\0');
     75 
     76   return TRUE;
     77 }
     78 
     79 /**
     80  * Find the given byte scanning backward from the given start.
     81  * Sets *found to -1 if the byte is not found.
     82  *
     83  * @param str the string
     84  * @param start the place to start scanning (will not find the byte at this point)
     85  * @param byte the byte to find
     86  * @param found return location for where it was found
     87  * @returns #TRUE if found
     88  */
     89 dbus_bool_t
     90 _dbus_string_find_byte_backward (const DBusString  *str,
     91                                  int                start,
     92                                  unsigned char      byte,
     93                                  int               *found)
     94 {
     95   int i;
     96   DBUS_CONST_STRING_PREAMBLE (str);
     97   _dbus_assert (start <= real->len);
     98   _dbus_assert (start >= 0);
     99   _dbus_assert (found != NULL);
    100 
    101   i = start - 1;
    102   while (i >= 0)
    103     {
    104       if (real->str[i] == byte)
    105         break;
    106 
    107       --i;
    108     }
    109 
    110   if (found)
    111     *found = i;
    112 
    113   return i >= 0;
    114 }
    115 
    116 /** @} */
    117 
    118 #ifdef DBUS_BUILD_TESTS
    119 #include "dbus-test.h"
    120 #include <stdio.h>
    121 
    122 static void
    123 test_hex_roundtrip (const unsigned char *data,
    124                     int                  len)
    125 {
    126   DBusString orig;
    127   DBusString encoded;
    128   DBusString decoded;
    129   int end;
    130 
    131   if (len < 0)
    132     len = strlen (data);
    133 
    134   if (!_dbus_string_init (&orig))
    135     _dbus_assert_not_reached ("could not init string");
    136 
    137   if (!_dbus_string_init (&encoded))
    138     _dbus_assert_not_reached ("could not init string");
    139 
    140   if (!_dbus_string_init (&decoded))
    141     _dbus_assert_not_reached ("could not init string");
    142 
    143   if (!_dbus_string_append_len (&orig, data, len))
    144     _dbus_assert_not_reached ("couldn't append orig data");
    145 
    146   if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))
    147     _dbus_assert_not_reached ("could not encode");
    148 
    149   if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0))
    150     _dbus_assert_not_reached ("could not decode");
    151 
    152   _dbus_assert (_dbus_string_get_length (&encoded) == end);
    153 
    154   if (!_dbus_string_equal (&orig, &decoded))
    155     {
    156       const char *s;
    157 
    158       printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
    159               _dbus_string_get_length (&orig),
    160               _dbus_string_get_length (&encoded),
    161               _dbus_string_get_length (&decoded));
    162       printf ("Original: %s\n", data);
    163       s = _dbus_string_get_const_data (&decoded);
    164       printf ("Decoded: %s\n", s);
    165       _dbus_assert_not_reached ("original string not the same as string decoded from hex");
    166     }
    167 
    168   _dbus_string_free (&orig);
    169   _dbus_string_free (&encoded);
    170   _dbus_string_free (&decoded);
    171 }
    172 
    173 typedef void (* TestRoundtripFunc) (const unsigned char *data,
    174                                     int                  len);
    175 static void
    176 test_roundtrips (TestRoundtripFunc func)
    177 {
    178   (* func) ("Hello this is a string\n", -1);
    179   (* func) ("Hello this is a string\n1", -1);
    180   (* func) ("Hello this is a string\n12", -1);
    181   (* func) ("Hello this is a string\n123", -1);
    182   (* func) ("Hello this is a string\n1234", -1);
    183   (* func) ("Hello this is a string\n12345", -1);
    184   (* func) ("", 0);
    185   (* func) ("1", 1);
    186   (* func) ("12", 2);
    187   (* func) ("123", 3);
    188   (* func) ("1234", 4);
    189   (* func) ("12345", 5);
    190   (* func) ("", 1);
    191   (* func) ("1", 2);
    192   (* func) ("12", 3);
    193   (* func) ("123", 4);
    194   (* func) ("1234", 5);
    195   (* func) ("12345", 6);
    196   {
    197     unsigned char buf[512];
    198     int i;
    199 
    200     i = 0;
    201     while (i < _DBUS_N_ELEMENTS (buf))
    202       {
    203         buf[i] = i;
    204         ++i;
    205       }
    206     i = 0;
    207     while (i < _DBUS_N_ELEMENTS (buf))
    208       {
    209         (* func) (buf, i);
    210         ++i;
    211       }
    212   }
    213 }
    214 
    215 /**
    216  * @ingroup DBusStringInternals
    217  * Unit test for DBusString.
    218  *
    219  * @todo Need to write tests for _dbus_string_copy() and
    220  * _dbus_string_move() moving to/from each of start/middle/end of a
    221  * string. Also need tests for _dbus_string_move_len ()
    222  *
    223  * @returns #TRUE on success.
    224  */
    225 dbus_bool_t
    226 _dbus_string_test (void)
    227 {
    228   DBusString str;
    229   DBusString other;
    230   int i, a, end;
    231   long v;
    232   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 };
    233   char *s;
    234 
    235   /* Test shortening and setting length */
    236   i = 0;
    237   while (i < _DBUS_N_ELEMENTS (lens))
    238     {
    239       int j;
    240 
    241       if (!_dbus_string_init (&str))
    242         _dbus_assert_not_reached ("failed to init string");
    243 
    244       if (!_dbus_string_set_length (&str, lens[i]))
    245         _dbus_assert_not_reached ("failed to set string length");
    246 
    247       j = lens[i];
    248       while (j > 0)
    249         {
    250           _dbus_assert (_dbus_string_get_length (&str) == j);
    251           if (j > 0)
    252             {
    253               _dbus_string_shorten (&str, 1);
    254               _dbus_assert (_dbus_string_get_length (&str) == (j - 1));
    255             }
    256           --j;
    257         }
    258 
    259       _dbus_string_free (&str);
    260 
    261       ++i;
    262     }
    263 
    264   /* Test equality */
    265   if (!_dbus_string_init (&str))
    266     _dbus_assert_not_reached ("oom");
    267 
    268   if (!_dbus_string_append (&str, "Hello World"))
    269     _dbus_assert_not_reached ("oom");
    270 
    271   _dbus_string_init_const (&other, "H");
    272   _dbus_assert (_dbus_string_equal_substring (&str, 0, 1, &other, 0));
    273   _dbus_assert (_dbus_string_equal_substring (&str, 1, 0, &other, 1));
    274   _dbus_string_init_const (&other, "Hello");
    275   _dbus_assert (_dbus_string_equal_substring (&str, 0, 5, &other, 0));
    276   _dbus_assert (_dbus_string_equal_substring (&str, 1, 4, &other, 1));
    277   _dbus_assert (_dbus_string_equal_substring (&str, 2, 3, &other, 2));
    278   _dbus_assert (_dbus_string_equal_substring (&str, 3, 2, &other, 3));
    279   _dbus_assert (_dbus_string_equal_substring (&str, 4, 1, &other, 4));
    280   _dbus_assert (_dbus_string_equal_substring (&str, 5, 0, &other, 5));
    281 
    282   _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 0));
    283   _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 1));
    284   _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 2));
    285   _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 3));
    286   _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 4));
    287   _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 5));
    288 
    289 
    290   _dbus_string_init_const (&other, "World");
    291   _dbus_assert (_dbus_string_equal_substring (&str, 6,  5, &other, 0));
    292   _dbus_assert (_dbus_string_equal_substring (&str, 7,  4, &other, 1));
    293   _dbus_assert (_dbus_string_equal_substring (&str, 8,  3, &other, 2));
    294   _dbus_assert (_dbus_string_equal_substring (&str, 9,  2, &other, 3));
    295   _dbus_assert (_dbus_string_equal_substring (&str, 10, 1, &other, 4));
    296   _dbus_assert (_dbus_string_equal_substring (&str, 11, 0, &other, 5));
    297 
    298   _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 6));
    299   _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 7));
    300   _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 8));
    301   _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 9));
    302   _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 10));
    303   _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 11));
    304 
    305   _dbus_string_free (&str);
    306 
    307   /* Test appending data */
    308   if (!_dbus_string_init (&str))
    309     _dbus_assert_not_reached ("failed to init string");
    310 
    311   i = 0;
    312   while (i < 10)
    313     {
    314       if (!_dbus_string_append (&str, "a"))
    315         _dbus_assert_not_reached ("failed to append string to string\n");
    316 
    317       _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1);
    318 
    319       if (!_dbus_string_append_byte (&str, 'b'))
    320         _dbus_assert_not_reached ("failed to append byte to string\n");
    321 
    322       _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2);
    323 
    324       ++i;
    325     }
    326 
    327   _dbus_string_free (&str);
    328 
    329   /* Check steal_data */
    330 
    331   if (!_dbus_string_init (&str))
    332     _dbus_assert_not_reached ("failed to init string");
    333 
    334   if (!_dbus_string_append (&str, "Hello World"))
    335     _dbus_assert_not_reached ("could not append to string");
    336 
    337   i = _dbus_string_get_length (&str);
    338 
    339   if (!_dbus_string_steal_data (&str, &s))
    340     _dbus_assert_not_reached ("failed to steal data");
    341 
    342   _dbus_assert (_dbus_string_get_length (&str) == 0);
    343   _dbus_assert (((int)strlen (s)) == i);
    344 
    345   dbus_free (s);
    346 
    347   /* Check move */
    348 
    349   if (!_dbus_string_append (&str, "Hello World"))
    350     _dbus_assert_not_reached ("could not append to string");
    351 
    352   i = _dbus_string_get_length (&str);
    353 
    354   if (!_dbus_string_init (&other))
    355     _dbus_assert_not_reached ("could not init string");
    356 
    357   if (!_dbus_string_move (&str, 0, &other, 0))
    358     _dbus_assert_not_reached ("could not move");
    359 
    360   _dbus_assert (_dbus_string_get_length (&str) == 0);
    361   _dbus_assert (_dbus_string_get_length (&other) == i);
    362 
    363   if (!_dbus_string_append (&str, "Hello World"))
    364     _dbus_assert_not_reached ("could not append to string");
    365 
    366   if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other)))
    367     _dbus_assert_not_reached ("could not move");
    368 
    369   _dbus_assert (_dbus_string_get_length (&str) == 0);
    370   _dbus_assert (_dbus_string_get_length (&other) == i * 2);
    371 
    372     if (!_dbus_string_append (&str, "Hello World"))
    373     _dbus_assert_not_reached ("could not append to string");
    374 
    375   if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2))
    376     _dbus_assert_not_reached ("could not move");
    377 
    378   _dbus_assert (_dbus_string_get_length (&str) == 0);
    379   _dbus_assert (_dbus_string_get_length (&other) == i * 3);
    380 
    381   _dbus_string_free (&other);
    382 
    383   /* Check copy */
    384 
    385   if (!_dbus_string_append (&str, "Hello World"))
    386     _dbus_assert_not_reached ("could not append to string");
    387 
    388   i = _dbus_string_get_length (&str);
    389 
    390   if (!_dbus_string_init (&other))
    391     _dbus_assert_not_reached ("could not init string");
    392 
    393   if (!_dbus_string_copy (&str, 0, &other, 0))
    394     _dbus_assert_not_reached ("could not copy");
    395 
    396   _dbus_assert (_dbus_string_get_length (&str) == i);
    397   _dbus_assert (_dbus_string_get_length (&other) == i);
    398 
    399   if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other)))
    400     _dbus_assert_not_reached ("could not copy");
    401 
    402   _dbus_assert (_dbus_string_get_length (&str) == i);
    403   _dbus_assert (_dbus_string_get_length (&other) == i * 2);
    404   _dbus_assert (_dbus_string_equal_c_str (&other,
    405                                           "Hello WorldHello World"));
    406 
    407   if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2))
    408     _dbus_assert_not_reached ("could not copy");
    409 
    410   _dbus_assert (_dbus_string_get_length (&str) == i);
    411   _dbus_assert (_dbus_string_get_length (&other) == i * 3);
    412   _dbus_assert (_dbus_string_equal_c_str (&other,
    413                                           "Hello WorldHello WorldHello World"));
    414 
    415   _dbus_string_free (&str);
    416   _dbus_string_free (&other);
    417 
    418   /* Check replace */
    419 
    420   if (!_dbus_string_init (&str))
    421     _dbus_assert_not_reached ("failed to init string");
    422 
    423   if (!_dbus_string_append (&str, "Hello World"))
    424     _dbus_assert_not_reached ("could not append to string");
    425 
    426   i = _dbus_string_get_length (&str);
    427 
    428   if (!_dbus_string_init (&other))
    429     _dbus_assert_not_reached ("could not init string");
    430 
    431   if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
    432                                  &other, 0, _dbus_string_get_length (&other)))
    433     _dbus_assert_not_reached ("could not replace");
    434 
    435   _dbus_assert (_dbus_string_get_length (&str) == i);
    436   _dbus_assert (_dbus_string_get_length (&other) == i);
    437   _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World"));
    438 
    439   if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
    440                                  &other, 5, 1))
    441     _dbus_assert_not_reached ("could not replace center space");
    442 
    443   _dbus_assert (_dbus_string_get_length (&str) == i);
    444   _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
    445   _dbus_assert (_dbus_string_equal_c_str (&other,
    446                                           "HelloHello WorldWorld"));
    447 
    448 
    449   if (!_dbus_string_replace_len (&str, 1, 1,
    450                                  &other,
    451                                  _dbus_string_get_length (&other) - 1,
    452                                  1))
    453     _dbus_assert_not_reached ("could not replace end character");
    454 
    455   _dbus_assert (_dbus_string_get_length (&str) == i);
    456   _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
    457   _dbus_assert (_dbus_string_equal_c_str (&other,
    458                                           "HelloHello WorldWorle"));
    459 
    460   _dbus_string_free (&str);
    461   _dbus_string_free (&other);
    462 
    463   /* Different tests are provided because different behaviours are
    464    * implemented in _dbus_string_replace_len() in function of replacing and
    465    * replaced lengths
    466    */
    467 
    468   if (!_dbus_string_init (&str))
    469     _dbus_assert_not_reached ("failed to init string");
    470 
    471   if (!_dbus_string_append (&str, "Hello World"))
    472     _dbus_assert_not_reached ("could not append to string");
    473 
    474   i = _dbus_string_get_length (&str);
    475 
    476   if (!_dbus_string_init (&other))
    477     _dbus_assert_not_reached ("could not init string");
    478 
    479   if (!_dbus_string_append (&other, "Foo String"))
    480     _dbus_assert_not_reached ("could not append to string");
    481 
    482   a = _dbus_string_get_length (&other);
    483 
    484   if (!_dbus_string_replace_len (&str, 0, 6,
    485                                  &other, 4, 0))
    486     _dbus_assert_not_reached ("could not replace 0 length");
    487 
    488   _dbus_assert (_dbus_string_get_length (&str) == i);
    489   _dbus_assert (_dbus_string_get_length (&other) == a + 6);
    490   _dbus_assert (_dbus_string_equal_c_str (&other,
    491                                           "Foo Hello String"));
    492 
    493   if (!_dbus_string_replace_len (&str, 5, 6,
    494                                  &other,
    495                                  _dbus_string_get_length (&other),
    496                                  0))
    497     _dbus_assert_not_reached ("could not replace at the end");
    498 
    499   _dbus_assert (_dbus_string_get_length (&str) == i);
    500   _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6);
    501   _dbus_assert (_dbus_string_equal_c_str (&other,
    502                                           "Foo Hello String World"));
    503 
    504   if (!_dbus_string_replace_len (&str, 0, 5,
    505                                  &other,
    506                                  _dbus_string_get_length (&other) - 5,
    507                                  5))
    508     _dbus_assert_not_reached ("could not replace same length");
    509 
    510   _dbus_assert (_dbus_string_get_length (&str) == i);
    511   _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6);
    512   _dbus_assert (_dbus_string_equal_c_str (&other,
    513                                           "Foo Hello String Hello"));
    514 
    515   if (!_dbus_string_replace_len (&str, 6, 5,
    516                                  &other, 4, 12))
    517     _dbus_assert_not_reached ("could not replace with shorter string");
    518 
    519   _dbus_assert (_dbus_string_get_length (&str) == i);
    520   _dbus_assert (_dbus_string_get_length (&other) == a + 5);
    521   _dbus_assert (_dbus_string_equal_c_str (&other,
    522                                           "Foo World Hello"));
    523 
    524   if (!_dbus_string_replace_len (&str, 0, 1,
    525                                  &other, 0, 3))
    526     _dbus_assert_not_reached ("could not replace at the beginning");
    527 
    528   _dbus_assert (_dbus_string_get_length (&str) == i);
    529   _dbus_assert (_dbus_string_get_length (&other) == a + 3);
    530   _dbus_assert (_dbus_string_equal_c_str (&other,
    531                                           "H World Hello"));
    532 
    533   if (!_dbus_string_replace_len (&str, 6, 5,
    534                                  &other,
    535                                  _dbus_string_get_length (&other) - 5,
    536                                  5))
    537     _dbus_assert_not_reached ("could not replace same length");
    538 
    539   _dbus_assert (_dbus_string_get_length (&str) == i);
    540   _dbus_assert (_dbus_string_get_length (&other) == a + 3);
    541   _dbus_assert (_dbus_string_equal_c_str (&other,
    542                                           "H World World"));
    543 
    544   _dbus_string_free (&str);
    545   _dbus_string_free (&other);
    546 
    547   /* Check insert/set/get byte */
    548 
    549   if (!_dbus_string_init (&str))
    550     _dbus_assert_not_reached ("failed to init string");
    551 
    552   if (!_dbus_string_append (&str, "Hello"))
    553     _dbus_assert_not_reached ("failed to append Hello");
    554 
    555   _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H');
    556   _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e');
    557   _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l');
    558   _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l');
    559   _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o');
    560 
    561   _dbus_string_set_byte (&str, 1, 'q');
    562   _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');
    563 
    564   if (!_dbus_string_insert_bytes (&str, 0, 1, 255))
    565     _dbus_assert_not_reached ("can't insert byte");
    566 
    567   if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z'))
    568     _dbus_assert_not_reached ("can't insert byte");
    569 
    570   if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W'))
    571     _dbus_assert_not_reached ("can't insert byte");
    572 
    573   _dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
    574   _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
    575   _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
    576   _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z');
    577   _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z');
    578   _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z');
    579   _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q');
    580   _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l');
    581   _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l');
    582   _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o');
    583   _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W');
    584 
    585   _dbus_string_free (&str);
    586 
    587   /* Check append/parse int/double */
    588 
    589   if (!_dbus_string_init (&str))
    590     _dbus_assert_not_reached ("failed to init string");
    591 
    592   if (!_dbus_string_append_int (&str, 27))
    593     _dbus_assert_not_reached ("failed to append int");
    594 
    595   i = _dbus_string_get_length (&str);
    596 
    597   if (!_dbus_string_parse_int (&str, 0, &v, &end))
    598     _dbus_assert_not_reached ("failed to parse int");
    599 
    600   _dbus_assert (v == 27);
    601   _dbus_assert (end == i);
    602 
    603   _dbus_string_free (&str);
    604 
    605   /* Test find */
    606   if (!_dbus_string_init (&str))
    607     _dbus_assert_not_reached ("failed to init string");
    608 
    609   if (!_dbus_string_append (&str, "Hello"))
    610     _dbus_assert_not_reached ("couldn't append to string");
    611 
    612   if (!_dbus_string_find (&str, 0, "He", &i))
    613     _dbus_assert_not_reached ("didn't find 'He'");
    614   _dbus_assert (i == 0);
    615 
    616   if (!_dbus_string_find (&str, 0, "Hello", &i))
    617     _dbus_assert_not_reached ("didn't find 'Hello'");
    618   _dbus_assert (i == 0);
    619 
    620   if (!_dbus_string_find (&str, 0, "ello", &i))
    621     _dbus_assert_not_reached ("didn't find 'ello'");
    622   _dbus_assert (i == 1);
    623 
    624   if (!_dbus_string_find (&str, 0, "lo", &i))
    625     _dbus_assert_not_reached ("didn't find 'lo'");
    626   _dbus_assert (i == 3);
    627 
    628   if (!_dbus_string_find (&str, 2, "lo", &i))
    629     _dbus_assert_not_reached ("didn't find 'lo'");
    630   _dbus_assert (i == 3);
    631 
    632   if (_dbus_string_find (&str, 4, "lo", &i))
    633     _dbus_assert_not_reached ("did find 'lo'");
    634 
    635   if (!_dbus_string_find (&str, 0, "l", &i))
    636     _dbus_assert_not_reached ("didn't find 'l'");
    637   _dbus_assert (i == 2);
    638 
    639   if (!_dbus_string_find (&str, 0, "H", &i))
    640     _dbus_assert_not_reached ("didn't find 'H'");
    641   _dbus_assert (i == 0);
    642 
    643   if (!_dbus_string_find (&str, 0, "", &i))
    644     _dbus_assert_not_reached ("didn't find ''");
    645   _dbus_assert (i == 0);
    646 
    647   if (_dbus_string_find (&str, 0, "Hello!", NULL))
    648     _dbus_assert_not_reached ("Did find 'Hello!'");
    649 
    650   if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
    651     _dbus_assert_not_reached ("Did find 'Oh, Hello'");
    652 
    653   if (_dbus_string_find (&str, 0, "ill", NULL))
    654     _dbus_assert_not_reached ("Did find 'ill'");
    655 
    656   if (_dbus_string_find (&str, 0, "q", NULL))
    657     _dbus_assert_not_reached ("Did find 'q'");
    658 
    659   if (!_dbus_string_find_to (&str, 0, 2, "He", NULL))
    660     _dbus_assert_not_reached ("Didn't find 'He'");
    661 
    662   if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL))
    663     _dbus_assert_not_reached ("Did find 'Hello'");
    664 
    665   if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i))
    666     _dbus_assert_not_reached ("Did not find 'H'");
    667   _dbus_assert (i == 0);
    668 
    669   if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i))
    670     _dbus_assert_not_reached ("Did not find 'o'");
    671   _dbus_assert (i == _dbus_string_get_length (&str) - 1);
    672 
    673   if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i))
    674     _dbus_assert_not_reached ("Did find 'o'");
    675   _dbus_assert (i == -1);
    676 
    677   if (_dbus_string_find_byte_backward (&str, 1, 'e', &i))
    678     _dbus_assert_not_reached ("Did find 'e'");
    679   _dbus_assert (i == -1);
    680 
    681   if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i))
    682     _dbus_assert_not_reached ("Didn't find 'e'");
    683   _dbus_assert (i == 1);
    684 
    685   _dbus_string_free (&str);
    686 
    687   /* Hex encoding */
    688   _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string");
    689   if (!_dbus_string_init (&other))
    690     _dbus_assert_not_reached ("could not init string");
    691 
    692   if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0))
    693     _dbus_assert_not_reached ("deccoded bogus hex string with no error");
    694 
    695   _dbus_assert (end == 8);
    696 
    697   _dbus_string_free (&other);
    698 
    699   test_roundtrips (test_hex_roundtrip);
    700 
    701   _dbus_string_free (&str);
    702 
    703   {
    704     int found, found_len;
    705 
    706     _dbus_string_init_const (&str, "012\r\n567\n90");
    707 
    708     if (!_dbus_string_find_eol (&str, 0, &found, &found_len) || found != 3 || found_len != 2)
    709       _dbus_assert_not_reached ("Did not find '\\r\\n'");
    710     if (found != 3 || found_len != 2)
    711       _dbus_assert_not_reached ("invalid return values");
    712 
    713     if (!_dbus_string_find_eol (&str, 5, &found, &found_len))
    714       _dbus_assert_not_reached ("Did not find '\\n'");
    715     if (found != 8 || found_len != 1)
    716       _dbus_assert_not_reached ("invalid return values");
    717 
    718     if (_dbus_string_find_eol (&str, 9, &found, &found_len))
    719       _dbus_assert_not_reached ("Found not expected '\\n'");
    720     else if (found != 11 || found_len != 0)
    721       _dbus_assert_not_reached ("invalid return values '\\n'");
    722 
    723     found = -1;
    724     found_len = -1;
    725     _dbus_string_init_const (&str, "");
    726     if (_dbus_string_find_eol (&str, 0, &found, &found_len))
    727       _dbus_assert_not_reached ("found an eol in an empty string");
    728     _dbus_assert (found == 0);
    729     _dbus_assert (found_len == 0);
    730 
    731     found = -1;
    732     found_len = -1;
    733     _dbus_string_init_const (&str, "foobar");
    734     if (_dbus_string_find_eol (&str, 0, &found, &found_len))
    735       _dbus_assert_not_reached ("found eol in string that lacks one");
    736     _dbus_assert (found == 6);
    737     _dbus_assert (found_len == 0);
    738 
    739     found = -1;
    740     found_len = -1;
    741     _dbus_string_init_const (&str, "foobar\n");
    742     if (!_dbus_string_find_eol (&str, 0, &found, &found_len))
    743       _dbus_assert_not_reached ("did not find eol in string that has one at end");
    744     _dbus_assert (found == 6);
    745     _dbus_assert (found_len == 1);
    746   }
    747 
    748   {
    749     DBusString line;
    750 
    751 #define FIRST_LINE "this is a line"
    752 #define SECOND_LINE "this is a second line"
    753     /* third line is empty */
    754 #define THIRD_LINE ""
    755 #define FOURTH_LINE "this is a fourth line"
    756 
    757     if (!_dbus_string_init (&str))
    758       _dbus_assert_not_reached ("no memory");
    759 
    760     if (!_dbus_string_append (&str, FIRST_LINE "\n" SECOND_LINE "\r\n" THIRD_LINE "\n" FOURTH_LINE))
    761       _dbus_assert_not_reached ("no memory");
    762 
    763     if (!_dbus_string_init (&line))
    764       _dbus_assert_not_reached ("no memory");
    765 
    766     if (!_dbus_string_pop_line (&str, &line))
    767       _dbus_assert_not_reached ("failed to pop first line");
    768 
    769     _dbus_assert (_dbus_string_equal_c_str (&line, FIRST_LINE));
    770 
    771     if (!_dbus_string_pop_line (&str, &line))
    772       _dbus_assert_not_reached ("failed to pop second line");
    773 
    774     _dbus_assert (_dbus_string_equal_c_str (&line, SECOND_LINE));
    775 
    776     if (!_dbus_string_pop_line (&str, &line))
    777       _dbus_assert_not_reached ("failed to pop third line");
    778 
    779     _dbus_assert (_dbus_string_equal_c_str (&line, THIRD_LINE));
    780 
    781     if (!_dbus_string_pop_line (&str, &line))
    782       _dbus_assert_not_reached ("failed to pop fourth line");
    783 
    784     _dbus_assert (_dbus_string_equal_c_str (&line, FOURTH_LINE));
    785 
    786     _dbus_string_free (&str);
    787     _dbus_string_free (&line);
    788   }
    789 
    790   {
    791     if (!_dbus_string_init (&str))
    792       _dbus_assert_not_reached ("no memory");
    793 
    794     for (i = 0; i < 10000; i++)
    795       if (!_dbus_string_append (&str, "abcdefghijklmnopqrstuvwxyz"))
    796         _dbus_assert_not_reached ("no memory");
    797 
    798     if (!_dbus_string_set_length (&str, 10))
    799       _dbus_assert_not_reached ("failed to set length");
    800 
    801     /* actually compact */
    802     if (!_dbus_string_compact (&str, 2048))
    803       _dbus_assert_not_reached ("failed to compact after set_length");
    804 
    805     /* peek inside to make sure it worked */
    806     if (((DBusRealString *)&str)->allocated > 30)
    807       _dbus_assert_not_reached ("compacting string didn't do anything");
    808 
    809     if (!_dbus_string_equal_c_str (&str, "abcdefghij"))
    810       _dbus_assert_not_reached ("unexpected content after compact");
    811 
    812     /* compact nothing */
    813     if (!_dbus_string_compact (&str, 2048))
    814       _dbus_assert_not_reached ("failed to compact 2nd time");
    815 
    816     if (!_dbus_string_equal_c_str (&str, "abcdefghij"))
    817       _dbus_assert_not_reached ("unexpected content after 2nd compact");
    818 
    819     /* and make sure it still works...*/
    820     if (!_dbus_string_append (&str, "123456"))
    821       _dbus_assert_not_reached ("failed to append after compact");
    822 
    823     if (!_dbus_string_equal_c_str (&str, "abcdefghij123456"))
    824       _dbus_assert_not_reached ("unexpected content after append");
    825 
    826     /* after growing automatically, this should do nothing */
    827     if (!_dbus_string_compact (&str, 20000))
    828       _dbus_assert_not_reached ("failed to compact after grow");
    829 
    830     /* but this one will do something */
    831     if (!_dbus_string_compact (&str, 0))
    832       _dbus_assert_not_reached ("failed to compact after grow");
    833 
    834     if (!_dbus_string_equal_c_str (&str, "abcdefghij123456"))
    835       _dbus_assert_not_reached ("unexpected content");
    836 
    837     if (!_dbus_string_append (&str, "!@#$%"))
    838       _dbus_assert_not_reached ("failed to append after compact");
    839 
    840     if (!_dbus_string_equal_c_str (&str, "abcdefghij123456!@#$%"))
    841       _dbus_assert_not_reached ("unexpected content");
    842 
    843     _dbus_string_free (&str);
    844   }
    845 
    846   {
    847     const char two_strings[] = "one\ttwo";
    848 
    849     if (!_dbus_string_init (&str))
    850       _dbus_assert_not_reached ("no memory");
    851 
    852     if (!_dbus_string_init (&other))
    853       _dbus_assert_not_reached ("no memory");
    854 
    855     if (!_dbus_string_append (&str, two_strings))
    856       _dbus_assert_not_reached ("no memory");
    857 
    858     if (!_dbus_string_split_on_byte (&str, '\t', &other))
    859       _dbus_assert_not_reached ("no memory or delimiter not found");
    860 
    861     if (strcmp (_dbus_string_get_data (&str), "one") != 0)
    862       _dbus_assert_not_reached ("left side after split on tab is wrong");
    863 
    864     if (strcmp (_dbus_string_get_data (&other), "two") != 0)
    865       _dbus_assert_not_reached ("right side after split on tab is wrong");
    866 
    867     _dbus_string_free (&str);
    868     _dbus_string_free (&other);
    869   }
    870 
    871   {
    872     const char upper_string[] = "TOUPPERSTRING";
    873     const char lower_string[] = "toupperstring";
    874     const char lower2_string[] = "toupperSTRING";
    875 
    876     if (!_dbus_string_init (&str))
    877       _dbus_assert_not_reached ("no memory");
    878 
    879     if (!_dbus_string_append (&str, upper_string))
    880       _dbus_assert_not_reached ("no memory");
    881 
    882     _dbus_string_tolower_ascii (&str, 0, _dbus_string_get_length(&str));
    883 
    884     if (!_dbus_string_equal_c_str (&str, lower_string))
    885       _dbus_assert_not_reached ("_dbus_string_tolower_ascii failed");
    886 
    887     _dbus_string_free (&str);
    888 
    889     if (!_dbus_string_init (&str))
    890       _dbus_assert_not_reached ("no memory");
    891 
    892     if (!_dbus_string_append (&str, upper_string))
    893       _dbus_assert_not_reached ("no memory");
    894 
    895     _dbus_string_tolower_ascii (&str, 0, 7);
    896 
    897     if (!_dbus_string_equal_c_str (&str, lower2_string))
    898       _dbus_assert_not_reached ("_dbus_string_tolower_ascii failed in partial conversion");
    899 
    900     _dbus_string_free (&str);
    901   }
    902 
    903   {
    904     const char lower_string[] = "toupperstring";
    905     const char upper_string[] = "TOUPPERSTRING";
    906     const char upper2_string[] = "TOUPPERstring";
    907 
    908     if (!_dbus_string_init (&str))
    909       _dbus_assert_not_reached ("no memory");
    910 
    911     if (!_dbus_string_append (&str, lower_string))
    912       _dbus_assert_not_reached ("no memory");
    913 
    914     _dbus_string_toupper_ascii (&str, 0, _dbus_string_get_length(&str));
    915 
    916     if (!_dbus_string_equal_c_str (&str, upper_string))
    917       _dbus_assert_not_reached ("_dbus_string_toupper_ascii failed");
    918 
    919     _dbus_string_free (&str);
    920 
    921     if (!_dbus_string_init (&str))
    922       _dbus_assert_not_reached ("no memory");
    923 
    924     if (!_dbus_string_append (&str, lower_string))
    925       _dbus_assert_not_reached ("no memory");
    926 
    927     _dbus_string_toupper_ascii (&str, 0, 7);
    928 
    929     if (!_dbus_string_equal_c_str (&str, upper2_string))
    930       _dbus_assert_not_reached ("_dbus_string_toupper_ascii failed in partial conversion");
    931 
    932     _dbus_string_free (&str);
    933   }
    934 
    935   return TRUE;
    936 }
    937 
    938 #endif /* DBUS_BUILD_TESTS */
    939