00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <config.h>
00026 #include "dbus-internals.h"
00027 #include "dbus-string.h"
00028
00029 #include <string.h>
00030
00031 #include <stdio.h>
00032 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
00033 #include "dbus-string-private.h"
00034 #include "dbus-marshal-basic.h"
00035
00036
00037
00038 #include "dbus-sysdeps.h"
00039
00078 static void
00079 fixup_alignment (DBusRealString *real)
00080 {
00081 unsigned char *aligned;
00082 unsigned char *real_block;
00083 unsigned int old_align_offset;
00084
00085
00086 _dbus_assert (real->len <= real->allocated - _DBUS_STRING_ALLOCATION_PADDING);
00087
00088 old_align_offset = real->align_offset;
00089 real_block = real->str - old_align_offset;
00090
00091 aligned = _DBUS_ALIGN_ADDRESS (real_block, 8);
00092
00093 real->align_offset = aligned - real_block;
00094 real->str = aligned;
00095
00096 if (old_align_offset != real->align_offset)
00097 {
00098
00099 memmove (real_block + real->align_offset,
00100 real_block + old_align_offset,
00101 real->len + 1);
00102 }
00103
00104 _dbus_assert (real->align_offset < 8);
00105 _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str);
00106 }
00107
00108 static void
00109 undo_alignment (DBusRealString *real)
00110 {
00111 if (real->align_offset != 0)
00112 {
00113 memmove (real->str - real->align_offset,
00114 real->str,
00115 real->len + 1);
00116
00117 real->str = real->str - real->align_offset;
00118 real->align_offset = 0;
00119 }
00120 }
00121
00131 dbus_bool_t
00132 _dbus_string_init_preallocated (DBusString *str,
00133 int allocate_size)
00134 {
00135 DBusRealString *real;
00136
00137 _dbus_assert (str != NULL);
00138
00139 _dbus_assert (sizeof (DBusString) == sizeof (DBusRealString));
00140
00141 real = (DBusRealString*) str;
00142
00143
00144
00145
00146
00147
00148
00149 real->str = dbus_malloc (_DBUS_STRING_ALLOCATION_PADDING + allocate_size);
00150 if (real->str == NULL)
00151 return FALSE;
00152
00153 real->allocated = _DBUS_STRING_ALLOCATION_PADDING + allocate_size;
00154 real->len = 0;
00155 real->str[real->len] = '\0';
00156
00157 real->constant = FALSE;
00158 real->locked = FALSE;
00159 real->invalid = FALSE;
00160 real->align_offset = 0;
00161
00162 fixup_alignment (real);
00163
00164 return TRUE;
00165 }
00166
00174 dbus_bool_t
00175 _dbus_string_init (DBusString *str)
00176 {
00177 return _dbus_string_init_preallocated (str, 0);
00178 }
00179
00189 void
00190 _dbus_string_init_const (DBusString *str,
00191 const char *value)
00192 {
00193 _dbus_assert (value != NULL);
00194
00195 _dbus_string_init_const_len (str, value,
00196 strlen (value));
00197 }
00198
00209 void
00210 _dbus_string_init_const_len (DBusString *str,
00211 const char *value,
00212 int len)
00213 {
00214 DBusRealString *real;
00215
00216 _dbus_assert (str != NULL);
00217 _dbus_assert (len == 0 || value != NULL);
00218 _dbus_assert (len <= _DBUS_STRING_MAX_LENGTH);
00219 _dbus_assert (len >= 0);
00220
00221 real = (DBusRealString*) str;
00222
00223 real->str = (unsigned char*) value;
00224 real->len = len;
00225 real->allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING;
00226 real->constant = TRUE;
00227 real->locked = TRUE;
00228 real->invalid = FALSE;
00229 real->align_offset = 0;
00230
00231
00232
00233
00234 }
00235
00241 void
00242 _dbus_string_free (DBusString *str)
00243 {
00244 DBusRealString *real = (DBusRealString*) str;
00245 DBUS_GENERIC_STRING_PREAMBLE (real);
00246
00247 if (real->constant)
00248 return;
00249 dbus_free (real->str - real->align_offset);
00250
00251 real->invalid = TRUE;
00252 }
00253
00254 static dbus_bool_t
00255 compact (DBusRealString *real,
00256 int max_waste)
00257 {
00258 unsigned char *new_str;
00259 int new_allocated;
00260 int waste;
00261
00262 waste = real->allocated - (real->len + _DBUS_STRING_ALLOCATION_PADDING);
00263
00264 if (waste <= max_waste)
00265 return TRUE;
00266
00267 new_allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING;
00268
00269 new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
00270 if (_DBUS_UNLIKELY (new_str == NULL))
00271 return FALSE;
00272
00273 real->str = new_str + real->align_offset;
00274 real->allocated = new_allocated;
00275 fixup_alignment (real);
00276
00277 return TRUE;
00278 }
00279
00280 #ifdef DBUS_BUILD_TESTS
00281
00282
00283
00293 void
00294 _dbus_string_lock (DBusString *str)
00295 {
00296 DBUS_LOCKED_STRING_PREAMBLE (str);
00297
00298 real->locked = TRUE;
00299
00300
00301
00302
00303 #define MAX_WASTE 48
00304 compact (real, MAX_WASTE);
00305 }
00306 #endif
00307
00308 static dbus_bool_t
00309 reallocate_for_length (DBusRealString *real,
00310 int new_length)
00311 {
00312 int new_allocated;
00313 unsigned char *new_str;
00314
00315
00316
00317
00318 if (real->allocated > (_DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2)
00319 new_allocated = _DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING;
00320 else
00321 new_allocated = real->allocated * 2;
00322
00323
00324
00325
00326
00327
00328
00329
00330 #ifdef DBUS_DISABLE_ASSERT
00331 #else
00332 #ifdef DBUS_BUILD_TESTS
00333 new_allocated = 0;
00334
00335
00336 #endif
00337 #endif
00338
00339
00340 new_allocated = MAX (new_allocated,
00341 new_length + _DBUS_STRING_ALLOCATION_PADDING);
00342
00343 _dbus_assert (new_allocated >= real->allocated);
00344 new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
00345 if (_DBUS_UNLIKELY (new_str == NULL))
00346 return FALSE;
00347
00348 real->str = new_str + real->align_offset;
00349 real->allocated = new_allocated;
00350 fixup_alignment (real);
00351
00352 return TRUE;
00353 }
00354
00366 dbus_bool_t
00367 _dbus_string_compact (DBusString *str,
00368 int max_waste)
00369 {
00370 DBUS_STRING_PREAMBLE (str);
00371
00372 return compact (real, max_waste);
00373 }
00374
00375 static dbus_bool_t
00376 set_length (DBusRealString *real,
00377 int new_length)
00378 {
00379
00380
00381
00382 if (_DBUS_UNLIKELY (new_length > _DBUS_STRING_MAX_LENGTH))
00383 return FALSE;
00384 else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) &&
00385 _DBUS_UNLIKELY (!reallocate_for_length (real, new_length)))
00386 return FALSE;
00387 else
00388 {
00389 real->len = new_length;
00390 real->str[new_length] = '\0';
00391 return TRUE;
00392 }
00393 }
00394
00395 static dbus_bool_t
00396 open_gap (int len,
00397 DBusRealString *dest,
00398 int insert_at)
00399 {
00400 if (len == 0)
00401 return TRUE;
00402
00403 if (len > _DBUS_STRING_MAX_LENGTH - dest->len)
00404 return FALSE;
00405
00406 if (!set_length (dest, dest->len + len))
00407 return FALSE;
00408
00409 memmove (dest->str + insert_at + len,
00410 dest->str + insert_at,
00411 dest->len - len - insert_at);
00412
00413 return TRUE;
00414 }
00415
00416 #ifndef _dbus_string_get_data
00417
00428 char*
00429 _dbus_string_get_data (DBusString *str)
00430 {
00431 DBUS_STRING_PREAMBLE (str);
00432
00433 return (char*) real->str;
00434 }
00435 #endif
00436
00437
00438 #ifndef _dbus_string_get_const_data
00439
00445 const char*
00446 _dbus_string_get_const_data (const DBusString *str)
00447 {
00448 DBUS_CONST_STRING_PREAMBLE (str);
00449
00450 return (const char*) real->str;
00451 }
00452 #endif
00453
00467 char*
00468 _dbus_string_get_data_len (DBusString *str,
00469 int start,
00470 int len)
00471 {
00472 DBUS_STRING_PREAMBLE (str);
00473 _dbus_assert (start >= 0);
00474 _dbus_assert (len >= 0);
00475 _dbus_assert (start <= real->len);
00476 _dbus_assert (len <= real->len - start);
00477
00478 return (char*) real->str + start;
00479 }
00480
00481
00482 #ifndef _dbus_string_get_const_data_len
00483
00491 const char*
00492 _dbus_string_get_const_data_len (const DBusString *str,
00493 int start,
00494 int len)
00495 {
00496 DBUS_CONST_STRING_PREAMBLE (str);
00497 _dbus_assert (start >= 0);
00498 _dbus_assert (len >= 0);
00499 _dbus_assert (start <= real->len);
00500 _dbus_assert (len <= real->len - start);
00501
00502 return (const char*) real->str + start;
00503 }
00504 #endif
00505
00506
00507 #ifndef _dbus_string_set_byte
00508
00515 void
00516 _dbus_string_set_byte (DBusString *str,
00517 int i,
00518 unsigned char byte)
00519 {
00520 DBUS_STRING_PREAMBLE (str);
00521 _dbus_assert (i < real->len);
00522 _dbus_assert (i >= 0);
00523
00524 real->str[i] = byte;
00525 }
00526 #endif
00527
00528
00529 #ifndef _dbus_string_get_byte
00530
00539 unsigned char
00540 _dbus_string_get_byte (const DBusString *str,
00541 int start)
00542 {
00543 DBUS_CONST_STRING_PREAMBLE (str);
00544 _dbus_assert (start <= real->len);
00545 _dbus_assert (start >= 0);
00546
00547 return real->str[start];
00548 }
00549 #endif
00550
00561 dbus_bool_t
00562 _dbus_string_insert_bytes (DBusString *str,
00563 int i,
00564 int n_bytes,
00565 unsigned char byte)
00566 {
00567 DBUS_STRING_PREAMBLE (str);
00568 _dbus_assert (i <= real->len);
00569 _dbus_assert (i >= 0);
00570 _dbus_assert (n_bytes >= 0);
00571
00572 if (n_bytes == 0)
00573 return TRUE;
00574
00575 if (!open_gap (n_bytes, real, i))
00576 return FALSE;
00577
00578 memset (real->str + i, byte, n_bytes);
00579
00580 return TRUE;
00581 }
00582
00591 dbus_bool_t
00592 _dbus_string_insert_byte (DBusString *str,
00593 int i,
00594 unsigned char byte)
00595 {
00596 DBUS_STRING_PREAMBLE (str);
00597 _dbus_assert (i <= real->len);
00598 _dbus_assert (i >= 0);
00599
00600 if (!open_gap (1, real, i))
00601 return FALSE;
00602
00603 real->str[i] = byte;
00604
00605 return TRUE;
00606 }
00607
00618 dbus_bool_t
00619 _dbus_string_steal_data (DBusString *str,
00620 char **data_return)
00621 {
00622 DBUS_STRING_PREAMBLE (str);
00623 _dbus_assert (data_return != NULL);
00624
00625 undo_alignment (real);
00626
00627 *data_return = (char*) real->str;
00628
00629
00630 if (!_dbus_string_init (str))
00631 {
00632
00633 real->str = (unsigned char*) *data_return;
00634 *data_return = NULL;
00635 fixup_alignment (real);
00636 return FALSE;
00637 }
00638
00639 return TRUE;
00640 }
00641
00649 dbus_bool_t
00650 _dbus_string_copy_data (const DBusString *str,
00651 char **data_return)
00652 {
00653 DBUS_CONST_STRING_PREAMBLE (str);
00654 _dbus_assert (data_return != NULL);
00655
00656 *data_return = dbus_malloc (real->len + 1);
00657 if (*data_return == NULL)
00658 return FALSE;
00659
00660 memcpy (*data_return, real->str, real->len + 1);
00661
00662 return TRUE;
00663 }
00664
00674 void
00675 _dbus_string_copy_to_buffer (const DBusString *str,
00676 char *buffer,
00677 int avail_len)
00678 {
00679 DBUS_CONST_STRING_PREAMBLE (str);
00680
00681 _dbus_assert (avail_len >= 0);
00682 _dbus_assert (avail_len >= real->len);
00683
00684 memcpy (buffer, real->str, real->len);
00685 }
00686
00696 void
00697 _dbus_string_copy_to_buffer_with_nul (const DBusString *str,
00698 char *buffer,
00699 int avail_len)
00700 {
00701 DBUS_CONST_STRING_PREAMBLE (str);
00702
00703 _dbus_assert (avail_len >= 0);
00704 _dbus_assert (avail_len > real->len);
00705
00706 memcpy (buffer, real->str, real->len+1);
00707 }
00708
00709
00710 #ifndef _dbus_string_get_length
00711
00716 int
00717 _dbus_string_get_length (const DBusString *str)
00718 {
00719 DBUS_CONST_STRING_PREAMBLE (str);
00720
00721 return real->len;
00722 }
00723 #endif
00724
00737 dbus_bool_t
00738 _dbus_string_lengthen (DBusString *str,
00739 int additional_length)
00740 {
00741 DBUS_STRING_PREAMBLE (str);
00742 _dbus_assert (additional_length >= 0);
00743
00744 if (_DBUS_UNLIKELY (additional_length > _DBUS_STRING_MAX_LENGTH - real->len))
00745 return FALSE;
00746
00747 return set_length (real,
00748 real->len + additional_length);
00749 }
00750
00757 void
00758 _dbus_string_shorten (DBusString *str,
00759 int length_to_remove)
00760 {
00761 DBUS_STRING_PREAMBLE (str);
00762 _dbus_assert (length_to_remove >= 0);
00763 _dbus_assert (length_to_remove <= real->len);
00764
00765 set_length (real,
00766 real->len - length_to_remove);
00767 }
00768
00779 dbus_bool_t
00780 _dbus_string_set_length (DBusString *str,
00781 int length)
00782 {
00783 DBUS_STRING_PREAMBLE (str);
00784 _dbus_assert (length >= 0);
00785
00786 return set_length (real, length);
00787 }
00788
00789 static dbus_bool_t
00790 align_insert_point_then_open_gap (DBusString *str,
00791 int *insert_at_p,
00792 int alignment,
00793 int gap_size)
00794 {
00795 unsigned long new_len;
00796 unsigned long gap_pos;
00797 int insert_at;
00798 int delta;
00799 DBUS_STRING_PREAMBLE (str);
00800 _dbus_assert (alignment >= 1);
00801 _dbus_assert (alignment <= 8);
00802
00803 insert_at = *insert_at_p;
00804
00805 _dbus_assert (insert_at <= real->len);
00806
00807 gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
00808 new_len = real->len + (gap_pos - insert_at) + gap_size;
00809
00810 if (_DBUS_UNLIKELY (new_len > (unsigned long) _DBUS_STRING_MAX_LENGTH))
00811 return FALSE;
00812
00813 delta = new_len - real->len;
00814 _dbus_assert (delta >= 0);
00815
00816 if (delta == 0)
00817 {
00818 _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
00819 return TRUE;
00820 }
00821
00822 if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
00823 real, insert_at)))
00824 return FALSE;
00825
00826
00827 if (gap_size < delta)
00828 {
00829 memset (&real->str[insert_at], '\0',
00830 gap_pos - insert_at);
00831 }
00832
00833 *insert_at_p = gap_pos;
00834
00835 return TRUE;
00836 }
00837
00838 static dbus_bool_t
00839 align_length_then_lengthen (DBusString *str,
00840 int alignment,
00841 int then_lengthen_by)
00842 {
00843 int insert_at;
00844
00845 insert_at = _dbus_string_get_length (str);
00846
00847 return align_insert_point_then_open_gap (str,
00848 &insert_at,
00849 alignment, then_lengthen_by);
00850 }
00851
00860 dbus_bool_t
00861 _dbus_string_align_length (DBusString *str,
00862 int alignment)
00863 {
00864 return align_length_then_lengthen (str, alignment, 0);
00865 }
00866
00876 dbus_bool_t
00877 _dbus_string_alloc_space (DBusString *str,
00878 int extra_bytes)
00879 {
00880 if (!_dbus_string_lengthen (str, extra_bytes))
00881 return FALSE;
00882 _dbus_string_shorten (str, extra_bytes);
00883
00884 return TRUE;
00885 }
00886
00887 static dbus_bool_t
00888 append (DBusRealString *real,
00889 const char *buffer,
00890 int buffer_len)
00891 {
00892 if (buffer_len == 0)
00893 return TRUE;
00894
00895 if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
00896 return FALSE;
00897
00898 memcpy (real->str + (real->len - buffer_len),
00899 buffer,
00900 buffer_len);
00901
00902 return TRUE;
00903 }
00904
00912 dbus_bool_t
00913 _dbus_string_append (DBusString *str,
00914 const char *buffer)
00915 {
00916 unsigned long buffer_len;
00917
00918 DBUS_STRING_PREAMBLE (str);
00919 _dbus_assert (buffer != NULL);
00920
00921 buffer_len = strlen (buffer);
00922 if (buffer_len > (unsigned long) _DBUS_STRING_MAX_LENGTH)
00923 return FALSE;
00924
00925 return append (real, buffer, buffer_len);
00926 }
00927
00929 #define ASSIGN_2_OCTETS(p, octets) \
00930 *((dbus_uint16_t*)(p)) = *((dbus_uint16_t*)(octets));
00931
00933 #define ASSIGN_4_OCTETS(p, octets) \
00934 *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
00935
00936 #ifdef DBUS_HAVE_INT64
00937
00938 #define ASSIGN_8_OCTETS(p, octets) \
00939 *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
00940 #else
00941
00942 #define ASSIGN_8_OCTETS(p, octets) \
00943 do { \
00944 unsigned char *b; \
00945 \
00946 b = p; \
00947 \
00948 *b++ = octets[0]; \
00949 *b++ = octets[1]; \
00950 *b++ = octets[2]; \
00951 *b++ = octets[3]; \
00952 *b++ = octets[4]; \
00953 *b++ = octets[5]; \
00954 *b++ = octets[6]; \
00955 *b++ = octets[7]; \
00956 _dbus_assert (b == p + 8); \
00957 } while (0)
00958 #endif
00959
00969 dbus_bool_t
00970 _dbus_string_insert_2_aligned (DBusString *str,
00971 int insert_at,
00972 const unsigned char octets[4])
00973 {
00974 DBUS_STRING_PREAMBLE (str);
00975
00976 if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2))
00977 return FALSE;
00978
00979 ASSIGN_2_OCTETS (real->str + insert_at, octets);
00980
00981 return TRUE;
00982 }
00983
00993 dbus_bool_t
00994 _dbus_string_insert_4_aligned (DBusString *str,
00995 int insert_at,
00996 const unsigned char octets[4])
00997 {
00998 DBUS_STRING_PREAMBLE (str);
00999
01000 if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
01001 return FALSE;
01002
01003 ASSIGN_4_OCTETS (real->str + insert_at, octets);
01004
01005 return TRUE;
01006 }
01007
01017 dbus_bool_t
01018 _dbus_string_insert_8_aligned (DBusString *str,
01019 int insert_at,
01020 const unsigned char octets[8])
01021 {
01022 DBUS_STRING_PREAMBLE (str);
01023
01024 if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
01025 return FALSE;
01026
01027 _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
01028
01029 ASSIGN_8_OCTETS (real->str + insert_at, octets);
01030
01031 return TRUE;
01032 }
01033
01034
01045 dbus_bool_t
01046 _dbus_string_insert_alignment (DBusString *str,
01047 int *insert_at,
01048 int alignment)
01049 {
01050 DBUS_STRING_PREAMBLE (str);
01051
01052 if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0))
01053 return FALSE;
01054
01055 _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at);
01056
01057 return TRUE;
01058 }
01059
01069 dbus_bool_t
01070 _dbus_string_append_printf_valist (DBusString *str,
01071 const char *format,
01072 va_list args)
01073 {
01074 int len;
01075 va_list args_copy;
01076
01077 DBUS_STRING_PREAMBLE (str);
01078
01079 DBUS_VA_COPY (args_copy, args);
01080
01081
01082 len = _dbus_printf_string_upper_bound (format, args);
01083
01084 if (len < 0)
01085 return FALSE;
01086
01087 if (!_dbus_string_lengthen (str, len))
01088 {
01089
01090 va_end (args_copy);
01091 return FALSE;
01092 }
01093
01094 vsprintf ((char*) (real->str + (real->len - len)),
01095 format, args_copy);
01096
01097 va_end (args_copy);
01098
01099 return TRUE;
01100 }
01101
01110 dbus_bool_t
01111 _dbus_string_append_printf (DBusString *str,
01112 const char *format,
01113 ...)
01114 {
01115 va_list args;
01116 dbus_bool_t retval;
01117
01118 va_start (args, format);
01119 retval = _dbus_string_append_printf_valist (str, format, args);
01120 va_end (args);
01121
01122 return retval;
01123 }
01124
01133 dbus_bool_t
01134 _dbus_string_append_len (DBusString *str,
01135 const char *buffer,
01136 int len)
01137 {
01138 DBUS_STRING_PREAMBLE (str);
01139 _dbus_assert (buffer != NULL);
01140 _dbus_assert (len >= 0);
01141
01142 return append (real, buffer, len);
01143 }
01144
01153 dbus_bool_t
01154 _dbus_string_append_byte (DBusString *str,
01155 unsigned char byte)
01156 {
01157 DBUS_STRING_PREAMBLE (str);
01158
01159 if (!set_length (real, real->len + 1))
01160 return FALSE;
01161
01162 real->str[real->len-1] = byte;
01163
01164 return TRUE;
01165 }
01166
01167 static void
01168 delete (DBusRealString *real,
01169 int start,
01170 int len)
01171 {
01172 if (len == 0)
01173 return;
01174
01175 memmove (real->str + start, real->str + start + len, real->len - (start + len));
01176 real->len -= len;
01177 real->str[real->len] = '\0';
01178 }
01179
01189 void
01190 _dbus_string_delete (DBusString *str,
01191 int start,
01192 int len)
01193 {
01194 DBUS_STRING_PREAMBLE (str);
01195 _dbus_assert (start >= 0);
01196 _dbus_assert (len >= 0);
01197 _dbus_assert (start <= real->len);
01198 _dbus_assert (len <= real->len - start);
01199
01200 delete (real, start, len);
01201 }
01202
01203 static dbus_bool_t
01204 copy (DBusRealString *source,
01205 int start,
01206 int len,
01207 DBusRealString *dest,
01208 int insert_at)
01209 {
01210 if (len == 0)
01211 return TRUE;
01212
01213 if (!open_gap (len, dest, insert_at))
01214 return FALSE;
01215
01216 memmove (dest->str + insert_at,
01217 source->str + start,
01218 len);
01219
01220 return TRUE;
01221 }
01222
01232 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at) \
01233 DBusRealString *real_source = (DBusRealString*) source; \
01234 DBusRealString *real_dest = (DBusRealString*) dest; \
01235 _dbus_assert ((source) != (dest)); \
01236 DBUS_GENERIC_STRING_PREAMBLE (real_source); \
01237 DBUS_GENERIC_STRING_PREAMBLE (real_dest); \
01238 _dbus_assert (!real_dest->constant); \
01239 _dbus_assert (!real_dest->locked); \
01240 _dbus_assert ((start) >= 0); \
01241 _dbus_assert ((start) <= real_source->len); \
01242 _dbus_assert ((insert_at) >= 0); \
01243 _dbus_assert ((insert_at) <= real_dest->len)
01244
01255 dbus_bool_t
01256 _dbus_string_move (DBusString *source,
01257 int start,
01258 DBusString *dest,
01259 int insert_at)
01260 {
01261 DBusRealString *real_source = (DBusRealString*) source;
01262 _dbus_assert (start <= real_source->len);
01263
01264 return _dbus_string_move_len (source, start,
01265 real_source->len - start,
01266 dest, insert_at);
01267 }
01268
01279 dbus_bool_t
01280 _dbus_string_copy (const DBusString *source,
01281 int start,
01282 DBusString *dest,
01283 int insert_at)
01284 {
01285 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01286
01287 return copy (real_source, start,
01288 real_source->len - start,
01289 real_dest,
01290 insert_at);
01291 }
01292
01304 dbus_bool_t
01305 _dbus_string_move_len (DBusString *source,
01306 int start,
01307 int len,
01308 DBusString *dest,
01309 int insert_at)
01310
01311 {
01312 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01313 _dbus_assert (len >= 0);
01314 _dbus_assert ((start + len) <= real_source->len);
01315
01316
01317 if (len == 0)
01318 {
01319 return TRUE;
01320 }
01321 else if (start == 0 &&
01322 len == real_source->len &&
01323 real_dest->len == 0)
01324 {
01325
01326
01327
01328
01329
01330
01331 #define ASSIGN_DATA(a, b) do { \
01332 (a)->str = (b)->str; \
01333 (a)->len = (b)->len; \
01334 (a)->allocated = (b)->allocated; \
01335 (a)->align_offset = (b)->align_offset; \
01336 } while (0)
01337
01338 DBusRealString tmp;
01339
01340 ASSIGN_DATA (&tmp, real_source);
01341 ASSIGN_DATA (real_source, real_dest);
01342 ASSIGN_DATA (real_dest, &tmp);
01343
01344 return TRUE;
01345 }
01346 else
01347 {
01348 if (!copy (real_source, start, len,
01349 real_dest,
01350 insert_at))
01351 return FALSE;
01352
01353 delete (real_source, start,
01354 len);
01355
01356 return TRUE;
01357 }
01358 }
01359
01371 dbus_bool_t
01372 _dbus_string_copy_len (const DBusString *source,
01373 int start,
01374 int len,
01375 DBusString *dest,
01376 int insert_at)
01377 {
01378 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01379 _dbus_assert (len >= 0);
01380 _dbus_assert (start <= real_source->len);
01381 _dbus_assert (len <= real_source->len - start);
01382
01383 return copy (real_source, start, len,
01384 real_dest,
01385 insert_at);
01386 }
01387
01400 dbus_bool_t
01401 _dbus_string_replace_len (const DBusString *source,
01402 int start,
01403 int len,
01404 DBusString *dest,
01405 int replace_at,
01406 int replace_len)
01407 {
01408 DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
01409 _dbus_assert (len >= 0);
01410 _dbus_assert (start <= real_source->len);
01411 _dbus_assert (len <= real_source->len - start);
01412 _dbus_assert (replace_at >= 0);
01413 _dbus_assert (replace_at <= real_dest->len);
01414 _dbus_assert (replace_len <= real_dest->len - replace_at);
01415
01416 if (len == replace_len)
01417 {
01418 memmove (real_dest->str + replace_at,
01419 real_source->str + start, len);
01420 }
01421 else if (len < replace_len)
01422 {
01423 memmove (real_dest->str + replace_at,
01424 real_source->str + start, len);
01425 delete (real_dest, replace_at + len,
01426 replace_len - len);
01427 }
01428 else
01429 {
01430 int diff;
01431
01432 _dbus_assert (len > replace_len);
01433
01434 diff = len - replace_len;
01435
01436
01437
01438
01439
01440 if (!copy (real_source, start + replace_len, diff,
01441 real_dest, replace_at + replace_len))
01442 return FALSE;
01443
01444 memmove (real_dest->str + replace_at,
01445 real_source->str + start, replace_len);
01446 }
01447
01448 return TRUE;
01449 }
01450
01463 dbus_bool_t
01464 _dbus_string_split_on_byte (DBusString *source,
01465 unsigned char byte,
01466 DBusString *tail)
01467 {
01468 int byte_position;
01469 char byte_string[2] = "";
01470 int head_length;
01471 int tail_length;
01472
01473 byte_string[0] = (char) byte;
01474
01475 if (!_dbus_string_find (source, 0, byte_string, &byte_position))
01476 return FALSE;
01477
01478 head_length = byte_position;
01479 tail_length = _dbus_string_get_length (source) - head_length - 1;
01480
01481 if (!_dbus_string_move_len (source, byte_position + 1, tail_length,
01482 tail, 0))
01483 return FALSE;
01484
01485
01486
01487 if (!_dbus_string_set_length (source, head_length))
01488 return FALSE;
01489
01490 return TRUE;
01491 }
01492
01493
01494
01495
01496
01502 #define UTF8_COMPUTE(Char, Mask, Len) \
01503 if (Char < 128) \
01504 { \
01505 Len = 1; \
01506 Mask = 0x7f; \
01507 } \
01508 else if ((Char & 0xe0) == 0xc0) \
01509 { \
01510 Len = 2; \
01511 Mask = 0x1f; \
01512 } \
01513 else if ((Char & 0xf0) == 0xe0) \
01514 { \
01515 Len = 3; \
01516 Mask = 0x0f; \
01517 } \
01518 else if ((Char & 0xf8) == 0xf0) \
01519 { \
01520 Len = 4; \
01521 Mask = 0x07; \
01522 } \
01523 else if ((Char & 0xfc) == 0xf8) \
01524 { \
01525 Len = 5; \
01526 Mask = 0x03; \
01527 } \
01528 else if ((Char & 0xfe) == 0xfc) \
01529 { \
01530 Len = 6; \
01531 Mask = 0x01; \
01532 } \
01533 else \
01534 { \
01535 Len = 0; \
01536 Mask = 0; \
01537 }
01538
01543 #define UTF8_LENGTH(Char) \
01544 ((Char) < 0x80 ? 1 : \
01545 ((Char) < 0x800 ? 2 : \
01546 ((Char) < 0x10000 ? 3 : \
01547 ((Char) < 0x200000 ? 4 : \
01548 ((Char) < 0x4000000 ? 5 : 6)))))
01549
01559 #define UTF8_GET(Result, Chars, Count, Mask, Len) \
01560 (Result) = (Chars)[0] & (Mask); \
01561 for ((Count) = 1; (Count) < (Len); ++(Count)) \
01562 { \
01563 if (((Chars)[(Count)] & 0xc0) != 0x80) \
01564 { \
01565 (Result) = -1; \
01566 break; \
01567 } \
01568 (Result) <<= 6; \
01569 (Result) |= ((Chars)[(Count)] & 0x3f); \
01570 }
01571
01582 #define UNICODE_VALID(Char) \
01583 ((Char) < 0x110000 && \
01584 (((Char) & 0xFFFFF800) != 0xD800))
01585
01600 dbus_bool_t
01601 _dbus_string_find (const DBusString *str,
01602 int start,
01603 const char *substr,
01604 int *found)
01605 {
01606 return _dbus_string_find_to (str, start,
01607 ((const DBusRealString*)str)->len,
01608 substr, found);
01609 }
01610
01623 dbus_bool_t
01624 _dbus_string_find_eol (const DBusString *str,
01625 int start,
01626 int *found,
01627 int *found_len)
01628 {
01629 int i;
01630
01631 DBUS_CONST_STRING_PREAMBLE (str);
01632 _dbus_assert (start <= real->len);
01633 _dbus_assert (start >= 0);
01634
01635 i = start;
01636 while (i < real->len)
01637 {
01638 if (real->str[i] == '\r')
01639 {
01640 if ((i+1) < real->len && real->str[i+1] == '\n')
01641 {
01642 if (found)
01643 *found = i;
01644 if (found_len)
01645 *found_len = 2;
01646 return TRUE;
01647 }
01648 else
01649 {
01650 if (found)
01651 *found = i;
01652 if (found_len)
01653 *found_len = 1;
01654 return TRUE;
01655 }
01656 }
01657 else if (real->str[i] == '\n')
01658 {
01659 if (found)
01660 *found = i;
01661 if (found_len)
01662 *found_len = 1;
01663 return TRUE;
01664 }
01665 ++i;
01666 }
01667
01668 if (found)
01669 *found = real->len;
01670
01671 if (found_len)
01672 *found_len = 0;
01673
01674 return FALSE;
01675 }
01676
01693 dbus_bool_t
01694 _dbus_string_find_to (const DBusString *str,
01695 int start,
01696 int end,
01697 const char *substr,
01698 int *found)
01699 {
01700 int i;
01701 DBUS_CONST_STRING_PREAMBLE (str);
01702 _dbus_assert (substr != NULL);
01703 _dbus_assert (start <= real->len);
01704 _dbus_assert (start >= 0);
01705 _dbus_assert (substr != NULL);
01706 _dbus_assert (end <= real->len);
01707 _dbus_assert (start <= end);
01708
01709
01710 if (*substr == '\0')
01711 {
01712 if (found)
01713 *found = start;
01714 return TRUE;
01715 }
01716
01717 i = start;
01718 while (i < end)
01719 {
01720 if (real->str[i] == substr[0])
01721 {
01722 int j = i + 1;
01723
01724 while (j < end)
01725 {
01726 if (substr[j - i] == '\0')
01727 break;
01728 else if (real->str[j] != substr[j - i])
01729 break;
01730
01731 ++j;
01732 }
01733
01734 if (substr[j - i] == '\0')
01735 {
01736 if (found)
01737 *found = i;
01738 return TRUE;
01739 }
01740 }
01741
01742 ++i;
01743 }
01744
01745 if (found)
01746 *found = end;
01747
01748 return FALSE;
01749 }
01750
01761 dbus_bool_t
01762 _dbus_string_find_blank (const DBusString *str,
01763 int start,
01764 int *found)
01765 {
01766 int i;
01767 DBUS_CONST_STRING_PREAMBLE (str);
01768 _dbus_assert (start <= real->len);
01769 _dbus_assert (start >= 0);
01770
01771 i = start;
01772 while (i < real->len)
01773 {
01774 if (real->str[i] == ' ' ||
01775 real->str[i] == '\t')
01776 {
01777 if (found)
01778 *found = i;
01779 return TRUE;
01780 }
01781
01782 ++i;
01783 }
01784
01785 if (found)
01786 *found = real->len;
01787
01788 return FALSE;
01789 }
01790
01799 void
01800 _dbus_string_skip_blank (const DBusString *str,
01801 int start,
01802 int *end)
01803 {
01804 int i;
01805 DBUS_CONST_STRING_PREAMBLE (str);
01806 _dbus_assert (start <= real->len);
01807 _dbus_assert (start >= 0);
01808
01809 i = start;
01810 while (i < real->len)
01811 {
01812 if (!DBUS_IS_ASCII_BLANK (real->str[i]))
01813 break;
01814
01815 ++i;
01816 }
01817
01818 _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
01819
01820 if (end)
01821 *end = i;
01822 }
01823
01824
01833 void
01834 _dbus_string_skip_white (const DBusString *str,
01835 int start,
01836 int *end)
01837 {
01838 int i;
01839 DBUS_CONST_STRING_PREAMBLE (str);
01840 _dbus_assert (start <= real->len);
01841 _dbus_assert (start >= 0);
01842
01843 i = start;
01844 while (i < real->len)
01845 {
01846 if (!DBUS_IS_ASCII_WHITE (real->str[i]))
01847 break;
01848
01849 ++i;
01850 }
01851
01852 _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
01853
01854 if (end)
01855 *end = i;
01856 }
01857
01866 void
01867 _dbus_string_skip_white_reverse (const DBusString *str,
01868 int end,
01869 int *start)
01870 {
01871 int i;
01872 DBUS_CONST_STRING_PREAMBLE (str);
01873 _dbus_assert (end <= real->len);
01874 _dbus_assert (end >= 0);
01875
01876 i = end;
01877 while (i > 0)
01878 {
01879 if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
01880 break;
01881 --i;
01882 }
01883
01884 _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
01885
01886 if (start)
01887 *start = i;
01888 }
01889
01905 dbus_bool_t
01906 _dbus_string_pop_line (DBusString *source,
01907 DBusString *dest)
01908 {
01909 int eol, eol_len;
01910
01911 _dbus_string_set_length (dest, 0);
01912
01913 eol = 0;
01914 eol_len = 0;
01915 if (!_dbus_string_find_eol (source, 0, &eol, &eol_len))
01916 {
01917 _dbus_assert (eol == _dbus_string_get_length (source));
01918 if (eol == 0)
01919 {
01920
01921 return FALSE;
01922 }
01923
01924 }
01925
01926
01927
01928
01929
01930 if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0))
01931 return FALSE;
01932
01933
01934 if (!_dbus_string_set_length (dest, eol))
01935 {
01936 _dbus_assert_not_reached ("out of memory when shortening a string");
01937 return FALSE;
01938 }
01939
01940 return TRUE;
01941 }
01942
01943 #ifdef DBUS_BUILD_TESTS
01944
01950 void
01951 _dbus_string_delete_first_word (DBusString *str)
01952 {
01953 int i;
01954
01955 if (_dbus_string_find_blank (str, 0, &i))
01956 _dbus_string_skip_blank (str, i, &i);
01957
01958 _dbus_string_delete (str, 0, i);
01959 }
01960 #endif
01961
01962 #ifdef DBUS_BUILD_TESTS
01963
01968 void
01969 _dbus_string_delete_leading_blanks (DBusString *str)
01970 {
01971 int i;
01972
01973 _dbus_string_skip_blank (str, 0, &i);
01974
01975 if (i > 0)
01976 _dbus_string_delete (str, 0, i);
01977 }
01978 #endif
01979
01985 void
01986 _dbus_string_chop_white(DBusString *str)
01987 {
01988 int i;
01989
01990 _dbus_string_skip_white (str, 0, &i);
01991
01992 if (i > 0)
01993 _dbus_string_delete (str, 0, i);
01994
01995 _dbus_string_skip_white_reverse (str, _dbus_string_get_length (str), &i);
01996
01997 _dbus_string_set_length (str, i);
01998 }
01999
02009 dbus_bool_t
02010 _dbus_string_equal (const DBusString *a,
02011 const DBusString *b)
02012 {
02013 const unsigned char *ap;
02014 const unsigned char *bp;
02015 const unsigned char *a_end;
02016 const DBusRealString *real_a = (const DBusRealString*) a;
02017 const DBusRealString *real_b = (const DBusRealString*) b;
02018 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02019 DBUS_GENERIC_STRING_PREAMBLE (real_b);
02020
02021 if (real_a->len != real_b->len)
02022 return FALSE;
02023
02024 ap = real_a->str;
02025 bp = real_b->str;
02026 a_end = real_a->str + real_a->len;
02027 while (ap != a_end)
02028 {
02029 if (*ap != *bp)
02030 return FALSE;
02031
02032 ++ap;
02033 ++bp;
02034 }
02035
02036 return TRUE;
02037 }
02038
02052 dbus_bool_t
02053 _dbus_string_equal_len (const DBusString *a,
02054 const DBusString *b,
02055 int len)
02056 {
02057 const unsigned char *ap;
02058 const unsigned char *bp;
02059 const unsigned char *a_end;
02060 const DBusRealString *real_a = (const DBusRealString*) a;
02061 const DBusRealString *real_b = (const DBusRealString*) b;
02062 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02063 DBUS_GENERIC_STRING_PREAMBLE (real_b);
02064
02065 if (real_a->len != real_b->len &&
02066 (real_a->len < len || real_b->len < len))
02067 return FALSE;
02068
02069 ap = real_a->str;
02070 bp = real_b->str;
02071 a_end = real_a->str + MIN (real_a->len, len);
02072 while (ap != a_end)
02073 {
02074 if (*ap != *bp)
02075 return FALSE;
02076
02077 ++ap;
02078 ++bp;
02079 }
02080
02081 return TRUE;
02082 }
02083
02100 dbus_bool_t
02101 _dbus_string_equal_substring (const DBusString *a,
02102 int a_start,
02103 int a_len,
02104 const DBusString *b,
02105 int b_start)
02106 {
02107 const unsigned char *ap;
02108 const unsigned char *bp;
02109 const unsigned char *a_end;
02110 const DBusRealString *real_a = (const DBusRealString*) a;
02111 const DBusRealString *real_b = (const DBusRealString*) b;
02112 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02113 DBUS_GENERIC_STRING_PREAMBLE (real_b);
02114 _dbus_assert (a_start >= 0);
02115 _dbus_assert (a_len >= 0);
02116 _dbus_assert (a_start <= real_a->len);
02117 _dbus_assert (a_len <= real_a->len - a_start);
02118 _dbus_assert (b_start >= 0);
02119 _dbus_assert (b_start <= real_b->len);
02120
02121 if (a_len > real_b->len - b_start)
02122 return FALSE;
02123
02124 ap = real_a->str + a_start;
02125 bp = real_b->str + b_start;
02126 a_end = ap + a_len;
02127 while (ap != a_end)
02128 {
02129 if (*ap != *bp)
02130 return FALSE;
02131
02132 ++ap;
02133 ++bp;
02134 }
02135
02136 _dbus_assert (bp <= (real_b->str + real_b->len));
02137
02138 return TRUE;
02139 }
02140
02148 dbus_bool_t
02149 _dbus_string_equal_c_str (const DBusString *a,
02150 const char *c_str)
02151 {
02152 const unsigned char *ap;
02153 const unsigned char *bp;
02154 const unsigned char *a_end;
02155 const DBusRealString *real_a = (const DBusRealString*) a;
02156 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02157 _dbus_assert (c_str != NULL);
02158
02159 ap = real_a->str;
02160 bp = (const unsigned char*) c_str;
02161 a_end = real_a->str + real_a->len;
02162 while (ap != a_end && *bp)
02163 {
02164 if (*ap != *bp)
02165 return FALSE;
02166
02167 ++ap;
02168 ++bp;
02169 }
02170
02171 if (ap != a_end || *bp)
02172 return FALSE;
02173
02174 return TRUE;
02175 }
02176
02184 dbus_bool_t
02185 _dbus_string_starts_with_c_str (const DBusString *a,
02186 const char *c_str)
02187 {
02188 const unsigned char *ap;
02189 const unsigned char *bp;
02190 const unsigned char *a_end;
02191 const DBusRealString *real_a = (const DBusRealString*) a;
02192 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02193 _dbus_assert (c_str != NULL);
02194
02195 ap = real_a->str;
02196 bp = (const unsigned char*) c_str;
02197 a_end = real_a->str + real_a->len;
02198 while (ap != a_end && *bp)
02199 {
02200 if (*ap != *bp)
02201 return FALSE;
02202
02203 ++ap;
02204 ++bp;
02205 }
02206
02207 if (*bp == '\0')
02208 return TRUE;
02209 else
02210 return FALSE;
02211 }
02212
02221 dbus_bool_t
02222 _dbus_string_append_byte_as_hex (DBusString *str,
02223 int byte)
02224 {
02225 const char hexdigits[16] = {
02226 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
02227 'a', 'b', 'c', 'd', 'e', 'f'
02228 };
02229
02230 if (!_dbus_string_append_byte (str,
02231 hexdigits[(byte >> 4)]))
02232 return FALSE;
02233
02234 if (!_dbus_string_append_byte (str,
02235 hexdigits[(byte & 0x0f)]))
02236 {
02237 _dbus_string_set_length (str,
02238 _dbus_string_get_length (str) - 1);
02239 return FALSE;
02240 }
02241
02242 return TRUE;
02243 }
02244
02255 dbus_bool_t
02256 _dbus_string_hex_encode (const DBusString *source,
02257 int start,
02258 DBusString *dest,
02259 int insert_at)
02260 {
02261 DBusString result;
02262 const unsigned char *p;
02263 const unsigned char *end;
02264 dbus_bool_t retval;
02265
02266 _dbus_assert (start <= _dbus_string_get_length (source));
02267
02268 if (!_dbus_string_init (&result))
02269 return FALSE;
02270
02271 retval = FALSE;
02272
02273 p = (const unsigned char*) _dbus_string_get_const_data (source);
02274 end = p + _dbus_string_get_length (source);
02275 p += start;
02276
02277 while (p != end)
02278 {
02279 if (!_dbus_string_append_byte_as_hex (&result, *p))
02280 goto out;
02281
02282 ++p;
02283 }
02284
02285 if (!_dbus_string_move (&result, 0, dest, insert_at))
02286 goto out;
02287
02288 retval = TRUE;
02289
02290 out:
02291 _dbus_string_free (&result);
02292 return retval;
02293 }
02294
02305 dbus_bool_t
02306 _dbus_string_hex_decode (const DBusString *source,
02307 int start,
02308 int *end_return,
02309 DBusString *dest,
02310 int insert_at)
02311 {
02312 DBusString result;
02313 const unsigned char *p;
02314 const unsigned char *end;
02315 dbus_bool_t retval;
02316 dbus_bool_t high_bits;
02317
02318 _dbus_assert (start <= _dbus_string_get_length (source));
02319
02320 if (!_dbus_string_init (&result))
02321 return FALSE;
02322
02323 retval = FALSE;
02324
02325 high_bits = TRUE;
02326 p = (const unsigned char*) _dbus_string_get_const_data (source);
02327 end = p + _dbus_string_get_length (source);
02328 p += start;
02329
02330 while (p != end)
02331 {
02332 unsigned int val;
02333
02334 switch (*p)
02335 {
02336 case '0':
02337 val = 0;
02338 break;
02339 case '1':
02340 val = 1;
02341 break;
02342 case '2':
02343 val = 2;
02344 break;
02345 case '3':
02346 val = 3;
02347 break;
02348 case '4':
02349 val = 4;
02350 break;
02351 case '5':
02352 val = 5;
02353 break;
02354 case '6':
02355 val = 6;
02356 break;
02357 case '7':
02358 val = 7;
02359 break;
02360 case '8':
02361 val = 8;
02362 break;
02363 case '9':
02364 val = 9;
02365 break;
02366 case 'a':
02367 case 'A':
02368 val = 10;
02369 break;
02370 case 'b':
02371 case 'B':
02372 val = 11;
02373 break;
02374 case 'c':
02375 case 'C':
02376 val = 12;
02377 break;
02378 case 'd':
02379 case 'D':
02380 val = 13;
02381 break;
02382 case 'e':
02383 case 'E':
02384 val = 14;
02385 break;
02386 case 'f':
02387 case 'F':
02388 val = 15;
02389 break;
02390 default:
02391 goto done;
02392 }
02393
02394 if (high_bits)
02395 {
02396 if (!_dbus_string_append_byte (&result,
02397 val << 4))
02398 goto out;
02399 }
02400 else
02401 {
02402 int len;
02403 unsigned char b;
02404
02405 len = _dbus_string_get_length (&result);
02406
02407 b = _dbus_string_get_byte (&result, len - 1);
02408
02409 b |= val;
02410
02411 _dbus_string_set_byte (&result, len - 1, b);
02412 }
02413
02414 high_bits = !high_bits;
02415
02416 ++p;
02417 }
02418
02419 done:
02420 if (!_dbus_string_move (&result, 0, dest, insert_at))
02421 goto out;
02422
02423 if (end_return)
02424 *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
02425
02426 retval = TRUE;
02427
02428 out:
02429 _dbus_string_free (&result);
02430 return retval;
02431 }
02432
02446 dbus_bool_t
02447 _dbus_string_validate_ascii (const DBusString *str,
02448 int start,
02449 int len)
02450 {
02451 const unsigned char *s;
02452 const unsigned char *end;
02453 DBUS_CONST_STRING_PREAMBLE (str);
02454 _dbus_assert (start >= 0);
02455 _dbus_assert (start <= real->len);
02456 _dbus_assert (len >= 0);
02457
02458 if (len > real->len - start)
02459 return FALSE;
02460
02461 s = real->str + start;
02462 end = s + len;
02463 while (s != end)
02464 {
02465 if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
02466 return FALSE;
02467
02468 ++s;
02469 }
02470
02471 return TRUE;
02472 }
02473
02481 void
02482 _dbus_string_tolower_ascii (const DBusString *str,
02483 int start,
02484 int len)
02485 {
02486 unsigned char *s;
02487 unsigned char *end;
02488 DBUS_STRING_PREAMBLE (str);
02489 _dbus_assert (start >= 0);
02490 _dbus_assert (start <= real->len);
02491 _dbus_assert (len >= 0);
02492 _dbus_assert (len <= real->len - start);
02493
02494 s = real->str + start;
02495 end = s + len;
02496
02497 while (s != end)
02498 {
02499 if (*s >= 'A' && *s <= 'Z')
02500 *s += 'a' - 'A';
02501 ++s;
02502 }
02503 }
02504
02512 void
02513 _dbus_string_toupper_ascii (const DBusString *str,
02514 int start,
02515 int len)
02516 {
02517 unsigned char *s;
02518 unsigned char *end;
02519 DBUS_STRING_PREAMBLE (str);
02520 _dbus_assert (start >= 0);
02521 _dbus_assert (start <= real->len);
02522 _dbus_assert (len >= 0);
02523 _dbus_assert (len <= real->len - start);
02524
02525 s = real->str + start;
02526 end = s + len;
02527
02528 while (s != end)
02529 {
02530 if (*s >= 'a' && *s <= 'z')
02531 *s += 'A' - 'a';
02532 ++s;
02533 }
02534 }
02535
02551 dbus_bool_t
02552 _dbus_string_validate_utf8 (const DBusString *str,
02553 int start,
02554 int len)
02555 {
02556 const unsigned char *p;
02557 const unsigned char *end;
02558 DBUS_CONST_STRING_PREAMBLE (str);
02559 _dbus_assert (start >= 0);
02560 _dbus_assert (start <= real->len);
02561 _dbus_assert (len >= 0);
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571 if (_DBUS_UNLIKELY (len > real->len - start))
02572 return FALSE;
02573
02574 p = real->str + start;
02575 end = p + len;
02576
02577 while (p < end)
02578 {
02579 int i, mask, char_len;
02580 dbus_unichar_t result;
02581
02582
02583 if (*p == '\0')
02584 break;
02585
02586
02587
02588
02589
02590
02591
02592 if (*p < 128)
02593 {
02594 ++p;
02595 continue;
02596 }
02597
02598 UTF8_COMPUTE (*p, mask, char_len);
02599
02600 if (_DBUS_UNLIKELY (char_len == 0))
02601 break;
02602
02603
02604 if (_DBUS_UNLIKELY ((end - p) < char_len))
02605 break;
02606
02607 UTF8_GET (result, p, i, mask, char_len);
02608
02609
02610 if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len))
02611 break;
02612 #if 0
02613
02614 if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1))
02615 break;
02616 #endif
02617
02618 if (_DBUS_UNLIKELY (!UNICODE_VALID (result)))
02619 break;
02620
02621
02622 _dbus_assert (result != (dbus_unichar_t)-1);
02623
02624 p += char_len;
02625 }
02626
02627
02628
02629
02630 if (_DBUS_UNLIKELY (p != end))
02631 return FALSE;
02632 else
02633 return TRUE;
02634 }
02635
02649 dbus_bool_t
02650 _dbus_string_validate_nul (const DBusString *str,
02651 int start,
02652 int len)
02653 {
02654 const unsigned char *s;
02655 const unsigned char *end;
02656 DBUS_CONST_STRING_PREAMBLE (str);
02657 _dbus_assert (start >= 0);
02658 _dbus_assert (len >= 0);
02659 _dbus_assert (start <= real->len);
02660
02661 if (len > real->len - start)
02662 return FALSE;
02663
02664 s = real->str + start;
02665 end = s + len;
02666 while (s != end)
02667 {
02668 if (_DBUS_UNLIKELY (*s != '\0'))
02669 return FALSE;
02670 ++s;
02671 }
02672
02673 return TRUE;
02674 }
02675
02681 void
02682 _dbus_string_zero (DBusString *str)
02683 {
02684 DBUS_STRING_PREAMBLE (str);
02685
02686 memset (real->str - real->align_offset, '\0', real->allocated);
02687 }
02690