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
01588 #define UNICODE_VALID(Char) \
01589 ((Char) < 0x110000 && \
01590 (((Char) & 0xFFFFF800) != 0xD800) && \
01591 ((Char) < 0xFDD0 || (Char) > 0xFDEF) && \
01592 ((Char) & 0xFFFE) != 0xFFFE)
01593
01608 dbus_bool_t
01609 _dbus_string_find (const DBusString *str,
01610 int start,
01611 const char *substr,
01612 int *found)
01613 {
01614 return _dbus_string_find_to (str, start,
01615 ((const DBusRealString*)str)->len,
01616 substr, found);
01617 }
01618
01631 dbus_bool_t
01632 _dbus_string_find_eol (const DBusString *str,
01633 int start,
01634 int *found,
01635 int *found_len)
01636 {
01637 int i;
01638
01639 DBUS_CONST_STRING_PREAMBLE (str);
01640 _dbus_assert (start <= real->len);
01641 _dbus_assert (start >= 0);
01642
01643 i = start;
01644 while (i < real->len)
01645 {
01646 if (real->str[i] == '\r')
01647 {
01648 if ((i+1) < real->len && real->str[i+1] == '\n')
01649 {
01650 if (found)
01651 *found = i;
01652 if (found_len)
01653 *found_len = 2;
01654 return TRUE;
01655 }
01656 else
01657 {
01658 if (found)
01659 *found = i;
01660 if (found_len)
01661 *found_len = 1;
01662 return TRUE;
01663 }
01664 }
01665 else if (real->str[i] == '\n')
01666 {
01667 if (found)
01668 *found = i;
01669 if (found_len)
01670 *found_len = 1;
01671 return TRUE;
01672 }
01673 ++i;
01674 }
01675
01676 if (found)
01677 *found = real->len;
01678
01679 if (found_len)
01680 *found_len = 0;
01681
01682 return FALSE;
01683 }
01684
01701 dbus_bool_t
01702 _dbus_string_find_to (const DBusString *str,
01703 int start,
01704 int end,
01705 const char *substr,
01706 int *found)
01707 {
01708 int i;
01709 DBUS_CONST_STRING_PREAMBLE (str);
01710 _dbus_assert (substr != NULL);
01711 _dbus_assert (start <= real->len);
01712 _dbus_assert (start >= 0);
01713 _dbus_assert (substr != NULL);
01714 _dbus_assert (end <= real->len);
01715 _dbus_assert (start <= end);
01716
01717
01718 if (*substr == '\0')
01719 {
01720 if (found)
01721 *found = start;
01722 return TRUE;
01723 }
01724
01725 i = start;
01726 while (i < end)
01727 {
01728 if (real->str[i] == substr[0])
01729 {
01730 int j = i + 1;
01731
01732 while (j < end)
01733 {
01734 if (substr[j - i] == '\0')
01735 break;
01736 else if (real->str[j] != substr[j - i])
01737 break;
01738
01739 ++j;
01740 }
01741
01742 if (substr[j - i] == '\0')
01743 {
01744 if (found)
01745 *found = i;
01746 return TRUE;
01747 }
01748 }
01749
01750 ++i;
01751 }
01752
01753 if (found)
01754 *found = end;
01755
01756 return FALSE;
01757 }
01758
01769 dbus_bool_t
01770 _dbus_string_find_blank (const DBusString *str,
01771 int start,
01772 int *found)
01773 {
01774 int i;
01775 DBUS_CONST_STRING_PREAMBLE (str);
01776 _dbus_assert (start <= real->len);
01777 _dbus_assert (start >= 0);
01778
01779 i = start;
01780 while (i < real->len)
01781 {
01782 if (real->str[i] == ' ' ||
01783 real->str[i] == '\t')
01784 {
01785 if (found)
01786 *found = i;
01787 return TRUE;
01788 }
01789
01790 ++i;
01791 }
01792
01793 if (found)
01794 *found = real->len;
01795
01796 return FALSE;
01797 }
01798
01807 void
01808 _dbus_string_skip_blank (const DBusString *str,
01809 int start,
01810 int *end)
01811 {
01812 int i;
01813 DBUS_CONST_STRING_PREAMBLE (str);
01814 _dbus_assert (start <= real->len);
01815 _dbus_assert (start >= 0);
01816
01817 i = start;
01818 while (i < real->len)
01819 {
01820 if (!DBUS_IS_ASCII_BLANK (real->str[i]))
01821 break;
01822
01823 ++i;
01824 }
01825
01826 _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
01827
01828 if (end)
01829 *end = i;
01830 }
01831
01832
01841 void
01842 _dbus_string_skip_white (const DBusString *str,
01843 int start,
01844 int *end)
01845 {
01846 int i;
01847 DBUS_CONST_STRING_PREAMBLE (str);
01848 _dbus_assert (start <= real->len);
01849 _dbus_assert (start >= 0);
01850
01851 i = start;
01852 while (i < real->len)
01853 {
01854 if (!DBUS_IS_ASCII_WHITE (real->str[i]))
01855 break;
01856
01857 ++i;
01858 }
01859
01860 _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
01861
01862 if (end)
01863 *end = i;
01864 }
01865
01874 void
01875 _dbus_string_skip_white_reverse (const DBusString *str,
01876 int end,
01877 int *start)
01878 {
01879 int i;
01880 DBUS_CONST_STRING_PREAMBLE (str);
01881 _dbus_assert (end <= real->len);
01882 _dbus_assert (end >= 0);
01883
01884 i = end;
01885 while (i > 0)
01886 {
01887 if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
01888 break;
01889 --i;
01890 }
01891
01892 _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
01893
01894 if (start)
01895 *start = i;
01896 }
01897
01913 dbus_bool_t
01914 _dbus_string_pop_line (DBusString *source,
01915 DBusString *dest)
01916 {
01917 int eol, eol_len;
01918
01919 _dbus_string_set_length (dest, 0);
01920
01921 eol = 0;
01922 eol_len = 0;
01923 if (!_dbus_string_find_eol (source, 0, &eol, &eol_len))
01924 {
01925 _dbus_assert (eol == _dbus_string_get_length (source));
01926 if (eol == 0)
01927 {
01928
01929 return FALSE;
01930 }
01931
01932 }
01933
01934
01935
01936
01937
01938 if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0))
01939 return FALSE;
01940
01941
01942 if (!_dbus_string_set_length (dest, eol))
01943 {
01944 _dbus_assert_not_reached ("out of memory when shortening a string");
01945 return FALSE;
01946 }
01947
01948 return TRUE;
01949 }
01950
01951 #ifdef DBUS_BUILD_TESTS
01952
01958 void
01959 _dbus_string_delete_first_word (DBusString *str)
01960 {
01961 int i;
01962
01963 if (_dbus_string_find_blank (str, 0, &i))
01964 _dbus_string_skip_blank (str, i, &i);
01965
01966 _dbus_string_delete (str, 0, i);
01967 }
01968 #endif
01969
01970 #ifdef DBUS_BUILD_TESTS
01971
01976 void
01977 _dbus_string_delete_leading_blanks (DBusString *str)
01978 {
01979 int i;
01980
01981 _dbus_string_skip_blank (str, 0, &i);
01982
01983 if (i > 0)
01984 _dbus_string_delete (str, 0, i);
01985 }
01986 #endif
01987
01993 void
01994 _dbus_string_chop_white(DBusString *str)
01995 {
01996 int i;
01997
01998 _dbus_string_skip_white (str, 0, &i);
01999
02000 if (i > 0)
02001 _dbus_string_delete (str, 0, i);
02002
02003 _dbus_string_skip_white_reverse (str, _dbus_string_get_length (str), &i);
02004
02005 _dbus_string_set_length (str, i);
02006 }
02007
02017 dbus_bool_t
02018 _dbus_string_equal (const DBusString *a,
02019 const DBusString *b)
02020 {
02021 const unsigned char *ap;
02022 const unsigned char *bp;
02023 const unsigned char *a_end;
02024 const DBusRealString *real_a = (const DBusRealString*) a;
02025 const DBusRealString *real_b = (const DBusRealString*) b;
02026 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02027 DBUS_GENERIC_STRING_PREAMBLE (real_b);
02028
02029 if (real_a->len != real_b->len)
02030 return FALSE;
02031
02032 ap = real_a->str;
02033 bp = real_b->str;
02034 a_end = real_a->str + real_a->len;
02035 while (ap != a_end)
02036 {
02037 if (*ap != *bp)
02038 return FALSE;
02039
02040 ++ap;
02041 ++bp;
02042 }
02043
02044 return TRUE;
02045 }
02046
02060 dbus_bool_t
02061 _dbus_string_equal_len (const DBusString *a,
02062 const DBusString *b,
02063 int len)
02064 {
02065 const unsigned char *ap;
02066 const unsigned char *bp;
02067 const unsigned char *a_end;
02068 const DBusRealString *real_a = (const DBusRealString*) a;
02069 const DBusRealString *real_b = (const DBusRealString*) b;
02070 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02071 DBUS_GENERIC_STRING_PREAMBLE (real_b);
02072
02073 if (real_a->len != real_b->len &&
02074 (real_a->len < len || real_b->len < len))
02075 return FALSE;
02076
02077 ap = real_a->str;
02078 bp = real_b->str;
02079 a_end = real_a->str + MIN (real_a->len, len);
02080 while (ap != a_end)
02081 {
02082 if (*ap != *bp)
02083 return FALSE;
02084
02085 ++ap;
02086 ++bp;
02087 }
02088
02089 return TRUE;
02090 }
02091
02108 dbus_bool_t
02109 _dbus_string_equal_substring (const DBusString *a,
02110 int a_start,
02111 int a_len,
02112 const DBusString *b,
02113 int b_start)
02114 {
02115 const unsigned char *ap;
02116 const unsigned char *bp;
02117 const unsigned char *a_end;
02118 const DBusRealString *real_a = (const DBusRealString*) a;
02119 const DBusRealString *real_b = (const DBusRealString*) b;
02120 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02121 DBUS_GENERIC_STRING_PREAMBLE (real_b);
02122 _dbus_assert (a_start >= 0);
02123 _dbus_assert (a_len >= 0);
02124 _dbus_assert (a_start <= real_a->len);
02125 _dbus_assert (a_len <= real_a->len - a_start);
02126 _dbus_assert (b_start >= 0);
02127 _dbus_assert (b_start <= real_b->len);
02128
02129 if (a_len > real_b->len - b_start)
02130 return FALSE;
02131
02132 ap = real_a->str + a_start;
02133 bp = real_b->str + b_start;
02134 a_end = ap + a_len;
02135 while (ap != a_end)
02136 {
02137 if (*ap != *bp)
02138 return FALSE;
02139
02140 ++ap;
02141 ++bp;
02142 }
02143
02144 _dbus_assert (bp <= (real_b->str + real_b->len));
02145
02146 return TRUE;
02147 }
02148
02156 dbus_bool_t
02157 _dbus_string_equal_c_str (const DBusString *a,
02158 const char *c_str)
02159 {
02160 const unsigned char *ap;
02161 const unsigned char *bp;
02162 const unsigned char *a_end;
02163 const DBusRealString *real_a = (const DBusRealString*) a;
02164 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02165 _dbus_assert (c_str != NULL);
02166
02167 ap = real_a->str;
02168 bp = (const unsigned char*) c_str;
02169 a_end = real_a->str + real_a->len;
02170 while (ap != a_end && *bp)
02171 {
02172 if (*ap != *bp)
02173 return FALSE;
02174
02175 ++ap;
02176 ++bp;
02177 }
02178
02179 if (ap != a_end || *bp)
02180 return FALSE;
02181
02182 return TRUE;
02183 }
02184
02192 dbus_bool_t
02193 _dbus_string_starts_with_c_str (const DBusString *a,
02194 const char *c_str)
02195 {
02196 const unsigned char *ap;
02197 const unsigned char *bp;
02198 const unsigned char *a_end;
02199 const DBusRealString *real_a = (const DBusRealString*) a;
02200 DBUS_GENERIC_STRING_PREAMBLE (real_a);
02201 _dbus_assert (c_str != NULL);
02202
02203 ap = real_a->str;
02204 bp = (const unsigned char*) c_str;
02205 a_end = real_a->str + real_a->len;
02206 while (ap != a_end && *bp)
02207 {
02208 if (*ap != *bp)
02209 return FALSE;
02210
02211 ++ap;
02212 ++bp;
02213 }
02214
02215 if (*bp == '\0')
02216 return TRUE;
02217 else
02218 return FALSE;
02219 }
02220
02229 dbus_bool_t
02230 _dbus_string_append_byte_as_hex (DBusString *str,
02231 int byte)
02232 {
02233 const char hexdigits[16] = {
02234 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
02235 'a', 'b', 'c', 'd', 'e', 'f'
02236 };
02237
02238 if (!_dbus_string_append_byte (str,
02239 hexdigits[(byte >> 4)]))
02240 return FALSE;
02241
02242 if (!_dbus_string_append_byte (str,
02243 hexdigits[(byte & 0x0f)]))
02244 {
02245 _dbus_string_set_length (str,
02246 _dbus_string_get_length (str) - 1);
02247 return FALSE;
02248 }
02249
02250 return TRUE;
02251 }
02252
02263 dbus_bool_t
02264 _dbus_string_hex_encode (const DBusString *source,
02265 int start,
02266 DBusString *dest,
02267 int insert_at)
02268 {
02269 DBusString result;
02270 const unsigned char *p;
02271 const unsigned char *end;
02272 dbus_bool_t retval;
02273
02274 _dbus_assert (start <= _dbus_string_get_length (source));
02275
02276 if (!_dbus_string_init (&result))
02277 return FALSE;
02278
02279 retval = FALSE;
02280
02281 p = (const unsigned char*) _dbus_string_get_const_data (source);
02282 end = p + _dbus_string_get_length (source);
02283 p += start;
02284
02285 while (p != end)
02286 {
02287 if (!_dbus_string_append_byte_as_hex (&result, *p))
02288 goto out;
02289
02290 ++p;
02291 }
02292
02293 if (!_dbus_string_move (&result, 0, dest, insert_at))
02294 goto out;
02295
02296 retval = TRUE;
02297
02298 out:
02299 _dbus_string_free (&result);
02300 return retval;
02301 }
02302
02313 dbus_bool_t
02314 _dbus_string_hex_decode (const DBusString *source,
02315 int start,
02316 int *end_return,
02317 DBusString *dest,
02318 int insert_at)
02319 {
02320 DBusString result;
02321 const unsigned char *p;
02322 const unsigned char *end;
02323 dbus_bool_t retval;
02324 dbus_bool_t high_bits;
02325
02326 _dbus_assert (start <= _dbus_string_get_length (source));
02327
02328 if (!_dbus_string_init (&result))
02329 return FALSE;
02330
02331 retval = FALSE;
02332
02333 high_bits = TRUE;
02334 p = (const unsigned char*) _dbus_string_get_const_data (source);
02335 end = p + _dbus_string_get_length (source);
02336 p += start;
02337
02338 while (p != end)
02339 {
02340 unsigned int val;
02341
02342 switch (*p)
02343 {
02344 case '0':
02345 val = 0;
02346 break;
02347 case '1':
02348 val = 1;
02349 break;
02350 case '2':
02351 val = 2;
02352 break;
02353 case '3':
02354 val = 3;
02355 break;
02356 case '4':
02357 val = 4;
02358 break;
02359 case '5':
02360 val = 5;
02361 break;
02362 case '6':
02363 val = 6;
02364 break;
02365 case '7':
02366 val = 7;
02367 break;
02368 case '8':
02369 val = 8;
02370 break;
02371 case '9':
02372 val = 9;
02373 break;
02374 case 'a':
02375 case 'A':
02376 val = 10;
02377 break;
02378 case 'b':
02379 case 'B':
02380 val = 11;
02381 break;
02382 case 'c':
02383 case 'C':
02384 val = 12;
02385 break;
02386 case 'd':
02387 case 'D':
02388 val = 13;
02389 break;
02390 case 'e':
02391 case 'E':
02392 val = 14;
02393 break;
02394 case 'f':
02395 case 'F':
02396 val = 15;
02397 break;
02398 default:
02399 goto done;
02400 }
02401
02402 if (high_bits)
02403 {
02404 if (!_dbus_string_append_byte (&result,
02405 val << 4))
02406 goto out;
02407 }
02408 else
02409 {
02410 int len;
02411 unsigned char b;
02412
02413 len = _dbus_string_get_length (&result);
02414
02415 b = _dbus_string_get_byte (&result, len - 1);
02416
02417 b |= val;
02418
02419 _dbus_string_set_byte (&result, len - 1, b);
02420 }
02421
02422 high_bits = !high_bits;
02423
02424 ++p;
02425 }
02426
02427 done:
02428 if (!_dbus_string_move (&result, 0, dest, insert_at))
02429 goto out;
02430
02431 if (end_return)
02432 *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
02433
02434 retval = TRUE;
02435
02436 out:
02437 _dbus_string_free (&result);
02438 return retval;
02439 }
02440
02454 dbus_bool_t
02455 _dbus_string_validate_ascii (const DBusString *str,
02456 int start,
02457 int len)
02458 {
02459 const unsigned char *s;
02460 const unsigned char *end;
02461 DBUS_CONST_STRING_PREAMBLE (str);
02462 _dbus_assert (start >= 0);
02463 _dbus_assert (start <= real->len);
02464 _dbus_assert (len >= 0);
02465
02466 if (len > real->len - start)
02467 return FALSE;
02468
02469 s = real->str + start;
02470 end = s + len;
02471 while (s != end)
02472 {
02473 if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
02474 return FALSE;
02475
02476 ++s;
02477 }
02478
02479 return TRUE;
02480 }
02481
02489 void
02490 _dbus_string_tolower_ascii (const DBusString *str,
02491 int start,
02492 int len)
02493 {
02494 unsigned char *s;
02495 unsigned char *end;
02496 DBUS_STRING_PREAMBLE (str);
02497 _dbus_assert (start >= 0);
02498 _dbus_assert (start <= real->len);
02499 _dbus_assert (len >= 0);
02500 _dbus_assert (len <= real->len - start);
02501
02502 s = real->str + start;
02503 end = s + len;
02504
02505 while (s != end)
02506 {
02507 if (*s >= 'A' && *s <= 'Z')
02508 *s += 'a' - 'A';
02509 ++s;
02510 }
02511 }
02512
02520 void
02521 _dbus_string_toupper_ascii (const DBusString *str,
02522 int start,
02523 int len)
02524 {
02525 unsigned char *s;
02526 unsigned char *end;
02527 DBUS_STRING_PREAMBLE (str);
02528 _dbus_assert (start >= 0);
02529 _dbus_assert (start <= real->len);
02530 _dbus_assert (len >= 0);
02531 _dbus_assert (len <= real->len - start);
02532
02533 s = real->str + start;
02534 end = s + len;
02535
02536 while (s != end)
02537 {
02538 if (*s >= 'a' && *s <= 'z')
02539 *s += 'A' - 'a';
02540 ++s;
02541 }
02542 }
02543
02559 dbus_bool_t
02560 _dbus_string_validate_utf8 (const DBusString *str,
02561 int start,
02562 int len)
02563 {
02564 const unsigned char *p;
02565 const unsigned char *end;
02566 DBUS_CONST_STRING_PREAMBLE (str);
02567 _dbus_assert (start >= 0);
02568 _dbus_assert (start <= real->len);
02569 _dbus_assert (len >= 0);
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579 if (_DBUS_UNLIKELY (len > real->len - start))
02580 return FALSE;
02581
02582 p = real->str + start;
02583 end = p + len;
02584
02585 while (p < end)
02586 {
02587 int i, mask, char_len;
02588 dbus_unichar_t result;
02589
02590
02591 if (*p == '\0')
02592 break;
02593
02594
02595
02596
02597
02598
02599
02600 if (*p < 128)
02601 {
02602 ++p;
02603 continue;
02604 }
02605
02606 UTF8_COMPUTE (*p, mask, char_len);
02607
02608 if (_DBUS_UNLIKELY (char_len == 0))
02609 break;
02610
02611
02612 if (_DBUS_UNLIKELY ((end - p) < char_len))
02613 break;
02614
02615 UTF8_GET (result, p, i, mask, char_len);
02616
02617
02618 if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len))
02619 break;
02620 #if 0
02621
02622 if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1))
02623 break;
02624 #endif
02625
02626 if (_DBUS_UNLIKELY (!UNICODE_VALID (result)))
02627 break;
02628
02629
02630 _dbus_assert (result != (dbus_unichar_t)-1);
02631
02632 p += char_len;
02633 }
02634
02635
02636
02637
02638 if (_DBUS_UNLIKELY (p != end))
02639 return FALSE;
02640 else
02641 return TRUE;
02642 }
02643
02657 dbus_bool_t
02658 _dbus_string_validate_nul (const DBusString *str,
02659 int start,
02660 int len)
02661 {
02662 const unsigned char *s;
02663 const unsigned char *end;
02664 DBUS_CONST_STRING_PREAMBLE (str);
02665 _dbus_assert (start >= 0);
02666 _dbus_assert (len >= 0);
02667 _dbus_assert (start <= real->len);
02668
02669 if (len > real->len - start)
02670 return FALSE;
02671
02672 s = real->str + start;
02673 end = s + len;
02674 while (s != end)
02675 {
02676 if (_DBUS_UNLIKELY (*s != '\0'))
02677 return FALSE;
02678 ++s;
02679 }
02680
02681 return TRUE;
02682 }
02683
02689 void
02690 _dbus_string_zero (DBusString *str)
02691 {
02692 DBUS_STRING_PREAMBLE (str);
02693
02694 memset (real->str - real->align_offset, '\0', real->allocated);
02695 }
02698