Merge "Optional autogen.sh flag --enable-kdbus-transport added allowing to compile...
[platform/upstream/dbus.git] / dbus / 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
40 /**
41  * @defgroup DBusString DBusString class
42  * @ingroup  DBusInternals
43  * @brief DBusString data structure for safer string handling
44  *
45  * Types and functions related to DBusString. DBusString is intended
46  * to be a string class that makes it hard to mess up security issues
47  * (and just in general harder to write buggy code).  It should be
48  * used (or extended and then used) rather than the libc stuff in
49  * string.h.  The string class is a bit inconvenient at spots because
50  * it handles out-of-memory failures and tries to be extra-robust.
51  * 
52  * A DBusString has a maximum length set at initialization time; this
53  * can be used to ensure that a buffer doesn't get too big.  The
54  * _dbus_string_lengthen() method checks for overflow, and for max
55  * length being exceeded.
56  * 
57  * Try to avoid conversion to a plain C string, i.e. add methods on
58  * the string object instead, only convert to C string when passing
59  * things out to the public API. In particular, no sprintf, strcpy,
60  * strcat, any of that should be used. The GString feature of
61  * accepting negative numbers for "length of string" is also absent,
62  * because it could keep us from detecting bogus huge lengths. i.e. if
63  * we passed in some bogus huge length it would be taken to mean
64  * "current length of string" instead of "broken crack"
65  *
66  * @todo #DBusString needs a lot of cleaning up; some of the
67  * API is no longer used, and the API is pretty inconsistent.
68  * In particular all the "append" APIs, especially those involving
69  * alignment but probably lots of them, are no longer used by the
70  * marshaling code which always does "inserts" now.
71  */
72
73 /**
74  * @addtogroup DBusString
75  * @{
76  */
77
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
122 /**
123  * Initializes a string that can be up to the given allocation size
124  * before it has to realloc. The string starts life with zero length.
125  * The string must eventually be freed with _dbus_string_free().
126  * 
127  * @param str memory to hold the string
128  * @param allocate_size amount to preallocate
129  * @returns #TRUE on success, #FALSE if no memory
130  */
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
167 /**
168  * Initializes a string. The string starts life with zero length.  The
169  * string must eventually be freed with _dbus_string_free().
170  * 
171  * @param str memory to hold the string
172  * @returns #TRUE on success, #FALSE if no memory
173  */
174 dbus_bool_t
175 _dbus_string_init (DBusString *str)
176 {
177   return _dbus_string_init_preallocated (str, 0);
178 }
179
180 /**
181  * Initializes a constant string. The value parameter is not copied
182  * (should be static), and the string may never be modified.
183  * It is safe but not necessary to call _dbus_string_free()
184  * on a const string. The string has a length limit of MAXINT - 8.
185  * 
186  * @param str memory to use for the string
187  * @param value a string to be stored in str (not copied!!!)
188  */
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
199 /**
200  * Initializes a constant string with a length. The value parameter is
201  * not copied (should be static), and the string may never be
202  * modified.  It is safe but not necessary to call _dbus_string_free()
203  * on a const string.
204  * 
205  * @param str memory to use for the string
206  * @param value a string to be stored in str (not copied!!!)
207  * @param len the length to use
208  */
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
236 /**
237  * Frees a string created by _dbus_string_init().
238  *
239  * @param str memory where the string is stored.
240  */
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  */
292 /**
293  * Locks a string such that any attempts to change the string will
294  * result in aborting the program. Also, if the string is wasting a
295  * lot of memory (allocation is sufficiently larger than what the
296  * string is really using), _dbus_string_lock() will realloc the
297  * string's data to "compact" it.
298  *
299  * @param str the string to lock.
300  */
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
360 /**
361  * Compacts the string to avoid wasted memory.  Wasted memory is
362  * memory that is allocated but not actually required to store the
363  * current length of the string.  The compact is only done if more
364  * than the given amount of memory is being wasted (otherwise the
365  * waste is ignored and the call does nothing).
366  *
367  * @param str the string
368  * @param max_waste the maximum amount of waste to ignore
369  * @returns #FALSE if the compact failed due to realloc failure
370  */
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 /**
423  * Gets the raw character buffer from the string.  The returned buffer
424  * will be nul-terminated, but note that strings may contain binary
425  * data so there may be extra nul characters prior to the termination.
426  * This function should be little-used, extend DBusString or add
427  * stuff to dbus-sysdeps.c instead. It's an error to use this
428  * function on a const string.
429  *
430  * @param str the string
431  * @returns the data
432  */
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 /**
445  * Gets the raw character buffer from a const string.
446  *
447  * @param str the string
448  * @returns the string data
449  */
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
459 /**
460  * Gets a sub-portion of the raw character buffer from the
461  * string. The "len" field is required simply for error
462  * checking, to be sure you don't try to use more
463  * string than exists. The nul termination of the
464  * returned buffer remains at the end of the entire
465  * string, not at start + len.
466  *
467  * @param str the string
468  * @param start byte offset to return
469  * @param len length of segment to return
470  * @returns the string data
471  */
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 /**
489  * const version of _dbus_string_get_data_len().
490  *
491  * @param str the string
492  * @param start byte offset to return
493  * @param len length of segment to return
494  * @returns the string data
495  */
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 /**
514  * Sets the value of the byte at the given position.
515  *
516  * @param str the string
517  * @param i the position
518  * @param byte the new value
519  */
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 /**
536  * Gets the byte at the given position. It is
537  * allowed to ask for the nul byte at the end of
538  * the string.
539  *
540  * @param str the string
541  * @param start the position
542  * @returns the byte at that position
543  */
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
556 /**
557  * Inserts a number of bytes of a given value at the
558  * given position.
559  *
560  * @param str the string
561  * @param i the position
562  * @param n_bytes number of bytes
563  * @param byte the value to insert
564  * @returns #TRUE on success
565  */
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
588 /**
589  * Inserts a single byte at the given position.
590  *
591  * @param str the string
592  * @param i the position
593  * @param byte the value to insert
594  * @returns #TRUE on success
595  */
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
613 /**
614  * Like _dbus_string_get_data(), but removes the
615  * gotten data from the original string. The caller
616  * must free the data returned. This function may
617  * fail due to lack of memory, and return #FALSE.
618  *
619  * @param str the string
620  * @param data_return location to return the buffer
621  * @returns #TRUE on success
622  */
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
647 /**
648  * Copies the data from the string into a char*
649  *
650  * @param str the string
651  * @param data_return place to return the data
652  * @returns #TRUE on success, #FALSE on no memory
653  */
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
670 /**
671  * Copies the contents of a DBusString into a different buffer. It is
672  * a bug if avail_len is too short to hold the string contents. nul
673  * termination is not copied, just the supplied bytes.
674  * 
675  * @param str a string
676  * @param buffer a C buffer to copy data to
677  * @param avail_len maximum length of C buffer
678  */
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
692 /**
693  * Copies the contents of a DBusString into a different buffer. It is
694  * a bug if avail_len is too short to hold the string contents plus a
695  * nul byte. 
696  * 
697  * @param str a string
698  * @param buffer a C buffer to copy data to
699  * @param avail_len maximum length of C buffer
700  */
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 /**
717  * Gets the length of a string (not including nul termination).
718  *
719  * @returns the length.
720  */
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
730 /**
731  * Makes a string longer by the given number of bytes.  Checks whether
732  * adding additional_length to the current length would overflow an
733  * integer, and checks for exceeding a string's max length.
734  * The new bytes are not initialized, other than nul-terminating
735  * the end of the string. The uninitialized bytes may contain
736  * nul bytes or other junk.
737  *
738  * @param str a string
739  * @param additional_length length to add to the string.
740  * @returns #TRUE on success.
741  */
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
756 /**
757  * Makes a string shorter by the given number of bytes.
758  *
759  * @param str a string
760  * @param length_to_remove length to remove from the string.
761  */
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
774 /**
775  * Sets the length of a string. Can be used to truncate or lengthen
776  * the string. If the string is lengthened, the function may fail and
777  * return #FALSE. Newly-added bytes are not initialized, as with
778  * _dbus_string_lengthen().
779  *
780  * @param str a string
781  * @param length new length of the string.
782  * @returns #FALSE on failure.
783  */
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
857 /**
858  * Align the length of a string to a specific alignment (typically 4 or 8)
859  * by appending nul bytes to the string.
860  *
861  * @param str a string
862  * @param alignment the alignment
863  * @returns #FALSE if no memory
864  */
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
872 /**
873  * Preallocate extra_bytes such that a future lengthening of the
874  * string by extra_bytes is guaranteed to succeed without an out of
875  * memory error.
876  *
877  * @param str a string
878  * @param extra_bytes bytes to alloc
879  * @returns #FALSE if no memory
880  */
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
910 /**
911  * Appends a nul-terminated C-style string to a DBusString.
912  *
913  * @param str the DBusString
914  * @param buffer the nul-terminated characters to append
915  * @returns #FALSE if not enough memory.
916  */
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
933 /** assign 2 bytes from one string to another */
934 #define ASSIGN_2_OCTETS(p, octets) \
935   *((dbus_uint16_t*)(p)) = *((dbus_uint16_t*)(octets));
936
937 /** assign 4 bytes from one string to another */
938 #define ASSIGN_4_OCTETS(p, octets) \
939   *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
940
941 #ifdef DBUS_HAVE_INT64
942 /** assign 8 bytes from one string to another */
943 #define ASSIGN_8_OCTETS(p, octets) \
944   *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
945 #else
946 /** assign 8 bytes from one string to another */
947 #define ASSIGN_8_OCTETS(p, octets)              \
948 do {                                            \
949   unsigned char *b;                             \
950                                                 \
951   b = p;                                        \
952                                                 \
953   *b++ = octets[0];                             \
954   *b++ = octets[1];                             \
955   *b++ = octets[2];                             \
956   *b++ = octets[3];                             \
957   *b++ = octets[4];                             \
958   *b++ = octets[5];                             \
959   *b++ = octets[6];                             \
960   *b++ = octets[7];                             \
961   _dbus_assert (b == p + 8);                    \
962 } while (0)
963 #endif /* DBUS_HAVE_INT64 */
964
965 /**
966  * Inserts 2 bytes aligned on a 2 byte boundary
967  * with any alignment padding initialized to 0.
968  *
969  * @param str the DBusString
970  * @param insert_at where to insert
971  * @param octets 2 bytes to insert
972  * @returns #FALSE if not enough memory.
973  */
974 dbus_bool_t
975 _dbus_string_insert_2_aligned (DBusString         *str,
976                                int                 insert_at,
977                                const unsigned char octets[2])
978 {
979   DBUS_STRING_PREAMBLE (str);
980   
981   if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2))
982     return FALSE;
983
984   ASSIGN_2_OCTETS (real->str + insert_at, octets);
985
986   return TRUE;
987 }
988
989 /**
990  * Inserts 4 bytes aligned on a 4 byte boundary
991  * with any alignment padding initialized to 0.
992  *
993  * @param str the DBusString
994  * @param insert_at where to insert
995  * @param octets 4 bytes to insert
996  * @returns #FALSE if not enough memory.
997  */
998 dbus_bool_t
999 _dbus_string_insert_4_aligned (DBusString         *str,
1000                                int                 insert_at,
1001                                const unsigned char octets[4])
1002 {
1003   DBUS_STRING_PREAMBLE (str);
1004   
1005   if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
1006     return FALSE;
1007
1008   ASSIGN_4_OCTETS (real->str + insert_at, octets);
1009
1010   return TRUE;
1011 }
1012
1013 /**
1014  * Inserts 8 bytes aligned on an 8 byte boundary
1015  * with any alignment padding initialized to 0.
1016  *
1017  * @param str the DBusString
1018  * @param insert_at where to insert
1019  * @param octets 8 bytes to insert
1020  * @returns #FALSE if not enough memory.
1021  */
1022 dbus_bool_t
1023 _dbus_string_insert_8_aligned (DBusString         *str,
1024                                int                 insert_at,
1025                                const unsigned char octets[8])
1026 {
1027   DBUS_STRING_PREAMBLE (str);
1028   
1029   if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
1030     return FALSE;
1031
1032   _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
1033   
1034   ASSIGN_8_OCTETS (real->str + insert_at, octets);
1035
1036   return TRUE;
1037 }
1038
1039
1040 /**
1041  * Inserts padding at *insert_at such to align it to the given
1042  * boundary. Initializes the padding to nul bytes. Sets *insert_at
1043  * to the aligned position.
1044  *
1045  * @param str the DBusString
1046  * @param insert_at location to be aligned
1047  * @param alignment alignment boundary (1, 2, 4, or 8)
1048  * @returns #FALSE if not enough memory.
1049  */
1050 dbus_bool_t
1051 _dbus_string_insert_alignment (DBusString        *str,
1052                                int               *insert_at,
1053                                int                alignment)
1054 {
1055   DBUS_STRING_PREAMBLE (str);
1056   
1057   if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0))
1058     return FALSE;
1059
1060   _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at);
1061
1062   return TRUE;
1063 }
1064
1065 /**
1066  * Appends a printf-style formatted string
1067  * to the #DBusString.
1068  *
1069  * @param str the string
1070  * @param format printf format
1071  * @param args variable argument list
1072  * @returns #FALSE if no memory
1073  */
1074 dbus_bool_t
1075 _dbus_string_append_printf_valist  (DBusString        *str,
1076                                     const char        *format,
1077                                     va_list            args)
1078 {
1079   int len;
1080   va_list args_copy;
1081
1082   DBUS_STRING_PREAMBLE (str);
1083
1084   DBUS_VA_COPY (args_copy, args);
1085
1086   /* Measure the message length without terminating nul */
1087   len = _dbus_printf_string_upper_bound (format, args);
1088
1089   if (len < 0)
1090     return FALSE;
1091
1092   if (!_dbus_string_lengthen (str, len))
1093     {
1094       /* don't leak the copy */
1095       va_end (args_copy);
1096       return FALSE;
1097     }
1098   
1099   vsprintf ((char*) (real->str + (real->len - len)),
1100             format, args_copy);
1101
1102   va_end (args_copy);
1103
1104   return TRUE;
1105 }
1106
1107 /**
1108  * Appends a printf-style formatted string
1109  * to the #DBusString.
1110  *
1111  * @param str the string
1112  * @param format printf format
1113  * @returns #FALSE if no memory
1114  */
1115 dbus_bool_t
1116 _dbus_string_append_printf (DBusString        *str,
1117                             const char        *format,
1118                             ...)
1119 {
1120   va_list args;
1121   dbus_bool_t retval;
1122   
1123   va_start (args, format);
1124   retval = _dbus_string_append_printf_valist (str, format, args);
1125   va_end (args);
1126
1127   return retval;
1128 }
1129
1130 /**
1131  * Appends block of bytes with the given length to a DBusString.
1132  *
1133  * @param str the DBusString
1134  * @param buffer the bytes to append
1135  * @param len the number of bytes to append
1136  * @returns #FALSE if not enough memory.
1137  */
1138 dbus_bool_t
1139 _dbus_string_append_len (DBusString *str,
1140                          const char *buffer,
1141                          int         len)
1142 {
1143   DBUS_STRING_PREAMBLE (str);
1144   _dbus_assert (buffer != NULL);
1145   _dbus_assert (len >= 0);
1146
1147   return append (real, buffer, len);
1148 }
1149
1150 /**
1151  * Appends a single byte to the string, returning #FALSE
1152  * if not enough memory.
1153  *
1154  * @param str the string
1155  * @param byte the byte to append
1156  * @returns #TRUE on success
1157  */
1158 dbus_bool_t
1159 _dbus_string_append_byte (DBusString    *str,
1160                           unsigned char  byte)
1161 {
1162   DBUS_STRING_PREAMBLE (str);
1163
1164   if (!set_length (real, real->len + 1))
1165     return FALSE;
1166
1167   real->str[real->len-1] = byte;
1168
1169   return TRUE;
1170 }
1171
1172 static void
1173 delete (DBusRealString *real,
1174         int             start,
1175         int             len)
1176 {
1177   if (len == 0)
1178     return;
1179   
1180   memmove (real->str + start, real->str + start + len, real->len - (start + len));
1181   real->len -= len;
1182   real->str[real->len] = '\0';
1183 }
1184
1185 /**
1186  * Deletes a segment of a DBusString with length len starting at
1187  * start. (Hint: to clear an entire string, setting length to 0
1188  * with _dbus_string_set_length() is easier.)
1189  *
1190  * @param str the DBusString
1191  * @param start where to start deleting
1192  * @param len the number of bytes to delete
1193  */
1194 void
1195 _dbus_string_delete (DBusString       *str,
1196                      int               start,
1197                      int               len)
1198 {
1199   DBUS_STRING_PREAMBLE (str);
1200   _dbus_assert (start >= 0);
1201   _dbus_assert (len >= 0);
1202   _dbus_assert (start <= real->len);
1203   _dbus_assert (len <= real->len - start);
1204   
1205   delete (real, start, len);
1206 }
1207
1208 static dbus_bool_t
1209 copy (DBusRealString *source,
1210       int             start,
1211       int             len,
1212       DBusRealString *dest,
1213       int             insert_at)
1214 {
1215   if (len == 0)
1216     return TRUE;
1217
1218   if (!open_gap (len, dest, insert_at))
1219     return FALSE;
1220   
1221   memmove (dest->str + insert_at,
1222            source->str + start,
1223            len);
1224
1225   return TRUE;
1226 }
1227
1228 /**
1229  * Checks assertions for two strings we're copying a segment between,
1230  * and declares real_source/real_dest variables.
1231  *
1232  * @param source the source string
1233  * @param start the starting offset
1234  * @param dest the dest string
1235  * @param insert_at where the copied segment is inserted
1236  */
1237 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at)       \
1238   DBusRealString *real_source = (DBusRealString*) source;               \
1239   DBusRealString *real_dest = (DBusRealString*) dest;                   \
1240   _dbus_assert ((source) != (dest));                                    \
1241   DBUS_GENERIC_STRING_PREAMBLE (real_source);                           \
1242   DBUS_GENERIC_STRING_PREAMBLE (real_dest);                             \
1243   _dbus_assert (!real_dest->constant);                                  \
1244   _dbus_assert (!real_dest->locked);                                    \
1245   _dbus_assert ((start) >= 0);                                          \
1246   _dbus_assert ((start) <= real_source->len);                           \
1247   _dbus_assert ((insert_at) >= 0);                                      \
1248   _dbus_assert ((insert_at) <= real_dest->len)
1249
1250 /**
1251  * Moves the end of one string into another string. Both strings
1252  * must be initialized, valid strings.
1253  *
1254  * @param source the source string
1255  * @param start where to chop off the source string
1256  * @param dest the destination string
1257  * @param insert_at where to move the chopped-off part of source string
1258  * @returns #FALSE if not enough memory
1259  */
1260 dbus_bool_t
1261 _dbus_string_move (DBusString       *source,
1262                    int               start,
1263                    DBusString       *dest,
1264                    int               insert_at)
1265 {
1266   DBusRealString *real_source = (DBusRealString*) source;
1267   _dbus_assert (start <= real_source->len);
1268   
1269   return _dbus_string_move_len (source, start,
1270                                 real_source->len - start,
1271                                 dest, insert_at);
1272 }
1273
1274 /**
1275  * Like _dbus_string_move(), but does not delete the section
1276  * of the source string that's copied to the dest string.
1277  *
1278  * @param source the source string
1279  * @param start where to start copying the source string
1280  * @param dest the destination string
1281  * @param insert_at where to place the copied part of source string
1282  * @returns #FALSE if not enough memory
1283  */
1284 dbus_bool_t
1285 _dbus_string_copy (const DBusString *source,
1286                    int               start,
1287                    DBusString       *dest,
1288                    int               insert_at)
1289 {
1290   DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1291
1292   return copy (real_source, start,
1293                real_source->len - start,
1294                real_dest,
1295                insert_at);
1296 }
1297
1298 /**
1299  * Like _dbus_string_move(), but can move a segment from
1300  * the middle of the source string.
1301  *
1302  * @param source the source string
1303  * @param start first byte of source string to move
1304  * @param len length of segment to move
1305  * @param dest the destination string
1306  * @param insert_at where to move the bytes from the source string
1307  * @returns #FALSE if not enough memory
1308  */
1309 dbus_bool_t
1310 _dbus_string_move_len (DBusString       *source,
1311                        int               start,
1312                        int               len,
1313                        DBusString       *dest,
1314                        int               insert_at)
1315
1316 {
1317   DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1318   _dbus_assert (len >= 0);
1319   _dbus_assert ((start + len) <= real_source->len);
1320
1321
1322   if (len == 0)
1323     {
1324       return TRUE;
1325     }
1326   else if (start == 0 &&
1327            len == real_source->len &&
1328            real_dest->len == 0)
1329     {
1330       /* Short-circuit moving an entire existing string to an empty string
1331        * by just swapping the buffers.
1332        */
1333       /* we assume ->constant doesn't matter as you can't have
1334        * a constant string involved in a move.
1335        */
1336 #define ASSIGN_DATA(a, b) do {                  \
1337         (a)->str = (b)->str;                    \
1338         (a)->len = (b)->len;                    \
1339         (a)->allocated = (b)->allocated;        \
1340         (a)->align_offset = (b)->align_offset;  \
1341       } while (0)
1342       
1343       DBusRealString tmp;
1344
1345       ASSIGN_DATA (&tmp, real_source);
1346       ASSIGN_DATA (real_source, real_dest);
1347       ASSIGN_DATA (real_dest, &tmp);
1348
1349       return TRUE;
1350     }
1351   else
1352     {
1353       if (!copy (real_source, start, len,
1354                  real_dest,
1355                  insert_at))
1356         return FALSE;
1357       
1358       delete (real_source, start,
1359               len);
1360       
1361       return TRUE;
1362     }
1363 }
1364
1365 /**
1366  * Like _dbus_string_copy(), but can copy a segment from the middle of
1367  * the source string.
1368  *
1369  * @param source the source string
1370  * @param start where to start copying the source string
1371  * @param len length of segment to copy
1372  * @param dest the destination string
1373  * @param insert_at where to place the copied segment of source string
1374  * @returns #FALSE if not enough memory
1375  */
1376 dbus_bool_t
1377 _dbus_string_copy_len (const DBusString *source,
1378                        int               start,
1379                        int               len,
1380                        DBusString       *dest,
1381                        int               insert_at)
1382 {
1383   DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1384   _dbus_assert (len >= 0);
1385   _dbus_assert (start <= real_source->len);
1386   _dbus_assert (len <= real_source->len - start);
1387   
1388   return copy (real_source, start, len,
1389                real_dest,
1390                insert_at);
1391 }
1392
1393 /**
1394  * Replaces a segment of dest string with a segment of source string.
1395  *
1396  * @param source the source string
1397  * @param start where to start copying the source string
1398  * @param len length of segment to copy
1399  * @param dest the destination string
1400  * @param replace_at start of segment of dest string to replace
1401  * @param replace_len length of segment of dest string to replace
1402  * @returns #FALSE if not enough memory
1403  *
1404  */
1405 dbus_bool_t
1406 _dbus_string_replace_len (const DBusString *source,
1407                           int               start,
1408                           int               len,
1409                           DBusString       *dest,
1410                           int               replace_at,
1411                           int               replace_len)
1412 {
1413   DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
1414   _dbus_assert (len >= 0);
1415   _dbus_assert (start <= real_source->len);
1416   _dbus_assert (len <= real_source->len - start);
1417   _dbus_assert (replace_at >= 0);
1418   _dbus_assert (replace_at <= real_dest->len);
1419   _dbus_assert (replace_len <= real_dest->len - replace_at);
1420
1421   if (len == replace_len)
1422     {
1423       memmove (real_dest->str + replace_at,
1424                real_source->str + start, len);
1425     }
1426   else if (len < replace_len)
1427     {
1428       memmove (real_dest->str + replace_at,
1429                real_source->str + start, len);
1430       delete (real_dest, replace_at + len,
1431               replace_len - len);
1432     }
1433   else
1434     {
1435       int diff;
1436
1437       _dbus_assert (len > replace_len);
1438
1439       diff = len - replace_len;
1440
1441       /* First of all we check if destination string can be enlarged as
1442        * required, then we overwrite previous bytes
1443        */
1444
1445       if (!copy (real_source, start + replace_len, diff,
1446                  real_dest, replace_at + replace_len))
1447         return FALSE;
1448
1449       memmove (real_dest->str + replace_at,
1450                real_source->str + start, replace_len);
1451     }
1452
1453   return TRUE;
1454 }
1455
1456 /**
1457  * Looks for the first occurance of a byte, deletes that byte,
1458  * and moves everything after the byte to the beginning of a
1459  * separate string.  Both strings must be initialized, valid
1460  * strings.
1461  *
1462  * @param source the source string
1463  * @param byte the byte to remove and split the string at
1464  * @param tail the split off string
1465  * @returns #FALSE if not enough memory or if byte could not be found
1466  *
1467  */
1468 dbus_bool_t
1469 _dbus_string_split_on_byte (DBusString        *source,
1470                             unsigned char      byte,
1471                             DBusString        *tail)
1472 {
1473   int byte_position;
1474   char byte_string[2] = "";
1475   int head_length;
1476   int tail_length;
1477
1478   byte_string[0] = (char) byte;
1479
1480   if (!_dbus_string_find (source, 0, byte_string, &byte_position))
1481     return FALSE;
1482
1483   head_length = byte_position;
1484   tail_length = _dbus_string_get_length (source) - head_length - 1;
1485
1486   if (!_dbus_string_move_len (source, byte_position + 1, tail_length,
1487                               tail, 0))
1488     return FALSE;
1489
1490   /* remove the trailing delimiter byte from the head now.
1491    */
1492   if (!_dbus_string_set_length (source, head_length))
1493     return FALSE;
1494
1495   return TRUE;
1496 }
1497
1498 /* Unicode macros and utf8_validate() from GLib Owen Taylor, Havoc
1499  * Pennington, and Tom Tromey are the authors and authorized relicense.
1500  */
1501
1502 /** computes length and mask of a unicode character
1503  * @param Char the char
1504  * @param Mask the mask variable to assign to
1505  * @param Len the length variable to assign to
1506  */
1507 #define UTF8_COMPUTE(Char, Mask, Len)                                         \
1508   if (Char < 128)                                                             \
1509     {                                                                         \
1510       Len = 1;                                                                \
1511       Mask = 0x7f;                                                            \
1512     }                                                                         \
1513   else if ((Char & 0xe0) == 0xc0)                                             \
1514     {                                                                         \
1515       Len = 2;                                                                \
1516       Mask = 0x1f;                                                            \
1517     }                                                                         \
1518   else if ((Char & 0xf0) == 0xe0)                                             \
1519     {                                                                         \
1520       Len = 3;                                                                \
1521       Mask = 0x0f;                                                            \
1522     }                                                                         \
1523   else if ((Char & 0xf8) == 0xf0)                                             \
1524     {                                                                         \
1525       Len = 4;                                                                \
1526       Mask = 0x07;                                                            \
1527     }                                                                         \
1528   else if ((Char & 0xfc) == 0xf8)                                             \
1529     {                                                                         \
1530       Len = 5;                                                                \
1531       Mask = 0x03;                                                            \
1532     }                                                                         \
1533   else if ((Char & 0xfe) == 0xfc)                                             \
1534     {                                                                         \
1535       Len = 6;                                                                \
1536       Mask = 0x01;                                                            \
1537     }                                                                         \
1538   else                                                                        \
1539     {                                                                         \
1540       Len = 0;                                                               \
1541       Mask = 0;                                                               \
1542     }
1543
1544 /**
1545  * computes length of a unicode character in UTF-8
1546  * @param Char the char
1547  */
1548 #define UTF8_LENGTH(Char)              \
1549   ((Char) < 0x80 ? 1 :                 \
1550    ((Char) < 0x800 ? 2 :               \
1551     ((Char) < 0x10000 ? 3 :            \
1552      ((Char) < 0x200000 ? 4 :          \
1553       ((Char) < 0x4000000 ? 5 : 6)))))
1554    
1555 /**
1556  * Gets a UTF-8 value.
1557  *
1558  * @param Result variable for extracted unicode char.
1559  * @param Chars the bytes to decode
1560  * @param Count counter variable
1561  * @param Mask mask for this char
1562  * @param Len length for this char in bytes
1563  */
1564 #define UTF8_GET(Result, Chars, Count, Mask, Len)                             \
1565   (Result) = (Chars)[0] & (Mask);                                             \
1566   for ((Count) = 1; (Count) < (Len); ++(Count))                               \
1567     {                                                                         \
1568       if (((Chars)[(Count)] & 0xc0) != 0x80)                                  \
1569         {                                                                     \
1570           (Result) = -1;                                                      \
1571           break;                                                              \
1572         }                                                                     \
1573       (Result) <<= 6;                                                         \
1574       (Result) |= ((Chars)[(Count)] & 0x3f);                                  \
1575     }
1576
1577 /**
1578  * Check whether a Unicode (5.2) char is in a valid range.
1579  *
1580  * The first check comes from the Unicode guarantee to never encode
1581  * a point above 0x0010ffff, since UTF-16 couldn't represent it.
1582  *
1583  * The second check covers surrogate pairs (category Cs).
1584  *
1585  * @param Char the character
1586  */
1587 #define UNICODE_VALID(Char)                   \
1588     ((Char) < 0x110000 &&                     \
1589      (((Char) & 0xFFFFF800) != 0xD800))
1590
1591 /**
1592  * Finds the given substring in the string,
1593  * returning #TRUE and filling in the byte index
1594  * where the substring was found, if it was found.
1595  * Returns #FALSE if the substring wasn't found.
1596  * Sets *start to the length of the string if the substring
1597  * is not found.
1598  *
1599  * @param str the string
1600  * @param start where to start looking
1601  * @param substr the substring
1602  * @param found return location for where it was found, or #NULL
1603  * @returns #TRUE if found
1604  */
1605 dbus_bool_t
1606 _dbus_string_find (const DBusString *str,
1607                    int               start,
1608                    const char       *substr,
1609                    int              *found)
1610 {
1611   return _dbus_string_find_to (str, start,
1612                                ((const DBusRealString*)str)->len,
1613                                substr, found);
1614 }
1615
1616 /**
1617  * Finds end of line ("\r\n" or "\n") in the string,
1618  * returning #TRUE and filling in the byte index
1619  * where the eol string was found, if it was found.
1620  * Returns #FALSE if eol wasn't found.
1621  *
1622  * @param str the string
1623  * @param start where to start looking
1624  * @param found return location for where eol was found or string length otherwise
1625  * @param found_len return length of found eol string or zero otherwise
1626  * @returns #TRUE if found
1627  */
1628 dbus_bool_t
1629 _dbus_string_find_eol (const DBusString *str,
1630                        int               start,
1631                        int              *found,
1632                        int              *found_len)
1633 {
1634   int i;
1635
1636   DBUS_CONST_STRING_PREAMBLE (str);
1637   _dbus_assert (start <= real->len);
1638   _dbus_assert (start >= 0);
1639   
1640   i = start;
1641   while (i < real->len)
1642     {
1643       if (real->str[i] == '\r') 
1644         {
1645           if ((i+1) < real->len && real->str[i+1] == '\n') /* "\r\n" */
1646             {
1647               if (found) 
1648                 *found = i;
1649               if (found_len)
1650                 *found_len = 2;
1651               return TRUE;
1652             } 
1653           else /* only "\r" */
1654             {
1655               if (found) 
1656                 *found = i;
1657               if (found_len)
1658                 *found_len = 1;
1659               return TRUE;
1660             }
1661         } 
1662       else if (real->str[i] == '\n')  /* only "\n" */
1663         {
1664           if (found) 
1665             *found = i;
1666           if (found_len)
1667             *found_len = 1;
1668           return TRUE;
1669         }
1670       ++i;
1671     }
1672
1673   if (found)
1674     *found = real->len;
1675
1676   if (found_len)
1677     *found_len = 0;
1678   
1679   return FALSE;
1680 }
1681
1682 /**
1683  * Finds the given substring in the string,
1684  * up to a certain position,
1685  * returning #TRUE and filling in the byte index
1686  * where the substring was found, if it was found.
1687  * Returns #FALSE if the substring wasn't found.
1688  * Sets *start to the length of the string if the substring
1689  * is not found.
1690  *
1691  * @param str the string
1692  * @param start where to start looking
1693  * @param end where to stop looking
1694  * @param substr the substring
1695  * @param found return location for where it was found, or #NULL
1696  * @returns #TRUE if found
1697  */
1698 dbus_bool_t
1699 _dbus_string_find_to (const DBusString *str,
1700                       int               start,
1701                       int               end,
1702                       const char       *substr,
1703                       int              *found)
1704 {
1705   int i;
1706   DBUS_CONST_STRING_PREAMBLE (str);
1707   _dbus_assert (substr != NULL);
1708   _dbus_assert (start <= real->len);
1709   _dbus_assert (start >= 0);
1710   _dbus_assert (substr != NULL);
1711   _dbus_assert (end <= real->len);
1712   _dbus_assert (start <= end);
1713
1714   /* we always "find" an empty string */
1715   if (*substr == '\0')
1716     {
1717       if (found)
1718         *found = start;
1719       return TRUE;
1720     }
1721
1722   i = start;
1723   while (i < end)
1724     {
1725       if (real->str[i] == substr[0])
1726         {
1727           int j = i + 1;
1728           
1729           while (j < end)
1730             {
1731               if (substr[j - i] == '\0')
1732                 break;
1733               else if (real->str[j] != substr[j - i])
1734                 break;
1735               
1736               ++j;
1737             }
1738
1739           if (substr[j - i] == '\0')
1740             {
1741               if (found)
1742                 *found = i;
1743               return TRUE;
1744             }
1745         }
1746       
1747       ++i;
1748     }
1749
1750   if (found)
1751     *found = end;
1752   
1753   return FALSE;  
1754 }
1755
1756 /**
1757  * Finds a blank (space or tab) in the string. Returns #TRUE
1758  * if found, #FALSE otherwise. If a blank is not found sets
1759  * *found to the length of the string.
1760  *
1761  * @param str the string
1762  * @param start byte index to start looking
1763  * @param found place to store the location of the first blank
1764  * @returns #TRUE if a blank was found
1765  */
1766 dbus_bool_t
1767 _dbus_string_find_blank (const DBusString *str,
1768                          int               start,
1769                          int              *found)
1770 {
1771   int i;
1772   DBUS_CONST_STRING_PREAMBLE (str);
1773   _dbus_assert (start <= real->len);
1774   _dbus_assert (start >= 0);
1775   
1776   i = start;
1777   while (i < real->len)
1778     {
1779       if (real->str[i] == ' ' ||
1780           real->str[i] == '\t')
1781         {
1782           if (found)
1783             *found = i;
1784           return TRUE;
1785         }
1786       
1787       ++i;
1788     }
1789
1790   if (found)
1791     *found = real->len;
1792   
1793   return FALSE;
1794 }
1795
1796 /**
1797  * Skips blanks from start, storing the first non-blank in *end
1798  * (blank is space or tab).
1799  *
1800  * @param str the string
1801  * @param start where to start
1802  * @param end where to store the first non-blank byte index
1803  */
1804 void
1805 _dbus_string_skip_blank (const DBusString *str,
1806                          int               start,
1807                          int              *end)
1808 {
1809   int i;
1810   DBUS_CONST_STRING_PREAMBLE (str);
1811   _dbus_assert (start <= real->len);
1812   _dbus_assert (start >= 0);
1813   
1814   i = start;
1815   while (i < real->len)
1816     {
1817       if (!DBUS_IS_ASCII_BLANK (real->str[i]))
1818         break;
1819       
1820       ++i;
1821     }
1822
1823   _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
1824   
1825   if (end)
1826     *end = i;
1827 }
1828
1829
1830 /**
1831  * Skips whitespace from start, storing the first non-whitespace in *end.
1832  * (whitespace is space, tab, newline, CR).
1833  *
1834  * @param str the string
1835  * @param start where to start
1836  * @param end where to store the first non-whitespace byte index
1837  */
1838 void
1839 _dbus_string_skip_white (const DBusString *str,
1840                          int               start,
1841                          int              *end)
1842 {
1843   int i;
1844   DBUS_CONST_STRING_PREAMBLE (str);
1845   _dbus_assert (start <= real->len);
1846   _dbus_assert (start >= 0);
1847   
1848   i = start;
1849   while (i < real->len)
1850     {
1851       if (!DBUS_IS_ASCII_WHITE (real->str[i]))
1852         break;
1853       
1854       ++i;
1855     }
1856
1857   _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
1858   
1859   if (end)
1860     *end = i;
1861 }
1862
1863 /**
1864  * Skips whitespace from end, storing the start index of the trailing
1865  * whitespace in *start. (whitespace is space, tab, newline, CR).
1866  *
1867  * @param str the string
1868  * @param end where to start scanning backward
1869  * @param start where to store the start of whitespace chars
1870  */
1871 void
1872 _dbus_string_skip_white_reverse (const DBusString *str,
1873                                  int               end,
1874                                  int              *start)
1875 {
1876   int i;
1877   DBUS_CONST_STRING_PREAMBLE (str);
1878   _dbus_assert (end <= real->len);
1879   _dbus_assert (end >= 0);
1880   
1881   i = end;
1882   while (i > 0)
1883     {
1884       if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
1885         break;
1886       --i;
1887     }
1888
1889   _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
1890   
1891   if (start)
1892     *start = i;
1893 }
1894
1895 /**
1896  * Assigns a newline-terminated or \\r\\n-terminated line from the front
1897  * of the string to the given dest string. The dest string's previous
1898  * contents are deleted. If the source string contains no newline,
1899  * moves the entire source string to the dest string.
1900  *
1901  * @todo owen correctly notes that this is a stupid function (it was
1902  * written purely for test code,
1903  * e.g. dbus-message-builder.c). Probably should be enforced as test
1904  * code only with ifdef DBUS_ENABLE_EMBEDDED_TESTS
1905  * 
1906  * @param source the source string
1907  * @param dest the destination string (contents are replaced)
1908  * @returns #FALSE if no memory, or source has length 0
1909  */
1910 dbus_bool_t
1911 _dbus_string_pop_line (DBusString *source,
1912                        DBusString *dest)
1913 {
1914   int eol, eol_len;
1915   
1916   _dbus_string_set_length (dest, 0);
1917   
1918   eol = 0;
1919   eol_len = 0;
1920   if (!_dbus_string_find_eol (source, 0, &eol, &eol_len))
1921     {
1922       _dbus_assert (eol == _dbus_string_get_length (source));
1923       if (eol == 0)
1924         {
1925           /* If there's no newline and source has zero length, we're done */
1926           return FALSE;
1927         }
1928       /* otherwise, the last line of the file has no eol characters */
1929     }
1930
1931   /* remember eol can be 0 if it's an empty line, but eol_len should not be zero also
1932    * since find_eol returned TRUE
1933    */
1934   
1935   if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0))
1936     return FALSE;
1937   
1938   /* remove line ending */
1939   if (!_dbus_string_set_length (dest, eol))
1940     {
1941       _dbus_assert_not_reached ("out of memory when shortening a string");
1942       return FALSE;
1943     }
1944
1945   return TRUE;
1946 }
1947
1948 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1949 /**
1950  * Deletes up to and including the first blank space
1951  * in the string.
1952  *
1953  * @param str the string
1954  */
1955 void
1956 _dbus_string_delete_first_word (DBusString *str)
1957 {
1958   int i;
1959   
1960   if (_dbus_string_find_blank (str, 0, &i))
1961     _dbus_string_skip_blank (str, i, &i);
1962
1963   _dbus_string_delete (str, 0, i);
1964 }
1965 #endif
1966
1967 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
1968 /**
1969  * Deletes any leading blanks in the string
1970  *
1971  * @param str the string
1972  */
1973 void
1974 _dbus_string_delete_leading_blanks (DBusString *str)
1975 {
1976   int i;
1977   
1978   _dbus_string_skip_blank (str, 0, &i);
1979
1980   if (i > 0)
1981     _dbus_string_delete (str, 0, i);
1982 }
1983 #endif
1984
1985 /**
1986  * Deletes leading and trailing whitespace
1987  * 
1988  * @param str the string
1989  */
1990 void
1991 _dbus_string_chop_white(DBusString *str)
1992 {
1993   int i;
1994   
1995   _dbus_string_skip_white (str, 0, &i);
1996
1997   if (i > 0)
1998     _dbus_string_delete (str, 0, i);
1999   
2000   _dbus_string_skip_white_reverse (str, _dbus_string_get_length (str), &i);
2001
2002   _dbus_string_set_length (str, i);
2003 }
2004
2005 /**
2006  * Tests two DBusString for equality.
2007  *
2008  * @todo memcmp is probably faster
2009  *
2010  * @param a first string
2011  * @param b second string
2012  * @returns #TRUE if equal
2013  */
2014 dbus_bool_t
2015 _dbus_string_equal (const DBusString *a,
2016                     const DBusString *b)
2017 {
2018   const unsigned char *ap;
2019   const unsigned char *bp;
2020   const unsigned char *a_end;
2021   const DBusRealString *real_a = (const DBusRealString*) a;
2022   const DBusRealString *real_b = (const DBusRealString*) b;
2023   DBUS_GENERIC_STRING_PREAMBLE (real_a);
2024   DBUS_GENERIC_STRING_PREAMBLE (real_b);
2025
2026   if (real_a->len != real_b->len)
2027     return FALSE;
2028
2029   ap = real_a->str;
2030   bp = real_b->str;
2031   a_end = real_a->str + real_a->len;
2032   while (ap != a_end)
2033     {
2034       if (*ap != *bp)
2035         return FALSE;
2036       
2037       ++ap;
2038       ++bp;
2039     }
2040
2041   return TRUE;
2042 }
2043
2044 /**
2045  * Tests two DBusString for equality up to the given length.
2046  * The strings may be shorter than the given length.
2047  *
2048  * @todo write a unit test
2049  *
2050  * @todo memcmp is probably faster
2051  *
2052  * @param a first string
2053  * @param b second string
2054  * @param len the maximum length to look at
2055  * @returns #TRUE if equal for the given number of bytes
2056  */
2057 dbus_bool_t
2058 _dbus_string_equal_len (const DBusString *a,
2059                         const DBusString *b,
2060                         int               len)
2061 {
2062   const unsigned char *ap;
2063   const unsigned char *bp;
2064   const unsigned char *a_end;
2065   const DBusRealString *real_a = (const DBusRealString*) a;
2066   const DBusRealString *real_b = (const DBusRealString*) b;
2067   DBUS_GENERIC_STRING_PREAMBLE (real_a);
2068   DBUS_GENERIC_STRING_PREAMBLE (real_b);
2069
2070   if (real_a->len != real_b->len &&
2071       (real_a->len < len || real_b->len < len))
2072     return FALSE;
2073
2074   ap = real_a->str;
2075   bp = real_b->str;
2076   a_end = real_a->str + MIN (real_a->len, len);
2077   while (ap != a_end)
2078     {
2079       if (*ap != *bp)
2080         return FALSE;
2081       
2082       ++ap;
2083       ++bp;
2084     }
2085
2086   return TRUE;
2087 }
2088
2089 /**
2090  * Tests two sub-parts of two DBusString for equality.  The specified
2091  * range of the first string must exist; the specified start position
2092  * of the second string must exist.
2093  *
2094  * @todo write a unit test
2095  *
2096  * @todo memcmp is probably faster
2097  *
2098  * @param a first string
2099  * @param a_start where to start substring in first string
2100  * @param a_len length of substring in first string
2101  * @param b second string
2102  * @param b_start where to start substring in second string
2103  * @returns #TRUE if the two substrings are equal
2104  */
2105 dbus_bool_t
2106 _dbus_string_equal_substring (const DBusString  *a,
2107                               int                a_start,
2108                               int                a_len,
2109                               const DBusString  *b,
2110                               int                b_start)
2111 {
2112   const unsigned char *ap;
2113   const unsigned char *bp;
2114   const unsigned char *a_end;
2115   const DBusRealString *real_a = (const DBusRealString*) a;
2116   const DBusRealString *real_b = (const DBusRealString*) b;
2117   DBUS_GENERIC_STRING_PREAMBLE (real_a);
2118   DBUS_GENERIC_STRING_PREAMBLE (real_b);
2119   _dbus_assert (a_start >= 0);
2120   _dbus_assert (a_len >= 0);
2121   _dbus_assert (a_start <= real_a->len);
2122   _dbus_assert (a_len <= real_a->len - a_start);
2123   _dbus_assert (b_start >= 0);
2124   _dbus_assert (b_start <= real_b->len);
2125   
2126   if (a_len > real_b->len - b_start)
2127     return FALSE;
2128
2129   ap = real_a->str + a_start;
2130   bp = real_b->str + b_start;
2131   a_end = ap + a_len;
2132   while (ap != a_end)
2133     {
2134       if (*ap != *bp)
2135         return FALSE;
2136       
2137       ++ap;
2138       ++bp;
2139     }
2140
2141   _dbus_assert (bp <= (real_b->str + real_b->len));
2142   
2143   return TRUE;
2144 }
2145
2146 /**
2147  * Checks whether a string is equal to a C string.
2148  *
2149  * @param a the string
2150  * @param c_str the C string
2151  * @returns #TRUE if equal
2152  */
2153 dbus_bool_t
2154 _dbus_string_equal_c_str (const DBusString *a,
2155                           const char       *c_str)
2156 {
2157   const unsigned char *ap;
2158   const unsigned char *bp;
2159   const unsigned char *a_end;
2160   const DBusRealString *real_a = (const DBusRealString*) a;
2161   DBUS_GENERIC_STRING_PREAMBLE (real_a);
2162   _dbus_assert (c_str != NULL);
2163   
2164   ap = real_a->str;
2165   bp = (const unsigned char*) c_str;
2166   a_end = real_a->str + real_a->len;
2167   while (ap != a_end && *bp)
2168     {
2169       if (*ap != *bp)
2170         return FALSE;
2171       
2172       ++ap;
2173       ++bp;
2174     }
2175
2176   if (ap != a_end || *bp)
2177     return FALSE;
2178   
2179   return TRUE;
2180 }
2181
2182 /**
2183  * Checks whether a string starts with the given C string.
2184  *
2185  * @param a the string
2186  * @param c_str the C string
2187  * @returns #TRUE if string starts with it
2188  */
2189 dbus_bool_t
2190 _dbus_string_starts_with_c_str (const DBusString *a,
2191                                 const char       *c_str)
2192 {
2193   const unsigned char *ap;
2194   const unsigned char *bp;
2195   const unsigned char *a_end;
2196   const DBusRealString *real_a = (const DBusRealString*) a;
2197   DBUS_GENERIC_STRING_PREAMBLE (real_a);
2198   _dbus_assert (c_str != NULL);
2199   
2200   ap = real_a->str;
2201   bp = (const unsigned char*) c_str;
2202   a_end = real_a->str + real_a->len;
2203   while (ap != a_end && *bp)
2204     {
2205       if (*ap != *bp)
2206         return FALSE;
2207       
2208       ++ap;
2209       ++bp;
2210     }
2211
2212   if (*bp == '\0')
2213     return TRUE;
2214   else
2215     return FALSE;
2216 }
2217
2218 /**
2219  * Appends a two-character hex digit to a string, where the hex digit
2220  * has the value of the given byte.
2221  *
2222  * @param str the string
2223  * @param byte the byte
2224  * @returns #FALSE if no memory
2225  */
2226 dbus_bool_t
2227 _dbus_string_append_byte_as_hex (DBusString *str,
2228                                  unsigned char byte)
2229 {
2230   const char hexdigits[16] = {
2231     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
2232     'a', 'b', 'c', 'd', 'e', 'f'
2233   };
2234
2235   if (!_dbus_string_append_byte (str,
2236                                  hexdigits[(byte >> 4)]))
2237     return FALSE;
2238   
2239   if (!_dbus_string_append_byte (str,
2240                                  hexdigits[(byte & 0x0f)]))
2241     {
2242       _dbus_string_set_length (str,
2243                                _dbus_string_get_length (str) - 1);
2244       return FALSE;
2245     }
2246
2247   return TRUE;
2248 }
2249
2250 /**
2251  * Encodes a string in hex, the way MD5 and SHA-1 are usually
2252  * encoded. (Each byte is two hex digits.)
2253  *
2254  * @param source the string to encode
2255  * @param start byte index to start encoding
2256  * @param dest string where encoded data should be placed
2257  * @param insert_at where to place encoded data
2258  * @returns #TRUE if encoding was successful, #FALSE if no memory etc.
2259  */
2260 dbus_bool_t
2261 _dbus_string_hex_encode (const DBusString *source,
2262                          int               start,
2263                          DBusString       *dest,
2264                          int               insert_at)
2265 {
2266   DBusString result;
2267   const unsigned char *p;
2268   const unsigned char *end;
2269   dbus_bool_t retval;
2270   
2271   _dbus_assert (start <= _dbus_string_get_length (source));
2272
2273   if (!_dbus_string_init (&result))
2274     return FALSE;
2275
2276   retval = FALSE;
2277   
2278   p = (const unsigned char*) _dbus_string_get_const_data (source);
2279   end = p + _dbus_string_get_length (source);
2280   p += start;
2281   
2282   while (p != end)
2283     {
2284       if (!_dbus_string_append_byte_as_hex (&result, *p))
2285         goto out;
2286       
2287       ++p;
2288     }
2289
2290   if (!_dbus_string_move (&result, 0, dest, insert_at))
2291     goto out;
2292
2293   retval = TRUE;
2294
2295  out:
2296   _dbus_string_free (&result);
2297   return retval;
2298 }
2299
2300 /**
2301  * Decodes a string from hex encoding.
2302  *
2303  * @param source the string to decode
2304  * @param start byte index to start decode
2305  * @param end_return return location of the end of the hex data, or #NULL
2306  * @param dest string where decoded data should be placed
2307  * @param insert_at where to place decoded data
2308  * @returns #TRUE if decoding was successful, #FALSE if no memory.
2309  */
2310 dbus_bool_t
2311 _dbus_string_hex_decode (const DBusString *source,
2312                          int               start,
2313                          int              *end_return,
2314                          DBusString       *dest,
2315                          int               insert_at)
2316 {
2317   DBusString result;
2318   const unsigned char *p;
2319   const unsigned char *end;
2320   dbus_bool_t retval;
2321   dbus_bool_t high_bits;
2322   
2323   _dbus_assert (start <= _dbus_string_get_length (source));
2324
2325   if (!_dbus_string_init (&result))
2326     return FALSE;
2327
2328   retval = FALSE;
2329
2330   high_bits = TRUE;
2331   p = (const unsigned char*) _dbus_string_get_const_data (source);
2332   end = p + _dbus_string_get_length (source);
2333   p += start;
2334   
2335   while (p != end)
2336     {
2337       unsigned int val;
2338
2339       switch (*p)
2340         {
2341         case '0':
2342           val = 0;
2343           break;
2344         case '1':
2345           val = 1;
2346           break;
2347         case '2':
2348           val = 2;
2349           break;
2350         case '3':
2351           val = 3;
2352           break;
2353         case '4':
2354           val = 4;
2355           break;
2356         case '5':
2357           val = 5;
2358           break;
2359         case '6':
2360           val = 6;
2361           break;
2362         case '7':
2363           val = 7;
2364           break;
2365         case '8':
2366           val = 8;
2367           break;
2368         case '9':
2369           val = 9;
2370           break;
2371         case 'a':
2372         case 'A':
2373           val = 10;
2374           break;
2375         case 'b':
2376         case 'B':
2377           val = 11;
2378           break;
2379         case 'c':
2380         case 'C':
2381           val = 12;
2382           break;
2383         case 'd':
2384         case 'D':
2385           val = 13;
2386           break;
2387         case 'e':
2388         case 'E':
2389           val = 14;
2390           break;
2391         case 'f':
2392         case 'F':
2393           val = 15;
2394           break;
2395         default:
2396           goto done;
2397         }
2398
2399       if (high_bits)
2400         {
2401           if (!_dbus_string_append_byte (&result,
2402                                          val << 4))
2403             goto out;
2404         }
2405       else
2406         {
2407           int len;
2408           unsigned char b;
2409
2410           len = _dbus_string_get_length (&result);
2411           
2412           b = _dbus_string_get_byte (&result, len - 1);
2413
2414           b |= val;
2415
2416           _dbus_string_set_byte (&result, len - 1, b);
2417         }
2418
2419       high_bits = !high_bits;
2420
2421       ++p;
2422     }
2423
2424  done:
2425   if (!_dbus_string_move (&result, 0, dest, insert_at))
2426     goto out;
2427
2428   if (end_return)
2429     *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
2430
2431   retval = TRUE;
2432   
2433  out:
2434   _dbus_string_free (&result);  
2435   return retval;
2436 }
2437
2438 /**
2439  * Checks that the given range of the string is valid ASCII with no
2440  * nul bytes. If the given range is not entirely contained in the
2441  * string, returns #FALSE.
2442  *
2443  * @todo this is inconsistent with most of DBusString in that
2444  * it allows a start,len range that extends past the string end.
2445  * 
2446  * @param str the string
2447  * @param start first byte index to check
2448  * @param len number of bytes to check
2449  * @returns #TRUE if the byte range exists and is all valid ASCII
2450  */
2451 dbus_bool_t
2452 _dbus_string_validate_ascii (const DBusString *str,
2453                              int               start,
2454                              int               len)
2455 {
2456   const unsigned char *s;
2457   const unsigned char *end;
2458   DBUS_CONST_STRING_PREAMBLE (str);
2459   _dbus_assert (start >= 0);
2460   _dbus_assert (start <= real->len);
2461   _dbus_assert (len >= 0);
2462   
2463   if (len > real->len - start)
2464     return FALSE;
2465   
2466   s = real->str + start;
2467   end = s + len;
2468   while (s != end)
2469     {
2470       if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
2471         return FALSE;
2472         
2473       ++s;
2474     }
2475   
2476   return TRUE;
2477 }
2478
2479 /**
2480  * Converts the given range of the string to lower case.
2481  *
2482  * @param str the string
2483  * @param start first byte index to convert
2484  * @param len number of bytes to convert
2485  */
2486 void
2487 _dbus_string_tolower_ascii (const DBusString *str,
2488                             int               start,
2489                             int               len)
2490 {
2491   unsigned char *s;
2492   unsigned char *end;
2493   DBUS_STRING_PREAMBLE (str);
2494   _dbus_assert (start >= 0);
2495   _dbus_assert (start <= real->len);
2496   _dbus_assert (len >= 0);
2497   _dbus_assert (len <= real->len - start);
2498
2499   s = real->str + start;
2500   end = s + len;
2501
2502   while (s != end)
2503     {
2504       if (*s >= 'A' && *s <= 'Z')
2505           *s += 'a' - 'A';
2506       ++s;
2507     }
2508 }
2509
2510 /**
2511  * Converts the given range of the string to upper case.
2512  *
2513  * @param str the string
2514  * @param start first byte index to convert
2515  * @param len number of bytes to convert
2516  */
2517 void
2518 _dbus_string_toupper_ascii (const DBusString *str,
2519                             int               start,
2520                             int               len)
2521 {
2522   unsigned char *s;
2523   unsigned char *end;
2524   DBUS_STRING_PREAMBLE (str);
2525   _dbus_assert (start >= 0);
2526   _dbus_assert (start <= real->len);
2527   _dbus_assert (len >= 0);
2528   _dbus_assert (len <= real->len - start);
2529
2530   s = real->str + start;
2531   end = s + len;
2532
2533   while (s != end)
2534     {
2535       if (*s >= 'a' && *s <= 'z')
2536           *s += 'A' - 'a';
2537       ++s;
2538     }
2539 }
2540
2541 /**
2542  * Checks that the given range of the string is valid UTF-8. If the
2543  * given range is not entirely contained in the string, returns
2544  * #FALSE. If the string contains any nul bytes in the given range,
2545  * returns #FALSE. If the start and start+len are not on character
2546  * boundaries, returns #FALSE.
2547  *
2548  * @todo this is inconsistent with most of DBusString in that
2549  * it allows a start,len range that extends past the string end.
2550  * 
2551  * @param str the string
2552  * @param start first byte index to check
2553  * @param len number of bytes to check
2554  * @returns #TRUE if the byte range exists and is all valid UTF-8
2555  */
2556 dbus_bool_t
2557 _dbus_string_validate_utf8  (const DBusString *str,
2558                              int               start,
2559                              int               len)
2560 {
2561   const unsigned char *p;
2562   const unsigned char *end;
2563   DBUS_CONST_STRING_PREAMBLE (str);
2564   _dbus_assert (start >= 0);
2565   _dbus_assert (start <= real->len);
2566   _dbus_assert (len >= 0);
2567
2568   /* we are doing _DBUS_UNLIKELY() here which might be
2569    * dubious in a generic library like GLib, but in D-Bus
2570    * we know we're validating messages and that it would
2571    * only be evil/broken apps that would have invalid
2572    * UTF-8. Also, this function seems to be a performance
2573    * bottleneck in profiles.
2574    */
2575   
2576   if (_DBUS_UNLIKELY (len > real->len - start))
2577     return FALSE;
2578   
2579   p = real->str + start;
2580   end = p + len;
2581   
2582   while (p < end)
2583     {
2584       int i, mask, char_len;
2585       dbus_unichar_t result;
2586
2587       /* nul bytes considered invalid */
2588       if (*p == '\0')
2589         break;
2590       
2591       /* Special-case ASCII; this makes us go a lot faster in
2592        * D-Bus profiles where we are typically validating
2593        * function names and such. We have to know that
2594        * all following checks will pass for ASCII though,
2595        * comments follow ...
2596        */      
2597       if (*p < 128)
2598         {
2599           ++p;
2600           continue;
2601         }
2602       
2603       UTF8_COMPUTE (*p, mask, char_len);
2604
2605       if (_DBUS_UNLIKELY (char_len == 0))  /* ASCII: char_len == 1 */
2606         break;
2607
2608       /* check that the expected number of bytes exists in the remaining length */
2609       if (_DBUS_UNLIKELY ((end - p) < char_len)) /* ASCII: p < end and char_len == 1 */
2610         break;
2611         
2612       UTF8_GET (result, p, i, mask, char_len);
2613
2614       /* Check for overlong UTF-8 */
2615       if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* ASCII: UTF8_LENGTH == 1 */
2616         break;
2617 #if 0
2618       /* The UNICODE_VALID check below will catch this */
2619       if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) /* ASCII: result = ascii value */
2620         break;
2621 #endif
2622
2623       if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) /* ASCII: always valid */
2624         break;
2625
2626       /* UNICODE_VALID should have caught it */
2627       _dbus_assert (result != (dbus_unichar_t)-1);
2628       
2629       p += char_len;
2630     }
2631
2632   /* See that we covered the entire length if a length was
2633    * passed in
2634    */
2635   if (_DBUS_UNLIKELY (p != end))
2636     return FALSE;
2637   else
2638     return TRUE;
2639 }
2640
2641 /**
2642  * Checks that the given range of the string is all nul bytes. If the
2643  * given range is not entirely contained in the string, returns
2644  * #FALSE.
2645  *
2646  * @todo this is inconsistent with most of DBusString in that
2647  * it allows a start,len range that extends past the string end.
2648  * 
2649  * @param str the string
2650  * @param start first byte index to check
2651  * @param len number of bytes to check
2652  * @returns #TRUE if the byte range exists and is all nul bytes
2653  */
2654 dbus_bool_t
2655 _dbus_string_validate_nul (const DBusString *str,
2656                            int               start,
2657                            int               len)
2658 {
2659   const unsigned char *s;
2660   const unsigned char *end;
2661   DBUS_CONST_STRING_PREAMBLE (str);
2662   _dbus_assert (start >= 0);
2663   _dbus_assert (len >= 0);
2664   _dbus_assert (start <= real->len);
2665   
2666   if (len > real->len - start)
2667     return FALSE;
2668   
2669   s = real->str + start;
2670   end = s + len;
2671   while (s != end)
2672     {
2673       if (_DBUS_UNLIKELY (*s != '\0'))
2674         return FALSE;
2675       ++s;
2676     }
2677   
2678   return TRUE;
2679 }
2680
2681 /**
2682  * Clears all allocated bytes in the string to zero.
2683  *
2684  * @param str the string
2685  */
2686 void
2687 _dbus_string_zero (DBusString *str)
2688 {
2689   DBUS_STRING_PREAMBLE (str);
2690
2691   memset (real->str - real->align_offset, '\0', real->allocated);
2692 }
2693 /** @} */
2694
2695 /* tests are in dbus-string-util.c */