00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "dbus-internals.h"
00025 #include "dbus-string.h"
00026
00027 #include <string.h>
00028 #include "dbus-marshal.h"
00029 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
00030 #include "dbus-string-private.h"
00031 #include "dbus-protocol.h"
00032
00075 #define ALLOCATION_PADDING 8
00076
00081 #define MAX_MAX_LENGTH (_DBUS_INT_MAX - ALLOCATION_PADDING)
00082
00088 #define DBUS_GENERIC_STRING_PREAMBLE(real) _dbus_assert ((real) != NULL); _dbus_assert (!(real)->invalid); _dbus_assert ((real)->len >= 0); _dbus_assert ((real)->allocated >= 0); _dbus_assert ((real)->max_length >= 0); _dbus_assert ((real)->len <= ((real)->allocated - ALLOCATION_PADDING)); _dbus_assert ((real)->len <= (real)->max_length)
00089
00096 #define DBUS_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \
00097 DBUS_GENERIC_STRING_PREAMBLE (real); \
00098 _dbus_assert (!(real)->constant); \
00099 _dbus_assert (!(real)->locked)
00100
00108 #define DBUS_LOCKED_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \
00109 DBUS_GENERIC_STRING_PREAMBLE (real); \
00110 _dbus_assert (!(real)->constant)
00111
00117 #define DBUS_CONST_STRING_PREAMBLE(str) const DBusRealString *real = (DBusRealString*) str; \
00118 DBUS_GENERIC_STRING_PREAMBLE (real)
00119
00127 static void
00128 fixup_alignment (DBusRealString *real)
00129 {
00130 char *aligned;
00131 char *real_block;
00132 unsigned int old_align_offset;
00133
00134
00135 _dbus_assert (real->len <= real->allocated - ALLOCATION_PADDING);
00136
00137 old_align_offset = real->align_offset;
00138 real_block = real->str - old_align_offset;
00139
00140 aligned = _DBUS_ALIGN_ADDRESS (real_block, 8);
00141
00142 real->align_offset = aligned - real_block;
00143 real->str = aligned;
00144
00145 if (old_align_offset != real->align_offset)
00146 {
00147
00148 memmove (real_block + real->align_offset,
00149 real_block + old_align_offset,
00150 real->len + 1);
00151 }
00152
00153 _dbus_assert (real->align_offset < 8);
00154 _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str);
00155 }
00156
00157 static void
00158 undo_alignment (DBusRealString *real)
00159 {
00160 if (real->align_offset != 0)
00161 {
00162 memmove (real->str - real->align_offset,
00163 real->str,
00164 real->len + 1);
00165
00166 real->str = real->str - real->align_offset;
00167 real->align_offset = 0;
00168 }
00169 }
00170
00180 dbus_bool_t
00181 _dbus_string_init_preallocated (DBusString *str,
00182 int allocate_size)
00183 {
00184 DBusRealString *real;
00185
00186 _dbus_assert (str != NULL);
00187
00188 _dbus_assert (sizeof (DBusString) == sizeof (DBusRealString));
00189
00190 real = (DBusRealString*) str;
00191
00192
00193
00194
00195
00196
00197
00198 real->str = dbus_malloc (ALLOCATION_PADDING + allocate_size);
00199 if (real->str == NULL)
00200 return FALSE;
00201
00202 real->allocated = ALLOCATION_PADDING + allocate_size;
00203 real->len = 0;
00204 real->str[real->len] = '\0';
00205
00206 real->max_length = MAX_MAX_LENGTH;
00207 real->constant = FALSE;
00208 real->locked = FALSE;
00209 real->invalid = FALSE;
00210 real->align_offset = 0;
00211
00212 fixup_alignment (real);
00213
00214 return TRUE;
00215 }
00216
00224 dbus_bool_t
00225 _dbus_string_init (DBusString *str)
00226 {
00227 return _dbus_string_init_preallocated (str, 0);
00228 }
00229
00230
00231
00232
00233
00234
00235
00236 static void
00237 set_max_length (DBusString *str,
00238 int max_length)
00239 {
00240 DBusRealString *real;
00241
00242 real = (DBusRealString*) str;
00243
00244 real->max_length = max_length;
00245 }
00246
00256 void
00257 _dbus_string_init_const (DBusString *str,
00258 const char *value)
00259 {
00260 _dbus_assert (value != NULL);
00261
00262 _dbus_string_init_const_len (str, value,
00263 strlen (value));
00264 }
00265
00276 void
00277 _dbus_string_init_const_len (DBusString *str,
00278 const char *value,
00279 int len)
00280 {
00281 DBusRealString *real;
00282
00283 _dbus_assert (str != NULL);
00284 _dbus_assert (value != NULL);
00285 _dbus_assert (len <= MAX_MAX_LENGTH);
00286 _dbus_assert (len >= 0);
00287
00288 real = (DBusRealString*) str;
00289
00290 real->str = (char*) value;
00291 real->len = len;
00292 real->allocated = real->len + ALLOCATION_PADDING;
00293 real->max_length = real->len + 1;
00294 real->constant = TRUE;
00295 real->invalid = FALSE;
00296
00297
00298
00299
00300 }
00301
00307 void
00308 _dbus_string_free (DBusString *str)
00309 {
00310 DBusRealString *real = (DBusRealString*) str;
00311 DBUS_GENERIC_STRING_PREAMBLE (real);
00312
00313 if (real->constant)
00314 return;
00315 dbus_free (real->str - real->align_offset);
00316
00317 real->invalid = TRUE;
00318 }
00319
00320 #ifdef DBUS_BUILD_TESTS
00321
00322
00323
00333 void
00334 _dbus_string_lock (DBusString *str)
00335 {
00336 DBUS_LOCKED_STRING_PREAMBLE (str);
00337
00338 real->locked = TRUE;
00339
00340
00341
00342
00343 #define MAX_WASTE 48
00344 if (real->allocated - MAX_WASTE > real->len)
00345 {
00346 char *new_str;
00347 int new_allocated;
00348
00349 new_allocated = real->len + ALLOCATION_PADDING;
00350
00351 new_str = dbus_realloc (real->str - real->align_offset,
00352 new_allocated);
00353 if (new_str != NULL)
00354 {
00355 real->str = new_str + real->align_offset;
00356 real->allocated = new_allocated;
00357 fixup_alignment (real);
00358 }
00359 }
00360 }
00361 #endif
00362
00363 static dbus_bool_t
00364 reallocate_for_length (DBusRealString *real,
00365 int new_length)
00366 {
00367 int new_allocated;
00368 char *new_str;
00369
00370
00371
00372
00373 if (real->allocated > (MAX_MAX_LENGTH + ALLOCATION_PADDING) / 2)
00374 new_allocated = MAX_MAX_LENGTH + ALLOCATION_PADDING;
00375 else
00376 new_allocated = real->allocated * 2;
00377
00378
00379
00380
00381 #ifdef DBUS_BUILD_TESTS
00382 new_allocated = 0;
00383
00384
00385 #endif
00386
00387
00388 new_allocated = MAX (new_allocated, new_length + ALLOCATION_PADDING);
00389
00390 _dbus_assert (new_allocated >= real->allocated);
00391 new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
00392 if (new_str == NULL)
00393 return FALSE;
00394
00395 real->str = new_str + real->align_offset;
00396 real->allocated = new_allocated;
00397 fixup_alignment (real);
00398
00399 return TRUE;
00400 }
00401
00402 static dbus_bool_t
00403 set_length (DBusRealString *real,
00404 int new_length)
00405 {
00406
00407
00408
00409 if (new_length > real->max_length)
00410 return FALSE;
00411 else if (new_length > (real->allocated - ALLOCATION_PADDING) &&
00412 !reallocate_for_length (real, new_length))
00413 return FALSE;
00414 else
00415 {
00416 real->len = new_length;
00417 real->str[real->len] = '\0';
00418 return TRUE;
00419 }
00420 }
00421
00422 static dbus_bool_t
00423 open_gap (int len,
00424 DBusRealString *dest,
00425 int insert_at)
00426 {
00427 if (len == 0)
00428 return TRUE;
00429
00430 if (len > dest->max_length - dest->len)
00431 return FALSE;
00432
00433 if (!set_length (dest, dest->len + len))
00434 return FALSE;
00435
00436 memmove (dest->str + insert_at + len,
00437 dest->str + insert_at,
00438 dest->len - len - insert_at);
00439
00440 return TRUE;
00441 }
00442
00454 char*
00455 _dbus_string_get_data (DBusString *str)
00456 {
00457 DBUS_STRING_PREAMBLE (str);
00458
00459 return real->str;
00460 }
00461
00468 const char*
00469 _dbus_string_get_const_data (const DBusString *str)
00470 {
00471 DBUS_CONST_STRING_PREAMBLE (str);
00472
00473 return real->str;
00474 }
00475
00489 char*
00490 _dbus_string_get_data_len (DBusString *str,
00491 int start,
00492 int len)
00493 {
00494 DBUS_STRING_PREAMBLE (str);
00495 _dbus_assert (start >= 0);
00496 _dbus_assert (len >= 0);
00497 _dbus_assert (start <= real->len);
00498 _dbus_assert (len <= real->len - start);
00499
00500 return real->str + start;
00501 }
00502
00511 const char*
00512 _dbus_string_get_const_data_len (const DBusString *str,
00513 int start,
00514 int len)
00515 {
00516 DBUS_CONST_STRING_PREAMBLE (str);
00517 _dbus_assert (start >= 0);
00518 _dbus_assert (len >= 0);
00519 _dbus_assert (start <= real->len);
00520 _dbus_assert (len <= real->len - start);
00521
00522 return real->str + start;
00523 }
00524
00532 void
00533 _dbus_string_set_byte (DBusString *str,
00534 int i,
00535 unsigned char byte)
00536 {
00537 DBUS_STRING_PREAMBLE (str);
00538 _dbus_assert (i < real->len);
00539 _dbus_assert (i >= 0);
00540
00541 real->str[i] = byte;
00542 }
00543
00551 unsigned char
00552 _dbus_string_get_byte (const DBusString *str,
00553 int start)
00554 {
00555 DBUS_CONST_STRING_PREAMBLE (str);
00556 _dbus_assert (start < real->len);
00557 _dbus_assert (start >= 0);
00558
00559 return real->str[start];
00560 }
00561
00570 dbus_bool_t
00571 _dbus_string_insert_byte (DBusString *str,
00572 int i,
00573 unsigned char byte)
00574 {
00575 DBUS_STRING_PREAMBLE (str);
00576 _dbus_assert (i <= real->len);
00577 _dbus_assert (i >= 0);
00578
00579 if (!open_gap (1, real, i))
00580 return FALSE;
00581
00582 real->str[i] = byte;
00583
00584 return TRUE;
00585 }
00586
00597 dbus_bool_t
00598 _dbus_string_steal_data (DBusString *str,
00599 char **data_return)
00600 {
00601 int old_max_length;
00602 DBUS_STRING_PREAMBLE (str);
00603 _dbus_assert (data_return != NULL);
00604
00605 undo_alignment (real);
00606
00607 *data_return = real->str;
00608
00609 old_max_length = real->max_length;
00610
00611
00612 if (!_dbus_string_init (str))
00613 {
00614
00615 real->str = *data_return;
00616 *data_return = NULL;
00617 fixup_alignment (real);
00618 return FALSE;
00619 }
00620
00621 real->max_length = old_max_length;
00622
00623 return TRUE;
00624 }
00625
00641 dbus_bool_t
00642 _dbus_string_steal_data_len (DBusString *str,
00643 char **data_return,
00644 int start,
00645 int len)
00646 {
00647 DBusString dest;
00648 DBUS_STRING_PREAMBLE (str);
00649 _dbus_assert (data_return != NULL);
00650 _dbus_assert (start >= 0);
00651 _dbus_assert (len >= 0);
00652 _dbus_assert (start <= real->len);
00653 _dbus_assert (len <= real->len - start);
00654
00655 if (!_dbus_string_init (&dest))
00656 return FALSE;
00657
00658 set_max_length (&dest, real->max_length);
00659
00660 if (!_dbus_string_move_len (str, start, len, &dest, 0))
00661 {
00662 _dbus_string_free (&dest);
00663 return FALSE;
00664 }
00665
00666 _dbus_warn ("Broken code in _dbus_string_steal_data_len(), see @todo, FIXME\n");
00667 if (!_dbus_string_steal_data (&dest, data_return))
00668 {
00669 _dbus_string_free (&dest);
00670 return FALSE;
00671 }
00672
00673 _dbus_string_free (&dest);
00674 return TRUE;
00675 }
00676
00677
00685 dbus_bool_t
00686 _dbus_string_copy_data (const DBusString *str,
00687 char **data_return)
00688 {
00689 DBUS_CONST_STRING_PREAMBLE (str);
00690 _dbus_assert (data_return != NULL);
00691
00692 *data_return = dbus_malloc (real->len + 1);
00693 if (*data_return == NULL)
00694 return FALSE;
00695
00696 memcpy (*data_return, real->str, real->len + 1);
00697
00698 return TRUE;
00699 }
00700
00710 dbus_bool_t
00711 _dbus_string_copy_data_len (const DBusString *str,
00712 char **data_return,
00713 int start,
00714 int len)
00715 {
00716 DBusString dest;
00717
00718 DBUS_CONST_STRING_PREAMBLE (str);
00719 _dbus_assert (data_return != NULL);
00720 _dbus_assert (start >= 0);
00721 _dbus_assert (len >= 0);
00722 _dbus_assert (start <= real->len);
00723 _dbus_assert (len <= real->len - start);
00724
00725 if (!_dbus_string_init (&dest))
00726 return FALSE;
00727
00728 set_max_length (&dest, real->max_length);
00729
00730 if (!_dbus_string_copy_len (str, start, len, &dest, 0))
00731 {
00732 _dbus_string_free (&dest);
00733 return FALSE;
00734 }
00735
00736 if (!_dbus_string_steal_data (&dest, data_return))
00737 {
00738 _dbus_string_free (&dest);
00739 return FALSE;
00740 }
00741
00742 _dbus_string_free (&dest);
00743 return TRUE;
00744 }
00745
00751 int
00752 _dbus_string_get_length (const DBusString *str)
00753 {
00754 DBUS_CONST_STRING_PREAMBLE (str);
00755
00756 return real->len;
00757 }
00758
00771 dbus_bool_t
00772 _dbus_string_lengthen (DBusString *str,
00773 int additional_length)
00774 {
00775 DBUS_STRING_PREAMBLE (str);
00776 _dbus_assert (additional_length >= 0);
00777
00778 if (additional_length > real->max_length - real->len)
00779 return FALSE;
00780
00781 return set_length (real,
00782 real->len + additional_length);
00783 }
00784
00791 void
00792 _dbus_string_shorten (DBusString *str,
00793 int length_to_remove)
00794 {
00795 DBUS_STRING_PREAMBLE (str);
00796 _dbus_assert (length_to_remove >= 0);
00797 _dbus_assert (length_to_remove <= real->len);
00798
00799 set_length (real,
00800 real->len - length_to_remove);
00801 }
00802
00813 dbus_bool_t
00814 _dbus_string_set_length (DBusString *str,
00815 int length)
00816 {
00817 DBUS_STRING_PREAMBLE (str);
00818 _dbus_assert (length >= 0);
00819
00820 return set_length (real, length);
00821 }
00822
00823 static dbus_bool_t
00824 align_length_then_lengthen (DBusString *str,
00825 int alignment,
00826 int then_lengthen_by)
00827 {
00828 unsigned long new_len;
00829 int delta;
00830 DBUS_STRING_PREAMBLE (str);
00831 _dbus_assert (alignment >= 1);
00832 _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
00833
00834 new_len = _DBUS_ALIGN_VALUE (real->len, alignment);
00835 if (new_len > (unsigned long) real->max_length - then_lengthen_by)
00836 return FALSE;
00837 new_len += then_lengthen_by;
00838
00839 delta = new_len - real->len;
00840 _dbus_assert (delta >= 0);
00841
00842 if (delta == 0)
00843 return TRUE;
00844
00845 if (!set_length (real, new_len))
00846 return FALSE;
00847
00848
00849
00850
00851 if (then_lengthen_by < delta)
00852 {
00853 unsigned int i;
00854 i = new_len - delta;
00855 while (i < (new_len - then_lengthen_by))
00856 {
00857 real->str[i] = '\0';
00858 ++i;
00859 }
00860 }
00861
00862 return TRUE;
00863 }
00864
00873 dbus_bool_t
00874 _dbus_string_align_length (DBusString *str,
00875 int alignment)
00876 {
00877 return align_length_then_lengthen (str, alignment, 0);
00878 }
00879
00880 static dbus_bool_t
00881 append (DBusRealString *real,
00882 const char *buffer,
00883 int buffer_len)
00884 {
00885 if (buffer_len == 0)
00886 return TRUE;
00887
00888 if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
00889 return FALSE;
00890
00891 memcpy (real->str + (real->len - buffer_len),
00892 buffer,
00893 buffer_len);
00894
00895 return TRUE;
00896 }
00897
00905 dbus_bool_t
00906 _dbus_string_append (DBusString *str,
00907 const char *buffer)
00908 {
00909 unsigned long buffer_len;
00910
00911 DBUS_STRING_PREAMBLE (str);
00912 _dbus_assert (buffer != NULL);
00913
00914 buffer_len = strlen (buffer);
00915 if (buffer_len > (unsigned long) real->max_length)
00916 return FALSE;
00917
00918 return append (real, buffer, buffer_len);
00919 }
00920
00929 dbus_bool_t
00930 _dbus_string_append_4_aligned (DBusString *str,
00931 const unsigned char octets[4])
00932 {
00933 dbus_uint32_t *p;
00934 DBUS_STRING_PREAMBLE (str);
00935
00936 if (!align_length_then_lengthen (str, 4, 4))
00937 return FALSE;
00938
00939 p = (dbus_uint32_t*) (real->str + (real->len - 4));
00940 *p = *((dbus_uint32_t*)octets);
00941
00942 return TRUE;
00943 }
00944
00953 dbus_bool_t
00954 _dbus_string_append_8_aligned (DBusString *str,
00955 const unsigned char octets[8])
00956 {
00957 #ifdef DBUS_HAVE_INT64
00958 dbus_uint64_t *p;
00959 DBUS_STRING_PREAMBLE (str);
00960
00961 if (!align_length_then_lengthen (str, 8, 8))
00962 return FALSE;
00963
00964 p = (dbus_uint64_t*) (real->str + (real->len - 8));
00965 *p = *((dbus_uint64_t*)octets);
00966 #else
00967 char *p;
00968 DBUS_STRING_PREAMBLE (str);
00969
00970 if (!align_length_then_lengthen (str, 8, 8))
00971 return FALSE;
00972
00973 p = real->str + (real->len - 8);
00974
00975 *p++ = octets[0];
00976 *p++ = octets[1];
00977 *p++ = octets[2];
00978 *p++ = octets[3];
00979 *p++ = octets[4];
00980 *p++ = octets[5];
00981 *p++ = octets[6];
00982 *p++ = octets[7];
00983 _dbus_assert (p == (real->str + real->len));
00984 #endif
00985
00986 return TRUE;
00987 }
00988
00997 dbus_bool_t
00998 _dbus_string_append_len (DBusString *str,
00999 const char *buffer,
01000 int len)
01001 {
01002 DBUS_STRING_PREAMBLE (str);
01003 _dbus_assert (buffer != NULL);
01004 _dbus_assert (len >= 0);
01005
01006 return append (real, buffer, len);
01007 }
01008
01017 dbus_bool_t
01018 _dbus_string_append_byte (DBusString *str,
01019 unsigned char byte)
01020 {
01021 DBUS_STRING_PREAMBLE (str);
01022
01023 if (!set_length (real, real->len + 1))
01024 return FALSE;
01025
01026 real->str[real->len-1] = byte;
01027
01028 return TRUE;
01029 }
01030
01038 dbus_bool_t
01039 _dbus_string_append_unichar (DBusString *str,
01040 dbus_unichar_t ch)
01041 {
01042 int len;
01043 int first;
01044 int i;
01045 char *out;
01046
01047 DBUS_STRING_PREAMBLE (str);
01048
01049
01050
01051 len = 0;
01052
01053 if (ch < 0x80)
01054 {
01055 first = 0;
01056 len = 1;
01057 }
01058 else if (ch < 0x800)
01059 {
01060 first = 0xc0;
01061 len = 2;
01062 }
01063 else if (ch < 0x10000)
01064 {
01065 first = 0xe0;
01066 len = 3;
01067 }
01068 else if (ch < 0x200000)
01069 {
01070 first = 0xf0;
01071 len = 4;
01072 }
01073 else if (ch < 0x4000000)
01074 {
01075 first = 0xf8;
01076 len = 5;
01077 }
01078 else
01079 {
01080 first = 0xfc;
01081 len = 6;
01082 }
01083
01084 if (len > (real->max_length - real->len))
01085 return FALSE;
01086
01087 if (!set_length (real, real->len + len))
01088 return FALSE;
01089
01090 out = real->str + (real->len - len);
01091
01092 for (i = len - 1; i > 0; --i)
01093 {
01094 out[i] = (ch & 0x3f) | 0x80;
01095 ch >>= 6;
01096 }
01097 out[0] = ch | first;
01098
01099 return TRUE;
01100 }
01101
01102 static void
01103 delete (DBusRealString *real,
01104 int start,
01105 int len)
01106 {
01107 if (len == 0)
01108 return;
01109
01110 memmove (real->str + start, real->str + start + len, real->len - (start + len));
01111 real->len -= len;
01112 real->str[real->len] = '\0';
01113 }
01114
01124 void
01125 _dbus_string_delete (DBusString *str,
01126 int start,
01127 int len)
01128 {
01129 DBUS_STRING_PREAMBLE (str);
01130 _dbus_assert (start >= 0);
01131 _dbus_assert (len >= 0);
01132 _dbus_assert (start <= real->len);
01133 _dbus_assert (len <= real->len - start);
01134
01135 delete (real, start, len);
01136 }
01137
01138 static dbus_bool_t
01139 copy (DBusRealString *source,
01140 int start,
01141 int len,
01142 DBusRealString *dest,
01143 int insert_at)
01144 {
01145 if (len == 0)
01146 return TRUE;
01147
01148 if (!open_gap (len, dest, insert_at))
01149 return FALSE;
01150
01151 memcpy (dest->str + insert_at,
01152 source->str + start,
01153 len);
01154
01155 return TRUE;
01156 }
01157
01167 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at) \
01168 DBusRealString *real_source = (DBusRealString*) source; \
01169 DBusRealString *real_dest = (DBusRealString*) dest; \
01170 _dbus_assert ((source) != (dest)); \
01171 DBUS_GENERIC_STRING_PREAMBLE (real_source); \
01172 DBUS_GENERIC_STRING_PREAMBLE (real_dest); \
01173 _dbus_assert (!real_dest->constant); \
01174 _dbus_assert (!real_dest->locked); \
01175 _dbus_assert ((start) >= 0); \
01176 _dbus_assert ((start) <= real_source->len); \
01177 _dbus_assert ((insert_at) >= 0); \
01178 _dbus_assert ((insert_at) <= real_dest->len)
01179
01190 dbus_bool_t
01191 _dbus_string_move (DBusString *source,
01192 int start,
01193 DBusString *dest,
01194 int insert_at)
01195 {
01196 DBusRealString *real_source = (DBusRealString*) source;
01197 _dbus_assert (start <= real_source->len);
01198
01199 return _dbus_string_move_len (source, start,
01200 real_source->len - start,
01201 dest, insert_at);
01202 }
01203
01214 dbus_bool_t
01215 _dbus_string_copy (const DBusString *source,
01216 int start,
01217 DBusString *dest,
01218 int insert_at)
01219 {
01220 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01221
01222 return copy (real_source, start,
01223 real_source->len - start,
01224 real_dest,
01225 insert_at);
01226 }
01227
01242 dbus_bool_t
01243 _dbus_string_move_len (DBusString *source,
01244 int start,
01245 int len,
01246 DBusString *dest,
01247 int insert_at)
01248
01249 {
01250 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01251 _dbus_assert (len >= 0);
01252 _dbus_assert ((start + len) <= real_source->len);
01253
01254
01255 if (len == 0)
01256 {
01257 return TRUE;
01258 }
01259 else if (start == 0 &&
01260 len == real_source->len &&
01261 real_dest->len == 0)
01262 {
01263
01264
01265
01266
01267
01268
01269 #define ASSIGN_DATA(a, b) do { \
01270 (a)->str = (b)->str; \
01271 (a)->len = (b)->len; \
01272 (a)->allocated = (b)->allocated; \
01273 (a)->align_offset = (b)->align_offset; \
01274 } while (0)
01275
01276 DBusRealString tmp;
01277
01278 ASSIGN_DATA (&tmp, real_source);
01279 ASSIGN_DATA (real_source, real_dest);
01280 ASSIGN_DATA (real_dest, &tmp);
01281
01282 return TRUE;
01283 }
01284 else
01285 {
01286 if (!copy (real_source, start, len,
01287 real_dest,
01288 insert_at))
01289 return FALSE;
01290
01291 delete (real_source, start,
01292 len);
01293
01294 return TRUE;
01295 }
01296 }
01297
01309 dbus_bool_t
01310 _dbus_string_copy_len (const DBusString *source,
01311 int start,
01312 int len,
01313 DBusString *dest,
01314 int insert_at)
01315 {
01316 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01317 _dbus_assert (len >= 0);
01318 _dbus_assert (start <= real_source->len);
01319 _dbus_assert (len <= real_source->len - start);
01320
01321 return copy (real_source, start, len,
01322 real_dest,
01323 insert_at);
01324 }
01325
01347 dbus_bool_t
01348 _dbus_string_replace_len (const DBusString *source,
01349 int start,
01350 int len,
01351 DBusString *dest,
01352 int replace_at,
01353 int replace_len)
01354 {
01355 DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
01356 _dbus_assert (len >= 0);
01357 _dbus_assert (start <= real_source->len);
01358 _dbus_assert (len <= real_source->len - start);
01359 _dbus_assert (replace_at >= 0);
01360 _dbus_assert (replace_at <= real_dest->len);
01361 _dbus_assert (replace_len <= real_dest->len - replace_at);
01362
01363 if (!copy (real_source, start, len,
01364 real_dest, replace_at))
01365 return FALSE;
01366
01367 delete (real_dest, replace_at + len, replace_len);
01368
01369 return TRUE;
01370 }
01371
01372
01373
01374
01375
01381 #define UTF8_COMPUTE(Char, Mask, Len) \
01382 if (Char < 128) \
01383 { \
01384 Len = 1; \
01385 Mask = 0x7f; \
01386 } \
01387 else if ((Char & 0xe0) == 0xc0) \
01388 { \
01389 Len = 2; \
01390 Mask = 0x1f; \
01391 } \
01392 else if ((Char & 0xf0) == 0xe0) \
01393 { \
01394 Len = 3; \
01395 Mask = 0x0f; \
01396 } \
01397 else if ((Char & 0xf8) == 0xf0) \
01398 { \
01399 Len = 4; \
01400 Mask = 0x07; \
01401 } \
01402 else if ((Char & 0xfc) == 0xf8) \
01403 { \
01404 Len = 5; \
01405 Mask = 0x03; \
01406 } \
01407 else if ((Char & 0xfe) == 0xfc) \
01408 { \
01409 Len = 6; \
01410 Mask = 0x01; \
01411 } \
01412 else \
01413 Len = -1;
01414
01419 #define UTF8_LENGTH(Char) \
01420 ((Char) < 0x80 ? 1 : \
01421 ((Char) < 0x800 ? 2 : \
01422 ((Char) < 0x10000 ? 3 : \
01423 ((Char) < 0x200000 ? 4 : \
01424 ((Char) < 0x4000000 ? 5 : 6)))))
01425
01435 #define UTF8_GET(Result, Chars, Count, Mask, Len) \
01436 (Result) = (Chars)[0] & (Mask); \
01437 for ((Count) = 1; (Count) < (Len); ++(Count)) \
01438 { \
01439 if (((Chars)[(Count)] & 0xc0) != 0x80) \
01440 { \
01441 (Result) = -1; \
01442 break; \
01443 } \
01444 (Result) <<= 6; \
01445 (Result) |= ((Chars)[(Count)] & 0x3f); \
01446 }
01447
01453 #define UNICODE_VALID(Char) \
01454 ((Char) < 0x110000 && \
01455 (((Char) & 0xFFFFF800) != 0xD800) && \
01456 ((Char) < 0xFDD0 || (Char) > 0xFDEF) && \
01457 ((Char) & 0xFFFF) != 0xFFFF)
01458
01469 void
01470 _dbus_string_get_unichar (const DBusString *str,
01471 int start,
01472 dbus_unichar_t *ch_return,
01473 int *end_return)
01474 {
01475 int i, mask, len;
01476 dbus_unichar_t result;
01477 unsigned char c;
01478 unsigned char *p;
01479 DBUS_CONST_STRING_PREAMBLE (str);
01480 _dbus_assert (start >= 0);
01481 _dbus_assert (start <= real->len);
01482
01483 if (ch_return)
01484 *ch_return = 0;
01485 if (end_return)
01486 *end_return = real->len;
01487
01488 mask = 0;
01489 p = real->str + start;
01490 c = *p;
01491
01492 UTF8_COMPUTE (c, mask, len);
01493 if (len == -1)
01494 return;
01495 UTF8_GET (result, p, i, mask, len);
01496
01497 if (result == (dbus_unichar_t)-1)
01498 return;
01499
01500 if (ch_return)
01501 *ch_return = result;
01502 if (end_return)
01503 *end_return = start + len;
01504 }
01505
01520 dbus_bool_t
01521 _dbus_string_find (const DBusString *str,
01522 int start,
01523 const char *substr,
01524 int *found)
01525 {
01526 return _dbus_string_find_to (str, start,
01527 ((const DBusRealString*)str)->len,
01528 substr, found);
01529 }
01530
01547 dbus_bool_t
01548 _dbus_string_find_to (const DBusString *str,
01549 int start,
01550 int end,
01551 const char *substr,
01552 int *found)
01553 {
01554 int i;
01555 DBUS_CONST_STRING_PREAMBLE (str);
01556 _dbus_assert (substr != NULL);
01557 _dbus_assert (start <= real->len);
01558 _dbus_assert (start >= 0);
01559 _dbus_assert (substr != NULL);
01560 _dbus_assert (end <= real->len);
01561 _dbus_assert (start <= end);
01562
01563
01564 if (*substr == '\0')
01565 {
01566 if (found)
01567 *found = start;
01568 return TRUE;
01569 }
01570
01571 i = start;
01572 while (i < end)
01573 {
01574 if (real->str[i] == substr[0])
01575 {
01576 int j = i + 1;
01577
01578 while (j < end)
01579 {
01580 if (substr[j - i] == '\0')
01581 break;
01582 else if (real->str[j] != substr[j - i])
01583 break;
01584
01585 ++j;
01586 }
01587
01588 if (substr[j - i] == '\0')
01589 {
01590 if (found)
01591 *found = i;
01592 return TRUE;
01593 }
01594 }
01595
01596 ++i;
01597 }
01598
01599 if (found)
01600 *found = end;
01601
01602 return FALSE;
01603 }
01604
01615 dbus_bool_t
01616 _dbus_string_find_byte_backward (const DBusString *str,
01617 int start,
01618 unsigned char byte,
01619 int *found)
01620 {
01621 int i;
01622 DBUS_CONST_STRING_PREAMBLE (str);
01623 _dbus_assert (start <= real->len);
01624 _dbus_assert (start >= 0);
01625 _dbus_assert (found != NULL);
01626
01627 i = start - 1;
01628 while (i >= 0)
01629 {
01630 if (real->str[i] == byte)
01631 break;
01632
01633 --i;
01634 }
01635
01636 if (found)
01637 *found = i;
01638
01639 return i >= 0;
01640 }
01641
01652 dbus_bool_t
01653 _dbus_string_find_blank (const DBusString *str,
01654 int start,
01655 int *found)
01656 {
01657 int i;
01658 DBUS_CONST_STRING_PREAMBLE (str);
01659 _dbus_assert (start <= real->len);
01660 _dbus_assert (start >= 0);
01661
01662 i = start;
01663 while (i < real->len)
01664 {
01665 if (real->str[i] == ' ' ||
01666 real->str[i] == '\t')
01667 {
01668 if (found)
01669 *found = i;
01670 return TRUE;
01671 }
01672
01673 ++i;
01674 }
01675
01676 if (found)
01677 *found = real->len;
01678
01679 return FALSE;
01680 }
01681
01690 void
01691 _dbus_string_skip_blank (const DBusString *str,
01692 int start,
01693 int *end)
01694 {
01695 int i;
01696 DBUS_CONST_STRING_PREAMBLE (str);
01697 _dbus_assert (start <= real->len);
01698 _dbus_assert (start >= 0);
01699
01700 i = start;
01701 while (i < real->len)
01702 {
01703 if (!(real->str[i] == ' ' ||
01704 real->str[i] == '\t'))
01705 break;
01706
01707 ++i;
01708 }
01709
01710 _dbus_assert (i == real->len || !(real->str[i] == ' ' ||
01711 real->str[i] == '\t'));
01712
01713 if (end)
01714 *end = i;
01715 }
01716
01725 void
01726 _dbus_string_skip_white (const DBusString *str,
01727 int start,
01728 int *end)
01729 {
01730 int i;
01731 DBUS_CONST_STRING_PREAMBLE (str);
01732 _dbus_assert (start <= real->len);
01733 _dbus_assert (start >= 0);
01734
01735 i = start;
01736 while (i < real->len)
01737 {
01738 if (!(real->str[i] == ' ' ||
01739 real->str[i] == '\n' ||
01740 real->str[i] == '\r' ||
01741 real->str[i] == '\t'))
01742 break;
01743
01744 ++i;
01745 }
01746
01747 _dbus_assert (i == real->len || !(real->str[i] == ' ' ||
01748 real->str[i] == '\t'));
01749
01750 if (end)
01751 *end = i;
01752 }
01753
01769 dbus_bool_t
01770 _dbus_string_pop_line (DBusString *source,
01771 DBusString *dest)
01772 {
01773 int eol;
01774 dbus_bool_t have_newline;
01775
01776 _dbus_string_set_length (dest, 0);
01777
01778 eol = 0;
01779 if (_dbus_string_find (source, 0, "\n", &eol))
01780 {
01781 have_newline = TRUE;
01782 eol += 1;
01783 }
01784 else
01785 {
01786 eol = _dbus_string_get_length (source);
01787 have_newline = FALSE;
01788 }
01789
01790 if (eol == 0)
01791 return FALSE;
01792
01793 if (!_dbus_string_move_len (source, 0, eol,
01794 dest, 0))
01795 {
01796 return FALSE;
01797 }
01798
01799
01800 if (have_newline)
01801 {
01802 dbus_bool_t have_cr;
01803
01804 _dbus_assert (_dbus_string_get_length (dest) > 0);
01805
01806 if (_dbus_string_get_length (dest) > 1 &&
01807 _dbus_string_get_byte (dest,
01808 _dbus_string_get_length (dest) - 2) == '\r')
01809 have_cr = TRUE;
01810 else
01811 have_cr = FALSE;
01812
01813 _dbus_string_set_length (dest,
01814 _dbus_string_get_length (dest) -
01815 (have_cr ? 2 : 1));
01816 }
01817
01818 return TRUE;
01819 }
01820
01827 void
01828 _dbus_string_delete_first_word (DBusString *str)
01829 {
01830 int i;
01831
01832 if (_dbus_string_find_blank (str, 0, &i))
01833 _dbus_string_skip_blank (str, i, &i);
01834
01835 _dbus_string_delete (str, 0, i);
01836 }
01837
01843 void
01844 _dbus_string_delete_leading_blanks (DBusString *str)
01845 {
01846 int i;
01847
01848 _dbus_string_skip_blank (str, 0, &i);
01849
01850 if (i > 0)
01851 _dbus_string_delete (str, 0, i);
01852 }
01853
01863 dbus_bool_t
01864 _dbus_string_equal (const DBusString *a,
01865 const DBusString *b)
01866 {
01867 const unsigned char *ap;
01868 const unsigned char *bp;
01869 const unsigned char *a_end;
01870 const DBusRealString *real_a = (const DBusRealString*) a;
01871 const DBusRealString *real_b = (const DBusRealString*) b;
01872 DBUS_GENERIC_STRING_PREAMBLE (real_a);
01873 DBUS_GENERIC_STRING_PREAMBLE (real_b);
01874
01875 if (real_a->len != real_b->len)
01876 return FALSE;
01877
01878 ap = real_a->str;
01879 bp = real_b->str;
01880 a_end = real_a->str + real_a->len;
01881 while (ap != a_end)
01882 {
01883 if (*ap != *bp)
01884 return FALSE;
01885
01886 ++ap;
01887 ++bp;
01888 }
01889
01890 return TRUE;
01891 }
01892
01905 dbus_bool_t
01906 _dbus_string_equal_len (const DBusString *a,
01907 const DBusString *b,
01908 int len)
01909 {
01910 const unsigned char *ap;
01911 const unsigned char *bp;
01912 const unsigned char *a_end;
01913 const DBusRealString *real_a = (const DBusRealString*) a;
01914 const DBusRealString *real_b = (const DBusRealString*) b;
01915 DBUS_GENERIC_STRING_PREAMBLE (real_a);
01916 DBUS_GENERIC_STRING_PREAMBLE (real_b);
01917
01918 if (real_a->len != real_b->len &&
01919 (real_a->len < len || real_b->len < len))
01920 return FALSE;
01921
01922 ap = real_a->str;
01923 bp = real_b->str;
01924 a_end = real_a->str + MIN (real_a->len, len);
01925 while (ap != a_end)
01926 {
01927 if (*ap != *bp)
01928 return FALSE;
01929
01930 ++ap;
01931 ++bp;
01932 }
01933
01934 return TRUE;
01935 }
01936
01944 dbus_bool_t
01945 _dbus_string_equal_c_str (const DBusString *a,
01946 const char *c_str)
01947 {
01948 const unsigned char *ap;
01949 const unsigned char *bp;
01950 const unsigned char *a_end;
01951 const DBusRealString *real_a = (const DBusRealString*) a;
01952 DBUS_GENERIC_STRING_PREAMBLE (real_a);
01953 _dbus_assert (c_str != NULL);
01954
01955 ap = real_a->str;
01956 bp = (const unsigned char*) c_str;
01957 a_end = real_a->str + real_a->len;
01958 while (ap != a_end && *bp)
01959 {
01960 if (*ap != *bp)
01961 return FALSE;
01962
01963 ++ap;
01964 ++bp;
01965 }
01966
01967 if (ap != a_end || *bp)
01968 return FALSE;
01969
01970 return TRUE;
01971 }
01972
01980 dbus_bool_t
01981 _dbus_string_starts_with_c_str (const DBusString *a,
01982 const char *c_str)
01983 {
01984 const unsigned char *ap;
01985 const unsigned char *bp;
01986 const unsigned char *a_end;
01987 const DBusRealString *real_a = (const DBusRealString*) a;
01988 DBUS_GENERIC_STRING_PREAMBLE (real_a);
01989 _dbus_assert (c_str != NULL);
01990
01991 ap = real_a->str;
01992 bp = (const unsigned char*) c_str;
01993 a_end = real_a->str + real_a->len;
01994 while (ap != a_end && *bp)
01995 {
01996 if (*ap != *bp)
01997 return FALSE;
01998
01999 ++ap;
02000 ++bp;
02001 }
02002
02003 if (*bp == '\0')
02004 return TRUE;
02005 else
02006 return FALSE;
02007 }
02008
02018 dbus_bool_t
02019 _dbus_string_ends_with_c_str (const DBusString *a,
02020 const char *c_str)
02021 {
02022 const unsigned char *ap;
02023 const unsigned char *bp;
02024 const unsigned char *a_end;
02025 unsigned long c_str_len;
02026 const DBusRealString *real_a = (const DBusRealString*) a;
02027 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02028 _dbus_assert (c_str != NULL);
02029
02030 c_str_len = strlen (c_str);
02031 if (((unsigned long)real_a->len) < c_str_len)
02032 return FALSE;
02033
02034 ap = real_a->str + (real_a->len - c_str_len);
02035 bp = (const unsigned char*) c_str;
02036 a_end = real_a->str + real_a->len;
02037 while (ap != a_end)
02038 {
02039 if (*ap != *bp)
02040 return FALSE;
02041
02042 ++ap;
02043 ++bp;
02044 }
02045
02046 _dbus_assert (*ap == '\0');
02047 _dbus_assert (*bp == '\0');
02048
02049 return TRUE;
02050 }
02051
02052 static const signed char base64_table[] = {
02053 'A',
02054 'B',
02055 'C',
02056 'D',
02057 'E',
02058 'F',
02059 'G',
02060 'H',
02061 'I',
02062 'J',
02063 'K',
02064 'L',
02065 'M',
02066 'N',
02067 'O',
02068 'P',
02069 'Q',
02070 'R',
02071 'S',
02072 'T',
02073 'U',
02074 'V',
02075 'W',
02076 'X',
02077 'Y',
02078 'Z',
02079 'a',
02080 'b',
02081 'c',
02082 'd',
02083 'e',
02084 'f',
02085 'g',
02086 'h',
02087 'i',
02088 'j',
02089 'k',
02090 'l',
02091 'm',
02092 'n',
02093 'o',
02094 'p',
02095 'q',
02096 'r',
02097 's',
02098 't',
02099 'u',
02100 'v',
02101 'w',
02102 'x',
02103 'y',
02104 'z',
02105 '0',
02106 '1',
02107 '2',
02108 '3',
02109 '4',
02110 '5',
02111 '6',
02112 '7',
02113 '8',
02114 '9',
02115 '+',
02116 '/'
02117 };
02118
02120 #define UNBASE64_MIN_CHAR (43)
02121
02122 #define UNBASE64_MAX_CHAR (122)
02123
02126 #define UNBASE64_TABLE_OFFSET UNBASE64_MIN_CHAR
02127 static const signed char unbase64_table[] = {
02128 62,
02129 -1,
02130 -1,
02131 -1,
02132 63,
02133 52,
02134 53,
02135 54,
02136 55,
02137 56,
02138 57,
02139 58,
02140 59,
02141 60,
02142 61,
02143 -1,
02144 -1,
02145 -1,
02146 -1,
02147 -1,
02148 -1,
02149 -1,
02150 0,
02151 1,
02152 2,
02153 3,
02154 4,
02155 5,
02156 6,
02157 7,
02158 8,
02159 9,
02160 10,
02161 11,
02162 12,
02163 13,
02164 14,
02165 15,
02166 16,
02167 17,
02168 18,
02169 19,
02170 20,
02171 21,
02172 22,
02173 23,
02174 24,
02175 25,
02176 -1,
02177 -1,
02178 -1,
02179 -1,
02180 -1,
02181 -1,
02182 26,
02183 27,
02184 28,
02185 29,
02186 30,
02187 31,
02188 32,
02189 33,
02190 34,
02191 35,
02192 36,
02193 37,
02194 38,
02195 39,
02196 40,
02197 41,
02198 42,
02199 43,
02200 44,
02201 45,
02202 46,
02203 47,
02204 48,
02205 49,
02206 50,
02207 51
02208 };
02209
02219 dbus_bool_t
02220 _dbus_string_base64_encode (const DBusString *source,
02221 int start,
02222 DBusString *dest,
02223 int insert_at)
02224 {
02225 int source_len;
02226 unsigned int dest_len;
02227 const unsigned char *s;
02228 unsigned char *d;
02229 const unsigned char *triplet_end;
02230 const unsigned char *final_end;
02231 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
02232 _dbus_assert (source != dest);
02233
02234
02235
02236
02237 source_len = real_source->len - start;
02238 dest_len = (source_len / 3) * 4;
02239 if (source_len % 3 != 0)
02240 dest_len += 4;
02241
02242 if (dest_len > (unsigned int) real_dest->max_length)
02243 return FALSE;
02244
02245 if (source_len == 0)
02246 return TRUE;
02247
02248 if (!open_gap (dest_len, real_dest, insert_at))
02249 return FALSE;
02250
02251 d = real_dest->str + insert_at;
02252 s = real_source->str + start;
02253 final_end = real_source->str + (start + source_len);
02254 triplet_end = final_end - (source_len % 3);
02255 _dbus_assert (triplet_end <= final_end);
02256 _dbus_assert ((final_end - triplet_end) < 3);
02257
02258 #define ENCODE_64(v) (base64_table[ (unsigned char) (v) ])
02259 #define SIX_BITS_MASK (0x3f)
02260 _dbus_assert (SIX_BITS_MASK < _DBUS_N_ELEMENTS (base64_table));
02261
02262 while (s != triplet_end)
02263 {
02264 unsigned int triplet;
02265
02266 triplet = s[2] | (s[1] << 8) | (s[0] << 16);
02267
02268
02269
02270 *d++ = ENCODE_64 (triplet >> 18);
02271 *d++ = ENCODE_64 ((triplet >> 12) & SIX_BITS_MASK);
02272 *d++ = ENCODE_64 ((triplet >> 6) & SIX_BITS_MASK);
02273 *d++ = ENCODE_64 (triplet & SIX_BITS_MASK);
02274
02275 s += 3;
02276 }
02277
02278 switch (final_end - triplet_end)
02279 {
02280 case 2:
02281 {
02282 unsigned int doublet;
02283
02284 doublet = s[1] | (s[0] << 8);
02285
02286 *d++ = ENCODE_64 (doublet >> 12);
02287 *d++ = ENCODE_64 ((doublet >> 6) & SIX_BITS_MASK);
02288 *d++ = ENCODE_64 (doublet & SIX_BITS_MASK);
02289 *d++ = '=';
02290 }
02291 break;
02292 case 1:
02293 {
02294 unsigned int singlet;
02295
02296 singlet = s[0];
02297
02298 *d++ = ENCODE_64 ((singlet >> 6) & SIX_BITS_MASK);
02299 *d++ = ENCODE_64 (singlet & SIX_BITS_MASK);
02300 *d++ = '=';
02301 *d++ = '=';
02302 }
02303 break;
02304 case 0:
02305 break;
02306 }
02307
02308 _dbus_assert (d == (real_dest->str + (insert_at + dest_len)));
02309
02310 return TRUE;
02311 }
02312
02327 dbus_bool_t
02328 _dbus_string_base64_decode (const DBusString *source,
02329 int start,
02330 DBusString *dest,
02331 int insert_at)
02332 {
02333 int source_len;
02334 const char *s;
02335 const char *end;
02336 DBusString result;
02337 unsigned int triplet = 0;
02338 int sextet_count;
02339 int pad_count;
02340 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
02341 _dbus_assert (source != dest);
02342
02343 source_len = real_source->len - start;
02344 s = real_source->str + start;
02345 end = real_source->str + source_len;
02346
02347 if (source_len == 0)
02348 return TRUE;
02349
02350 if (!_dbus_string_init (&result))
02351 return FALSE;
02352
02353 pad_count = 0;
02354 sextet_count = 0;
02355 while (s != end)
02356 {
02357
02358
02359
02360
02361
02362
02363 if (*s >= UNBASE64_MIN_CHAR &&
02364 *s <= UNBASE64_MAX_CHAR)
02365 {
02366 if (*s == '=')
02367 {
02368
02369
02370
02371 pad_count += 1;
02372 sextet_count += 1;
02373 }
02374 else
02375 {
02376 int val;
02377
02378 val = unbase64_table[(*s) - UNBASE64_TABLE_OFFSET];
02379
02380 if (val >= 0)
02381 {
02382 triplet <<= 6;
02383 triplet |= (unsigned int) val;
02384 sextet_count += 1;
02385 }
02386 }
02387
02388 if (sextet_count == 4)
02389 {
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403 if (pad_count < 1)
02404 {
02405 if (!_dbus_string_append_byte (&result,
02406 triplet >> 16))
02407 goto failed;
02408 }
02409
02410 if (pad_count < 2)
02411 {
02412 if (!_dbus_string_append_byte (&result,
02413 (triplet >> 8) & 0xff))
02414 goto failed;
02415 }
02416
02417 if (!_dbus_string_append_byte (&result,
02418 triplet & 0xff))
02419 goto failed;
02420
02421 sextet_count = 0;
02422 pad_count = 0;
02423 triplet = 0;
02424 }
02425 }
02426
02427 ++s;
02428 }
02429
02430 if (!_dbus_string_move (&result, 0, dest, insert_at))
02431 {
02432 _dbus_string_free (&result);
02433 return FALSE;
02434 }
02435
02436 _dbus_string_free (&result);
02437
02438 return TRUE;
02439
02440 failed:
02441 _dbus_string_free (&result);
02442
02443 return FALSE;
02444 }
02445
02456 dbus_bool_t
02457 _dbus_string_hex_encode (const DBusString *source,
02458 int start,
02459 DBusString *dest,
02460 int insert_at)
02461 {
02462 DBusString result;
02463 const char hexdigits[16] = {
02464 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
02465 'a', 'b', 'c', 'd', 'e', 'f'
02466 };
02467 const unsigned char *p;
02468 const unsigned char *end;
02469 dbus_bool_t retval;
02470
02471 _dbus_assert (start <= _dbus_string_get_length (source));
02472
02473 if (!_dbus_string_init (&result))
02474 return FALSE;
02475
02476 retval = FALSE;
02477
02478 p = (const unsigned char*) _dbus_string_get_const_data (source);
02479 end = p + _dbus_string_get_length (source);
02480 p += start;
02481
02482 while (p != end)
02483 {
02484 if (!_dbus_string_append_byte (&result,
02485 hexdigits[(*p >> 4)]))
02486 goto out;
02487
02488 if (!_dbus_string_append_byte (&result,
02489 hexdigits[(*p & 0x0f)]))
02490 goto out;
02491
02492 ++p;
02493 }
02494
02495 if (!_dbus_string_move (&result, 0, dest, insert_at))
02496 goto out;
02497
02498 retval = TRUE;
02499
02500 out:
02501 _dbus_string_free (&result);
02502 return retval;
02503 }
02504
02514 dbus_bool_t
02515 _dbus_string_hex_decode (const DBusString *source,
02516 int start,
02517 DBusString *dest,
02518 int insert_at)
02519 {
02520 DBusString result;
02521 const unsigned char *p;
02522 const unsigned char *end;
02523 dbus_bool_t retval;
02524 dbus_bool_t high_bits;
02525
02526 _dbus_assert (start <= _dbus_string_get_length (source));
02527
02528 if (!_dbus_string_init (&result))
02529 return FALSE;
02530
02531 retval = FALSE;
02532
02533 high_bits = TRUE;
02534 p = (const unsigned char*) _dbus_string_get_const_data (source);
02535 end = p + _dbus_string_get_length (source);
02536 p += start;
02537
02538 while (p != end)
02539 {
02540 unsigned int val;
02541
02542 switch (*p)
02543 {
02544 case '0':
02545 val = 0;
02546 break;
02547 case '1':
02548 val = 1;
02549 break;
02550 case '2':
02551 val = 2;
02552 break;
02553 case '3':
02554 val = 3;
02555 break;
02556 case '4':
02557 val = 4;
02558 break;
02559 case '5':
02560 val = 5;
02561 break;
02562 case '6':
02563 val = 6;
02564 break;
02565 case '7':
02566 val = 7;
02567 break;
02568 case '8':
02569 val = 8;
02570 break;
02571 case '9':
02572 val = 9;
02573 break;
02574 case 'a':
02575 case 'A':
02576 val = 10;
02577 break;
02578 case 'b':
02579 case 'B':
02580 val = 11;
02581 break;
02582 case 'c':
02583 case 'C':
02584 val = 12;
02585 break;
02586 case 'd':
02587 case 'D':
02588 val = 13;
02589 break;
02590 case 'e':
02591 case 'E':
02592 val = 14;
02593 break;
02594 case 'f':
02595 case 'F':
02596 val = 15;
02597 break;
02598 default:
02599 val = 0;
02600 _dbus_verbose ("invalid character '%c' in hex encoded text\n",
02601 *p);
02602 goto out;
02603 }
02604
02605 if (high_bits)
02606 {
02607 if (!_dbus_string_append_byte (&result,
02608 val << 4))
02609 goto out;
02610 }
02611 else
02612 {
02613 int len;
02614 unsigned char b;
02615
02616 len = _dbus_string_get_length (&result);
02617
02618 b = _dbus_string_get_byte (&result, len - 1);
02619
02620 b |= val;
02621
02622 _dbus_string_set_byte (&result, len - 1, b);
02623 }
02624
02625 high_bits = !high_bits;
02626
02627 ++p;
02628 }
02629
02630 if (!_dbus_string_move (&result, 0, dest, insert_at))
02631 goto out;
02632
02633 retval = TRUE;
02634
02635 out:
02636 _dbus_string_free (&result);
02637 return retval;
02638 }
02639
02653 dbus_bool_t
02654 _dbus_string_validate_ascii (const DBusString *str,
02655 int start,
02656 int len)
02657 {
02658 const unsigned char *s;
02659 const unsigned char *end;
02660 DBUS_CONST_STRING_PREAMBLE (str);
02661 _dbus_assert (start >= 0);
02662 _dbus_assert (start <= real->len);
02663 _dbus_assert (len >= 0);
02664
02665 if (len > real->len - start)
02666 return FALSE;
02667
02668 s = real->str + start;
02669 end = s + len;
02670 while (s != end)
02671 {
02672 if (*s == '\0' ||
02673 ((*s & ~0x7f) != 0))
02674 return FALSE;
02675
02676 ++s;
02677 }
02678
02679 return TRUE;
02680 }
02681
02697 dbus_bool_t
02698 _dbus_string_validate_utf8 (const DBusString *str,
02699 int start,
02700 int len)
02701 {
02702 const unsigned char *p;
02703 const unsigned char *end;
02704 DBUS_CONST_STRING_PREAMBLE (str);
02705 _dbus_assert (start >= 0);
02706 _dbus_assert (start <= real->len);
02707 _dbus_assert (len >= 0);
02708
02709 if (len > real->len - start)
02710 return FALSE;
02711
02712 p = real->str + start;
02713 end = p + len;
02714
02715 while (p < end)
02716 {
02717 int i, mask = 0, char_len;
02718 dbus_unichar_t result;
02719 unsigned char c = (unsigned char) *p;
02720
02721 UTF8_COMPUTE (c, mask, char_len);
02722
02723 if (char_len == -1)
02724 break;
02725
02726
02727 if ((end - p) < char_len)
02728 break;
02729
02730 UTF8_GET (result, p, i, mask, char_len);
02731
02732 if (UTF8_LENGTH (result) != char_len)
02733 break;
02734
02735 if (result == (dbus_unichar_t)-1)
02736 break;
02737
02738 if (!UNICODE_VALID (result))
02739 break;
02740
02741 p += char_len;
02742 }
02743
02744
02745
02746
02747 if (p != end)
02748 return FALSE;
02749 else
02750 return TRUE;
02751 }
02752
02766 dbus_bool_t
02767 _dbus_string_validate_nul (const DBusString *str,
02768 int start,
02769 int len)
02770 {
02771 const unsigned char *s;
02772 const unsigned char *end;
02773 DBUS_CONST_STRING_PREAMBLE (str);
02774 _dbus_assert (start >= 0);
02775 _dbus_assert (len >= 0);
02776 _dbus_assert (start <= real->len);
02777
02778 if (len > real->len - start)
02779 return FALSE;
02780
02781 s = real->str + start;
02782 end = s + len;
02783 while (s != end)
02784 {
02785 if (*s != '\0')
02786 return FALSE;
02787 ++s;
02788 }
02789
02790 return TRUE;
02791 }
02792
02807 dbus_bool_t
02808 _dbus_string_validate_name (const DBusString *str,
02809 int start,
02810 int len)
02811 {
02812 const unsigned char *s;
02813 const unsigned char *end;
02814 dbus_bool_t saw_dot;
02815
02816 DBUS_CONST_STRING_PREAMBLE (str);
02817 _dbus_assert (start >= 0);
02818 _dbus_assert (len >= 0);
02819 _dbus_assert (start <= real->len);
02820
02821 if (len > real->len - start)
02822 return FALSE;
02823
02824 if (len > DBUS_MAXIMUM_NAME_LENGTH)
02825 return FALSE;
02826
02827 if (len == 0)
02828 return FALSE;
02829
02830 saw_dot = FALSE;
02831 s = real->str + start;
02832 end = s + len;
02833 while (s != end)
02834 {
02835 if (*s == '.')
02836 {
02837 saw_dot = TRUE;
02838 break;
02839 }
02840
02841 ++s;
02842 }
02843
02844 if (!saw_dot)
02845 return FALSE;
02846
02847 return TRUE;
02848 }
02849
02850
02865 dbus_bool_t
02866 _dbus_string_validate_service (const DBusString *str,
02867 int start,
02868 int len)
02869 {
02870 const unsigned char *s;
02871 const unsigned char *end;
02872 dbus_bool_t saw_dot;
02873 dbus_bool_t is_base_service;
02874
02875 DBUS_CONST_STRING_PREAMBLE (str);
02876 _dbus_assert (start >= 0);
02877 _dbus_assert (len >= 0);
02878 _dbus_assert (start <= real->len);
02879
02880 if (len > real->len - start)
02881 return FALSE;
02882
02883 if (len > DBUS_MAXIMUM_NAME_LENGTH)
02884 return FALSE;
02885
02886 if (len == 0)
02887 return FALSE;
02888
02889 is_base_service = _dbus_string_get_byte (str, start) == ':';
02890 if (is_base_service)
02891 return TRUE;
02892
02893
02894
02895 saw_dot = FALSE;
02896 s = real->str + start;
02897 end = s + len;
02898 while (s != end)
02899 {
02900 if (*s == '.')
02901 {
02902 saw_dot = TRUE;
02903 break;
02904 }
02905
02906 ++s;
02907 }
02908
02909 return saw_dot;
02910 }
02911
02917 void
02918 _dbus_string_zero (DBusString *str)
02919 {
02920 DBUS_STRING_PREAMBLE (str);
02921
02922 memset (real->str - real->align_offset, '\0', real->allocated);
02923 }
02926 #ifdef DBUS_BUILD_TESTS
02927 #include "dbus-test.h"
02928 #include <stdio.h>
02929
02930 static void
02931 test_max_len (DBusString *str,
02932 int max_len)
02933 {
02934 if (max_len > 0)
02935 {
02936 if (!_dbus_string_set_length (str, max_len - 1))
02937 _dbus_assert_not_reached ("setting len to one less than max should have worked");
02938 }
02939
02940 if (!_dbus_string_set_length (str, max_len))
02941 _dbus_assert_not_reached ("setting len to max len should have worked");
02942
02943 if (_dbus_string_set_length (str, max_len + 1))
02944 _dbus_assert_not_reached ("setting len to one more than max len should not have worked");
02945
02946 if (!_dbus_string_set_length (str, 0))
02947 _dbus_assert_not_reached ("setting len to zero should have worked");
02948 }
02949
02950 static void
02951 test_base64_roundtrip (const unsigned char *data,
02952 int len)
02953 {
02954 DBusString orig;
02955 DBusString encoded;
02956 DBusString decoded;
02957
02958 if (len < 0)
02959 len = strlen (data);
02960
02961 if (!_dbus_string_init (&orig))
02962 _dbus_assert_not_reached ("could not init string");
02963
02964 if (!_dbus_string_init (&encoded))
02965 _dbus_assert_not_reached ("could not init string");
02966
02967 if (!_dbus_string_init (&decoded))
02968 _dbus_assert_not_reached ("could not init string");
02969
02970 if (!_dbus_string_append_len (&orig, data, len))
02971 _dbus_assert_not_reached ("couldn't append orig data");
02972
02973 if (!_dbus_string_base64_encode (&orig, 0, &encoded, 0))
02974 _dbus_assert_not_reached ("could not encode");
02975
02976 if (!_dbus_string_base64_decode (&encoded, 0, &decoded, 0))
02977 _dbus_assert_not_reached ("could not decode");
02978
02979 if (!_dbus_string_equal (&orig, &decoded))
02980 {
02981 const char *s;
02982
02983 printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
02984 _dbus_string_get_length (&orig),
02985 _dbus_string_get_length (&encoded),
02986 _dbus_string_get_length (&decoded));
02987 printf ("Original: %s\n", data);
02988 s = _dbus_string_get_const_data (&decoded);
02989 printf ("Decoded: %s\n", s);
02990 _dbus_assert_not_reached ("original string not the same as string decoded from base64");
02991 }
02992
02993 _dbus_string_free (&orig);
02994 _dbus_string_free (&encoded);
02995 _dbus_string_free (&decoded);
02996 }
02997
02998 static void
02999 test_hex_roundtrip (const unsigned char *data,
03000 int len)
03001 {
03002 DBusString orig;
03003 DBusString encoded;
03004 DBusString decoded;
03005
03006 if (len < 0)
03007 len = strlen (data);
03008
03009 if (!_dbus_string_init (&orig))
03010 _dbus_assert_not_reached ("could not init string");
03011
03012 if (!_dbus_string_init (&encoded))
03013 _dbus_assert_not_reached ("could not init string");
03014
03015 if (!_dbus_string_init (&decoded))
03016 _dbus_assert_not_reached ("could not init string");
03017
03018 if (!_dbus_string_append_len (&orig, data, len))
03019 _dbus_assert_not_reached ("couldn't append orig data");
03020
03021 if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))
03022 _dbus_assert_not_reached ("could not encode");
03023
03024 if (!_dbus_string_hex_decode (&encoded, 0, &decoded, 0))
03025 _dbus_assert_not_reached ("could not decode");
03026
03027 if (!_dbus_string_equal (&orig, &decoded))
03028 {
03029 const char *s;
03030
03031 printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
03032 _dbus_string_get_length (&orig),
03033 _dbus_string_get_length (&encoded),
03034 _dbus_string_get_length (&decoded));
03035 printf ("Original: %s\n", data);
03036 s = _dbus_string_get_const_data (&decoded);
03037 printf ("Decoded: %s\n", s);
03038 _dbus_assert_not_reached ("original string not the same as string decoded from base64");
03039 }
03040
03041 _dbus_string_free (&orig);
03042 _dbus_string_free (&encoded);
03043 _dbus_string_free (&decoded);
03044 }
03045
03046 typedef void (* TestRoundtripFunc) (const unsigned char *data,
03047 int len);
03048 static void
03049 test_roundtrips (TestRoundtripFunc func)
03050 {
03051 (* func) ("Hello this is a string\n", -1);
03052 (* func) ("Hello this is a string\n1", -1);
03053 (* func) ("Hello this is a string\n12", -1);
03054 (* func) ("Hello this is a string\n123", -1);
03055 (* func) ("Hello this is a string\n1234", -1);
03056 (* func) ("Hello this is a string\n12345", -1);
03057 (* func) ("", 0);
03058 (* func) ("1", 1);
03059 (* func) ("12", 2);
03060 (* func) ("123", 3);
03061 (* func) ("1234", 4);
03062 (* func) ("12345", 5);
03063 (* func) ("", 1);
03064 (* func) ("1", 2);
03065 (* func) ("12", 3);
03066 (* func) ("123", 4);
03067 (* func) ("1234", 5);
03068 (* func) ("12345", 6);
03069 {
03070 unsigned char buf[512];
03071 int i;
03072
03073 i = 0;
03074 while (i < _DBUS_N_ELEMENTS (buf))
03075 {
03076 buf[i] = i;
03077 ++i;
03078 }
03079 i = 0;
03080 while (i < _DBUS_N_ELEMENTS (buf))
03081 {
03082 (* func) (buf, i);
03083 ++i;
03084 }
03085 }
03086 }
03087
03088
03099 dbus_bool_t
03100 _dbus_string_test (void)
03101 {
03102 DBusString str;
03103 DBusString other;
03104 int i, end;
03105 long v;
03106 double d;
03107 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 };
03108 char *s;
03109 dbus_unichar_t ch;
03110
03111 i = 0;
03112 while (i < _DBUS_N_ELEMENTS (lens))
03113 {
03114 if (!_dbus_string_init (&str))
03115 _dbus_assert_not_reached ("failed to init string");
03116
03117 set_max_length (&str, lens[i]);
03118
03119 test_max_len (&str, lens[i]);
03120 _dbus_string_free (&str);
03121
03122 ++i;
03123 }
03124
03125
03126 i = 0;
03127 while (i < _DBUS_N_ELEMENTS (lens))
03128 {
03129 int j;
03130
03131 if (!_dbus_string_init (&str))
03132 _dbus_assert_not_reached ("failed to init string");
03133
03134 set_max_length (&str, lens[i]);
03135
03136 if (!_dbus_string_set_length (&str, lens[i]))
03137 _dbus_assert_not_reached ("failed to set string length");
03138
03139 j = lens[i];
03140 while (j > 0)
03141 {
03142 _dbus_assert (_dbus_string_get_length (&str) == j);
03143 if (j > 0)
03144 {
03145 _dbus_string_shorten (&str, 1);
03146 _dbus_assert (_dbus_string_get_length (&str) == (j - 1));
03147 }
03148 --j;
03149 }
03150
03151 _dbus_string_free (&str);
03152
03153 ++i;
03154 }
03155
03156
03157 if (!_dbus_string_init (&str))
03158 _dbus_assert_not_reached ("failed to init string");
03159
03160 i = 0;
03161 while (i < 10)
03162 {
03163 if (!_dbus_string_append (&str, "a"))
03164 _dbus_assert_not_reached ("failed to append string to string\n");
03165
03166 _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1);
03167
03168 if (!_dbus_string_append_byte (&str, 'b'))
03169 _dbus_assert_not_reached ("failed to append byte to string\n");
03170
03171 _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2);
03172
03173 ++i;
03174 }
03175
03176 _dbus_string_free (&str);
03177
03178
03179
03180 if (!_dbus_string_init (&str))
03181 _dbus_assert_not_reached ("failed to init string");
03182
03183 if (!_dbus_string_append (&str, "Hello World"))
03184 _dbus_assert_not_reached ("could not append to string");
03185
03186 i = _dbus_string_get_length (&str);
03187
03188 if (!_dbus_string_steal_data (&str, &s))
03189 _dbus_assert_not_reached ("failed to steal data");
03190
03191 _dbus_assert (_dbus_string_get_length (&str) == 0);
03192 _dbus_assert (((int)strlen (s)) == i);
03193
03194 dbus_free (s);
03195
03196
03197
03198 if (!_dbus_string_append (&str, "Hello World"))
03199 _dbus_assert_not_reached ("could not append to string");
03200
03201 i = _dbus_string_get_length (&str);
03202
03203 if (!_dbus_string_init (&other))
03204 _dbus_assert_not_reached ("could not init string");
03205
03206 if (!_dbus_string_move (&str, 0, &other, 0))
03207 _dbus_assert_not_reached ("could not move");
03208
03209 _dbus_assert (_dbus_string_get_length (&str) == 0);
03210 _dbus_assert (_dbus_string_get_length (&other) == i);
03211
03212 if (!_dbus_string_append (&str, "Hello World"))
03213 _dbus_assert_not_reached ("could not append to string");
03214
03215 if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other)))
03216 _dbus_assert_not_reached ("could not move");
03217
03218 _dbus_assert (_dbus_string_get_length (&str) == 0);
03219 _dbus_assert (_dbus_string_get_length (&other) == i * 2);
03220
03221 if (!_dbus_string_append (&str, "Hello World"))
03222 _dbus_assert_not_reached ("could not append to string");
03223
03224 if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2))
03225 _dbus_assert_not_reached ("could not move");
03226
03227 _dbus_assert (_dbus_string_get_length (&str) == 0);
03228 _dbus_assert (_dbus_string_get_length (&other) == i * 3);
03229
03230 _dbus_string_free (&other);
03231
03232
03233
03234 if (!_dbus_string_append (&str, "Hello World"))
03235 _dbus_assert_not_reached ("could not append to string");
03236
03237 i = _dbus_string_get_length (&str);
03238
03239 if (!_dbus_string_init (&other))
03240 _dbus_assert_not_reached ("could not init string");
03241
03242 if (!_dbus_string_copy (&str, 0, &other, 0))
03243 _dbus_assert_not_reached ("could not copy");
03244
03245 _dbus_assert (_dbus_string_get_length (&str) == i);
03246 _dbus_assert (_dbus_string_get_length (&other) == i);
03247
03248 if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other)))
03249 _dbus_assert_not_reached ("could not copy");
03250
03251 _dbus_assert (_dbus_string_get_length (&str) == i);
03252 _dbus_assert (_dbus_string_get_length (&other) == i * 2);
03253 _dbus_assert (_dbus_string_equal_c_str (&other,
03254 "Hello WorldHello World"));
03255
03256 if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2))
03257 _dbus_assert_not_reached ("could not copy");
03258
03259 _dbus_assert (_dbus_string_get_length (&str) == i);
03260 _dbus_assert (_dbus_string_get_length (&other) == i * 3);
03261 _dbus_assert (_dbus_string_equal_c_str (&other,
03262 "Hello WorldHello WorldHello World"));
03263
03264 _dbus_string_free (&str);
03265 _dbus_string_free (&other);
03266
03267
03268
03269 if (!_dbus_string_init (&str))
03270 _dbus_assert_not_reached ("failed to init string");
03271
03272 if (!_dbus_string_append (&str, "Hello World"))
03273 _dbus_assert_not_reached ("could not append to string");
03274
03275 i = _dbus_string_get_length (&str);
03276
03277 if (!_dbus_string_init (&other))
03278 _dbus_assert_not_reached ("could not init string");
03279
03280 if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
03281 &other, 0, _dbus_string_get_length (&other)))
03282 _dbus_assert_not_reached ("could not replace");
03283
03284 _dbus_assert (_dbus_string_get_length (&str) == i);
03285 _dbus_assert (_dbus_string_get_length (&other) == i);
03286 _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World"));
03287
03288 if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
03289 &other, 5, 1))
03290 _dbus_assert_not_reached ("could not replace center space");
03291
03292 _dbus_assert (_dbus_string_get_length (&str) == i);
03293 _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
03294 _dbus_assert (_dbus_string_equal_c_str (&other,
03295 "HelloHello WorldWorld"));
03296
03297
03298 if (!_dbus_string_replace_len (&str, 1, 1,
03299 &other,
03300 _dbus_string_get_length (&other) - 1,
03301 1))
03302 _dbus_assert_not_reached ("could not replace end character");
03303
03304 _dbus_assert (_dbus_string_get_length (&str) == i);
03305 _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
03306 _dbus_assert (_dbus_string_equal_c_str (&other,
03307 "HelloHello WorldWorle"));
03308
03309 _dbus_string_free (&str);
03310 _dbus_string_free (&other);
03311
03312
03313
03314 if (!_dbus_string_init (&str))
03315 _dbus_assert_not_reached ("failed to init string");
03316
03317 ch = 0;
03318 if (!_dbus_string_append_unichar (&str, 0xfffc))
03319 _dbus_assert_not_reached ("failed to append unichar");
03320
03321 _dbus_string_get_unichar (&str, 0, &ch, &i);
03322
03323 _dbus_assert (ch == 0xfffc);
03324 _dbus_assert (i == _dbus_string_get_length (&str));
03325
03326 _dbus_string_free (&str);
03327
03328
03329
03330 if (!_dbus_string_init (&str))
03331 _dbus_assert_not_reached ("failed to init string");
03332
03333 if (!_dbus_string_append (&str, "Hello"))
03334 _dbus_assert_not_reached ("failed to append Hello");
03335
03336 _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H');
03337 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e');
03338 _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l');
03339 _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l');
03340 _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o');
03341
03342 _dbus_string_set_byte (&str, 1, 'q');
03343 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');
03344
03345 if (!_dbus_string_insert_byte (&str, 0, 255))
03346 _dbus_assert_not_reached ("can't insert byte");
03347
03348 if (!_dbus_string_insert_byte (&str, 2, 'Z'))
03349 _dbus_assert_not_reached ("can't insert byte");
03350
03351 if (!_dbus_string_insert_byte (&str, _dbus_string_get_length (&str), 'W'))
03352 _dbus_assert_not_reached ("can't insert byte");
03353
03354 _dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
03355 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
03356 _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
03357 _dbus_assert (_dbus_string_get_byte (&str, 3) == 'q');
03358 _dbus_assert (_dbus_string_get_byte (&str, 4) == 'l');
03359 _dbus_assert (_dbus_string_get_byte (&str, 5) == 'l');
03360 _dbus_assert (_dbus_string_get_byte (&str, 6) == 'o');
03361 _dbus_assert (_dbus_string_get_byte (&str, 7) == 'W');
03362
03363 _dbus_string_free (&str);
03364
03365
03366
03367 if (!_dbus_string_init (&str))
03368 _dbus_assert_not_reached ("failed to init string");
03369
03370 if (!_dbus_string_append_int (&str, 27))
03371 _dbus_assert_not_reached ("failed to append int");
03372
03373 i = _dbus_string_get_length (&str);
03374
03375 if (!_dbus_string_parse_int (&str, 0, &v, &end))
03376 _dbus_assert_not_reached ("failed to parse int");
03377
03378 _dbus_assert (v == 27);
03379 _dbus_assert (end == i);
03380
03381 _dbus_string_free (&str);
03382
03383 if (!_dbus_string_init (&str))
03384 _dbus_assert_not_reached ("failed to init string");
03385
03386 if (!_dbus_string_append_double (&str, 50.3))
03387 _dbus_assert_not_reached ("failed to append float");
03388
03389 i = _dbus_string_get_length (&str);
03390
03391 if (!_dbus_string_parse_double (&str, 0, &d, &end))
03392 _dbus_assert_not_reached ("failed to parse float");
03393
03394 _dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6));
03395 _dbus_assert (end == i);
03396
03397 _dbus_string_free (&str);
03398
03399
03400 if (!_dbus_string_init (&str))
03401 _dbus_assert_not_reached ("failed to init string");
03402
03403 if (!_dbus_string_append (&str, "Hello"))
03404 _dbus_assert_not_reached ("couldn't append to string");
03405
03406 if (!_dbus_string_find (&str, 0, "He", &i))
03407 _dbus_assert_not_reached ("didn't find 'He'");
03408 _dbus_assert (i == 0);
03409
03410 if (!_dbus_string_find (&str, 0, "Hello", &i))
03411 _dbus_assert_not_reached ("didn't find 'Hello'");
03412 _dbus_assert (i == 0);
03413
03414 if (!_dbus_string_find (&str, 0, "ello", &i))
03415 _dbus_assert_not_reached ("didn't find 'ello'");
03416 _dbus_assert (i == 1);
03417
03418 if (!_dbus_string_find (&str, 0, "lo", &i))
03419 _dbus_assert_not_reached ("didn't find 'lo'");
03420 _dbus_assert (i == 3);
03421
03422 if (!_dbus_string_find (&str, 2, "lo", &i))
03423 _dbus_assert_not_reached ("didn't find 'lo'");
03424 _dbus_assert (i == 3);
03425
03426 if (_dbus_string_find (&str, 4, "lo", &i))
03427 _dbus_assert_not_reached ("did find 'lo'");
03428
03429 if (!_dbus_string_find (&str, 0, "l", &i))
03430 _dbus_assert_not_reached ("didn't find 'l'");
03431 _dbus_assert (i == 2);
03432
03433 if (!_dbus_string_find (&str, 0, "H", &i))
03434 _dbus_assert_not_reached ("didn't find 'H'");
03435 _dbus_assert (i == 0);
03436
03437 if (!_dbus_string_find (&str, 0, "", &i))
03438 _dbus_assert_not_reached ("didn't find ''");
03439 _dbus_assert (i == 0);
03440
03441 if (_dbus_string_find (&str, 0, "Hello!", NULL))
03442 _dbus_assert_not_reached ("Did find 'Hello!'");
03443
03444 if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
03445 _dbus_assert_not_reached ("Did find 'Oh, Hello'");
03446
03447 if (_dbus_string_find (&str, 0, "ill", NULL))
03448 _dbus_assert_not_reached ("Did find 'ill'");
03449
03450 if (_dbus_string_find (&str, 0, "q", NULL))
03451 _dbus_assert_not_reached ("Did find 'q'");
03452
03453 if (!_dbus_string_find_to (&str, 0, 2, "He", NULL))
03454 _dbus_assert_not_reached ("Didn't find 'He'");
03455
03456 if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL))
03457 _dbus_assert_not_reached ("Did find 'Hello'");
03458
03459 if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i))
03460 _dbus_assert_not_reached ("Did not find 'H'");
03461 _dbus_assert (i == 0);
03462
03463 if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i))
03464 _dbus_assert_not_reached ("Did not find 'o'");
03465 _dbus_assert (i == _dbus_string_get_length (&str) - 1);
03466
03467 if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i))
03468 _dbus_assert_not_reached ("Did find 'o'");
03469 _dbus_assert (i == -1);
03470
03471 if (_dbus_string_find_byte_backward (&str, 1, 'e', &i))
03472 _dbus_assert_not_reached ("Did find 'e'");
03473 _dbus_assert (i == -1);
03474
03475 if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i))
03476 _dbus_assert_not_reached ("Didn't find 'e'");
03477 _dbus_assert (i == 1);
03478
03479 _dbus_string_free (&str);
03480
03481
03482 test_roundtrips (test_base64_roundtrip);
03483 test_roundtrips (test_hex_roundtrip);
03484
03485 return TRUE;
03486 }
03487
03488 #endif