dbus-string.c revision 47e37899a3daf33ab799f674c2dc8ce869cdd5fa
1d012387afef0ba02185ebe27bc6bb15551912e92Havoc Pennington/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
27652304bff969afb3969603149bb385efe861fe8John (J/* dbus-string.c String utility class (internal to D-Bus implementation)
3d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
4b3416423b1e3c17357833d896c1b7cd684660771Havoc Pennington * Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
5cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * Copyright (C) 2006 Ralf Habacker <ralf.habacker@freenet.de>
6d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
743605a6f4e78a8c28afb4b1e924dff0301e0e95cHavoc Pennington * Licensed under the Academic Free License version 2.1
8d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
9d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * This program is free software; you can redistribute it and/or modify
10d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * it under the terms of the GNU General Public License as published by
11d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the Free Software Foundation; either version 2 of the License, or
12d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * (at your option) any later version.
13d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
14d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * This program is distributed in the hope that it will be useful,
15d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * but WITHOUT ANY WARRANTY; without even the implied warranty of
16d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * GNU General Public License for more details.
18d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
19d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * You should have received a copy of the GNU General Public License
20d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * along with this program; if not, write to the Free Software
215baf2f856a9c6625993234855b07680da1c8916fTobias Mueller * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
23d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
24d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
25271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington#include "dbus-internals.h"
26d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#include "dbus-string.h"
27d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/* we allow a system header here, for speed/convenience */
28d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#include <string.h>
291d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington/* for vsnprintf */
301d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington#include <stdio.h>
3113f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington#define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
3213f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington#include "dbus-string-private.h"
339c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington#include "dbus-marshal-basic.h" /* probably should be removed by moving the usage of DBUS_TYPE
349c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                 * into the marshaling-related files
359c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                 */
36868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen/* for DBUS_VA_COPY */
37868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen#include "dbus-sysdeps.h"
38d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
39d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
40e19ebac55d671ecd92877af182300311afa7641aHavoc Pennington * @defgroup DBusString DBusString class
41d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @ingroup  DBusInternals
42e19ebac55d671ecd92877af182300311afa7641aHavoc Pennington * @brief DBusString data structure for safer string handling
43d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
44d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Types and functions related to DBusString. DBusString is intended
45d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * to be a string class that makes it hard to mess up security issues
46d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * (and just in general harder to write buggy code).  It should be
47d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * used (or extended and then used) rather than the libc stuff in
48d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * string.h.  The string class is a bit inconvenient at spots because
49d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * it handles out-of-memory failures and tries to be extra-robust.
50d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
51d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * A DBusString has a maximum length set at initialization time; this
52d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * can be used to ensure that a buffer doesn't get too big.  The
53d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * _dbus_string_lengthen() method checks for overflow, and for max
54d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * length being exceeded.
55d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
56d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Try to avoid conversion to a plain C string, i.e. add methods on
57d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the string object instead, only convert to C string when passing
58d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * things out to the public API. In particular, no sprintf, strcpy,
59d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * strcat, any of that should be used. The GString feature of
60d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * accepting negative numbers for "length of string" is also absent,
61d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * because it could keep us from detecting bogus huge lengths. i.e. if
62d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * we passed in some bogus huge length it would be taken to mean
63d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * "current length of string" instead of "broken crack"
6407d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington *
6507d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * @todo #DBusString needs a lot of cleaning up; some of the
6607d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * API is no longer used, and the API is pretty inconsistent.
6707d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * In particular all the "append" APIs, especially those involving
6807d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * alignment but probably lots of them, are no longer used by the
6907d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * marshaling code which always does "inserts" now.
70d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
71d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
72d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
73d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @addtogroup DBusString
74d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @{
75d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
76d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
77b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Penningtonstatic void
78b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Penningtonfixup_alignment (DBusRealString *real)
79b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington{
806606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  unsigned char *aligned;
816606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  unsigned char *real_block;
82b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  unsigned int old_align_offset;
83b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
84b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  /* we have to have extra space in real->allocated for the align offset and nul byte */
859c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (real->len <= real->allocated - _DBUS_STRING_ALLOCATION_PADDING);
86b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
87b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  old_align_offset = real->align_offset;
88b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  real_block = real->str - old_align_offset;
89b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
90b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  aligned = _DBUS_ALIGN_ADDRESS (real_block, 8);
91b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
92b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  real->align_offset = aligned - real_block;
93b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  real->str = aligned;
94b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
95b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (old_align_offset != real->align_offset)
96b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    {
97b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington      /* Here comes the suck */
98b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington      memmove (real_block + real->align_offset,
99b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington               real_block + old_align_offset,
100b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington               real->len + 1);
101b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    }
102b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
103b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (real->align_offset < 8);
104b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str);
105b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington}
106650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington
10713f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Penningtonstatic void
10813f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Penningtonundo_alignment (DBusRealString *real)
10913f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington{
11013f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington  if (real->align_offset != 0)
11113f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington    {
11213f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington      memmove (real->str - real->align_offset,
11313f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington               real->str,
11413f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington               real->len + 1);
11513f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington
11613f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington      real->str = real->str - real->align_offset;
117ce173b29fc1e9432cb5956952afdbe775da12415Havoc Pennington      real->align_offset = 0;
11813f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington    }
11913f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington}
12013f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington
121d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
122d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * Initializes a string that can be up to the given allocation size
123d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * before it has to realloc. The string starts life with zero length.
124d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * The string must eventually be freed with _dbus_string_free().
1251d2478ae4f2da8869eab94ca455a1329230c179eHavoc Pennington *
126d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str memory to hold the string
127d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param allocate_size amount to preallocate
128fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * @returns #TRUE on success, #FALSE if no memory
129fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington */
130d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
131d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington_dbus_string_init_preallocated (DBusString *str,
132d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                                int         allocate_size)
133d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
134d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusRealString *real;
135d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
136d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (str != NULL);
137d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
138d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (sizeof (DBusString) == sizeof (DBusRealString));
139d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
140d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real = (DBusRealString*) str;
141d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
142d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* It's very important not to touch anything
143d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   * other than real->str if we're going to fail,
144d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   * since we also use this function to reset
145d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   * an existing string, e.g. in _dbus_string_steal_data()
146d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   */
147d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1489c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  real->str = dbus_malloc (_DBUS_STRING_ALLOCATION_PADDING + allocate_size);
149d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (real->str == NULL)
150650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington    return FALSE;
151650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington
1529c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  real->allocated = _DBUS_STRING_ALLOCATION_PADDING + allocate_size;
153d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->len = 0;
154d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->str[real->len] = '\0';
155d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1567bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington  real->max_length = _DBUS_STRING_MAX_MAX_LENGTH;
157d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->constant = FALSE;
158d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->locked = FALSE;
159d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->invalid = FALSE;
160b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  real->align_offset = 0;
161b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
162b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  fixup_alignment (real);
163650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington
164d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
165d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
166d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
167d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington/**
168d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * Initializes a string. The string starts life with zero length.  The
169d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * string must eventually be freed with _dbus_string_free().
170d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington *
171d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param str memory to hold the string
172d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @returns #TRUE on success, #FALSE if no memory
173d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington */
174d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtondbus_bool_t
175d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington_dbus_string_init (DBusString *str)
176d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington{
177d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  return _dbus_string_init_preallocated (str, 0);
178d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington}
179d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1807bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
181fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington/* The max length thing is sort of a historical artifact
182fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * from a feature that turned out to be dumb; perhaps
183fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * we should purge it entirely. The problem with
184fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * the feature is that it looks like memory allocation
185fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * failure, but is not a transient or resolvable failure.
186fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington */
187fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonstatic void
188fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonset_max_length (DBusString *str,
189fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington                int         max_length)
190fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington{
191fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  DBusRealString *real;
192fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
193fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  real = (DBusRealString*) str;
194fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
195fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  real->max_length = max_length;
196fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington}
1977bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
198fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
199d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
200d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Initializes a constant string. The value parameter is not copied
201d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * (should be static), and the string may never be modified.
202d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * It is safe but not necessary to call _dbus_string_free()
203b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * on a const string. The string has a length limit of MAXINT - 8.
204d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
205d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str memory to use for the string
206d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param value a string to be stored in str (not copied!!!)
207d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
208d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
209d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_init_const (DBusString *str,
210d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                         const char *value)
211d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
212b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (value != NULL);
213b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
21450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_string_init_const_len (str, value,
21550c25505f62786756519ef1e194883360eda82e0Havoc Pennington                               strlen (value));
21650c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
21750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
21850c25505f62786756519ef1e194883360eda82e0Havoc Pennington/**
21950c25505f62786756519ef1e194883360eda82e0Havoc Pennington * Initializes a constant string with a length. The value parameter is
22050c25505f62786756519ef1e194883360eda82e0Havoc Pennington * not copied (should be static), and the string may never be
22150c25505f62786756519ef1e194883360eda82e0Havoc Pennington * modified.  It is safe but not necessary to call _dbus_string_free()
22250c25505f62786756519ef1e194883360eda82e0Havoc Pennington * on a const string.
22350c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
22450c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param str memory to use for the string
22550c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param value a string to be stored in str (not copied!!!)
22650c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param len the length to use
22750c25505f62786756519ef1e194883360eda82e0Havoc Pennington */
22850c25505f62786756519ef1e194883360eda82e0Havoc Penningtonvoid
22950c25505f62786756519ef1e194883360eda82e0Havoc Pennington_dbus_string_init_const_len (DBusString *str,
23050c25505f62786756519ef1e194883360eda82e0Havoc Pennington                             const char *value,
23150c25505f62786756519ef1e194883360eda82e0Havoc Pennington                             int         len)
23250c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
233d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusRealString *real;
234d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
235d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (str != NULL);
2360d0642b31b9bac2546f9fa2c6bdc55b5ced0b7adRobert McQueen  _dbus_assert (len == 0 || value != NULL);
2377bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington  _dbus_assert (len <= _DBUS_STRING_MAX_MAX_LENGTH);
238b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len >= 0);
239b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
240d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real = (DBusRealString*) str;
241d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
2426606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  real->str = (unsigned char*) value;
24350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  real->len = len;
2449c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  real->allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING; /* a lie, just to avoid special-case assertions... */
245b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  real->max_length = real->len + 1;
246d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->constant = TRUE;
2479c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  real->locked = TRUE;
248d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->invalid = FALSE;
2499c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  real->align_offset = 0;
250650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington
251650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington  /* We don't require const strings to be 8-byte aligned as the
252650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington   * memory is coming from elsewhere.
253650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington   */
254d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
255d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
256d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
257d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Frees a string created by _dbus_string_init().
258d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
259d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str memory where the string is stored.
260d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
261d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
262d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_free (DBusString *str)
263d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
26405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  DBusRealString *real = (DBusRealString*) str;
26505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real);
266d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
267d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (real->constant)
268d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return;
26913f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington  dbus_free (real->str - real->align_offset);
270d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
271d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->invalid = TRUE;
272d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
273d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
2748c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortiestatic dbus_bool_t
2758c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortiecompact (DBusRealString *real,
2768c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie         int             max_waste)
2778c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie{
2788c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  unsigned char *new_str;
2798c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  int new_allocated;
2808c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  int waste;
2818c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
2828c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  waste = real->allocated - (real->len + _DBUS_STRING_ALLOCATION_PADDING);
2838c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
2848c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  if (waste <= max_waste)
2858c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie    return TRUE;
2868c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
2878c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  new_allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING;
2888c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
2898c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
2908c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  if (_DBUS_UNLIKELY (new_str == NULL))
2918c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie    return FALSE;
2928c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
2938c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  real->str = new_str + real->align_offset;
2948c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  real->allocated = new_allocated;
2958c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  fixup_alignment (real);
2968c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
2978c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  return TRUE;
2988c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie}
2998c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
300d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington#ifdef DBUS_BUILD_TESTS
301d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington/* Not using this feature at the moment,
302d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington * so marked DBUS_BUILD_TESTS-only
303d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington */
304d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
305b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * Locks a string such that any attempts to change the string will
306b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * result in aborting the program. Also, if the string is wasting a
307b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * lot of memory (allocation is sufficiently larger than what the
308b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * string is really using), _dbus_string_lock() will realloc the
309b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * string's data to "compact" it.
310d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
311d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string to lock.
312d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
313d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
314d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_lock (DBusString *str)
315d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
316d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_LOCKED_STRING_PREAMBLE (str); /* can lock multiple times */
317d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
318d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->locked = TRUE;
319d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
320d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* Try to realloc to avoid excess memory usage, since
321d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   * we know we won't change the string further
322d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   */
323b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington#define MAX_WASTE 48
3248c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  compact (real, MAX_WASTE);
325d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
326d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington#endif /* DBUS_BUILD_TESTS */
327d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
328e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtonstatic dbus_bool_t
329d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtonreallocate_for_length (DBusRealString *real,
330d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                       int             new_length)
331e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington{
332d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  int new_allocated;
3336606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  unsigned char *new_str;
334b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
335d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  /* at least double our old allocation to avoid O(n), avoiding
336d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington   * overflow
337d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington   */
3387bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington  if (real->allocated > (_DBUS_STRING_MAX_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2)
3397bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington    new_allocated = _DBUS_STRING_MAX_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING;
340d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  else
341d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    new_allocated = real->allocated * 2;
342b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
343d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  /* if you change the code just above here, run the tests without
3441b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington   * the following assert-only hack before you commit
345d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington   */
3461b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington  /* This is keyed off asserts in addition to tests so when you
3471b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington   * disable asserts to profile, you don't get this destroyer
3481b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington   * of profiles.
3491b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington   */
3501b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington#ifdef DBUS_DISABLE_ASSERT
3511b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington#else
35221cef58bc1b46ba4d5e7371463920c7744904d32Havoc Pennington#ifdef DBUS_BUILD_TESTS
353d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  new_allocated = 0; /* ensure a realloc every time so that we go
354d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                      * through all malloc failure codepaths
355d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                      */
3561b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington#endif /* DBUS_BUILD_TESTS */
3571b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington#endif /* !DBUS_DISABLE_ASSERT */
3581b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington
359d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  /* But be sure we always alloc at least space for the new length */
3601b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington  new_allocated = MAX (new_allocated,
3619c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                       new_length + _DBUS_STRING_ALLOCATION_PADDING);
362e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
363d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  _dbus_assert (new_allocated >= real->allocated); /* code relies on this */
364d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
3651b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington  if (_DBUS_UNLIKELY (new_str == NULL))
366d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
367e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
368d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  real->str = new_str + real->align_offset;
369d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  real->allocated = new_allocated;
370d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  fixup_alignment (real);
371e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
372e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  return TRUE;
373e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington}
374e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
3758c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie/**
3768c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie * Compacts the string to avoid wasted memory.  Wasted memory is
3778c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie * memory that is allocated but not actually required to store the
3788c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie * current length of the string.  The compact is only done if more
3798c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie * than the given amount of memory is being wasted (otherwise the
3808c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie * waste is ignored and the call does nothing).
3818c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie *
3828c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie * @param str the string
3838c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie * @param max_waste the maximum amount of waste to ignore
3848c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie * @returns #FALSE if the compact failed due to realloc failure
3858c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie */
3868c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortiedbus_bool_t
3878c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie_dbus_string_compact (DBusString *str,
3888c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie                      int         max_waste)
3898c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie{
3908c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  DBUS_STRING_PREAMBLE (str);
3918c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
3928c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  return compact (real, max_waste);
3938c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie}
3948c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
395e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtonstatic dbus_bool_t
396d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtonset_length (DBusRealString *real,
397d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington            int             new_length)
398d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington{
399d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  /* Note, we are setting the length not including nul termination */
400d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
401d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  /* exceeding max length is the same as failure to allocate memory */
4021b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington  if (_DBUS_UNLIKELY (new_length > real->max_length))
403d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
4049c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) &&
4051b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington           _DBUS_UNLIKELY (!reallocate_for_length (real, new_length)))
406d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
407d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  else
408d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    {
409d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      real->len = new_length;
4101b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      real->str[new_length] = '\0';
411d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      return TRUE;
412d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    }
413d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington}
414d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
415d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtonstatic dbus_bool_t
416e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtonopen_gap (int             len,
417e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington          DBusRealString *dest,
418e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington          int             insert_at)
419e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington{
420e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  if (len == 0)
421e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington    return TRUE;
422e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
423b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (len > dest->max_length - dest->len)
424b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    return FALSE; /* detected overflow of dest->len + len below */
425b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
426e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  if (!set_length (dest, dest->len + len))
427e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington    return FALSE;
428e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
429e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  memmove (dest->str + insert_at + len,
430e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington           dest->str + insert_at,
431e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington           dest->len - len - insert_at);
432e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
433e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  return TRUE;
434e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington}
435e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
4367bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifndef _dbus_string_get_data
437d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
438d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Gets the raw character buffer from the string.  The returned buffer
439d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * will be nul-terminated, but note that strings may contain binary
440d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * data so there may be extra nul characters prior to the termination.
441d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * This function should be little-used, extend DBusString or add
442d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * stuff to dbus-sysdeps.c instead. It's an error to use this
443d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * function on a const string.
444d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
445d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
446fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * @returns the data
447d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
448fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonchar*
449fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington_dbus_string_get_data (DBusString *str)
450d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
451d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
452d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
4536606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  return (char*) real->str;
454d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
4557bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* _dbus_string_get_data */
456d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
457b60c835d346b7e214e627abd8e0cdf06932313a7Havoc Pennington/* only do the function if we don't have the macro */
458b60c835d346b7e214e627abd8e0cdf06932313a7Havoc Pennington#ifndef _dbus_string_get_const_data
459d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
460a07bc460ae1a3d3582a6dac7e48ed1ea117990efHavoc Pennington * Gets the raw character buffer from a const string.
461a07bc460ae1a3d3582a6dac7e48ed1ea117990efHavoc Pennington *
462d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
463fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * @returns the string data
464d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
465fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonconst char*
466fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington_dbus_string_get_const_data (const DBusString  *str)
467d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
468d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
469d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
4706606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  return (const char*) real->str;
471d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
472b60c835d346b7e214e627abd8e0cdf06932313a7Havoc Pennington#endif /* _dbus_string_get_const_data */
473d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
474d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
475d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Gets a sub-portion of the raw character buffer from the
476d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * string. The "len" field is required simply for error
477d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * checking, to be sure you don't try to use more
478d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * string than exists. The nul termination of the
479d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * returned buffer remains at the end of the entire
480d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * string, not at start + len.
481d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
482d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
483d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start byte offset to return
484d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len length of segment to return
485fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * @returns the string data
486d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
487fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonchar*
488d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_get_data_len (DBusString *str,
489d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                           int         start,
490d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                           int         len)
491d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
492d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
493d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (start >= 0);
494d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
495b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
496b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real->len - start);
497d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
4986606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  return (char*) real->str + start;
499d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
500d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
501b3416423b1e3c17357833d896c1b7cd684660771Havoc Pennington/* only do the function if we don't have the macro */
502b3416423b1e3c17357833d896c1b7cd684660771Havoc Pennington#ifndef _dbus_string_get_const_data_len
503d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
504d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * const version of _dbus_string_get_data_len().
505d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
506d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
507d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start byte offset to return
508d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len length of segment to return
509fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * @returns the string data
510d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
511fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonconst char*
512d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_get_const_data_len (const DBusString  *str,
513d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                                 int                start,
514d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                                 int                len)
515d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
516d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
517d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (start >= 0);
518d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
519b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
520b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real->len - start);
521d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
5226606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  return (const char*) real->str + start;
523d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
524b3416423b1e3c17357833d896c1b7cd684660771Havoc Pennington#endif /* _dbus_string_get_const_data_len */
525d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
526b3416423b1e3c17357833d896c1b7cd684660771Havoc Pennington/* only do the function if we don't have the macro */
527b3416423b1e3c17357833d896c1b7cd684660771Havoc Pennington#ifndef _dbus_string_set_byte
528d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
529e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * Sets the value of the byte at the given position.
530e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington *
531e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param str the string
532e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param i the position
533e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param byte the new value
534e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington */
535e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtonvoid
536e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington_dbus_string_set_byte (DBusString    *str,
537e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington                       int            i,
538e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington                       unsigned char  byte)
539e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington{
540e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  DBUS_STRING_PREAMBLE (str);
541e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_assert (i < real->len);
542b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (i >= 0);
543b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
544e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  real->str[i] = byte;
545e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington}
546b3416423b1e3c17357833d896c1b7cd684660771Havoc Pennington#endif /* _dbus_string_set_byte */
547e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
548b60c835d346b7e214e627abd8e0cdf06932313a7Havoc Pennington/* only have the function if we didn't create a macro */
549b60c835d346b7e214e627abd8e0cdf06932313a7Havoc Pennington#ifndef _dbus_string_get_byte
550e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington/**
55175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * Gets the byte at the given position. It is
55275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * allowed to ask for the nul byte at the end of
55375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * the string.
55450c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
55550c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param str the string
55650c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param start the position
55750c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @returns the byte at that position
55850c25505f62786756519ef1e194883360eda82e0Havoc Pennington */
559e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtonunsigned char
56050c25505f62786756519ef1e194883360eda82e0Havoc Pennington_dbus_string_get_byte (const DBusString  *str,
56150c25505f62786756519ef1e194883360eda82e0Havoc Pennington                       int                start)
56250c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
56350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
56475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  _dbus_assert (start <= real->len);
565b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start >= 0);
566b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
56750c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return real->str[start];
56850c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
569b60c835d346b7e214e627abd8e0cdf06932313a7Havoc Pennington#endif /* _dbus_string_get_byte */
57050c25505f62786756519ef1e194883360eda82e0Havoc Pennington
57150c25505f62786756519ef1e194883360eda82e0Havoc Pennington/**
57246c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin * Inserts a number of bytes of a given value at the
57346c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin * given position.
574e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington *
575e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param str the string
576e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param i the position
57746c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin * @param n_bytes number of bytes
578e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param byte the value to insert
579e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @returns #TRUE on success
580e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington */
581e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtondbus_bool_t
58246c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin_dbus_string_insert_bytes (DBusString   *str,
58346c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin			   int           i,
58446c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin			   int           n_bytes,
58546c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin			   unsigned char byte)
586e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington{
587e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  DBUS_STRING_PREAMBLE (str);
588e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_assert (i <= real->len);
589b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (i >= 0);
590e11ae7246655e59f8e04d1ffcb3788176a6d98b8Havoc Pennington  _dbus_assert (n_bytes >= 0);
591e11ae7246655e59f8e04d1ffcb3788176a6d98b8Havoc Pennington
592e11ae7246655e59f8e04d1ffcb3788176a6d98b8Havoc Pennington  if (n_bytes == 0)
593e11ae7246655e59f8e04d1ffcb3788176a6d98b8Havoc Pennington    return TRUE;
594b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
59546c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  if (!open_gap (n_bytes, real, i))
596e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington    return FALSE;
597e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
59846c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  memset (real->str + i, byte, n_bytes);
599e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
600e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  return TRUE;
601e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington}
602e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
603e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington/**
604617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * Inserts a single byte at the given position.
605617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington *
606617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param str the string
607617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param i the position
608617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param byte the value to insert
609617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @returns #TRUE on success
610617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington */
611617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Penningtondbus_bool_t
612617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington_dbus_string_insert_byte (DBusString   *str,
613617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington			   int           i,
614617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington			   unsigned char byte)
615617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington{
616617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  DBUS_STRING_PREAMBLE (str);
617617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  _dbus_assert (i <= real->len);
618617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  _dbus_assert (i >= 0);
619617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
620617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  if (!open_gap (1, real, i))
621617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington    return FALSE;
622617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
623617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  real->str[i] = byte;
624617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
625617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  return TRUE;
626617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington}
627617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
628617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington/**
629d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Like _dbus_string_get_data(), but removes the
630d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * gotten data from the original string. The caller
631d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * must free the data returned. This function may
632d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * fail due to lack of memory, and return #FALSE.
633d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
634d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
635d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param data_return location to return the buffer
636d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #TRUE on success
637d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
638d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
639d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_steal_data (DBusString        *str,
640d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                         char             **data_return)
641d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
642fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  int old_max_length;
643d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
644d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (data_return != NULL);
64513f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington
64613f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington  undo_alignment (real);
647d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
6486606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  *data_return = (char*) real->str;
649d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
650fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  old_max_length = real->max_length;
651fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
652d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* reset the string */
653fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (str))
654d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
655d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      /* hrm, put it back then */
6566606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington      real->str = (unsigned char*) *data_return;
657d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      *data_return = NULL;
65813f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington      fixup_alignment (real);
659d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      return FALSE;
660d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
661d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
662fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  real->max_length = old_max_length;
663fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
664d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
665d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
666d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
6677bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
668d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
669d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Like _dbus_string_get_data_len(), but removes the gotten data from
670d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the original string. The caller must free the data returned. This
671d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * function may fail due to lack of memory, and return #FALSE.
672d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * The returned string is nul-terminated and has length len.
673d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
674b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo this function is broken because on failure it
675b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * may corrupt the source string.
676b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
677d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
678d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param data_return location to return the buffer
679d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start the start of segment to steal
680d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len the length of segment to steal
681d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #TRUE on success
682d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
683d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
684d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_steal_data_len (DBusString        *str,
685d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                             char             **data_return,
686d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                             int                start,
687d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                             int                len)
688d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
689d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusString dest;
690d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
691d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (data_return != NULL);
692d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (start >= 0);
693d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
694b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
695b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real->len - start);
696d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
697fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&dest))
698d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return FALSE;
699d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
700fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  set_max_length (&dest, real->max_length);
701fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
702d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_move_len (str, start, len, &dest, 0))
703d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
704d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      _dbus_string_free (&dest);
705d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      return FALSE;
706d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
707b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
708bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_warn ("Broken code in _dbus_string_steal_data_len(), see @todo, FIXME\n");
709bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  if (!_dbus_string_steal_data (&dest, data_return))
710bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    {
711bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington      _dbus_string_free (&dest);
712bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington      return FALSE;
713bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    }
714bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
715bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_string_free (&dest);
716bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  return TRUE;
717bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington}
7187bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
719bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
720bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington/**
721bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * Copies the data from the string into a char*
722bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington *
723bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param str the string
724bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param data_return place to return the data
725bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @returns #TRUE on success, #FALSE on no memory
726bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington */
727bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Penningtondbus_bool_t
728bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington_dbus_string_copy_data (const DBusString  *str,
729bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington                        char             **data_return)
730bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington{
731bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
732bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (data_return != NULL);
733bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
734bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  *data_return = dbus_malloc (real->len + 1);
735bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  if (*data_return == NULL)
736bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    return FALSE;
737bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
738bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  memcpy (*data_return, real->str, real->len + 1);
739bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
740bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  return TRUE;
741bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington}
742bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
7437ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington/**
744bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * Copies the contents of a DBusString into a different buffer. It is
745bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * a bug if avail_len is too short to hold the string contents. nul
746bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * termination is not copied, just the supplied bytes.
7477ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington *
7487ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington * @param str a string
7497ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington * @param buffer a C buffer to copy data to
7507ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington * @param avail_len maximum length of C buffer
7517ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington */
7527ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Penningtonvoid
7537ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington_dbus_string_copy_to_buffer (const DBusString  *str,
7547ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington			     char              *buffer,
7557ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington			     int                avail_len)
7567ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington{
7577ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
7587ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington
7597ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington  _dbus_assert (avail_len >= 0);
760bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington  _dbus_assert (avail_len >= real->len);
761bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington
762bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington  memcpy (buffer, real->str, real->len);
763bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington}
764bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington
765bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington/**
766bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * Copies the contents of a DBusString into a different buffer. It is
767bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * a bug if avail_len is too short to hold the string contents plus a
768bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * nul byte.
769bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington *
770bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * @param str a string
771bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * @param buffer a C buffer to copy data to
772bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * @param avail_len maximum length of C buffer
773bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington */
774bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Penningtonvoid
775bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington_dbus_string_copy_to_buffer_with_nul (const DBusString  *str,
776bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington                                      char              *buffer,
777bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington                                      int                avail_len)
778bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington{
779bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
7807ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington
781bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington  _dbus_assert (avail_len >= 0);
782bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington  _dbus_assert (avail_len > real->len);
783bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington
784bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington  memcpy (buffer, real->str, real->len+1);
7857ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington}
7867ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington
7877bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
788bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington/**
789bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * Copies a segment of the string into a char*
790bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington *
791bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param str the string
792bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param data_return place to return the data
793bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param start start index
794bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param len length to copy
795bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @returns #FALSE if no memory
796bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington */
797bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Penningtondbus_bool_t
798bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington_dbus_string_copy_data_len (const DBusString  *str,
799bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington                            char             **data_return,
800bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington                            int                start,
801bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington                            int                len)
802bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington{
803bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  DBusString dest;
804bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
805bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
806bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (data_return != NULL);
807bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (start >= 0);
808bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (len >= 0);
809bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (start <= real->len);
810bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (len <= real->len - start);
811bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
812fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&dest))
813bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    return FALSE;
814bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
815fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  set_max_length (&dest, real->max_length);
816fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
817bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  if (!_dbus_string_copy_len (str, start, len, &dest, 0))
818bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    {
819bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington      _dbus_string_free (&dest);
820bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington      return FALSE;
821bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    }
822bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
823d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_steal_data (&dest, data_return))
824d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
825d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      _dbus_string_free (&dest);
826d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      return FALSE;
827d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
828d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
829d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_string_free (&dest);
830d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
831d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
8327bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
833935a41a04c3f638134fa905503fc41ddbd18902fColin Walters
8341b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington/* Only have the function if we don't have the macro */
8351b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington#ifndef _dbus_string_get_length
836935a41a04c3f638134fa905503fc41ddbd18902fColin Walters/**
837d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Gets the length of a string (not including nul termination).
838d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
839d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns the length.
840d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
841d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonint
842d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_get_length (const DBusString  *str)
843d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
844d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
845d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
846d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return real->len;
847d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
8481b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington#endif /* !_dbus_string_get_length */
849d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
850d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
851d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Makes a string longer by the given number of bytes.  Checks whether
852d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * adding additional_length to the current length would overflow an
853d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * integer, and checks for exceeding a string's max length.
854d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * The new bytes are not initialized, other than nul-terminating
855d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the end of the string. The uninitialized bytes may contain
856b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * nul bytes or other junk.
857d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
858d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str a string
859d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param additional_length length to add to the string.
860d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #TRUE on success.
861d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
862d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
863d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_lengthen (DBusString *str,
864d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int         additional_length)
865d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
866d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
867d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (additional_length >= 0);
868b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
8691b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington  if (_DBUS_UNLIKELY (additional_length > real->max_length - real->len))
870b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    return FALSE; /* would overflow */
871d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
872d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return set_length (real,
873d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                     real->len + additional_length);
874d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
875d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
876d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
877d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Makes a string shorter by the given number of bytes.
878d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
879d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str a string
880d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param length_to_remove length to remove from the string.
881d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
882d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
883d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_shorten (DBusString *str,
884d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                      int         length_to_remove)
885d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
886d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
887d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (length_to_remove >= 0);
888d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (length_to_remove <= real->len);
889d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
890d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  set_length (real,
891d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington              real->len - length_to_remove);
892d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
893d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
894d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
895d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Sets the length of a string. Can be used to truncate or lengthen
896d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the string. If the string is lengthened, the function may fail and
897d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * return #FALSE. Newly-added bytes are not initialized, as with
898d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * _dbus_string_lengthen().
899d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
900d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str a string
901d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param length new length of the string.
902d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE on failure.
903d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
904d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
905d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_set_length (DBusString *str,
906d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                         int         length)
907d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
908d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
909d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (length >= 0);
910d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
911d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return set_length (real, length);
912d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
913d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
914d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtonstatic dbus_bool_t
915617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Penningtonalign_insert_point_then_open_gap (DBusString *str,
916617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                                  int        *insert_at_p,
917617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                                  int         alignment,
918617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                                  int         gap_size)
919993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington{
920b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */
921617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  unsigned long gap_pos;
922617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  int insert_at;
923993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  int delta;
924993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  DBUS_STRING_PREAMBLE (str);
925993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  _dbus_assert (alignment >= 1);
9267ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
927993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
928617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  insert_at = *insert_at_p;
929617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
930617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  _dbus_assert (insert_at <= real->len);
931617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
932617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
933617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  new_len = real->len + (gap_pos - insert_at) + gap_size;
934617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
935617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  if (_DBUS_UNLIKELY (new_len > (unsigned long) real->max_length))
936b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    return FALSE;
937b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
938993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  delta = new_len - real->len;
939993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  _dbus_assert (delta >= 0);
940993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
941617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  if (delta == 0) /* only happens if gap_size == 0 and insert_at is aligned already */
942617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington    {
943617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington      _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
944617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington      return TRUE;
945617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington    }
946993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
947617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
948617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                                 real, insert_at)))
949993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington    return FALSE;
950993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
951617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  /* nul the padding if we had to add any padding */
952617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  if (gap_size < delta)
953d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    {
954617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington      memset (&real->str[insert_at], '\0',
955617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington              gap_pos - insert_at);
956d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    }
957617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
958617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *insert_at_p = gap_pos;
959617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
960993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  return TRUE;
961993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington}
962993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
963617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Penningtonstatic dbus_bool_t
964617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Penningtonalign_length_then_lengthen (DBusString *str,
965617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                            int         alignment,
966617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                            int         then_lengthen_by)
967617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington{
968617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  int insert_at;
969617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
970617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  insert_at = _dbus_string_get_length (str);
971617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
972617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  return align_insert_point_then_open_gap (str,
973617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                                           &insert_at,
974617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                                           alignment, then_lengthen_by);
975617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington}
976617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
977d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington/**
978d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * Align the length of a string to a specific alignment (typically 4 or 8)
979d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * by appending nul bytes to the string.
980d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington *
981d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param str a string
982d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param alignment the alignment
983d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @returns #FALSE if no memory
984d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington */
985d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtondbus_bool_t
986d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington_dbus_string_align_length (DBusString *str,
987d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                           int         alignment)
988d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington{
989d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  return align_length_then_lengthen (str, alignment, 0);
990d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington}
991d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
992617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington/**
993617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * Preallocate extra_bytes such that a future lengthening of the
994617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * string by extra_bytes is guaranteed to succeed without an out of
995617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * memory error.
996617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington *
997617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param str a string
998617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param extra_bytes bytes to alloc
999617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @returns #FALSE if no memory
1000617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington */
1001617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Penningtondbus_bool_t
1002617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington_dbus_string_alloc_space (DBusString        *str,
1003617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                          int                extra_bytes)
1004617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington{
1005617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  if (!_dbus_string_lengthen (str, extra_bytes))
1006617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington    return FALSE;
1007617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  _dbus_string_shorten (str, extra_bytes);
1008617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
1009617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  return TRUE;
1010617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington}
1011617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
1012d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonstatic dbus_bool_t
1013d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonappend (DBusRealString *real,
1014d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        const char     *buffer,
1015d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        int             buffer_len)
1016d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1017d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (buffer_len == 0)
1018d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return TRUE;
1019d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1020d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
1021d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return FALSE;
1022d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1023d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  memcpy (real->str + (real->len - buffer_len),
1024d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington          buffer,
1025d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington          buffer_len);
1026d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1027d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
1028d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1029d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1030d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1031d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Appends a nul-terminated C-style string to a DBusString.
1032d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1033d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the DBusString
1034d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param buffer the nul-terminated characters to append
1035d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory.
1036d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1037d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1038d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_append (DBusString *str,
1039d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                     const char *buffer)
1040d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1041b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  unsigned long buffer_len;
1042d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1043d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
1044d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (buffer != NULL);
1045d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1046d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  buffer_len = strlen (buffer);
1047b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (buffer_len > (unsigned long) real->max_length)
1048b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    return FALSE;
1049b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
1050d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return append (real, buffer, buffer_len);
1051d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1052d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
10533ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington/** assign 2 bytes from one string to another */
10543ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington#define ASSIGN_2_OCTETS(p, octets) \
10553ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington  *((dbus_uint16_t*)(p)) = *((dbus_uint16_t*)(octets));
10567bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington
105731988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington/** assign 4 bytes from one string to another */
1058617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington#define ASSIGN_4_OCTETS(p, octets) \
1059617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
1060617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
1061617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington#ifdef DBUS_HAVE_INT64
106231988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington/** assign 8 bytes from one string to another */
1063617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington#define ASSIGN_8_OCTETS(p, octets) \
1064617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
1065617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington#else
106631988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington/** assign 8 bytes from one string to another */
1067617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington#define ASSIGN_8_OCTETS(p, octets)              \
1068617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Penningtondo {                                            \
1069617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  unsigned char *b;                             \
1070617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                                                \
1071617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  b = p;                                        \
1072617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                                                \
1073617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *b++ = octets[0];                             \
1074617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *b++ = octets[1];                             \
1075617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *b++ = octets[2];                             \
1076617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *b++ = octets[3];                             \
1077617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *b++ = octets[4];                             \
1078617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *b++ = octets[5];                             \
1079617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *b++ = octets[6];                             \
1080617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *b++ = octets[7];                             \
1081617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  _dbus_assert (b == p + 8);                    \
1082617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington} while (0)
1083617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington#endif /* DBUS_HAVE_INT64 */
1084617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
10857bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
1086d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1087d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * Appends 4 bytes aligned on a 4 byte boundary
1088d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * with any alignment padding initialized to 0.
1089d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington *
1090d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param str the DBusString
1091d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param octets 4 bytes to append
1092d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @returns #FALSE if not enough memory.
1093d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington */
1094d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtondbus_bool_t
1095d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington_dbus_string_append_4_aligned (DBusString         *str,
1096d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                               const unsigned char octets[4])
1097d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington{
1098d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  DBUS_STRING_PREAMBLE (str);
1099d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1100d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  if (!align_length_then_lengthen (str, 4, 4))
1101d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
1102d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1103617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  ASSIGN_4_OCTETS (real->str + (real->len - 4), octets);
1104d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1105d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  return TRUE;
1106d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington}
11077bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
1108d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
11097bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
1110d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington/**
1111d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * Appends 8 bytes aligned on an 8 byte boundary
1112d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * with any alignment padding initialized to 0.
1113d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington *
1114d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param str the DBusString
1115617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param octets 8 bytes to append
1116d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @returns #FALSE if not enough memory.
1117d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington */
1118d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtondbus_bool_t
1119d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington_dbus_string_append_8_aligned (DBusString         *str,
1120d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                               const unsigned char octets[8])
1121d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington{
1122d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  DBUS_STRING_PREAMBLE (str);
1123d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1124d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  if (!align_length_then_lengthen (str, 8, 8))
1125d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
1126d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1127617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  ASSIGN_8_OCTETS (real->str + (real->len - 8), octets);
1128617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
1129617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  return TRUE;
1130617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington}
11317bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
1132617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
1133617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington/**
11343ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington * Inserts 2 bytes aligned on a 2 byte boundary
11353ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington * with any alignment padding initialized to 0.
11363ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington *
11373ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington * @param str the DBusString
11383ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington * @param insert_at where to insert
11393ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington * @param octets 2 bytes to insert
11403ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington * @returns #FALSE if not enough memory.
11413ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington */
11423ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Penningtondbus_bool_t
11433ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington_dbus_string_insert_2_aligned (DBusString         *str,
11443ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington                               int                 insert_at,
11453ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington                               const unsigned char octets[4])
11463ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington{
11473ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington  DBUS_STRING_PREAMBLE (str);
11483ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington
11493ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington  if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2))
11503ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington    return FALSE;
11513ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington
11523ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington  ASSIGN_2_OCTETS (real->str + insert_at, octets);
11533ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington
11543ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington  return TRUE;
11553ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington}
11563ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington
11573ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington/**
1158617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * Inserts 4 bytes aligned on a 4 byte boundary
1159617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * with any alignment padding initialized to 0.
1160617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington *
1161617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param str the DBusString
116231988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington * @param insert_at where to insert
1163617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param octets 4 bytes to insert
1164617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @returns #FALSE if not enough memory.
1165617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington */
1166617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Penningtondbus_bool_t
1167617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington_dbus_string_insert_4_aligned (DBusString         *str,
1168617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                               int                 insert_at,
1169617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                               const unsigned char octets[4])
1170617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington{
1171d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  DBUS_STRING_PREAMBLE (str);
1172d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1173617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
1174d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
1175d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1176617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  ASSIGN_4_OCTETS (real->str + insert_at, octets);
1177617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
1178617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  return TRUE;
1179617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington}
1180617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
1181617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington/**
1182617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * Inserts 8 bytes aligned on an 8 byte boundary
1183617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * with any alignment padding initialized to 0.
1184617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington *
1185617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param str the DBusString
118631988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington * @param insert_at where to insert
1187617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param octets 8 bytes to insert
1188617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @returns #FALSE if not enough memory.
1189617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington */
1190617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Penningtondbus_bool_t
1191617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington_dbus_string_insert_8_aligned (DBusString         *str,
1192617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                               int                 insert_at,
1193617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                               const unsigned char octets[8])
1194617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington{
1195617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  DBUS_STRING_PREAMBLE (str);
1196d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1197617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
1198617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington    return FALSE;
1199617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
1200bb8f518d07adffbefcc7d592af0655b2afa4ab19Havoc Pennington  _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
1201bb8f518d07adffbefcc7d592af0655b2afa4ab19Havoc Pennington
1202617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  ASSIGN_8_OCTETS (real->str + insert_at, octets);
1203d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1204d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  return TRUE;
1205d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington}
1206d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
120707d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington
120807d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington/**
120907d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * Inserts padding at *insert_at such to align it to the given
121007d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * boundary. Initializes the padding to nul bytes. Sets *insert_at
121107d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * to the aligned position.
121207d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington *
121307d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * @param str the DBusString
121407d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * @param insert_at location to be aligned
12153ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington * @param alignment alignment boundary (1, 2, 4, or 8)
121607d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * @returns #FALSE if not enough memory.
121707d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington */
121807d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Penningtondbus_bool_t
121907d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington_dbus_string_insert_alignment (DBusString        *str,
122007d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington                               int               *insert_at,
122107d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington                               int                alignment)
122207d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington{
122307d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington  DBUS_STRING_PREAMBLE (str);
122407d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington
12259c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0))
122607d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington    return FALSE;
122707d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington
12289c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at);
122907d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington
123007d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington  return TRUE;
123107d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington}
123207d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington
1233d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington/**
12341d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * Appends a printf-style formatted string
12351d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * to the #DBusString.
12361d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington *
12371d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @param str the string
12381d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @param format printf format
12391d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @param args variable argument list
12401d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @returns #FALSE if no memory
12411d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington */
12421d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Penningtondbus_bool_t
12431d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington_dbus_string_append_printf_valist  (DBusString        *str,
12441d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington                                    const char        *format,
12451d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington                                    va_list            args)
12461d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington{
12471d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  int len;
1248ce09b82ec2dd3cb1d239605f8f458e09afd70694Colin Walters  va_list args_copy;
1249868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen
125024f411a6a10e4838f57595720642ce83ceae814cHavoc Pennington  DBUS_STRING_PREAMBLE (str);
1251868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen
1252868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen  DBUS_VA_COPY (args_copy, args);
1253868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen
12541d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  /* Measure the message length without terminating nul */
1255d387411488a093f77f4cd752b75e8bf8360550c6John (J  len = _dbus_printf_string_upper_bound (format, args);
12561d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
12571d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  if (!_dbus_string_lengthen (str, len))
1258868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen    {
1259868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen      /* don't leak the copy */
1260868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen      va_end (args_copy);
1261868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen      return FALSE;
1262868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen    }
1263868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen
12646606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  vsprintf ((char*) (real->str + (real->len - len)),
1265868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen            format, args_copy);
1266868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen
1267868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen  va_end (args_copy);
12681d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
12691d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  return TRUE;
12701d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington}
12711d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
12721d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington/**
12731d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * Appends a printf-style formatted string
12741d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * to the #DBusString.
12751d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington *
12761d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @param str the string
12771d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @param format printf format
12781d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @returns #FALSE if no memory
12791d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington */
12801d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Penningtondbus_bool_t
12811d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington_dbus_string_append_printf (DBusString        *str,
12821d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington                            const char        *format,
12831d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington                            ...)
12841d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington{
12851d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  va_list args;
12861d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  dbus_bool_t retval;
12871d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
12881d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  va_start (args, format);
12891d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  retval = _dbus_string_append_printf_valist (str, format, args);
12901d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  va_end (args);
12911d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
12921d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  return retval;
12931d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington}
12941d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
12951d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington/**
1296d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Appends block of bytes with the given length to a DBusString.
1297d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1298d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the DBusString
1299d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param buffer the bytes to append
1300d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len the number of bytes to append
1301d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory.
1302d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1303d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1304d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_append_len (DBusString *str,
1305d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                         const char *buffer,
1306d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                         int         len)
1307d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1308d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
1309d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (buffer != NULL);
1310d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
1311d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1312d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return append (real, buffer, len);
1313d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1314d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1315d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1316d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Appends a single byte to the string, returning #FALSE
1317d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * if not enough memory.
1318d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1319d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
1320d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param byte the byte to append
1321d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #TRUE on success
1322d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1323d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1324d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_append_byte (DBusString    *str,
1325d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                          unsigned char  byte)
1326d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1327d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
1328d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1329d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!set_length (real, real->len + 1))
1330d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return FALSE;
1331d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1332d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->str[real->len-1] = byte;
1333d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1334d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
1335d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1336d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
13377bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
1338d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1339d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Appends a single Unicode character, encoding the character
1340d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * in UTF-8 format.
1341d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1342d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
1343d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param ch the Unicode character
1344d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1345d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1346d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_append_unichar (DBusString    *str,
1347d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                             dbus_unichar_t ch)
1348d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1349d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  int len;
1350d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  int first;
1351d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  int i;
13526606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  unsigned char *out;
1353d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1354d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
1355d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1356d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* this code is from GLib but is pretty standard I think */
1357d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1358d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  len = 0;
1359d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1360d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (ch < 0x80)
1361d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1362d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0;
1363d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 1;
1364d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1365d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if (ch < 0x800)
1366d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1367d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0xc0;
1368d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 2;
1369d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1370d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if (ch < 0x10000)
1371d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1372d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0xe0;
1373d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 3;
1374d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1375d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   else if (ch < 0x200000)
1376d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1377d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0xf0;
1378d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 4;
1379d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1380d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if (ch < 0x4000000)
1381d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1382d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0xf8;
1383d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 5;
1384d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1385d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else
1386d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1387d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0xfc;
1388d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 6;
1389d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1390d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1391b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (len > (real->max_length - real->len))
1392b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    return FALSE; /* real->len + len would overflow */
1393b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
1394d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!set_length (real, real->len + len))
1395d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return FALSE;
1396d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1397d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  out = real->str + (real->len - len);
1398d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1399d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  for (i = len - 1; i > 0; --i)
1400d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1401d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      out[i] = (ch & 0x3f) | 0x80;
1402d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      ch >>= 6;
1403d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1404d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  out[0] = ch | first;
1405d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1406d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
1407d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
14087bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
1409d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1410d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonstatic void
1411d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondelete (DBusRealString *real,
1412d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        int             start,
1413d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        int             len)
1414d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1415d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (len == 0)
1416d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return;
1417d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1418d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  memmove (real->str + start, real->str + start + len, real->len - (start + len));
1419d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->len -= len;
1420d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->str[real->len] = '\0';
1421d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1422d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1423d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1424d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Deletes a segment of a DBusString with length len starting at
1425d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * start. (Hint: to clear an entire string, setting length to 0
1426d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * with _dbus_string_set_length() is easier.)
1427d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1428d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the DBusString
1429d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start where to start deleting
1430d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len the number of bytes to delete
1431d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1432d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
1433d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_delete (DBusString       *str,
1434d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                     int               start,
1435d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                     int               len)
1436d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1437d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
1438d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (start >= 0);
1439d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
1440b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
1441b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real->len - start);
144250c25505f62786756519ef1e194883360eda82e0Havoc Pennington
1443d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  delete (real, start, len);
1444d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1445d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1446d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonstatic dbus_bool_t
14472297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtoncopy (DBusRealString *source,
14482297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      int             start,
14492297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      int             len,
14502297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      DBusRealString *dest,
14512297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      int             insert_at)
14522297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
145350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (len == 0)
145450c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return TRUE;
145550c25505f62786756519ef1e194883360eda82e0Havoc Pennington
14562297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!open_gap (len, dest, insert_at))
14572297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    return FALSE;
145850c25505f62786756519ef1e194883360eda82e0Havoc Pennington
14596606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  memmove (dest->str + insert_at,
14606606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington           source->str + start,
14616606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington           len);
1462d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1463d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
1464d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1465d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1466d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1467d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Checks assertions for two strings we're copying a segment between,
1468d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * and declares real_source/real_dest variables.
1469d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1470d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param source the source string
1471d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start the starting offset
1472d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param dest the dest string
1473d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param insert_at where the copied segment is inserted
1474d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1475d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at)       \
1476d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusRealString *real_source = (DBusRealString*) source;               \
1477d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusRealString *real_dest = (DBusRealString*) dest;                   \
1478d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((source) != (dest));                                    \
1479d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_source);                           \
1480d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_dest);                             \
1481d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (!real_dest->constant);                                  \
1482d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (!real_dest->locked);                                    \
1483d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((start) >= 0);                                          \
1484d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((start) <= real_source->len);                           \
1485d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((insert_at) >= 0);                                      \
1486d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((insert_at) <= real_dest->len)
1487d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1488d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1489d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Moves the end of one string into another string. Both strings
1490d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * must be initialized, valid strings.
1491d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1492d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param source the source string
1493d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start where to chop off the source string
1494d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param dest the destination string
1495d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param insert_at where to move the chopped-off part of source string
1496d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory
1497d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1498d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1499d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_move (DBusString       *source,
1500d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   int               start,
1501d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   DBusString       *dest,
1502d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   int               insert_at)
1503d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1504d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  DBusRealString *real_source = (DBusRealString*) source;
1505d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  _dbus_assert (start <= real_source->len);
1506d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1507d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  return _dbus_string_move_len (source, start,
1508d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                                real_source->len - start,
1509d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                                dest, insert_at);
1510d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1511d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1512d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1513d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Like _dbus_string_move(), but does not delete the section
1514d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * of the source string that's copied to the dest string.
1515d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1516d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param source the source string
1517d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start where to start copying the source string
1518d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param dest the destination string
1519d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param insert_at where to place the copied part of source string
1520d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory
1521d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1522d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1523d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_copy (const DBusString *source,
1524d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   int               start,
1525d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   DBusString       *dest,
1526d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   int               insert_at)
1527d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1528d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1529d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1530d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return copy (real_source, start,
1531d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington               real_source->len - start,
1532d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington               real_dest,
1533d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington               insert_at);
1534d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1535d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1536d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1537d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Like _dbus_string_move(), but can move a segment from
1538d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the middle of the source string.
1539d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington *
1540d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @todo this doesn't do anything with max_length field.
1541d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * we should probably just kill the max_length field though.
1542d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1543d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param source the source string
1544d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start first byte of source string to move
1545d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len length of segment to move
1546d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param dest the destination string
1547d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param insert_at where to move the bytes from the source string
1548d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory
1549d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1550d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1551d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_move_len (DBusString       *source,
1552d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               start,
1553d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               len,
1554d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       DBusString       *dest,
1555d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               insert_at)
1556d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1557d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1558d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1559d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
1560d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((start + len) <= real_source->len);
1561d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1562d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1563d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  if (len == 0)
1564d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    {
1565d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      return TRUE;
1566d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    }
1567d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  else if (start == 0 &&
1568d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington           len == real_source->len &&
1569d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington           real_dest->len == 0)
1570d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    {
1571d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      /* Short-circuit moving an entire existing string to an empty string
1572d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington       * by just swapping the buffers.
1573d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington       */
1574d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      /* we assume ->constant doesn't matter as you can't have
1575d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington       * a constant string involved in a move.
1576d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington       */
1577d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington#define ASSIGN_DATA(a, b) do {                  \
1578d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        (a)->str = (b)->str;                    \
1579d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        (a)->len = (b)->len;                    \
1580d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        (a)->allocated = (b)->allocated;        \
1581d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        (a)->align_offset = (b)->align_offset;  \
1582d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      } while (0)
1583d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1584d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      DBusRealString tmp;
1585d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1586d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      ASSIGN_DATA (&tmp, real_source);
1587d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      ASSIGN_DATA (real_source, real_dest);
1588d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      ASSIGN_DATA (real_dest, &tmp);
1589d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1590d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      return TRUE;
1591d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    }
1592d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  else
1593d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    {
1594d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      if (!copy (real_source, start, len,
1595d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                 real_dest,
1596d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                 insert_at))
1597d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        return FALSE;
1598d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1599d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      delete (real_source, start,
1600d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington              len);
1601d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1602d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      return TRUE;
1603d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    }
1604d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1605d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1606d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1607d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Like _dbus_string_copy(), but can copy a segment from the middle of
1608d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the source string.
1609d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1610d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param source the source string
1611d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start where to start copying the source string
1612d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len length of segment to copy
1613d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param dest the destination string
1614d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param insert_at where to place the copied segment of source string
1615d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory
1616d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1617d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1618d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_copy_len (const DBusString *source,
1619d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               start,
1620d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               len,
1621d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       DBusString       *dest,
1622d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               insert_at)
1623d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1624d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1625d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
1626b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real_source->len);
1627b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real_source->len - start);
1628d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1629d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return copy (real_source, start, len,
1630d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington               real_dest,
1631d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington               insert_at);
1632d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1633d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
163450c25505f62786756519ef1e194883360eda82e0Havoc Pennington/**
163550c25505f62786756519ef1e194883360eda82e0Havoc Pennington * Replaces a segment of dest string with a segment of source string.
163650c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
163750c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @todo optimize the case where the two lengths are the same, and
163850c25505f62786756519ef1e194883360eda82e0Havoc Pennington * avoid memmoving the data in the trailing part of the string twice.
1639b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
1640b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo avoid inserting the source into dest, then deleting
1641b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * the replaced chunk of dest (which creates a potentially large
1642b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * intermediate string). Instead, extend the replaced chunk
1643b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * of dest with padding to the same size as the source chunk,
1644b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * then copy in the source bytes.
164550c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
164650c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param source the source string
164750c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param start where to start copying the source string
164850c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param len length of segment to copy
164950c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param dest the destination string
165050c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param replace_at start of segment of dest string to replace
165150c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param replace_len length of segment of dest string to replace
165250c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @returns #FALSE if not enough memory
165350c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
165450c25505f62786756519ef1e194883360eda82e0Havoc Pennington */
165550c25505f62786756519ef1e194883360eda82e0Havoc Penningtondbus_bool_t
165650c25505f62786756519ef1e194883360eda82e0Havoc Pennington_dbus_string_replace_len (const DBusString *source,
165750c25505f62786756519ef1e194883360eda82e0Havoc Pennington                          int               start,
165850c25505f62786756519ef1e194883360eda82e0Havoc Pennington                          int               len,
165950c25505f62786756519ef1e194883360eda82e0Havoc Pennington                          DBusString       *dest,
166050c25505f62786756519ef1e194883360eda82e0Havoc Pennington                          int               replace_at,
166150c25505f62786756519ef1e194883360eda82e0Havoc Pennington                          int               replace_len)
166250c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
166350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
166450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (len >= 0);
1665b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real_source->len);
1666b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real_source->len - start);
166750c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (replace_at >= 0);
1668b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (replace_at <= real_dest->len);
1669b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (replace_len <= real_dest->len - replace_at);
167050c25505f62786756519ef1e194883360eda82e0Havoc Pennington
167150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!copy (real_source, start, len,
167250c25505f62786756519ef1e194883360eda82e0Havoc Pennington             real_dest, replace_at))
167350c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return FALSE;
167450c25505f62786756519ef1e194883360eda82e0Havoc Pennington
167550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  delete (real_dest, replace_at + len, replace_len);
167650c25505f62786756519ef1e194883360eda82e0Havoc Pennington
167750c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return TRUE;
167850c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
167950c25505f62786756519ef1e194883360eda82e0Havoc Pennington
16800e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode/**
16810e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode * Looks for the first occurance of a byte, deletes that byte,
16820e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode * and moves everything after the byte to the beginning of a
16830e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode * separate string.  Both strings must be initialized, valid
16840e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode * strings.
16850e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode *
16860e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode * @param source the source string
16870e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode * @param byte the byte to remove and split the string at
16880e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode * @param tail the split off string
16890e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode * @returns #FALSE if not enough memory or if byte could not be found
16900e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode *
16910e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode */
16920e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strodedbus_bool_t
16930e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode_dbus_string_split_on_byte (DBusString        *source,
16940e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode                            unsigned char      byte,
16950e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode                            DBusString        *tail)
16960e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode{
16970e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  int byte_position;
16980e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  char byte_string[2] = "";
16990e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  int head_length;
17000e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  int tail_length;
17010e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode
17020e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  byte_string[0] = (char) byte;
17030e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode
17040e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  if (!_dbus_string_find (source, 0, byte_string, &byte_position))
17050e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode    return FALSE;
17060e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode
17070e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  head_length = byte_position;
17080e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  tail_length = _dbus_string_get_length (source) - head_length - 1;
17090e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode
17100e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  if (!_dbus_string_move_len (source, byte_position + 1, tail_length,
17110e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode                              tail, 0))
17120e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode    return FALSE;
17130e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode
17140e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  /* remove the trailing delimiter byte from the head now.
17150e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode   */
17160e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  if (!_dbus_string_set_length (source, head_length))
17170e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode    return FALSE;
17180e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode
17190e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  return TRUE;
17200e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode}
17210e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode
1722021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington/* Unicode macros and utf8_validate() from GLib Owen Taylor, Havoc
1723021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington * Pennington, and Tom Tromey are the authors and authorized relicense.
1724021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington */
1725d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1726d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/** computes length and mask of a unicode character
1727d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Char the char
1728d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Mask the mask variable to assign to
1729d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Len the length variable to assign to
1730d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1731d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define UTF8_COMPUTE(Char, Mask, Len)					      \
1732d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (Char < 128)							      \
1733d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1734d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 1;								      \
1735d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x7f;							      \
1736d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
1737d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if ((Char & 0xe0) == 0xc0)					      \
1738d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1739d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 2;								      \
1740d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x1f;							      \
1741d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
1742d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if ((Char & 0xf0) == 0xe0)					      \
1743d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1744d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 3;								      \
1745d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x0f;							      \
1746d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
1747d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if ((Char & 0xf8) == 0xf0)					      \
1748d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1749d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 4;								      \
1750d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x07;							      \
1751d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
1752d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if ((Char & 0xfc) == 0xf8)					      \
1753d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1754d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 5;								      \
1755d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x03;							      \
1756d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
1757d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if ((Char & 0xfe) == 0xfc)					      \
1758d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1759d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 6;								      \
1760d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x01;							      \
1761d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
17621b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington  else                                                                        \
17631b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington    {                                                                         \
17641b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      Len = 0;                                                               \
17651b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      Mask = 0;                                                               \
17661b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington    }
1767d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1768d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1769d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * computes length of a unicode character in UTF-8
1770d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Char the char
1771d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1772d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define UTF8_LENGTH(Char)              \
1773d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  ((Char) < 0x80 ? 1 :                 \
1774d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   ((Char) < 0x800 ? 2 :               \
1775d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    ((Char) < 0x10000 ? 3 :            \
1776d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington     ((Char) < 0x200000 ? 4 :          \
1777d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      ((Char) < 0x4000000 ? 5 : 6)))))
1778d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1779d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1780d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Gets a UTF-8 value.
1781d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1782d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Result variable for extracted unicode char.
1783d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Chars the bytes to decode
1784d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Count counter variable
1785d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Mask mask for this char
1786d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Len length for this char in bytes
1787d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1788d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define UTF8_GET(Result, Chars, Count, Mask, Len)			      \
1789d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  (Result) = (Chars)[0] & (Mask);					      \
1790d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  for ((Count) = 1; (Count) < (Len); ++(Count))				      \
1791d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1792d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      if (((Chars)[(Count)] & 0xc0) != 0x80)				      \
1793d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington	{								      \
1794d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington	  (Result) = -1;						      \
1795d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington	  break;							      \
1796d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington	}								      \
1797d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      (Result) <<= 6;							      \
1798d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      (Result) |= ((Chars)[(Count)] & 0x3f);				      \
1799d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1800d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1801d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1802fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters * Check whether a Unicode (5.2) char is in a valid range.
1803fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters *
1804fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters * The first check comes from the Unicode guarantee to never encode
1805fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters * a point above 0x0010ffff, since UTF-16 couldn't represent it.
1806fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters *
1807fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters * The second check covers surrogate pairs (category Cs).
1808fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters *
1809fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters * The last two checks cover "Noncharacter": defined as:
1810fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters *   "A code point that is permanently reserved for
1811fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters *    internal use, and that should never be interchanged. In
1812fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters *    Unicode 3.1, these consist of the values U+nFFFE and U+nFFFF
1813fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters *    (where n is from 0 to 10_16) and the values U+FDD0..U+FDEF."
1814d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1815d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Char the character
1816d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1817d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define UNICODE_VALID(Char)                   \
1818d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    ((Char) < 0x110000 &&                     \
1819bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington     (((Char) & 0xFFFFF800) != 0xD800) &&     \
1820bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington     ((Char) < 0xFDD0 || (Char) > 0xFDEF) &&  \
1821fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters     ((Char) & 0xFFFE) != 0xFFFE)
1822d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
18237bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
1824d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1825d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Gets a unicode character from a UTF-8 string. Does no validation;
1826d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * you must verify that the string is valid UTF-8 in advance and must
1827d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * pass in the start of a character.
1828d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1829d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
1830d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start the start of the UTF-8 character.
1831d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param ch_return location to return the character
1832d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param end_return location to return the byte index of next character
1833d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1834d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
1835d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_get_unichar (const DBusString *str,
1836d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                          int               start,
1837d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                          dbus_unichar_t   *ch_return,
1838d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                          int              *end_return)
1839d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1840d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  int i, mask, len;
1841d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  dbus_unichar_t result;
1842d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  unsigned char c;
1843d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  unsigned char *p;
1844d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
1845b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start >= 0);
1846b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
1847b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
1848d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (ch_return)
1849d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    *ch_return = 0;
1850d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (end_return)
1851d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    *end_return = real->len;
1852d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1853d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  mask = 0;
1854d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  p = real->str + start;
1855d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  c = *p;
1856d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1857d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  UTF8_COMPUTE (c, mask, len);
18581b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington  if (len == 0)
1859d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return;
1860d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  UTF8_GET (result, p, i, mask, len);
1861d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1862d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (result == (dbus_unichar_t)-1)
1863d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return;
1864d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1865d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (ch_return)
1866d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    *ch_return = result;
1867d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (end_return)
1868d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    *end_return = start + len;
1869d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
18707bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
1871d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
18722297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
18732297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Finds the given substring in the string,
18742297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * returning #TRUE and filling in the byte index
18752297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * where the substring was found, if it was found.
18762297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Returns #FALSE if the substring wasn't found.
18772297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Sets *start to the length of the string if the substring
18782297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * is not found.
18792297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
18802297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param str the string
18812297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param start where to start looking
18822297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param substr the substring
18832297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param found return location for where it was found, or #NULL
18842297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @returns #TRUE if found
18852297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
18862297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtondbus_bool_t
18872297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_find (const DBusString *str,
18882297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                   int               start,
18892297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                   const char       *substr,
18902297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                   int              *found)
18912297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
1892b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  return _dbus_string_find_to (str, start,
1893b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington                               ((const DBusRealString*)str)->len,
1894b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington                               substr, found);
18952297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
18962297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
18972297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
1898cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * Finds end of line ("\r\n" or "\n") in the string,
1899cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * returning #TRUE and filling in the byte index
1900cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * where the eol string was found, if it was found.
1901cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * Returns #FALSE if eol wasn't found.
1902cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker *
1903cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * @param str the string
1904cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * @param start where to start looking
1905cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * @param found return location for where eol was found or string length otherwise
1906cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * @param found_len return length of found eol string or zero otherwise
1907cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * @returns #TRUE if found
1908cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker */
1909cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habackerdbus_bool_t
1910cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker_dbus_string_find_eol (const DBusString *str,
1911a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington                       int               start,
1912a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington                       int              *found,
1913a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington                       int              *found_len)
1914cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker{
1915cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  int i;
1916cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker
1917cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  DBUS_CONST_STRING_PREAMBLE (str);
1918cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  _dbus_assert (start <= real->len);
1919cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  _dbus_assert (start >= 0);
1920cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker
1921cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  i = start;
1922cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  while (i < real->len)
1923cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker    {
1924cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker      if (real->str[i] == '\r')
1925cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker        {
1926cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker          if ((i+1) < real->len && real->str[i+1] == '\n') /* "\r\n" */
1927cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker            {
1928cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker              if (found)
1929cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker                *found = i;
1930cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker              if (found_len)
1931cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker                *found_len = 2;
1932cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker              return TRUE;
1933cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker            }
1934cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker          else /* only "\r" */
1935cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker            {
1936cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker              if (found)
1937cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker                *found = i;
1938cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker              if (found_len)
1939cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker                *found_len = 1;
1940cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker              return TRUE;
1941cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker            }
1942cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker        }
1943cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker      else if (real->str[i] == '\n')  /* only "\n" */
1944cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker        {
1945cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker          if (found)
1946cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker            *found = i;
1947cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker          if (found_len)
1948cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker            *found_len = 1;
1949cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker          return TRUE;
1950a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington        }
1951cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker      ++i;
1952cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker    }
1953cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker
1954cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  if (found)
1955cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker    *found = real->len;
1956cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker
1957cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  if (found_len)
1958cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker    *found_len = 0;
1959cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker
1960cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  return FALSE;
1961cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker}
1962cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker
1963cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker/**
19645ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * Finds the given substring in the string,
19655ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * up to a certain position,
19665ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * returning #TRUE and filling in the byte index
19675ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * where the substring was found, if it was found.
19685ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * Returns #FALSE if the substring wasn't found.
19695ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * Sets *start to the length of the string if the substring
19705ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * is not found.
19715ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson *
19725ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @param str the string
19735ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @param start where to start looking
19745ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @param end where to stop looking
19755ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @param substr the substring
19765ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @param found return location for where it was found, or #NULL
19775ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @returns #TRUE if found
19785ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson */
19795ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlssondbus_bool_t
19805ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson_dbus_string_find_to (const DBusString *str,
19815ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson		      int               start,
19825ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson		      int               end,
19835ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson		      const char       *substr,
19845ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson		      int              *found)
19855ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson{
19865ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  int i;
19875ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  DBUS_CONST_STRING_PREAMBLE (str);
19885ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  _dbus_assert (substr != NULL);
19895ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  _dbus_assert (start <= real->len);
1990b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start >= 0);
1991b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (substr != NULL);
19925ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  _dbus_assert (end <= real->len);
1993b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= end);
19945ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
19955ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  /* we always "find" an empty string */
19965ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  if (*substr == '\0')
19975ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    {
19985ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson      if (found)
1999b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington        *found = start;
20005ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson      return TRUE;
20015ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    }
20025ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
20035ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  i = start;
2004b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  while (i < end)
20055ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    {
20065ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson      if (real->str[i] == substr[0])
20075ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson        {
20085ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson          int j = i + 1;
20095ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
2010b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington          while (j < end)
20115ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson            {
20125ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson              if (substr[j - i] == '\0')
20135ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson                break;
20145ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson              else if (real->str[j] != substr[j - i])
20155ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson                break;
20165ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
20175ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson              ++j;
20185ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson            }
20195ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
20205ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson          if (substr[j - i] == '\0')
20215ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson            {
20225ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson              if (found)
20235ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson                *found = i;
20245ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson              return TRUE;
20255ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson            }
20265ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson        }
20275ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
20285ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson      ++i;
20295ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    }
20305ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
20315ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  if (found)
20325ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    *found = end;
20335ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
20345ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  return FALSE;
20355ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson}
20365ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
20375ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson/**
20382297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Finds a blank (space or tab) in the string. Returns #TRUE
20392297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * if found, #FALSE otherwise. If a blank is not found sets
20402297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * *found to the length of the string.
20412297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
20422297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param str the string
20432297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param start byte index to start looking
20442297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param found place to store the location of the first blank
20452297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @returns #TRUE if a blank was found
20462297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
20472297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtondbus_bool_t
20482297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_find_blank (const DBusString *str,
20492297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                         int               start,
20502297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                         int              *found)
20512297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
20522297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  int i;
20532297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
20542297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert (start <= real->len);
2055b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start >= 0);
20562297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
20572297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  i = start;
20582297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  while (i < real->len)
20592297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
20602297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      if (real->str[i] == ' ' ||
20612297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington          real->str[i] == '\t')
20622297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        {
20632297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington          if (found)
20642297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington            *found = i;
20652297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington          return TRUE;
20662297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        }
20672297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
20682297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++i;
20692297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
20702297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
20712297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (found)
20722297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    *found = real->len;
20732297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
20742297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  return FALSE;
20752297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
20762297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
20772297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
20782297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Skips blanks from start, storing the first non-blank in *end
2079bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * (blank is space or tab).
20802297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
20812297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param str the string
20822297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param start where to start
20832297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param end where to store the first non-blank byte index
20842297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
20852297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtonvoid
20862297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_skip_blank (const DBusString *str,
20872297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                         int               start,
20882297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                         int              *end)
20892297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
20902297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  int i;
20912297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
20922297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert (start <= real->len);
2093b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start >= 0);
20942297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
20952297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  i = start;
20962297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  while (i < real->len)
20972297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
2098d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington      if (!DBUS_IS_ASCII_BLANK (real->str[i]))
20992297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        break;
21002297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
21012297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++i;
21022297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
21032297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
2104d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
2105ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
21062297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (end)
21072297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    *end = i;
21082297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
21092297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
2110d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2111d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington/**
2112d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * Skips whitespace from start, storing the first non-whitespace in *end.
2113d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * (whitespace is space, tab, newline, CR).
2114d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington *
2115d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * @param str the string
2116d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * @param start where to start
2117d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * @param end where to store the first non-whitespace byte index
2118d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington */
2119d8155bf51bf6484a94e734601526bf211053a5e1Havoc Penningtonvoid
2120d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington_dbus_string_skip_white (const DBusString *str,
2121d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington                         int               start,
2122d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington                         int              *end)
2123d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington{
2124d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  int i;
2125d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
2126d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_assert (start <= real->len);
2127d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_assert (start >= 0);
2128d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2129d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  i = start;
2130d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  while (i < real->len)
2131d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington    {
2132d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington      if (!DBUS_IS_ASCII_WHITE (real->str[i]))
2133d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington        break;
2134d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2135d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington      ++i;
2136d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington    }
2137d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2138d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
2139d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2140d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  if (end)
2141d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington    *end = i;
2142d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington}
2143d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2144d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington/**
2145d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * Skips whitespace from end, storing the start index of the trailing
2146d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * whitespace in *start. (whitespace is space, tab, newline, CR).
2147d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington *
2148d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * @param str the string
2149d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * @param end where to start scanning backward
2150d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * @param start where to store the start of whitespace chars
2151d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington */
2152d8155bf51bf6484a94e734601526bf211053a5e1Havoc Penningtonvoid
2153d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington_dbus_string_skip_white_reverse (const DBusString *str,
2154d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington                                 int               end,
2155d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington                                 int              *start)
2156d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington{
2157d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  int i;
2158d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
2159d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_assert (end <= real->len);
2160d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_assert (end >= 0);
2161d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2162d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  i = end;
2163d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  while (i > 0)
2164d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington    {
2165d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington      if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
2166d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington        break;
2167d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington      --i;
2168d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington    }
2169d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2170d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
2171d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2172d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  if (start)
2173d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington    *start = i;
2174d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington}
2175d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
21762297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
217785ab0327d82e4945ad16630e583d8cc68df25a90Havoc Pennington * Assigns a newline-terminated or \\r\\n-terminated line from the front
2178c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington * of the string to the given dest string. The dest string's previous
2179c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington * contents are deleted. If the source string contains no newline,
2180c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington * moves the entire source string to the dest string.
2181b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
2182b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo owen correctly notes that this is a stupid function (it was
2183b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * written purely for test code,
2184b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * e.g. dbus-message-builder.c). Probably should be enforced as test
218515ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington * code only with ifdef DBUS_BUILD_TESTS
21863791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington *
21873791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param source the source string
21883791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param dest the destination string (contents are replaced)
21893791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @returns #FALSE if no memory, or source has length 0
21903791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington */
21913791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Penningtondbus_bool_t
21923791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington_dbus_string_pop_line (DBusString *source,
21933791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington                       DBusString *dest)
21943791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington{
2195f2e17db66f2e07e165fc90bba030a9f1d430834bRalf Habacker  int eol, eol_len;
21963791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
21973791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  _dbus_string_set_length (dest, 0);
21983791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
21993791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  eol = 0;
2200a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington  eol_len = 0;
2201f2e17db66f2e07e165fc90bba030a9f1d430834bRalf Habacker  if (!_dbus_string_find_eol (source, 0, &eol, &eol_len))
2202a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington    {
2203a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington      _dbus_assert (eol == _dbus_string_get_length (source));
2204a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington      if (eol == 0)
2205a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington        {
2206a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington          /* If there's no newline and source has zero length, we're done */
2207a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington          return FALSE;
2208a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington        }
2209a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington      /* otherwise, the last line of the file has no eol characters */
2210a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington    }
22113791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
2212a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington  /* remember eol can be 0 if it's an empty line, but eol_len should not be zero also
2213a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington   * since find_eol returned TRUE
2214a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington   */
22153791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
2216f2e17db66f2e07e165fc90bba030a9f1d430834bRalf Habacker  if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0))
2217a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington    return FALSE;
2218a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington
2219f2e17db66f2e07e165fc90bba030a9f1d430834bRalf Habacker  /* remove line ending */
2220a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington  if (!_dbus_string_set_length (dest, eol))
2221a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington    {
2222a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington      _dbus_assert_not_reached ("out of memory when shortening a string");
2223a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington      return FALSE;
2224a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington    }
2225a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington
2226a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington  return TRUE;
22273791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington}
22283791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
22297bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
22303791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington/**
22313791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * Deletes up to and including the first blank space
22323791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * in the string.
22333791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington *
22343791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param str the string
22353791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington */
22363791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Penningtonvoid
22373791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington_dbus_string_delete_first_word (DBusString *str)
22383791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington{
22393791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  int i;
22403791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
22413791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  if (_dbus_string_find_blank (str, 0, &i))
22423791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    _dbus_string_skip_blank (str, i, &i);
22433791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
22443791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  _dbus_string_delete (str, 0, i);
22453791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington}
22467bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif
22473791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
22487bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
22493791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington/**
22503791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * Deletes any leading blanks in the string
22513791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington *
22523791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param str the string
22533791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington */
22543791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Penningtonvoid
22553791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington_dbus_string_delete_leading_blanks (DBusString *str)
22563791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington{
22573791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  int i;
22583791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
22593791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  _dbus_string_skip_blank (str, 0, &i);
22603791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
22613791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  if (i > 0)
22623791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    _dbus_string_delete (str, 0, i);
22633791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington}
22647bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif
22653791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
22663791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington/**
2267d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * Deletes leading and trailing whitespace
2268d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington *
2269d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * @param str the string
2270d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington */
2271d8155bf51bf6484a94e734601526bf211053a5e1Havoc Penningtonvoid
2272d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington_dbus_string_chop_white(DBusString *str)
2273d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington{
2274d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  int i;
2275d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2276d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_string_skip_white (str, 0, &i);
2277d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2278d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  if (i > 0)
2279d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington    _dbus_string_delete (str, 0, i);
2280d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2281d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_string_skip_white_reverse (str, _dbus_string_get_length (str), &i);
2282d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2283d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_string_set_length (str, i);
2284d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington}
2285d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2286d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington/**
22872297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Tests two DBusString for equality.
22882297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
2289b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo memcmp is probably faster
2290b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
22912297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param a first string
22922297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param b second string
22932297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @returns #TRUE if equal
22942297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
22952297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtondbus_bool_t
22962297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_equal (const DBusString *a,
22972297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                    const DBusString *b)
22982297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
22992297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *ap;
23002297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *bp;
23012297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *a_end;
23022297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const DBusRealString *real_a = (const DBusRealString*) a;
23032297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const DBusRealString *real_b = (const DBusRealString*) b;
23042297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_a);
23052297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_b);
23062297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23072297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (real_a->len != real_b->len)
23082297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    return FALSE;
23092297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23102297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  ap = real_a->str;
23112297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  bp = real_b->str;
23122297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  a_end = real_a->str + real_a->len;
23132297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  while (ap != a_end)
23142297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
23152297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      if (*ap != *bp)
23162297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        return FALSE;
23172297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23182297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++ap;
23192297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++bp;
23202297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
23212297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23222297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  return TRUE;
23232297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
23242297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23252297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
23263791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * Tests two DBusString for equality up to the given length.
2327c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * The strings may be shorter than the given length.
23283791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington *
23293791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @todo write a unit test
23303791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington *
2331b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo memcmp is probably faster
2332b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
23333791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param a first string
23343791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param b second string
2335c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @param len the maximum length to look at
23363791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @returns #TRUE if equal for the given number of bytes
23373791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington */
23383791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Penningtondbus_bool_t
23393791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington_dbus_string_equal_len (const DBusString *a,
23403791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington                        const DBusString *b,
23413791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington                        int               len)
23423791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington{
23433791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  const unsigned char *ap;
23443791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  const unsigned char *bp;
23453791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  const unsigned char *a_end;
23463791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  const DBusRealString *real_a = (const DBusRealString*) a;
23473791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  const DBusRealString *real_b = (const DBusRealString*) b;
23483791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_a);
23493791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_b);
23503791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
23513791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  if (real_a->len != real_b->len &&
23523791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      (real_a->len < len || real_b->len < len))
23533791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    return FALSE;
23543791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
23553791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  ap = real_a->str;
23563791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  bp = real_b->str;
23573791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  a_end = real_a->str + MIN (real_a->len, len);
23583791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  while (ap != a_end)
23593791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    {
23603791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      if (*ap != *bp)
23613791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington        return FALSE;
23623791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
23633791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      ++ap;
23643791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      ++bp;
23653791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    }
23663791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
23673791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  return TRUE;
23683791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington}
23693791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
23703791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington/**
2371c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * Tests two sub-parts of two DBusString for equality.  The specified
2372c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * range of the first string must exist; the specified start position
2373c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * of the second string must exist.
2374c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington *
2375c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @todo write a unit test
2376c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington *
2377c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @todo memcmp is probably faster
2378c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington *
2379c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @param a first string
2380c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @param a_start where to start substring in first string
2381c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @param a_len length of substring in first string
2382c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @param b second string
2383c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @param b_start where to start substring in second string
2384c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @returns #TRUE if the two substrings are equal
2385c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington */
2386c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Penningtondbus_bool_t
2387c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington_dbus_string_equal_substring (const DBusString  *a,
2388c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington                              int                a_start,
2389c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington                              int                a_len,
2390c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington                              const DBusString  *b,
2391c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington                              int                b_start)
2392c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington{
2393c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  const unsigned char *ap;
2394c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  const unsigned char *bp;
2395c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  const unsigned char *a_end;
2396c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  const DBusRealString *real_a = (const DBusRealString*) a;
2397c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  const DBusRealString *real_b = (const DBusRealString*) b;
2398c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_a);
2399c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_b);
2400c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  _dbus_assert (a_start >= 0);
2401c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  _dbus_assert (a_len >= 0);
2402c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  _dbus_assert (a_start <= real_a->len);
2403c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  _dbus_assert (a_len <= real_a->len - a_start);
2404c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  _dbus_assert (b_start >= 0);
2405c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  _dbus_assert (b_start <= real_b->len);
2406c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington
2407c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  if (a_len > real_b->len - b_start)
2408c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington    return FALSE;
2409c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington
2410c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  ap = real_a->str + a_start;
2411c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  bp = real_b->str + b_start;
2412c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  a_end = ap + a_len;
2413c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  while (ap != a_end)
2414c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington    {
2415c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington      if (*ap != *bp)
2416c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington        return FALSE;
2417c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington
2418c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington      ++ap;
2419c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington      ++bp;
2420c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington    }
2421c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington
2422c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  _dbus_assert (bp <= (real_b->str + real_b->len));
2423c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington
2424c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  return TRUE;
2425c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington}
2426c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington
2427c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington/**
24282297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Checks whether a string is equal to a C string.
24292297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
24302297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param a the string
24312297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param c_str the C string
24322297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @returns #TRUE if equal
24332297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
24342297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtondbus_bool_t
24352297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_equal_c_str (const DBusString *a,
24362297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                          const char       *c_str)
24372297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
24382297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *ap;
24392297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *bp;
24402297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *a_end;
24412297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const DBusRealString *real_a = (const DBusRealString*) a;
24422297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_a);
2443b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (c_str != NULL);
2444b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
24452297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  ap = real_a->str;
24462297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  bp = (const unsigned char*) c_str;
24472297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  a_end = real_a->str + real_a->len;
24482297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  while (ap != a_end && *bp)
24492297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
24502297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      if (*ap != *bp)
24512297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        return FALSE;
24522297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24532297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++ap;
24542297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++bp;
24552297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
24562297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
2457b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (ap != a_end || *bp)
24582297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    return FALSE;
24592297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24602297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  return TRUE;
24612297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
24622297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24637bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
24642f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington/**
24652f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington * Checks whether a string starts with the given C string.
24662f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington *
24672f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington * @param a the string
24682f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington * @param c_str the C string
24692f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington * @returns #TRUE if string starts with it
24702f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington */
24712f440457d5fe45afb732820da64a147157e2e82dHavoc Penningtondbus_bool_t
24722f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington_dbus_string_starts_with_c_str (const DBusString *a,
24732f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington                                const char       *c_str)
24742f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington{
24752f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  const unsigned char *ap;
24762f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  const unsigned char *bp;
24772f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  const unsigned char *a_end;
24782f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  const DBusRealString *real_a = (const DBusRealString*) a;
24792f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_a);
2480b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (c_str != NULL);
2481b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
24822f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  ap = real_a->str;
24832f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  bp = (const unsigned char*) c_str;
24842f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  a_end = real_a->str + real_a->len;
24852f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  while (ap != a_end && *bp)
24862f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington    {
24872f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington      if (*ap != *bp)
24882f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington        return FALSE;
24892f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington
24902f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington      ++ap;
24912f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington      ++bp;
24922f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington    }
24932f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington
24942f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  if (*bp == '\0')
24952f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington    return TRUE;
24962f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  else
24972f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington    return FALSE;
24982f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington}
24997bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
250005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
2501ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington/**
2502aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington * Appends a two-character hex digit to a string, where the hex digit
2503aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington * has the value of the given byte.
2504aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington *
2505aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington * @param str the string
2506aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington * @param byte the byte
2507aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington * @returns #FALSE if no memory
2508aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington */
2509aa4f823781185fb18187714798795d7e4b0c9b65Havoc Penningtondbus_bool_t
2510aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington_dbus_string_append_byte_as_hex (DBusString *str,
2511aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington                                 int         byte)
2512aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington{
2513aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington  const char hexdigits[16] = {
2514aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
2515aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington    'a', 'b', 'c', 'd', 'e', 'f'
2516aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington  };
2517aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington
2518aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington  if (!_dbus_string_append_byte (str,
2519aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington                                 hexdigits[(byte >> 4)]))
2520aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington    return FALSE;
2521aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington
2522aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington  if (!_dbus_string_append_byte (str,
2523aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington                                 hexdigits[(byte & 0x0f)]))
2524aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington    {
2525aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington      _dbus_string_set_length (str,
2526aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington                               _dbus_string_get_length (str) - 1);
2527aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington      return FALSE;
2528aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington    }
2529aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington
2530aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington  return TRUE;
2531aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington}
2532aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington
2533aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington/**
25342f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * Encodes a string in hex, the way MD5 and SHA-1 are usually
25352f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * encoded. (Each byte is two hex digits.)
25362f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington *
25372f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param source the string to encode
25382f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param start byte index to start encoding
25392f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param dest string where encoded data should be placed
25402f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param insert_at where to place encoded data
25412f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @returns #TRUE if encoding was successful, #FALSE if no memory etc.
25422f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington */
25432f38c959212d98e2194139daa9120fda37415b4fHavoc Penningtondbus_bool_t
25442f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington_dbus_string_hex_encode (const DBusString *source,
25452f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         int               start,
25462f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         DBusString       *dest,
25472f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         int               insert_at)
25482f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington{
25492f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  DBusString result;
25502f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  const unsigned char *p;
25512f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  const unsigned char *end;
25522f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  dbus_bool_t retval;
25532f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25542f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  _dbus_assert (start <= _dbus_string_get_length (source));
25552f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
2556fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&result))
25572f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    return FALSE;
25582f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25592f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  retval = FALSE;
25602f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
2561fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  p = (const unsigned char*) _dbus_string_get_const_data (source);
25622f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  end = p + _dbus_string_get_length (source);
25632f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  p += start;
25642f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25652f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  while (p != end)
25662f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    {
2567aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington      if (!_dbus_string_append_byte_as_hex (&result, *p))
25682f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        goto out;
25692f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25702f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      ++p;
25712f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    }
25722f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25732f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  if (!_dbus_string_move (&result, 0, dest, insert_at))
25742f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    goto out;
25752f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25762f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  retval = TRUE;
25772f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25782f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington out:
25792f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  _dbus_string_free (&result);
25802f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  return retval;
25812f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington}
25822f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25832f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington/**
25842f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * Decodes a string from hex encoding.
25852f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington *
25862f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param source the string to decode
25872f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param start byte index to start decode
2588d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg * @param end_return return location of the end of the hex data, or #NULL
25892f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param dest string where decoded data should be placed
25902f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param insert_at where to place decoded data
2591d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg * @returns #TRUE if decoding was successful, #FALSE if no memory.
25922f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington */
25932f38c959212d98e2194139daa9120fda37415b4fHavoc Penningtondbus_bool_t
25942f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington_dbus_string_hex_decode (const DBusString *source,
25952f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         int               start,
2596d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg			 int              *end_return,
25972f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         DBusString       *dest,
25982f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         int               insert_at)
25992f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington{
26002f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  DBusString result;
26012f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  const unsigned char *p;
26022f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  const unsigned char *end;
26032f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  dbus_bool_t retval;
26042f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  dbus_bool_t high_bits;
26052f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26062f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  _dbus_assert (start <= _dbus_string_get_length (source));
26072f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
2608fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&result))
26092f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    return FALSE;
26102f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26112f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  retval = FALSE;
26122f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26132f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  high_bits = TRUE;
2614fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  p = (const unsigned char*) _dbus_string_get_const_data (source);
26152f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  end = p + _dbus_string_get_length (source);
26162f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  p += start;
26172f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26182f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  while (p != end)
26192f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    {
26202f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      unsigned int val;
26212f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26222f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      switch (*p)
26232f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        {
26242f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '0':
26252f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 0;
26262f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26272f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '1':
26282f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 1;
26292f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26302f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '2':
26312f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 2;
26322f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26332f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '3':
26342f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 3;
26352f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26362f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '4':
26372f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 4;
26382f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26392f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '5':
26402f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 5;
26412f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26422f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '6':
26432f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 6;
26442f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26452f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '7':
26462f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 7;
26472f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26482f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '8':
26492f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 8;
26502f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26512f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '9':
26522f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 9;
26532f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26542f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'a':
26552f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'A':
26562f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 10;
26572f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26582f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'b':
26592f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'B':
26602f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 11;
26612f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26622f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'c':
26632f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'C':
26642f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 12;
26652f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26662f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'd':
26672f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'D':
26682f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 13;
26692f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26702f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'e':
26712f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'E':
26722f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 14;
26732f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26742f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'f':
26752f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'F':
26762f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 15;
26772f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26782f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        default:
2679d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg          goto done;
26802f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        }
26812f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26822f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      if (high_bits)
26832f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        {
26842f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          if (!_dbus_string_append_byte (&result,
26852f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                                         val << 4))
2686d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg	    goto out;
26872f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        }
26882f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      else
26892f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        {
26902f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          int len;
26912f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          unsigned char b;
26922f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26932f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          len = _dbus_string_get_length (&result);
26942f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26952f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          b = _dbus_string_get_byte (&result, len - 1);
26962f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26972f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          b |= val;
26982f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26992f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          _dbus_string_set_byte (&result, len - 1, b);
27002f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        }
27012f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
27022f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      high_bits = !high_bits;
27032f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
27042f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      ++p;
27052f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    }
27062f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
2707d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg done:
27082f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  if (!_dbus_string_move (&result, 0, dest, insert_at))
27092f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    goto out;
27102f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
2711d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg  if (end_return)
2712d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg    *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
2713d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg
27142f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  retval = TRUE;
27152f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
27162f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington out:
27172f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  _dbus_string_free (&result);
27182f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  return retval;
27192f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington}
27202f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
27212f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington/**
27222f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * Checks that the given range of the string is valid ASCII with no
2723b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * nul bytes. If the given range is not entirely contained in the
2724b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * string, returns #FALSE.
2725ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington *
2726b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo this is inconsistent with most of DBusString in that
2727dbdea921b5967ed25b24a9e5af5d6a3db54c5ec7Havoc Pennington * it allows a start,len range that extends past the string end.
2728b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
2729ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * @param str the string
2730ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * @param start first byte index to check
2731ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * @param len number of bytes to check
2732ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * @returns #TRUE if the byte range exists and is all valid ASCII
2733ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington */
2734ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Penningtondbus_bool_t
2735ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington_dbus_string_validate_ascii (const DBusString *str,
2736ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington                             int               start,
2737ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington                             int               len)
2738ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington{
2739ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  const unsigned char *s;
2740ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  const unsigned char *end;
2741ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
2742ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (start >= 0);
2743b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
2744ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (len >= 0);
2745ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
2746b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (len > real->len - start)
2747ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    return FALSE;
2748ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
2749ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  s = real->str + start;
2750ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  end = s + len;
2751ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  while (s != end)
2752ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    {
2753f3228b477df95ba247c90cc54189ce6d62059251Havoc Pennington      if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
2754ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington        return FALSE;
2755ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
2756ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington      ++s;
2757ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    }
2758ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
2759ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  return TRUE;
2760ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington}
27612297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
27627ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington/**
2763a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker * Converts the given range of the string to lower case.
2764a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker *
2765a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker * @param str the string
2766a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker * @param start first byte index to convert
2767a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker * @param len number of bytes to convert
2768a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker */
2769a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habackervoid
2770a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker_dbus_string_tolower_ascii (const DBusString *str,
2771a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker                            int               start,
2772a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker                            int               len)
2773a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker{
2774a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  unsigned char *s;
2775a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  unsigned char *end;
2776a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  DBUS_STRING_PREAMBLE (str);
2777a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  _dbus_assert (start >= 0);
2778a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  _dbus_assert (start <= real->len);
2779a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  _dbus_assert (len >= 0);
2780a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  _dbus_assert (len <= real->len - start);
2781a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker
2782a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  s = real->str + start;
2783a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  end = s + len;
2784a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker
2785a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  while (s != end)
2786a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker    {
2787a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker      if (*s >= 'A' && *s <= 'Z')
2788a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker          *s += 'a' - 'A';
2789a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker      ++s;
2790a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker    }
2791a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker}
2792a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker
2793a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker/**
279447e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker * Converts the given range of the string to upper case.
279547e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker *
279647e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker * @param str the string
279747e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker * @param start first byte index to convert
279847e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker * @param len number of bytes to convert
279947e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker */
280047e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habackervoid
280147e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker_dbus_string_toupper_ascii (const DBusString *str,
280247e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker                            int               start,
280347e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker                            int               len)
280447e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker{
280547e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  unsigned char *s;
280647e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  unsigned char *end;
280747e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  DBUS_STRING_PREAMBLE (str);
280847e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  _dbus_assert (start >= 0);
280947e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  _dbus_assert (start <= real->len);
281047e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  _dbus_assert (len >= 0);
281147e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  _dbus_assert (len <= real->len - start);
281247e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker
281347e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  s = real->str + start;
281447e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  end = s + len;
281547e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker
281647e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  while (s != end)
281747e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker    {
281847e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker      if (*s >= 'a' && *s <= 'z')
281947e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker          *s += 'A' - 'a';
282047e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker      ++s;
282147e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker    }
282247e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker}
282347e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker
282447e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker/**
2825b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * Checks that the given range of the string is valid UTF-8. If the
2826b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * given range is not entirely contained in the string, returns
2827b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * #FALSE. If the string contains any nul bytes in the given range,
2828021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington * returns #FALSE. If the start and start+len are not on character
2829021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington * boundaries, returns #FALSE.
2830b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
2831b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo this is inconsistent with most of DBusString in that
2832dbdea921b5967ed25b24a9e5af5d6a3db54c5ec7Havoc Pennington * it allows a start,len range that extends past the string end.
28337ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington *
28347ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param str the string
28357ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param start first byte index to check
28367ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param len number of bytes to check
28377ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @returns #TRUE if the byte range exists and is all valid UTF-8
28387ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington */
28397ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Penningtondbus_bool_t
28407ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington_dbus_string_validate_utf8  (const DBusString *str,
28417ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                             int               start,
28427ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                             int               len)
28437ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington{
2844021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  const unsigned char *p;
2845ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington  const unsigned char *end;
2846021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
2847021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  _dbus_assert (start >= 0);
2848021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  _dbus_assert (start <= real->len);
2849021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  _dbus_assert (len >= 0);
2850021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
285175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  /* we are doing _DBUS_UNLIKELY() here which might be
28527652304bff969afb3969603149bb385efe861fe8John (J   * dubious in a generic library like GLib, but in D-Bus
285375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   * we know we're validating messages and that it would
285475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   * only be evil/broken apps that would have invalid
285575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   * UTF-8. Also, this function seems to be a performance
285675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   * bottleneck in profiles.
285775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   */
285875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
285975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_DBUS_UNLIKELY (len > real->len - start))
2860021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington    return FALSE;
2861021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2862ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington  p = real->str + start;
2863ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington  end = p + len;
2864021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2865ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington  while (p < end)
2866021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington    {
28671b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      int i, mask, char_len;
2868021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington      dbus_unichar_t result;
28691b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington
287025c1f310aafc8b3d89ee19656a64244e6f108dbbHavoc Pennington      /* nul bytes considered invalid */
287125c1f310aafc8b3d89ee19656a64244e6f108dbbHavoc Pennington      if (*p == '\0')
28721b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington        break;
28731b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington
28741b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      /* Special-case ASCII; this makes us go a lot faster in
28757652304bff969afb3969603149bb385efe861fe8John (J       * D-Bus profiles where we are typically validating
28761b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington       * function names and such. We have to know that
28771b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington       * all following checks will pass for ASCII though,
287825c1f310aafc8b3d89ee19656a64244e6f108dbbHavoc Pennington       * comments follow ...
287925c1f310aafc8b3d89ee19656a64244e6f108dbbHavoc Pennington       */
288025c1f310aafc8b3d89ee19656a64244e6f108dbbHavoc Pennington      if (*p < 128)
28811b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington        {
28821b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington          ++p;
28831b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington          continue;
28841b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington        }
2885021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
288625c1f310aafc8b3d89ee19656a64244e6f108dbbHavoc Pennington      UTF8_COMPUTE (*p, mask, char_len);
2887e537e421ff4f092621fcd9f6b51526a017ad020cAnders Carlsson
28881b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      if (_DBUS_UNLIKELY (char_len == 0))  /* ASCII: char_len == 1 */
2889021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington        break;
2890021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2891ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington      /* check that the expected number of bytes exists in the remaining length */
28921b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      if (_DBUS_UNLIKELY ((end - p) < char_len)) /* ASCII: p < end and char_len == 1 */
2893021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington        break;
2894021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2895021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington      UTF8_GET (result, p, i, mask, char_len);
2896021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
28971b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      /* Check for overlong UTF-8 */
28981b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* ASCII: UTF8_LENGTH == 1 */
2899ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington        break;
29001b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington#if 0
29011b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      /* The UNICODE_VALID check below will catch this */
29021b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) /* ASCII: result = ascii value */
2903021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington        break;
29041b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington#endif
2905021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
29061b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) /* ASCII: always valid */
2907ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington        break;
29081b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington
29091b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      /* UNICODE_VALID should have caught it */
29101b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      _dbus_assert (result != (dbus_unichar_t)-1);
2911021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2912021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington      p += char_len;
2913021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington    }
2914021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2915021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  /* See that we covered the entire length if a length was
2916021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington   * passed in
2917021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington   */
291875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_DBUS_UNLIKELY (p != end))
2919021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington    return FALSE;
2920021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  else
2921021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington    return TRUE;
29227ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington}
29237ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
29247ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington/**
2925b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * Checks that the given range of the string is all nul bytes. If the
2926b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * given range is not entirely contained in the string, returns
2927b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * #FALSE.
2928b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
2929b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo this is inconsistent with most of DBusString in that
2930dbdea921b5967ed25b24a9e5af5d6a3db54c5ec7Havoc Pennington * it allows a start,len range that extends past the string end.
29317ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington *
29327ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param str the string
29337ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param start first byte index to check
29347ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param len number of bytes to check
29357ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @returns #TRUE if the byte range exists and is all nul bytes
29367ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington */
29377ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Penningtondbus_bool_t
29387ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington_dbus_string_validate_nul (const DBusString *str,
29397ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                           int               start,
29407ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                           int               len)
29417ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington{
29427ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  const unsigned char *s;
29437ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  const unsigned char *end;
29447ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
29457ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  _dbus_assert (start >= 0);
29467ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  _dbus_assert (len >= 0);
2947b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
29487ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
2949b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (len > real->len - start)
29507ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    return FALSE;
29517ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
29527ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  s = real->str + start;
29537ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  end = s + len;
29547ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  while (s != end)
29557ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    {
295675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (_DBUS_UNLIKELY (*s != '\0'))
29577ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington        return FALSE;
29587ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington      ++s;
29597ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    }
29607ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
29617ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  return TRUE;
29627ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington}
29637ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
296478e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington/**
296578e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington * Clears all allocated bytes in the string to zero.
296678e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington *
2967c21511c01ab56d75f3aa4643761e9fd096a7f8beHavoc Pennington * @param str the string
296878e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington */
296978e16e99e753175fa49e787eab256932eefaa03fHavoc Penningtonvoid
297078e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington_dbus_string_zero (DBusString *str)
297178e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington{
297278e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington  DBUS_STRING_PREAMBLE (str);
297378e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington
2974d3fb6f35716ff1d6f6644dea2043d539007811deHavoc Pennington  memset (real->str - real->align_offset, '\0', real->allocated);
297578e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington}
2976d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/** @} */
2977d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
29787bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington/* tests are in dbus-string-util.c */
2979