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_STATIC_ASSERT (sizeof (DBusString) == sizeof (DBusRealString));
00138
00139 _dbus_assert (str != NULL);
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
00244 dbus_bool_t
00245 _dbus_string_init_from_string(DBusString *str,
00246 const DBusString *from)
00247 {
00248 if (!_dbus_string_init (str))
00249 return FALSE;
00250 return _dbus_string_append (str, _dbus_string_get_const_data (from));
00251 }
00252
00258 void
00259 _dbus_string_free (DBusString *str)
00260 {
00261 DBusRealString *real = (DBusRealString*) str;
00262 DBUS_GENERIC_STRING_PREAMBLE (real);
00263
00264 if (real->constant)
00265 return;
00266
00267
00268
00269
00270
00271 if (real->str == NULL)
00272 return;
00273
00274 dbus_free (real->str - real->align_offset);
00275
00276 real->invalid = TRUE;
00277 }
00278
00279 static dbus_bool_t
00280 compact (DBusRealString *real,
00281 int max_waste)
00282 {
00283 unsigned char *new_str;
00284 int new_allocated;
00285 int waste;
00286
00287 waste = real->allocated - (real->len + _DBUS_STRING_ALLOCATION_PADDING);
00288
00289 if (waste <= max_waste)
00290 return TRUE;
00291
00292 new_allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING;
00293
00294 new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
00295 if (_DBUS_UNLIKELY (new_str == NULL))
00296 return FALSE;
00297
00298 real->str = new_str + real->align_offset;
00299 real->allocated = new_allocated;
00300 fixup_alignment (real);
00301
00302 return TRUE;
00303 }
00304
00305 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
00306
00307
00308
00318 void
00319 _dbus_string_lock (DBusString *str)
00320 {
00321 DBUS_LOCKED_STRING_PREAMBLE (str);
00322
00323 real->locked = TRUE;
00324
00325
00326
00327
00328 #define MAX_WASTE 48
00329 compact (real, MAX_WASTE);
00330 }
00331 #endif
00332
00333 static dbus_bool_t
00334 reallocate_for_length (DBusRealString *real,
00335 int new_length)
00336 {
00337 int new_allocated;
00338 unsigned char *new_str;
00339
00340
00341
00342
00343 if (real->allocated > (_DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2)
00344 new_allocated = _DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING;
00345 else
00346 new_allocated = real->allocated * 2;
00347
00348
00349
00350
00351
00352
00353
00354
00355 #if defined (DBUS_ENABLE_EMBEDDED_TESTS) && !defined (DBUS_DISABLE_ASSERT)
00356 new_allocated = 0;
00357
00358
00359 #endif
00360
00361
00362 new_allocated = MAX (new_allocated,
00363 new_length + _DBUS_STRING_ALLOCATION_PADDING);
00364
00365 _dbus_assert (new_allocated >= real->allocated);
00366 new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
00367 if (_DBUS_UNLIKELY (new_str == NULL))
00368 return FALSE;
00369
00370 real->str = new_str + real->align_offset;
00371 real->allocated = new_allocated;
00372 fixup_alignment (real);
00373
00374 return TRUE;
00375 }
00376
00388 dbus_bool_t
00389 _dbus_string_compact (DBusString *str,
00390 int max_waste)
00391 {
00392 DBUS_STRING_PREAMBLE (str);
00393
00394 return compact (real, max_waste);
00395 }
00396
00397 static dbus_bool_t
00398 set_length (DBusRealString *real,
00399 int new_length)
00400 {
00401
00402
00403
00404 if (_DBUS_UNLIKELY (new_length > _DBUS_STRING_MAX_LENGTH))
00405 return FALSE;
00406 else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) &&
00407 _DBUS_UNLIKELY (!reallocate_for_length (real, new_length)))
00408 return FALSE;
00409 else
00410 {
00411 real->len = new_length;
00412 real->str[new_length] = '\0';
00413 return TRUE;
00414 }
00415 }
00416
00417 static dbus_bool_t
00418 open_gap (int len,
00419 DBusRealString *dest,
00420 int insert_at)
00421 {
00422 if (len == 0)
00423 return TRUE;
00424
00425 if (len > _DBUS_STRING_MAX_LENGTH - dest->len)
00426 return FALSE;
00427
00428 if (!set_length (dest, dest->len + len))
00429 return FALSE;
00430
00431 memmove (dest->str + insert_at + len,
00432 dest->str + insert_at,
00433 dest->len - len - insert_at);
00434
00435 return TRUE;
00436 }
00437
00438 #ifndef _dbus_string_get_data
00439
00450 char*
00451 _dbus_string_get_data (DBusString *str)
00452 {
00453 DBUS_STRING_PREAMBLE (str);
00454
00455 return (char*) real->str;
00456 }
00457 #endif
00458
00459
00460 #ifndef _dbus_string_get_const_data
00461
00467 const char*
00468 _dbus_string_get_const_data (const DBusString *str)
00469 {
00470 DBUS_CONST_STRING_PREAMBLE (str);
00471
00472 return (const char*) real->str;
00473 }
00474 #endif
00475
00489 char*
00490 _dbus_string_get_data_len (DBusString *str,
00491 int start,
00492 int len)
00493 {
00494 DBUS_STRING_PREAMBLE (str);
00495 _dbus_assert (start >= 0);
00496 _dbus_assert (len >= 0);
00497 _dbus_assert (start <= real->len);
00498 _dbus_assert (len <= real->len - start);
00499
00500 return (char*) real->str + start;
00501 }
00502
00503
00504 #ifndef _dbus_string_get_const_data_len
00505
00513 const char*
00514 _dbus_string_get_const_data_len (const DBusString *str,
00515 int start,
00516 int len)
00517 {
00518 DBUS_CONST_STRING_PREAMBLE (str);
00519 _dbus_assert (start >= 0);
00520 _dbus_assert (len >= 0);
00521 _dbus_assert (start <= real->len);
00522 _dbus_assert (len <= real->len - start);
00523
00524 return (const char*) real->str + start;
00525 }
00526 #endif
00527
00528
00529 #ifndef _dbus_string_set_byte
00530
00537 void
00538 _dbus_string_set_byte (DBusString *str,
00539 int i,
00540 unsigned char byte)
00541 {
00542 DBUS_STRING_PREAMBLE (str);
00543 _dbus_assert (i < real->len);
00544 _dbus_assert (i >= 0);
00545
00546 real->str[i] = byte;
00547 }
00548 #endif
00549
00550
00551 #ifndef _dbus_string_get_byte
00552
00561 unsigned char
00562 _dbus_string_get_byte (const DBusString *str,
00563 int start)
00564 {
00565 DBUS_CONST_STRING_PREAMBLE (str);
00566 _dbus_assert (start <= real->len);
00567 _dbus_assert (start >= 0);
00568
00569 return real->str[start];
00570 }
00571 #endif
00572
00583 dbus_bool_t
00584 _dbus_string_insert_bytes (DBusString *str,
00585 int i,
00586 int n_bytes,
00587 unsigned char byte)
00588 {
00589 DBUS_STRING_PREAMBLE (str);
00590 _dbus_assert (i <= real->len);
00591 _dbus_assert (i >= 0);
00592 _dbus_assert (n_bytes >= 0);
00593
00594 if (n_bytes == 0)
00595 return TRUE;
00596
00597 if (!open_gap (n_bytes, real, i))
00598 return FALSE;
00599
00600 memset (real->str + i, byte, n_bytes);
00601
00602 return TRUE;
00603 }
00604
00613 dbus_bool_t
00614 _dbus_string_insert_byte (DBusString *str,
00615 int i,
00616 unsigned char byte)
00617 {
00618 DBUS_STRING_PREAMBLE (str);
00619 _dbus_assert (i <= real->len);
00620 _dbus_assert (i >= 0);
00621
00622 if (!open_gap (1, real, i))
00623 return FALSE;
00624
00625 real->str[i] = byte;
00626
00627 return TRUE;
00628 }
00629
00640 dbus_bool_t
00641 _dbus_string_steal_data (DBusString *str,
00642 char **data_return)
00643 {
00644 DBUS_STRING_PREAMBLE (str);
00645 _dbus_assert (data_return != NULL);
00646
00647 undo_alignment (real);
00648
00649 *data_return = (char*) real->str;
00650
00651
00652 if (!_dbus_string_init (str))
00653 {
00654
00655 real->str = (unsigned char*) *data_return;
00656 *data_return = NULL;
00657 fixup_alignment (real);
00658 return FALSE;
00659 }
00660
00661 return TRUE;
00662 }
00663
00671 dbus_bool_t
00672 _dbus_string_copy_data (const DBusString *str,
00673 char **data_return)
00674 {
00675 DBUS_CONST_STRING_PREAMBLE (str);
00676 _dbus_assert (data_return != NULL);
00677
00678 *data_return = dbus_malloc (real->len + 1);
00679 if (*data_return == NULL)
00680 return FALSE;
00681
00682 memcpy (*data_return, real->str, real->len + 1);
00683
00684 return TRUE;
00685 }
00686
00696 void
00697 _dbus_string_copy_to_buffer (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);
00707 }
00708
00718 void
00719 _dbus_string_copy_to_buffer_with_nul (const DBusString *str,
00720 char *buffer,
00721 int avail_len)
00722 {
00723 DBUS_CONST_STRING_PREAMBLE (str);
00724
00725 _dbus_assert (avail_len >= 0);
00726 _dbus_assert (avail_len > real->len);
00727
00728 memcpy (buffer, real->str, real->len+1);
00729 }
00730
00731
00732 #ifndef _dbus_string_get_length
00733
00738 int
00739 _dbus_string_get_length (const DBusString *str)
00740 {
00741 DBUS_CONST_STRING_PREAMBLE (str);
00742
00743 return real->len;
00744 }
00745 #endif
00746
00759 dbus_bool_t
00760 _dbus_string_lengthen (DBusString *str,
00761 int additional_length)
00762 {
00763 DBUS_STRING_PREAMBLE (str);
00764 _dbus_assert (additional_length >= 0);
00765
00766 if (_DBUS_UNLIKELY (additional_length > _DBUS_STRING_MAX_LENGTH - real->len))
00767 return FALSE;
00768
00769 return set_length (real,
00770 real->len + additional_length);
00771 }
00772
00779 void
00780 _dbus_string_shorten (DBusString *str,
00781 int length_to_remove)
00782 {
00783 DBUS_STRING_PREAMBLE (str);
00784 _dbus_assert (length_to_remove >= 0);
00785 _dbus_assert (length_to_remove <= real->len);
00786
00787 set_length (real,
00788 real->len - length_to_remove);
00789 }
00790
00801 dbus_bool_t
00802 _dbus_string_set_length (DBusString *str,
00803 int length)
00804 {
00805 DBUS_STRING_PREAMBLE (str);
00806 _dbus_assert (length >= 0);
00807
00808 return set_length (real, length);
00809 }
00810
00811 static dbus_bool_t
00812 align_insert_point_then_open_gap (DBusString *str,
00813 int *insert_at_p,
00814 int alignment,
00815 int gap_size)
00816 {
00817 unsigned long new_len;
00818 unsigned long gap_pos;
00819 int insert_at;
00820 int delta;
00821 DBUS_STRING_PREAMBLE (str);
00822 _dbus_assert (alignment >= 1);
00823 _dbus_assert (alignment <= 8);
00824
00825 insert_at = *insert_at_p;
00826
00827 _dbus_assert (insert_at <= real->len);
00828
00829 gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
00830 new_len = real->len + (gap_pos - insert_at) + gap_size;
00831
00832 if (_DBUS_UNLIKELY (new_len > (unsigned long) _DBUS_STRING_MAX_LENGTH))
00833 return FALSE;
00834
00835 delta = new_len - real->len;
00836 _dbus_assert (delta >= 0);
00837
00838 if (delta == 0)
00839 {
00840 _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
00841 return TRUE;
00842 }
00843
00844 if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
00845 real, insert_at)))
00846 return FALSE;
00847
00848
00849 if (gap_size < delta)
00850 {
00851 memset (&real->str[insert_at], '\0',
00852 gap_pos - insert_at);
00853 }
00854
00855 *insert_at_p = gap_pos;
00856
00857 return TRUE;
00858 }
00859
00860 static dbus_bool_t
00861 align_length_then_lengthen (DBusString *str,
00862 int alignment,
00863 int then_lengthen_by)
00864 {
00865 int insert_at;
00866
00867 insert_at = _dbus_string_get_length (str);
00868
00869 return align_insert_point_then_open_gap (str,
00870 &insert_at,
00871 alignment, then_lengthen_by);
00872 }
00873
00882 dbus_bool_t
00883 _dbus_string_align_length (DBusString *str,
00884 int alignment)
00885 {
00886 return align_length_then_lengthen (str, alignment, 0);
00887 }
00888
00898 dbus_bool_t
00899 _dbus_string_alloc_space (DBusString *str,
00900 int extra_bytes)
00901 {
00902 if (!_dbus_string_lengthen (str, extra_bytes))
00903 return FALSE;
00904 _dbus_string_shorten (str, extra_bytes);
00905
00906 return TRUE;
00907 }
00908
00909 static dbus_bool_t
00910 append (DBusRealString *real,
00911 const char *buffer,
00912 int buffer_len)
00913 {
00914 if (buffer_len == 0)
00915 return TRUE;
00916
00917 if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
00918 return FALSE;
00919
00920 memcpy (real->str + (real->len - buffer_len),
00921 buffer,
00922 buffer_len);
00923
00924 return TRUE;
00925 }
00926
00934 dbus_bool_t
00935 _dbus_string_append (DBusString *str,
00936 const char *buffer)
00937 {
00938 unsigned long buffer_len;
00939
00940 DBUS_STRING_PREAMBLE (str);
00941 _dbus_assert (buffer != NULL);
00942
00943 buffer_len = strlen (buffer);
00944 if (buffer_len > (unsigned long) _DBUS_STRING_MAX_LENGTH)
00945 return FALSE;
00946
00947 return append (real, buffer, buffer_len);
00948 }
00949
00951 #define ASSIGN_2_OCTETS(p, octets) \
00952 *((dbus_uint16_t*)(p)) = *((dbus_uint16_t*)(octets));
00953
00955 #define ASSIGN_4_OCTETS(p, octets) \
00956 *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
00957
00959 #define ASSIGN_8_OCTETS(p, octets) \
00960 *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
00961
00971 dbus_bool_t
00972 _dbus_string_insert_2_aligned (DBusString *str,
00973 int insert_at,
00974 const unsigned char octets[2])
00975 {
00976 DBUS_STRING_PREAMBLE (str);
00977
00978 if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2))
00979 return FALSE;
00980
00981 ASSIGN_2_OCTETS (real->str + insert_at, octets);
00982
00983 return TRUE;
00984 }
00985
00995 dbus_bool_t
00996 _dbus_string_insert_4_aligned (DBusString *str,
00997 int insert_at,
00998 const unsigned char octets[4])
00999 {
01000 DBUS_STRING_PREAMBLE (str);
01001
01002 if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
01003 return FALSE;
01004
01005 ASSIGN_4_OCTETS (real->str + insert_at, octets);
01006
01007 return TRUE;
01008 }
01009
01019 dbus_bool_t
01020 _dbus_string_insert_8_aligned (DBusString *str,
01021 int insert_at,
01022 const unsigned char octets[8])
01023 {
01024 DBUS_STRING_PREAMBLE (str);
01025
01026 if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
01027 return FALSE;
01028
01029 _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
01030
01031 ASSIGN_8_OCTETS (real->str + insert_at, octets);
01032
01033 return TRUE;
01034 }
01035
01036
01047 dbus_bool_t
01048 _dbus_string_insert_alignment (DBusString *str,
01049 int *insert_at,
01050 int alignment)
01051 {
01052 DBUS_STRING_PREAMBLE (str);
01053
01054 if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0))
01055 return FALSE;
01056
01057 _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at);
01058
01059 return TRUE;
01060 }
01061
01071 dbus_bool_t
01072 _dbus_string_append_printf_valist (DBusString *str,
01073 const char *format,
01074 va_list args)
01075 {
01076 dbus_bool_t ret = FALSE;
01077 int len;
01078 va_list args_copy;
01079
01080 DBUS_STRING_PREAMBLE (str);
01081
01082 DBUS_VA_COPY (args_copy, args);
01083
01084
01085 len = _dbus_printf_string_upper_bound (format, args);
01086
01087 if (len < 0)
01088 goto out;
01089
01090 if (!_dbus_string_lengthen (str, len))
01091 {
01092 goto out;
01093 }
01094
01095 vsprintf ((char*) (real->str + (real->len - len)),
01096 format, args_copy);
01097 ret = TRUE;
01098
01099 out:
01100 va_end (args_copy);
01101
01102 return ret;
01103 }
01104
01113 dbus_bool_t
01114 _dbus_string_append_printf (DBusString *str,
01115 const char *format,
01116 ...)
01117 {
01118 va_list args;
01119 dbus_bool_t retval;
01120
01121 va_start (args, format);
01122 retval = _dbus_string_append_printf_valist (str, format, args);
01123 va_end (args);
01124
01125 return retval;
01126 }
01127
01136 dbus_bool_t
01137 _dbus_string_append_len (DBusString *str,
01138 const char *buffer,
01139 int len)
01140 {
01141 DBUS_STRING_PREAMBLE (str);
01142 _dbus_assert (buffer != NULL);
01143 _dbus_assert (len >= 0);
01144
01145 return append (real, buffer, len);
01146 }
01147
01156 dbus_bool_t
01157 _dbus_string_append_byte (DBusString *str,
01158 unsigned char byte)
01159 {
01160 DBUS_STRING_PREAMBLE (str);
01161
01162 if (!set_length (real, real->len + 1))
01163 return FALSE;
01164
01165 real->str[real->len-1] = byte;
01166
01167 return TRUE;
01168 }
01169
01170 static void
01171 delete (DBusRealString *real,
01172 int start,
01173 int len)
01174 {
01175 if (len == 0)
01176 return;
01177
01178 memmove (real->str + start, real->str + start + len, real->len - (start + len));
01179 real->len -= len;
01180 real->str[real->len] = '\0';
01181 }
01182
01192 void
01193 _dbus_string_delete (DBusString *str,
01194 int start,
01195 int len)
01196 {
01197 DBUS_STRING_PREAMBLE (str);
01198 _dbus_assert (start >= 0);
01199 _dbus_assert (len >= 0);
01200 _dbus_assert (start <= real->len);
01201 _dbus_assert (len <= real->len - start);
01202
01203 delete (real, start, len);
01204 }
01205
01206 static dbus_bool_t
01207 copy (DBusRealString *source,
01208 int start,
01209 int len,
01210 DBusRealString *dest,
01211 int insert_at)
01212 {
01213 if (len == 0)
01214 return TRUE;
01215
01216 if (!open_gap (len, dest, insert_at))
01217 return FALSE;
01218
01219 memmove (dest->str + insert_at,
01220 source->str + start,
01221 len);
01222
01223 return TRUE;
01224 }
01225
01235 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at) \
01236 DBusRealString *real_source = (DBusRealString*) source; \
01237 DBusRealString *real_dest = (DBusRealString*) dest; \
01238 _dbus_assert ((source) != (dest)); \
01239 DBUS_GENERIC_STRING_PREAMBLE (real_source); \
01240 DBUS_GENERIC_STRING_PREAMBLE (real_dest); \
01241 _dbus_assert (!real_dest->constant); \
01242 _dbus_assert (!real_dest->locked); \
01243 _dbus_assert ((start) >= 0); \
01244 _dbus_assert ((start) <= real_source->len); \
01245 _dbus_assert ((insert_at) >= 0); \
01246 _dbus_assert ((insert_at) <= real_dest->len)
01247
01258 dbus_bool_t
01259 _dbus_string_move (DBusString *source,
01260 int start,
01261 DBusString *dest,
01262 int insert_at)
01263 {
01264 DBusRealString *real_source = (DBusRealString*) source;
01265 _dbus_assert (start <= real_source->len);
01266
01267 return _dbus_string_move_len (source, start,
01268 real_source->len - start,
01269 dest, insert_at);
01270 }
01271
01282 dbus_bool_t
01283 _dbus_string_copy (const DBusString *source,
01284 int start,
01285 DBusString *dest,
01286 int insert_at)
01287 {
01288 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01289
01290 return copy (real_source, start,
01291 real_source->len - start,
01292 real_dest,
01293 insert_at);
01294 }
01295
01307 dbus_bool_t
01308 _dbus_string_move_len (DBusString *source,
01309 int start,
01310 int len,
01311 DBusString *dest,
01312 int insert_at)
01313
01314 {
01315 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01316 _dbus_assert (len >= 0);
01317 _dbus_assert ((start + len) <= real_source->len);
01318
01319
01320 if (len == 0)
01321 {
01322 return TRUE;
01323 }
01324 else if (start == 0 &&
01325 len == real_source->len &&
01326 real_dest->len == 0)
01327 {
01328
01329
01330
01331
01332
01333
01334 #define ASSIGN_DATA(a, b) do { \
01335 (a)->str = (b)->str; \
01336 (a)->len = (b)->len; \
01337 (a)->allocated = (b)->allocated; \
01338 (a)->align_offset = (b)->align_offset; \
01339 } while (0)
01340
01341 DBusRealString tmp;
01342
01343 ASSIGN_DATA (&tmp, real_source);
01344 ASSIGN_DATA (real_source, real_dest);
01345 ASSIGN_DATA (real_dest, &tmp);
01346
01347 return TRUE;
01348 }
01349 else
01350 {
01351 if (!copy (real_source, start, len,
01352 real_dest,
01353 insert_at))
01354 return FALSE;
01355
01356 delete (real_source, start,
01357 len);
01358
01359 return TRUE;
01360 }
01361 }
01362
01374 dbus_bool_t
01375 _dbus_string_copy_len (const DBusString *source,
01376 int start,
01377 int len,
01378 DBusString *dest,
01379 int insert_at)
01380 {
01381 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
01382 _dbus_assert (len >= 0);
01383 _dbus_assert (start <= real_source->len);
01384 _dbus_assert (len <= real_source->len - start);
01385
01386 return copy (real_source, start, len,
01387 real_dest,
01388 insert_at);
01389 }
01390
01403 dbus_bool_t
01404 _dbus_string_replace_len (const DBusString *source,
01405 int start,
01406 int len,
01407 DBusString *dest,
01408 int replace_at,
01409 int replace_len)
01410 {
01411 DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
01412 _dbus_assert (len >= 0);
01413 _dbus_assert (start <= real_source->len);
01414 _dbus_assert (len <= real_source->len - start);
01415 _dbus_assert (replace_at >= 0);
01416 _dbus_assert (replace_at <= real_dest->len);
01417 _dbus_assert (replace_len <= real_dest->len - replace_at);
01418
01419 if (len == replace_len)
01420 {
01421 memmove (real_dest->str + replace_at,
01422 real_source->str + start, len);
01423 }
01424 else if (len < replace_len)
01425 {
01426 memmove (real_dest->str + replace_at,
01427 real_source->str + start, len);
01428 delete (real_dest, replace_at + len,
01429 replace_len - len);
01430 }
01431 else
01432 {
01433 int diff;
01434
01435 _dbus_assert (len > replace_len);
01436
01437 diff = len - replace_len;
01438
01439
01440
01441
01442
01443 if (!copy (real_source, start + replace_len, diff,
01444 real_dest, replace_at + replace_len))
01445 return FALSE;
01446
01447 memmove (real_dest->str + replace_at,
01448 real_source->str + start, replace_len);
01449 }
01450
01451 return TRUE;
01452 }
01453
01466 dbus_bool_t
01467 _dbus_string_split_on_byte (DBusString *source,
01468 unsigned char byte,
01469 DBusString *tail)
01470 {
01471 int byte_position;
01472 char byte_string[2] = "";
01473 int head_length;
01474 int tail_length;
01475
01476 byte_string[0] = (char) byte;
01477
01478 if (!_dbus_string_find (source, 0, byte_string, &byte_position))
01479 return FALSE;
01480
01481 head_length = byte_position;
01482 tail_length = _dbus_string_get_length (source) - head_length - 1;
01483
01484 if (!_dbus_string_move_len (source, byte_position + 1, tail_length,
01485 tail, 0))
01486 return FALSE;
01487
01488
01489
01490 if (!_dbus_string_set_length (source, head_length))
01491 return FALSE;
01492
01493 return TRUE;
01494 }
01495
01496
01497
01498
01499
01505 #define UTF8_COMPUTE(Char, Mask, Len) \
01506 if (Char < 128) \
01507 { \
01508 Len = 1; \
01509 Mask = 0x7f; \
01510 } \
01511 else if ((Char & 0xe0) == 0xc0) \
01512 { \
01513 Len = 2; \
01514 Mask = 0x1f; \
01515 } \
01516 else if ((Char & 0xf0) == 0xe0) \
01517 { \
01518 Len = 3; \
01519 Mask = 0x0f; \
01520 } \
01521 else if ((Char & 0xf8) == 0xf0) \
01522 { \
01523 Len = 4; \
01524 Mask = 0x07; \
01525 } \
01526 else if ((Char & 0xfc) == 0xf8) \
01527 { \
01528 Len = 5; \
01529 Mask = 0x03; \
01530 } \
01531 else if ((Char & 0xfe) == 0xfc) \
01532 { \
01533 Len = 6; \
01534 Mask = 0x01; \
01535 } \
01536 else \
01537 { \
01538 Len = 0; \
01539 Mask = 0; \
01540 }
01541
01546 #define UTF8_LENGTH(Char) \
01547 ((Char) < 0x80 ? 1 : \
01548 ((Char) < 0x800 ? 2 : \
01549 ((Char) < 0x10000 ? 3 : \
01550 ((Char) < 0x200000 ? 4 : \
01551 ((Char) < 0x4000000 ? 5 : 6)))))
01552
01562 #define UTF8_GET(Result, Chars, Count, Mask, Len) \
01563 (Result) = (Chars)[0] & (Mask); \
01564 for ((Count) = 1; (Count) < (Len); ++(Count)) \
01565 { \
01566 if (((Chars)[(Count)] & 0xc0) != 0x80) \
01567 { \
01568 (Result) = -1; \
01569 break; \
01570 } \
01571 (Result) <<= 6; \
01572 (Result) |= ((Chars)[(Count)] & 0x3f); \
01573 }
01574
01585 #define UNICODE_VALID(Char) \
01586 ((Char) < 0x110000 && \
01587 (((Char) & 0xFFFFF800) != 0xD800))
01588
01603 dbus_bool_t
01604 _dbus_string_find (const DBusString *str,
01605 int start,
01606 const char *substr,
01607 int *found)
01608 {
01609 return _dbus_string_find_to (str, start,
01610 ((const DBusRealString*)str)->len,
01611 substr, found);
01612 }
01613
01626 dbus_bool_t
01627 _dbus_string_find_eol (const DBusString *str,
01628 int start,
01629 int *found,
01630 int *found_len)
01631 {
01632 int i;
01633
01634 DBUS_CONST_STRING_PREAMBLE (str);
01635 _dbus_assert (start <= real->len);
01636 _dbus_assert (start >= 0);
01637
01638 i = start;
01639 while (i < real->len)
01640 {
01641 if (real->str[i] == '\r')
01642 {
01643 if ((i+1) < real->len && real->str[i+1] == '\n')
01644 {
01645 if (found)
01646 *found = i;
01647 if (found_len)
01648 *found_len = 2;
01649 return TRUE;
01650 }
01651 else
01652 {
01653 if (found)
01654 *found = i;
01655 if (found_len)
01656 *found_len = 1;
01657 return TRUE;
01658 }
01659 }
01660 else if (real->str[i] == '\n')
01661 {
01662 if (found)
01663 *found = i;
01664 if (found_len)
01665 *found_len = 1;
01666 return TRUE;
01667 }
01668 ++i;
01669 }
01670
01671 if (found)
01672 *found = real->len;
01673
01674 if (found_len)
01675 *found_len = 0;
01676
01677 return FALSE;
01678 }
01679
01696 dbus_bool_t
01697 _dbus_string_find_to (const DBusString *str,
01698 int start,
01699 int end,
01700 const char *substr,
01701 int *found)
01702 {
01703 int i;
01704 DBUS_CONST_STRING_PREAMBLE (str);
01705 _dbus_assert (substr != NULL);
01706 _dbus_assert (start <= real->len);
01707 _dbus_assert (start >= 0);
01708 _dbus_assert (substr != NULL);
01709 _dbus_assert (end <= real->len);
01710 _dbus_assert (start <= end);
01711
01712
01713 if (*substr == '\0')
01714 {
01715 if (found)
01716 *found = start;
01717 return TRUE;
01718 }
01719
01720 i = start;
01721 while (i < end)
01722 {
01723 if (real->str[i] == substr[0])
01724 {
01725 int j = i + 1;
01726
01727 while (j < end)
01728 {
01729 if (substr[j - i] == '\0')
01730 break;
01731 else if (real->str[j] != substr[j - i])
01732 break;
01733
01734 ++j;
01735 }
01736
01737 if (substr[j - i] == '\0')
01738 {
01739 if (found)
01740 *found = i;
01741 return TRUE;
01742 }
01743 }
01744
01745 ++i;
01746 }
01747
01748 if (found)
01749 *found = end;
01750
01751 return FALSE;
01752 }
01753
01764 dbus_bool_t
01765 _dbus_string_find_blank (const DBusString *str,
01766 int start,
01767 int *found)
01768 {
01769 int i;
01770 DBUS_CONST_STRING_PREAMBLE (str);
01771 _dbus_assert (start <= real->len);
01772 _dbus_assert (start >= 0);
01773
01774 i = start;
01775 while (i < real->len)
01776 {
01777 if (real->str[i] == ' ' ||
01778 real->str[i] == '\t')
01779 {
01780 if (found)
01781 *found = i;
01782 return TRUE;
01783 }
01784
01785 ++i;
01786 }
01787
01788 if (found)
01789 *found = real->len;
01790
01791 return FALSE;
01792 }
01793
01802 void
01803 _dbus_string_skip_blank (const DBusString *str,
01804 int start,
01805 int *end)
01806 {
01807 int i;
01808 DBUS_CONST_STRING_PREAMBLE (str);
01809 _dbus_assert (start <= real->len);
01810 _dbus_assert (start >= 0);
01811
01812 i = start;
01813 while (i < real->len)
01814 {
01815 if (!DBUS_IS_ASCII_BLANK (real->str[i]))
01816 break;
01817
01818 ++i;
01819 }
01820
01821 _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
01822
01823 if (end)
01824 *end = i;
01825 }
01826
01827
01836 void
01837 _dbus_string_skip_white (const DBusString *str,
01838 int start,
01839 int *end)
01840 {
01841 int i;
01842 DBUS_CONST_STRING_PREAMBLE (str);
01843 _dbus_assert (start <= real->len);
01844 _dbus_assert (start >= 0);
01845
01846 i = start;
01847 while (i < real->len)
01848 {
01849 if (!DBUS_IS_ASCII_WHITE (real->str[i]))
01850 break;
01851
01852 ++i;
01853 }
01854
01855 _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
01856
01857 if (end)
01858 *end = i;
01859 }
01860
01869 void
01870 _dbus_string_skip_white_reverse (const DBusString *str,
01871 int end,
01872 int *start)
01873 {
01874 int i;
01875 DBUS_CONST_STRING_PREAMBLE (str);
01876 _dbus_assert (end <= real->len);
01877 _dbus_assert (end >= 0);
01878
01879 i = end;
01880 while (i > 0)
01881 {
01882 if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
01883 break;
01884 --i;
01885 }
01886
01887 _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
01888
01889 if (start)
01890 *start = i;
01891 }
01892
01908 dbus_bool_t
01909 _dbus_string_pop_line (DBusString *source,
01910 DBusString *dest)
01911 {
01912 int eol, eol_len;
01913
01914 _dbus_string_set_length (dest, 0);
01915
01916 eol = 0;
01917 eol_len = 0;
01918 if (!_dbus_string_find_eol (source, 0, &eol, &eol_len))
01919 {
01920 _dbus_assert (eol == _dbus_string_get_length (source));
01921 if (eol == 0)
01922 {
01923
01924 return FALSE;
01925 }
01926
01927 }
01928
01929
01930
01931
01932
01933 if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0))
01934 return FALSE;
01935
01936
01937 if (!_dbus_string_set_length (dest, eol))
01938 {
01939 _dbus_assert_not_reached ("out of memory when shortening a string");
01940 return FALSE;
01941 }
01942
01943 return TRUE;
01944 }
01945
01946 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
01947
01953 void
01954 _dbus_string_delete_first_word (DBusString *str)
01955 {
01956 int i;
01957
01958 if (_dbus_string_find_blank (str, 0, &i))
01959 _dbus_string_skip_blank (str, i, &i);
01960
01961 _dbus_string_delete (str, 0, i);
01962 }
01963 #endif
01964
01965 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
01966
01971 void
01972 _dbus_string_delete_leading_blanks (DBusString *str)
01973 {
01974 int i;
01975
01976 _dbus_string_skip_blank (str, 0, &i);
01977
01978 if (i > 0)
01979 _dbus_string_delete (str, 0, i);
01980 }
01981 #endif
01982
01988 void
01989 _dbus_string_chop_white(DBusString *str)
01990 {
01991 int i;
01992
01993 _dbus_string_skip_white (str, 0, &i);
01994
01995 if (i > 0)
01996 _dbus_string_delete (str, 0, i);
01997
01998 _dbus_string_skip_white_reverse (str, _dbus_string_get_length (str), &i);
01999
02000 _dbus_string_set_length (str, i);
02001 }
02002
02012 dbus_bool_t
02013 _dbus_string_equal (const DBusString *a,
02014 const DBusString *b)
02015 {
02016 const unsigned char *ap;
02017 const unsigned char *bp;
02018 const unsigned char *a_end;
02019 const DBusRealString *real_a = (const DBusRealString*) a;
02020 const DBusRealString *real_b = (const DBusRealString*) b;
02021 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02022 DBUS_GENERIC_STRING_PREAMBLE (real_b);
02023
02024 if (real_a->len != real_b->len)
02025 return FALSE;
02026
02027 ap = real_a->str;
02028 bp = real_b->str;
02029 a_end = real_a->str + real_a->len;
02030 while (ap != a_end)
02031 {
02032 if (*ap != *bp)
02033 return FALSE;
02034
02035 ++ap;
02036 ++bp;
02037 }
02038
02039 return TRUE;
02040 }
02041
02055 dbus_bool_t
02056 _dbus_string_equal_len (const DBusString *a,
02057 const DBusString *b,
02058 int len)
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 const DBusRealString *real_b = (const DBusRealString*) b;
02065 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02066 DBUS_GENERIC_STRING_PREAMBLE (real_b);
02067
02068 if (real_a->len != real_b->len &&
02069 (real_a->len < len || real_b->len < len))
02070 return FALSE;
02071
02072 ap = real_a->str;
02073 bp = real_b->str;
02074 a_end = real_a->str + MIN (real_a->len, len);
02075 while (ap != a_end)
02076 {
02077 if (*ap != *bp)
02078 return FALSE;
02079
02080 ++ap;
02081 ++bp;
02082 }
02083
02084 return TRUE;
02085 }
02086
02103 dbus_bool_t
02104 _dbus_string_equal_substring (const DBusString *a,
02105 int a_start,
02106 int a_len,
02107 const DBusString *b,
02108 int b_start)
02109 {
02110 const unsigned char *ap;
02111 const unsigned char *bp;
02112 const unsigned char *a_end;
02113 const DBusRealString *real_a = (const DBusRealString*) a;
02114 const DBusRealString *real_b = (const DBusRealString*) b;
02115 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02116 DBUS_GENERIC_STRING_PREAMBLE (real_b);
02117 _dbus_assert (a_start >= 0);
02118 _dbus_assert (a_len >= 0);
02119 _dbus_assert (a_start <= real_a->len);
02120 _dbus_assert (a_len <= real_a->len - a_start);
02121 _dbus_assert (b_start >= 0);
02122 _dbus_assert (b_start <= real_b->len);
02123
02124 if (a_len > real_b->len - b_start)
02125 return FALSE;
02126
02127 ap = real_a->str + a_start;
02128 bp = real_b->str + b_start;
02129 a_end = ap + a_len;
02130 while (ap != a_end)
02131 {
02132 if (*ap != *bp)
02133 return FALSE;
02134
02135 ++ap;
02136 ++bp;
02137 }
02138
02139 _dbus_assert (bp <= (real_b->str + real_b->len));
02140
02141 return TRUE;
02142 }
02143
02151 dbus_bool_t
02152 _dbus_string_equal_c_str (const DBusString *a,
02153 const char *c_str)
02154 {
02155 const unsigned char *ap;
02156 const unsigned char *bp;
02157 const unsigned char *a_end;
02158 const DBusRealString *real_a = (const DBusRealString*) a;
02159 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02160 _dbus_assert (c_str != NULL);
02161
02162 ap = real_a->str;
02163 bp = (const unsigned char*) c_str;
02164 a_end = real_a->str + real_a->len;
02165 while (ap != a_end && *bp)
02166 {
02167 if (*ap != *bp)
02168 return FALSE;
02169
02170 ++ap;
02171 ++bp;
02172 }
02173
02174 if (ap != a_end || *bp)
02175 return FALSE;
02176
02177 return TRUE;
02178 }
02179
02187 dbus_bool_t
02188 _dbus_string_starts_with_c_str (const DBusString *a,
02189 const char *c_str)
02190 {
02191 const unsigned char *ap;
02192 const unsigned char *bp;
02193 const unsigned char *a_end;
02194 const DBusRealString *real_a = (const DBusRealString*) a;
02195 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02196 _dbus_assert (c_str != NULL);
02197
02198 ap = real_a->str;
02199 bp = (const unsigned char*) c_str;
02200 a_end = real_a->str + real_a->len;
02201 while (ap != a_end && *bp)
02202 {
02203 if (*ap != *bp)
02204 return FALSE;
02205
02206 ++ap;
02207 ++bp;
02208 }
02209
02210 if (*bp == '\0')
02211 return TRUE;
02212 else
02213 return FALSE;
02214 }
02215
02224 dbus_bool_t
02225 _dbus_string_append_byte_as_hex (DBusString *str,
02226 unsigned char byte)
02227 {
02228 const char hexdigits[16] = {
02229 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
02230 'a', 'b', 'c', 'd', 'e', 'f'
02231 };
02232
02233 if (!_dbus_string_append_byte (str,
02234 hexdigits[(byte >> 4)]))
02235 return FALSE;
02236
02237 if (!_dbus_string_append_byte (str,
02238 hexdigits[(byte & 0x0f)]))
02239 {
02240 _dbus_string_set_length (str,
02241 _dbus_string_get_length (str) - 1);
02242 return FALSE;
02243 }
02244
02245 return TRUE;
02246 }
02247
02258 dbus_bool_t
02259 _dbus_string_hex_encode (const DBusString *source,
02260 int start,
02261 DBusString *dest,
02262 int insert_at)
02263 {
02264 DBusString result;
02265 const unsigned char *p;
02266 const unsigned char *end;
02267 dbus_bool_t retval;
02268
02269 _dbus_assert (start <= _dbus_string_get_length (source));
02270
02271 if (!_dbus_string_init (&result))
02272 return FALSE;
02273
02274 retval = FALSE;
02275
02276 p = (const unsigned char*) _dbus_string_get_const_data (source);
02277 end = p + _dbus_string_get_length (source);
02278 p += start;
02279
02280 while (p != end)
02281 {
02282 if (!_dbus_string_append_byte_as_hex (&result, *p))
02283 goto out;
02284
02285 ++p;
02286 }
02287
02288 if (!_dbus_string_move (&result, 0, dest, insert_at))
02289 goto out;
02290
02291 retval = TRUE;
02292
02293 out:
02294 _dbus_string_free (&result);
02295 return retval;
02296 }
02297
02308 dbus_bool_t
02309 _dbus_string_hex_decode (const DBusString *source,
02310 int start,
02311 int *end_return,
02312 DBusString *dest,
02313 int insert_at)
02314 {
02315 DBusString result;
02316 const unsigned char *p;
02317 const unsigned char *end;
02318 dbus_bool_t retval;
02319 dbus_bool_t high_bits;
02320
02321 _dbus_assert (start <= _dbus_string_get_length (source));
02322
02323 if (!_dbus_string_init (&result))
02324 return FALSE;
02325
02326 retval = FALSE;
02327
02328 high_bits = TRUE;
02329 p = (const unsigned char*) _dbus_string_get_const_data (source);
02330 end = p + _dbus_string_get_length (source);
02331 p += start;
02332
02333 while (p != end)
02334 {
02335 unsigned int val;
02336
02337 switch (*p)
02338 {
02339 case '0':
02340 val = 0;
02341 break;
02342 case '1':
02343 val = 1;
02344 break;
02345 case '2':
02346 val = 2;
02347 break;
02348 case '3':
02349 val = 3;
02350 break;
02351 case '4':
02352 val = 4;
02353 break;
02354 case '5':
02355 val = 5;
02356 break;
02357 case '6':
02358 val = 6;
02359 break;
02360 case '7':
02361 val = 7;
02362 break;
02363 case '8':
02364 val = 8;
02365 break;
02366 case '9':
02367 val = 9;
02368 break;
02369 case 'a':
02370 case 'A':
02371 val = 10;
02372 break;
02373 case 'b':
02374 case 'B':
02375 val = 11;
02376 break;
02377 case 'c':
02378 case 'C':
02379 val = 12;
02380 break;
02381 case 'd':
02382 case 'D':
02383 val = 13;
02384 break;
02385 case 'e':
02386 case 'E':
02387 val = 14;
02388 break;
02389 case 'f':
02390 case 'F':
02391 val = 15;
02392 break;
02393 default:
02394 goto done;
02395 }
02396
02397 if (high_bits)
02398 {
02399 if (!_dbus_string_append_byte (&result,
02400 val << 4))
02401 goto out;
02402 }
02403 else
02404 {
02405 int len;
02406 unsigned char b;
02407
02408 len = _dbus_string_get_length (&result);
02409
02410 b = _dbus_string_get_byte (&result, len - 1);
02411
02412 b |= val;
02413
02414 _dbus_string_set_byte (&result, len - 1, b);
02415 }
02416
02417 high_bits = !high_bits;
02418
02419 ++p;
02420 }
02421
02422 done:
02423 if (!_dbus_string_move (&result, 0, dest, insert_at))
02424 goto out;
02425
02426 if (end_return)
02427 *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
02428
02429 retval = TRUE;
02430
02431 out:
02432 _dbus_string_free (&result);
02433 return retval;
02434 }
02435
02449 dbus_bool_t
02450 _dbus_string_validate_ascii (const DBusString *str,
02451 int start,
02452 int len)
02453 {
02454 const unsigned char *s;
02455 const unsigned char *end;
02456 DBUS_CONST_STRING_PREAMBLE (str);
02457 _dbus_assert (start >= 0);
02458 _dbus_assert (start <= real->len);
02459 _dbus_assert (len >= 0);
02460
02461 if (len > real->len - start)
02462 return FALSE;
02463
02464 s = real->str + start;
02465 end = s + len;
02466 while (s != end)
02467 {
02468 if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
02469 return FALSE;
02470
02471 ++s;
02472 }
02473
02474 return TRUE;
02475 }
02476
02484 void
02485 _dbus_string_tolower_ascii (const DBusString *str,
02486 int start,
02487 int len)
02488 {
02489 unsigned char *s;
02490 unsigned char *end;
02491 DBUS_STRING_PREAMBLE (str);
02492 _dbus_assert (start >= 0);
02493 _dbus_assert (start <= real->len);
02494 _dbus_assert (len >= 0);
02495 _dbus_assert (len <= real->len - start);
02496
02497 s = real->str + start;
02498 end = s + len;
02499
02500 while (s != end)
02501 {
02502 if (*s >= 'A' && *s <= 'Z')
02503 *s += 'a' - 'A';
02504 ++s;
02505 }
02506 }
02507
02515 void
02516 _dbus_string_toupper_ascii (const DBusString *str,
02517 int start,
02518 int len)
02519 {
02520 unsigned char *s;
02521 unsigned char *end;
02522 DBUS_STRING_PREAMBLE (str);
02523 _dbus_assert (start >= 0);
02524 _dbus_assert (start <= real->len);
02525 _dbus_assert (len >= 0);
02526 _dbus_assert (len <= real->len - start);
02527
02528 s = real->str + start;
02529 end = s + len;
02530
02531 while (s != end)
02532 {
02533 if (*s >= 'a' && *s <= 'z')
02534 *s += 'A' - 'a';
02535 ++s;
02536 }
02537 }
02538
02554 dbus_bool_t
02555 _dbus_string_validate_utf8 (const DBusString *str,
02556 int start,
02557 int len)
02558 {
02559 const unsigned char *p;
02560 const unsigned char *end;
02561 DBUS_CONST_STRING_PREAMBLE (str);
02562 _dbus_assert (start >= 0);
02563 _dbus_assert (start <= real->len);
02564 _dbus_assert (len >= 0);
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574 if (_DBUS_UNLIKELY (len > real->len - start))
02575 return FALSE;
02576
02577 p = real->str + start;
02578 end = p + len;
02579
02580 while (p < end)
02581 {
02582 int i, mask, char_len;
02583 dbus_unichar_t result;
02584
02585
02586 if (*p == '\0')
02587 break;
02588
02589
02590
02591
02592
02593
02594
02595 if (*p < 128)
02596 {
02597 ++p;
02598 continue;
02599 }
02600
02601 UTF8_COMPUTE (*p, mask, char_len);
02602
02603 if (_DBUS_UNLIKELY (char_len == 0))
02604 break;
02605
02606
02607 if (_DBUS_UNLIKELY ((end - p) < char_len))
02608 break;
02609
02610 UTF8_GET (result, p, i, mask, char_len);
02611
02612
02613 if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len))
02614 break;
02615 #if 0
02616
02617 if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1))
02618 break;
02619 #endif
02620
02621 if (_DBUS_UNLIKELY (!UNICODE_VALID (result)))
02622 break;
02623
02624
02625 _dbus_assert (result != (dbus_unichar_t)-1);
02626
02627 p += char_len;
02628 }
02629
02630
02631
02632
02633 if (_DBUS_UNLIKELY (p != end))
02634 return FALSE;
02635 else
02636 return TRUE;
02637 }
02638
02652 dbus_bool_t
02653 _dbus_string_validate_nul (const DBusString *str,
02654 int start,
02655 int len)
02656 {
02657 const unsigned char *s;
02658 const unsigned char *end;
02659 DBUS_CONST_STRING_PREAMBLE (str);
02660 _dbus_assert (start >= 0);
02661 _dbus_assert (len >= 0);
02662 _dbus_assert (start <= real->len);
02663
02664 if (len > real->len - start)
02665 return FALSE;
02666
02667 s = real->str + start;
02668 end = s + len;
02669 while (s != end)
02670 {
02671 if (_DBUS_UNLIKELY (*s != '\0'))
02672 return FALSE;
02673 ++s;
02674 }
02675
02676 return TRUE;
02677 }
02678
02684 void
02685 _dbus_string_zero (DBusString *str)
02686 {
02687 DBUS_STRING_PREAMBLE (str);
02688
02689 memset (real->str - real->align_offset, '\0', real->allocated);
02690 }
02693