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
00029 #include <stdio.h>
00030 #include "dbus-marshal.h"
00031 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
00032 #include "dbus-string-private.h"
00033 #include "dbus-protocol.h"
00034
00035 #include "dbus-sysdeps.h"
00036
00079 #define ALLOCATION_PADDING 8
00080
00085 #define MAX_MAX_LENGTH (_DBUS_INT_MAX - ALLOCATION_PADDING)
00086
00092 #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)
00093
00100 #define DBUS_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \
00101 DBUS_GENERIC_STRING_PREAMBLE (real); \
00102 _dbus_assert (!(real)->constant); \
00103 _dbus_assert (!(real)->locked)
00104
00112 #define DBUS_LOCKED_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \
00113 DBUS_GENERIC_STRING_PREAMBLE (real); \
00114 _dbus_assert (!(real)->constant)
00115
00121 #define DBUS_CONST_STRING_PREAMBLE(str) const DBusRealString *real = (DBusRealString*) str; \
00122 DBUS_GENERIC_STRING_PREAMBLE (real)
00123
00131 static void
00132 fixup_alignment (DBusRealString *real)
00133 {
00134 char *aligned;
00135 char *real_block;
00136 unsigned int old_align_offset;
00137
00138
00139 _dbus_assert (real->len <= real->allocated - ALLOCATION_PADDING);
00140
00141 old_align_offset = real->align_offset;
00142 real_block = real->str - old_align_offset;
00143
00144 aligned = _DBUS_ALIGN_ADDRESS (real_block, 8);
00145
00146 real->align_offset = aligned - real_block;
00147 real->str = aligned;
00148
00149 if (old_align_offset != real->align_offset)
00150 {
00151
00152 memmove (real_block + real->align_offset,
00153 real_block + old_align_offset,
00154 real->len + 1);
00155 }
00156
00157 _dbus_assert (real->align_offset < 8);
00158 _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str);
00159 }
00160
00161 static void
00162 undo_alignment (DBusRealString *real)
00163 {
00164 if (real->align_offset != 0)
00165 {
00166 memmove (real->str - real->align_offset,
00167 real->str,
00168 real->len + 1);
00169
00170 real->str = real->str - real->align_offset;
00171 real->align_offset = 0;
00172 }
00173 }
00174
00184 dbus_bool_t
00185 _dbus_string_init_preallocated (DBusString *str,
00186 int allocate_size)
00187 {
00188 DBusRealString *real;
00189
00190 _dbus_assert (str != NULL);
00191
00192 _dbus_assert (sizeof (DBusString) == sizeof (DBusRealString));
00193
00194 real = (DBusRealString*) str;
00195
00196
00197
00198
00199
00200
00201
00202 real->str = dbus_malloc (ALLOCATION_PADDING + allocate_size);
00203 if (real->str == NULL)
00204 return FALSE;
00205
00206 real->allocated = ALLOCATION_PADDING + allocate_size;
00207 real->len = 0;
00208 real->str[real->len] = '\0';
00209
00210 real->max_length = MAX_MAX_LENGTH;
00211 real->constant = FALSE;
00212 real->locked = FALSE;
00213 real->invalid = FALSE;
00214 real->align_offset = 0;
00215
00216 fixup_alignment (real);
00217
00218 return TRUE;
00219 }
00220
00228 dbus_bool_t
00229 _dbus_string_init (DBusString *str)
00230 {
00231 return _dbus_string_init_preallocated (str, 0);
00232 }
00233
00234
00235
00236
00237
00238
00239
00240 static void
00241 set_max_length (DBusString *str,
00242 int max_length)
00243 {
00244 DBusRealString *real;
00245
00246 real = (DBusRealString*) str;
00247
00248 real->max_length = max_length;
00249 }
00250
00260 void
00261 _dbus_string_init_const (DBusString *str,
00262 const char *value)
00263 {
00264 _dbus_assert (value != NULL);
00265
00266 _dbus_string_init_const_len (str, value,
00267 strlen (value));
00268 }
00269
00280 void
00281 _dbus_string_init_const_len (DBusString *str,
00282 const char *value,
00283 int len)
00284 {
00285 DBusRealString *real;
00286
00287 _dbus_assert (str != NULL);
00288 _dbus_assert (value != NULL);
00289 _dbus_assert (len <= MAX_MAX_LENGTH);
00290 _dbus_assert (len >= 0);
00291
00292 real = (DBusRealString*) str;
00293
00294 real->str = (char*) value;
00295 real->len = len;
00296 real->allocated = real->len + ALLOCATION_PADDING;
00297 real->max_length = real->len + 1;
00298 real->constant = TRUE;
00299 real->invalid = FALSE;
00300
00301
00302
00303
00304 }
00305
00311 void
00312 _dbus_string_free (DBusString *str)
00313 {
00314 DBusRealString *real = (DBusRealString*) str;
00315 DBUS_GENERIC_STRING_PREAMBLE (real);
00316
00317 if (real->constant)
00318 return;
00319 dbus_free (real->str - real->align_offset);
00320
00321 real->invalid = TRUE;
00322 }
00323
00324 #ifdef DBUS_BUILD_TESTS
00325
00326
00327
00337 void
00338 _dbus_string_lock (DBusString *str)
00339 {
00340 DBUS_LOCKED_STRING_PREAMBLE (str);
00341
00342 real->locked = TRUE;
00343
00344
00345
00346
00347 #define MAX_WASTE 48
00348 if (real->allocated - MAX_WASTE > real->len)
00349 {
00350 char *new_str;
00351 int new_allocated;
00352
00353 new_allocated = real->len + ALLOCATION_PADDING;
00354
00355 new_str = dbus_realloc (real->str - real->align_offset,
00356 new_allocated);
00357 if (new_str != NULL)
00358 {
00359 real->str = new_str + real->align_offset;
00360 real->allocated = new_allocated;
00361 fixup_alignment (real);
00362 }
00363 }
00364 }
00365 #endif
00366
00367 static dbus_bool_t
00368 reallocate_for_length (DBusRealString *real,
00369 int new_length)
00370 {
00371 int new_allocated;
00372 char *new_str;
00373
00374
00375
00376
00377 if (real->allocated > (MAX_MAX_LENGTH + ALLOCATION_PADDING) / 2)
00378 new_allocated = MAX_MAX_LENGTH + ALLOCATION_PADDING;
00379 else
00380 new_allocated = real->allocated * 2;
00381
00382
00383
00384
00385 #ifdef DBUS_BUILD_TESTS
00386 new_allocated = 0;
00387
00388
00389 #endif
00390
00391
00392 new_allocated = MAX (new_allocated, new_length + ALLOCATION_PADDING);
00393
00394 _dbus_assert (new_allocated >= real->allocated);
00395 new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
00396 if (new_str == NULL)
00397 return FALSE;
00398
00399 real->str = new_str + real->align_offset;
00400 real->allocated = new_allocated;
00401 fixup_alignment (real);
00402
00403 return TRUE;
00404 }
00405
00406 static dbus_bool_t
00407 set_length (DBusRealString *real,
00408 int new_length)
00409 {
00410
00411
00412
00413 if (new_length > real->max_length)
00414 return FALSE;
00415 else if (new_length > (real->allocated - ALLOCATION_PADDING) &&
00416 !reallocate_for_length (real, new_length))
00417 return FALSE;
00418 else
00419 {
00420 real->len = new_length;
00421 real->str[real->len] = '\0';
00422 return TRUE;
00423 }
00424 }
00425
00426 static dbus_bool_t
00427 open_gap (int len,
00428 DBusRealString *dest,
00429 int insert_at)
00430 {
00431 if (len == 0)
00432 return TRUE;
00433
00434 if (len > dest->max_length - dest->len)
00435 return FALSE;
00436
00437 if (!set_length (dest, dest->len + len))
00438 return FALSE;
00439
00440 memmove (dest->str + insert_at + len,
00441 dest->str + insert_at,
00442 dest->len - len - insert_at);
00443
00444 return TRUE;
00445 }
00446
00458 char*
00459 _dbus_string_get_data (DBusString *str)
00460 {
00461 DBUS_STRING_PREAMBLE (str);
00462
00463 return real->str;
00464 }
00465
00472 const char*
00473 _dbus_string_get_const_data (const DBusString *str)
00474 {
00475 DBUS_CONST_STRING_PREAMBLE (str);
00476
00477 return real->str;
00478 }
00479
00493 char*
00494 _dbus_string_get_data_len (DBusString *str,
00495 int start,
00496 int len)
00497 {
00498 DBUS_STRING_PREAMBLE (str);
00499 _dbus_assert (start >= 0);
00500 _dbus_assert (len >= 0);
00501 _dbus_assert (start <= real->len);
00502 _dbus_assert (len <= real->len - start);
00503
00504 return real->str + start;
00505 }
00506
00515 const char*
00516 _dbus_string_get_const_data_len (const DBusString *str,
00517 int start,
00518 int len)
00519 {
00520 DBUS_CONST_STRING_PREAMBLE (str);
00521 _dbus_assert (start >= 0);
00522 _dbus_assert (len >= 0);
00523 _dbus_assert (start <= real->len);
00524 _dbus_assert (len <= real->len - start);
00525
00526 return real->str + start;
00527 }
00528
00536 void
00537 _dbus_string_set_byte (DBusString *str,
00538 int i,
00539 unsigned char byte)
00540 {
00541 DBUS_STRING_PREAMBLE (str);
00542 _dbus_assert (i < real->len);
00543 _dbus_assert (i >= 0);
00544
00545 real->str[i] = byte;
00546 }
00547
00557 unsigned char
00558 _dbus_string_get_byte (const DBusString *str,
00559 int start)
00560 {
00561 DBUS_CONST_STRING_PREAMBLE (str);
00562 _dbus_assert (start <= real->len);
00563 _dbus_assert (start >= 0);
00564
00565 return real->str[start];
00566 }
00567
00578 dbus_bool_t
00579 _dbus_string_insert_bytes (DBusString *str,
00580 int i,
00581 int n_bytes,
00582 unsigned char byte)
00583 {
00584 DBUS_STRING_PREAMBLE (str);
00585 _dbus_assert (i <= real->len);
00586 _dbus_assert (i >= 0);
00587 _dbus_assert (n_bytes >= 0);
00588
00589 if (n_bytes == 0)
00590 return TRUE;
00591
00592 if (!open_gap (n_bytes, real, i))
00593 return FALSE;
00594
00595 memset (real->str + i, byte, n_bytes);
00596
00597 return TRUE;
00598 }
00599
00610 dbus_bool_t
00611 _dbus_string_steal_data (DBusString *str,
00612 char **data_return)
00613 {
00614 int old_max_length;
00615 DBUS_STRING_PREAMBLE (str);
00616 _dbus_assert (data_return != NULL);
00617
00618 undo_alignment (real);
00619
00620 *data_return = real->str;
00621
00622 old_max_length = real->max_length;
00623
00624
00625 if (!_dbus_string_init (str))
00626 {
00627
00628 real->str = *data_return;
00629 *data_return = NULL;
00630 fixup_alignment (real);
00631 return FALSE;
00632 }
00633
00634 real->max_length = old_max_length;
00635
00636 return TRUE;
00637 }
00638
00654 dbus_bool_t
00655 _dbus_string_steal_data_len (DBusString *str,
00656 char **data_return,
00657 int start,
00658 int len)
00659 {
00660 DBusString dest;
00661 DBUS_STRING_PREAMBLE (str);
00662 _dbus_assert (data_return != NULL);
00663 _dbus_assert (start >= 0);
00664 _dbus_assert (len >= 0);
00665 _dbus_assert (start <= real->len);
00666 _dbus_assert (len <= real->len - start);
00667
00668 if (!_dbus_string_init (&dest))
00669 return FALSE;
00670
00671 set_max_length (&dest, real->max_length);
00672
00673 if (!_dbus_string_move_len (str, start, len, &dest, 0))
00674 {
00675 _dbus_string_free (&dest);
00676 return FALSE;
00677 }
00678
00679 _dbus_warn ("Broken code in _dbus_string_steal_data_len(), see @todo, FIXME\n");
00680 if (!_dbus_string_steal_data (&dest, data_return))
00681 {
00682 _dbus_string_free (&dest);
00683 return FALSE;
00684 }
00685
00686 _dbus_string_free (&dest);
00687 return TRUE;
00688 }
00689
00690
00698 dbus_bool_t
00699 _dbus_string_copy_data (const DBusString *str,
00700 char **data_return)
00701 {
00702 DBUS_CONST_STRING_PREAMBLE (str);
00703 _dbus_assert (data_return != NULL);
00704
00705 *data_return = dbus_malloc (real->len + 1);
00706 if (*data_return == NULL)
00707 return FALSE;
00708
00709 memcpy (*data_return, real->str, real->len + 1);
00710
00711 return TRUE;
00712 }
00713
00723 dbus_bool_t
00724 _dbus_string_copy_data_len (const DBusString *str,
00725 char **data_return,
00726 int start,
00727 int len)
00728 {
00729 DBusString dest;
00730
00731 DBUS_CONST_STRING_PREAMBLE (str);
00732 _dbus_assert (data_return != NULL);
00733 _dbus_assert (start >= 0);
00734 _dbus_assert (len >= 0);
00735 _dbus_assert (start <= real->len);
00736 _dbus_assert (len <= real->len - start);
00737
00738 if (!_dbus_string_init (&dest))
00739 return FALSE;
00740
00741 set_max_length (&dest, real->max_length);
00742
00743 if (!_dbus_string_copy_len (str, start, len, &dest, 0))
00744 {
00745 _dbus_string_free (&dest);
00746 return FALSE;
00747 }
00748
00749 if (!_dbus_string_steal_data (&dest, data_return))
00750 {
00751 _dbus_string_free (&dest);
00752 return FALSE;
00753 }
00754
00755 _dbus_string_free (&dest);
00756 return TRUE;
00757 }
00758
00764 int
00765 _dbus_string_get_length (const DBusString *str)
00766 {
00767 DBUS_CONST_STRING_PREAMBLE (str);
00768
00769 return real->len;
00770 }
00771
00784 dbus_bool_t
00785 _dbus_string_lengthen (DBusString *str,
00786 int additional_length)
00787 {
00788 DBUS_STRING_PREAMBLE (str);
00789 _dbus_assert (additional_length >= 0);
00790
00791 if (additional_length > real->max_length - real->len)
00792 return FALSE;
00793
00794 return set_length (real,
00795 real->len + additional_length);
00796 }
00797
00804 void
00805 _dbus_string_shorten (DBusString *str,
00806 int length_to_remove)
00807 {
00808 DBUS_STRING_PREAMBLE (str);
00809 _dbus_assert (length_to_remove >= 0);
00810 _dbus_assert (length_to_remove <= real->len);
00811
00812 set_length (real,
00813 real->len - length_to_remove);
00814 }
00815
00826 dbus_bool_t
00827 _dbus_string_set_length (DBusString *str,
00828 int length)
00829 {
00830 DBUS_STRING_PREAMBLE (str);
00831 _dbus_assert (length >= 0);
00832
00833 return set_length (real, length);
00834 }
00835
00836 static dbus_bool_t
00837 align_length_then_lengthen (DBusString *str,
00838 int alignment,
00839 int then_lengthen_by)
00840 {
00841 unsigned long new_len;
00842 int delta;
00843 DBUS_STRING_PREAMBLE (str);
00844 _dbus_assert (alignment >= 1);
00845 _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
00846
00847 new_len = _DBUS_ALIGN_VALUE (real->len, alignment);
00848 if (new_len > (unsigned long) real->max_length - then_lengthen_by)
00849 return FALSE;
00850 new_len += then_lengthen_by;
00851
00852 delta = new_len - real->len;
00853 _dbus_assert (delta >= 0);
00854
00855 if (delta == 0)
00856 return TRUE;
00857
00858 if (!set_length (real, new_len))
00859 return FALSE;
00860
00861
00862
00863
00864 if (then_lengthen_by < delta)
00865 {
00866 unsigned int i;
00867 i = new_len - delta;
00868 while (i < (new_len - then_lengthen_by))
00869 {
00870 real->str[i] = '\0';
00871 ++i;
00872 }
00873 }
00874
00875 return TRUE;
00876 }
00877
00886 dbus_bool_t
00887 _dbus_string_align_length (DBusString *str,
00888 int alignment)
00889 {
00890 return align_length_then_lengthen (str, alignment, 0);
00891 }
00892
00893 static dbus_bool_t
00894 append (DBusRealString *real,
00895 const char *buffer,
00896 int buffer_len)
00897 {
00898 if (buffer_len == 0)
00899 return TRUE;
00900
00901 if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
00902 return FALSE;
00903
00904 memcpy (real->str + (real->len - buffer_len),
00905 buffer,
00906 buffer_len);
00907
00908 return TRUE;
00909 }
00910
00918 dbus_bool_t
00919 _dbus_string_append (DBusString *str,
00920 const char *buffer)
00921 {
00922 unsigned long buffer_len;
00923
00924 DBUS_STRING_PREAMBLE (str);
00925 _dbus_assert (buffer != NULL);
00926
00927 buffer_len = strlen (buffer);
00928 if (buffer_len > (unsigned long) real->max_length)
00929 return FALSE;
00930
00931 return append (real, buffer, buffer_len);
00932 }
00933
00942 dbus_bool_t
00943 _dbus_string_append_4_aligned (DBusString *str,
00944 const unsigned char octets[4])
00945 {
00946 dbus_uint32_t *p;
00947 DBUS_STRING_PREAMBLE (str);
00948
00949 if (!align_length_then_lengthen (str, 4, 4))
00950 return FALSE;
00951
00952 p = (dbus_uint32_t*) (real->str + (real->len - 4));
00953 *p = *((dbus_uint32_t*)octets);
00954
00955 return TRUE;
00956 }
00957
00966 dbus_bool_t
00967 _dbus_string_append_8_aligned (DBusString *str,
00968 const unsigned char octets[8])
00969 {
00970 #ifdef DBUS_HAVE_INT64
00971 dbus_uint64_t *p;
00972 DBUS_STRING_PREAMBLE (str);
00973
00974 if (!align_length_then_lengthen (str, 8, 8))
00975 return FALSE;
00976
00977 p = (dbus_uint64_t*) (real->str + (real->len - 8));
00978 *p = *((dbus_uint64_t*)octets);
00979 #else
00980 unsigned char *p;
00981 DBUS_STRING_PREAMBLE (str);
00982
00983 if (!align_length_then_lengthen (str, 8, 8))
00984 return FALSE;
00985
00986 p = real->str + (real->len - 8);
00987
00988 *p++ = octets[0];
00989 *p++ = octets[1];
00990 *p++ = octets[2];
00991 *p++ = octets[3];
00992 *p++ = octets[4];
00993 *p++ = octets[5];
00994 *p++ = octets[6];
00995 *p++ = octets[7];
00996 _dbus_assert (p == (real->str + real->len));
00997 #endif
00998
00999 return TRUE;
01000 }
01001
01011 dbus_bool_t
01012 _dbus_string_append_printf_valist (DBusString *str,
01013 const char *format,
01014 va_list args)
01015 {
01016 int len;
01017 char c;
01018 va_list args_copy;
01019
01020 DBUS_STRING_PREAMBLE (str);
01021
01022 DBUS_VA_COPY (args_copy, args);
01023
01024
01025 len = vsnprintf (&c, 1, format, args);
01026
01027 if (!_dbus_string_lengthen (str, len))
01028 {
01029
01030 va_end (args_copy);
01031 return FALSE;
01032 }
01033
01034 vsprintf (real->str + (real->len - len),
01035 format, args_copy);
01036
01037 va_end (args_copy);
01038
01039 return TRUE;
01040 }
01041
01050 dbus_bool_t
01051 _dbus_string_append_printf (DBusString *str,
01052 const char *format,
01053 ...)
01054 {
01055 va_list args;
01056 dbus_bool_t retval;
01057
01058 va_start (args, format);
01059 retval = _dbus_string_append_printf_valist (str, format, args);
01060 va_end (args);
01061
01062 return retval;
01063 }
01064
01073 dbus_bool_t
01074 _dbus_string_append_len (DBusString *str,
01075 const char *buffer,
01076 int len)
01077 {
01078 DBUS_STRING_PREAMBLE (str);
01079 _dbus_assert (buffer != NULL);
01080 _dbus_assert (len >= 0);
01081
01082 return append (real, buffer, len);
01083 }
01084
01093 dbus_bool_t
01094 _dbus_string_append_byte (DBusString *str,
01095 unsigned char byte)
01096 {
01097 DBUS_STRING_PREAMBLE (str);
01098
01099 if (!set_length (real, real->len + 1))
01100 return FALSE;
01101
01102 real->str[real->len-1] = byte;
01103
01104 return TRUE;
01105 }
01106
01114 dbus_bool_t
01115 _dbus_string_append_unichar (DBusString *str,
01116 dbus_unichar_t ch)
01117 {
01118 int len;
01119 int first;
01120 int i;
01121 char *out;
01122
01123 DBUS_STRING_PREAMBLE (str);
01124
01125
01126
01127 len = 0;
01128
01129 if (ch < 0x80)
01130 {
01131 first = 0;
01132 len = 1;
01133 }
01134 else if (ch < 0x800)
01135 {
01136 first = 0xc0;
01137 len = 2;
01138 }
01139 else if (ch < 0x10000)
01140 {
01141 first = 0xe0;
01142 len = 3;
01143 }
01144 else if (ch < 0x200000)
01145 {
01146 first = 0xf0;
01147 len = 4;
01148 }
01149 else if (ch < 0x4000000)
01150 {
01151 first = 0xf8;
01152 len = 5;
01153 }
01154 else
01155 {
01156 first = 0xfc;
01157 len = 6;
01158 }
01159
01160 if (len > (real->max_length - real->len))
01161 return FALSE;
01162
01163 if (!set_length (real, real->len + len))
01164 return FALSE;
01165
01166 out = real->str + (real->len - len);
01167
01168 for (i = len - 1; i > 0; --i)
01169 {
01170 out[i] = (ch & 0x3f) | 0x80;
01171 ch >>= 6;
01172 }
01173 out[0] = ch | first;
01174
01175 return TRUE;
01176 }
01177
01178 static void
01179 delete (DBusRealString *real,
01180 int start,
01181 int len)
01182 {
01183 if (len == 0)
01184 return;
01185
01186 memmove (real->str + start, real->str + start + len, real->len - (start + len));
01187 real->len -= len;
01188 real->str[real->len] = '\0';
01189 }
01190
01200 void
01201 _dbus_string_delete (DBusString *str,
01202 int start,
01203 int len)
01204 {
01205 DBUS_STRING_PREAMBLE (str);
01206 _dbus_assert (start >= 0);
01207 _dbus_assert (len >= 0);
01208 _dbus_assert (start <= real->len);
01209 _dbus_assert (len <= real->len - start);
01210
01211 delete (real, start, len);
01212 }
01213
01214 static dbus_bool_t
01215 copy (DBusRealString *source,
01216 int start,
01217 int len,
01218 DBusRealString *dest,
01219 int insert_at)
01220 {
01221 if (len == 0)
01222 return TRUE;
01223
01224 if (!open_gap (len, dest, insert_at))
01225 return FALSE;
01226
01227 memcpy (dest->str + insert_at,
01228 source->str + start,
01229 len);
01230
01231 return TRUE;
01232 }
01233
01243 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at) \
01244 DBusRealString *real_source = (DBusRealString*) source; \
01245 DBusRealString *real_dest = (DBusRealString*) dest; \
01246 _dbus_assert ((source) != (dest)); \
01247 DBUS_GENERIC_STRING_PREAMBLE (real_source); \
01248 DBUS_GENERIC_STRING_PREAMBLE (real_dest); \
01249 _dbus_assert (!real_dest->constant); \
01250 _dbus_assert (!real_dest->locked); \
01251 _dbus_assert ((start) >= 0); \
01252 _dbus_assert ((start) <= real_source->len); \
01253 _dbus_assert ((insert_at) >= 0); \
01254 _dbus_assert ((insert_at) <= real_dest->len)
01255
01266 dbus_bool_t
01267 _dbus_string_move (DBusString *source,
01268 int start,
01269 DBusString *dest,
01270 int insert_at)
01271 {
01272 DBusRealString *real_source = (DBusRealString*) source;
01273 _dbus_assert (start <= real_source->len);
01274
01275 return _dbus_string_move_len (source, start,
01276 real_source->len - start,
01277 dest, insert_at);
01278 }
01279
01290 dbus_bool_t
01291 _dbus_string_copy (const DBusString *source,
01292 int start,
01293 DBusString *dest,
01294 int insert_at)
01295 {
01296 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01297
01298 return copy (real_source, start,
01299 real_source->len - start,
01300 real_dest,
01301 insert_at);
01302 }
01303
01318 dbus_bool_t
01319 _dbus_string_move_len (DBusString *source,
01320 int start,
01321 int len,
01322 DBusString *dest,
01323 int insert_at)
01324
01325 {
01326 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01327 _dbus_assert (len >= 0);
01328 _dbus_assert ((start + len) <= real_source->len);
01329
01330
01331 if (len == 0)
01332 {
01333 return TRUE;
01334 }
01335 else if (start == 0 &&
01336 len == real_source->len &&
01337 real_dest->len == 0)
01338 {
01339
01340
01341
01342
01343
01344
01345 #define ASSIGN_DATA(a, b) do { \
01346 (a)->str = (b)->str; \
01347 (a)->len = (b)->len; \
01348 (a)->allocated = (b)->allocated; \
01349 (a)->align_offset = (b)->align_offset; \
01350 } while (0)
01351
01352 DBusRealString tmp;
01353
01354 ASSIGN_DATA (&tmp, real_source);
01355 ASSIGN_DATA (real_source, real_dest);
01356 ASSIGN_DATA (real_dest, &tmp);
01357
01358 return TRUE;
01359 }
01360 else
01361 {
01362 if (!copy (real_source, start, len,
01363 real_dest,
01364 insert_at))
01365 return FALSE;
01366
01367 delete (real_source, start,
01368 len);
01369
01370 return TRUE;
01371 }
01372 }
01373
01385 dbus_bool_t
01386 _dbus_string_copy_len (const DBusString *source,
01387 int start,
01388 int len,
01389 DBusString *dest,
01390 int insert_at)
01391 {
01392 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01393 _dbus_assert (len >= 0);
01394 _dbus_assert (start <= real_source->len);
01395 _dbus_assert (len <= real_source->len - start);
01396
01397 return copy (real_source, start, len,
01398 real_dest,
01399 insert_at);
01400 }
01401
01423 dbus_bool_t
01424 _dbus_string_replace_len (const DBusString *source,
01425 int start,
01426 int len,
01427 DBusString *dest,
01428 int replace_at,
01429 int replace_len)
01430 {
01431 DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
01432 _dbus_assert (len >= 0);
01433 _dbus_assert (start <= real_source->len);
01434 _dbus_assert (len <= real_source->len - start);
01435 _dbus_assert (replace_at >= 0);
01436 _dbus_assert (replace_at <= real_dest->len);
01437 _dbus_assert (replace_len <= real_dest->len - replace_at);
01438
01439 if (!copy (real_source, start, len,
01440 real_dest, replace_at))
01441 return FALSE;
01442
01443 delete (real_dest, replace_at + len, replace_len);
01444
01445 return TRUE;
01446 }
01447
01448
01449
01450
01451
01457 #define UTF8_COMPUTE(Char, Mask, Len) \
01458 if (Char < 128) \
01459 { \
01460 Len = 1; \
01461 Mask = 0x7f; \
01462 } \
01463 else if ((Char & 0xe0) == 0xc0) \
01464 { \
01465 Len = 2; \
01466 Mask = 0x1f; \
01467 } \
01468 else if ((Char & 0xf0) == 0xe0) \
01469 { \
01470 Len = 3; \
01471 Mask = 0x0f; \
01472 } \
01473 else if ((Char & 0xf8) == 0xf0) \
01474 { \
01475 Len = 4; \
01476 Mask = 0x07; \
01477 } \
01478 else if ((Char & 0xfc) == 0xf8) \
01479 { \
01480 Len = 5; \
01481 Mask = 0x03; \
01482 } \
01483 else if ((Char & 0xfe) == 0xfc) \
01484 { \
01485 Len = 6; \
01486 Mask = 0x01; \
01487 } \
01488 else \
01489 Len = -1;
01490
01495 #define UTF8_LENGTH(Char) \
01496 ((Char) < 0x80 ? 1 : \
01497 ((Char) < 0x800 ? 2 : \
01498 ((Char) < 0x10000 ? 3 : \
01499 ((Char) < 0x200000 ? 4 : \
01500 ((Char) < 0x4000000 ? 5 : 6)))))
01501
01511 #define UTF8_GET(Result, Chars, Count, Mask, Len) \
01512 (Result) = (Chars)[0] & (Mask); \
01513 for ((Count) = 1; (Count) < (Len); ++(Count)) \
01514 { \
01515 if (((Chars)[(Count)] & 0xc0) != 0x80) \
01516 { \
01517 (Result) = -1; \
01518 break; \
01519 } \
01520 (Result) <<= 6; \
01521 (Result) |= ((Chars)[(Count)] & 0x3f); \
01522 }
01523
01529 #define UNICODE_VALID(Char) \
01530 ((Char) < 0x110000 && \
01531 (((Char) & 0xFFFFF800) != 0xD800) && \
01532 ((Char) < 0xFDD0 || (Char) > 0xFDEF) && \
01533 ((Char) & 0xFFFF) != 0xFFFF)
01534
01545 void
01546 _dbus_string_get_unichar (const DBusString *str,
01547 int start,
01548 dbus_unichar_t *ch_return,
01549 int *end_return)
01550 {
01551 int i, mask, len;
01552 dbus_unichar_t result;
01553 unsigned char c;
01554 unsigned char *p;
01555 DBUS_CONST_STRING_PREAMBLE (str);
01556 _dbus_assert (start >= 0);
01557 _dbus_assert (start <= real->len);
01558
01559 if (ch_return)
01560 *ch_return = 0;
01561 if (end_return)
01562 *end_return = real->len;
01563
01564 mask = 0;
01565 p = real->str + start;
01566 c = *p;
01567
01568 UTF8_COMPUTE (c, mask, len);
01569 if (len == -1)
01570 return;
01571 UTF8_GET (result, p, i, mask, len);
01572
01573 if (result == (dbus_unichar_t)-1)
01574 return;
01575
01576 if (ch_return)
01577 *ch_return = result;
01578 if (end_return)
01579 *end_return = start + len;
01580 }
01581
01596 dbus_bool_t
01597 _dbus_string_find (const DBusString *str,
01598 int start,
01599 const char *substr,
01600 int *found)
01601 {
01602 return _dbus_string_find_to (str, start,
01603 ((const DBusRealString*)str)->len,
01604 substr, found);
01605 }
01606
01623 dbus_bool_t
01624 _dbus_string_find_to (const DBusString *str,
01625 int start,
01626 int end,
01627 const char *substr,
01628 int *found)
01629 {
01630 int i;
01631 DBUS_CONST_STRING_PREAMBLE (str);
01632 _dbus_assert (substr != NULL);
01633 _dbus_assert (start <= real->len);
01634 _dbus_assert (start >= 0);
01635 _dbus_assert (substr != NULL);
01636 _dbus_assert (end <= real->len);
01637 _dbus_assert (start <= end);
01638
01639
01640 if (*substr == '\0')
01641 {
01642 if (found)
01643 *found = start;
01644 return TRUE;
01645 }
01646
01647 i = start;
01648 while (i < end)
01649 {
01650 if (real->str[i] == substr[0])
01651 {
01652 int j = i + 1;
01653
01654 while (j < end)
01655 {
01656 if (substr[j - i] == '\0')
01657 break;
01658 else if (real->str[j] != substr[j - i])
01659 break;
01660
01661 ++j;
01662 }
01663
01664 if (substr[j - i] == '\0')
01665 {
01666 if (found)
01667 *found = i;
01668 return TRUE;
01669 }
01670 }
01671
01672 ++i;
01673 }
01674
01675 if (found)
01676 *found = end;
01677
01678 return FALSE;
01679 }
01680
01691 dbus_bool_t
01692 _dbus_string_find_byte_backward (const DBusString *str,
01693 int start,
01694 unsigned char byte,
01695 int *found)
01696 {
01697 int i;
01698 DBUS_CONST_STRING_PREAMBLE (str);
01699 _dbus_assert (start <= real->len);
01700 _dbus_assert (start >= 0);
01701 _dbus_assert (found != NULL);
01702
01703 i = start - 1;
01704 while (i >= 0)
01705 {
01706 if (real->str[i] == byte)
01707 break;
01708
01709 --i;
01710 }
01711
01712 if (found)
01713 *found = i;
01714
01715 return i >= 0;
01716 }
01717
01728 dbus_bool_t
01729 _dbus_string_find_blank (const DBusString *str,
01730 int start,
01731 int *found)
01732 {
01733 int i;
01734 DBUS_CONST_STRING_PREAMBLE (str);
01735 _dbus_assert (start <= real->len);
01736 _dbus_assert (start >= 0);
01737
01738 i = start;
01739 while (i < real->len)
01740 {
01741 if (real->str[i] == ' ' ||
01742 real->str[i] == '\t')
01743 {
01744 if (found)
01745 *found = i;
01746 return TRUE;
01747 }
01748
01749 ++i;
01750 }
01751
01752 if (found)
01753 *found = real->len;
01754
01755 return FALSE;
01756 }
01757
01766 void
01767 _dbus_string_skip_blank (const DBusString *str,
01768 int start,
01769 int *end)
01770 {
01771 int i;
01772 DBUS_CONST_STRING_PREAMBLE (str);
01773 _dbus_assert (start <= real->len);
01774 _dbus_assert (start >= 0);
01775
01776 i = start;
01777 while (i < real->len)
01778 {
01779 if (!(real->str[i] == ' ' ||
01780 real->str[i] == '\t'))
01781 break;
01782
01783 ++i;
01784 }
01785
01786 _dbus_assert (i == real->len || !(real->str[i] == ' ' ||
01787 real->str[i] == '\t'));
01788
01789 if (end)
01790 *end = i;
01791 }
01792
01801 void
01802 _dbus_string_skip_white (const DBusString *str,
01803 int start,
01804 int *end)
01805 {
01806 int i;
01807 DBUS_CONST_STRING_PREAMBLE (str);
01808 _dbus_assert (start <= real->len);
01809 _dbus_assert (start >= 0);
01810
01811 i = start;
01812 while (i < real->len)
01813 {
01814 if (!(real->str[i] == ' ' ||
01815 real->str[i] == '\n' ||
01816 real->str[i] == '\r' ||
01817 real->str[i] == '\t'))
01818 break;
01819
01820 ++i;
01821 }
01822
01823 _dbus_assert (i == real->len || !(real->str[i] == ' ' ||
01824 real->str[i] == '\t'));
01825
01826 if (end)
01827 *end = i;
01828 }
01829
01845 dbus_bool_t
01846 _dbus_string_pop_line (DBusString *source,
01847 DBusString *dest)
01848 {
01849 int eol;
01850 dbus_bool_t have_newline;
01851
01852 _dbus_string_set_length (dest, 0);
01853
01854 eol = 0;
01855 if (_dbus_string_find (source, 0, "\n", &eol))
01856 {
01857 have_newline = TRUE;
01858 eol += 1;
01859 }
01860 else
01861 {
01862 eol = _dbus_string_get_length (source);
01863 have_newline = FALSE;
01864 }
01865
01866 if (eol == 0)
01867 return FALSE;
01868
01869 if (!_dbus_string_move_len (source, 0, eol,
01870 dest, 0))
01871 {
01872 return FALSE;
01873 }
01874
01875
01876 if (have_newline)
01877 {
01878 dbus_bool_t have_cr;
01879
01880 _dbus_assert (_dbus_string_get_length (dest) > 0);
01881
01882 if (_dbus_string_get_length (dest) > 1 &&
01883 _dbus_string_get_byte (dest,
01884 _dbus_string_get_length (dest) - 2) == '\r')
01885 have_cr = TRUE;
01886 else
01887 have_cr = FALSE;
01888
01889 _dbus_string_set_length (dest,
01890 _dbus_string_get_length (dest) -
01891 (have_cr ? 2 : 1));
01892 }
01893
01894 return TRUE;
01895 }
01896
01903 void
01904 _dbus_string_delete_first_word (DBusString *str)
01905 {
01906 int i;
01907
01908 if (_dbus_string_find_blank (str, 0, &i))
01909 _dbus_string_skip_blank (str, i, &i);
01910
01911 _dbus_string_delete (str, 0, i);
01912 }
01913
01919 void
01920 _dbus_string_delete_leading_blanks (DBusString *str)
01921 {
01922 int i;
01923
01924 _dbus_string_skip_blank (str, 0, &i);
01925
01926 if (i > 0)
01927 _dbus_string_delete (str, 0, i);
01928 }
01929
01939 dbus_bool_t
01940 _dbus_string_equal (const DBusString *a,
01941 const DBusString *b)
01942 {
01943 const unsigned char *ap;
01944 const unsigned char *bp;
01945 const unsigned char *a_end;
01946 const DBusRealString *real_a = (const DBusRealString*) a;
01947 const DBusRealString *real_b = (const DBusRealString*) b;
01948 DBUS_GENERIC_STRING_PREAMBLE (real_a);
01949 DBUS_GENERIC_STRING_PREAMBLE (real_b);
01950
01951 if (real_a->len != real_b->len)
01952 return FALSE;
01953
01954 ap = real_a->str;
01955 bp = real_b->str;
01956 a_end = real_a->str + real_a->len;
01957 while (ap != a_end)
01958 {
01959 if (*ap != *bp)
01960 return FALSE;
01961
01962 ++ap;
01963 ++bp;
01964 }
01965
01966 return TRUE;
01967 }
01968
01981 dbus_bool_t
01982 _dbus_string_equal_len (const DBusString *a,
01983 const DBusString *b,
01984 int len)
01985 {
01986 const unsigned char *ap;
01987 const unsigned char *bp;
01988 const unsigned char *a_end;
01989 const DBusRealString *real_a = (const DBusRealString*) a;
01990 const DBusRealString *real_b = (const DBusRealString*) b;
01991 DBUS_GENERIC_STRING_PREAMBLE (real_a);
01992 DBUS_GENERIC_STRING_PREAMBLE (real_b);
01993
01994 if (real_a->len != real_b->len &&
01995 (real_a->len < len || real_b->len < len))
01996 return FALSE;
01997
01998 ap = real_a->str;
01999 bp = real_b->str;
02000 a_end = real_a->str + MIN (real_a->len, len);
02001 while (ap != a_end)
02002 {
02003 if (*ap != *bp)
02004 return FALSE;
02005
02006 ++ap;
02007 ++bp;
02008 }
02009
02010 return TRUE;
02011 }
02012
02020 dbus_bool_t
02021 _dbus_string_equal_c_str (const DBusString *a,
02022 const char *c_str)
02023 {
02024 const unsigned char *ap;
02025 const unsigned char *bp;
02026 const unsigned char *a_end;
02027 const DBusRealString *real_a = (const DBusRealString*) a;
02028 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02029 _dbus_assert (c_str != NULL);
02030
02031 ap = real_a->str;
02032 bp = (const unsigned char*) c_str;
02033 a_end = real_a->str + real_a->len;
02034 while (ap != a_end && *bp)
02035 {
02036 if (*ap != *bp)
02037 return FALSE;
02038
02039 ++ap;
02040 ++bp;
02041 }
02042
02043 if (ap != a_end || *bp)
02044 return FALSE;
02045
02046 return TRUE;
02047 }
02048
02056 dbus_bool_t
02057 _dbus_string_starts_with_c_str (const DBusString *a,
02058 const char *c_str)
02059 {
02060 const unsigned char *ap;
02061 const unsigned char *bp;
02062 const unsigned char *a_end;
02063 const DBusRealString *real_a = (const DBusRealString*) a;
02064 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02065 _dbus_assert (c_str != NULL);
02066
02067 ap = real_a->str;
02068 bp = (const unsigned char*) c_str;
02069 a_end = real_a->str + real_a->len;
02070 while (ap != a_end && *bp)
02071 {
02072 if (*ap != *bp)
02073 return FALSE;
02074
02075 ++ap;
02076 ++bp;
02077 }
02078
02079 if (*bp == '\0')
02080 return TRUE;
02081 else
02082 return FALSE;
02083 }
02084
02094 dbus_bool_t
02095 _dbus_string_ends_with_c_str (const DBusString *a,
02096 const char *c_str)
02097 {
02098 const unsigned char *ap;
02099 const unsigned char *bp;
02100 const unsigned char *a_end;
02101 unsigned long c_str_len;
02102 const DBusRealString *real_a = (const DBusRealString*) a;
02103 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02104 _dbus_assert (c_str != NULL);
02105
02106 c_str_len = strlen (c_str);
02107 if (((unsigned long)real_a->len) < c_str_len)
02108 return FALSE;
02109
02110 ap = real_a->str + (real_a->len - c_str_len);
02111 bp = (const unsigned char*) c_str;
02112 a_end = real_a->str + real_a->len;
02113 while (ap != a_end)
02114 {
02115 if (*ap != *bp)
02116 return FALSE;
02117
02118 ++ap;
02119 ++bp;
02120 }
02121
02122 _dbus_assert (*ap == '\0');
02123 _dbus_assert (*bp == '\0');
02124
02125 return TRUE;
02126 }
02127
02138 dbus_bool_t
02139 _dbus_string_hex_encode (const DBusString *source,
02140 int start,
02141 DBusString *dest,
02142 int insert_at)
02143 {
02144 DBusString result;
02145 const char hexdigits[16] = {
02146 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
02147 'a', 'b', 'c', 'd', 'e', 'f'
02148 };
02149 const unsigned char *p;
02150 const unsigned char *end;
02151 dbus_bool_t retval;
02152
02153 _dbus_assert (start <= _dbus_string_get_length (source));
02154
02155 if (!_dbus_string_init (&result))
02156 return FALSE;
02157
02158 retval = FALSE;
02159
02160 p = (const unsigned char*) _dbus_string_get_const_data (source);
02161 end = p + _dbus_string_get_length (source);
02162 p += start;
02163
02164 while (p != end)
02165 {
02166 if (!_dbus_string_append_byte (&result,
02167 hexdigits[(*p >> 4)]))
02168 goto out;
02169
02170 if (!_dbus_string_append_byte (&result,
02171 hexdigits[(*p & 0x0f)]))
02172 goto out;
02173
02174 ++p;
02175 }
02176
02177 if (!_dbus_string_move (&result, 0, dest, insert_at))
02178 goto out;
02179
02180 retval = TRUE;
02181
02182 out:
02183 _dbus_string_free (&result);
02184 return retval;
02185 }
02186
02197 dbus_bool_t
02198 _dbus_string_hex_decode (const DBusString *source,
02199 int start,
02200 int *end_return,
02201 DBusString *dest,
02202 int insert_at)
02203 {
02204 DBusString result;
02205 const unsigned char *p;
02206 const unsigned char *end;
02207 dbus_bool_t retval;
02208 dbus_bool_t high_bits;
02209
02210 _dbus_assert (start <= _dbus_string_get_length (source));
02211
02212 if (!_dbus_string_init (&result))
02213 return FALSE;
02214
02215 retval = FALSE;
02216
02217 high_bits = TRUE;
02218 p = (const unsigned char*) _dbus_string_get_const_data (source);
02219 end = p + _dbus_string_get_length (source);
02220 p += start;
02221
02222 while (p != end)
02223 {
02224 unsigned int val;
02225
02226 switch (*p)
02227 {
02228 case '0':
02229 val = 0;
02230 break;
02231 case '1':
02232 val = 1;
02233 break;
02234 case '2':
02235 val = 2;
02236 break;
02237 case '3':
02238 val = 3;
02239 break;
02240 case '4':
02241 val = 4;
02242 break;
02243 case '5':
02244 val = 5;
02245 break;
02246 case '6':
02247 val = 6;
02248 break;
02249 case '7':
02250 val = 7;
02251 break;
02252 case '8':
02253 val = 8;
02254 break;
02255 case '9':
02256 val = 9;
02257 break;
02258 case 'a':
02259 case 'A':
02260 val = 10;
02261 break;
02262 case 'b':
02263 case 'B':
02264 val = 11;
02265 break;
02266 case 'c':
02267 case 'C':
02268 val = 12;
02269 break;
02270 case 'd':
02271 case 'D':
02272 val = 13;
02273 break;
02274 case 'e':
02275 case 'E':
02276 val = 14;
02277 break;
02278 case 'f':
02279 case 'F':
02280 val = 15;
02281 break;
02282 default:
02283 goto done;
02284 }
02285
02286 if (high_bits)
02287 {
02288 if (!_dbus_string_append_byte (&result,
02289 val << 4))
02290 goto out;
02291 }
02292 else
02293 {
02294 int len;
02295 unsigned char b;
02296
02297 len = _dbus_string_get_length (&result);
02298
02299 b = _dbus_string_get_byte (&result, len - 1);
02300
02301 b |= val;
02302
02303 _dbus_string_set_byte (&result, len - 1, b);
02304 }
02305
02306 high_bits = !high_bits;
02307
02308 ++p;
02309 }
02310
02311 done:
02312 if (!_dbus_string_move (&result, 0, dest, insert_at))
02313 goto out;
02314
02315 if (end_return)
02316 *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
02317
02318 retval = TRUE;
02319
02320 out:
02321 _dbus_string_free (&result);
02322 return retval;
02323 }
02324
02338 dbus_bool_t
02339 _dbus_string_validate_ascii (const DBusString *str,
02340 int start,
02341 int len)
02342 {
02343 const unsigned char *s;
02344 const unsigned char *end;
02345 DBUS_CONST_STRING_PREAMBLE (str);
02346 _dbus_assert (start >= 0);
02347 _dbus_assert (start <= real->len);
02348 _dbus_assert (len >= 0);
02349
02350 if (len > real->len - start)
02351 return FALSE;
02352
02353 s = real->str + start;
02354 end = s + len;
02355 while (s != end)
02356 {
02357 if (_DBUS_UNLIKELY (*s == '\0' ||
02358 ((*s & ~0x7f) != 0)))
02359 return FALSE;
02360
02361 ++s;
02362 }
02363
02364 return TRUE;
02365 }
02366
02382 dbus_bool_t
02383 _dbus_string_validate_utf8 (const DBusString *str,
02384 int start,
02385 int len)
02386 {
02387 const unsigned char *p;
02388 const unsigned char *end;
02389 DBUS_CONST_STRING_PREAMBLE (str);
02390 _dbus_assert (start >= 0);
02391 _dbus_assert (start <= real->len);
02392 _dbus_assert (len >= 0);
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402 if (_DBUS_UNLIKELY (len > real->len - start))
02403 return FALSE;
02404
02405 p = real->str + start;
02406 end = p + len;
02407
02408 while (p < end)
02409 {
02410 int i, mask = 0, char_len;
02411 dbus_unichar_t result;
02412 unsigned char c = (unsigned char) *p;
02413
02414 UTF8_COMPUTE (c, mask, char_len);
02415
02416 if (_DBUS_UNLIKELY (char_len == -1))
02417 break;
02418
02419
02420 if (_DBUS_UNLIKELY ((end - p) < char_len))
02421 break;
02422
02423 UTF8_GET (result, p, i, mask, char_len);
02424
02425 if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len))
02426 break;
02427
02428 if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1))
02429 break;
02430
02431 if (_DBUS_UNLIKELY (!UNICODE_VALID (result)))
02432 break;
02433
02434 p += char_len;
02435 }
02436
02437
02438
02439
02440 if (_DBUS_UNLIKELY (p != end))
02441 return FALSE;
02442 else
02443 return TRUE;
02444 }
02445
02459 dbus_bool_t
02460 _dbus_string_validate_nul (const DBusString *str,
02461 int start,
02462 int len)
02463 {
02464 const unsigned char *s;
02465 const unsigned char *end;
02466 DBUS_CONST_STRING_PREAMBLE (str);
02467 _dbus_assert (start >= 0);
02468 _dbus_assert (len >= 0);
02469 _dbus_assert (start <= real->len);
02470
02471 if (len > real->len - start)
02472 return FALSE;
02473
02474 s = real->str + start;
02475 end = s + len;
02476 while (s != end)
02477 {
02478 if (_DBUS_UNLIKELY (*s != '\0'))
02479 return FALSE;
02480 ++s;
02481 }
02482
02483 return TRUE;
02484 }
02485
02503 dbus_bool_t
02504 _dbus_string_validate_path (const DBusString *str,
02505 int start,
02506 int len)
02507 {
02508 const unsigned char *s;
02509 const unsigned char *end;
02510 const unsigned char *last_slash;
02511
02512 DBUS_CONST_STRING_PREAMBLE (str);
02513 _dbus_assert (start >= 0);
02514 _dbus_assert (len >= 0);
02515 _dbus_assert (start <= real->len);
02516
02517 if (len > real->len - start)
02518 return FALSE;
02519
02520 if (len > DBUS_MAXIMUM_NAME_LENGTH)
02521 return FALSE;
02522
02523 if (len == 0)
02524 return FALSE;
02525
02526 s = real->str + start;
02527 end = s + len;
02528
02529 if (*s != '/')
02530 return FALSE;
02531 last_slash = s;
02532 ++s;
02533
02534 while (s != end)
02535 {
02536 if (*s == '/')
02537 {
02538 if ((s - last_slash) < 2)
02539 return FALSE;
02540
02541 last_slash = s;
02542 }
02543
02544 ++s;
02545 }
02546
02547 if ((end - last_slash) < 2 &&
02548 len > 1)
02549 return FALSE;
02550
02551 return TRUE;
02552 }
02553
02558 #define VALID_INITIAL_NAME_CHARACTER(c) \
02559 ( ((c) >= 'A' && (c) <= 'Z') || \
02560 ((c) >= 'a' && (c) <= 'z') || \
02561 ((c) == '_') )
02562
02567 #define VALID_NAME_CHARACTER(c) \
02568 ( ((c) >= '0' && (c) <= '9') || \
02569 ((c) >= 'A' && (c) <= 'Z') || \
02570 ((c) >= 'a' && (c) <= 'z') || \
02571 ((c) == '_') )
02572
02586 dbus_bool_t
02587 _dbus_string_validate_interface (const DBusString *str,
02588 int start,
02589 int len)
02590 {
02591 const unsigned char *s;
02592 const unsigned char *end;
02593 const unsigned char *iface;
02594 const unsigned char *last_dot;
02595
02596 DBUS_CONST_STRING_PREAMBLE (str);
02597 _dbus_assert (start >= 0);
02598 _dbus_assert (len >= 0);
02599 _dbus_assert (start <= real->len);
02600
02601 if (len > real->len - start)
02602 return FALSE;
02603
02604 if (len > DBUS_MAXIMUM_NAME_LENGTH)
02605 return FALSE;
02606
02607 if (len == 0)
02608 return FALSE;
02609
02610 last_dot = NULL;
02611 iface = real->str + start;
02612 end = iface + len;
02613 s = iface;
02614
02615
02616
02617
02618 if (_DBUS_UNLIKELY (*s == '.'))
02619 return FALSE;
02620 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
02621 return FALSE;
02622 else
02623 ++s;
02624
02625 while (s != end)
02626 {
02627 if (*s == '.')
02628 {
02629 if (_DBUS_UNLIKELY ((s + 1) == end))
02630 return FALSE;
02631 else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*(s + 1))))
02632 return FALSE;
02633 last_dot = s;
02634 ++s;
02635 }
02636 else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
02637 {
02638 return FALSE;
02639 }
02640
02641 ++s;
02642 }
02643
02644 if (_DBUS_UNLIKELY (last_dot == NULL))
02645 return FALSE;
02646
02647 return TRUE;
02648 }
02649
02663 dbus_bool_t
02664 _dbus_string_validate_member (const DBusString *str,
02665 int start,
02666 int len)
02667 {
02668 const unsigned char *s;
02669 const unsigned char *end;
02670 const unsigned char *member;
02671
02672 DBUS_CONST_STRING_PREAMBLE (str);
02673 _dbus_assert (start >= 0);
02674 _dbus_assert (len >= 0);
02675 _dbus_assert (start <= real->len);
02676
02677 if (len > real->len - start)
02678 return FALSE;
02679
02680 if (len > DBUS_MAXIMUM_NAME_LENGTH)
02681 return FALSE;
02682
02683 if (len == 0)
02684 return FALSE;
02685
02686 member = real->str + start;
02687 end = member + len;
02688 s = member;
02689
02690
02691
02692
02693
02694 if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
02695 return FALSE;
02696 else
02697 ++s;
02698
02699 while (s != end)
02700 {
02701 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
02702 {
02703 return FALSE;
02704 }
02705
02706 ++s;
02707 }
02708
02709 return TRUE;
02710 }
02711
02725 dbus_bool_t
02726 _dbus_string_validate_error_name (const DBusString *str,
02727 int start,
02728 int len)
02729 {
02730
02731 return _dbus_string_validate_interface (str, start, len);
02732 }
02733
02734
02735 static dbus_bool_t
02736 _dbus_string_validate_base_service (const DBusString *str,
02737 int start,
02738 int len)
02739 {
02740 const unsigned char *s;
02741 const unsigned char *end;
02742 const unsigned char *service;
02743
02744 DBUS_CONST_STRING_PREAMBLE (str);
02745 _dbus_assert (start >= 0);
02746 _dbus_assert (len >= 0);
02747 _dbus_assert (start <= real->len);
02748
02749 if (len > real->len - start)
02750 return FALSE;
02751
02752 if (len > DBUS_MAXIMUM_NAME_LENGTH)
02753 return FALSE;
02754
02755 _dbus_assert (len > 0);
02756
02757 service = real->str + start;
02758 end = service + len;
02759 _dbus_assert (*service == ':');
02760 s = service + 1;
02761
02762 while (s != end)
02763 {
02764 if (*s == '.')
02765 {
02766 if (_DBUS_UNLIKELY ((s + 1) == end))
02767 return FALSE;
02768 if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*(s + 1))))
02769 return FALSE;
02770 ++s;
02771 }
02772 else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
02773 {
02774 return FALSE;
02775 }
02776
02777 ++s;
02778 }
02779
02780 return TRUE;
02781 }
02782
02796 dbus_bool_t
02797 _dbus_string_validate_service (const DBusString *str,
02798 int start,
02799 int len)
02800 {
02801 if (_DBUS_UNLIKELY (len == 0))
02802 return FALSE;
02803 if (_dbus_string_get_byte (str, start) == ':')
02804 return _dbus_string_validate_base_service (str, start, len);
02805 else
02806 return _dbus_string_validate_interface (str, start, len);
02807 }
02808
02814 void
02815 _dbus_string_zero (DBusString *str)
02816 {
02817 DBUS_STRING_PREAMBLE (str);
02818
02819 memset (real->str - real->align_offset, '\0', real->allocated);
02820 }
02823 #ifdef DBUS_BUILD_TESTS
02824 #include "dbus-test.h"
02825 #include <stdio.h>
02826
02840 dbus_bool_t
02841 _dbus_string_parse_basic_type (const DBusString *str,
02842 char type,
02843 int start,
02844 void *value,
02845 int *end_return)
02846 {
02847 int end = start;
02848
02849 switch (type)
02850 {
02851 case DBUS_TYPE_BOOLEAN:
02852 {
02853 int len = _dbus_string_get_length (str) - start;
02854 if (len >= 5 && _dbus_string_find_to (str, start, start + 5, "false", NULL))
02855 {
02856 end += 5;
02857 *(unsigned char *) value = TRUE;
02858 }
02859 else if (len >= 4 && _dbus_string_find_to (str, start, start + 4, "true", NULL))
02860 {
02861 end += 4;
02862 *(unsigned char *) value = FALSE;
02863 }
02864 else
02865 _dbus_warn ("could not parse BOOLEAN\n");
02866 break;
02867 }
02868 case DBUS_TYPE_BYTE:
02869 {
02870 long val = 0;
02871
02872 if (_dbus_string_get_byte (str, start) == '\'' &&
02873 _dbus_string_get_length (str) >= start + 4 &&
02874 _dbus_string_get_byte (str, start + 1) == '\\' &&
02875 _dbus_string_get_byte (str, start + 2) == '\'' &&
02876 _dbus_string_get_byte (str, start + 3) == '\'')
02877 {
02878 val = '\'';
02879 end += 4;
02880 }
02881 else if (_dbus_string_get_byte (str, start) == '\'' &&
02882 _dbus_string_get_length (str) >= start + 3 &&
02883 _dbus_string_get_byte (str, start + 2) == '\'')
02884 {
02885 val = _dbus_string_get_byte (str, start + 1);
02886 end += 3;
02887 }
02888 else
02889 {
02890 if (!_dbus_string_parse_int (str, start, &val, &end))
02891 _dbus_warn ("Failed to parse integer for BYTE\n");
02892 }
02893
02894 if (val > 255)
02895 _dbus_warn ("A byte must be in range 0-255 not %ld\n", val);
02896
02897 *(unsigned char *) value = val;
02898 break;
02899 }
02900 case DBUS_TYPE_INT32:
02901 {
02902 long val;
02903 if (_dbus_string_parse_int (str, start, &val, &end))
02904 *(dbus_int32_t *)value = val;
02905 break;
02906 }
02907 case DBUS_TYPE_UINT32:
02908 {
02909 unsigned long val;
02910 if (_dbus_string_parse_uint (str, start, &val, &end))
02911 *(dbus_uint32_t *)value = val;
02912 break;
02913 }
02914 #ifdef DBUS_HAVE_INT64
02915 case DBUS_TYPE_INT64:
02916 case DBUS_TYPE_UINT64:
02917
02918 _dbus_assert_not_reached ("string -> [u]int64 not supported yet");
02919 break;
02920 #endif
02921 case DBUS_TYPE_DOUBLE:
02922 _dbus_string_parse_double (str, start, value, &end);
02923 break;
02924 default:
02925 _dbus_assert_not_reached ("not a basic type");
02926 break;
02927 }
02928 if (end_return)
02929 *end_return = end;
02930
02931 return end != start;
02932 }
02933
02934 static void
02935 test_max_len (DBusString *str,
02936 int max_len)
02937 {
02938 if (max_len > 0)
02939 {
02940 if (!_dbus_string_set_length (str, max_len - 1))
02941 _dbus_assert_not_reached ("setting len to one less than max should have worked");
02942 }
02943
02944 if (!_dbus_string_set_length (str, max_len))
02945 _dbus_assert_not_reached ("setting len to max len should have worked");
02946
02947 if (_dbus_string_set_length (str, max_len + 1))
02948 _dbus_assert_not_reached ("setting len to one more than max len should not have worked");
02949
02950 if (!_dbus_string_set_length (str, 0))
02951 _dbus_assert_not_reached ("setting len to zero should have worked");
02952 }
02953
02954 static void
02955 test_hex_roundtrip (const unsigned char *data,
02956 int len)
02957 {
02958 DBusString orig;
02959 DBusString encoded;
02960 DBusString decoded;
02961 int end;
02962
02963 if (len < 0)
02964 len = strlen (data);
02965
02966 if (!_dbus_string_init (&orig))
02967 _dbus_assert_not_reached ("could not init string");
02968
02969 if (!_dbus_string_init (&encoded))
02970 _dbus_assert_not_reached ("could not init string");
02971
02972 if (!_dbus_string_init (&decoded))
02973 _dbus_assert_not_reached ("could not init string");
02974
02975 if (!_dbus_string_append_len (&orig, data, len))
02976 _dbus_assert_not_reached ("couldn't append orig data");
02977
02978 if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))
02979 _dbus_assert_not_reached ("could not encode");
02980
02981 if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0))
02982 _dbus_assert_not_reached ("could not decode");
02983
02984 _dbus_assert (_dbus_string_get_length (&encoded) == end);
02985
02986 if (!_dbus_string_equal (&orig, &decoded))
02987 {
02988 const char *s;
02989
02990 printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
02991 _dbus_string_get_length (&orig),
02992 _dbus_string_get_length (&encoded),
02993 _dbus_string_get_length (&decoded));
02994 printf ("Original: %s\n", data);
02995 s = _dbus_string_get_const_data (&decoded);
02996 printf ("Decoded: %s\n", s);
02997 _dbus_assert_not_reached ("original string not the same as string decoded from hex");
02998 }
02999
03000 _dbus_string_free (&orig);
03001 _dbus_string_free (&encoded);
03002 _dbus_string_free (&decoded);
03003 }
03004
03005 typedef void (* TestRoundtripFunc) (const unsigned char *data,
03006 int len);
03007 static void
03008 test_roundtrips (TestRoundtripFunc func)
03009 {
03010 (* func) ("Hello this is a string\n", -1);
03011 (* func) ("Hello this is a string\n1", -1);
03012 (* func) ("Hello this is a string\n12", -1);
03013 (* func) ("Hello this is a string\n123", -1);
03014 (* func) ("Hello this is a string\n1234", -1);
03015 (* func) ("Hello this is a string\n12345", -1);
03016 (* func) ("", 0);
03017 (* func) ("1", 1);
03018 (* func) ("12", 2);
03019 (* func) ("123", 3);
03020 (* func) ("1234", 4);
03021 (* func) ("12345", 5);
03022 (* func) ("", 1);
03023 (* func) ("1", 2);
03024 (* func) ("12", 3);
03025 (* func) ("123", 4);
03026 (* func) ("1234", 5);
03027 (* func) ("12345", 6);
03028 {
03029 unsigned char buf[512];
03030 int i;
03031
03032 i = 0;
03033 while (i < _DBUS_N_ELEMENTS (buf))
03034 {
03035 buf[i] = i;
03036 ++i;
03037 }
03038 i = 0;
03039 while (i < _DBUS_N_ELEMENTS (buf))
03040 {
03041 (* func) (buf, i);
03042 ++i;
03043 }
03044 }
03045 }
03046
03047
03058 dbus_bool_t
03059 _dbus_string_test (void)
03060 {
03061 DBusString str;
03062 DBusString other;
03063 int i, end;
03064 long v;
03065 double d;
03066 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 };
03067 char *s;
03068 dbus_unichar_t ch;
03069 const char *valid_paths[] = {
03070 "/",
03071 "/foo/bar",
03072 "/foo",
03073 "/foo/bar/baz"
03074 };
03075 const char *invalid_paths[] = {
03076 "bar",
03077 "bar/baz",
03078 "/foo/bar/",
03079 "/foo/"
03080 "foo/",
03081 "boo//blah",
03082 "//",
03083 "
03084 "foo
03085 "Hello World",
03086 "",
03087 " ",
03088 "foo bar"
03089 };
03090
03091 const char *valid_interfaces[] = {
03092 "org.freedesktop.Foo",
03093 "Bar.Baz",
03094 "Blah.Blah.Blah.Blah.Blah",
03095 "a.b",
03096 "a.b.c.d.e.f.g",
03097 "a0.b1.c2.d3.e4.f5.g6",
03098 "abc123.foo27"
03099 };
03100 const char *invalid_interfaces[] = {
03101 ".",
03102 "",
03103 "..",
03104 ".Foo.Bar",
03105 "..Foo.Bar",
03106 "Foo.Bar.",
03107 "Foo.Bar..",
03108 "Foo",
03109 "9foo.bar.baz",
03110 "foo.bar..baz",
03111 "foo.bar...baz",
03112 "foo.bar.b..blah",
03113 ":",
03114 ":0-1",
03115 "10",
03116 ":11.34324",
03117 "0.0.0",
03118 "0..0",
03119 "foo.Bar.%",
03120 "foo.Bar!!",
03121 "!Foo.bar.bz",
03122 "foo.$.blah",
03123 "",
03124 " ",
03125 "foo bar"
03126 };
03127
03128 const char *valid_base_services[] = {
03129 ":0",
03130 ":a",
03131 ":",
03132 ":.a",
03133 ":.1",
03134 ":0.1",
03135 ":000.2222",
03136 ":.blah",
03137 ":abce.freedesktop.blah"
03138 };
03139 const char *invalid_base_services[] = {
03140 ":-",
03141 ":!",
03142 ":0-10",
03143 ":blah.",
03144 ":blah.",
03145 ":blah..org",
03146 ":blah.org..",
03147 ":..blah.org",
03148 "",
03149 " ",
03150 "foo bar"
03151 };
03152
03153 const char *valid_members[] = {
03154 "Hello",
03155 "Bar",
03156 "foobar",
03157 "_foobar",
03158 "foo89"
03159 };
03160
03161 const char *invalid_members[] = {
03162 "9Hello",
03163 "10",
03164 "1",
03165 "foo-bar",
03166 "blah.org",
03167 ".blah",
03168 "blah.",
03169 "Hello.",
03170 "!foo",
03171 "",
03172 " ",
03173 "foo bar"
03174 };
03175
03176 i = 0;
03177 while (i < _DBUS_N_ELEMENTS (lens))
03178 {
03179 if (!_dbus_string_init (&str))
03180 _dbus_assert_not_reached ("failed to init string");
03181
03182 set_max_length (&str, lens[i]);
03183
03184 test_max_len (&str, lens[i]);
03185 _dbus_string_free (&str);
03186
03187 ++i;
03188 }
03189
03190
03191 i = 0;
03192 while (i < _DBUS_N_ELEMENTS (lens))
03193 {
03194 int j;
03195
03196 if (!_dbus_string_init (&str))
03197 _dbus_assert_not_reached ("failed to init string");
03198
03199 set_max_length (&str, lens[i]);
03200
03201 if (!_dbus_string_set_length (&str, lens[i]))
03202 _dbus_assert_not_reached ("failed to set string length");
03203
03204 j = lens[i];
03205 while (j > 0)
03206 {
03207 _dbus_assert (_dbus_string_get_length (&str) == j);
03208 if (j > 0)
03209 {
03210 _dbus_string_shorten (&str, 1);
03211 _dbus_assert (_dbus_string_get_length (&str) == (j - 1));
03212 }
03213 --j;
03214 }
03215
03216 _dbus_string_free (&str);
03217
03218 ++i;
03219 }
03220
03221
03222 if (!_dbus_string_init (&str))
03223 _dbus_assert_not_reached ("failed to init string");
03224
03225 i = 0;
03226 while (i < 10)
03227 {
03228 if (!_dbus_string_append (&str, "a"))
03229 _dbus_assert_not_reached ("failed to append string to string\n");
03230
03231 _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1);
03232
03233 if (!_dbus_string_append_byte (&str, 'b'))
03234 _dbus_assert_not_reached ("failed to append byte to string\n");
03235
03236 _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2);
03237
03238 ++i;
03239 }
03240
03241 _dbus_string_free (&str);
03242
03243
03244
03245 if (!_dbus_string_init (&str))
03246 _dbus_assert_not_reached ("failed to init string");
03247
03248 if (!_dbus_string_append (&str, "Hello World"))
03249 _dbus_assert_not_reached ("could not append to string");
03250
03251 i = _dbus_string_get_length (&str);
03252
03253 if (!_dbus_string_steal_data (&str, &s))
03254 _dbus_assert_not_reached ("failed to steal data");
03255
03256 _dbus_assert (_dbus_string_get_length (&str) == 0);
03257 _dbus_assert (((int)strlen (s)) == i);
03258
03259 dbus_free (s);
03260
03261
03262
03263 if (!_dbus_string_append (&str, "Hello World"))
03264 _dbus_assert_not_reached ("could not append to string");
03265
03266 i = _dbus_string_get_length (&str);
03267
03268 if (!_dbus_string_init (&other))
03269 _dbus_assert_not_reached ("could not init string");
03270
03271 if (!_dbus_string_move (&str, 0, &other, 0))
03272 _dbus_assert_not_reached ("could not move");
03273
03274 _dbus_assert (_dbus_string_get_length (&str) == 0);
03275 _dbus_assert (_dbus_string_get_length (&other) == i);
03276
03277 if (!_dbus_string_append (&str, "Hello World"))
03278 _dbus_assert_not_reached ("could not append to string");
03279
03280 if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other)))
03281 _dbus_assert_not_reached ("could not move");
03282
03283 _dbus_assert (_dbus_string_get_length (&str) == 0);
03284 _dbus_assert (_dbus_string_get_length (&other) == i * 2);
03285
03286 if (!_dbus_string_append (&str, "Hello World"))
03287 _dbus_assert_not_reached ("could not append to string");
03288
03289 if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2))
03290 _dbus_assert_not_reached ("could not move");
03291
03292 _dbus_assert (_dbus_string_get_length (&str) == 0);
03293 _dbus_assert (_dbus_string_get_length (&other) == i * 3);
03294
03295 _dbus_string_free (&other);
03296
03297
03298
03299 if (!_dbus_string_append (&str, "Hello World"))
03300 _dbus_assert_not_reached ("could not append to string");
03301
03302 i = _dbus_string_get_length (&str);
03303
03304 if (!_dbus_string_init (&other))
03305 _dbus_assert_not_reached ("could not init string");
03306
03307 if (!_dbus_string_copy (&str, 0, &other, 0))
03308 _dbus_assert_not_reached ("could not copy");
03309
03310 _dbus_assert (_dbus_string_get_length (&str) == i);
03311 _dbus_assert (_dbus_string_get_length (&other) == i);
03312
03313 if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other)))
03314 _dbus_assert_not_reached ("could not copy");
03315
03316 _dbus_assert (_dbus_string_get_length (&str) == i);
03317 _dbus_assert (_dbus_string_get_length (&other) == i * 2);
03318 _dbus_assert (_dbus_string_equal_c_str (&other,
03319 "Hello WorldHello World"));
03320
03321 if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2))
03322 _dbus_assert_not_reached ("could not copy");
03323
03324 _dbus_assert (_dbus_string_get_length (&str) == i);
03325 _dbus_assert (_dbus_string_get_length (&other) == i * 3);
03326 _dbus_assert (_dbus_string_equal_c_str (&other,
03327 "Hello WorldHello WorldHello World"));
03328
03329 _dbus_string_free (&str);
03330 _dbus_string_free (&other);
03331
03332
03333
03334 if (!_dbus_string_init (&str))
03335 _dbus_assert_not_reached ("failed to init string");
03336
03337 if (!_dbus_string_append (&str, "Hello World"))
03338 _dbus_assert_not_reached ("could not append to string");
03339
03340 i = _dbus_string_get_length (&str);
03341
03342 if (!_dbus_string_init (&other))
03343 _dbus_assert_not_reached ("could not init string");
03344
03345 if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
03346 &other, 0, _dbus_string_get_length (&other)))
03347 _dbus_assert_not_reached ("could not replace");
03348
03349 _dbus_assert (_dbus_string_get_length (&str) == i);
03350 _dbus_assert (_dbus_string_get_length (&other) == i);
03351 _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World"));
03352
03353 if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
03354 &other, 5, 1))
03355 _dbus_assert_not_reached ("could not replace center space");
03356
03357 _dbus_assert (_dbus_string_get_length (&str) == i);
03358 _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
03359 _dbus_assert (_dbus_string_equal_c_str (&other,
03360 "HelloHello WorldWorld"));
03361
03362
03363 if (!_dbus_string_replace_len (&str, 1, 1,
03364 &other,
03365 _dbus_string_get_length (&other) - 1,
03366 1))
03367 _dbus_assert_not_reached ("could not replace end character");
03368
03369 _dbus_assert (_dbus_string_get_length (&str) == i);
03370 _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
03371 _dbus_assert (_dbus_string_equal_c_str (&other,
03372 "HelloHello WorldWorle"));
03373
03374 _dbus_string_free (&str);
03375 _dbus_string_free (&other);
03376
03377
03378
03379 if (!_dbus_string_init (&str))
03380 _dbus_assert_not_reached ("failed to init string");
03381
03382 ch = 0;
03383 if (!_dbus_string_append_unichar (&str, 0xfffc))
03384 _dbus_assert_not_reached ("failed to append unichar");
03385
03386 _dbus_string_get_unichar (&str, 0, &ch, &i);
03387
03388 _dbus_assert (ch == 0xfffc);
03389 _dbus_assert (i == _dbus_string_get_length (&str));
03390
03391 _dbus_string_free (&str);
03392
03393
03394
03395 if (!_dbus_string_init (&str))
03396 _dbus_assert_not_reached ("failed to init string");
03397
03398 if (!_dbus_string_append (&str, "Hello"))
03399 _dbus_assert_not_reached ("failed to append Hello");
03400
03401 _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H');
03402 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e');
03403 _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l');
03404 _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l');
03405 _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o');
03406
03407 _dbus_string_set_byte (&str, 1, 'q');
03408 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');
03409
03410 if (!_dbus_string_insert_bytes (&str, 0, 1, 255))
03411 _dbus_assert_not_reached ("can't insert byte");
03412
03413 if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z'))
03414 _dbus_assert_not_reached ("can't insert byte");
03415
03416 if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W'))
03417 _dbus_assert_not_reached ("can't insert byte");
03418
03419 _dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
03420 _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
03421 _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
03422 _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z');
03423 _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z');
03424 _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z');
03425 _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q');
03426 _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l');
03427 _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l');
03428 _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o');
03429 _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W');
03430
03431 _dbus_string_free (&str);
03432
03433
03434
03435 if (!_dbus_string_init (&str))
03436 _dbus_assert_not_reached ("failed to init string");
03437
03438 if (!_dbus_string_append_int (&str, 27))
03439 _dbus_assert_not_reached ("failed to append int");
03440
03441 i = _dbus_string_get_length (&str);
03442
03443 if (!_dbus_string_parse_int (&str, 0, &v, &end))
03444 _dbus_assert_not_reached ("failed to parse int");
03445
03446 _dbus_assert (v == 27);
03447 _dbus_assert (end == i);
03448
03449 _dbus_string_free (&str);
03450
03451 if (!_dbus_string_init (&str))
03452 _dbus_assert_not_reached ("failed to init string");
03453
03454 if (!_dbus_string_append_double (&str, 50.3))
03455 _dbus_assert_not_reached ("failed to append float");
03456
03457 i = _dbus_string_get_length (&str);
03458
03459 if (!_dbus_string_parse_double (&str, 0, &d, &end))
03460 _dbus_assert_not_reached ("failed to parse float");
03461
03462 _dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6));
03463 _dbus_assert (end == i);
03464
03465 _dbus_string_free (&str);
03466
03467
03468 if (!_dbus_string_init (&str))
03469 _dbus_assert_not_reached ("failed to init string");
03470
03471 if (!_dbus_string_append (&str, "Hello"))
03472 _dbus_assert_not_reached ("couldn't append to string");
03473
03474 if (!_dbus_string_find (&str, 0, "He", &i))
03475 _dbus_assert_not_reached ("didn't find 'He'");
03476 _dbus_assert (i == 0);
03477
03478 if (!_dbus_string_find (&str, 0, "Hello", &i))
03479 _dbus_assert_not_reached ("didn't find 'Hello'");
03480 _dbus_assert (i == 0);
03481
03482 if (!_dbus_string_find (&str, 0, "ello", &i))
03483 _dbus_assert_not_reached ("didn't find 'ello'");
03484 _dbus_assert (i == 1);
03485
03486 if (!_dbus_string_find (&str, 0, "lo", &i))
03487 _dbus_assert_not_reached ("didn't find 'lo'");
03488 _dbus_assert (i == 3);
03489
03490 if (!_dbus_string_find (&str, 2, "lo", &i))
03491 _dbus_assert_not_reached ("didn't find 'lo'");
03492 _dbus_assert (i == 3);
03493
03494 if (_dbus_string_find (&str, 4, "lo", &i))
03495 _dbus_assert_not_reached ("did find 'lo'");
03496
03497 if (!_dbus_string_find (&str, 0, "l", &i))
03498 _dbus_assert_not_reached ("didn't find 'l'");
03499 _dbus_assert (i == 2);
03500
03501 if (!_dbus_string_find (&str, 0, "H", &i))
03502 _dbus_assert_not_reached ("didn't find 'H'");
03503 _dbus_assert (i == 0);
03504
03505 if (!_dbus_string_find (&str, 0, "", &i))
03506 _dbus_assert_not_reached ("didn't find ''");
03507 _dbus_assert (i == 0);
03508
03509 if (_dbus_string_find (&str, 0, "Hello!", NULL))
03510 _dbus_assert_not_reached ("Did find 'Hello!'");
03511
03512 if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
03513 _dbus_assert_not_reached ("Did find 'Oh, Hello'");
03514
03515 if (_dbus_string_find (&str, 0, "ill", NULL))
03516 _dbus_assert_not_reached ("Did find 'ill'");
03517
03518 if (_dbus_string_find (&str, 0, "q", NULL))
03519 _dbus_assert_not_reached ("Did find 'q'");
03520
03521 if (!_dbus_string_find_to (&str, 0, 2, "He", NULL))
03522 _dbus_assert_not_reached ("Didn't find 'He'");
03523
03524 if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL))
03525 _dbus_assert_not_reached ("Did find 'Hello'");
03526
03527 if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i))
03528 _dbus_assert_not_reached ("Did not find 'H'");
03529 _dbus_assert (i == 0);
03530
03531 if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i))
03532 _dbus_assert_not_reached ("Did not find 'o'");
03533 _dbus_assert (i == _dbus_string_get_length (&str) - 1);
03534
03535 if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i))
03536 _dbus_assert_not_reached ("Did find 'o'");
03537 _dbus_assert (i == -1);
03538
03539 if (_dbus_string_find_byte_backward (&str, 1, 'e', &i))
03540 _dbus_assert_not_reached ("Did find 'e'");
03541 _dbus_assert (i == -1);
03542
03543 if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i))
03544 _dbus_assert_not_reached ("Didn't find 'e'");
03545 _dbus_assert (i == 1);
03546
03547 _dbus_string_free (&str);
03548
03549
03550 _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string");
03551 if (!_dbus_string_init (&other))
03552 _dbus_assert_not_reached ("could not init string");
03553
03554 if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0))
03555 _dbus_assert_not_reached ("deccoded bogus hex string with no error");
03556
03557 _dbus_assert (end == 8);
03558
03559 _dbus_string_free (&other);
03560
03561 test_roundtrips (test_hex_roundtrip);
03562
03563
03564 i = 0;
03565 while (i < (int) _DBUS_N_ELEMENTS (valid_paths))
03566 {
03567 _dbus_string_init_const (&str, valid_paths[i]);
03568
03569 if (!_dbus_string_validate_path (&str, 0,
03570 _dbus_string_get_length (&str)))
03571 {
03572 _dbus_warn ("Path \"%s\" should have been valid\n", valid_paths[i]);
03573 _dbus_assert_not_reached ("invalid path");
03574 }
03575
03576 ++i;
03577 }
03578
03579 i = 0;
03580 while (i < (int) _DBUS_N_ELEMENTS (invalid_paths))
03581 {
03582 _dbus_string_init_const (&str, invalid_paths[i]);
03583
03584 if (_dbus_string_validate_path (&str, 0,
03585 _dbus_string_get_length (&str)))
03586 {
03587 _dbus_warn ("Path \"%s\" should have been invalid\n", invalid_paths[i]);
03588 _dbus_assert_not_reached ("valid path");
03589 }
03590
03591 ++i;
03592 }
03593
03594
03595 i = 0;
03596 while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
03597 {
03598 _dbus_string_init_const (&str, valid_interfaces[i]);
03599
03600 if (!_dbus_string_validate_interface (&str, 0,
03601 _dbus_string_get_length (&str)))
03602 {
03603 _dbus_warn ("Interface \"%s\" should have been valid\n", valid_interfaces[i]);
03604 _dbus_assert_not_reached ("invalid interface");
03605 }
03606
03607 ++i;
03608 }
03609
03610 i = 0;
03611 while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
03612 {
03613 _dbus_string_init_const (&str, invalid_interfaces[i]);
03614
03615 if (_dbus_string_validate_interface (&str, 0,
03616 _dbus_string_get_length (&str)))
03617 {
03618 _dbus_warn ("Interface \"%s\" should have been invalid\n", invalid_interfaces[i]);
03619 _dbus_assert_not_reached ("valid interface");
03620 }
03621
03622 ++i;
03623 }
03624
03625
03626
03627
03628 i = 0;
03629 while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
03630 {
03631 _dbus_string_init_const (&str, valid_interfaces[i]);
03632
03633 if (!_dbus_string_validate_service (&str, 0,
03634 _dbus_string_get_length (&str)))
03635 {
03636 _dbus_warn ("Service \"%s\" should have been valid\n", valid_interfaces[i]);
03637 _dbus_assert_not_reached ("invalid service");
03638 }
03639
03640 ++i;
03641 }
03642
03643 i = 0;
03644 while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
03645 {
03646 if (invalid_interfaces[i][0] != ':')
03647 {
03648 _dbus_string_init_const (&str, invalid_interfaces[i]);
03649
03650 if (_dbus_string_validate_service (&str, 0,
03651 _dbus_string_get_length (&str)))
03652 {
03653 _dbus_warn ("Service \"%s\" should have been invalid\n", invalid_interfaces[i]);
03654 _dbus_assert_not_reached ("valid service");
03655 }
03656 }
03657
03658 ++i;
03659 }
03660
03661
03662 i = 0;
03663 while (i < (int) _DBUS_N_ELEMENTS (valid_base_services))
03664 {
03665 _dbus_string_init_const (&str, valid_base_services[i]);
03666
03667 if (!_dbus_string_validate_service (&str, 0,
03668 _dbus_string_get_length (&str)))
03669 {
03670 _dbus_warn ("Service \"%s\" should have been valid\n", valid_base_services[i]);
03671 _dbus_assert_not_reached ("invalid base service");
03672 }
03673
03674 ++i;
03675 }
03676
03677 i = 0;
03678 while (i < (int) _DBUS_N_ELEMENTS (invalid_base_services))
03679 {
03680 _dbus_string_init_const (&str, invalid_base_services[i]);
03681
03682 if (_dbus_string_validate_service (&str, 0,
03683 _dbus_string_get_length (&str)))
03684 {
03685 _dbus_warn ("Service \"%s\" should have been invalid\n", invalid_base_services[i]);
03686 _dbus_assert_not_reached ("valid base service");
03687 }
03688
03689 ++i;
03690 }
03691
03692
03693
03694
03695 i = 0;
03696 while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
03697 {
03698 _dbus_string_init_const (&str, valid_interfaces[i]);
03699
03700 if (!_dbus_string_validate_error_name (&str, 0,
03701 _dbus_string_get_length (&str)))
03702 {
03703 _dbus_warn ("Error name \"%s\" should have been valid\n", valid_interfaces[i]);
03704 _dbus_assert_not_reached ("invalid error name");
03705 }
03706
03707 ++i;
03708 }
03709
03710 i = 0;
03711 while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
03712 {
03713 if (invalid_interfaces[i][0] != ':')
03714 {
03715 _dbus_string_init_const (&str, invalid_interfaces[i]);
03716
03717 if (_dbus_string_validate_error_name (&str, 0,
03718 _dbus_string_get_length (&str)))
03719 {
03720 _dbus_warn ("Error name \"%s\" should have been invalid\n", invalid_interfaces[i]);
03721 _dbus_assert_not_reached ("valid error name");
03722 }
03723 }
03724
03725 ++i;
03726 }
03727
03728
03729 i = 0;
03730 while (i < (int) _DBUS_N_ELEMENTS (valid_members))
03731 {
03732 _dbus_string_init_const (&str, valid_members[i]);
03733
03734 if (!_dbus_string_validate_member (&str, 0,
03735 _dbus_string_get_length (&str)))
03736 {
03737 _dbus_warn ("Member \"%s\" should have been valid\n", valid_members[i]);
03738 _dbus_assert_not_reached ("invalid member");
03739 }
03740
03741 ++i;
03742 }
03743
03744 i = 0;
03745 while (i < (int) _DBUS_N_ELEMENTS (invalid_members))
03746 {
03747 _dbus_string_init_const (&str, invalid_members[i]);
03748
03749 if (_dbus_string_validate_member (&str, 0,
03750 _dbus_string_get_length (&str)))
03751 {
03752 _dbus_warn ("Member \"%s\" should have been invalid\n", invalid_members[i]);
03753 _dbus_assert_not_reached ("valid member");
03754 }
03755
03756 ++i;
03757 }
03758
03759
03760 _dbus_string_init_const (&str, "abc.efg");
03761 if (_dbus_string_validate_service (&str, 0, 8))
03762 _dbus_assert_not_reached ("validated too-long string");
03763 if (_dbus_string_validate_interface (&str, 0, 8))
03764 _dbus_assert_not_reached ("validated too-long string");
03765 if (_dbus_string_validate_error_name (&str, 0, 8))
03766 _dbus_assert_not_reached ("validated too-long string");
03767
03768 _dbus_string_init_const (&str, "abc");
03769 if (_dbus_string_validate_member (&str, 0, 4))
03770 _dbus_assert_not_reached ("validated too-long string");
03771
03772
03773 if (!_dbus_string_init (&str))
03774 _dbus_assert_not_reached ("no memory");
03775
03776 while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
03777 if (!_dbus_string_append (&str, "abc.def"))
03778 _dbus_assert_not_reached ("no memory");
03779
03780 if (_dbus_string_validate_service (&str, 0, _dbus_string_get_length (&str)))
03781 _dbus_assert_not_reached ("validated overmax string");
03782 if (_dbus_string_validate_interface (&str, 0, _dbus_string_get_length (&str)))
03783 _dbus_assert_not_reached ("validated overmax string");
03784 if (_dbus_string_validate_error_name (&str, 0, _dbus_string_get_length (&str)))
03785 _dbus_assert_not_reached ("validated overmax string");
03786
03787
03788 _dbus_string_set_length (&str, 0);
03789 while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
03790 if (!_dbus_string_append (&str, "abc"))
03791 _dbus_assert_not_reached ("no memory");
03792
03793 if (_dbus_string_validate_member (&str, 0, _dbus_string_get_length (&str)))
03794 _dbus_assert_not_reached ("validated overmax string");
03795
03796
03797 _dbus_string_set_length (&str, 0);
03798 _dbus_string_append (&str, ":");
03799 while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
03800 if (!_dbus_string_append (&str, "abc"))
03801 _dbus_assert_not_reached ("no memory");
03802
03803 if (_dbus_string_validate_service (&str, 0, _dbus_string_get_length (&str)))
03804 _dbus_assert_not_reached ("validated overmax string");
03805
03806 _dbus_string_free (&str);
03807
03808 return TRUE;
03809 }
03810
03811 #endif