D-Bus: dbus-string.c Source File

D-Bus 1.8.16

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List

dbus-string.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-string.c String utility class (internal to D-Bus implementation)
3 *
4 * Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
5 * Copyright (C) 2006 Ralf Habacker <ralf.habacker@freenet.de>
6 *
7 * Licensed under the Academic Free License version 2.1
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 */
24
25 #include <config.h>
26 #include "dbus-internals.h"
27 #include "dbus-string.h"
28 /* we allow a system header here, for speed/convenience */
29 #include <string.h>
30 /* for vsnprintf */
31 #include <stdio.h>
32 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
33 #include "dbus-string-private.h"
34 #include "dbus-marshal-basic.h" /* probably should be removed by moving the usage of DBUS_TYPE
35 * into the marshaling-related files
36 */
37 /* for DBUS_VA_COPY */
38 #include "dbus-sysdeps.h"
39
78 static void
79 fixup_alignment (DBusRealString *real)
80 {
81 unsigned char *aligned;
82 unsigned char *real_block;
83 unsigned int old_align_offset;
84
85 /* we have to have extra space in real->allocated for the align offset and nul byte */
86 _dbus_assert (real->len <= real->allocated - _DBUS_STRING_ALLOCATION_PADDING);
87
88 old_align_offset = real->align_offset;
89 real_block = real->str - old_align_offset;
90
91 aligned = _DBUS_ALIGN_ADDRESS (real_block, 8);
92
93 real->align_offset = aligned - real_block;
94 real->str = aligned;
95
96 if (old_align_offset != real->align_offset)
97 {
98 /* Here comes the suck */
99 memmove (real_block + real->align_offset,
100 real_block + old_align_offset,
101 real->len + 1);
102 }
103
104 _dbus_assert (real->align_offset < 8);
105 _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str);
106 }
107
108 static void
109 undo_alignment (DBusRealString *real)
110 {
111 if (real->align_offset != 0)
112 {
113 memmove (real->str - real->align_offset,
114 real->str,
115 real->len + 1);
116
117 real->str = real->str - real->align_offset;
118 real->align_offset = 0;
119 }
120 }
121
131 dbus_bool_t
132 _dbus_string_init_preallocated (DBusString *str,
133 int allocate_size)
134 {
135 DBusRealString *real;
136
137 _dbus_assert (str != NULL);
138
139 _dbus_assert (sizeof (DBusString) == sizeof (DBusRealString));
140
141 real = (DBusRealString*) str;
142
143 /* It's very important not to touch anything
144 * other than real->str if we're going to fail,
145 * since we also use this function to reset
146 * an existing string, e.g. in _dbus_string_steal_data()
147 */
148
149 real->str = dbus_malloc (_DBUS_STRING_ALLOCATION_PADDING + allocate_size);
150 if (real->str == NULL)
151 return FALSE;
152
153 real->allocated = _DBUS_STRING_ALLOCATION_PADDING + allocate_size;
154 real->len = 0;
155 real->str[real->len] = '\0';
156
157 real->constant = FALSE;
158 real->locked = FALSE;
159 real->invalid = FALSE;
160 real->align_offset = 0;
161
162 fixup_alignment (real);
163
164 return TRUE;
165 }
166
174 dbus_bool_t
175 _dbus_string_init (DBusString *str)
176 {
177 return _dbus_string_init_preallocated (str, 0);
178 }
179
189 void
190 _dbus_string_init_const (DBusString *str,
191 const char *value)
192 {
193 _dbus_assert (value != NULL);
194
195 _dbus_string_init_const_len (str, value,
196 strlen (value));
197 }
198
209 void
210 _dbus_string_init_const_len (DBusString *str,
211 const char *value,
212 int len)
213 {
214 DBusRealString *real;
215
216 _dbus_assert (str != NULL);
217 _dbus_assert (len == 0 || value != NULL);
218 _dbus_assert (len <= _DBUS_STRING_MAX_LENGTH);
219 _dbus_assert (len >= 0);
220
221 real = (DBusRealString*) str;
222
223 real->str = (unsigned char*) value;
224 real->len = len;
225 real->allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING; /* a lie, just to avoid special-case assertions... */
226 real->constant = TRUE;
227 real->locked = TRUE;
228 real->invalid = FALSE;
229 real->align_offset = 0;
230
231 /* We don't require const strings to be 8-byte aligned as the
232 * memory is coming from elsewhere.
233 */
234 }
235
241 void
242 _dbus_string_free (DBusString *str)
243 {
244 DBusRealString *real = (DBusRealString*) str;
245 DBUS_GENERIC_STRING_PREAMBLE (real);
246
247 if (real->constant)
248 return;
249
250 /* so it's safe if @p str returned by a failed
251 * _dbus_string_init call
252 * Bug: https://bugs.freedesktop.org/show_bug.cgi?id=65959
253 */
254 if (real->str == NULL)
255 return;
256
257 dbus_free (real->str - real->align_offset);
258
259 real->invalid = TRUE;
260 }
261
262 static dbus_bool_t
263 compact (DBusRealString *real,
264 int max_waste)
265 {
266 unsigned char *new_str;
267 int new_allocated;
268 int waste;
269
270 waste = real->allocated - (real->len + _DBUS_STRING_ALLOCATION_PADDING);
271
272 if (waste <= max_waste)
273 return TRUE;
274
275 new_allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING;
276
277 new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
278 if (_DBUS_UNLIKELY (new_str == NULL))
279 return FALSE;
280
281 real->str = new_str + real->align_offset;
282 real->allocated = new_allocated;
283 fixup_alignment (real);
284
285 return TRUE;
286 }
287
288 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
289 /* Not using this feature at the moment,
290 * so marked DBUS_ENABLE_EMBEDDED_TESTS-only
291 */
301 void
302 _dbus_string_lock (DBusString *str)
303 {
304 DBUS_LOCKED_STRING_PREAMBLE (str); /* can lock multiple times */
305
306 real->locked = TRUE;
307
308 /* Try to realloc to avoid excess memory usage, since
309 * we know we won't change the string further
310 */
311 #define MAX_WASTE 48
312 compact (real, MAX_WASTE);
313 }
314 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */
315
316 static dbus_bool_t
317 reallocate_for_length (DBusRealString *real,
318 int new_length)
319 {
320 int new_allocated;
321 unsigned char *new_str;
322
323 /* at least double our old allocation to avoid O(n), avoiding
324 * overflow
325 */
326 if (real->allocated > (_DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2)
327 new_allocated = _DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING;
328 else
329 new_allocated = real->allocated * 2;
330
331 /* if you change the code just above here, run the tests without
332 * the following assert-only hack before you commit
333 */
334 /* This is keyed off asserts in addition to tests so when you
335 * disable asserts to profile, you don't get this destroyer
336 * of profiles.
337 */
338 #if defined (DBUS_ENABLE_EMBEDDED_TESTS) && !defined (DBUS_DISABLE_ASSERT)
339 new_allocated = 0; /* ensure a realloc every time so that we go
340 * through all malloc failure codepaths
341 */
342 #endif
343
344 /* But be sure we always alloc at least space for the new length */
345 new_allocated = MAX (new_allocated,
346 new_length + _DBUS_STRING_ALLOCATION_PADDING);
347
348 _dbus_assert (new_allocated >= real->allocated); /* code relies on this */
349 new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
350 if (_DBUS_UNLIKELY (new_str == NULL))
351 return FALSE;
352
353 real->str = new_str + real->align_offset;
354 real->allocated = new_allocated;
355 fixup_alignment (real);
356
357 return TRUE;
358 }
359
371 dbus_bool_t
372 _dbus_string_compact (DBusString *str,
373 int max_waste)
374 {
375 DBUS_STRING_PREAMBLE (str);
376
377 return compact (real, max_waste);
378 }
379
380 static dbus_bool_t
381 set_length (DBusRealString *real,
382 int new_length)
383 {
384 /* Note, we are setting the length not including nul termination */
385
386 /* exceeding max length is the same as failure to allocate memory */
387 if (_DBUS_UNLIKELY (new_length > _DBUS_STRING_MAX_LENGTH))
388 return FALSE;
389 else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) &&
390 _DBUS_UNLIKELY (!reallocate_for_length (real, new_length)))
391 return FALSE;
392 else
393 {
394 real->len = new_length;
395 real->str[new_length] = '\0';
396 return TRUE;
397 }
398 }
399
400 static dbus_bool_t
401 open_gap (int len,
402 DBusRealString *dest,
403 int insert_at)
404 {
405 if (len == 0)
406 return TRUE;
407
408 if (len > _DBUS_STRING_MAX_LENGTH - dest->len)
409 return FALSE; /* detected overflow of dest->len + len below */
410
411 if (!set_length (dest, dest->len + len))
412 return FALSE;
413
414 memmove (dest->str + insert_at + len,
415 dest->str + insert_at,
416 dest->len - len - insert_at);
417
418 return TRUE;
419 }
420
421 #ifndef _dbus_string_get_data
422
433 char*
434 _dbus_string_get_data (DBusString *str)
435 {
436 DBUS_STRING_PREAMBLE (str);
437
438 return (char*) real->str;
439 }
440 #endif /* _dbus_string_get_data */
441
442 /* only do the function if we don't have the macro */
443 #ifndef _dbus_string_get_const_data
444
450 const char*
451 _dbus_string_get_const_data (const DBusString *str)
452 {
453 DBUS_CONST_STRING_PREAMBLE (str);
454
455 return (const char*) real->str;
456 }
457 #endif /* _dbus_string_get_const_data */
458
472 char*
473 _dbus_string_get_data_len (DBusString *str,
474 int start,
475 int len)
476 {
477 DBUS_STRING_PREAMBLE (str);
478 _dbus_assert (start >= 0);
479 _dbus_assert (len >= 0);
480 _dbus_assert (start <= real->len);
481 _dbus_assert (len <= real->len - start);
482
483 return (char*) real->str + start;
484 }
485
486 /* only do the function if we don't have the macro */
487 #ifndef _dbus_string_get_const_data_len
488
496 const char*
497 _dbus_string_get_const_data_len (const DBusString *str,
498 int start,
499 int len)
500 {
501 DBUS_CONST_STRING_PREAMBLE (str);
502 _dbus_assert (start >= 0);
503 _dbus_assert (len >= 0);
504 _dbus_assert (start <= real->len);
505 _dbus_assert (len <= real->len - start);
506
507 return (const char*) real->str + start;
508 }
509 #endif /* _dbus_string_get_const_data_len */
510
511 /* only do the function if we don't have the macro */
512 #ifndef _dbus_string_set_byte
513
520 void
521 _dbus_string_set_byte (DBusString *str,
522 int i,
523 unsigned char byte)
524 {
525 DBUS_STRING_PREAMBLE (str);
526 _dbus_assert (i < real->len);
527 _dbus_assert (i >= 0);
528
529 real->str[i] = byte;
530 }
531 #endif /* _dbus_string_set_byte */
532
533 /* only have the function if we didn't create a macro */
534 #ifndef _dbus_string_get_byte
535
544 unsigned char
545 _dbus_string_get_byte (const DBusString *str,
546 int start)
547 {
548 DBUS_CONST_STRING_PREAMBLE (str);
549 _dbus_assert (start <= real->len);
550 _dbus_assert (start >= 0);
551
552 return real->str[start];
553 }
554 #endif /* _dbus_string_get_byte */
555
566 dbus_bool_t
567 _dbus_string_insert_bytes (DBusString *str,
568 int i,
569 int n_bytes,
570 unsigned char byte)
571 {
572 DBUS_STRING_PREAMBLE (str);
573 _dbus_assert (i <= real->len);
574 _dbus_assert (i >= 0);
575 _dbus_assert (n_bytes >= 0);
576
577 if (n_bytes == 0)
578 return TRUE;
579
580 if (!open_gap (n_bytes, real, i))
581 return FALSE;
582
583 memset (real->str + i, byte, n_bytes);
584
585 return TRUE;
586 }
587
596 dbus_bool_t
597 _dbus_string_insert_byte (DBusString *str,
598 int i,
599 unsigned char byte)
600 {
601 DBUS_STRING_PREAMBLE (str);
602 _dbus_assert (i <= real->len);
603 _dbus_assert (i >= 0);
604
605 if (!open_gap (1, real, i))
606 return FALSE;
607
608 real->str[i] = byte;
609
610 return TRUE;
611 }
612
623 dbus_bool_t
624 _dbus_string_steal_data (DBusString *str,
625 char **data_return)
626 {
627 DBUS_STRING_PREAMBLE (str);
628 _dbus_assert (data_return != NULL);
629
630 undo_alignment (real);
631
632 *data_return = (char*) real->str;
633
634 /* reset the string */
635 if (!_dbus_string_init (str))
636 {
637 /* hrm, put it back then */
638 real->str = (unsigned char*) *data_return;
639 *data_return = NULL;
640 fixup_alignment (real);
641 return FALSE;
642 }
643
644 return TRUE;
645 }
646
654 dbus_bool_t
655 _dbus_string_copy_data (const DBusString *str,
656 char **data_return)
657 {
658 DBUS_CONST_STRING_PREAMBLE (str);
659 _dbus_assert (data_return != NULL);
660
661 *data_return = dbus_malloc (real->len + 1);
662 if (*data_return == NULL)
663 return FALSE;
664
665 memcpy (*data_return, real->str, real->len + 1);
666
667 return TRUE;
668 }
669
679 void
680 _dbus_string_copy_to_buffer (const DBusString *str,
681 char *buffer,
682 int avail_len)
683 {
684 DBUS_CONST_STRING_PREAMBLE (str);
685
686 _dbus_assert (avail_len >= 0);
687 _dbus_assert (avail_len >= real->len);
688
689 memcpy (buffer, real->str, real->len);
690 }
691
701 void
702 _dbus_string_copy_to_buffer_with_nul (const DBusString *str,
703 char *buffer,
704 int avail_len)
705 {
706 DBUS_CONST_STRING_PREAMBLE (str);
707
708 _dbus_assert (avail_len >= 0);
709 _dbus_assert (avail_len > real->len);
710
711 memcpy (buffer, real->str, real->len+1);
712 }
713
714 /* Only have the function if we don't have the macro */
715 #ifndef _dbus_string_get_length
716
721 int
722 _dbus_string_get_length (const DBusString *str)
723 {
724 DBUS_CONST_STRING_PREAMBLE (str);
725
726 return real->len;
727 }
728 #endif /* !_dbus_string_get_length */
729
742 dbus_bool_t
743 _dbus_string_lengthen (DBusString *str,
744 int additional_length)
745 {
746 DBUS_STRING_PREAMBLE (str);
747 _dbus_assert (additional_length >= 0);
748
749 if (_DBUS_UNLIKELY (additional_length > _DBUS_STRING_MAX_LENGTH - real->len))
750 return FALSE; /* would overflow */
751
752 return set_length (real,
753 real->len + additional_length);
754 }
755
762 void
763 _dbus_string_shorten (DBusString *str,
764 int length_to_remove)
765 {
766 DBUS_STRING_PREAMBLE (str);
767 _dbus_assert (length_to_remove >= 0);
768 _dbus_assert (length_to_remove <= real->len);
769
770 set_length (real,
771 real->len - length_to_remove);
772 }
773
784 dbus_bool_t
785 _dbus_string_set_length (DBusString *str,
786 int length)
787 {
788 DBUS_STRING_PREAMBLE (str);
789 _dbus_assert (length >= 0);
790
791 return set_length (real, length);
792 }
793
794 static dbus_bool_t
795 align_insert_point_then_open_gap (DBusString *str,
796 int *insert_at_p,
797 int alignment,
798 int gap_size)
799 {
800 unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */
801 unsigned long gap_pos;
802 int insert_at;
803 int delta;
804 DBUS_STRING_PREAMBLE (str);
805 _dbus_assert (alignment >= 1);
806 _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
807
808 insert_at = *insert_at_p;
809
810 _dbus_assert (insert_at <= real->len);
811
812 gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
813 new_len = real->len + (gap_pos - insert_at) + gap_size;
814
815 if (_DBUS_UNLIKELY (new_len > (unsigned long) _DBUS_STRING_MAX_LENGTH))
816 return FALSE;
817
818 delta = new_len - real->len;
819 _dbus_assert (delta >= 0);
820
821 if (delta == 0) /* only happens if gap_size == 0 and insert_at is aligned already */
822 {
823 _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
824 return TRUE;
825 }
826
827 if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
828 real, insert_at)))
829 return FALSE;
830
831 /* nul the padding if we had to add any padding */
832 if (gap_size < delta)
833 {
834 memset (&real->str[insert_at], '\0',
835 gap_pos - insert_at);
836 }
837
838 *insert_at_p = gap_pos;
839
840 return TRUE;
841 }
842
843 static dbus_bool_t
844 align_length_then_lengthen (DBusString *str,
845 int alignment,
846 int then_lengthen_by)
847 {
848 int insert_at;
849
850 insert_at = _dbus_string_get_length (str);
851
852 return align_insert_point_then_open_gap (str,
853 &insert_at,
854 alignment, then_lengthen_by);
855 }
856
865 dbus_bool_t
866 _dbus_string_align_length (DBusString *str,
867 int alignment)
868 {
869 return align_length_then_lengthen (str, alignment, 0);
870 }
871
881 dbus_bool_t
882 _dbus_string_alloc_space (DBusString *str,
883 int extra_bytes)
884 {
885 if (!_dbus_string_lengthen (str, extra_bytes))
886 return FALSE;
887 _dbus_string_shorten (str, extra_bytes);
888
889 return TRUE;
890 }
891
892 static dbus_bool_t
893 append (DBusRealString *real,
894 const char *buffer,
895 int buffer_len)
896 {
897 if (buffer_len == 0)
898 return TRUE;
899
900 if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
901 return FALSE;
902
903 memcpy (real->str + (real->len - buffer_len),
904 buffer,
905 buffer_len);
906
907 return TRUE;
908 }
909
917 dbus_bool_t
918 _dbus_string_append (DBusString *str,
919 const char *buffer)
920 {
921 unsigned long buffer_len;
922
923 DBUS_STRING_PREAMBLE (str);
924 _dbus_assert (buffer != NULL);
925
926 buffer_len = strlen (buffer);
927 if (buffer_len > (unsigned long) _DBUS_STRING_MAX_LENGTH)
928 return FALSE;
929
930 return append (real, buffer, buffer_len);
931 }
932
934 #define ASSIGN_2_OCTETS(p, octets) \
935 *((dbus_uint16_t*)(p)) = *((dbus_uint16_t*)(octets));
936
938 #define ASSIGN_4_OCTETS(p, octets) \
939 *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
940
942 #define ASSIGN_8_OCTETS(p, octets) \
943 *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
944
954 dbus_bool_t
955 _dbus_string_insert_2_aligned (DBusString *str,
956 int insert_at,
957 const unsigned char octets[2])
958 {
959 DBUS_STRING_PREAMBLE (str);
960
961 if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2))
962 return FALSE;
963
964 ASSIGN_2_OCTETS (real->str + insert_at, octets);
965
966 return TRUE;
967 }
968
978 dbus_bool_t
979 _dbus_string_insert_4_aligned (DBusString *str,
980 int insert_at,
981 const unsigned char octets[4])
982 {
983 DBUS_STRING_PREAMBLE (str);
984
985 if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
986 return FALSE;
987
988 ASSIGN_4_OCTETS (real->str + insert_at, octets);
989
990 return TRUE;
991 }
992
1002 dbus_bool_t
1003 _dbus_string_insert_8_aligned (DBusString *str,
1004 int insert_at,
1005 const unsigned char octets[8])
1006 {
1007 DBUS_STRING_PREAMBLE (str);
1008
1009 if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
1010 return FALSE;
1011
1012 _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
1013
1014 ASSIGN_8_OCTETS (real->str + insert_at, octets);
1015
1016 return TRUE;
1017 }
1018
1019
1030 dbus_bool_t
1031 _dbus_string_insert_alignment (DBusString *str,
1032 int *insert_at,
1033 int alignment)
1034 {
1035 DBUS_STRING_PREAMBLE (str);
1036
1037 if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0))
1038 return FALSE;
1039
1040 _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at);
1041
1042 return TRUE;
1043 }
1044
1054 dbus_bool_t
1055 _dbus_string_append_printf_valist (DBusString *str,
1056 const char *format,
1057 va_list args)
1058 {
1059 int len;
1060 va_list args_copy;
1061
1062 DBUS_STRING_PREAMBLE (str);
1063
1064 DBUS_VA_COPY (args_copy, args);
1065
1066 /* Measure the message length without terminating nul */
1067 len = _dbus_printf_string_upper_bound (format, args);
1068
1069 if (len < 0)
1070 return FALSE;
1071
1072 if (!_dbus_string_lengthen (str, len))
1073 {
1074 /* don't leak the copy */
1075 va_end (args_copy);
1076 return FALSE;
1077 }
1078
1079 vsprintf ((char*) (real->str + (real->len - len)),
1080 format, args_copy);
1081
1082 va_end (args_copy);
1083
1084 return TRUE;
1085 }
1086
1095 dbus_bool_t
1096 _dbus_string_append_printf (DBusString *str,
1097 const char *format,
1098 ...)
1099 {
1100 va_list args;
1101 dbus_bool_t retval;
1102
1103 va_start (args, format);
1104 retval = _dbus_string_append_printf_valist (str, format, args);
1105 va_end (args);
1106
1107 return retval;
1108 }
1109
1118 dbus_bool_t
1119 _dbus_string_append_len (DBusString *str,
1120 const char *buffer,
1121 int len)
1122 {
1123 DBUS_STRING_PREAMBLE (str);
1124 _dbus_assert (buffer != NULL);
1125 _dbus_assert (len >= 0);
1126
1127 return append (real, buffer, len);
1128 }
1129
1138 dbus_bool_t
1139 _dbus_string_append_byte (DBusString *str,
1140 unsigned char byte)
1141 {
1142 DBUS_STRING_PREAMBLE (str);
1143
1144 if (!set_length (real, real->len + 1))
1145 return FALSE;
1146
1147 real->str[real->len-1] = byte;
1148
1149 return TRUE;
1150 }
1151
1152 static void
1153 delete (DBusRealString *real,
1154 int start,
1155 int len)
1156 {
1157 if (len == 0)
1158 return;
1159
1160 memmove (real->str + start, real->str + start + len, real->len - (start + len));
1161 real->len -= len;
1162 real->str[real->len] = '\0';
1163 }
1164
1174 void
1175 _dbus_string_delete (DBusString *str,
1176 int start,
1177 int len)
1178 {
1179 DBUS_STRING_PREAMBLE (str);
1180 _dbus_assert (start >= 0);
1181 _dbus_assert (len >= 0);
1182 _dbus_assert (start <= real->len);
1183 _dbus_assert (len <= real->len - start);
1184
1185 delete (real, start, len);
1186 }
1187
1188 static dbus_bool_t
1189 copy (DBusRealString *source,
1190 int start,
1191 int len,
1192 DBusRealString *dest,
1193 int insert_at)
1194 {
1195 if (len == 0)
1196 return TRUE;
1197
1198 if (!open_gap (len, dest, insert_at))
1199 return FALSE;
1200
1201 memmove (dest->str + insert_at,
1202 source->str + start,
1203 len);
1204
1205 return TRUE;
1206 }
1207
1217 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at) \
1218 DBusRealString *real_source = (DBusRealString*) source; \
1219 DBusRealString *real_dest = (DBusRealString*) dest; \
1220 _dbus_assert ((source) != (dest)); \
1221 DBUS_GENERIC_STRING_PREAMBLE (real_source); \
1222 DBUS_GENERIC_STRING_PREAMBLE (real_dest); \
1223 _dbus_assert (!real_dest->constant); \
1224 _dbus_assert (!real_dest->locked); \
1225 _dbus_assert ((start) >= 0); \
1226 _dbus_assert ((start) <= real_source->len); \
1227 _dbus_assert ((insert_at) >= 0); \
1228 _dbus_assert ((insert_at) <= real_dest->len)
1229
1240 dbus_bool_t
1241 _dbus_string_move (DBusString *source,
1242 int start,
1243 DBusString *dest,
1244 int insert_at)
1245 {
1246 DBusRealString *real_source = (DBusRealString*) source;
1247 _dbus_assert (start <= real_source->len);
1248
1249 return _dbus_string_move_len (source, start,
1250 real_source->len - start,
1251 dest, insert_at);
1252 }
1253
1264 dbus_bool_t
1265 _dbus_string_copy (const DBusString *source,
1266 int start,
1267 DBusString *dest,
1268 int insert_at)
1269 {
1270 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1271
1272 return copy (real_source, start,
1273 real_source->len - start,
1274 real_dest,
1275 insert_at);
1276 }
1277
1289 dbus_bool_t
1290 _dbus_string_move_len (DBusString *source,
1291 int start,
1292 int len,
1293 DBusString *dest,
1294 int insert_at)
1295
1296 {
1297 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1298 _dbus_assert (len >= 0);
1299 _dbus_assert ((start + len) <= real_source->len);
1300
1301
1302 if (len == 0)
1303 {
1304 return TRUE;
1305 }
1306 else if (start == 0 &&
1307 len == real_source->len &&
1308 real_dest->len == 0)
1309 {
1310 /* Short-circuit moving an entire existing string to an empty string
1311 * by just swapping the buffers.
1312 */
1313 /* we assume ->constant doesn't matter as you can't have
1314 * a constant string involved in a move.
1315 */
1316 #define ASSIGN_DATA(a, b) do { \
1317 (a)->str = (b)->str; \
1318 (a)->len = (b)->len; \
1319 (a)->allocated = (b)->allocated; \
1320 (a)->align_offset = (b)->align_offset; \
1321 } while (0)
1322
1323 DBusRealString tmp;
1324
1325 ASSIGN_DATA (&tmp, real_source);
1326 ASSIGN_DATA (real_source, real_dest);
1327 ASSIGN_DATA (real_dest, &tmp);
1328
1329 return TRUE;
1330 }
1331 else
1332 {
1333 if (!copy (real_source, start, len,
1334 real_dest,
1335 insert_at))
1336 return FALSE;
1337
1338 delete (real_source, start,
1339 len);
1340
1341 return TRUE;
1342 }
1343 }
1344
1356 dbus_bool_t
1357 _dbus_string_copy_len (const DBusString *source,
1358 int start,
1359 int len,
1360 DBusString *dest,
1361 int insert_at)
1362 {
1363 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1364 _dbus_assert (len >= 0);
1365 _dbus_assert (start <= real_source->len);
1366 _dbus_assert (len <= real_source->len - start);
1367
1368 return copy (real_source, start, len,
1369 real_dest,
1370 insert_at);
1371 }
1372
1385 dbus_bool_t
1386 _dbus_string_replace_len (const DBusString *source,
1387 int start,
1388 int len,
1389 DBusString *dest,
1390 int replace_at,
1391 int replace_len)
1392 {
1393 DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
1394 _dbus_assert (len >= 0);
1395 _dbus_assert (start <= real_source->len);
1396 _dbus_assert (len <= real_source->len - start);
1397 _dbus_assert (replace_at >= 0);
1398 _dbus_assert (replace_at <= real_dest->len);
1399 _dbus_assert (replace_len <= real_dest->len - replace_at);
1400
1401 if (len == replace_len)
1402 {
1403 memmove (real_dest->str + replace_at,
1404 real_source->str + start, len);
1405 }
1406 else if (len < replace_len)
1407 {
1408 memmove (real_dest->str + replace_at,
1409 real_source->str + start, len);
1410 delete (real_dest, replace_at + len,
1411 replace_len - len);
1412 }
1413 else
1414 {
1415 int diff;
1416
1417 _dbus_assert (len > replace_len);
1418
1419 diff = len - replace_len;
1420
1421 /* First of all we check if destination string can be enlarged as
1422 * required, then we overwrite previous bytes
1423 */
1424
1425 if (!copy (real_source, start + replace_len, diff,
1426 real_dest, replace_at + replace_len))
1427 return FALSE;
1428
1429 memmove (real_dest->str + replace_at,
1430 real_source->str + start, replace_len);
1431 }
1432
1433 return TRUE;
1434 }
1435
1448 dbus_bool_t
1449 _dbus_string_split_on_byte (DBusString *source,
1450 unsigned char byte,
1451 DBusString *tail)
1452 {
1453 int byte_position;
1454 char byte_string[2] = "";
1455 int head_length;
1456 int tail_length;
1457
1458 byte_string[0] = (char) byte;
1459
1460 if (!_dbus_string_find (source, 0, byte_string, &byte_position))
1461 return FALSE;
1462
1463 head_length = byte_position;
1464 tail_length = _dbus_string_get_length (source) - head_length - 1;
1465
1466 if (!_dbus_string_move_len (source, byte_position + 1, tail_length,
1467 tail, 0))
1468 return FALSE;
1469
1470 /* remove the trailing delimiter byte from the head now.
1471 */
1472 if (!_dbus_string_set_length (source, head_length))
1473 return FALSE;
1474
1475 return TRUE;
1476 }
1477
1478 /* Unicode macros and utf8_validate() from GLib Owen Taylor, Havoc
1479 * Pennington, and Tom Tromey are the authors and authorized relicense.
1480 */
1481
1487 #define UTF8_COMPUTE(Char, Mask, Len) \
1488 if (Char < 128) \
1489 { \
1490 Len = 1; \
1491 Mask = 0x7f; \
1492 } \
1493 else if ((Char & 0xe0) == 0xc0) \
1494 { \
1495 Len = 2; \
1496 Mask = 0x1f; \
1497 } \
1498 else if ((Char & 0xf0) == 0xe0) \
1499 { \
1500 Len = 3; \
1501 Mask = 0x0f; \
1502 } \
1503 else if ((Char & 0xf8) == 0xf0) \
1504 { \
1505 Len = 4; \
1506 Mask = 0x07; \
1507 } \
1508 else if ((Char & 0xfc) == 0xf8) \
1509 { \
1510 Len = 5; \
1511 Mask = 0x03; \
1512 } \
1513 else if ((Char & 0xfe) == 0xfc) \
1514 { \
1515 Len = 6; \
1516 Mask = 0x01; \
1517 } \
1518 else \
1519 { \
1520 Len = 0; \
1521 Mask = 0; \
1522 }
1523
1528 #define UTF8_LENGTH(Char) \
1529 ((Char) < 0x80 ? 1 : \
1530 ((Char) < 0x800 ? 2 : \
1531 ((Char) < 0x10000 ? 3 : \
1532 ((Char) < 0x200000 ? 4 : \
1533 ((Char) < 0x4000000 ? 5 : 6)))))
1534
1544 #define UTF8_GET(Result, Chars, Count, Mask, Len) \
1545 (Result) = (Chars)[0] & (Mask); \
1546 for ((Count) = 1; (Count) < (Len); ++(Count)) \
1547 { \
1548 if (((Chars)[(Count)] & 0xc0) != 0x80) \
1549 { \
1550 (Result) = -1; \
1551 break; \
1552 } \
1553 (Result) <<= 6; \
1554 (Result) |= ((Chars)[(Count)] & 0x3f); \
1555 }
1556
1567 #define UNICODE_VALID(Char) \
1568 ((Char) < 0x110000 && \
1569 (((Char) & 0xFFFFF800) != 0xD800))
1570
1585 dbus_bool_t
1586 _dbus_string_find (const DBusString *str,
1587 int start,
1588 const char *substr,
1589 int *found)
1590 {
1591 return _dbus_string_find_to (str, start,
1592 ((const DBusRealString*)str)->len,
1593 substr, found);
1594 }
1595
1608 dbus_bool_t
1609 _dbus_string_find_eol (const DBusString *str,
1610 int start,
1611 int *found,
1612 int *found_len)
1613 {
1614 int i;
1615
1616 DBUS_CONST_STRING_PREAMBLE (str);
1617 _dbus_assert (start <= real->len);
1618 _dbus_assert (start >= 0);
1619
1620 i = start;
1621 while (i < real->len)
1622 {
1623 if (real->str[i] == '\r')
1624 {
1625 if ((i+1) < real->len && real->str[i+1] == '\n') /* "\r\n" */
1626 {
1627 if (found)
1628 *found = i;
1629 if (found_len)
1630 *found_len = 2;
1631 return TRUE;
1632 }
1633 else /* only "\r" */
1634 {
1635 if (found)
1636 *found = i;
1637 if (found_len)
1638 *found_len = 1;
1639 return TRUE;
1640 }
1641 }
1642 else if (real->str[i] == '\n') /* only "\n" */
1643 {
1644 if (found)
1645 *found = i;
1646 if (found_len)
1647 *found_len = 1;
1648 return TRUE;
1649 }
1650 ++i;
1651 }
1652
1653 if (found)
1654 *found = real->len;
1655
1656 if (found_len)
1657 *found_len = 0;
1658
1659 return FALSE;
1660 }
1661
1678 dbus_bool_t
1679 _dbus_string_find_to (const DBusString *str,
1680 int start,
1681 int end,
1682 const char *substr,
1683 int *found)
1684 {
1685 int i;
1686 DBUS_CONST_STRING_PREAMBLE (str);
1687 _dbus_assert (substr != NULL);
1688 _dbus_assert (start <= real->len);
1689 _dbus_assert (start >= 0);
1690 _dbus_assert (substr != NULL);
1691 _dbus_assert (end <= real->len);
1692 _dbus_assert (start <= end);
1693
1694 /* we always "find" an empty string */
1695 if (*substr == '\0')
1696 {
1697 if (found)
1698 *found = start;
1699 return TRUE;
1700 }
1701
1702 i = start;
1703 while (i < end)
1704 {
1705 if (real->str[i] == substr[0])
1706 {
1707 int j = i + 1;
1708
1709 while (j < end)
1710 {
1711 if (substr[j - i] == '\0')
1712 break;
1713 else if (real->str[j] != substr[j - i])
1714 break;
1715
1716 ++j;
1717 }
1718
1719 if (substr[j - i] == '\0')
1720 {
1721 if (found)
1722 *found = i;
1723 return TRUE;
1724 }
1725 }
1726
1727 ++i;
1728 }
1729
1730 if (found)
1731 *found = end;
1732
1733 return FALSE;
1734 }
1735
1746 dbus_bool_t
1747 _dbus_string_find_blank (const DBusString *str,
1748 int start,
1749 int *found)
1750 {
1751 int i;
1752 DBUS_CONST_STRING_PREAMBLE (str);
1753 _dbus_assert (start <= real->len);
1754 _dbus_assert (start >= 0);
1755
1756 i = start;
1757 while (i < real->len)
1758 {
1759 if (real->str[i] == ' ' ||
1760 real->str[i] == '\t')
1761 {
1762 if (found)
1763 *found = i;
1764 return TRUE;
1765 }
1766
1767 ++i;
1768 }
1769
1770 if (found)
1771 *found = real->len;
1772
1773 return FALSE;
1774 }
1775
1784 void
1785 _dbus_string_skip_blank (const DBusString *str,
1786 int start,
1787 int *end)
1788 {
1789 int i;
1790 DBUS_CONST_STRING_PREAMBLE (str);
1791 _dbus_assert (start <= real->len);
1792 _dbus_assert (start >= 0);
1793
1794 i = start;
1795 while (i < real->len)
1796 {
1797 if (!DBUS_IS_ASCII_BLANK (real->str[i]))
1798 break;
1799
1800 ++i;
1801 }
1802
1803 _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
1804
1805 if (end)
1806 *end = i;
1807 }
1808
1809
1818 void
1819 _dbus_string_skip_white (const DBusString *str,
1820 int start,
1821 int *end)
1822 {
1823 int i;
1824 DBUS_CONST_STRING_PREAMBLE (str);
1825 _dbus_assert (start <= real->len);
1826 _dbus_assert (start >= 0);
1827
1828 i = start;
1829 while (i < real->len)
1830 {
1831 if (!DBUS_IS_ASCII_WHITE (real->str[i]))
1832 break;
1833
1834 ++i;
1835 }
1836
1837 _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
1838
1839 if (end)
1840 *end = i;
1841 }
1842
1851 void
1852 _dbus_string_skip_white_reverse (const DBusString *str,
1853 int end,
1854 int *start)
1855 {
1856 int i;
1857 DBUS_CONST_STRING_PREAMBLE (str);
1858 _dbus_assert (end <= real->len);
1859 _dbus_assert (end >= 0);
1860
1861 i = end;
1862 while (i > 0)
1863 {
1864 if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
1865 break;
1866 --i;
1867 }
1868
1869 _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
1870
1871 if (start)
1872 *start = i;
1873 }
1874
1890 dbus_bool_t
1891 _dbus_string_pop_line (DBusString *source,
1892 DBusString *dest)
1893 {
1894 int eol, eol_len;
1895
1896 _dbus_string_set_length (dest, 0);
1897
1898 eol = 0;
1899 eol_len = 0;
1900 if (!_dbus_string_find_eol (source, 0, &eol, &eol_len))
1901 {
1902 _dbus_assert (eol == _dbus_string_get_length (source));
1903 if (eol == 0)
1904 {
1905 /* If there's no newline and source has zero length, we're done */
1906 return FALSE;
1907 }
1908 /* otherwise, the last line of the file has no eol characters */
1909 }
1910
1911 /* remember eol can be 0 if it's an empty line, but eol_len should not be zero also
1912 * since find_eol returned TRUE
1913 */
1914
1915 if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0))
1916 return FALSE;
1917
1918 /* remove line ending */
1919 if (!_dbus_string_set_length (dest, eol))
1920 {
1921 _dbus_assert_not_reached ("out of memory when shortening a string");
1922 return FALSE;
1923 }
1924
1925 return TRUE;
1926 }
1927
1928 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1929
1935 void
1936 _dbus_string_delete_first_word (DBusString *str)
1937 {
1938 int i;
1939
1940 if (_dbus_string_find_blank (str, 0, &i))
1941 _dbus_string_skip_blank (str, i, &i);
1942
1943 _dbus_string_delete (str, 0, i);
1944 }
1945 #endif
1946
1947 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1948
1953 void
1954 _dbus_string_delete_leading_blanks (DBusString *str)
1955 {
1956 int i;
1957
1958 _dbus_string_skip_blank (str, 0, &i);
1959
1960 if (i > 0)
1961 _dbus_string_delete (str, 0, i);
1962 }
1963 #endif
1964
1970 void
1971 _dbus_string_chop_white(DBusString *str)
1972 {
1973 int i;
1974
1975 _dbus_string_skip_white (str, 0, &i);
1976
1977 if (i > 0)
1978 _dbus_string_delete (str, 0, i);
1979
1980 _dbus_string_skip_white_reverse (str, _dbus_string_get_length (str), &i);
1981
1982 _dbus_string_set_length (str, i);
1983 }
1984
1994 dbus_bool_t
1995 _dbus_string_equal (const DBusString *a,
1996 const DBusString *b)
1997 {
1998 const unsigned char *ap;
1999 const unsigned char *bp;
2000 const unsigned char *a_end;
2001 const DBusRealString *real_a = (const DBusRealString*) a;
2002 const DBusRealString *real_b = (const DBusRealString*) b;
2003 DBUS_GENERIC_STRING_PREAMBLE (real_a);
2004 DBUS_GENERIC_STRING_PREAMBLE (real_b);
2005
2006 if (real_a->len != real_b->len)
2007 return FALSE;
2008
2009 ap = real_a->str;
2010 bp = real_b->str;
2011 a_end = real_a->str + real_a->len;
2012 while (ap != a_end)
2013 {
2014 if (*ap != *bp)
2015 return FALSE;
2016
2017 ++ap;
2018 ++bp;
2019 }
2020
2021 return TRUE;
2022 }
2023
2037 dbus_bool_t
2038 _dbus_string_equal_len (const DBusString *a,
2039 const DBusString *b,
2040 int len)
2041 {
2042 const unsigned char *ap;
2043 const unsigned char *bp;
2044 const unsigned char *a_end;
2045 const DBusRealString *real_a = (const DBusRealString*) a;
2046 const DBusRealString *real_b = (const DBusRealString*) b;
2047 DBUS_GENERIC_STRING_PREAMBLE (real_a);
2048 DBUS_GENERIC_STRING_PREAMBLE (real_b);
2049
2050 if (real_a->len != real_b->len &&
2051 (real_a->len < len || real_b->len < len))
2052 return FALSE;
2053
2054 ap = real_a->str;
2055 bp = real_b->str;
2056 a_end = real_a->str + MIN (real_a->len, len);
2057 while (ap != a_end)
2058 {
2059 if (*ap != *bp)
2060 return FALSE;
2061
2062 ++ap;
2063 ++bp;
2064 }
2065
2066 return TRUE;
2067 }
2068
2085 dbus_bool_t
2086 _dbus_string_equal_substring (const DBusString *a,
2087 int a_start,
2088 int a_len,
2089 const DBusString *b,
2090 int b_start)
2091 {
2092 const unsigned char *ap;
2093 const unsigned char *bp;
2094 const unsigned char *a_end;
2095 const DBusRealString *real_a = (const DBusRealString*) a;
2096 const DBusRealString *real_b = (const DBusRealString*) b;
2097 DBUS_GENERIC_STRING_PREAMBLE (real_a);
2098 DBUS_GENERIC_STRING_PREAMBLE (real_b);
2099 _dbus_assert (a_start >= 0);
2100 _dbus_assert (a_len >= 0);
2101 _dbus_assert (a_start <= real_a->len);
2102 _dbus_assert (a_len <= real_a->len - a_start);
2103 _dbus_assert (b_start >= 0);
2104 _dbus_assert (b_start <= real_b->len);
2105
2106 if (a_len > real_b->len - b_start)
2107 return FALSE;
2108
2109 ap = real_a->str + a_start;
2110 bp = real_b->str + b_start;
2111 a_end = ap + a_len;
2112 while (ap != a_end)
2113 {
2114 if (*ap != *bp)
2115 return FALSE;
2116
2117 ++ap;
2118 ++bp;
2119 }
2120
2121 _dbus_assert (bp <= (real_b->str + real_b->len));
2122
2123 return TRUE;
2124 }
2125
2133 dbus_bool_t
2134 _dbus_string_equal_c_str (const DBusString *a,
2135 const char *c_str)
2136 {
2137 const unsigned char *ap;
2138 const unsigned char *bp;
2139 const unsigned char *a_end;
2140 const DBusRealString *real_a = (const DBusRealString*) a;
2141 DBUS_GENERIC_STRING_PREAMBLE (real_a);
2142 _dbus_assert (c_str != NULL);
2143
2144 ap = real_a->str;
2145 bp = (const unsigned char*) c_str;
2146 a_end = real_a->str + real_a->len;
2147 while (ap != a_end && *bp)
2148 {
2149 if (*ap != *bp)
2150 return FALSE;
2151
2152 ++ap;
2153 ++bp;
2154 }
2155
2156 if (ap != a_end || *bp)
2157 return FALSE;
2158
2159 return TRUE;
2160 }
2161
2169 dbus_bool_t
2170 _dbus_string_starts_with_c_str (const DBusString *a,
2171 const char *c_str)
2172 {
2173 const unsigned char *ap;
2174 const unsigned char *bp;
2175 const unsigned char *a_end;
2176 const DBusRealString *real_a = (const DBusRealString*) a;
2177 DBUS_GENERIC_STRING_PREAMBLE (real_a);
2178 _dbus_assert (c_str != NULL);
2179
2180 ap = real_a->str;
2181 bp = (const unsigned char*) c_str;
2182 a_end = real_a->str + real_a->len;
2183 while (ap != a_end && *bp)
2184 {
2185 if (*ap != *bp)
2186 return FALSE;
2187
2188 ++ap;
2189 ++bp;
2190 }
2191
2192 if (*bp == '\0')
2193 return TRUE;
2194 else
2195 return FALSE;
2196 }
2197
2206 dbus_bool_t
2207 _dbus_string_append_byte_as_hex (DBusString *str,
2208 unsigned char byte)
2209 {
2210 const char hexdigits[16] = {
2211 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
2212 'a', 'b', 'c', 'd', 'e', 'f'
2213 };
2214
2215 if (!_dbus_string_append_byte (str,
2216 hexdigits[(byte >> 4)]))
2217 return FALSE;
2218
2219 if (!_dbus_string_append_byte (str,
2220 hexdigits[(byte & 0x0f)]))
2221 {
2222 _dbus_string_set_length (str,
2223 _dbus_string_get_length (str) - 1);
2224 return FALSE;
2225 }
2226
2227 return TRUE;
2228 }
2229
2240 dbus_bool_t
2241 _dbus_string_hex_encode (const DBusString *source,
2242 int start,
2243 DBusString *dest,
2244 int insert_at)
2245 {
2246 DBusString result;
2247 const unsigned char *p;
2248 const unsigned char *end;
2249 dbus_bool_t retval;
2250
2251 _dbus_assert (start <= _dbus_string_get_length (source));
2252
2253 if (!_dbus_string_init (&result))
2254 return FALSE;
2255
2256 retval = FALSE;
2257
2258 p = (const unsigned char*) _dbus_string_get_const_data (source);
2259 end = p + _dbus_string_get_length (source);
2260 p += start;
2261
2262 while (p != end)
2263 {
2264 if (!_dbus_string_append_byte_as_hex (&result, *p))
2265 goto out;
2266
2267 ++p;
2268 }
2269
2270 if (!_dbus_string_move (&result, 0, dest, insert_at))
2271 goto out;
2272
2273 retval = TRUE;
2274
2275 out:
2276 _dbus_string_free (&result);
2277 return retval;
2278 }
2279
2290 dbus_bool_t
2291 _dbus_string_hex_decode (const DBusString *source,
2292 int start,
2293 int *end_return,
2294 DBusString *dest,
2295 int insert_at)
2296 {
2297 DBusString result;
2298 const unsigned char *p;
2299 const unsigned char *end;
2300 dbus_bool_t retval;
2301 dbus_bool_t high_bits;
2302
2303 _dbus_assert (start <= _dbus_string_get_length (source));
2304
2305 if (!_dbus_string_init (&result))
2306 return FALSE;
2307
2308 retval = FALSE;
2309
2310 high_bits = TRUE;
2311 p = (const unsigned char*) _dbus_string_get_const_data (source);
2312 end = p + _dbus_string_get_length (source);
2313 p += start;
2314
2315 while (p != end)
2316 {
2317 unsigned int val;
2318
2319 switch (*p)
2320 {
2321 case '0':
2322 val = 0;
2323 break;
2324 case '1':
2325 val = 1;
2326 break;
2327 case '2':
2328 val = 2;
2329 break;
2330 case '3':
2331 val = 3;
2332 break;
2333 case '4':
2334 val = 4;
2335 break;
2336 case '5':
2337 val = 5;
2338 break;
2339 case '6':
2340 val = 6;
2341 break;
2342 case '7':
2343 val = 7;
2344 break;
2345 case '8':
2346 val = 8;
2347 break;
2348 case '9':
2349 val = 9;
2350 break;
2351 case 'a':
2352 case 'A':
2353 val = 10;
2354 break;
2355 case 'b':
2356 case 'B':
2357 val = 11;
2358 break;
2359 case 'c':
2360 case 'C':
2361 val = 12;
2362 break;
2363 case 'd':
2364 case 'D':
2365 val = 13;
2366 break;
2367 case 'e':
2368 case 'E':
2369 val = 14;
2370 break;
2371 case 'f':
2372 case 'F':
2373 val = 15;
2374 break;
2375 default:
2376 goto done;
2377 }
2378
2379 if (high_bits)
2380 {
2381 if (!_dbus_string_append_byte (&result,
2382 val << 4))
2383 goto out;
2384 }
2385 else
2386 {
2387 int len;
2388 unsigned char b;
2389
2390 len = _dbus_string_get_length (&result);
2391
2392 b = _dbus_string_get_byte (&result, len - 1);
2393
2394 b |= val;
2395
2396 _dbus_string_set_byte (&result, len - 1, b);
2397 }
2398
2399 high_bits = !high_bits;
2400
2401 ++p;
2402 }
2403
2404 done:
2405 if (!_dbus_string_move (&result, 0, dest, insert_at))
2406 goto out;
2407
2408 if (end_return)
2409 *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
2410
2411 retval = TRUE;
2412
2413 out:
2414 _dbus_string_free (&result);
2415 return retval;
2416 }
2417
2431 dbus_bool_t
2432 _dbus_string_validate_ascii (const DBusString *str,
2433 int start,
2434 int len)
2435 {
2436 const unsigned char *s;
2437 const unsigned char *end;
2438 DBUS_CONST_STRING_PREAMBLE (str);
2439 _dbus_assert (start >= 0);
2440 _dbus_assert (start <= real->len);
2441 _dbus_assert (len >= 0);
2442
2443 if (len > real->len - start)
2444 return FALSE;
2445
2446 s = real->str + start;
2447 end = s + len;
2448 while (s != end)
2449 {
2450 if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
2451 return FALSE;
2452
2453 ++s;
2454 }
2455
2456 return TRUE;
2457 }
2458
2466 void
2467 _dbus_string_tolower_ascii (const DBusString *str,
2468 int start,
2469 int len)
2470 {
2471 unsigned char *s;
2472 unsigned char *end;
2473 DBUS_STRING_PREAMBLE (str);
2474 _dbus_assert (start >= 0);
2475 _dbus_assert (start <= real->len);
2476 _dbus_assert (len >= 0);
2477 _dbus_assert (len <= real->len - start);
2478
2479 s = real->str + start;
2480 end = s + len;
2481
2482 while (s != end)
2483 {
2484 if (*s >= 'A' && *s <= 'Z')
2485 *s += 'a' - 'A';
2486 ++s;
2487 }
2488 }
2489
2497 void
2498 _dbus_string_toupper_ascii (const DBusString *str,
2499 int start,
2500 int len)
2501 {
2502 unsigned char *s;
2503 unsigned char *end;
2504 DBUS_STRING_PREAMBLE (str);
2505 _dbus_assert (start >= 0);
2506 _dbus_assert (start <= real->len);
2507 _dbus_assert (len >= 0);
2508 _dbus_assert (len <= real->len - start);
2509
2510 s = real->str + start;
2511 end = s + len;
2512
2513 while (s != end)
2514 {
2515 if (*s >= 'a' && *s <= 'z')
2516 *s += 'A' - 'a';
2517 ++s;
2518 }
2519 }
2520
2536 dbus_bool_t
2537 _dbus_string_validate_utf8 (const DBusString *str,
2538 int start,
2539 int len)
2540 {
2541 const unsigned char *p;
2542 const unsigned char *end;
2543 DBUS_CONST_STRING_PREAMBLE (str);
2544 _dbus_assert (start >= 0);
2545 _dbus_assert (start <= real->len);
2546 _dbus_assert (len >= 0);
2547
2548 /* we are doing _DBUS_UNLIKELY() here which might be
2549 * dubious in a generic library like GLib, but in D-Bus
2550 * we know we're validating messages and that it would
2551 * only be evil/broken apps that would have invalid
2552 * UTF-8. Also, this function seems to be a performance
2553 * bottleneck in profiles.
2554 */
2555
2556 if (_DBUS_UNLIKELY (len > real->len - start))
2557 return FALSE;
2558
2559 p = real->str + start;
2560 end = p + len;
2561
2562 while (p < end)
2563 {
2564 int i, mask, char_len;
2565 dbus_unichar_t result;
2566
2567 /* nul bytes considered invalid */
2568 if (*p == '\0')
2569 break;
2570
2571 /* Special-case ASCII; this makes us go a lot faster in
2572 * D-Bus profiles where we are typically validating
2573 * function names and such. We have to know that
2574 * all following checks will pass for ASCII though,
2575 * comments follow ...
2576 */
2577 if (*p < 128)
2578 {
2579 ++p;
2580 continue;
2581 }
2582
2583 UTF8_COMPUTE (*p, mask, char_len);
2584
2585 if (_DBUS_UNLIKELY (char_len == 0)) /* ASCII: char_len == 1 */
2586 break;
2587
2588 /* check that the expected number of bytes exists in the remaining length */
2589 if (_DBUS_UNLIKELY ((end - p) < char_len)) /* ASCII: p < end and char_len == 1 */
2590 break;
2591
2592 UTF8_GET (result, p, i, mask, char_len);
2593
2594 /* Check for overlong UTF-8 */
2595 if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* ASCII: UTF8_LENGTH == 1 */
2596 break;
2597 #if 0
2598 /* The UNICODE_VALID check below will catch this */
2599 if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) /* ASCII: result = ascii value */
2600 break;
2601 #endif
2602
2603 if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) /* ASCII: always valid */
2604 break;
2605
2606 /* UNICODE_VALID should have caught it */
2607 _dbus_assert (result != (dbus_unichar_t)-1);
2608
2609 p += char_len;
2610 }
2611
2612 /* See that we covered the entire length if a length was
2613 * passed in
2614 */
2615 if (_DBUS_UNLIKELY (p != end))
2616 return FALSE;
2617 else
2618 return TRUE;
2619 }
2620
2634 dbus_bool_t
2635 _dbus_string_validate_nul (const DBusString *str,
2636 int start,
2637 int len)
2638 {
2639 const unsigned char *s;
2640 const unsigned char *end;
2641 DBUS_CONST_STRING_PREAMBLE (str);
2642 _dbus_assert (start >= 0);
2643 _dbus_assert (len >= 0);
2644 _dbus_assert (start <= real->len);
2645
2646 if (len > real->len - start)
2647 return FALSE;
2648
2649 s = real->str + start;
2650 end = s + len;
2651 while (s != end)
2652 {
2653 if (_DBUS_UNLIKELY (*s != '\0'))
2654 return FALSE;
2655 ++s;
2656 }
2657
2658 return TRUE;
2659 }
2660
2666 void
2667 _dbus_string_zero (DBusString *str)
2668 {
2669 DBUS_STRING_PREAMBLE (str);
2670
2671 memset (real->str - real->align_offset, '\0', real->allocated);
2672 }
2675 /* tests are in dbus-string-util.c */
DBUS_IS_ASCII_WHITE
#define DBUS_IS_ASCII_WHITE(c)
Checks for ASCII whitespace byte.
Definition: dbus-string-private.h:127
_dbus_string_insert_bytes
dbus_bool_t _dbus_string_insert_bytes(DBusString *str, int i, int n_bytes, unsigned char byte)
Inserts a number of bytes of a given value at the given position.
Definition: dbus-string.c:567
_dbus_string_append
dbus_bool_t _dbus_string_append(DBusString *str, const char *buffer)
Appends a nul-terminated C-style string to a DBusString.
Definition: dbus-string.c:918
_dbus_string_copy_to_buffer
void _dbus_string_copy_to_buffer(const DBusString *str, char *buffer, int avail_len)
Copies the contents of a DBusString into a different buffer.
Definition: dbus-string.c:680
NULL
#define NULL
A null pointer, defined appropriately for C or C++.
DBUS_STRING_COPY_PREAMBLE
#define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at)
Checks assertions for two strings we're copying a segment between, and declares real_source/real_dest...
Definition: dbus-string.c:1217
DBusRealString
Internals of DBusString.
Definition: dbus-string-private.h:43
_dbus_string_equal
dbus_bool_t _dbus_string_equal(const DBusString *a, const DBusString *b)
Tests two DBusString for equality.
Definition: dbus-string.c:1995
_dbus_string_find_eol
dbus_bool_t _dbus_string_find_eol(const DBusString *str, int start, int *found, int *found_len)
Finds end of line ("\r\n" or "\n") in the string, returning TRUE and filling in the byte index where ...
Definition: dbus-string.c:1609
_dbus_string_lengthen
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
Definition: dbus-string.c:743
dbus_realloc
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:601
ASSIGN_4_OCTETS
#define ASSIGN_4_OCTETS(p, octets)
assign 4 bytes from one string to another
Definition: dbus-string.c:938
dbus_free
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:701
_dbus_string_copy_to_buffer_with_nul
void _dbus_string_copy_to_buffer_with_nul(const DBusString *str, char *buffer, int avail_len)
Copies the contents of a DBusString into a different buffer.
Definition: dbus-string.c:702
_dbus_string_hex_encode
dbus_bool_t _dbus_string_hex_encode(const DBusString *source, int start, DBusString *dest, int insert_at)
Encodes a string in hex, the way MD5 and SHA-1 are usually encoded.
Definition: dbus-string.c:2241
ASSIGN_8_OCTETS
#define ASSIGN_8_OCTETS(p, octets)
assign 8 bytes from one string to another
Definition: dbus-string.c:942
_dbus_string_starts_with_c_str
dbus_bool_t _dbus_string_starts_with_c_str(const DBusString *a, const char *c_str)
Checks whether a string starts with the given C string.
Definition: dbus-string.c:2170
_dbus_string_chop_white
void _dbus_string_chop_white(DBusString *str)
Deletes leading and trailing whitespace.
Definition: dbus-string.c:1971
_dbus_string_insert_8_aligned
dbus_bool_t _dbus_string_insert_8_aligned(DBusString *str, int insert_at, const unsigned char octets[8])
Inserts 8 bytes aligned on an 8 byte boundary with any alignment padding initialized to 0...
Definition: dbus-string.c:1003
_dbus_assert
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
Definition: dbus-internals.h:135
_dbus_string_tolower_ascii
void _dbus_string_tolower_ascii(const DBusString *str, int start, int len)
Converts the given range of the string to lower case.
Definition: dbus-string.c:2467
DBusRealString::invalid
unsigned int invalid
DBusString is invalid (e.g.
Definition: dbus-string-private.h:50
DBUS_CONST_STRING_PREAMBLE
#define DBUS_CONST_STRING_PREAMBLE(str)
Checks assertions about a string that may be const or locked.
Definition: dbus-string-private.h:114
_dbus_string_get_data_len
char * _dbus_string_get_data_len(DBusString *str, int start, int len)
Gets a sub-portion of the raw character buffer from the string.
Definition: dbus-string.c:473
_DBUS_STRING_MAX_LENGTH
#define _DBUS_STRING_MAX_LENGTH
The maximum length of a DBusString.
Definition: dbus-string-private.h:69
_dbus_string_init
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
_dbus_string_append_printf_valist
dbus_bool_t _dbus_string_append_printf_valist(DBusString *str, const char *format, va_list args)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1055
_dbus_string_shorten
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:763
_dbus_string_copy
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that's copied to the d...
Definition: dbus-string.c:1265
UTF8_GET
#define UTF8_GET(Result, Chars, Count, Mask, Len)
Gets a UTF-8 value.
Definition: dbus-string.c:1544
_dbus_string_find
dbus_bool_t _dbus_string_find(const DBusString *str, int start, const char *substr, int *found)
Finds the given substring in the string, returning TRUE and filling in the byte index where the subst...
Definition: dbus-string.c:1586
_dbus_string_skip_white
void _dbus_string_skip_white(const DBusString *str, int start, int *end)
Skips whitespace from start, storing the first non-whitespace in *end.
Definition: dbus-string.c:1819
ASSIGN_2_OCTETS
#define ASSIGN_2_OCTETS(p, octets)
assign 2 bytes from one string to another
Definition: dbus-string.c:934
_dbus_string_move
dbus_bool_t _dbus_string_move(DBusString *source, int start, DBusString *dest, int insert_at)
Moves the end of one string into another string.
Definition: dbus-string.c:1241
dbus_malloc
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:461
UNICODE_VALID
#define UNICODE_VALID(Char)
Check whether a Unicode (5.2) char is in a valid range.
Definition: dbus-string.c:1567
_dbus_string_equal_c_str
dbus_bool_t _dbus_string_equal_c_str(const DBusString *a, const char *c_str)
Checks whether a string is equal to a C string.
Definition: dbus-string.c:2134
_dbus_string_compact
dbus_bool_t _dbus_string_compact(DBusString *str, int max_waste)
Compacts the string to avoid wasted memory.
Definition: dbus-string.c:372
_dbus_string_copy_data
dbus_bool_t _dbus_string_copy_data(const DBusString *str, char **data_return)
Copies the data from the string into a char*.
Definition: dbus-string.c:655
DBusString
Definition: dbus-string.h:42
dbus_bool_t
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
_dbus_string_init_const
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
DBUS_GENERIC_STRING_PREAMBLE
#define DBUS_GENERIC_STRING_PREAMBLE(real)
Checks a bunch of assertions about a string object.
Definition: dbus-string-private.h:76
_dbus_string_replace_len
dbus_bool_t _dbus_string_replace_len(const DBusString *source, int start, int len, DBusString *dest, int replace_at, int replace_len)
Replaces a segment of dest string with a segment of source string.
Definition: dbus-string.c:1386
DBUS_STRING_PREAMBLE
#define DBUS_STRING_PREAMBLE(str)
Checks assertions about a string object that needs to be modifiable - may not be locked or const...
Definition: dbus-string-private.h:93
_dbus_string_skip_blank
void _dbus_string_skip_blank(const DBusString *str, int start, int *end)
Skips blanks from start, storing the first non-blank in *end (blank is space or tab).
Definition: dbus-string.c:1785
UTF8_LENGTH
#define UTF8_LENGTH(Char)
computes length of a unicode character in UTF-8
Definition: dbus-string.c:1528
_dbus_string_pop_line
dbus_bool_t _dbus_string_pop_line(DBusString *source, DBusString *dest)
Assigns a newline-terminated or \r\n-terminated line from the front of the string to the given dest s...
Definition: dbus-string.c:1891
_dbus_string_delete
void _dbus_string_delete(DBusString *str, int start, int len)
Deletes a segment of a DBusString with length len starting at start.
Definition: dbus-string.c:1175
_dbus_string_init_preallocated
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc...
Definition: dbus-string.c:132
DBusRealString::len
int len
Length without nul.
Definition: dbus-string-private.h:46
_dbus_string_append_printf
dbus_bool_t _dbus_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1096
_dbus_string_zero
void _dbus_string_zero(DBusString *str)
Clears all allocated bytes in the string to zero.
Definition: dbus-string.c:2667
_dbus_string_validate_utf8
dbus_bool_t _dbus_string_validate_utf8(const DBusString *str, int start, int len)
Checks that the given range of the string is valid UTF-8.
Definition: dbus-string.c:2537
_dbus_string_align_length
dbus_bool_t _dbus_string_align_length(DBusString *str, int alignment)
Align the length of a string to a specific alignment (typically 4 or 8) by appending nul bytes to the...
Definition: dbus-string.c:866
_dbus_string_equal_substring
dbus_bool_t _dbus_string_equal_substring(const DBusString *a, int a_start, int a_len, const DBusString *b, int b_start)
Tests two sub-parts of two DBusString for equality.
Definition: dbus-string.c:2086
_dbus_string_equal_len
dbus_bool_t _dbus_string_equal_len(const DBusString *a, const DBusString *b, int len)
Tests two DBusString for equality up to the given length.
Definition: dbus-string.c:2038
DBusRealString::locked
unsigned int locked
DBusString has been locked and can't be changed.
Definition: dbus-string-private.h:49
_dbus_string_insert_byte
dbus_bool_t _dbus_string_insert_byte(DBusString *str, int i, unsigned char byte)
Inserts a single byte at the given position.
Definition: dbus-string.c:597
_dbus_string_append_byte
dbus_bool_t _dbus_string_append_byte(DBusString *str, unsigned char byte)
Appends a single byte to the string, returning FALSE if not enough memory.
Definition: dbus-string.c:1139
_dbus_string_free
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:242
TRUE
#define TRUE
Expands to "1".
_dbus_assert_not_reached
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
Definition: dbus-internals.h:145
DBusRealString::allocated
int allocated
Allocated size of data.
Definition: dbus-string-private.h:47
DBUS_IS_ASCII_BLANK
#define DBUS_IS_ASCII_BLANK(c)
Checks for ASCII blank byte.
Definition: dbus-string-private.h:121
_dbus_string_find_blank
dbus_bool_t _dbus_string_find_blank(const DBusString *str, int start, int *found)
Finds a blank (space or tab) in the string.
Definition: dbus-string.c:1747
_dbus_string_alloc_space
dbus_bool_t _dbus_string_alloc_space(DBusString *str, int extra_bytes)
Preallocate extra_bytes such that a future lengthening of the string by extra_bytes is guaranteed to ...
Definition: dbus-string.c:882
_dbus_string_hex_decode
dbus_bool_t _dbus_string_hex_decode(const DBusString *source, int start, int *end_return, DBusString *dest, int insert_at)
Decodes a string from hex encoding.
Definition: dbus-string.c:2291
DBusRealString::align_offset
unsigned int align_offset
str - align_offset is the actual malloc block
Definition: dbus-string-private.h:51
_dbus_string_append_byte_as_hex
dbus_bool_t _dbus_string_append_byte_as_hex(DBusString *str, unsigned char byte)
Appends a two-character hex digit to a string, where the hex digit has the value of the given byte...
Definition: dbus-string.c:2207
_dbus_string_append_len
dbus_bool_t _dbus_string_append_len(DBusString *str, const char *buffer, int len)
Appends block of bytes with the given length to a DBusString.
Definition: dbus-string.c:1119
_dbus_string_find_to
dbus_bool_t _dbus_string_find_to(const DBusString *str, int start, int end, const char *substr, int *found)
Finds the given substring in the string, up to a certain position, returning TRUE and filling in the ...
Definition: dbus-string.c:1679
DBusRealString::str
unsigned char * str
String data, plus nul termination.
Definition: dbus-string-private.h:45
_dbus_string_validate_nul
dbus_bool_t _dbus_string_validate_nul(const DBusString *str, int start, int len)
Checks that the given range of the string is all nul bytes.
Definition: dbus-string.c:2635
FALSE
#define FALSE
Expands to "0".
_dbus_string_insert_4_aligned
dbus_bool_t _dbus_string_insert_4_aligned(DBusString *str, int insert_at, const unsigned char octets[4])
Inserts 4 bytes aligned on a 4 byte boundary with any alignment padding initialized to 0...
Definition: dbus-string.c:979
_dbus_string_skip_white_reverse
void _dbus_string_skip_white_reverse(const DBusString *str, int end, int *start)
Skips whitespace from end, storing the start index of the trailing whitespace in *start.
Definition: dbus-string.c:1852
DBUS_LOCKED_STRING_PREAMBLE
#define DBUS_LOCKED_STRING_PREAMBLE(str)
Checks assertions about a string object that may be locked but can't be const.
Definition: dbus-string-private.h:105
_dbus_string_set_length
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:785
_dbus_string_insert_2_aligned
dbus_bool_t _dbus_string_insert_2_aligned(DBusString *str, int insert_at, const unsigned char octets[2])
Inserts 2 bytes aligned on a 2 byte boundary with any alignment padding initialized to 0...
Definition: dbus-string.c:955
_dbus_string_copy_len
dbus_bool_t _dbus_string_copy_len(const DBusString *source, int start, int len, DBusString *dest, int insert_at)
Like _dbus_string_copy(), but can copy a segment from the middle of the source string.
Definition: dbus-string.c:1357
_dbus_printf_string_upper_bound
int _dbus_printf_string_upper_bound(const char *format, va_list args)
Measure the length of the given format string and arguments, not including the terminating nul...
Definition: dbus-sysdeps-unix.c:3183
_dbus_string_steal_data
dbus_bool_t _dbus_string_steal_data(DBusString *str, char **data_return)
Like _dbus_string_get_data(), but removes the gotten data from the original string.
Definition: dbus-string.c:624
_dbus_string_toupper_ascii
void _dbus_string_toupper_ascii(const DBusString *str, int start, int len)
Converts the given range of the string to upper case.
Definition: dbus-string.c:2498
UTF8_COMPUTE
#define UTF8_COMPUTE(Char, Mask, Len)
computes length and mask of a unicode character
Definition: dbus-string.c:1487
_dbus_string_insert_alignment
dbus_bool_t _dbus_string_insert_alignment(DBusString *str, int *insert_at, int alignment)
Inserts padding at *insert_at such to align it to the given boundary.
Definition: dbus-string.c:1031
_dbus_string_validate_ascii
dbus_bool_t _dbus_string_validate_ascii(const DBusString *str, int start, int len)
Checks that the given range of the string is valid ASCII with no nul bytes.
Definition: dbus-string.c:2432
_dbus_string_init_const_len
void _dbus_string_init_const_len(DBusString *str, const char *value, int len)
Initializes a constant string with a length.
Definition: dbus-string.c:210
_dbus_string_move_len
dbus_bool_t _dbus_string_move_len(DBusString *source, int start, int len, DBusString *dest, int insert_at)
Like _dbus_string_move(), but can move a segment from the middle of the source string.
Definition: dbus-string.c:1290
DBusRealString::constant
unsigned int constant
String data is not owned by DBusString.
Definition: dbus-string-private.h:48
_dbus_string_split_on_byte
dbus_bool_t _dbus_string_split_on_byte(DBusString *source, unsigned char byte, DBusString *tail)
Looks for the first occurance of a byte, deletes that byte, and moves everything after the byte to th...
Definition: dbus-string.c:1449