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