* dbus/dbus-string.[ch] (_dbus_string_find_eol): new function.
[platform/upstream/dbus.git] / dbus / dbus-string.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  */
24
25 #include "dbus-internals.h"
26 #include "dbus-string.h"
27 /* we allow a system header here, for speed/convenience */
28 #include <string.h>
29 /* for vsnprintf */
30 #include <stdio.h>
31 #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
32 #include "dbus-string-private.h"
33 #include "dbus-marshal-basic.h" /* probably should be removed by moving the usage of DBUS_TYPE
34                                  * into the marshaling-related files
35                                  */
36 /* for DBUS_VA_COPY */
37 #include "dbus-sysdeps.h"
38
39 /**
40  * @defgroup DBusString DBusString class
41  * @ingroup  DBusInternals
42  * @brief DBusString data structure for safer string handling
43  *
44  * Types and functions related to DBusString. DBusString is intended
45  * to be a string class that makes it hard to mess up security issues
46  * (and just in general harder to write buggy code).  It should be
47  * used (or extended and then used) rather than the libc stuff in
48  * string.h.  The string class is a bit inconvenient at spots because
49  * it handles out-of-memory failures and tries to be extra-robust.
50  * 
51  * A DBusString has a maximum length set at initialization time; this
52  * can be used to ensure that a buffer doesn't get too big.  The
53  * _dbus_string_lengthen() method checks for overflow, and for max
54  * length being exceeded.
55  * 
56  * Try to avoid conversion to a plain C string, i.e. add methods on
57  * the string object instead, only convert to C string when passing
58  * things out to the public API. In particular, no sprintf, strcpy,
59  * strcat, any of that should be used. The GString feature of
60  * accepting negative numbers for "length of string" is also absent,
61  * because it could keep us from detecting bogus huge lengths. i.e. if
62  * we passed in some bogus huge length it would be taken to mean
63  * "current length of string" instead of "broken crack"
64  *
65  * @todo #DBusString needs a lot of cleaning up; some of the
66  * API is no longer used, and the API is pretty inconsistent.
67  * In particular all the "append" APIs, especially those involving
68  * alignment but probably lots of them, are no longer used by the
69  * marshaling code which always does "inserts" now.
70  */
71
72 /**
73  * @addtogroup DBusString
74  * @{
75  */
76
77 static void
78 fixup_alignment (DBusRealString *real)
79 {
80   unsigned char *aligned;
81   unsigned char *real_block;
82   unsigned int old_align_offset;
83
84   /* we have to have extra space in real->allocated for the align offset and nul byte */
85   _dbus_assert (real->len <= real->allocated - _DBUS_STRING_ALLOCATION_PADDING);
86   
87   old_align_offset = real->align_offset;
88   real_block = real->str - old_align_offset;
89   
90   aligned = _DBUS_ALIGN_ADDRESS (real_block, 8);
91
92   real->align_offset = aligned - real_block;
93   real->str = aligned;
94   
95   if (old_align_offset != real->align_offset)
96     {
97       /* Here comes the suck */
98       memmove (real_block + real->align_offset,
99                real_block + old_align_offset,
100                real->len + 1);
101     }
102
103   _dbus_assert (real->align_offset < 8);
104   _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str);
105 }
106
107 static void
108 undo_alignment (DBusRealString *real)
109 {
110   if (real->align_offset != 0)
111     {
112       memmove (real->str - real->align_offset,
113                real->str,
114                real->len + 1);
115
116       real->str = real->str - real->align_offset;
117       real->align_offset = 0;
118     }
119 }
120
121 /**
122  * Initializes a string that can be up to the given allocation size
123  * before it has to realloc. The string starts life with zero length.
124  * The string must eventually be freed with _dbus_string_free().
125  * 
126  * @param str memory to hold the string
127  * @param allocate_size amount to preallocate
128  * @returns #TRUE on success, #FALSE if no memory
129  */
130 dbus_bool_t
131 _dbus_string_init_preallocated (DBusString *str,
132                                 int         allocate_size)
133 {
134   DBusRealString *real;
135   
136   _dbus_assert (str != NULL);
137
138   _dbus_assert (sizeof (DBusString) == sizeof (DBusRealString));
139   
140   real = (DBusRealString*) str;
141
142   /* It's very important not to touch anything
143    * other than real->str if we're going to fail,
144    * since we also use this function to reset
145    * an existing string, e.g. in _dbus_string_steal_data()
146    */
147   
148   real->str = dbus_malloc (_DBUS_STRING_ALLOCATION_PADDING + allocate_size);
149   if (real->str == NULL)
150     return FALSE;  
151   
152   real->allocated = _DBUS_STRING_ALLOCATION_PADDING + allocate_size;
153   real->len = 0;
154   real->str[real->len] = '\0';
155   
156   real->max_length = _DBUS_STRING_MAX_MAX_LENGTH;
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 #ifdef DBUS_BUILD_TESTS
181 /* The max length thing is sort of a historical artifact
182  * from a feature that turned out to be dumb; perhaps
183  * we should purge it entirely. The problem with
184  * the feature is that it looks like memory allocation
185  * failure, but is not a transient or resolvable failure.
186  */
187 static void
188 set_max_length (DBusString *str,
189                 int         max_length)
190 {
191   DBusRealString *real;
192   
193   real = (DBusRealString*) str;
194
195   real->max_length = max_length;
196 }
197 #endif /* DBUS_BUILD_TESTS */
198
199 /**
200  * Initializes a constant string. The value parameter is not copied
201  * (should be static), and the string may never be modified.
202  * It is safe but not necessary to call _dbus_string_free()
203  * on a const string. The string has a length limit of MAXINT - 8.
204  * 
205  * @param str memory to use for the string
206  * @param value a string to be stored in str (not copied!!!)
207  */
208 void
209 _dbus_string_init_const (DBusString *str,
210                          const char *value)
211 {
212   _dbus_assert (value != NULL);
213   
214   _dbus_string_init_const_len (str, value,
215                                strlen (value));
216 }
217
218 /**
219  * Initializes a constant string with a length. The value parameter is
220  * not copied (should be static), and the string may never be
221  * modified.  It is safe but not necessary to call _dbus_string_free()
222  * on a const string.
223  * 
224  * @param str memory to use for the string
225  * @param value a string to be stored in str (not copied!!!)
226  * @param len the length to use
227  */
228 void
229 _dbus_string_init_const_len (DBusString *str,
230                              const char *value,
231                              int         len)
232 {
233   DBusRealString *real;
234   
235   _dbus_assert (str != NULL);
236   _dbus_assert (len == 0 || value != NULL);
237   _dbus_assert (len <= _DBUS_STRING_MAX_MAX_LENGTH);
238   _dbus_assert (len >= 0);
239   
240   real = (DBusRealString*) str;
241   
242   real->str = (unsigned char*) value;
243   real->len = len;
244   real->allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING; /* a lie, just to avoid special-case assertions... */
245   real->max_length = real->len + 1;
246   real->constant = TRUE;
247   real->locked = TRUE;
248   real->invalid = FALSE;
249   real->align_offset = 0;
250
251   /* We don't require const strings to be 8-byte aligned as the
252    * memory is coming from elsewhere.
253    */
254 }
255
256 /**
257  * Frees a string created by _dbus_string_init().
258  *
259  * @param str memory where the string is stored.
260  */
261 void
262 _dbus_string_free (DBusString *str)
263 {
264   DBusRealString *real = (DBusRealString*) str;
265   DBUS_GENERIC_STRING_PREAMBLE (real);
266   
267   if (real->constant)
268     return;
269   dbus_free (real->str - real->align_offset);
270
271   real->invalid = TRUE;
272 }
273
274 #ifdef DBUS_BUILD_TESTS
275 /* Not using this feature at the moment,
276  * so marked DBUS_BUILD_TESTS-only
277  */
278 /**
279  * Locks a string such that any attempts to change the string will
280  * result in aborting the program. Also, if the string is wasting a
281  * lot of memory (allocation is sufficiently larger than what the
282  * string is really using), _dbus_string_lock() will realloc the
283  * string's data to "compact" it.
284  *
285  * @param str the string to lock.
286  */
287 void
288 _dbus_string_lock (DBusString *str)
289 {  
290   DBUS_LOCKED_STRING_PREAMBLE (str); /* can lock multiple times */
291
292   real->locked = TRUE;
293
294   /* Try to realloc to avoid excess memory usage, since
295    * we know we won't change the string further
296    */
297 #define MAX_WASTE 48
298   if (real->allocated - MAX_WASTE > real->len)
299     {
300       unsigned char *new_str;
301       int new_allocated;
302
303       new_allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING;
304
305       new_str = dbus_realloc (real->str - real->align_offset,
306                               new_allocated);
307       if (new_str != NULL)
308         {
309           real->str = new_str + real->align_offset;
310           real->allocated = new_allocated;
311           fixup_alignment (real);
312         }
313     }
314 }
315 #endif /* DBUS_BUILD_TESTS */
316
317 static dbus_bool_t
318 reallocate_for_length (DBusRealString *real,
319                        int             new_length)
320 {
321   int new_allocated;
322   unsigned char *new_str;
323
324   /* at least double our old allocation to avoid O(n), avoiding
325    * overflow
326    */
327   if (real->allocated > (_DBUS_STRING_MAX_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2)
328     new_allocated = _DBUS_STRING_MAX_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING;
329   else
330     new_allocated = real->allocated * 2;
331
332   /* if you change the code just above here, run the tests without
333    * the following assert-only hack before you commit
334    */
335   /* This is keyed off asserts in addition to tests so when you
336    * disable asserts to profile, you don't get this destroyer
337    * of profiles.
338    */
339 #ifdef DBUS_DISABLE_ASSERT
340 #else
341 #ifdef DBUS_BUILD_TESTS
342   new_allocated = 0; /* ensure a realloc every time so that we go
343                       * through all malloc failure codepaths
344                       */
345 #endif /* DBUS_BUILD_TESTS */
346 #endif /* !DBUS_DISABLE_ASSERT */
347
348   /* But be sure we always alloc at least space for the new length */
349   new_allocated = MAX (new_allocated,
350                        new_length + _DBUS_STRING_ALLOCATION_PADDING);
351
352   _dbus_assert (new_allocated >= real->allocated); /* code relies on this */
353   new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
354   if (_DBUS_UNLIKELY (new_str == NULL))
355     return FALSE;
356
357   real->str = new_str + real->align_offset;
358   real->allocated = new_allocated;
359   fixup_alignment (real);
360
361   return TRUE;
362 }
363
364 static dbus_bool_t
365 set_length (DBusRealString *real,
366             int             new_length)
367 {
368   /* Note, we are setting the length not including nul termination */
369
370   /* exceeding max length is the same as failure to allocate memory */
371   if (_DBUS_UNLIKELY (new_length > real->max_length))
372     return FALSE;
373   else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) &&
374            _DBUS_UNLIKELY (!reallocate_for_length (real, new_length)))
375     return FALSE;
376   else
377     {
378       real->len = new_length;
379       real->str[new_length] = '\0';
380       return TRUE;
381     }
382 }
383
384 static dbus_bool_t
385 open_gap (int             len,
386           DBusRealString *dest,
387           int             insert_at)
388 {
389   if (len == 0)
390     return TRUE;
391
392   if (len > dest->max_length - dest->len)
393     return FALSE; /* detected overflow of dest->len + len below */
394   
395   if (!set_length (dest, dest->len + len))
396     return FALSE;
397
398   memmove (dest->str + insert_at + len, 
399            dest->str + insert_at,
400            dest->len - len - insert_at);
401
402   return TRUE;
403 }
404
405 #ifndef _dbus_string_get_data
406 /**
407  * Gets the raw character buffer from the string.  The returned buffer
408  * will be nul-terminated, but note that strings may contain binary
409  * data so there may be extra nul characters prior to the termination.
410  * This function should be little-used, extend DBusString or add
411  * stuff to dbus-sysdeps.c instead. It's an error to use this
412  * function on a const string.
413  *
414  * @param str the string
415  * @returns the data
416  */
417 char*
418 _dbus_string_get_data (DBusString *str)
419 {
420   DBUS_STRING_PREAMBLE (str);
421   
422   return (char*) real->str;
423 }
424 #endif /* _dbus_string_get_data */
425
426 /* only do the function if we don't have the macro */
427 #ifndef _dbus_string_get_const_data
428 /**
429  * Gets the raw character buffer from a const string.
430  *
431  * @param str the string
432  * @returns the string data
433  */
434 const char*
435 _dbus_string_get_const_data (const DBusString  *str)
436 {
437   DBUS_CONST_STRING_PREAMBLE (str);
438   
439   return (const char*) real->str;
440 }
441 #endif /* _dbus_string_get_const_data */
442
443 /**
444  * Gets a sub-portion of the raw character buffer from the
445  * string. The "len" field is required simply for error
446  * checking, to be sure you don't try to use more
447  * string than exists. The nul termination of the
448  * returned buffer remains at the end of the entire
449  * string, not at start + len.
450  *
451  * @param str the string
452  * @param start byte offset to return
453  * @param len length of segment to return
454  * @returns the string data
455  */
456 char*
457 _dbus_string_get_data_len (DBusString *str,
458                            int         start,
459                            int         len)
460 {
461   DBUS_STRING_PREAMBLE (str);
462   _dbus_assert (start >= 0);
463   _dbus_assert (len >= 0);
464   _dbus_assert (start <= real->len);
465   _dbus_assert (len <= real->len - start);
466   
467   return (char*) real->str + start;
468 }
469
470 /* only do the function if we don't have the macro */
471 #ifndef _dbus_string_get_const_data_len
472 /**
473  * const version of _dbus_string_get_data_len().
474  *
475  * @param str the string
476  * @param start byte offset to return
477  * @param len length of segment to return
478  * @returns the string data
479  */
480 const char*
481 _dbus_string_get_const_data_len (const DBusString  *str,
482                                  int                start,
483                                  int                len)
484 {
485   DBUS_CONST_STRING_PREAMBLE (str);
486   _dbus_assert (start >= 0);
487   _dbus_assert (len >= 0);
488   _dbus_assert (start <= real->len);
489   _dbus_assert (len <= real->len - start);
490   
491   return (const char*) real->str + start;
492 }
493 #endif /* _dbus_string_get_const_data_len */
494
495 /* only do the function if we don't have the macro */
496 #ifndef _dbus_string_set_byte
497 /**
498  * Sets the value of the byte at the given position.
499  *
500  * @param str the string
501  * @param i the position
502  * @param byte the new value
503  */
504 void
505 _dbus_string_set_byte (DBusString    *str,
506                        int            i,
507                        unsigned char  byte)
508 {
509   DBUS_STRING_PREAMBLE (str);
510   _dbus_assert (i < real->len);
511   _dbus_assert (i >= 0);
512   
513   real->str[i] = byte;
514 }
515 #endif /* _dbus_string_set_byte */
516
517 /* only have the function if we didn't create a macro */
518 #ifndef _dbus_string_get_byte
519 /**
520  * Gets the byte at the given position. It is
521  * allowed to ask for the nul byte at the end of
522  * the string.
523  *
524  * @param str the string
525  * @param start the position
526  * @returns the byte at that position
527  */
528 unsigned char
529 _dbus_string_get_byte (const DBusString  *str,
530                        int                start)
531 {
532   DBUS_CONST_STRING_PREAMBLE (str);
533   _dbus_assert (start <= real->len);
534   _dbus_assert (start >= 0);
535   
536   return real->str[start];
537 }
538 #endif /* _dbus_string_get_byte */
539
540 /**
541  * Inserts a number of bytes of a given value at the
542  * given position.
543  *
544  * @param str the string
545  * @param i the position
546  * @param n_bytes number of bytes
547  * @param byte the value to insert
548  * @returns #TRUE on success
549  */
550 dbus_bool_t
551 _dbus_string_insert_bytes (DBusString   *str,
552                            int           i,
553                            int           n_bytes,
554                            unsigned char byte)
555 {
556   DBUS_STRING_PREAMBLE (str);
557   _dbus_assert (i <= real->len);
558   _dbus_assert (i >= 0);
559   _dbus_assert (n_bytes >= 0);
560
561   if (n_bytes == 0)
562     return TRUE;
563   
564   if (!open_gap (n_bytes, real, i))
565     return FALSE;
566   
567   memset (real->str + i, byte, n_bytes);
568
569   return TRUE;
570 }
571
572 /**
573  * Inserts a single byte at the given position.
574  *
575  * @param str the string
576  * @param i the position
577  * @param byte the value to insert
578  * @returns #TRUE on success
579  */
580 dbus_bool_t
581 _dbus_string_insert_byte (DBusString   *str,
582                            int           i,
583                            unsigned char byte)
584 {
585   DBUS_STRING_PREAMBLE (str);
586   _dbus_assert (i <= real->len);
587   _dbus_assert (i >= 0);
588   
589   if (!open_gap (1, real, i))
590     return FALSE;
591
592   real->str[i] = byte;
593
594   return TRUE;
595 }
596
597 /**
598  * Like _dbus_string_get_data(), but removes the
599  * gotten data from the original string. The caller
600  * must free the data returned. This function may
601  * fail due to lack of memory, and return #FALSE.
602  *
603  * @param str the string
604  * @param data_return location to return the buffer
605  * @returns #TRUE on success
606  */
607 dbus_bool_t
608 _dbus_string_steal_data (DBusString        *str,
609                          char             **data_return)
610 {
611   int old_max_length;
612   DBUS_STRING_PREAMBLE (str);
613   _dbus_assert (data_return != NULL);
614
615   undo_alignment (real);
616   
617   *data_return = (char*) real->str;
618
619   old_max_length = real->max_length;
620   
621   /* reset the string */
622   if (!_dbus_string_init (str))
623     {
624       /* hrm, put it back then */
625       real->str = (unsigned char*) *data_return;
626       *data_return = NULL;
627       fixup_alignment (real);
628       return FALSE;
629     }
630
631   real->max_length = old_max_length;
632
633   return TRUE;
634 }
635
636 #ifdef DBUS_BUILD_TESTS
637 /**
638  * Like _dbus_string_get_data_len(), but removes the gotten data from
639  * the original string. The caller must free the data returned. This
640  * function may fail due to lack of memory, and return #FALSE.
641  * The returned string is nul-terminated and has length len.
642  *
643  * @todo this function is broken because on failure it
644  * may corrupt the source string.
645  * 
646  * @param str the string
647  * @param data_return location to return the buffer
648  * @param start the start of segment to steal
649  * @param len the length of segment to steal
650  * @returns #TRUE on success
651  */
652 dbus_bool_t
653 _dbus_string_steal_data_len (DBusString        *str,
654                              char             **data_return,
655                              int                start,
656                              int                len)
657 {
658   DBusString dest;
659   DBUS_STRING_PREAMBLE (str);
660   _dbus_assert (data_return != NULL);
661   _dbus_assert (start >= 0);
662   _dbus_assert (len >= 0);
663   _dbus_assert (start <= real->len);
664   _dbus_assert (len <= real->len - start);
665
666   if (!_dbus_string_init (&dest))
667     return FALSE;
668
669   set_max_length (&dest, real->max_length);
670   
671   if (!_dbus_string_move_len (str, start, len, &dest, 0))
672     {
673       _dbus_string_free (&dest);
674       return FALSE;
675     }
676
677   _dbus_warn ("Broken code in _dbus_string_steal_data_len(), see @todo, FIXME\n");
678   if (!_dbus_string_steal_data (&dest, data_return))
679     {
680       _dbus_string_free (&dest);
681       return FALSE;
682     }
683
684   _dbus_string_free (&dest);
685   return TRUE;
686 }
687 #endif /* DBUS_BUILD_TESTS */
688
689 /**
690  * Copies the data from the string into a char*
691  *
692  * @param str the string
693  * @param data_return place to return the data
694  * @returns #TRUE on success, #FALSE on no memory
695  */
696 dbus_bool_t
697 _dbus_string_copy_data (const DBusString  *str,
698                         char             **data_return)
699 {
700   DBUS_CONST_STRING_PREAMBLE (str);
701   _dbus_assert (data_return != NULL);
702   
703   *data_return = dbus_malloc (real->len + 1);
704   if (*data_return == NULL)
705     return FALSE;
706
707   memcpy (*data_return, real->str, real->len + 1);
708
709   return TRUE;
710 }
711
712 /**
713  * Copies the contents of a DBusString into a different
714  * buffer. The resulting buffer will be nul-terminated.
715  * 
716  * @param str a string
717  * @param buffer a C buffer to copy data to
718  * @param avail_len maximum length of C buffer
719  */
720 void
721 _dbus_string_copy_to_buffer (const DBusString  *str,
722                              char              *buffer,
723                              int                avail_len)
724 {
725   int copy_len;
726   DBUS_CONST_STRING_PREAMBLE (str);
727
728   _dbus_assert (avail_len >= 0);
729
730   copy_len = MIN (avail_len, real->len+1);
731   memcpy (buffer, real->str, copy_len);
732   if (avail_len > 0 && avail_len == copy_len)
733     buffer[avail_len-1] = '\0';
734 }
735
736 #ifdef DBUS_BUILD_TESTS
737 /**
738  * Copies a segment of the string into a char*
739  *
740  * @param str the string
741  * @param data_return place to return the data
742  * @param start start index
743  * @param len length to copy
744  * @returns #FALSE if no memory
745  */
746 dbus_bool_t
747 _dbus_string_copy_data_len (const DBusString  *str,
748                             char             **data_return,
749                             int                start,
750                             int                len)
751 {
752   DBusString dest;
753
754   DBUS_CONST_STRING_PREAMBLE (str);
755   _dbus_assert (data_return != NULL);
756   _dbus_assert (start >= 0);
757   _dbus_assert (len >= 0);
758   _dbus_assert (start <= real->len);
759   _dbus_assert (len <= real->len - start);
760
761   if (!_dbus_string_init (&dest))
762     return FALSE;
763
764   set_max_length (&dest, real->max_length);
765
766   if (!_dbus_string_copy_len (str, start, len, &dest, 0))
767     {
768       _dbus_string_free (&dest);
769       return FALSE;
770     }
771
772   if (!_dbus_string_steal_data (&dest, data_return))
773     {
774       _dbus_string_free (&dest);
775       return FALSE;
776     }
777
778   _dbus_string_free (&dest);
779   return TRUE;
780 }
781 #endif /* DBUS_BUILD_TESTS */
782
783 /* Only have the function if we don't have the macro */
784 #ifndef _dbus_string_get_length
785 /**
786  * Gets the length of a string (not including nul termination).
787  *
788  * @returns the length.
789  */
790 int
791 _dbus_string_get_length (const DBusString  *str)
792 {
793   DBUS_CONST_STRING_PREAMBLE (str);
794   
795   return real->len;
796 }
797 #endif /* !_dbus_string_get_length */
798
799 /**
800  * Makes a string longer by the given number of bytes.  Checks whether
801  * adding additional_length to the current length would overflow an
802  * integer, and checks for exceeding a string's max length.
803  * The new bytes are not initialized, other than nul-terminating
804  * the end of the string. The uninitialized bytes may contain
805  * nul bytes or other junk.
806  *
807  * @param str a string
808  * @param additional_length length to add to the string.
809  * @returns #TRUE on success.
810  */
811 dbus_bool_t
812 _dbus_string_lengthen (DBusString *str,
813                        int         additional_length)
814 {
815   DBUS_STRING_PREAMBLE (str);  
816   _dbus_assert (additional_length >= 0);
817
818   if (_DBUS_UNLIKELY (additional_length > real->max_length - real->len))
819     return FALSE; /* would overflow */
820   
821   return set_length (real,
822                      real->len + additional_length);
823 }
824
825 /**
826  * Makes a string shorter by the given number of bytes.
827  *
828  * @param str a string
829  * @param length_to_remove length to remove from the string.
830  */
831 void
832 _dbus_string_shorten (DBusString *str,
833                       int         length_to_remove)
834 {
835   DBUS_STRING_PREAMBLE (str);
836   _dbus_assert (length_to_remove >= 0);
837   _dbus_assert (length_to_remove <= real->len);
838
839   set_length (real,
840               real->len - length_to_remove);
841 }
842
843 /**
844  * Sets the length of a string. Can be used to truncate or lengthen
845  * the string. If the string is lengthened, the function may fail and
846  * return #FALSE. Newly-added bytes are not initialized, as with
847  * _dbus_string_lengthen().
848  *
849  * @param str a string
850  * @param length new length of the string.
851  * @returns #FALSE on failure.
852  */
853 dbus_bool_t
854 _dbus_string_set_length (DBusString *str,
855                          int         length)
856 {
857   DBUS_STRING_PREAMBLE (str);
858   _dbus_assert (length >= 0);
859
860   return set_length (real, length);
861 }
862
863 static dbus_bool_t
864 align_insert_point_then_open_gap (DBusString *str,
865                                   int        *insert_at_p,
866                                   int         alignment,
867                                   int         gap_size)
868 {
869   unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */
870   unsigned long gap_pos;
871   int insert_at;
872   int delta;
873   DBUS_STRING_PREAMBLE (str);
874   _dbus_assert (alignment >= 1);
875   _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
876
877   insert_at = *insert_at_p;
878
879   _dbus_assert (insert_at <= real->len);
880   
881   gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
882   new_len = real->len + (gap_pos - insert_at) + gap_size;
883   
884   if (_DBUS_UNLIKELY (new_len > (unsigned long) real->max_length))
885     return FALSE;
886   
887   delta = new_len - real->len;
888   _dbus_assert (delta >= 0);
889
890   if (delta == 0) /* only happens if gap_size == 0 and insert_at is aligned already */
891     {
892       _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
893       return TRUE;
894     }
895
896   if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
897                                  real, insert_at)))
898     return FALSE;
899
900   /* nul the padding if we had to add any padding */
901   if (gap_size < delta)
902     {
903       memset (&real->str[insert_at], '\0',
904               gap_pos - insert_at);
905     }
906
907   *insert_at_p = gap_pos;
908   
909   return TRUE;
910 }
911
912 static dbus_bool_t
913 align_length_then_lengthen (DBusString *str,
914                             int         alignment,
915                             int         then_lengthen_by)
916 {
917   int insert_at;
918
919   insert_at = _dbus_string_get_length (str);
920   
921   return align_insert_point_then_open_gap (str,
922                                            &insert_at,
923                                            alignment, then_lengthen_by);
924 }
925
926 /**
927  * Align the length of a string to a specific alignment (typically 4 or 8)
928  * by appending nul bytes to the string.
929  *
930  * @param str a string
931  * @param alignment the alignment
932  * @returns #FALSE if no memory
933  */
934 dbus_bool_t
935 _dbus_string_align_length (DBusString *str,
936                            int         alignment)
937 {
938   return align_length_then_lengthen (str, alignment, 0);
939 }
940
941 /**
942  * Preallocate extra_bytes such that a future lengthening of the
943  * string by extra_bytes is guaranteed to succeed without an out of
944  * memory error.
945  *
946  * @param str a string
947  * @param extra_bytes bytes to alloc
948  * @returns #FALSE if no memory
949  */
950 dbus_bool_t
951 _dbus_string_alloc_space (DBusString        *str,
952                           int                extra_bytes)
953 {
954   if (!_dbus_string_lengthen (str, extra_bytes))
955     return FALSE;
956   _dbus_string_shorten (str, extra_bytes);
957
958   return TRUE;
959 }
960
961 static dbus_bool_t
962 append (DBusRealString *real,
963         const char     *buffer,
964         int             buffer_len)
965 {
966   if (buffer_len == 0)
967     return TRUE;
968
969   if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
970     return FALSE;
971
972   memcpy (real->str + (real->len - buffer_len),
973           buffer,
974           buffer_len);
975
976   return TRUE;
977 }
978
979 /**
980  * Appends a nul-terminated C-style string to a DBusString.
981  *
982  * @param str the DBusString
983  * @param buffer the nul-terminated characters to append
984  * @returns #FALSE if not enough memory.
985  */
986 dbus_bool_t
987 _dbus_string_append (DBusString *str,
988                      const char *buffer)
989 {
990   unsigned long buffer_len;
991   
992   DBUS_STRING_PREAMBLE (str);
993   _dbus_assert (buffer != NULL);
994   
995   buffer_len = strlen (buffer);
996   if (buffer_len > (unsigned long) real->max_length)
997     return FALSE;
998   
999   return append (real, buffer, buffer_len);
1000 }
1001
1002 /** assign 2 bytes from one string to another */
1003 #define ASSIGN_2_OCTETS(p, octets) \
1004   *((dbus_uint16_t*)(p)) = *((dbus_uint16_t*)(octets));
1005
1006 /** assign 4 bytes from one string to another */
1007 #define ASSIGN_4_OCTETS(p, octets) \
1008   *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
1009
1010 #ifdef DBUS_HAVE_INT64
1011 /** assign 8 bytes from one string to another */
1012 #define ASSIGN_8_OCTETS(p, octets) \
1013   *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
1014 #else
1015 /** assign 8 bytes from one string to another */
1016 #define ASSIGN_8_OCTETS(p, octets)              \
1017 do {                                            \
1018   unsigned char *b;                             \
1019                                                 \
1020   b = p;                                        \
1021                                                 \
1022   *b++ = octets[0];                             \
1023   *b++ = octets[1];                             \
1024   *b++ = octets[2];                             \
1025   *b++ = octets[3];                             \
1026   *b++ = octets[4];                             \
1027   *b++ = octets[5];                             \
1028   *b++ = octets[6];                             \
1029   *b++ = octets[7];                             \
1030   _dbus_assert (b == p + 8);                    \
1031 } while (0)
1032 #endif /* DBUS_HAVE_INT64 */
1033
1034 #ifdef DBUS_BUILD_TESTS
1035 /**
1036  * Appends 4 bytes aligned on a 4 byte boundary
1037  * with any alignment padding initialized to 0.
1038  *
1039  * @param str the DBusString
1040  * @param octets 4 bytes to append
1041  * @returns #FALSE if not enough memory.
1042  */
1043 dbus_bool_t
1044 _dbus_string_append_4_aligned (DBusString         *str,
1045                                const unsigned char octets[4])
1046 {
1047   DBUS_STRING_PREAMBLE (str);
1048   
1049   if (!align_length_then_lengthen (str, 4, 4))
1050     return FALSE;
1051
1052   ASSIGN_4_OCTETS (real->str + (real->len - 4), octets);
1053
1054   return TRUE;
1055 }
1056 #endif /* DBUS_BUILD_TESTS */
1057
1058 #ifdef DBUS_BUILD_TESTS
1059 /**
1060  * Appends 8 bytes aligned on an 8 byte boundary
1061  * with any alignment padding initialized to 0.
1062  *
1063  * @param str the DBusString
1064  * @param octets 8 bytes to append
1065  * @returns #FALSE if not enough memory.
1066  */
1067 dbus_bool_t
1068 _dbus_string_append_8_aligned (DBusString         *str,
1069                                const unsigned char octets[8])
1070 {
1071   DBUS_STRING_PREAMBLE (str);
1072   
1073   if (!align_length_then_lengthen (str, 8, 8))
1074     return FALSE;
1075
1076   ASSIGN_8_OCTETS (real->str + (real->len - 8), octets);
1077
1078   return TRUE;
1079 }
1080 #endif /* DBUS_BUILD_TESTS */
1081
1082 /**
1083  * Inserts 2 bytes aligned on a 2 byte boundary
1084  * with any alignment padding initialized to 0.
1085  *
1086  * @param str the DBusString
1087  * @param insert_at where to insert
1088  * @param octets 2 bytes to insert
1089  * @returns #FALSE if not enough memory.
1090  */
1091 dbus_bool_t
1092 _dbus_string_insert_2_aligned (DBusString         *str,
1093                                int                 insert_at,
1094                                const unsigned char octets[4])
1095 {
1096   DBUS_STRING_PREAMBLE (str);
1097   
1098   if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2))
1099     return FALSE;
1100
1101   ASSIGN_2_OCTETS (real->str + insert_at, octets);
1102
1103   return TRUE;
1104 }
1105
1106 /**
1107  * Inserts 4 bytes aligned on a 4 byte boundary
1108  * with any alignment padding initialized to 0.
1109  *
1110  * @param str the DBusString
1111  * @param insert_at where to insert
1112  * @param octets 4 bytes to insert
1113  * @returns #FALSE if not enough memory.
1114  */
1115 dbus_bool_t
1116 _dbus_string_insert_4_aligned (DBusString         *str,
1117                                int                 insert_at,
1118                                const unsigned char octets[4])
1119 {
1120   DBUS_STRING_PREAMBLE (str);
1121   
1122   if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
1123     return FALSE;
1124
1125   ASSIGN_4_OCTETS (real->str + insert_at, octets);
1126
1127   return TRUE;
1128 }
1129
1130 /**
1131  * Inserts 8 bytes aligned on an 8 byte boundary
1132  * with any alignment padding initialized to 0.
1133  *
1134  * @param str the DBusString
1135  * @param insert_at where to insert
1136  * @param octets 8 bytes to insert
1137  * @returns #FALSE if not enough memory.
1138  */
1139 dbus_bool_t
1140 _dbus_string_insert_8_aligned (DBusString         *str,
1141                                int                 insert_at,
1142                                const unsigned char octets[8])
1143 {
1144   DBUS_STRING_PREAMBLE (str);
1145   
1146   if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
1147     return FALSE;
1148
1149   _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
1150   
1151   ASSIGN_8_OCTETS (real->str + insert_at, octets);
1152
1153   return TRUE;
1154 }
1155
1156
1157 /**
1158  * Inserts padding at *insert_at such to align it to the given
1159  * boundary. Initializes the padding to nul bytes. Sets *insert_at
1160  * to the aligned position.
1161  *
1162  * @param str the DBusString
1163  * @param insert_at location to be aligned
1164  * @param alignment alignment boundary (1, 2, 4, or 8)
1165  * @returns #FALSE if not enough memory.
1166  */
1167 dbus_bool_t
1168 _dbus_string_insert_alignment (DBusString        *str,
1169                                int               *insert_at,
1170                                int                alignment)
1171 {
1172   DBUS_STRING_PREAMBLE (str);
1173   
1174   if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0))
1175     return FALSE;
1176
1177   _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at);
1178
1179   return TRUE;
1180 }
1181
1182 /**
1183  * Appends a printf-style formatted string
1184  * to the #DBusString.
1185  *
1186  * @param str the string
1187  * @param format printf format
1188  * @param args variable argument list
1189  * @returns #FALSE if no memory
1190  */
1191 dbus_bool_t
1192 _dbus_string_append_printf_valist  (DBusString        *str,
1193                                     const char        *format,
1194                                     va_list            args)
1195 {
1196   int len;
1197   va_list args_copy;
1198
1199   DBUS_STRING_PREAMBLE (str);
1200
1201   DBUS_VA_COPY (args_copy, args);
1202
1203   /* Measure the message length without terminating nul */
1204   len = _dbus_printf_string_upper_bound (format, args);
1205
1206   if (!_dbus_string_lengthen (str, len))
1207     {
1208       /* don't leak the copy */
1209       va_end (args_copy);
1210       return FALSE;
1211     }
1212   
1213   vsprintf ((char*) (real->str + (real->len - len)),
1214             format, args_copy);
1215
1216   va_end (args_copy);
1217
1218   return TRUE;
1219 }
1220
1221 /**
1222  * Appends a printf-style formatted string
1223  * to the #DBusString.
1224  *
1225  * @param str the string
1226  * @param format printf format
1227  * @returns #FALSE if no memory
1228  */
1229 dbus_bool_t
1230 _dbus_string_append_printf (DBusString        *str,
1231                             const char        *format,
1232                             ...)
1233 {
1234   va_list args;
1235   dbus_bool_t retval;
1236   
1237   va_start (args, format);
1238   retval = _dbus_string_append_printf_valist (str, format, args);
1239   va_end (args);
1240
1241   return retval;
1242 }
1243
1244 /**
1245  * Appends block of bytes with the given length to a DBusString.
1246  *
1247  * @param str the DBusString
1248  * @param buffer the bytes to append
1249  * @param len the number of bytes to append
1250  * @returns #FALSE if not enough memory.
1251  */
1252 dbus_bool_t
1253 _dbus_string_append_len (DBusString *str,
1254                          const char *buffer,
1255                          int         len)
1256 {
1257   DBUS_STRING_PREAMBLE (str);
1258   _dbus_assert (buffer != NULL);
1259   _dbus_assert (len >= 0);
1260
1261   return append (real, buffer, len);
1262 }
1263
1264 /**
1265  * Appends a single byte to the string, returning #FALSE
1266  * if not enough memory.
1267  *
1268  * @param str the string
1269  * @param byte the byte to append
1270  * @returns #TRUE on success
1271  */
1272 dbus_bool_t
1273 _dbus_string_append_byte (DBusString    *str,
1274                           unsigned char  byte)
1275 {
1276   DBUS_STRING_PREAMBLE (str);
1277
1278   if (!set_length (real, real->len + 1))
1279     return FALSE;
1280
1281   real->str[real->len-1] = byte;
1282
1283   return TRUE;
1284 }
1285
1286 #ifdef DBUS_BUILD_TESTS
1287 /**
1288  * Appends a single Unicode character, encoding the character
1289  * in UTF-8 format.
1290  *
1291  * @param str the string
1292  * @param ch the Unicode character
1293  */
1294 dbus_bool_t
1295 _dbus_string_append_unichar (DBusString    *str,
1296                              dbus_unichar_t ch)
1297 {
1298   int len;
1299   int first;
1300   int i;
1301   unsigned char *out;
1302   
1303   DBUS_STRING_PREAMBLE (str);
1304
1305   /* this code is from GLib but is pretty standard I think */
1306   
1307   len = 0;
1308   
1309   if (ch < 0x80)
1310     {
1311       first = 0;
1312       len = 1;
1313     }
1314   else if (ch < 0x800)
1315     {
1316       first = 0xc0;
1317       len = 2;
1318     }
1319   else if (ch < 0x10000)
1320     {
1321       first = 0xe0;
1322       len = 3;
1323     }
1324    else if (ch < 0x200000)
1325     {
1326       first = 0xf0;
1327       len = 4;
1328     }
1329   else if (ch < 0x4000000)
1330     {
1331       first = 0xf8;
1332       len = 5;
1333     }
1334   else
1335     {
1336       first = 0xfc;
1337       len = 6;
1338     }
1339
1340   if (len > (real->max_length - real->len))
1341     return FALSE; /* real->len + len would overflow */
1342   
1343   if (!set_length (real, real->len + len))
1344     return FALSE;
1345
1346   out = real->str + (real->len - len);
1347   
1348   for (i = len - 1; i > 0; --i)
1349     {
1350       out[i] = (ch & 0x3f) | 0x80;
1351       ch >>= 6;
1352     }
1353   out[0] = ch | first;
1354
1355   return TRUE;
1356 }
1357 #endif /* DBUS_BUILD_TESTS */
1358
1359 static void
1360 delete (DBusRealString *real,
1361         int             start,
1362         int             len)
1363 {
1364   if (len == 0)
1365     return;
1366   
1367   memmove (real->str + start, real->str + start + len, real->len - (start + len));
1368   real->len -= len;
1369   real->str[real->len] = '\0';
1370 }
1371
1372 /**
1373  * Deletes a segment of a DBusString with length len starting at
1374  * start. (Hint: to clear an entire string, setting length to 0
1375  * with _dbus_string_set_length() is easier.)
1376  *
1377  * @param str the DBusString
1378  * @param start where to start deleting
1379  * @param len the number of bytes to delete
1380  */
1381 void
1382 _dbus_string_delete (DBusString       *str,
1383                      int               start,
1384                      int               len)
1385 {
1386   DBUS_STRING_PREAMBLE (str);
1387   _dbus_assert (start >= 0);
1388   _dbus_assert (len >= 0);
1389   _dbus_assert (start <= real->len);
1390   _dbus_assert (len <= real->len - start);
1391   
1392   delete (real, start, len);
1393 }
1394
1395 static dbus_bool_t
1396 copy (DBusRealString *source,
1397       int             start,
1398       int             len,
1399       DBusRealString *dest,
1400       int             insert_at)
1401 {
1402   if (len == 0)
1403     return TRUE;
1404
1405   if (!open_gap (len, dest, insert_at))
1406     return FALSE;
1407   
1408   memmove (dest->str + insert_at,
1409            source->str + start,
1410            len);
1411
1412   return TRUE;
1413 }
1414
1415 /**
1416  * Checks assertions for two strings we're copying a segment between,
1417  * and declares real_source/real_dest variables.
1418  *
1419  * @param source the source string
1420  * @param start the starting offset
1421  * @param dest the dest string
1422  * @param insert_at where the copied segment is inserted
1423  */
1424 #define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at)       \
1425   DBusRealString *real_source = (DBusRealString*) source;               \
1426   DBusRealString *real_dest = (DBusRealString*) dest;                   \
1427   _dbus_assert ((source) != (dest));                                    \
1428   DBUS_GENERIC_STRING_PREAMBLE (real_source);                           \
1429   DBUS_GENERIC_STRING_PREAMBLE (real_dest);                             \
1430   _dbus_assert (!real_dest->constant);                                  \
1431   _dbus_assert (!real_dest->locked);                                    \
1432   _dbus_assert ((start) >= 0);                                          \
1433   _dbus_assert ((start) <= real_source->len);                           \
1434   _dbus_assert ((insert_at) >= 0);                                      \
1435   _dbus_assert ((insert_at) <= real_dest->len)
1436
1437 /**
1438  * Moves the end of one string into another string. Both strings
1439  * must be initialized, valid strings.
1440  *
1441  * @param source the source string
1442  * @param start where to chop off the source string
1443  * @param dest the destination string
1444  * @param insert_at where to move the chopped-off part of source string
1445  * @returns #FALSE if not enough memory
1446  */
1447 dbus_bool_t
1448 _dbus_string_move (DBusString       *source,
1449                    int               start,
1450                    DBusString       *dest,
1451                    int               insert_at)
1452 {
1453   DBusRealString *real_source = (DBusRealString*) source;
1454   _dbus_assert (start <= real_source->len);
1455   
1456   return _dbus_string_move_len (source, start,
1457                                 real_source->len - start,
1458                                 dest, insert_at);
1459 }
1460
1461 /**
1462  * Like _dbus_string_move(), but does not delete the section
1463  * of the source string that's copied to the dest string.
1464  *
1465  * @param source the source string
1466  * @param start where to start copying the source string
1467  * @param dest the destination string
1468  * @param insert_at where to place the copied part of source string
1469  * @returns #FALSE if not enough memory
1470  */
1471 dbus_bool_t
1472 _dbus_string_copy (const DBusString *source,
1473                    int               start,
1474                    DBusString       *dest,
1475                    int               insert_at)
1476 {
1477   DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1478
1479   return copy (real_source, start,
1480                real_source->len - start,
1481                real_dest,
1482                insert_at);
1483 }
1484
1485 /**
1486  * Like _dbus_string_move(), but can move a segment from
1487  * the middle of the source string.
1488  *
1489  * @todo this doesn't do anything with max_length field.
1490  * we should probably just kill the max_length field though.
1491  * 
1492  * @param source the source string
1493  * @param start first byte of source string to move
1494  * @param len length of segment to move
1495  * @param dest the destination string
1496  * @param insert_at where to move the bytes from the source string
1497  * @returns #FALSE if not enough memory
1498  */
1499 dbus_bool_t
1500 _dbus_string_move_len (DBusString       *source,
1501                        int               start,
1502                        int               len,
1503                        DBusString       *dest,
1504                        int               insert_at)
1505
1506 {
1507   DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1508   _dbus_assert (len >= 0);
1509   _dbus_assert ((start + len) <= real_source->len);
1510
1511
1512   if (len == 0)
1513     {
1514       return TRUE;
1515     }
1516   else if (start == 0 &&
1517            len == real_source->len &&
1518            real_dest->len == 0)
1519     {
1520       /* Short-circuit moving an entire existing string to an empty string
1521        * by just swapping the buffers.
1522        */
1523       /* we assume ->constant doesn't matter as you can't have
1524        * a constant string involved in a move.
1525        */
1526 #define ASSIGN_DATA(a, b) do {                  \
1527         (a)->str = (b)->str;                    \
1528         (a)->len = (b)->len;                    \
1529         (a)->allocated = (b)->allocated;        \
1530         (a)->align_offset = (b)->align_offset;  \
1531       } while (0)
1532       
1533       DBusRealString tmp;
1534
1535       ASSIGN_DATA (&tmp, real_source);
1536       ASSIGN_DATA (real_source, real_dest);
1537       ASSIGN_DATA (real_dest, &tmp);
1538
1539       return TRUE;
1540     }
1541   else
1542     {
1543       if (!copy (real_source, start, len,
1544                  real_dest,
1545                  insert_at))
1546         return FALSE;
1547       
1548       delete (real_source, start,
1549               len);
1550       
1551       return TRUE;
1552     }
1553 }
1554
1555 /**
1556  * Like _dbus_string_copy(), but can copy a segment from the middle of
1557  * the source string.
1558  *
1559  * @param source the source string
1560  * @param start where to start copying the source string
1561  * @param len length of segment to copy
1562  * @param dest the destination string
1563  * @param insert_at where to place the copied segment of source string
1564  * @returns #FALSE if not enough memory
1565  */
1566 dbus_bool_t
1567 _dbus_string_copy_len (const DBusString *source,
1568                        int               start,
1569                        int               len,
1570                        DBusString       *dest,
1571                        int               insert_at)
1572 {
1573   DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1574   _dbus_assert (len >= 0);
1575   _dbus_assert (start <= real_source->len);
1576   _dbus_assert (len <= real_source->len - start);
1577   
1578   return copy (real_source, start, len,
1579                real_dest,
1580                insert_at);
1581 }
1582
1583 /**
1584  * Replaces a segment of dest string with a segment of source string.
1585  *
1586  * @todo optimize the case where the two lengths are the same, and
1587  * avoid memmoving the data in the trailing part of the string twice.
1588  *
1589  * @todo avoid inserting the source into dest, then deleting
1590  * the replaced chunk of dest (which creates a potentially large
1591  * intermediate string). Instead, extend the replaced chunk
1592  * of dest with padding to the same size as the source chunk,
1593  * then copy in the source bytes.
1594  * 
1595  * @param source the source string
1596  * @param start where to start copying the source string
1597  * @param len length of segment to copy
1598  * @param dest the destination string
1599  * @param replace_at start of segment of dest string to replace
1600  * @param replace_len length of segment of dest string to replace
1601  * @returns #FALSE if not enough memory
1602  *
1603  */
1604 dbus_bool_t
1605 _dbus_string_replace_len (const DBusString *source,
1606                           int               start,
1607                           int               len,
1608                           DBusString       *dest,
1609                           int               replace_at,
1610                           int               replace_len)
1611 {
1612   DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
1613   _dbus_assert (len >= 0);
1614   _dbus_assert (start <= real_source->len);
1615   _dbus_assert (len <= real_source->len - start);
1616   _dbus_assert (replace_at >= 0);
1617   _dbus_assert (replace_at <= real_dest->len);
1618   _dbus_assert (replace_len <= real_dest->len - replace_at);
1619
1620   if (!copy (real_source, start, len,
1621              real_dest, replace_at))
1622     return FALSE;
1623
1624   delete (real_dest, replace_at + len, replace_len);
1625
1626   return TRUE;
1627 }
1628
1629 /* Unicode macros and utf8_validate() from GLib Owen Taylor, Havoc
1630  * Pennington, and Tom Tromey are the authors and authorized relicense.
1631  */
1632
1633 /** computes length and mask of a unicode character
1634  * @param Char the char
1635  * @param Mask the mask variable to assign to
1636  * @param Len the length variable to assign to
1637  */
1638 #define UTF8_COMPUTE(Char, Mask, Len)                                         \
1639   if (Char < 128)                                                             \
1640     {                                                                         \
1641       Len = 1;                                                                \
1642       Mask = 0x7f;                                                            \
1643     }                                                                         \
1644   else if ((Char & 0xe0) == 0xc0)                                             \
1645     {                                                                         \
1646       Len = 2;                                                                \
1647       Mask = 0x1f;                                                            \
1648     }                                                                         \
1649   else if ((Char & 0xf0) == 0xe0)                                             \
1650     {                                                                         \
1651       Len = 3;                                                                \
1652       Mask = 0x0f;                                                            \
1653     }                                                                         \
1654   else if ((Char & 0xf8) == 0xf0)                                             \
1655     {                                                                         \
1656       Len = 4;                                                                \
1657       Mask = 0x07;                                                            \
1658     }                                                                         \
1659   else if ((Char & 0xfc) == 0xf8)                                             \
1660     {                                                                         \
1661       Len = 5;                                                                \
1662       Mask = 0x03;                                                            \
1663     }                                                                         \
1664   else if ((Char & 0xfe) == 0xfc)                                             \
1665     {                                                                         \
1666       Len = 6;                                                                \
1667       Mask = 0x01;                                                            \
1668     }                                                                         \
1669   else                                                                        \
1670     {                                                                         \
1671       Len = 0;                                                               \
1672       Mask = 0;                                                               \
1673     }
1674
1675 /**
1676  * computes length of a unicode character in UTF-8
1677  * @param Char the char
1678  */
1679 #define UTF8_LENGTH(Char)              \
1680   ((Char) < 0x80 ? 1 :                 \
1681    ((Char) < 0x800 ? 2 :               \
1682     ((Char) < 0x10000 ? 3 :            \
1683      ((Char) < 0x200000 ? 4 :          \
1684       ((Char) < 0x4000000 ? 5 : 6)))))
1685    
1686 /**
1687  * Gets a UTF-8 value.
1688  *
1689  * @param Result variable for extracted unicode char.
1690  * @param Chars the bytes to decode
1691  * @param Count counter variable
1692  * @param Mask mask for this char
1693  * @param Len length for this char in bytes
1694  */
1695 #define UTF8_GET(Result, Chars, Count, Mask, Len)                             \
1696   (Result) = (Chars)[0] & (Mask);                                             \
1697   for ((Count) = 1; (Count) < (Len); ++(Count))                               \
1698     {                                                                         \
1699       if (((Chars)[(Count)] & 0xc0) != 0x80)                                  \
1700         {                                                                     \
1701           (Result) = -1;                                                      \
1702           break;                                                              \
1703         }                                                                     \
1704       (Result) <<= 6;                                                         \
1705       (Result) |= ((Chars)[(Count)] & 0x3f);                                  \
1706     }
1707
1708 /**
1709  * Check whether a unicode char is in a valid range.
1710  *
1711  * @param Char the character
1712  */
1713 #define UNICODE_VALID(Char)                   \
1714     ((Char) < 0x110000 &&                     \
1715      (((Char) & 0xFFFFF800) != 0xD800) &&     \
1716      ((Char) < 0xFDD0 || (Char) > 0xFDEF) &&  \
1717      ((Char) & 0xFFFF) != 0xFFFF)
1718
1719 #ifdef DBUS_BUILD_TESTS
1720 /**
1721  * Gets a unicode character from a UTF-8 string. Does no validation;
1722  * you must verify that the string is valid UTF-8 in advance and must
1723  * pass in the start of a character.
1724  *
1725  * @param str the string
1726  * @param start the start of the UTF-8 character.
1727  * @param ch_return location to return the character
1728  * @param end_return location to return the byte index of next character
1729  */
1730 void
1731 _dbus_string_get_unichar (const DBusString *str,
1732                           int               start,
1733                           dbus_unichar_t   *ch_return,
1734                           int              *end_return)
1735 {
1736   int i, mask, len;
1737   dbus_unichar_t result;
1738   unsigned char c;
1739   unsigned char *p;
1740   DBUS_CONST_STRING_PREAMBLE (str);
1741   _dbus_assert (start >= 0);
1742   _dbus_assert (start <= real->len);
1743   
1744   if (ch_return)
1745     *ch_return = 0;
1746   if (end_return)
1747     *end_return = real->len;
1748   
1749   mask = 0;
1750   p = real->str + start;
1751   c = *p;
1752   
1753   UTF8_COMPUTE (c, mask, len);
1754   if (len == 0)
1755     return;
1756   UTF8_GET (result, p, i, mask, len);
1757
1758   if (result == (dbus_unichar_t)-1)
1759     return;
1760
1761   if (ch_return)
1762     *ch_return = result;
1763   if (end_return)
1764     *end_return = start + len;
1765 }
1766 #endif /* DBUS_BUILD_TESTS */
1767
1768 /**
1769  * Finds the given substring in the string,
1770  * returning #TRUE and filling in the byte index
1771  * where the substring was found, if it was found.
1772  * Returns #FALSE if the substring wasn't found.
1773  * Sets *start to the length of the string if the substring
1774  * is not found.
1775  *
1776  * @param str the string
1777  * @param start where to start looking
1778  * @param substr the substring
1779  * @param found return location for where it was found, or #NULL
1780  * @returns #TRUE if found
1781  */
1782 dbus_bool_t
1783 _dbus_string_find (const DBusString *str,
1784                    int               start,
1785                    const char       *substr,
1786                    int              *found)
1787 {
1788   return _dbus_string_find_to (str, start,
1789                                ((const DBusRealString*)str)->len,
1790                                substr, found);
1791 }
1792
1793 /**
1794  * Finds end of line ("\r\n" or "\n") in the string,
1795  * returning #TRUE and filling in the byte index
1796  * where the eol string was found, if it was found.
1797  * Returns #FALSE if eol wasn't found.
1798  *
1799  * @param str the string
1800  * @param start where to start looking
1801  * @param found return location for where eol was found or string length otherwise
1802  * @param found_len return length of found eol string or zero otherwise
1803  * @returns #TRUE if found
1804  */
1805 dbus_bool_t
1806 _dbus_string_find_eol (const DBusString *str,
1807                    int               start,
1808                    int              *found,
1809                    int              *found_len)
1810 {
1811   int i;
1812
1813   DBUS_CONST_STRING_PREAMBLE (str);
1814   _dbus_assert (start <= real->len);
1815   _dbus_assert (start >= 0);
1816   
1817   i = start;
1818   while (i < real->len)
1819     {
1820       if (real->str[i] == '\r') 
1821         {
1822           if ((i+1) < real->len && real->str[i+1] == '\n') /* "\r\n" */
1823             {
1824               if (found) 
1825                 *found = i;
1826               if (found_len)
1827                 *found_len = 2;
1828               return TRUE;
1829             } 
1830           else /* only "\r" */
1831             {
1832               if (found) 
1833                 *found = i;
1834               if (found_len)
1835                 *found_len = 1;
1836               return TRUE;
1837             }
1838         } 
1839       else if (real->str[i] == '\n')  /* only "\n" */
1840         {
1841           if (found) 
1842             *found = i;
1843           if (found_len)
1844             *found_len = 1;
1845           return TRUE;
1846         }      
1847       ++i;
1848     }
1849
1850   if (found)
1851     *found = real->len;
1852
1853   if (found_len)
1854     *found_len = 0;
1855   
1856   return FALSE;
1857 }
1858
1859 /**
1860  * Finds the given substring in the string,
1861  * up to a certain position,
1862  * returning #TRUE and filling in the byte index
1863  * where the substring was found, if it was found.
1864  * Returns #FALSE if the substring wasn't found.
1865  * Sets *start to the length of the string if the substring
1866  * is not found.
1867  *
1868  * @param str the string
1869  * @param start where to start looking
1870  * @param end where to stop looking
1871  * @param substr the substring
1872  * @param found return location for where it was found, or #NULL
1873  * @returns #TRUE if found
1874  */
1875 dbus_bool_t
1876 _dbus_string_find_to (const DBusString *str,
1877                       int               start,
1878                       int               end,
1879                       const char       *substr,
1880                       int              *found)
1881 {
1882   int i;
1883   DBUS_CONST_STRING_PREAMBLE (str);
1884   _dbus_assert (substr != NULL);
1885   _dbus_assert (start <= real->len);
1886   _dbus_assert (start >= 0);
1887   _dbus_assert (substr != NULL);
1888   _dbus_assert (end <= real->len);
1889   _dbus_assert (start <= end);
1890
1891   /* we always "find" an empty string */
1892   if (*substr == '\0')
1893     {
1894       if (found)
1895         *found = start;
1896       return TRUE;
1897     }
1898
1899   i = start;
1900   while (i < end)
1901     {
1902       if (real->str[i] == substr[0])
1903         {
1904           int j = i + 1;
1905           
1906           while (j < end)
1907             {
1908               if (substr[j - i] == '\0')
1909                 break;
1910               else if (real->str[j] != substr[j - i])
1911                 break;
1912               
1913               ++j;
1914             }
1915
1916           if (substr[j - i] == '\0')
1917             {
1918               if (found)
1919                 *found = i;
1920               return TRUE;
1921             }
1922         }
1923       
1924       ++i;
1925     }
1926
1927   if (found)
1928     *found = end;
1929   
1930   return FALSE;  
1931 }
1932
1933 /**
1934  * Finds a blank (space or tab) in the string. Returns #TRUE
1935  * if found, #FALSE otherwise. If a blank is not found sets
1936  * *found to the length of the string.
1937  *
1938  * @param str the string
1939  * @param start byte index to start looking
1940  * @param found place to store the location of the first blank
1941  * @returns #TRUE if a blank was found
1942  */
1943 dbus_bool_t
1944 _dbus_string_find_blank (const DBusString *str,
1945                          int               start,
1946                          int              *found)
1947 {
1948   int i;
1949   DBUS_CONST_STRING_PREAMBLE (str);
1950   _dbus_assert (start <= real->len);
1951   _dbus_assert (start >= 0);
1952   
1953   i = start;
1954   while (i < real->len)
1955     {
1956       if (real->str[i] == ' ' ||
1957           real->str[i] == '\t')
1958         {
1959           if (found)
1960             *found = i;
1961           return TRUE;
1962         }
1963       
1964       ++i;
1965     }
1966
1967   if (found)
1968     *found = real->len;
1969   
1970   return FALSE;
1971 }
1972
1973 /**
1974  * Skips blanks from start, storing the first non-blank in *end
1975  * (blank is space or tab).
1976  *
1977  * @param str the string
1978  * @param start where to start
1979  * @param end where to store the first non-blank byte index
1980  */
1981 void
1982 _dbus_string_skip_blank (const DBusString *str,
1983                          int               start,
1984                          int              *end)
1985 {
1986   int i;
1987   DBUS_CONST_STRING_PREAMBLE (str);
1988   _dbus_assert (start <= real->len);
1989   _dbus_assert (start >= 0);
1990   
1991   i = start;
1992   while (i < real->len)
1993     {
1994       if (!DBUS_IS_ASCII_BLANK (real->str[i]))
1995         break;
1996       
1997       ++i;
1998     }
1999
2000   _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
2001   
2002   if (end)
2003     *end = i;
2004 }
2005
2006
2007 /**
2008  * Skips whitespace from start, storing the first non-whitespace in *end.
2009  * (whitespace is space, tab, newline, CR).
2010  *
2011  * @param str the string
2012  * @param start where to start
2013  * @param end where to store the first non-whitespace byte index
2014  */
2015 void
2016 _dbus_string_skip_white (const DBusString *str,
2017                          int               start,
2018                          int              *end)
2019 {
2020   int i;
2021   DBUS_CONST_STRING_PREAMBLE (str);
2022   _dbus_assert (start <= real->len);
2023   _dbus_assert (start >= 0);
2024   
2025   i = start;
2026   while (i < real->len)
2027     {
2028       if (!DBUS_IS_ASCII_WHITE (real->str[i]))
2029         break;
2030       
2031       ++i;
2032     }
2033
2034   _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
2035   
2036   if (end)
2037     *end = i;
2038 }
2039
2040 /**
2041  * Skips whitespace from end, storing the start index of the trailing
2042  * whitespace in *start. (whitespace is space, tab, newline, CR).
2043  *
2044  * @param str the string
2045  * @param end where to start scanning backward
2046  * @param start where to store the start of whitespace chars
2047  */
2048 void
2049 _dbus_string_skip_white_reverse (const DBusString *str,
2050                                  int               end,
2051                                  int              *start)
2052 {
2053   int i;
2054   DBUS_CONST_STRING_PREAMBLE (str);
2055   _dbus_assert (end <= real->len);
2056   _dbus_assert (end >= 0);
2057   
2058   i = end;
2059   while (i > 0)
2060     {
2061       if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
2062         break;
2063       --i;
2064     }
2065
2066   _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
2067   
2068   if (start)
2069     *start = i;
2070 }
2071
2072 /**
2073  * Assigns a newline-terminated or \\r\\n-terminated line from the front
2074  * of the string to the given dest string. The dest string's previous
2075  * contents are deleted. If the source string contains no newline,
2076  * moves the entire source string to the dest string.
2077  *
2078  * @todo owen correctly notes that this is a stupid function (it was
2079  * written purely for test code,
2080  * e.g. dbus-message-builder.c). Probably should be enforced as test
2081  * code only with ifdef DBUS_BUILD_TESTS
2082  * 
2083  * @param source the source string
2084  * @param dest the destination string (contents are replaced)
2085  * @returns #FALSE if no memory, or source has length 0
2086  */
2087 dbus_bool_t
2088 _dbus_string_pop_line (DBusString *source,
2089                        DBusString *dest)
2090 {
2091   int eol;
2092   dbus_bool_t have_newline;
2093   
2094   _dbus_string_set_length (dest, 0);
2095   
2096   eol = 0;
2097   if (_dbus_string_find (source, 0, "\n", &eol))
2098     {
2099       have_newline = TRUE;
2100       eol += 1; /* include newline */
2101     }
2102   else
2103     {
2104       eol = _dbus_string_get_length (source);
2105       have_newline = FALSE;
2106     }
2107
2108   if (eol == 0)
2109     return FALSE; /* eof */
2110   
2111   if (!_dbus_string_move_len (source, 0, eol,
2112                               dest, 0))
2113     {
2114       return FALSE;
2115     }
2116
2117   /* dump the newline and the \r if we have one */
2118   if (have_newline)
2119     {
2120       dbus_bool_t have_cr;
2121       
2122       _dbus_assert (_dbus_string_get_length (dest) > 0);
2123
2124       if (_dbus_string_get_length (dest) > 1 &&
2125           _dbus_string_get_byte (dest,
2126                                  _dbus_string_get_length (dest) - 2) == '\r')
2127         have_cr = TRUE;
2128       else
2129         have_cr = FALSE;
2130         
2131       _dbus_string_set_length (dest,
2132                                _dbus_string_get_length (dest) -
2133                                (have_cr ? 2 : 1));
2134     }
2135   
2136   return TRUE;
2137 }
2138
2139 #ifdef DBUS_BUILD_TESTS
2140 /**
2141  * Deletes up to and including the first blank space
2142  * in the string.
2143  *
2144  * @param str the string
2145  */
2146 void
2147 _dbus_string_delete_first_word (DBusString *str)
2148 {
2149   int i;
2150   
2151   if (_dbus_string_find_blank (str, 0, &i))
2152     _dbus_string_skip_blank (str, i, &i);
2153
2154   _dbus_string_delete (str, 0, i);
2155 }
2156 #endif
2157
2158 #ifdef DBUS_BUILD_TESTS
2159 /**
2160  * Deletes any leading blanks in the string
2161  *
2162  * @param str the string
2163  */
2164 void
2165 _dbus_string_delete_leading_blanks (DBusString *str)
2166 {
2167   int i;
2168   
2169   _dbus_string_skip_blank (str, 0, &i);
2170
2171   if (i > 0)
2172     _dbus_string_delete (str, 0, i);
2173 }
2174 #endif
2175
2176 /**
2177  * Deletes leading and trailing whitespace
2178  * 
2179  * @param str the string
2180  */
2181 void
2182 _dbus_string_chop_white(DBusString *str)
2183 {
2184   int i;
2185   
2186   _dbus_string_skip_white (str, 0, &i);
2187
2188   if (i > 0)
2189     _dbus_string_delete (str, 0, i);
2190   
2191   _dbus_string_skip_white_reverse (str, _dbus_string_get_length (str), &i);
2192
2193   _dbus_string_set_length (str, i);
2194 }
2195
2196 /**
2197  * Tests two DBusString for equality.
2198  *
2199  * @todo memcmp is probably faster
2200  *
2201  * @param a first string
2202  * @param b second string
2203  * @returns #TRUE if equal
2204  */
2205 dbus_bool_t
2206 _dbus_string_equal (const DBusString *a,
2207                     const DBusString *b)
2208 {
2209   const unsigned char *ap;
2210   const unsigned char *bp;
2211   const unsigned char *a_end;
2212   const DBusRealString *real_a = (const DBusRealString*) a;
2213   const DBusRealString *real_b = (const DBusRealString*) b;
2214   DBUS_GENERIC_STRING_PREAMBLE (real_a);
2215   DBUS_GENERIC_STRING_PREAMBLE (real_b);
2216
2217   if (real_a->len != real_b->len)
2218     return FALSE;
2219
2220   ap = real_a->str;
2221   bp = real_b->str;
2222   a_end = real_a->str + real_a->len;
2223   while (ap != a_end)
2224     {
2225       if (*ap != *bp)
2226         return FALSE;
2227       
2228       ++ap;
2229       ++bp;
2230     }
2231
2232   return TRUE;
2233 }
2234
2235 #ifdef DBUS_BUILD_TESTS
2236 /**
2237  * Tests two DBusString for equality up to the given length.
2238  * The strings may be shorter than the given length.
2239  *
2240  * @todo write a unit test
2241  *
2242  * @todo memcmp is probably faster
2243  *
2244  * @param a first string
2245  * @param b second string
2246  * @param len the maximum length to look at
2247  * @returns #TRUE if equal for the given number of bytes
2248  */
2249 dbus_bool_t
2250 _dbus_string_equal_len (const DBusString *a,
2251                         const DBusString *b,
2252                         int               len)
2253 {
2254   const unsigned char *ap;
2255   const unsigned char *bp;
2256   const unsigned char *a_end;
2257   const DBusRealString *real_a = (const DBusRealString*) a;
2258   const DBusRealString *real_b = (const DBusRealString*) b;
2259   DBUS_GENERIC_STRING_PREAMBLE (real_a);
2260   DBUS_GENERIC_STRING_PREAMBLE (real_b);
2261
2262   if (real_a->len != real_b->len &&
2263       (real_a->len < len || real_b->len < len))
2264     return FALSE;
2265
2266   ap = real_a->str;
2267   bp = real_b->str;
2268   a_end = real_a->str + MIN (real_a->len, len);
2269   while (ap != a_end)
2270     {
2271       if (*ap != *bp)
2272         return FALSE;
2273       
2274       ++ap;
2275       ++bp;
2276     }
2277
2278   return TRUE;
2279 }
2280 #endif /* DBUS_BUILD_TESTS */
2281
2282 /**
2283  * Tests two sub-parts of two DBusString for equality.  The specified
2284  * range of the first string must exist; the specified start position
2285  * of the second string must exist.
2286  *
2287  * @todo write a unit test
2288  *
2289  * @todo memcmp is probably faster
2290  *
2291  * @param a first string
2292  * @param a_start where to start substring in first string
2293  * @param a_len length of substring in first string
2294  * @param b second string
2295  * @param b_start where to start substring in second string
2296  * @returns #TRUE if the two substrings are equal
2297  */
2298 dbus_bool_t
2299 _dbus_string_equal_substring (const DBusString  *a,
2300                               int                a_start,
2301                               int                a_len,
2302                               const DBusString  *b,
2303                               int                b_start)
2304 {
2305   const unsigned char *ap;
2306   const unsigned char *bp;
2307   const unsigned char *a_end;
2308   const DBusRealString *real_a = (const DBusRealString*) a;
2309   const DBusRealString *real_b = (const DBusRealString*) b;
2310   DBUS_GENERIC_STRING_PREAMBLE (real_a);
2311   DBUS_GENERIC_STRING_PREAMBLE (real_b);
2312   _dbus_assert (a_start >= 0);
2313   _dbus_assert (a_len >= 0);
2314   _dbus_assert (a_start <= real_a->len);
2315   _dbus_assert (a_len <= real_a->len - a_start);
2316   _dbus_assert (b_start >= 0);
2317   _dbus_assert (b_start <= real_b->len);
2318   
2319   if (a_len > real_b->len - b_start)
2320     return FALSE;
2321
2322   ap = real_a->str + a_start;
2323   bp = real_b->str + b_start;
2324   a_end = ap + a_len;
2325   while (ap != a_end)
2326     {
2327       if (*ap != *bp)
2328         return FALSE;
2329       
2330       ++ap;
2331       ++bp;
2332     }
2333
2334   _dbus_assert (bp <= (real_b->str + real_b->len));
2335   
2336   return TRUE;
2337 }
2338
2339 /**
2340  * Checks whether a string is equal to a C string.
2341  *
2342  * @param a the string
2343  * @param c_str the C string
2344  * @returns #TRUE if equal
2345  */
2346 dbus_bool_t
2347 _dbus_string_equal_c_str (const DBusString *a,
2348                           const char       *c_str)
2349 {
2350   const unsigned char *ap;
2351   const unsigned char *bp;
2352   const unsigned char *a_end;
2353   const DBusRealString *real_a = (const DBusRealString*) a;
2354   DBUS_GENERIC_STRING_PREAMBLE (real_a);
2355   _dbus_assert (c_str != NULL);
2356   
2357   ap = real_a->str;
2358   bp = (const unsigned char*) c_str;
2359   a_end = real_a->str + real_a->len;
2360   while (ap != a_end && *bp)
2361     {
2362       if (*ap != *bp)
2363         return FALSE;
2364       
2365       ++ap;
2366       ++bp;
2367     }
2368
2369   if (ap != a_end || *bp)
2370     return FALSE;
2371   
2372   return TRUE;
2373 }
2374
2375 #ifdef DBUS_BUILD_TESTS
2376 /**
2377  * Checks whether a string starts with the given C string.
2378  *
2379  * @param a the string
2380  * @param c_str the C string
2381  * @returns #TRUE if string starts with it
2382  */
2383 dbus_bool_t
2384 _dbus_string_starts_with_c_str (const DBusString *a,
2385                                 const char       *c_str)
2386 {
2387   const unsigned char *ap;
2388   const unsigned char *bp;
2389   const unsigned char *a_end;
2390   const DBusRealString *real_a = (const DBusRealString*) a;
2391   DBUS_GENERIC_STRING_PREAMBLE (real_a);
2392   _dbus_assert (c_str != NULL);
2393   
2394   ap = real_a->str;
2395   bp = (const unsigned char*) c_str;
2396   a_end = real_a->str + real_a->len;
2397   while (ap != a_end && *bp)
2398     {
2399       if (*ap != *bp)
2400         return FALSE;
2401       
2402       ++ap;
2403       ++bp;
2404     }
2405
2406   if (*bp == '\0')
2407     return TRUE;
2408   else
2409     return FALSE;
2410 }
2411 #endif /* DBUS_BUILD_TESTS */
2412
2413 /**
2414  * Appends a two-character hex digit to a string, where the hex digit
2415  * has the value of the given byte.
2416  *
2417  * @param str the string
2418  * @param byte the byte
2419  * @returns #FALSE if no memory
2420  */
2421 dbus_bool_t
2422 _dbus_string_append_byte_as_hex (DBusString *str,
2423                                  int         byte)
2424 {
2425   const char hexdigits[16] = {
2426     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
2427     'a', 'b', 'c', 'd', 'e', 'f'
2428   };
2429
2430   if (!_dbus_string_append_byte (str,
2431                                  hexdigits[(byte >> 4)]))
2432     return FALSE;
2433   
2434   if (!_dbus_string_append_byte (str,
2435                                  hexdigits[(byte & 0x0f)]))
2436     {
2437       _dbus_string_set_length (str,
2438                                _dbus_string_get_length (str) - 1);
2439       return FALSE;
2440     }
2441
2442   return TRUE;
2443 }
2444
2445 /**
2446  * Encodes a string in hex, the way MD5 and SHA-1 are usually
2447  * encoded. (Each byte is two hex digits.)
2448  *
2449  * @param source the string to encode
2450  * @param start byte index to start encoding
2451  * @param dest string where encoded data should be placed
2452  * @param insert_at where to place encoded data
2453  * @returns #TRUE if encoding was successful, #FALSE if no memory etc.
2454  */
2455 dbus_bool_t
2456 _dbus_string_hex_encode (const DBusString *source,
2457                          int               start,
2458                          DBusString       *dest,
2459                          int               insert_at)
2460 {
2461   DBusString result;
2462   const unsigned char *p;
2463   const unsigned char *end;
2464   dbus_bool_t retval;
2465   
2466   _dbus_assert (start <= _dbus_string_get_length (source));
2467
2468   if (!_dbus_string_init (&result))
2469     return FALSE;
2470
2471   retval = FALSE;
2472   
2473   p = (const unsigned char*) _dbus_string_get_const_data (source);
2474   end = p + _dbus_string_get_length (source);
2475   p += start;
2476   
2477   while (p != end)
2478     {
2479       if (!_dbus_string_append_byte_as_hex (&result, *p))
2480         goto out;
2481       
2482       ++p;
2483     }
2484
2485   if (!_dbus_string_move (&result, 0, dest, insert_at))
2486     goto out;
2487
2488   retval = TRUE;
2489
2490  out:
2491   _dbus_string_free (&result);
2492   return retval;
2493 }
2494
2495 /**
2496  * Decodes a string from hex encoding.
2497  *
2498  * @param source the string to decode
2499  * @param start byte index to start decode
2500  * @param end_return return location of the end of the hex data, or #NULL
2501  * @param dest string where decoded data should be placed
2502  * @param insert_at where to place decoded data
2503  * @returns #TRUE if decoding was successful, #FALSE if no memory.
2504  */
2505 dbus_bool_t
2506 _dbus_string_hex_decode (const DBusString *source,
2507                          int               start,
2508                          int              *end_return,
2509                          DBusString       *dest,
2510                          int               insert_at)
2511 {
2512   DBusString result;
2513   const unsigned char *p;
2514   const unsigned char *end;
2515   dbus_bool_t retval;
2516   dbus_bool_t high_bits;
2517   
2518   _dbus_assert (start <= _dbus_string_get_length (source));
2519
2520   if (!_dbus_string_init (&result))
2521     return FALSE;
2522
2523   retval = FALSE;
2524
2525   high_bits = TRUE;
2526   p = (const unsigned char*) _dbus_string_get_const_data (source);
2527   end = p + _dbus_string_get_length (source);
2528   p += start;
2529   
2530   while (p != end)
2531     {
2532       unsigned int val;
2533
2534       switch (*p)
2535         {
2536         case '0':
2537           val = 0;
2538           break;
2539         case '1':
2540           val = 1;
2541           break;
2542         case '2':
2543           val = 2;
2544           break;
2545         case '3':
2546           val = 3;
2547           break;
2548         case '4':
2549           val = 4;
2550           break;
2551         case '5':
2552           val = 5;
2553           break;
2554         case '6':
2555           val = 6;
2556           break;
2557         case '7':
2558           val = 7;
2559           break;
2560         case '8':
2561           val = 8;
2562           break;
2563         case '9':
2564           val = 9;
2565           break;
2566         case 'a':
2567         case 'A':
2568           val = 10;
2569           break;
2570         case 'b':
2571         case 'B':
2572           val = 11;
2573           break;
2574         case 'c':
2575         case 'C':
2576           val = 12;
2577           break;
2578         case 'd':
2579         case 'D':
2580           val = 13;
2581           break;
2582         case 'e':
2583         case 'E':
2584           val = 14;
2585           break;
2586         case 'f':
2587         case 'F':
2588           val = 15;
2589           break;
2590         default:
2591           goto done;
2592         }
2593
2594       if (high_bits)
2595         {
2596           if (!_dbus_string_append_byte (&result,
2597                                          val << 4))
2598             goto out;
2599         }
2600       else
2601         {
2602           int len;
2603           unsigned char b;
2604
2605           len = _dbus_string_get_length (&result);
2606           
2607           b = _dbus_string_get_byte (&result, len - 1);
2608
2609           b |= val;
2610
2611           _dbus_string_set_byte (&result, len - 1, b);
2612         }
2613
2614       high_bits = !high_bits;
2615
2616       ++p;
2617     }
2618
2619  done:
2620   if (!_dbus_string_move (&result, 0, dest, insert_at))
2621     goto out;
2622
2623   if (end_return)
2624     *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
2625
2626   retval = TRUE;
2627   
2628  out:
2629   _dbus_string_free (&result);  
2630   return retval;
2631 }
2632
2633 /**
2634  * Checks that the given range of the string is valid ASCII with no
2635  * nul bytes. If the given range is not entirely contained in the
2636  * string, returns #FALSE.
2637  *
2638  * @todo this is inconsistent with most of DBusString in that
2639  * it allows a start,len range that extends past the string end.
2640  * 
2641  * @param str the string
2642  * @param start first byte index to check
2643  * @param len number of bytes to check
2644  * @returns #TRUE if the byte range exists and is all valid ASCII
2645  */
2646 dbus_bool_t
2647 _dbus_string_validate_ascii (const DBusString *str,
2648                              int               start,
2649                              int               len)
2650 {
2651   const unsigned char *s;
2652   const unsigned char *end;
2653   DBUS_CONST_STRING_PREAMBLE (str);
2654   _dbus_assert (start >= 0);
2655   _dbus_assert (start <= real->len);
2656   _dbus_assert (len >= 0);
2657   
2658   if (len > real->len - start)
2659     return FALSE;
2660   
2661   s = real->str + start;
2662   end = s + len;
2663   while (s != end)
2664     {
2665       if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
2666         return FALSE;
2667         
2668       ++s;
2669     }
2670   
2671   return TRUE;
2672 }
2673
2674 /**
2675  * Checks that the given range of the string is valid UTF-8. If the
2676  * given range is not entirely contained in the string, returns
2677  * #FALSE. If the string contains any nul bytes in the given range,
2678  * returns #FALSE. If the start and start+len are not on character
2679  * boundaries, returns #FALSE.
2680  *
2681  * @todo this is inconsistent with most of DBusString in that
2682  * it allows a start,len range that extends past the string end.
2683  * 
2684  * @param str the string
2685  * @param start first byte index to check
2686  * @param len number of bytes to check
2687  * @returns #TRUE if the byte range exists and is all valid UTF-8
2688  */
2689 dbus_bool_t
2690 _dbus_string_validate_utf8  (const DBusString *str,
2691                              int               start,
2692                              int               len)
2693 {
2694   const unsigned char *p;
2695   const unsigned char *end;
2696   DBUS_CONST_STRING_PREAMBLE (str);
2697   _dbus_assert (start >= 0);
2698   _dbus_assert (start <= real->len);
2699   _dbus_assert (len >= 0);
2700
2701   /* we are doing _DBUS_UNLIKELY() here which might be
2702    * dubious in a generic library like GLib, but in D-Bus
2703    * we know we're validating messages and that it would
2704    * only be evil/broken apps that would have invalid
2705    * UTF-8. Also, this function seems to be a performance
2706    * bottleneck in profiles.
2707    */
2708   
2709   if (_DBUS_UNLIKELY (len > real->len - start))
2710     return FALSE;
2711   
2712   p = real->str + start;
2713   end = p + len;
2714   
2715   while (p < end)
2716     {
2717       int i, mask, char_len;
2718       dbus_unichar_t result;
2719
2720       /* nul bytes considered invalid */
2721       if (*p == '\0')
2722         break;
2723       
2724       /* Special-case ASCII; this makes us go a lot faster in
2725        * D-Bus profiles where we are typically validating
2726        * function names and such. We have to know that
2727        * all following checks will pass for ASCII though,
2728        * comments follow ...
2729        */      
2730       if (*p < 128)
2731         {
2732           ++p;
2733           continue;
2734         }
2735       
2736       UTF8_COMPUTE (*p, mask, char_len);
2737
2738       if (_DBUS_UNLIKELY (char_len == 0))  /* ASCII: char_len == 1 */
2739         break;
2740
2741       /* check that the expected number of bytes exists in the remaining length */
2742       if (_DBUS_UNLIKELY ((end - p) < char_len)) /* ASCII: p < end and char_len == 1 */
2743         break;
2744         
2745       UTF8_GET (result, p, i, mask, char_len);
2746
2747       /* Check for overlong UTF-8 */
2748       if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* ASCII: UTF8_LENGTH == 1 */
2749         break;
2750 #if 0
2751       /* The UNICODE_VALID check below will catch this */
2752       if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) /* ASCII: result = ascii value */
2753         break;
2754 #endif
2755
2756       if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) /* ASCII: always valid */
2757         break;
2758
2759       /* UNICODE_VALID should have caught it */
2760       _dbus_assert (result != (dbus_unichar_t)-1);
2761       
2762       p += char_len;
2763     }
2764
2765   /* See that we covered the entire length if a length was
2766    * passed in
2767    */
2768   if (_DBUS_UNLIKELY (p != end))
2769     return FALSE;
2770   else
2771     return TRUE;
2772 }
2773
2774 /**
2775  * Checks that the given range of the string is all nul bytes. If the
2776  * given range is not entirely contained in the string, returns
2777  * #FALSE.
2778  *
2779  * @todo this is inconsistent with most of DBusString in that
2780  * it allows a start,len range that extends past the string end.
2781  * 
2782  * @param str the string
2783  * @param start first byte index to check
2784  * @param len number of bytes to check
2785  * @returns #TRUE if the byte range exists and is all nul bytes
2786  */
2787 dbus_bool_t
2788 _dbus_string_validate_nul (const DBusString *str,
2789                            int               start,
2790                            int               len)
2791 {
2792   const unsigned char *s;
2793   const unsigned char *end;
2794   DBUS_CONST_STRING_PREAMBLE (str);
2795   _dbus_assert (start >= 0);
2796   _dbus_assert (len >= 0);
2797   _dbus_assert (start <= real->len);
2798   
2799   if (len > real->len - start)
2800     return FALSE;
2801   
2802   s = real->str + start;
2803   end = s + len;
2804   while (s != end)
2805     {
2806       if (_DBUS_UNLIKELY (*s != '\0'))
2807         return FALSE;
2808       ++s;
2809     }
2810   
2811   return TRUE;
2812 }
2813
2814 /**
2815  * Clears all allocated bytes in the string to zero.
2816  *
2817  * @param str the string
2818  */
2819 void
2820 _dbus_string_zero (DBusString *str)
2821 {
2822   DBUS_STRING_PREAMBLE (str);
2823
2824   memset (real->str - real->align_offset, '\0', real->allocated);
2825 }
2826 /** @} */
2827
2828 /* tests are in dbus-string-util.c */