D-Bus 1.13.18

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 2002-2007 Red Hat, Inc.
5 * Copyright 2003 CodeFactory AB
6 * Copyright 2003 Mark McLoughlin
7 * Copyright 2004 Michael Meeks
8 * Copyright 2006-2014 Ralf Habacker <ralf.habacker@freenet.de>
9 * Copyright 2006-2018 Collabora Ltd.
10 * Copyright 2007 Allison Lortie
11 * Copyright 2011 Roberto Guido
12 * Copyright 2013 Chengwei Yang / Intel
13 *
14 * Licensed under the Academic Free License version 2.1
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 *
30 */
31
32#include <config.h>
33#include "dbus-internals.h"
34#include "dbus-string.h"
35/* we allow a system header here, for speed/convenience */
36#include <string.h>
37/* for vsnprintf */
38#include <stdio.h>
39#define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
40#include "dbus-string-private.h"
41#include "dbus-marshal-basic.h" /* probably should be removed by moving the usage of DBUS_TYPE
42 * into the marshaling-related files
43 */
44/* for DBUS_VA_COPY */
45#include "dbus-sysdeps.h"
46
85 static void
86fixup_alignment (DBusRealString *real)
87{
88 unsigned char *aligned;
89 unsigned char *real_block;
90 unsigned int old_align_offset;
91
92 /* we have to have extra space in real->allocated for the align offset and nul byte */
93 _dbus_assert (real->len <= real->allocated - _DBUS_STRING_ALLOCATION_PADDING);
94
95 old_align_offset = real->align_offset;
96 real_block = real->str - old_align_offset;
97
98 aligned = _DBUS_ALIGN_ADDRESS (real_block, 8);
99
100 real->align_offset = aligned - real_block;
101 real->str = aligned;
102
103 if (old_align_offset != real->align_offset)
104 {
105 /* Here comes the suck */
106 memmove (real_block + real->align_offset,
107 real_block + old_align_offset,
108 real->len + 1);
109 }
110
111 _dbus_assert (real->align_offset < 8);
112 _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str);
113}
114
115 static void
116undo_alignment (DBusRealString *real)
117{
118 if (real->align_offset != 0)
119 {
120 memmove (real->str - real->align_offset,
121 real->str,
122 real->len + 1);
123
124 real->str = real->str - real->align_offset;
125 real->align_offset = 0;
126 }
127}
128
138 dbus_bool_t
139_dbus_string_init_preallocated (DBusString *str,
140 int allocate_size)
141{
142 DBusRealString *real;
143
144 _DBUS_STATIC_ASSERT (sizeof (DBusString) == sizeof (DBusRealString));
145
146 _dbus_assert (str != NULL);
147
148 real = (DBusRealString*) str;
149
150 /* It's very important not to touch anything
151 * other than real->str if we're going to fail,
152 * since we also use this function to reset
153 * an existing string, e.g. in _dbus_string_steal_data()
154 */
155
156 real->str = dbus_malloc (_DBUS_STRING_ALLOCATION_PADDING + allocate_size);
157 if (real->str == NULL)
158 return FALSE;
159
160 real->allocated = _DBUS_STRING_ALLOCATION_PADDING + allocate_size;
161 real->len = 0;
162 real->str[real->len] = '\0';
163
164 real->constant = FALSE;
165 real->locked = FALSE;
166 real->valid = TRUE;
167 real->align_offset = 0;
168
169 fixup_alignment (real);
170
171 return TRUE;
172}
173
181 dbus_bool_t
182_dbus_string_init (DBusString *str)
183{
184 return _dbus_string_init_preallocated (str, 0);
185}
186
196 void
197_dbus_string_init_const (DBusString *str,
198 const char *value)
199{
200 _dbus_assert (value != NULL);
201
202 _dbus_string_init_const_len (str, value,
203 strlen (value));
204}
205
216 void
217_dbus_string_init_const_len (DBusString *str,
218 const char *value,
219 int len)
220{
221 DBusRealString *real;
222
223 _dbus_assert (str != NULL);
224 _dbus_assert (len == 0 || value != NULL);
225 _dbus_assert (len <= _DBUS_STRING_MAX_LENGTH);
226 _dbus_assert (len >= 0);
227
228 real = (DBusRealString*) str;
229
230 real->str = (unsigned char*) value;
231 real->len = len;
232 real->allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING; /* a lie, just to avoid special-case assertions... */
233 real->constant = TRUE;
234 real->locked = TRUE;
235 real->valid = TRUE;
236 real->align_offset = 0;
237
238 /* We don't require const strings to be 8-byte aligned as the
239 * memory is coming from elsewhere.
240 */
241}
242
251 dbus_bool_t
252_dbus_string_init_from_string(DBusString *str,
253 const DBusString *from)
254{
255 if (!_dbus_string_init (str))
256 return FALSE;
257 return _dbus_string_append (str, _dbus_string_get_const_data (from));
258}
259
270 void
271_dbus_string_free (DBusString *str)
272{
273 DBusRealString *real = (DBusRealString*) str;
274 /* DBusRealString and DBusString have the same members in the same order,
275 * just differently-named */
276 DBusRealString invalid = _DBUS_STRING_INIT_INVALID;
277
278 /* Allow for the _DBUS_STRING_INIT_INVALID case */
279 if (real->str == NULL && real->len == 0 && real->allocated == 0 &&
280 !real->constant && !real->locked && !real->valid &&
281 real->align_offset == 0)
282 return;
283
284 DBUS_GENERIC_STRING_PREAMBLE (real);
285
286 if (real->constant)
287 goto wipe;
288
289 /* so it's safe if @p str returned by a failed
290 * _dbus_string_init call
291 * Bug: https://bugs.freedesktop.org/show_bug.cgi?id=65959
292 */
293 if (real->str == NULL)
294 goto wipe;
295
296 dbus_free (real->str - real->align_offset);
297
298wipe:
299 *real = invalid;
300 real->valid = FALSE;
301}
302
303 static dbus_bool_t
304compact (DBusRealString *real,
305 int max_waste)
306{
307 unsigned char *new_str;
308 int new_allocated;
309 int waste;
310
311 waste = real->allocated - (real->len + _DBUS_STRING_ALLOCATION_PADDING);
312
313 if (waste <= max_waste)
314 return TRUE;
315
316 new_allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING;
317
318 new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
319 if (_DBUS_UNLIKELY (new_str == NULL))
320 return FALSE;
321
322 real->str = new_str + real->align_offset;
323 real->allocated = new_allocated;
324 fixup_alignment (real);
325
326 return TRUE;
327}
328
329#ifdef DBUS_ENABLE_EMBEDDED_TESTS
330/* Not using this feature at the moment,
331 * so marked DBUS_ENABLE_EMBEDDED_TESTS-only
332 */
342 void
343_dbus_string_lock (DBusString *str)
344{
345 DBUS_LOCKED_STRING_PREAMBLE (str); /* can lock multiple times */
346
347 real->locked = TRUE;
348
349 /* Try to realloc to avoid excess memory usage, since
350 * we know we won't change the string further
351 */
352#define MAX_WASTE 48
353 compact (real, MAX_WASTE);
354}
355#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
356
357 static dbus_bool_t
358reallocate_for_length (DBusRealString *real,
359 int new_length)
360{
361 int new_allocated;
362 unsigned char *new_str;
363
364 /* at least double our old allocation to avoid O(n), avoiding
365 * overflow
366 */
367 if (real->allocated > (_DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2)
368 new_allocated = _DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING;
369 else
370 new_allocated = real->allocated * 2;
371
372 /* if you change the code just above here, run the tests without
373 * the following assert-only hack before you commit
374 */
375 /* This is keyed off asserts in addition to tests so when you
376 * disable asserts to profile, you don't get this destroyer
377 * of profiles.
378 */
379#if defined (DBUS_ENABLE_EMBEDDED_TESTS) && !defined (DBUS_DISABLE_ASSERT)
380 new_allocated = 0; /* ensure a realloc every time so that we go
381 * through all malloc failure codepaths
382 */
383#endif
384
385 /* But be sure we always alloc at least space for the new length */
386 new_allocated = MAX (new_allocated,
387 new_length + _DBUS_STRING_ALLOCATION_PADDING);
388
389 _dbus_assert (new_allocated >= real->allocated); /* code relies on this */
390 new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
391 if (_DBUS_UNLIKELY (new_str == NULL))
392 return FALSE;
393
394 real->str = new_str + real->align_offset;
395 real->allocated = new_allocated;
396 fixup_alignment (real);
397
398 return TRUE;
399}
400
412 dbus_bool_t
413_dbus_string_compact (DBusString *str,
414 int max_waste)
415{
416 DBUS_STRING_PREAMBLE (str);
417
418 return compact (real, max_waste);
419}
420
421 static dbus_bool_t
422set_length (DBusRealString *real,
423 int new_length)
424{
425 /* Note, we are setting the length not including nul termination */
426
427 /* exceeding max length is the same as failure to allocate memory */
428 if (_DBUS_UNLIKELY (new_length > _DBUS_STRING_MAX_LENGTH))
429 return FALSE;
430 else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) &&
431 _DBUS_UNLIKELY (!reallocate_for_length (real, new_length)))
432 return FALSE;
433 else
434 {
435 real->len = new_length;
436 real->str[new_length] = '\0';
437 return TRUE;
438 }
439}
440
441 static dbus_bool_t
442open_gap (int len,
443 DBusRealString *dest,
444 int insert_at)
445{
446 if (len == 0)
447 return TRUE;
448
449 if (len > _DBUS_STRING_MAX_LENGTH - dest->len)
450 return FALSE; /* detected overflow of dest->len + len below */
451
452 if (!set_length (dest, dest->len + len))
453 return FALSE;
454
455 memmove (dest->str + insert_at + len,
456 dest->str + insert_at,
457 dest->len - len - insert_at);
458
459 return TRUE;
460}
461
462#ifndef _dbus_string_get_data
474 char*
475_dbus_string_get_data (DBusString *str)
476{
477 DBUS_STRING_PREAMBLE (str);
478
479 return (char*) real->str;
480}
481#endif /* _dbus_string_get_data */
482
483/* only do the function if we don't have the macro */
484#ifndef _dbus_string_get_const_data
491 const char*
492_dbus_string_get_const_data (const DBusString *str)
493{
494 DBUS_CONST_STRING_PREAMBLE (str);
495
496 return (const char*) real->str;
497}
498#endif /* _dbus_string_get_const_data */
499
513 char*
514_dbus_string_get_data_len (DBusString *str,
515 int start,
516 int len)
517{
518 DBUS_STRING_PREAMBLE (str);
519 _dbus_assert (start >= 0);
520 _dbus_assert (len >= 0);
521 _dbus_assert (start <= real->len);
522 _dbus_assert (len <= real->len - start);
523
524 return (char*) real->str + start;
525}
526
527/* only do the function if we don't have the macro */
528#ifndef _dbus_string_get_const_data_len
537 const char*
538_dbus_string_get_const_data_len (const DBusString *str,
539 int start,
540 int len)
541{
542 DBUS_CONST_STRING_PREAMBLE (str);
543 _dbus_assert (start >= 0);
544 _dbus_assert (len >= 0);
545 _dbus_assert (start <= real->len);
546 _dbus_assert (len <= real->len - start);
547
548 return (const char*) real->str + start;
549}
550#endif /* _dbus_string_get_const_data_len */
551
552/* only do the function if we don't have the macro */
553#ifndef _dbus_string_set_byte
561 void
562_dbus_string_set_byte (DBusString *str,
563 int i,
564 unsigned char byte)
565{
566 DBUS_STRING_PREAMBLE (str);
567 _dbus_assert (i < real->len);
568 _dbus_assert (i >= 0);
569
570 real->str[i] = byte;
571}
572#endif /* _dbus_string_set_byte */
573
574/* only have the function if we didn't create a macro */
575#ifndef _dbus_string_get_byte
585 unsigned char
586_dbus_string_get_byte (const DBusString *str,
587 int start)
588{
589 DBUS_CONST_STRING_PREAMBLE (str);
590 _dbus_assert (start <= real->len);
591 _dbus_assert (start >= 0);
592
593 return real->str[start];
594}
595#endif /* _dbus_string_get_byte */
596
607 dbus_bool_t
608_dbus_string_insert_bytes (DBusString *str,
609 int i,
610 int n_bytes,
611 unsigned char byte)
612{
613 DBUS_STRING_PREAMBLE (str);
614 _dbus_assert (i <= real->len);
615 _dbus_assert (i >= 0);
616 _dbus_assert (n_bytes >= 0);
617
618 if (n_bytes == 0)
619 return TRUE;
620
621 if (!open_gap (n_bytes, real, i))
622 return FALSE;
623
624 memset (real->str + i, byte, n_bytes);
625
626 return TRUE;
627}
628
637 dbus_bool_t
638_dbus_string_insert_byte (DBusString *str,
639 int i,
640 unsigned char byte)
641{
642 DBUS_STRING_PREAMBLE (str);
643 _dbus_assert (i <= real->len);
644 _dbus_assert (i >= 0);
645
646 if (!open_gap (1, real, i))
647 return FALSE;
648
649 real->str[i] = byte;
650
651 return TRUE;
652}
653
664 dbus_bool_t
665_dbus_string_steal_data (DBusString *str,
666 char **data_return)
667{
668 DBUS_STRING_PREAMBLE (str);
669 _dbus_assert (data_return != NULL);
670
671 undo_alignment (real);
672
673 *data_return = (char*) real->str;
674
675 /* reset the string */
676 if (!_dbus_string_init (str))
677 {
678 /* hrm, put it back then */
679 real->str = (unsigned char*) *data_return;
680 *data_return = NULL;
681 fixup_alignment (real);
682 return FALSE;
683 }
684
685 return TRUE;
686}
687
695 dbus_bool_t
696_dbus_string_copy_data (const DBusString *str,
697 char **data_return)
698{
699 DBUS_CONST_STRING_PREAMBLE (str);
700 _dbus_assert (data_return != NULL);
701
702 *data_return = dbus_malloc (real->len + 1);
703 if (*data_return == NULL)
704 return FALSE;
705
706 memcpy (*data_return, real->str, real->len + 1);
707
708 return TRUE;
709}
710
720 void
721_dbus_string_copy_to_buffer (const DBusString *str,
722 char *buffer,
723 int avail_len)
724{
725 DBUS_CONST_STRING_PREAMBLE (str);
726
727 _dbus_assert (avail_len >= 0);
728 _dbus_assert (avail_len >= real->len);
729
730 memcpy (buffer, real->str, real->len);
731}
732
742 void
743_dbus_string_copy_to_buffer_with_nul (const DBusString *str,
744 char *buffer,
745 int avail_len)
746{
747 DBUS_CONST_STRING_PREAMBLE (str);
748
749 _dbus_assert (avail_len >= 0);
750 _dbus_assert (avail_len > real->len);
751
752 memcpy (buffer, real->str, real->len+1);
753}
754
755/* Only have the function if we don't have the macro */
756#ifndef _dbus_string_get_length
762 int
763_dbus_string_get_length (const DBusString *str)
764{
765 DBUS_CONST_STRING_PREAMBLE (str);
766
767 return real->len;
768}
769#endif /* !_dbus_string_get_length */
770
783 dbus_bool_t
784_dbus_string_lengthen (DBusString *str,
785 int additional_length)
786{
787 DBUS_STRING_PREAMBLE (str);
788 _dbus_assert (additional_length >= 0);
789
790 if (_DBUS_UNLIKELY (additional_length > _DBUS_STRING_MAX_LENGTH - real->len))
791 return FALSE; /* would overflow */
792
793 return set_length (real,
794 real->len + additional_length);
795}
796
803 void
804_dbus_string_shorten (DBusString *str,
805 int length_to_remove)
806{
807 DBUS_STRING_PREAMBLE (str);
808 _dbus_assert (length_to_remove >= 0);
809 _dbus_assert (length_to_remove <= real->len);
810
811 set_length (real,
812 real->len - length_to_remove);
813}
814
825 dbus_bool_t
826_dbus_string_set_length (DBusString *str,
827 int length)
828{
829 DBUS_STRING_PREAMBLE (str);
830 _dbus_assert (length >= 0);
831
832 return set_length (real, length);
833}
834
835 static dbus_bool_t
836align_insert_point_then_open_gap (DBusString *str,
837 int *insert_at_p,
838 int alignment,
839 int gap_size)
840{
841 unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */
842 unsigned long gap_pos;
843 int insert_at;
844 int delta;
845 DBUS_STRING_PREAMBLE (str);
846 _dbus_assert (alignment >= 1);
847 _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
848
849 insert_at = *insert_at_p;
850
851 _dbus_assert (insert_at <= real->len);
852
853 gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
854 new_len = real->len + (gap_pos - insert_at) + gap_size;
855
856 if (_DBUS_UNLIKELY (new_len > (unsigned long) _DBUS_STRING_MAX_LENGTH))
857 return FALSE;
858
859 delta = new_len - real->len;
860 _dbus_assert (delta >= 0);
861
862 if (delta == 0) /* only happens if gap_size == 0 and insert_at is aligned already */
863 {
864 _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
865 return TRUE;
866 }
867
868 if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
869 real, insert_at)))
870 return FALSE;
871
872 /* nul the padding if we had to add any padding */
873 if (gap_size < delta)
874 {
875 memset (&real->str[insert_at], '\0',
876 gap_pos - insert_at);
877 }
878
879 *insert_at_p = gap_pos;
880
881 return TRUE;
882}
883
884 static dbus_bool_t
885align_length_then_lengthen (DBusString *str,
886 int alignment,
887 int then_lengthen_by)
888{
889 int insert_at;
890
891 insert_at = _dbus_string_get_length (str);
892
893 return align_insert_point_then_open_gap (str,
894 &insert_at,
895 alignment, then_lengthen_by);
896}
897
906 dbus_bool_t
907_dbus_string_align_length (DBusString *str,
908 int alignment)
909{
910 return align_length_then_lengthen (str, alignment, 0);
911}
912
922 dbus_bool_t
923_dbus_string_alloc_space (DBusString *str,
924 int extra_bytes)
925{
926 if (!_dbus_string_lengthen (str, extra_bytes))
927 return FALSE;
928 _dbus_string_shorten (str, extra_bytes);
929
930 return TRUE;
931}
932
933 static dbus_bool_t
934append (DBusRealString *real,
935 const char *buffer,
936 int buffer_len)
937{
938 if (buffer_len == 0)
939 return TRUE;
940
941 if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
942 return FALSE;
943
944 memcpy (real->str + (real->len - buffer_len),
945 buffer,
946 buffer_len);
947
948 return TRUE;
949}
950
958 dbus_bool_t
959_dbus_string_append (DBusString *str,
960 const char *buffer)
961{
962 unsigned long buffer_len;
963
964 DBUS_STRING_PREAMBLE (str);
965 _dbus_assert (buffer != NULL);
966
967 buffer_len = strlen (buffer);
968 if (buffer_len > (unsigned long) _DBUS_STRING_MAX_LENGTH)
969 return FALSE;
970
971 return append (real, buffer, buffer_len);
972}
973
975#define ASSIGN_2_OCTETS(p, octets) \
976 *((dbus_uint16_t*)(p)) = *((dbus_uint16_t*)(octets));
977
979#define ASSIGN_4_OCTETS(p, octets) \
980 *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
981
983#define ASSIGN_8_OCTETS(p, octets) \
984 *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
985
995 dbus_bool_t
996_dbus_string_insert_2_aligned (DBusString *str,
997 int insert_at,
998 const unsigned char octets[2])
999{
1000 DBUS_STRING_PREAMBLE (str);
1001
1002 if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2))
1003 return FALSE;
1004
1005 ASSIGN_2_OCTETS (real->str + insert_at, octets);
1006
1007 return TRUE;
1008}
1009
1019 dbus_bool_t
1020_dbus_string_insert_4_aligned (DBusString *str,
1021 int insert_at,
1022 const unsigned char octets[4])
1023{
1024 DBUS_STRING_PREAMBLE (str);
1025
1026 if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
1027 return FALSE;
1028
1029 ASSIGN_4_OCTETS (real->str + insert_at, octets);
1030
1031 return TRUE;
1032}
1033
1043 dbus_bool_t
1044_dbus_string_insert_8_aligned (DBusString *str,
1045 int insert_at,
1046 const unsigned char octets[8])
1047{
1048 DBUS_STRING_PREAMBLE (str);
1049
1050 if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
1051 return FALSE;
1052
1053 _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
1054
1055 ASSIGN_8_OCTETS (real->str + insert_at, octets);
1056
1057 return TRUE;
1058}
1059
1060
1071 dbus_bool_t
1072_dbus_string_insert_alignment (DBusString *str,
1073 int *insert_at,
1074 int alignment)
1075{
1076 DBUS_STRING_PREAMBLE (str);
1077
1078 if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0))
1079 return FALSE;
1080
1081 _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at);
1082
1083 return TRUE;
1084}
1085
1095 dbus_bool_t
1096_dbus_string_append_printf_valist (DBusString *str,
1097 const char *format,
1098 va_list args)
1099{
1100 dbus_bool_t ret = FALSE;
1101 int len;
1102 va_list args_copy;
1103
1104 DBUS_STRING_PREAMBLE (str);
1105
1106 DBUS_VA_COPY (args_copy, args);
1107
1108 /* Measure the message length without terminating nul */
1109 len = _dbus_printf_string_upper_bound (format, args);
1110
1111 if (len < 0)
1112 goto out;
1113
1114 if (!_dbus_string_lengthen (str, len))
1115 {
1116 goto out;
1117 }
1118
1119 vsprintf ((char*) (real->str + (real->len - len)),
1120 format, args_copy);
1121 ret = TRUE;
1122
1123out:
1124 va_end (args_copy);
1125
1126 return ret;
1127}
1128
1137 dbus_bool_t
1138_dbus_string_append_printf (DBusString *str,
1139 const char *format,
1140 ...)
1141{
1142 va_list args;
1143 dbus_bool_t retval;
1144
1145 va_start (args, format);
1146 retval = _dbus_string_append_printf_valist (str, format, args);
1147 va_end (args);
1148
1149 return retval;
1150}
1151
1160 dbus_bool_t
1161_dbus_string_append_len (DBusString *str,
1162 const char *buffer,
1163 int len)
1164{
1165 DBUS_STRING_PREAMBLE (str);
1166 _dbus_assert (buffer != NULL);
1167 _dbus_assert (len >= 0);
1168
1169 return append (real, buffer, len);
1170}
1171
1180 dbus_bool_t
1181_dbus_string_append_byte (DBusString *str,
1182 unsigned char byte)
1183{
1184 DBUS_STRING_PREAMBLE (str);
1185
1186 if (!set_length (real, real->len + 1))
1187 return FALSE;
1188
1189 real->str[real->len-1] = byte;
1190
1191 return TRUE;
1192}
1193
1194 static void
1195 delete (DBusRealString *real,
1196 int start,
1197 int len)
1198{
1199 if (len == 0)
1200 return;
1201
1202 memmove (real->str + start, real->str + start + len, real->len - (start + len));
1203 real->len -= len;
1204 real->str[real->len] = '\0';
1205}
1206
1216 void
1217_dbus_string_delete (DBusString *str,
1218 int start,
1219 int len)
1220{
1221 DBUS_STRING_PREAMBLE (str);
1222 _dbus_assert (start >= 0);
1223 _dbus_assert (len >= 0);
1224 _dbus_assert (start <= real->len);
1225 _dbus_assert (len <= real->len - start);
1226
1227 delete (real, start, len);
1228}
1229
1230 static dbus_bool_t
1231copy (DBusRealString *source,
1232 int start,
1233 int len,
1234 DBusRealString *dest,
1235 int insert_at)
1236{
1237 if (len == 0)
1238 return TRUE;
1239
1240 if (!open_gap (len, dest, insert_at))
1241 return FALSE;
1242
1243 memmove (dest->str + insert_at,
1244 source->str + start,
1245 len);
1246
1247 return TRUE;
1248}
1249
1259#define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at) \
1260 DBusRealString *real_source = (DBusRealString*) source; \
1261 DBusRealString *real_dest = (DBusRealString*) dest; \
1262 _dbus_assert ((source) != (dest)); \
1263 DBUS_GENERIC_STRING_PREAMBLE (real_source); \
1264 DBUS_GENERIC_STRING_PREAMBLE (real_dest); \
1265 _dbus_assert (!real_dest->constant); \
1266 _dbus_assert (!real_dest->locked); \
1267 _dbus_assert ((start) >= 0); \
1268 _dbus_assert ((start) <= real_source->len); \
1269 _dbus_assert ((insert_at) >= 0); \
1270 _dbus_assert ((insert_at) <= real_dest->len)
1271
1282 dbus_bool_t
1283_dbus_string_move (DBusString *source,
1284 int start,
1285 DBusString *dest,
1286 int insert_at)
1287{
1288 DBusRealString *real_source = (DBusRealString*) source;
1289 _dbus_assert (start <= real_source->len);
1290
1291 return _dbus_string_move_len (source, start,
1292 real_source->len - start,
1293 dest, insert_at);
1294}
1295
1306 dbus_bool_t
1307_dbus_string_copy (const DBusString *source,
1308 int start,
1309 DBusString *dest,
1310 int insert_at)
1311{
1312 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1313
1314 return copy (real_source, start,
1315 real_source->len - start,
1316 real_dest,
1317 insert_at);
1318}
1319
1331 dbus_bool_t
1332_dbus_string_move_len (DBusString *source,
1333 int start,
1334 int len,
1335 DBusString *dest,
1336 int insert_at)
1337
1338{
1339 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1340 _dbus_assert (len >= 0);
1341 _dbus_assert ((start + len) <= real_source->len);
1342
1343
1344 if (len == 0)
1345 {
1346 return TRUE;
1347 }
1348 else if (start == 0 &&
1349 len == real_source->len &&
1350 real_dest->len == 0)
1351 {
1352 /* Short-circuit moving an entire existing string to an empty string
1353 * by just swapping the buffers.
1354 */
1355 /* we assume ->constant doesn't matter as you can't have
1356 * a constant string involved in a move.
1357 */
1358#define ASSIGN_DATA(a, b) do { \
1359 (a)->str = (b)->str; \
1360 (a)->len = (b)->len; \
1361 (a)->allocated = (b)->allocated; \
1362 (a)->align_offset = (b)->align_offset; \
1363 } while (0)
1364
1365 DBusRealString tmp;
1366
1367 ASSIGN_DATA (&tmp, real_source);
1368 ASSIGN_DATA (real_source, real_dest);
1369 ASSIGN_DATA (real_dest, &tmp);
1370
1371 return TRUE;
1372 }
1373 else
1374 {
1375 if (!copy (real_source, start, len,
1376 real_dest,
1377 insert_at))
1378 return FALSE;
1379
1380 delete (real_source, start,
1381 len);
1382
1383 return TRUE;
1384 }
1385}
1386
1398 dbus_bool_t
1399_dbus_string_copy_len (const DBusString *source,
1400 int start,
1401 int len,
1402 DBusString *dest,
1403 int insert_at)
1404{
1405 DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1406 _dbus_assert (len >= 0);
1407 _dbus_assert (start <= real_source->len);
1408 _dbus_assert (len <= real_source->len - start);
1409
1410 return copy (real_source, start, len,
1411 real_dest,
1412 insert_at);
1413}
1414
1427 dbus_bool_t
1428_dbus_string_replace_len (const DBusString *source,
1429 int start,
1430 int len,
1431 DBusString *dest,
1432 int replace_at,
1433 int replace_len)
1434{
1435 DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
1436 _dbus_assert (len >= 0);
1437 _dbus_assert (start <= real_source->len);
1438 _dbus_assert (len <= real_source->len - start);
1439 _dbus_assert (replace_at >= 0);
1440 _dbus_assert (replace_at <= real_dest->len);
1441 _dbus_assert (replace_len <= real_dest->len - replace_at);
1442
1443 if (len == replace_len)
1444 {
1445 memmove (real_dest->str + replace_at,
1446 real_source->str + start, len);
1447 }
1448 else if (len < replace_len)
1449 {
1450 memmove (real_dest->str + replace_at,
1451 real_source->str + start, len);
1452 delete (real_dest, replace_at + len,
1453 replace_len - len);
1454 }
1455 else
1456 {
1457 int diff;
1458
1459 _dbus_assert (len > replace_len);
1460
1461 diff = len - replace_len;
1462
1463 /* First of all we check if destination string can be enlarged as
1464 * required, then we overwrite previous bytes
1465 */
1466
1467 if (!copy (real_source, start + replace_len, diff,
1468 real_dest, replace_at + replace_len))
1469 return FALSE;
1470
1471 memmove (real_dest->str + replace_at,
1472 real_source->str + start, replace_len);
1473 }
1474
1475 return TRUE;
1476}
1477
1490 dbus_bool_t
1491_dbus_string_split_on_byte (DBusString *source,
1492 unsigned char byte,
1493 DBusString *tail)
1494{
1495 int byte_position;
1496 char byte_string[2] = "";
1497 int head_length;
1498 int tail_length;
1499
1500 byte_string[0] = (char) byte;
1501
1502 if (!_dbus_string_find (source, 0, byte_string, &byte_position))
1503 return FALSE;
1504
1505 head_length = byte_position;
1506 tail_length = _dbus_string_get_length (source) - head_length - 1;
1507
1508 if (!_dbus_string_move_len (source, byte_position + 1, tail_length,
1509 tail, 0))
1510 return FALSE;
1511
1512 /* remove the trailing delimiter byte from the head now.
1513 */
1514 if (!_dbus_string_set_length (source, head_length))
1515 return FALSE;
1516
1517 return TRUE;
1518}
1519
1520/* Unicode macros and utf8_validate() from GLib Owen Taylor, Havoc
1521 * Pennington, and Tom Tromey are the authors and authorized relicense.
1522 */
1523
1529#define UTF8_COMPUTE(Char, Mask, Len) \
1530 if (Char < 128) \
1531 { \
1532 Len = 1; \
1533 Mask = 0x7f; \
1534 } \
1535 else if ((Char & 0xe0) == 0xc0) \
1536 { \
1537 Len = 2; \
1538 Mask = 0x1f; \
1539 } \
1540 else if ((Char & 0xf0) == 0xe0) \
1541 { \
1542 Len = 3; \
1543 Mask = 0x0f; \
1544 } \
1545 else if ((Char & 0xf8) == 0xf0) \
1546 { \
1547 Len = 4; \
1548 Mask = 0x07; \
1549 } \
1550 else if ((Char & 0xfc) == 0xf8) \
1551 { \
1552 Len = 5; \
1553 Mask = 0x03; \
1554 } \
1555 else if ((Char & 0xfe) == 0xfc) \
1556 { \
1557 Len = 6; \
1558 Mask = 0x01; \
1559 } \
1560 else \
1561 { \
1562 Len = 0; \
1563 Mask = 0; \
1564 }
1565
1570#define UTF8_LENGTH(Char) \
1571 ((Char) < 0x80 ? 1 : \
1572 ((Char) < 0x800 ? 2 : \
1573 ((Char) < 0x10000 ? 3 : \
1574 ((Char) < 0x200000 ? 4 : \
1575 ((Char) < 0x4000000 ? 5 : 6)))))
1576
1586#define UTF8_GET(Result, Chars, Count, Mask, Len) \
1587 (Result) = (Chars)[0] & (Mask); \
1588 for ((Count) = 1; (Count) < (Len); ++(Count)) \
1589 { \
1590 if (((Chars)[(Count)] & 0xc0) != 0x80) \
1591 { \
1592 (Result) = -1; \
1593 break; \
1594 } \
1595 (Result) <<= 6; \
1596 (Result) |= ((Chars)[(Count)] & 0x3f); \
1597 }
1598
1609#define UNICODE_VALID(Char) \
1610 ((Char) < 0x110000 && \
1611 (((Char) & 0xFFFFF800) != 0xD800))
1612
1627 dbus_bool_t
1628_dbus_string_find (const DBusString *str,
1629 int start,
1630 const char *substr,
1631 int *found)
1632{
1633 return _dbus_string_find_to (str, start,
1634 ((const DBusRealString*)str)->len,
1635 substr, found);
1636}
1637
1650 dbus_bool_t
1651_dbus_string_find_eol (const DBusString *str,
1652 int start,
1653 int *found,
1654 int *found_len)
1655{
1656 int i;
1657
1658 DBUS_CONST_STRING_PREAMBLE (str);
1659 _dbus_assert (start <= real->len);
1660 _dbus_assert (start >= 0);
1661
1662 i = start;
1663 while (i < real->len)
1664 {
1665 if (real->str[i] == '\r')
1666 {
1667 if ((i+1) < real->len && real->str[i+1] == '\n') /* "\r\n" */
1668 {
1669 if (found)
1670 *found = i;
1671 if (found_len)
1672 *found_len = 2;
1673 return TRUE;
1674 }
1675 else /* only "\r" */
1676 {
1677 if (found)
1678 *found = i;
1679 if (found_len)
1680 *found_len = 1;
1681 return TRUE;
1682 }
1683 }
1684 else if (real->str[i] == '\n') /* only "\n" */
1685 {
1686 if (found)
1687 *found = i;
1688 if (found_len)
1689 *found_len = 1;
1690 return TRUE;
1691 }
1692 ++i;
1693 }
1694
1695 if (found)
1696 *found = real->len;
1697
1698 if (found_len)
1699 *found_len = 0;
1700
1701 return FALSE;
1702}
1703
1720 dbus_bool_t
1721_dbus_string_find_to (const DBusString *str,
1722 int start,
1723 int end,
1724 const char *substr,
1725 int *found)
1726{
1727 int i;
1728 DBUS_CONST_STRING_PREAMBLE (str);
1729 _dbus_assert (substr != NULL);
1730 _dbus_assert (start <= real->len);
1731 _dbus_assert (start >= 0);
1732 _dbus_assert (substr != NULL);
1733 _dbus_assert (end <= real->len);
1734 _dbus_assert (start <= end);
1735
1736 /* we always "find" an empty string */
1737 if (*substr == '\0')
1738 {
1739 if (found)
1740 *found = start;
1741 return TRUE;
1742 }
1743
1744 i = start;
1745 while (i < end)
1746 {
1747 if (real->str[i] == substr[0])
1748 {
1749 int j = i + 1;
1750
1751 while (j < end)
1752 {
1753 if (substr[j - i] == '\0')
1754 break;
1755 else if (real->str[j] != substr[j - i])
1756 break;
1757
1758 ++j;
1759 }
1760
1761 if (substr[j - i] == '\0')
1762 {
1763 if (found)
1764 *found = i;
1765 return TRUE;
1766 }
1767 }
1768
1769 ++i;
1770 }
1771
1772 if (found)
1773 *found = end;
1774
1775 return FALSE;
1776}
1777
1788 dbus_bool_t
1789_dbus_string_find_blank (const DBusString *str,
1790 int start,
1791 int *found)
1792{
1793 int i;
1794 DBUS_CONST_STRING_PREAMBLE (str);
1795 _dbus_assert (start <= real->len);
1796 _dbus_assert (start >= 0);
1797
1798 i = start;
1799 while (i < real->len)
1800 {
1801 if (real->str[i] == ' ' ||
1802 real->str[i] == '\t')
1803 {
1804 if (found)
1805 *found = i;
1806 return TRUE;
1807 }
1808
1809 ++i;
1810 }
1811
1812 if (found)
1813 *found = real->len;
1814
1815 return FALSE;
1816}
1817
1826 void
1827_dbus_string_skip_blank (const DBusString *str,
1828 int start,
1829 int *end)
1830{
1831 int i;
1832 DBUS_CONST_STRING_PREAMBLE (str);
1833 _dbus_assert (start <= real->len);
1834 _dbus_assert (start >= 0);
1835
1836 i = start;
1837 while (i < real->len)
1838 {
1839 if (!DBUS_IS_ASCII_BLANK (real->str[i]))
1840 break;
1841
1842 ++i;
1843 }
1844
1845 _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
1846
1847 if (end)
1848 *end = i;
1849}
1850
1851
1860 void
1861_dbus_string_skip_white (const DBusString *str,
1862 int start,
1863 int *end)
1864{
1865 int i;
1866 DBUS_CONST_STRING_PREAMBLE (str);
1867 _dbus_assert (start <= real->len);
1868 _dbus_assert (start >= 0);
1869
1870 i = start;
1871 while (i < real->len)
1872 {
1873 if (!DBUS_IS_ASCII_WHITE (real->str[i]))
1874 break;
1875
1876 ++i;
1877 }
1878
1879 _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
1880
1881 if (end)
1882 *end = i;
1883}
1884
1893 void
1894_dbus_string_skip_white_reverse (const DBusString *str,
1895 int end,
1896 int *start)
1897{
1898 int i;
1899 DBUS_CONST_STRING_PREAMBLE (str);
1900 _dbus_assert (end <= real->len);
1901 _dbus_assert (end >= 0);
1902
1903 i = end;
1904 while (i > 0)
1905 {
1906 if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
1907 break;
1908 --i;
1909 }
1910
1911 _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
1912
1913 if (start)
1914 *start = i;
1915}
1916
1932 dbus_bool_t
1933_dbus_string_pop_line (DBusString *source,
1934 DBusString *dest)
1935{
1936 int eol, eol_len;
1937
1938 _dbus_string_set_length (dest, 0);
1939
1940 eol = 0;
1941 eol_len = 0;
1942 if (!_dbus_string_find_eol (source, 0, &eol, &eol_len))
1943 {
1944 _dbus_assert (eol == _dbus_string_get_length (source));
1945 if (eol == 0)
1946 {
1947 /* If there's no newline and source has zero length, we're done */
1948 return FALSE;
1949 }
1950 /* otherwise, the last line of the file has no eol characters */
1951 }
1952
1953 /* remember eol can be 0 if it's an empty line, but eol_len should not be zero also
1954 * since find_eol returned TRUE
1955 */
1956
1957 if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0))
1958 return FALSE;
1959
1960 /* remove line ending */
1961 if (!_dbus_string_set_length (dest, eol))
1962 {
1963 _dbus_assert_not_reached ("out of memory when shortening a string");
1964 return FALSE;
1965 }
1966
1967 return TRUE;
1968}
1969
1970#ifdef DBUS_ENABLE_EMBEDDED_TESTS
1977 void
1978_dbus_string_delete_first_word (DBusString *str)
1979{
1980 int i;
1981
1982 if (_dbus_string_find_blank (str, 0, &i))
1983 _dbus_string_skip_blank (str, i, &i);
1984
1985 _dbus_string_delete (str, 0, i);
1986}
1987#endif
1988
1989#ifdef DBUS_ENABLE_EMBEDDED_TESTS
1995 void
1996_dbus_string_delete_leading_blanks (DBusString *str)
1997{
1998 int i;
1999
2000 _dbus_string_skip_blank (str, 0, &i);
2001
2002 if (i > 0)
2003 _dbus_string_delete (str, 0, i);
2004}
2005#endif
2006
2012 void
2013_dbus_string_chop_white(DBusString *str)
2014{
2015 int i;
2016
2017 _dbus_string_skip_white (str, 0, &i);
2018
2019 if (i > 0)
2020 _dbus_string_delete (str, 0, i);
2021
2022 _dbus_string_skip_white_reverse (str, _dbus_string_get_length (str), &i);
2023
2024 _dbus_string_set_length (str, i);
2025}
2026
2036 dbus_bool_t
2037_dbus_string_equal (const DBusString *a,
2038 const DBusString *b)
2039{
2040 const unsigned char *ap;
2041 const unsigned char *bp;
2042 const unsigned char *a_end;
2043 const DBusRealString *real_a = (const DBusRealString*) a;
2044 const DBusRealString *real_b = (const DBusRealString*) b;
2045 DBUS_GENERIC_STRING_PREAMBLE (real_a);
2046 DBUS_GENERIC_STRING_PREAMBLE (real_b);
2047
2048 if (real_a->len != real_b->len)
2049 return FALSE;
2050
2051 ap = real_a->str;
2052 bp = real_b->str;
2053 a_end = real_a->str + real_a->len;
2054 while (ap != a_end)
2055 {
2056 if (*ap != *bp)
2057 return FALSE;
2058
2059 ++ap;
2060 ++bp;
2061 }
2062
2063 return TRUE;
2064}
2065
2079 dbus_bool_t
2080_dbus_string_equal_len (const DBusString *a,
2081 const DBusString *b,
2082 int len)
2083{
2084 const unsigned char *ap;
2085 const unsigned char *bp;
2086 const unsigned char *a_end;
2087 const DBusRealString *real_a = (const DBusRealString*) a;
2088 const DBusRealString *real_b = (const DBusRealString*) b;
2089 DBUS_GENERIC_STRING_PREAMBLE (real_a);
2090 DBUS_GENERIC_STRING_PREAMBLE (real_b);
2091
2092 if (real_a->len != real_b->len &&
2093 (real_a->len < len || real_b->len < len))
2094 return FALSE;
2095
2096 ap = real_a->str;
2097 bp = real_b->str;
2098 a_end = real_a->str + MIN (real_a->len, len);
2099 while (ap != a_end)
2100 {
2101 if (*ap != *bp)
2102 return FALSE;
2103
2104 ++ap;
2105 ++bp;
2106 }
2107
2108 return TRUE;
2109}
2110
2127 dbus_bool_t
2128_dbus_string_equal_substring (const DBusString *a,
2129 int a_start,
2130 int a_len,
2131 const DBusString *b,
2132 int b_start)
2133{
2134 const unsigned char *ap;
2135 const unsigned char *bp;
2136 const unsigned char *a_end;
2137 const DBusRealString *real_a = (const DBusRealString*) a;
2138 const DBusRealString *real_b = (const DBusRealString*) b;
2139 DBUS_GENERIC_STRING_PREAMBLE (real_a);
2140 DBUS_GENERIC_STRING_PREAMBLE (real_b);
2141 _dbus_assert (a_start >= 0);
2142 _dbus_assert (a_len >= 0);
2143 _dbus_assert (a_start <= real_a->len);
2144 _dbus_assert (a_len <= real_a->len - a_start);
2145 _dbus_assert (b_start >= 0);
2146 _dbus_assert (b_start <= real_b->len);
2147
2148 if (a_len > real_b->len - b_start)
2149 return FALSE;
2150
2151 ap = real_a->str + a_start;
2152 bp = real_b->str + b_start;
2153 a_end = ap + a_len;
2154 while (ap != a_end)
2155 {
2156 if (*ap != *bp)
2157 return FALSE;
2158
2159 ++ap;
2160 ++bp;
2161 }
2162
2163 _dbus_assert (bp <= (real_b->str + real_b->len));
2164
2165 return TRUE;
2166}
2167
2175 dbus_bool_t
2176_dbus_string_equal_c_str (const DBusString *a,
2177 const char *c_str)
2178{
2179 const unsigned char *ap;
2180 const unsigned char *bp;
2181 const unsigned char *a_end;
2182 const DBusRealString *real_a = (const DBusRealString*) a;
2183 DBUS_GENERIC_STRING_PREAMBLE (real_a);
2184 _dbus_assert (c_str != NULL);
2185
2186 ap = real_a->str;
2187 bp = (const unsigned char*) c_str;
2188 a_end = real_a->str + real_a->len;
2189 while (ap != a_end && *bp)
2190 {
2191 if (*ap != *bp)
2192 return FALSE;
2193
2194 ++ap;
2195 ++bp;
2196 }
2197
2198 if (ap != a_end || *bp)
2199 return FALSE;
2200
2201 return TRUE;
2202}
2203
2211 dbus_bool_t
2212_dbus_string_starts_with_c_str (const DBusString *a,
2213 const char *c_str)
2214{
2215 const unsigned char *ap;
2216 const unsigned char *bp;
2217 const unsigned char *a_end;
2218 const DBusRealString *real_a = (const DBusRealString*) a;
2219 DBUS_GENERIC_STRING_PREAMBLE (real_a);
2220 _dbus_assert (c_str != NULL);
2221
2222 ap = real_a->str;
2223 bp = (const unsigned char*) c_str;
2224 a_end = real_a->str + real_a->len;
2225 while (ap != a_end && *bp)
2226 {
2227 if (*ap != *bp)
2228 return FALSE;
2229
2230 ++ap;
2231 ++bp;
2232 }
2233
2234 if (*bp == '\0')
2235 return TRUE;
2236 else
2237 return FALSE;
2238}
2239
2249 dbus_bool_t
2250_dbus_string_starts_with_words_c_str (const DBusString *a,
2251 const char *c_str,
2252 char word_separator)
2253{
2254 char next_char;
2255 const char *data;
2256 _dbus_assert (c_str != NULL);
2257
2258 if (!_dbus_string_starts_with_c_str (a, c_str))
2259 return FALSE;
2260
2261 data = _dbus_string_get_const_data (a);
2262 next_char = data[strlen (c_str)];
2263 return next_char == '\0' || next_char == word_separator;
2264}
2265
2274 dbus_bool_t
2275_dbus_string_append_byte_as_hex (DBusString *str,
2276 unsigned char byte)
2277{
2278 const char hexdigits[16] = {
2279 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
2280 'a', 'b', 'c', 'd', 'e', 'f'
2281 };
2282
2283 if (!_dbus_string_append_byte (str,
2284 hexdigits[(byte >> 4)]))
2285 return FALSE;
2286
2287 if (!_dbus_string_append_byte (str,
2288 hexdigits[(byte & 0x0f)]))
2289 {
2290 _dbus_string_set_length (str,
2291 _dbus_string_get_length (str) - 1);
2292 return FALSE;
2293 }
2294
2295 return TRUE;
2296}
2297
2308 dbus_bool_t
2309_dbus_string_hex_encode (const DBusString *source,
2310 int start,
2311 DBusString *dest,
2312 int insert_at)
2313{
2314 DBusString result;
2315 const unsigned char *p;
2316 const unsigned char *end;
2317 dbus_bool_t retval;
2318
2319 _dbus_assert (start <= _dbus_string_get_length (source));
2320
2321 if (!_dbus_string_init (&result))
2322 return FALSE;
2323
2324 retval = FALSE;
2325
2326 p = (const unsigned char*) _dbus_string_get_const_data (source);
2327 end = p + _dbus_string_get_length (source);
2328 p += start;
2329
2330 while (p != end)
2331 {
2332 if (!_dbus_string_append_byte_as_hex (&result, *p))
2333 goto out;
2334
2335 ++p;
2336 }
2337
2338 if (!_dbus_string_move (&result, 0, dest, insert_at))
2339 goto out;
2340
2341 retval = TRUE;
2342
2343 out:
2344 _dbus_string_free (&result);
2345 return retval;
2346}
2347
2358 dbus_bool_t
2359_dbus_string_hex_decode (const DBusString *source,
2360 int start,
2361 int *end_return,
2362 DBusString *dest,
2363 int insert_at)
2364{
2365 DBusString result;
2366 const unsigned char *p;
2367 const unsigned char *end;
2368 dbus_bool_t retval;
2369 dbus_bool_t high_bits;
2370
2371 _dbus_assert (start <= _dbus_string_get_length (source));
2372
2373 if (!_dbus_string_init (&result))
2374 return FALSE;
2375
2376 retval = FALSE;
2377
2378 high_bits = TRUE;
2379 p = (const unsigned char*) _dbus_string_get_const_data (source);
2380 end = p + _dbus_string_get_length (source);
2381 p += start;
2382
2383 while (p != end)
2384 {
2385 unsigned int val;
2386
2387 switch (*p)
2388 {
2389 case '0':
2390 val = 0;
2391 break;
2392 case '1':
2393 val = 1;
2394 break;
2395 case '2':
2396 val = 2;
2397 break;
2398 case '3':
2399 val = 3;
2400 break;
2401 case '4':
2402 val = 4;
2403 break;
2404 case '5':
2405 val = 5;
2406 break;
2407 case '6':
2408 val = 6;
2409 break;
2410 case '7':
2411 val = 7;
2412 break;
2413 case '8':
2414 val = 8;
2415 break;
2416 case '9':
2417 val = 9;
2418 break;
2419 case 'a':
2420 case 'A':
2421 val = 10;
2422 break;
2423 case 'b':
2424 case 'B':
2425 val = 11;
2426 break;
2427 case 'c':
2428 case 'C':
2429 val = 12;
2430 break;
2431 case 'd':
2432 case 'D':
2433 val = 13;
2434 break;
2435 case 'e':
2436 case 'E':
2437 val = 14;
2438 break;
2439 case 'f':
2440 case 'F':
2441 val = 15;
2442 break;
2443 default:
2444 goto done;
2445 }
2446
2447 if (high_bits)
2448 {
2449 if (!_dbus_string_append_byte (&result,
2450 val << 4))
2451 goto out;
2452 }
2453 else
2454 {
2455 int len;
2456 unsigned char b;
2457
2458 len = _dbus_string_get_length (&result);
2459
2460 b = _dbus_string_get_byte (&result, len - 1);
2461
2462 b |= val;
2463
2464 _dbus_string_set_byte (&result, len - 1, b);
2465 }
2466
2467 high_bits = !high_bits;
2468
2469 ++p;
2470 }
2471
2472 done:
2473 if (!_dbus_string_move (&result, 0, dest, insert_at))
2474 goto out;
2475
2476 if (end_return)
2477 *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
2478
2479 retval = TRUE;
2480
2481 out:
2482 _dbus_string_free (&result);
2483 return retval;
2484}
2485
2499 dbus_bool_t
2500_dbus_string_validate_ascii (const DBusString *str,
2501 int start,
2502 int len)
2503{
2504 const unsigned char *s;
2505 const unsigned char *end;
2506 DBUS_CONST_STRING_PREAMBLE (str);
2507 _dbus_assert (start >= 0);
2508 _dbus_assert (start <= real->len);
2509 _dbus_assert (len >= 0);
2510
2511 if (len > real->len - start)
2512 return FALSE;
2513
2514 s = real->str + start;
2515 end = s + len;
2516 while (s != end)
2517 {
2518 if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
2519 return FALSE;
2520
2521 ++s;
2522 }
2523
2524 return TRUE;
2525}
2526
2534 void
2535_dbus_string_tolower_ascii (const DBusString *str,
2536 int start,
2537 int len)
2538{
2539 unsigned char *s;
2540 unsigned char *end;
2541 DBUS_STRING_PREAMBLE (str);
2542 _dbus_assert (start >= 0);
2543 _dbus_assert (start <= real->len);
2544 _dbus_assert (len >= 0);
2545 _dbus_assert (len <= real->len - start);
2546
2547 s = real->str + start;
2548 end = s + len;
2549
2550 while (s != end)
2551 {
2552 if (*s >= 'A' && *s <= 'Z')
2553 *s += 'a' - 'A';
2554 ++s;
2555 }
2556}
2557
2565 void
2566_dbus_string_toupper_ascii (const DBusString *str,
2567 int start,
2568 int len)
2569{
2570 unsigned char *s;
2571 unsigned char *end;
2572 DBUS_STRING_PREAMBLE (str);
2573 _dbus_assert (start >= 0);
2574 _dbus_assert (start <= real->len);
2575 _dbus_assert (len >= 0);
2576 _dbus_assert (len <= real->len - start);
2577
2578 s = real->str + start;
2579 end = s + len;
2580
2581 while (s != end)
2582 {
2583 if (*s >= 'a' && *s <= 'z')
2584 *s += 'A' - 'a';
2585 ++s;
2586 }
2587}
2588
2604 dbus_bool_t
2605_dbus_string_validate_utf8 (const DBusString *str,
2606 int start,
2607 int len)
2608{
2609 const unsigned char *p;
2610 const unsigned char *end;
2611 DBUS_CONST_STRING_PREAMBLE (str);
2612 _dbus_assert (start >= 0);
2613 _dbus_assert (start <= real->len);
2614 _dbus_assert (len >= 0);
2615
2616 /* we are doing _DBUS_UNLIKELY() here which might be
2617 * dubious in a generic library like GLib, but in D-Bus
2618 * we know we're validating messages and that it would
2619 * only be evil/broken apps that would have invalid
2620 * UTF-8. Also, this function seems to be a performance
2621 * bottleneck in profiles.
2622 */
2623
2624 if (_DBUS_UNLIKELY (len > real->len - start))
2625 return FALSE;
2626
2627 p = real->str + start;
2628 end = p + len;
2629
2630 while (p < end)
2631 {
2632 int i, mask, char_len;
2633 dbus_unichar_t result;
2634
2635 /* nul bytes considered invalid */
2636 if (*p == '\0')
2637 break;
2638
2639 /* Special-case ASCII; this makes us go a lot faster in
2640 * D-Bus profiles where we are typically validating
2641 * function names and such. We have to know that
2642 * all following checks will pass for ASCII though,
2643 * comments follow ...
2644 */
2645 if (*p < 128)
2646 {
2647 ++p;
2648 continue;
2649 }
2650
2651 UTF8_COMPUTE (*p, mask, char_len);
2652
2653 if (_DBUS_UNLIKELY (char_len == 0)) /* ASCII: char_len == 1 */
2654 break;
2655
2656 /* check that the expected number of bytes exists in the remaining length */
2657 if (_DBUS_UNLIKELY ((end - p) < char_len)) /* ASCII: p < end and char_len == 1 */
2658 break;
2659
2660 UTF8_GET (result, p, i, mask, char_len);
2661
2662 /* Check for overlong UTF-8 */
2663 if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* ASCII: UTF8_LENGTH == 1 */
2664 break;
2665#if 0
2666 /* The UNICODE_VALID check below will catch this */
2667 if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) /* ASCII: result = ascii value */
2668 break;
2669#endif
2670
2671 if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) /* ASCII: always valid */
2672 break;
2673
2674 /* UNICODE_VALID should have caught it */
2675 _dbus_assert (result != (dbus_unichar_t)-1);
2676
2677 p += char_len;
2678 }
2679
2680 /* See that we covered the entire length if a length was
2681 * passed in
2682 */
2683 if (_DBUS_UNLIKELY (p != end))
2684 return FALSE;
2685 else
2686 return TRUE;
2687}
2688
2702 dbus_bool_t
2703_dbus_string_validate_nul (const DBusString *str,
2704 int start,
2705 int len)
2706{
2707 const unsigned char *s;
2708 const unsigned char *end;
2709 DBUS_CONST_STRING_PREAMBLE (str);
2710 _dbus_assert (start >= 0);
2711 _dbus_assert (len >= 0);
2712 _dbus_assert (start <= real->len);
2713
2714 if (len > real->len - start)
2715 return FALSE;
2716
2717 s = real->str + start;
2718 end = s + len;
2719 while (s != end)
2720 {
2721 if (_DBUS_UNLIKELY (*s != '\0'))
2722 return FALSE;
2723 ++s;
2724 }
2725
2726 return TRUE;
2727}
2728
2734 void
2735_dbus_string_zero (DBusString *str)
2736{
2737 DBUS_STRING_PREAMBLE (str);
2738
2739 memset (real->str - real->align_offset, '\0', real->allocated);
2740}
2743/* tests are in dbus-string-util.c */
_dbus_assert_not_reached
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
Definition: dbus-internals.h:164
_dbus_assert
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
Definition: dbus-internals.h:153
NULL
#define NULL
A null pointer, defined appropriately for C or C++.
TRUE
#define TRUE
Expands to "1".
FALSE
#define FALSE
Expands to "0".
dbus_free
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:704
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:604
dbus_malloc
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:464
_DBUS_STRING_MAX_LENGTH
#define _DBUS_STRING_MAX_LENGTH
The maximum length of a DBusString.
Definition: dbus-string-private.h:69
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_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_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_IS_ASCII_BLANK
#define DBUS_IS_ASCII_BLANK(c)
Checks for ASCII blank byte.
Definition: dbus-string-private.h:121
DBUS_IS_ASCII_WHITE
#define DBUS_IS_ASCII_WHITE(c)
Checks for ASCII whitespace byte.
Definition: dbus-string-private.h:127
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:826
_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:2359
_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:959
_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:1044
_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:2703
_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:2128
UNICODE_VALID
#define UNICODE_VALID(Char)
Check whether a Unicode (5.2) char is in a valid range.
Definition: dbus-string.c:1609
_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:1072
UTF8_COMPUTE
#define UTF8_COMPUTE(Char, Mask, Len)
computes length and mask of a unicode character
Definition: dbus-string.c:1529
_dbus_string_init
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:182
_dbus_string_init_const
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:197
_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:1307
_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:1651
ASSIGN_2_OCTETS
#define ASSIGN_2_OCTETS(p, octets)
assign 2 bytes from one string to another
Definition: dbus-string.c:975
_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:2212
_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:923
_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:665
_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:1827
_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:139
_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:1894
_dbus_string_init_from_string
dbus_bool_t _dbus_string_init_from_string(DBusString *str, const DBusString *from)
Initializes a string from another string.
Definition: dbus-string.c:252
_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:1491
_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:1628
_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:514
_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:2605
_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:1789
_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:217
_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:2535
_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:1161
_dbus_string_free
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init(), and fills it with the same contents as #_DBUS_STRING_I...
Definition: dbus-string.c:271
_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:804
_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:1217
_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:696
_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:2176
_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:1861
_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:1933
_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:1096
_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:784
_dbus_string_zero
void _dbus_string_zero(DBusString *str)
Clears all allocated bytes in the string to zero.
Definition: dbus-string.c:2735
UTF8_LENGTH
#define UTF8_LENGTH(Char)
computes length of a unicode character in UTF-8
Definition: dbus-string.c:1570
_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:2566
_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:608
_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:2500
_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:1181
_dbus_string_chop_white
void _dbus_string_chop_white(DBusString *str)
Deletes leading and trailing whitespace.
Definition: dbus-string.c:2013
_dbus_string_starts_with_words_c_str
dbus_bool_t _dbus_string_starts_with_words_c_str(const DBusString *a, const char *c_str, char word_separator)
Checks whether a string starts with the given C string, after which it ends or is separated from the ...
Definition: dbus-string.c:2250
_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:2309
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:1259
_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:1138
_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:638
UTF8_GET
#define UTF8_GET(Result, Chars, Count, Mask, Len)
Gets a UTF-8 value.
Definition: dbus-string.c:1586
_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:1332
_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:743
_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:413
_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:2080
ASSIGN_8_OCTETS
#define ASSIGN_8_OCTETS(p, octets)
assign 8 bytes from one string to another
Definition: dbus-string.c:983
_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:1283
_dbus_string_equal
dbus_bool_t _dbus_string_equal(const DBusString *a, const DBusString *b)
Tests two DBusString for equality.
Definition: dbus-string.c:2037
_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:1020
_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:996
ASSIGN_4_OCTETS
#define ASSIGN_4_OCTETS(p, octets)
assign 4 bytes from one string to another
Definition: dbus-string.c:979
_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:2275
_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:907
_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:1721
_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:1399
_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:721
_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:1428
_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:3798
dbus_bool_t
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
DBusRealString
Internals of DBusString.
Definition: dbus-string-private.h:44
DBusRealString::align_offset
unsigned int align_offset
str - align_offset is the actual malloc block
Definition: dbus-string-private.h:51
DBusRealString::valid
unsigned int valid
DBusString is valid (initialized and not freed)
Definition: dbus-string-private.h:50
DBusRealString::constant
unsigned int constant
String data is not owned by DBusString.
Definition: dbus-string-private.h:48
DBusRealString::locked
unsigned int locked
DBusString has been locked and can't be changed.
Definition: dbus-string-private.h:49
DBusRealString::str
unsigned char * str
String data, plus nul termination.
Definition: dbus-string-private.h:45
DBusRealString::allocated
int allocated
Allocated size of data.
Definition: dbus-string-private.h:47
DBusRealString::len
int len
Length without nul.
Definition: dbus-string-private.h:46
DBusString
Definition: dbus-string.h:43