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
25dbecdeabb20e0ce11121819c63373f0afba57c58Marcus Brinkmann#include <config.h>
26271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington#include "dbus-internals.h"
27d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#include "dbus-string.h"
28d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/* we allow a system header here, for speed/convenience */
29d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#include <string.h>
301d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington/* for vsnprintf */
311d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington#include <stdio.h>
3213f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington#define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
3313f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington#include "dbus-string-private.h"
349c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington#include "dbus-marshal-basic.h" /* probably should be removed by moving the usage of DBUS_TYPE
359c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                 * into the marshaling-related files
369c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                 */
37868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen/* for DBUS_VA_COPY */
38868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen#include "dbus-sysdeps.h"
39d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
40d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
41e19ebac55d671ecd92877af182300311afa7641aHavoc Pennington * @defgroup DBusString DBusString class
42d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @ingroup  DBusInternals
43e19ebac55d671ecd92877af182300311afa7641aHavoc Pennington * @brief DBusString data structure for safer string handling
44d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
45d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Types and functions related to DBusString. DBusString is intended
46d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * to be a string class that makes it hard to mess up security issues
47d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * (and just in general harder to write buggy code).  It should be
48d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * used (or extended and then used) rather than the libc stuff in
49d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * string.h.  The string class is a bit inconvenient at spots because
50d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * it handles out-of-memory failures and tries to be extra-robust.
51d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
52d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * A DBusString has a maximum length set at initialization time; this
53d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * can be used to ensure that a buffer doesn't get too big.  The
54d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * _dbus_string_lengthen() method checks for overflow, and for max
55d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * length being exceeded.
56d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
57d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Try to avoid conversion to a plain C string, i.e. add methods on
58d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the string object instead, only convert to C string when passing
59d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * things out to the public API. In particular, no sprintf, strcpy,
60d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * strcat, any of that should be used. The GString feature of
61d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * accepting negative numbers for "length of string" is also absent,
62d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * because it could keep us from detecting bogus huge lengths. i.e. if
63d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * we passed in some bogus huge length it would be taken to mean
64d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * "current length of string" instead of "broken crack"
6507d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington *
6607d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * @todo #DBusString needs a lot of cleaning up; some of the
6707d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * API is no longer used, and the API is pretty inconsistent.
6807d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * In particular all the "append" APIs, especially those involving
6907d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * alignment but probably lots of them, are no longer used by the
7007d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * marshaling code which always does "inserts" now.
71d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
72d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
73d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
74d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @addtogroup DBusString
75d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @{
76d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
77d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
78b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Penningtonstatic void
79b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Penningtonfixup_alignment (DBusRealString *real)
80b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington{
816606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  unsigned char *aligned;
826606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  unsigned char *real_block;
83b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  unsigned int old_align_offset;
84b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
85b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  /* we have to have extra space in real->allocated for the align offset and nul byte */
869c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (real->len <= real->allocated - _DBUS_STRING_ALLOCATION_PADDING);
87b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
88b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  old_align_offset = real->align_offset;
89b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  real_block = real->str - old_align_offset;
90b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
91b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  aligned = _DBUS_ALIGN_ADDRESS (real_block, 8);
92b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
93b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  real->align_offset = aligned - real_block;
94b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  real->str = aligned;
95b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
96b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (old_align_offset != real->align_offset)
97b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    {
98b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington      /* Here comes the suck */
99b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington      memmove (real_block + real->align_offset,
100b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington               real_block + old_align_offset,
101b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington               real->len + 1);
102b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    }
103b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
104b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (real->align_offset < 8);
105b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str);
106b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington}
107650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington
10813f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Penningtonstatic void
10913f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Penningtonundo_alignment (DBusRealString *real)
11013f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington{
11113f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington  if (real->align_offset != 0)
11213f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington    {
11313f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington      memmove (real->str - real->align_offset,
11413f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington               real->str,
11513f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington               real->len + 1);
11613f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington
11713f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington      real->str = real->str - real->align_offset;
118ce173b29fc1e9432cb5956952afdbe775da12415Havoc Pennington      real->align_offset = 0;
11913f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington    }
12013f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington}
12113f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington
122d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
123d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * Initializes a string that can be up to the given allocation size
124d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * before it has to realloc. The string starts life with zero length.
125d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * The string must eventually be freed with _dbus_string_free().
1261d2478ae4f2da8869eab94ca455a1329230c179eHavoc Pennington *
127d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str memory to hold the string
128d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param allocate_size amount to preallocate
129fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * @returns #TRUE on success, #FALSE if no memory
130fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington */
131d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
132d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington_dbus_string_init_preallocated (DBusString *str,
133d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                                int         allocate_size)
134d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
135d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusRealString *real;
136d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
137d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (str != NULL);
138d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
139d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (sizeof (DBusString) == sizeof (DBusRealString));
140d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
141d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real = (DBusRealString*) str;
142d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
143d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* It's very important not to touch anything
144d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   * other than real->str if we're going to fail,
145d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   * since we also use this function to reset
146d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   * an existing string, e.g. in _dbus_string_steal_data()
147d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   */
148d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1499c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  real->str = dbus_malloc (_DBUS_STRING_ALLOCATION_PADDING + allocate_size);
150d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (real->str == NULL)
151650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington    return FALSE;
152650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington
1539c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  real->allocated = _DBUS_STRING_ALLOCATION_PADDING + allocate_size;
154d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->len = 0;
155d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->str[real->len] = '\0';
156d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1577bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington  real->max_length = _DBUS_STRING_MAX_MAX_LENGTH;
158d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->constant = FALSE;
159d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->locked = FALSE;
160d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->invalid = FALSE;
161b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  real->align_offset = 0;
162b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
163b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  fixup_alignment (real);
164650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington
165d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
166d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
167d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
168d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington/**
169d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * Initializes a string. The string starts life with zero length.  The
170d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * string must eventually be freed with _dbus_string_free().
171d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington *
172d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param str memory to hold the string
173d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @returns #TRUE on success, #FALSE if no memory
174d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington */
175d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtondbus_bool_t
176d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington_dbus_string_init (DBusString *str)
177d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington{
178d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  return _dbus_string_init_preallocated (str, 0);
179d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington}
180d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1817bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
182fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington/* The max length thing is sort of a historical artifact
183fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * from a feature that turned out to be dumb; perhaps
184fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * we should purge it entirely. The problem with
185fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * the feature is that it looks like memory allocation
186fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * failure, but is not a transient or resolvable failure.
187fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington */
188fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonstatic void
189fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonset_max_length (DBusString *str,
190fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington                int         max_length)
191fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington{
192fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  DBusRealString *real;
193fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
194fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  real = (DBusRealString*) str;
195fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
196fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  real->max_length = max_length;
197fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington}
1987bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
199fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
200d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
201d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Initializes a constant string. The value parameter is not copied
202d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * (should be static), and the string may never be modified.
203d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * It is safe but not necessary to call _dbus_string_free()
204b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * on a const string. The string has a length limit of MAXINT - 8.
205d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
206d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str memory to use for the string
207d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param value a string to be stored in str (not copied!!!)
208d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
209d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
210d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_init_const (DBusString *str,
211d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                         const char *value)
212d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
213b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (value != NULL);
214b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
21550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_string_init_const_len (str, value,
21650c25505f62786756519ef1e194883360eda82e0Havoc Pennington                               strlen (value));
21750c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
21850c25505f62786756519ef1e194883360eda82e0Havoc Pennington
21950c25505f62786756519ef1e194883360eda82e0Havoc Pennington/**
22050c25505f62786756519ef1e194883360eda82e0Havoc Pennington * Initializes a constant string with a length. The value parameter is
22150c25505f62786756519ef1e194883360eda82e0Havoc Pennington * not copied (should be static), and the string may never be
22250c25505f62786756519ef1e194883360eda82e0Havoc Pennington * modified.  It is safe but not necessary to call _dbus_string_free()
22350c25505f62786756519ef1e194883360eda82e0Havoc Pennington * on a const string.
22450c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
22550c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param str memory to use for the string
22650c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param value a string to be stored in str (not copied!!!)
22750c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param len the length to use
22850c25505f62786756519ef1e194883360eda82e0Havoc Pennington */
22950c25505f62786756519ef1e194883360eda82e0Havoc Penningtonvoid
23050c25505f62786756519ef1e194883360eda82e0Havoc Pennington_dbus_string_init_const_len (DBusString *str,
23150c25505f62786756519ef1e194883360eda82e0Havoc Pennington                             const char *value,
23250c25505f62786756519ef1e194883360eda82e0Havoc Pennington                             int         len)
23350c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
234d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusRealString *real;
235d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
236d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (str != NULL);
2370d0642b31b9bac2546f9fa2c6bdc55b5ced0b7adRobert McQueen  _dbus_assert (len == 0 || value != NULL);
2387bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington  _dbus_assert (len <= _DBUS_STRING_MAX_MAX_LENGTH);
239b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len >= 0);
240b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
241d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real = (DBusRealString*) str;
242d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
2436606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  real->str = (unsigned char*) value;
24450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  real->len = len;
2459c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  real->allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING; /* a lie, just to avoid special-case assertions... */
246b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  real->max_length = real->len + 1;
247d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->constant = TRUE;
2489c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  real->locked = TRUE;
249d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->invalid = FALSE;
2509c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  real->align_offset = 0;
251650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington
252650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington  /* We don't require const strings to be 8-byte aligned as the
253650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington   * memory is coming from elsewhere.
254650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington   */
255d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
256d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
257d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
258d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Frees a string created by _dbus_string_init().
259d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
260d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str memory where the string is stored.
261d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
262d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
263d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_free (DBusString *str)
264d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
26505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  DBusRealString *real = (DBusRealString*) str;
26605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real);
267d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
268d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (real->constant)
269d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return;
27013f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington  dbus_free (real->str - real->align_offset);
271d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
272d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->invalid = TRUE;
273d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
274d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
2758c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortiestatic dbus_bool_t
2768c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortiecompact (DBusRealString *real,
2778c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie         int             max_waste)
2788c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie{
2798c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  unsigned char *new_str;
2808c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  int new_allocated;
2818c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  int waste;
2828c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
2838c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  waste = real->allocated - (real->len + _DBUS_STRING_ALLOCATION_PADDING);
2848c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
2858c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  if (waste <= max_waste)
2868c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie    return TRUE;
2878c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
2888c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  new_allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING;
2898c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
2908c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
2918c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  if (_DBUS_UNLIKELY (new_str == NULL))
2928c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie    return FALSE;
2938c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
2948c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  real->str = new_str + real->align_offset;
2958c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  real->allocated = new_allocated;
2968c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  fixup_alignment (real);
2978c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
2988c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  return TRUE;
2998c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie}
3008c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
301d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington#ifdef DBUS_BUILD_TESTS
302d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington/* Not using this feature at the moment,
303d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington * so marked DBUS_BUILD_TESTS-only
304d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington */
305d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
306b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * Locks a string such that any attempts to change the string will
307b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * result in aborting the program. Also, if the string is wasting a
308b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * lot of memory (allocation is sufficiently larger than what the
309b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * string is really using), _dbus_string_lock() will realloc the
310b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * string's data to "compact" it.
311d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
312d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string to lock.
313d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
314d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
315d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_lock (DBusString *str)
316d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
317d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_LOCKED_STRING_PREAMBLE (str); /* can lock multiple times */
318d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
319d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->locked = TRUE;
320d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
321d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* Try to realloc to avoid excess memory usage, since
322d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   * we know we won't change the string further
323d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   */
324b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington#define MAX_WASTE 48
3258c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  compact (real, MAX_WASTE);
326d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
327d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington#endif /* DBUS_BUILD_TESTS */
328d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
329e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtonstatic dbus_bool_t
330d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtonreallocate_for_length (DBusRealString *real,
331d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                       int             new_length)
332e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington{
333d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  int new_allocated;
3346606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  unsigned char *new_str;
335b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
336d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  /* at least double our old allocation to avoid O(n), avoiding
337d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington   * overflow
338d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington   */
3397bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington  if (real->allocated > (_DBUS_STRING_MAX_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2)
3407bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington    new_allocated = _DBUS_STRING_MAX_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING;
341d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  else
342d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    new_allocated = real->allocated * 2;
343b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
344d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  /* if you change the code just above here, run the tests without
3451b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington   * the following assert-only hack before you commit
346d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington   */
3471b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington  /* This is keyed off asserts in addition to tests so when you
3481b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington   * disable asserts to profile, you don't get this destroyer
3491b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington   * of profiles.
3501b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington   */
3511b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington#ifdef DBUS_DISABLE_ASSERT
3521b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington#else
35321cef58bc1b46ba4d5e7371463920c7744904d32Havoc Pennington#ifdef DBUS_BUILD_TESTS
354d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  new_allocated = 0; /* ensure a realloc every time so that we go
355d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                      * through all malloc failure codepaths
356d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                      */
3571b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington#endif /* DBUS_BUILD_TESTS */
3581b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington#endif /* !DBUS_DISABLE_ASSERT */
3591b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington
360d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  /* But be sure we always alloc at least space for the new length */
3611b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington  new_allocated = MAX (new_allocated,
3629c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                       new_length + _DBUS_STRING_ALLOCATION_PADDING);
363e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
364d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  _dbus_assert (new_allocated >= real->allocated); /* code relies on this */
365d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
3661b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington  if (_DBUS_UNLIKELY (new_str == NULL))
367d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
368e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
369d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  real->str = new_str + real->align_offset;
370d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  real->allocated = new_allocated;
371d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  fixup_alignment (real);
372e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
373e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  return TRUE;
374e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington}
375e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
3768c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie/**
3778c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie * Compacts the string to avoid wasted memory.  Wasted memory is
3788c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie * memory that is allocated but not actually required to store the
3798c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie * current length of the string.  The compact is only done if more
3808c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie * than the given amount of memory is being wasted (otherwise the
3818c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie * waste is ignored and the call does nothing).
3828c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie *
3838c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie * @param str the string
3848c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie * @param max_waste the maximum amount of waste to ignore
3858c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie * @returns #FALSE if the compact failed due to realloc failure
3868c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie */
3878c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortiedbus_bool_t
3888c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie_dbus_string_compact (DBusString *str,
3898c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie                      int         max_waste)
3908c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie{
3918c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  DBUS_STRING_PREAMBLE (str);
3928c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
3938c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie  return compact (real, max_waste);
3948c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie}
3958c6b0ab3f7e437362112eeaf83a566475b85d27cRyan Lortie
396e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtonstatic dbus_bool_t
397d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtonset_length (DBusRealString *real,
398d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington            int             new_length)
399d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington{
400d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  /* Note, we are setting the length not including nul termination */
401d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
402d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  /* exceeding max length is the same as failure to allocate memory */
4031b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington  if (_DBUS_UNLIKELY (new_length > real->max_length))
404d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
4059c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) &&
4061b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington           _DBUS_UNLIKELY (!reallocate_for_length (real, new_length)))
407d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
408d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  else
409d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    {
410d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      real->len = new_length;
4111b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      real->str[new_length] = '\0';
412d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      return TRUE;
413d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    }
414d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington}
415d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
416d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtonstatic dbus_bool_t
417e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtonopen_gap (int             len,
418e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington          DBusRealString *dest,
419e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington          int             insert_at)
420e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington{
421e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  if (len == 0)
422e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington    return TRUE;
423e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
424b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (len > dest->max_length - dest->len)
425b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    return FALSE; /* detected overflow of dest->len + len below */
426b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
427e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  if (!set_length (dest, dest->len + len))
428e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington    return FALSE;
429e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
430e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  memmove (dest->str + insert_at + len,
431e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington           dest->str + insert_at,
432e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington           dest->len - len - insert_at);
433e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
434e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  return TRUE;
435e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington}
436e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
4377bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifndef _dbus_string_get_data
438d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
439d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Gets the raw character buffer from the string.  The returned buffer
440d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * will be nul-terminated, but note that strings may contain binary
441d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * data so there may be extra nul characters prior to the termination.
442d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * This function should be little-used, extend DBusString or add
443d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * stuff to dbus-sysdeps.c instead. It's an error to use this
444d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * function on a const string.
445d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
446d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
447fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * @returns the data
448d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
449fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonchar*
450fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington_dbus_string_get_data (DBusString *str)
451d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
452d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
453d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
4546606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  return (char*) real->str;
455d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
4567bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* _dbus_string_get_data */
457d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
458b60c835d346b7e214e627abd8e0cdf06932313a7Havoc Pennington/* only do the function if we don't have the macro */
459b60c835d346b7e214e627abd8e0cdf06932313a7Havoc Pennington#ifndef _dbus_string_get_const_data
460d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
461a07bc460ae1a3d3582a6dac7e48ed1ea117990efHavoc Pennington * Gets the raw character buffer from a const string.
462a07bc460ae1a3d3582a6dac7e48ed1ea117990efHavoc Pennington *
463d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
464fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * @returns the string data
465d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
466fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonconst char*
467fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington_dbus_string_get_const_data (const DBusString  *str)
468d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
469d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
470d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
4716606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  return (const char*) real->str;
472d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
473b60c835d346b7e214e627abd8e0cdf06932313a7Havoc Pennington#endif /* _dbus_string_get_const_data */
474d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
475d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
476d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Gets a sub-portion of the raw character buffer from the
477d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * string. The "len" field is required simply for error
478d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * checking, to be sure you don't try to use more
479d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * string than exists. The nul termination of the
480d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * returned buffer remains at the end of the entire
481d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * string, not at start + len.
482d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
483d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
484d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start byte offset to return
485d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len length of segment to return
486fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * @returns the string data
487d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
488fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonchar*
489d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_get_data_len (DBusString *str,
490d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                           int         start,
491d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                           int         len)
492d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
493d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
494d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (start >= 0);
495d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
496b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
497b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real->len - start);
498d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
4996606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  return (char*) real->str + start;
500d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
501d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
502b3416423b1e3c17357833d896c1b7cd684660771Havoc Pennington/* only do the function if we don't have the macro */
503b3416423b1e3c17357833d896c1b7cd684660771Havoc Pennington#ifndef _dbus_string_get_const_data_len
504d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
505d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * const version of _dbus_string_get_data_len().
506d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
507d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
508d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start byte offset to return
509d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len length of segment to return
510fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * @returns the string data
511d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
512fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonconst char*
513d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_get_const_data_len (const DBusString  *str,
514d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                                 int                start,
515d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                                 int                len)
516d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
517d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
518d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (start >= 0);
519d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
520b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
521b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real->len - start);
522d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
5236606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  return (const char*) real->str + start;
524d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
525b3416423b1e3c17357833d896c1b7cd684660771Havoc Pennington#endif /* _dbus_string_get_const_data_len */
526d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
527b3416423b1e3c17357833d896c1b7cd684660771Havoc Pennington/* only do the function if we don't have the macro */
528b3416423b1e3c17357833d896c1b7cd684660771Havoc Pennington#ifndef _dbus_string_set_byte
529d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
530e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * Sets the value of the byte at the given position.
531e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington *
532e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param str the string
533e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param i the position
534e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param byte the new value
535e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington */
536e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtonvoid
537e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington_dbus_string_set_byte (DBusString    *str,
538e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington                       int            i,
539e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington                       unsigned char  byte)
540e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington{
541e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  DBUS_STRING_PREAMBLE (str);
542e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_assert (i < real->len);
543b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (i >= 0);
544b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
545e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  real->str[i] = byte;
546e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington}
547b3416423b1e3c17357833d896c1b7cd684660771Havoc Pennington#endif /* _dbus_string_set_byte */
548e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
549b60c835d346b7e214e627abd8e0cdf06932313a7Havoc Pennington/* only have the function if we didn't create a macro */
550b60c835d346b7e214e627abd8e0cdf06932313a7Havoc Pennington#ifndef _dbus_string_get_byte
551e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington/**
55275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * Gets the byte at the given position. It is
55375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * allowed to ask for the nul byte at the end of
55475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * the string.
55550c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
55650c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param str the string
55750c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param start the position
55850c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @returns the byte at that position
55950c25505f62786756519ef1e194883360eda82e0Havoc Pennington */
560e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtonunsigned char
56150c25505f62786756519ef1e194883360eda82e0Havoc Pennington_dbus_string_get_byte (const DBusString  *str,
56250c25505f62786756519ef1e194883360eda82e0Havoc Pennington                       int                start)
56350c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
56450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
56575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  _dbus_assert (start <= real->len);
566b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start >= 0);
567b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
56850c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return real->str[start];
56950c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
570b60c835d346b7e214e627abd8e0cdf06932313a7Havoc Pennington#endif /* _dbus_string_get_byte */
57150c25505f62786756519ef1e194883360eda82e0Havoc Pennington
57250c25505f62786756519ef1e194883360eda82e0Havoc Pennington/**
57346c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin * Inserts a number of bytes of a given value at the
57446c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin * given position.
575e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington *
576e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param str the string
577e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param i the position
57846c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin * @param n_bytes number of bytes
579e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param byte the value to insert
580e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @returns #TRUE on success
581e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington */
582e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtondbus_bool_t
58346c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin_dbus_string_insert_bytes (DBusString   *str,
58446c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin			   int           i,
58546c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin			   int           n_bytes,
58646c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin			   unsigned char byte)
587e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington{
588e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  DBUS_STRING_PREAMBLE (str);
589e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_assert (i <= real->len);
590b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (i >= 0);
591e11ae7246655e59f8e04d1ffcb3788176a6d98b8Havoc Pennington  _dbus_assert (n_bytes >= 0);
592e11ae7246655e59f8e04d1ffcb3788176a6d98b8Havoc Pennington
593e11ae7246655e59f8e04d1ffcb3788176a6d98b8Havoc Pennington  if (n_bytes == 0)
594e11ae7246655e59f8e04d1ffcb3788176a6d98b8Havoc Pennington    return TRUE;
595b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
59646c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  if (!open_gap (n_bytes, real, i))
597e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington    return FALSE;
598e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
59946c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  memset (real->str + i, byte, n_bytes);
600e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
601e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  return TRUE;
602e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington}
603e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
604e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington/**
605617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * Inserts a single byte at the given position.
606617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington *
607617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param str the string
608617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param i the position
609617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param byte the value to insert
610617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @returns #TRUE on success
611617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington */
612617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Penningtondbus_bool_t
613617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington_dbus_string_insert_byte (DBusString   *str,
614617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington			   int           i,
615617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington			   unsigned char byte)
616617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington{
617617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  DBUS_STRING_PREAMBLE (str);
618617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  _dbus_assert (i <= real->len);
619617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  _dbus_assert (i >= 0);
620617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
621617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  if (!open_gap (1, real, i))
622617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington    return FALSE;
623617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
624617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  real->str[i] = byte;
625617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
626617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  return TRUE;
627617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington}
628617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
629617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington/**
630d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Like _dbus_string_get_data(), but removes the
631d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * gotten data from the original string. The caller
632d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * must free the data returned. This function may
633d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * fail due to lack of memory, and return #FALSE.
634d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
635d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
636d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param data_return location to return the buffer
637d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #TRUE on success
638d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
639d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
640d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_steal_data (DBusString        *str,
641d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                         char             **data_return)
642d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
643fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  int old_max_length;
644d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
645d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (data_return != NULL);
64613f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington
64713f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington  undo_alignment (real);
648d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
6496606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  *data_return = (char*) real->str;
650d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
651fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  old_max_length = real->max_length;
652fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
653d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* reset the string */
654fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (str))
655d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
656d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      /* hrm, put it back then */
6576606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington      real->str = (unsigned char*) *data_return;
658d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      *data_return = NULL;
65913f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington      fixup_alignment (real);
660d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      return FALSE;
661d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
662d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
663fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  real->max_length = old_max_length;
664fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
665d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
666d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
667d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
6687bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
669d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
670d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Like _dbus_string_get_data_len(), but removes the gotten data from
671d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the original string. The caller must free the data returned. This
672d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * function may fail due to lack of memory, and return #FALSE.
673d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * The returned string is nul-terminated and has length len.
674d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
675b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo this function is broken because on failure it
676b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * may corrupt the source string.
677b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
678d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
679d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param data_return location to return the buffer
680d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start the start of segment to steal
681d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len the length of segment to steal
682d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #TRUE on success
683d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
684d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
685d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_steal_data_len (DBusString        *str,
686d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                             char             **data_return,
687d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                             int                start,
688d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                             int                len)
689d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
690d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusString dest;
691d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
692d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (data_return != NULL);
693d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (start >= 0);
694d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
695b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
696b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real->len - start);
697d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
698fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&dest))
699d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return FALSE;
700d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
701fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  set_max_length (&dest, real->max_length);
702fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
703d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_move_len (str, start, len, &dest, 0))
704d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
705d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      _dbus_string_free (&dest);
706d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      return FALSE;
707d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
708b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
709bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_warn ("Broken code in _dbus_string_steal_data_len(), see @todo, FIXME\n");
710bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  if (!_dbus_string_steal_data (&dest, data_return))
711bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    {
712bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington      _dbus_string_free (&dest);
713bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington      return FALSE;
714bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    }
715bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
716bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_string_free (&dest);
717bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  return TRUE;
718bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington}
7197bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
720bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
721bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington/**
722bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * Copies the data from the string into a char*
723bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington *
724bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param str the string
725bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param data_return place to return the data
726bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @returns #TRUE on success, #FALSE on no memory
727bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington */
728bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Penningtondbus_bool_t
729bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington_dbus_string_copy_data (const DBusString  *str,
730bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington                        char             **data_return)
731bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington{
732bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
733bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (data_return != NULL);
734bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
735bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  *data_return = dbus_malloc (real->len + 1);
736bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  if (*data_return == NULL)
737bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    return FALSE;
738bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
739bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  memcpy (*data_return, real->str, real->len + 1);
740bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
741bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  return TRUE;
742bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington}
743bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
7447ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington/**
745bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * Copies the contents of a DBusString into a different buffer. It is
746bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * a bug if avail_len is too short to hold the string contents. nul
747bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * termination is not copied, just the supplied bytes.
7487ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington *
7497ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington * @param str a string
7507ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington * @param buffer a C buffer to copy data to
7517ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington * @param avail_len maximum length of C buffer
7527ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington */
7537ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Penningtonvoid
7547ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington_dbus_string_copy_to_buffer (const DBusString  *str,
7557ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington			     char              *buffer,
7567ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington			     int                avail_len)
7577ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington{
7587ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
7597ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington
7607ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington  _dbus_assert (avail_len >= 0);
761bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington  _dbus_assert (avail_len >= real->len);
762bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington
763bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington  memcpy (buffer, real->str, real->len);
764bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington}
765bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington
766bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington/**
767bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * Copies the contents of a DBusString into a different buffer. It is
768bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * a bug if avail_len is too short to hold the string contents plus a
769bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * nul byte.
770bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington *
771bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * @param str a string
772bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * @param buffer a C buffer to copy data to
773bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington * @param avail_len maximum length of C buffer
774bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington */
775bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Penningtonvoid
776bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington_dbus_string_copy_to_buffer_with_nul (const DBusString  *str,
777bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington                                      char              *buffer,
778bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington                                      int                avail_len)
779bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington{
780bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
7817ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington
782bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington  _dbus_assert (avail_len >= 0);
783bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington  _dbus_assert (avail_len > real->len);
784bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington
785bef4260ad58bc9eb75e2e1a52ad9b49bc3c70fa5Havoc Pennington  memcpy (buffer, real->str, real->len+1);
7867ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington}
7877ce7502e1ae23766ba40105327de787c2d1cef9dHavoc Pennington
7887bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
789bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington/**
790bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * Copies a segment of the string into a char*
791bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington *
792bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param str the string
793bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param data_return place to return the data
794bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param start start index
795bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param len length to copy
796bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @returns #FALSE if no memory
797bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington */
798bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Penningtondbus_bool_t
799bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington_dbus_string_copy_data_len (const DBusString  *str,
800bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington                            char             **data_return,
801bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington                            int                start,
802bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington                            int                len)
803bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington{
804bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  DBusString dest;
805bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
806bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
807bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (data_return != NULL);
808bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (start >= 0);
809bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (len >= 0);
810bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (start <= real->len);
811bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (len <= real->len - start);
812bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
813fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&dest))
814bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    return FALSE;
815bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
816fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  set_max_length (&dest, real->max_length);
817fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
818bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  if (!_dbus_string_copy_len (str, start, len, &dest, 0))
819bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    {
820bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington      _dbus_string_free (&dest);
821bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington      return FALSE;
822bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    }
823bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
824d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_steal_data (&dest, data_return))
825d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
826d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      _dbus_string_free (&dest);
827d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      return FALSE;
828d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
829d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
830d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_string_free (&dest);
831d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
832d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
8337bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
834935a41a04c3f638134fa905503fc41ddbd18902fColin Walters
8351b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington/* Only have the function if we don't have the macro */
8361b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington#ifndef _dbus_string_get_length
837935a41a04c3f638134fa905503fc41ddbd18902fColin Walters/**
838d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Gets the length of a string (not including nul termination).
839d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
840d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns the length.
841d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
842d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonint
843d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_get_length (const DBusString  *str)
844d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
8453100d06aa6965f2eaa3f8f393817d0a4858c5329The Android Open Source Project  /* The assertion should not fail for empty strings. */
8463100d06aa6965f2eaa3f8f393817d0a4858c5329The Android Open Source Project  DBusRealString *real = (DBusRealString *)str;
8473100d06aa6965f2eaa3f8f393817d0a4858c5329The Android Open Source Project  if (((DBusRealString *)str)->len || ((DBusRealString *)str)->allocated) {
8483100d06aa6965f2eaa3f8f393817d0a4858c5329The Android Open Source Project      DBUS_CONST_STRING_PREAMBLE (str);
8493100d06aa6965f2eaa3f8f393817d0a4858c5329The Android Open Source Project  }
850d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
851d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return real->len;
852d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
8531b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington#endif /* !_dbus_string_get_length */
854d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
855d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
856d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Makes a string longer by the given number of bytes.  Checks whether
857d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * adding additional_length to the current length would overflow an
858d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * integer, and checks for exceeding a string's max length.
859d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * The new bytes are not initialized, other than nul-terminating
860d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the end of the string. The uninitialized bytes may contain
861b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * nul bytes or other junk.
862d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
863d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str a string
864d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param additional_length length to add to the string.
865d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #TRUE on success.
866d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
867d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
868d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_lengthen (DBusString *str,
869d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int         additional_length)
870d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
871d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
872d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (additional_length >= 0);
873b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
8741b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington  if (_DBUS_UNLIKELY (additional_length > real->max_length - real->len))
875b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    return FALSE; /* would overflow */
876d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
877d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return set_length (real,
878d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                     real->len + additional_length);
879d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
880d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
881d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
882d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Makes a string shorter by the given number of bytes.
883d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
884d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str a string
885d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param length_to_remove length to remove from the string.
886d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
887d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
888d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_shorten (DBusString *str,
889d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                      int         length_to_remove)
890d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
891d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
892d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (length_to_remove >= 0);
893d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (length_to_remove <= real->len);
894d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
895d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  set_length (real,
896d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington              real->len - length_to_remove);
897d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
898d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
899d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
900d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Sets the length of a string. Can be used to truncate or lengthen
901d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the string. If the string is lengthened, the function may fail and
902d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * return #FALSE. Newly-added bytes are not initialized, as with
903d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * _dbus_string_lengthen().
904d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
905d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str a string
906d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param length new length of the string.
907d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE on failure.
908d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
909d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
910d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_set_length (DBusString *str,
911d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                         int         length)
912d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
913d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
914d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (length >= 0);
915d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
916d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return set_length (real, length);
917d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
918d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
919d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtonstatic dbus_bool_t
920617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Penningtonalign_insert_point_then_open_gap (DBusString *str,
921617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                                  int        *insert_at_p,
922617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                                  int         alignment,
923617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                                  int         gap_size)
924993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington{
925b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */
926617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  unsigned long gap_pos;
927617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  int insert_at;
928993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  int delta;
929993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  DBUS_STRING_PREAMBLE (str);
930993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  _dbus_assert (alignment >= 1);
9317ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
932993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
933617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  insert_at = *insert_at_p;
934617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
935617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  _dbus_assert (insert_at <= real->len);
936617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
937617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment);
938617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  new_len = real->len + (gap_pos - insert_at) + gap_size;
939617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
940617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  if (_DBUS_UNLIKELY (new_len > (unsigned long) real->max_length))
941b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    return FALSE;
942b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
943993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  delta = new_len - real->len;
944993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  _dbus_assert (delta >= 0);
945993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
946617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  if (delta == 0) /* only happens if gap_size == 0 and insert_at is aligned already */
947617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington    {
948617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington      _dbus_assert (((unsigned long) *insert_at_p) == gap_pos);
949617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington      return TRUE;
950617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington    }
951993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
952617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  if (_DBUS_UNLIKELY (!open_gap (new_len - real->len,
953617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                                 real, insert_at)))
954993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington    return FALSE;
955993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
956617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  /* nul the padding if we had to add any padding */
957617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  if (gap_size < delta)
958d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    {
959617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington      memset (&real->str[insert_at], '\0',
960617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington              gap_pos - insert_at);
961d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    }
962617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
963617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *insert_at_p = gap_pos;
964617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
965993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  return TRUE;
966993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington}
967993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
968617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Penningtonstatic dbus_bool_t
969617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Penningtonalign_length_then_lengthen (DBusString *str,
970617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                            int         alignment,
971617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                            int         then_lengthen_by)
972617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington{
973617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  int insert_at;
974617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
975617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  insert_at = _dbus_string_get_length (str);
976617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
977617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  return align_insert_point_then_open_gap (str,
978617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                                           &insert_at,
979617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                                           alignment, then_lengthen_by);
980617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington}
981617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
982d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington/**
983d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * Align the length of a string to a specific alignment (typically 4 or 8)
984d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * by appending nul bytes to the string.
985d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington *
986d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param str a string
987d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param alignment the alignment
988d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @returns #FALSE if no memory
989d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington */
990d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtondbus_bool_t
991d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington_dbus_string_align_length (DBusString *str,
992d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                           int         alignment)
993d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington{
994d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  return align_length_then_lengthen (str, alignment, 0);
995d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington}
996d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
997617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington/**
998617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * Preallocate extra_bytes such that a future lengthening of the
999617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * string by extra_bytes is guaranteed to succeed without an out of
1000617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * memory error.
1001617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington *
1002617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param str a string
1003617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param extra_bytes bytes to alloc
1004617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @returns #FALSE if no memory
1005617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington */
1006617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Penningtondbus_bool_t
1007617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington_dbus_string_alloc_space (DBusString        *str,
1008617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                          int                extra_bytes)
1009617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington{
1010617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  if (!_dbus_string_lengthen (str, extra_bytes))
1011617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington    return FALSE;
1012617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  _dbus_string_shorten (str, extra_bytes);
1013617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
1014617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  return TRUE;
1015617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington}
1016617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
1017d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonstatic dbus_bool_t
1018d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonappend (DBusRealString *real,
1019d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        const char     *buffer,
1020d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        int             buffer_len)
1021d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1022d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (buffer_len == 0)
1023d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return TRUE;
1024d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1025d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
1026d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return FALSE;
1027d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1028d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  memcpy (real->str + (real->len - buffer_len),
1029d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington          buffer,
1030d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington          buffer_len);
1031d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1032d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
1033d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1034d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1035d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1036d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Appends a nul-terminated C-style string to a DBusString.
1037d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1038d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the DBusString
1039d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param buffer the nul-terminated characters to append
1040d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory.
1041d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1042d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1043d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_append (DBusString *str,
1044d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                     const char *buffer)
1045d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1046b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  unsigned long buffer_len;
1047d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1048d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
1049d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (buffer != NULL);
1050d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1051d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  buffer_len = strlen (buffer);
1052b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (buffer_len > (unsigned long) real->max_length)
1053b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    return FALSE;
1054b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
1055d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return append (real, buffer, buffer_len);
1056d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1057d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
10583ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington/** assign 2 bytes from one string to another */
10593ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington#define ASSIGN_2_OCTETS(p, octets) \
10603ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington  *((dbus_uint16_t*)(p)) = *((dbus_uint16_t*)(octets));
10617bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington
106231988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington/** assign 4 bytes from one string to another */
1063617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington#define ASSIGN_4_OCTETS(p, octets) \
1064617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
1065617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
1066617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington#ifdef DBUS_HAVE_INT64
106731988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington/** assign 8 bytes from one string to another */
1068617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington#define ASSIGN_8_OCTETS(p, octets) \
1069617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
1070617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington#else
107131988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington/** assign 8 bytes from one string to another */
1072617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington#define ASSIGN_8_OCTETS(p, octets)              \
1073617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Penningtondo {                                            \
1074617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  unsigned char *b;                             \
1075617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                                                \
1076617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  b = p;                                        \
1077617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                                                \
1078617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *b++ = octets[0];                             \
1079617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *b++ = octets[1];                             \
1080617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *b++ = octets[2];                             \
1081617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *b++ = octets[3];                             \
1082617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *b++ = octets[4];                             \
1083617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *b++ = octets[5];                             \
1084617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *b++ = octets[6];                             \
1085617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  *b++ = octets[7];                             \
1086617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  _dbus_assert (b == p + 8);                    \
1087617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington} while (0)
1088617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington#endif /* DBUS_HAVE_INT64 */
1089617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
10907bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
1091d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1092d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * Appends 4 bytes aligned on a 4 byte boundary
1093d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * with any alignment padding initialized to 0.
1094d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington *
1095d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param str the DBusString
1096d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param octets 4 bytes to append
1097d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @returns #FALSE if not enough memory.
1098d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington */
1099d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtondbus_bool_t
1100d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington_dbus_string_append_4_aligned (DBusString         *str,
1101d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                               const unsigned char octets[4])
1102d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington{
1103d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  DBUS_STRING_PREAMBLE (str);
1104d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1105d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  if (!align_length_then_lengthen (str, 4, 4))
1106d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
1107d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1108617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  ASSIGN_4_OCTETS (real->str + (real->len - 4), octets);
1109d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1110d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  return TRUE;
1111d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington}
11127bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
1113d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
11147bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
1115d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington/**
1116d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * Appends 8 bytes aligned on an 8 byte boundary
1117d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * with any alignment padding initialized to 0.
1118d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington *
1119d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param str the DBusString
1120617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param octets 8 bytes to append
1121d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @returns #FALSE if not enough memory.
1122d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington */
1123d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtondbus_bool_t
1124d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington_dbus_string_append_8_aligned (DBusString         *str,
1125d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                               const unsigned char octets[8])
1126d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington{
1127d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  DBUS_STRING_PREAMBLE (str);
1128d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1129d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  if (!align_length_then_lengthen (str, 8, 8))
1130d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
1131d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1132617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  ASSIGN_8_OCTETS (real->str + (real->len - 8), octets);
1133617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
1134617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  return TRUE;
1135617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington}
11367bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
1137617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
1138617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington/**
11393ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington * Inserts 2 bytes aligned on a 2 byte boundary
11403ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington * with any alignment padding initialized to 0.
11413ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington *
11423ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington * @param str the DBusString
11433ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington * @param insert_at where to insert
11443ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington * @param octets 2 bytes to insert
11453ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington * @returns #FALSE if not enough memory.
11463ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington */
11473ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Penningtondbus_bool_t
11483ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington_dbus_string_insert_2_aligned (DBusString         *str,
11493ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington                               int                 insert_at,
11503ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington                               const unsigned char octets[4])
11513ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington{
11523ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington  DBUS_STRING_PREAMBLE (str);
11533ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington
11543ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington  if (!align_insert_point_then_open_gap (str, &insert_at, 2, 2))
11553ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington    return FALSE;
11563ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington
11573ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington  ASSIGN_2_OCTETS (real->str + insert_at, octets);
11583ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington
11593ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington  return TRUE;
11603ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington}
11613ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington
11623ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington/**
1163617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * Inserts 4 bytes aligned on a 4 byte boundary
1164617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * with any alignment padding initialized to 0.
1165617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington *
1166617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param str the DBusString
116731988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington * @param insert_at where to insert
1168617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param octets 4 bytes to insert
1169617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @returns #FALSE if not enough memory.
1170617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington */
1171617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Penningtondbus_bool_t
1172617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington_dbus_string_insert_4_aligned (DBusString         *str,
1173617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                               int                 insert_at,
1174617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                               const unsigned char octets[4])
1175617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington{
1176d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  DBUS_STRING_PREAMBLE (str);
1177d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1178617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  if (!align_insert_point_then_open_gap (str, &insert_at, 4, 4))
1179d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
1180d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1181617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  ASSIGN_4_OCTETS (real->str + insert_at, octets);
1182617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
1183617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  return TRUE;
1184617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington}
1185617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
1186617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington/**
1187617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * Inserts 8 bytes aligned on an 8 byte boundary
1188617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * with any alignment padding initialized to 0.
1189617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington *
1190617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param str the DBusString
119131988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington * @param insert_at where to insert
1192617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @param octets 8 bytes to insert
1193617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington * @returns #FALSE if not enough memory.
1194617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington */
1195617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Penningtondbus_bool_t
1196617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington_dbus_string_insert_8_aligned (DBusString         *str,
1197617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                               int                 insert_at,
1198617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington                               const unsigned char octets[8])
1199617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington{
1200617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  DBUS_STRING_PREAMBLE (str);
1201d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1202617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  if (!align_insert_point_then_open_gap (str, &insert_at, 8, 8))
1203617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington    return FALSE;
1204617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington
1205bb8f518d07adffbefcc7d592af0655b2afa4ab19Havoc Pennington  _dbus_assert (_DBUS_ALIGN_VALUE (insert_at, 8) == (unsigned) insert_at);
1206bb8f518d07adffbefcc7d592af0655b2afa4ab19Havoc Pennington
1207617e73f7631e605fc9ebf6a67042a1f451b97850Havoc Pennington  ASSIGN_8_OCTETS (real->str + insert_at, octets);
1208d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1209d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  return TRUE;
1210d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington}
1211d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
121207d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington
121307d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington/**
121407d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * Inserts padding at *insert_at such to align it to the given
121507d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * boundary. Initializes the padding to nul bytes. Sets *insert_at
121607d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * to the aligned position.
121707d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington *
121807d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * @param str the DBusString
121907d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * @param insert_at location to be aligned
12203ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington * @param alignment alignment boundary (1, 2, 4, or 8)
122107d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington * @returns #FALSE if not enough memory.
122207d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington */
122307d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Penningtondbus_bool_t
122407d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington_dbus_string_insert_alignment (DBusString        *str,
122507d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington                               int               *insert_at,
122607d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington                               int                alignment)
122707d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington{
122807d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington  DBUS_STRING_PREAMBLE (str);
122907d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington
12309c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (!align_insert_point_then_open_gap (str, insert_at, alignment, 0))
123107d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington    return FALSE;
123207d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington
12339c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (_DBUS_ALIGN_VALUE (*insert_at, alignment) == (unsigned) *insert_at);
123407d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington
123507d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington  return TRUE;
123607d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington}
123707d2fd5aa2891d94bcb97db89178a4d536599d14Havoc Pennington
1238d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington/**
12391d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * Appends a printf-style formatted string
12401d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * to the #DBusString.
12411d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington *
12421d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @param str the string
12431d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @param format printf format
12441d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @param args variable argument list
12451d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @returns #FALSE if no memory
12461d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington */
12471d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Penningtondbus_bool_t
12481d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington_dbus_string_append_printf_valist  (DBusString        *str,
12491d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington                                    const char        *format,
12501d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington                                    va_list            args)
12511d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington{
12521d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  int len;
1253ce09b82ec2dd3cb1d239605f8f458e09afd70694Colin Walters  va_list args_copy;
1254868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen
125524f411a6a10e4838f57595720642ce83ceae814cHavoc Pennington  DBUS_STRING_PREAMBLE (str);
1256868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen
1257868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen  DBUS_VA_COPY (args_copy, args);
1258868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen
12591d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  /* Measure the message length without terminating nul */
1260d387411488a093f77f4cd752b75e8bf8360550c6John (J  len = _dbus_printf_string_upper_bound (format, args);
12611d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
12621d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  if (!_dbus_string_lengthen (str, len))
1263868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen    {
1264868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen      /* don't leak the copy */
1265868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen      va_end (args_copy);
1266868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen      return FALSE;
1267868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen    }
1268868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen
12696606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  vsprintf ((char*) (real->str + (real->len - len)),
1270868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen            format, args_copy);
1271868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen
1272868dd4b4b0be082b86354b1f89ed9cffd5b8e193David Zeuthen  va_end (args_copy);
12731d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
12741d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  return TRUE;
12751d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington}
12761d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
12771d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington/**
12781d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * Appends a printf-style formatted string
12791d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * to the #DBusString.
12801d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington *
12811d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @param str the string
12821d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @param format printf format
12831d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @returns #FALSE if no memory
12841d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington */
12851d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Penningtondbus_bool_t
12861d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington_dbus_string_append_printf (DBusString        *str,
12871d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington                            const char        *format,
12881d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington                            ...)
12891d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington{
12901d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  va_list args;
12911d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  dbus_bool_t retval;
12921d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
12931d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  va_start (args, format);
12941d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  retval = _dbus_string_append_printf_valist (str, format, args);
12951d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  va_end (args);
12961d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
12971d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  return retval;
12981d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington}
12991d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
13001d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington/**
1301d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Appends block of bytes with the given length to a DBusString.
1302d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1303d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the DBusString
1304d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param buffer the bytes to append
1305d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len the number of bytes to append
1306d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory.
1307d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1308d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1309d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_append_len (DBusString *str,
1310d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                         const char *buffer,
1311d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                         int         len)
1312d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1313d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
1314d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (buffer != NULL);
1315d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
1316d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1317d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return append (real, buffer, len);
1318d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1319d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1320d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1321d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Appends a single byte to the string, returning #FALSE
1322d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * if not enough memory.
1323d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1324d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
1325d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param byte the byte to append
1326d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #TRUE on success
1327d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1328d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1329d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_append_byte (DBusString    *str,
1330d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                          unsigned char  byte)
1331d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1332d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
1333d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1334d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!set_length (real, real->len + 1))
1335d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return FALSE;
1336d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1337d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->str[real->len-1] = byte;
1338d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1339d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
1340d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1341d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
13427bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
1343d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1344d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Appends a single Unicode character, encoding the character
1345d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * in UTF-8 format.
1346d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1347d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
1348d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param ch the Unicode character
1349d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1350d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1351d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_append_unichar (DBusString    *str,
1352d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                             dbus_unichar_t ch)
1353d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1354d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  int len;
1355d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  int first;
1356d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  int i;
13576606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  unsigned char *out;
1358d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1359d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
1360d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1361d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* this code is from GLib but is pretty standard I think */
1362d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1363d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  len = 0;
1364d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1365d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (ch < 0x80)
1366d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1367d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0;
1368d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 1;
1369d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1370d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if (ch < 0x800)
1371d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1372d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0xc0;
1373d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 2;
1374d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1375d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if (ch < 0x10000)
1376d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1377d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0xe0;
1378d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 3;
1379d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1380d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   else if (ch < 0x200000)
1381d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1382d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0xf0;
1383d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 4;
1384d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1385d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if (ch < 0x4000000)
1386d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1387d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0xf8;
1388d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 5;
1389d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1390d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else
1391d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1392d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0xfc;
1393d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 6;
1394d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1395d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1396b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (len > (real->max_length - real->len))
1397b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    return FALSE; /* real->len + len would overflow */
1398b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
1399d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!set_length (real, real->len + len))
1400d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return FALSE;
1401d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1402d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  out = real->str + (real->len - len);
1403d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1404d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  for (i = len - 1; i > 0; --i)
1405d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1406d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      out[i] = (ch & 0x3f) | 0x80;
1407d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      ch >>= 6;
1408d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1409d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  out[0] = ch | first;
1410d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1411d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
1412d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
14137bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
1414d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1415d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonstatic void
1416d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondelete (DBusRealString *real,
1417d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        int             start,
1418d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        int             len)
1419d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1420d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (len == 0)
1421d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return;
1422d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1423d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  memmove (real->str + start, real->str + start + len, real->len - (start + len));
1424d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->len -= len;
1425d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->str[real->len] = '\0';
1426d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1427d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1428d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1429d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Deletes a segment of a DBusString with length len starting at
1430d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * start. (Hint: to clear an entire string, setting length to 0
1431d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * with _dbus_string_set_length() is easier.)
1432d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1433d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the DBusString
1434d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start where to start deleting
1435d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len the number of bytes to delete
1436d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1437d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
1438d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_delete (DBusString       *str,
1439d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                     int               start,
1440d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                     int               len)
1441d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1442d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
1443d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (start >= 0);
1444d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
1445b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
1446b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real->len - start);
144750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
1448d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  delete (real, start, len);
1449d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1450d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1451d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonstatic dbus_bool_t
14522297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtoncopy (DBusRealString *source,
14532297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      int             start,
14542297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      int             len,
14552297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      DBusRealString *dest,
14562297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      int             insert_at)
14572297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
145850c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (len == 0)
145950c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return TRUE;
146050c25505f62786756519ef1e194883360eda82e0Havoc Pennington
14612297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!open_gap (len, dest, insert_at))
14622297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    return FALSE;
146350c25505f62786756519ef1e194883360eda82e0Havoc Pennington
14646606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington  memmove (dest->str + insert_at,
14656606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington           source->str + start,
14666606169cbcf17dd06dfa7f9e25d9c1c33b0bf080Havoc Pennington           len);
1467d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1468d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
1469d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1470d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1471d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1472d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Checks assertions for two strings we're copying a segment between,
1473d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * and declares real_source/real_dest variables.
1474d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1475d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param source the source string
1476d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start the starting offset
1477d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param dest the dest string
1478d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param insert_at where the copied segment is inserted
1479d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1480d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at)       \
1481d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusRealString *real_source = (DBusRealString*) source;               \
1482d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusRealString *real_dest = (DBusRealString*) dest;                   \
1483d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((source) != (dest));                                    \
1484d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_source);                           \
1485d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_dest);                             \
1486d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (!real_dest->constant);                                  \
1487d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (!real_dest->locked);                                    \
1488d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((start) >= 0);                                          \
1489d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((start) <= real_source->len);                           \
1490d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((insert_at) >= 0);                                      \
1491d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((insert_at) <= real_dest->len)
1492d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1493d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1494d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Moves the end of one string into another string. Both strings
1495d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * must be initialized, valid strings.
1496d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1497d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param source the source string
1498d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start where to chop off the source string
1499d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param dest the destination string
1500d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param insert_at where to move the chopped-off part of source string
1501d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory
1502d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1503d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1504d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_move (DBusString       *source,
1505d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   int               start,
1506d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   DBusString       *dest,
1507d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   int               insert_at)
1508d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1509d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  DBusRealString *real_source = (DBusRealString*) source;
1510d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  _dbus_assert (start <= real_source->len);
1511d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1512d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  return _dbus_string_move_len (source, start,
1513d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                                real_source->len - start,
1514d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                                dest, insert_at);
1515d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1516d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1517d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1518d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Like _dbus_string_move(), but does not delete the section
1519d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * of the source string that's copied to the dest string.
1520d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1521d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param source the source string
1522d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start where to start copying the source string
1523d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param dest the destination string
1524d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param insert_at where to place the copied part of source string
1525d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory
1526d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1527d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1528d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_copy (const DBusString *source,
1529d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   int               start,
1530d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   DBusString       *dest,
1531d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   int               insert_at)
1532d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1533d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1534d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1535d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return copy (real_source, start,
1536d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington               real_source->len - start,
1537d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington               real_dest,
1538d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington               insert_at);
1539d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1540d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1541d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1542d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Like _dbus_string_move(), but can move a segment from
1543d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the middle of the source string.
1544d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington *
1545d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @todo this doesn't do anything with max_length field.
1546d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * we should probably just kill the max_length field though.
1547d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1548d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param source the source string
1549d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start first byte of source string to move
1550d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len length of segment to move
1551d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param dest the destination string
1552d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param insert_at where to move the bytes from the source string
1553d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory
1554d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1555d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1556d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_move_len (DBusString       *source,
1557d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               start,
1558d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               len,
1559d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       DBusString       *dest,
1560d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               insert_at)
1561d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1562d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1563d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1564d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
1565d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((start + len) <= real_source->len);
1566d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1567d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1568d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  if (len == 0)
1569d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    {
1570d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      return TRUE;
1571d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    }
1572d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  else if (start == 0 &&
1573d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington           len == real_source->len &&
1574d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington           real_dest->len == 0)
1575d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    {
1576d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      /* Short-circuit moving an entire existing string to an empty string
1577d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington       * by just swapping the buffers.
1578d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington       */
1579d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      /* we assume ->constant doesn't matter as you can't have
1580d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington       * a constant string involved in a move.
1581d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington       */
1582d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington#define ASSIGN_DATA(a, b) do {                  \
1583d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        (a)->str = (b)->str;                    \
1584d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        (a)->len = (b)->len;                    \
1585d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        (a)->allocated = (b)->allocated;        \
1586d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        (a)->align_offset = (b)->align_offset;  \
1587d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      } while (0)
1588d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1589d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      DBusRealString tmp;
1590d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1591d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      ASSIGN_DATA (&tmp, real_source);
1592d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      ASSIGN_DATA (real_source, real_dest);
1593d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      ASSIGN_DATA (real_dest, &tmp);
1594d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1595d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      return TRUE;
1596d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    }
1597d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  else
1598d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    {
1599d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      if (!copy (real_source, start, len,
1600d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                 real_dest,
1601d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                 insert_at))
1602d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        return FALSE;
1603d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1604d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      delete (real_source, start,
1605d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington              len);
1606d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1607d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      return TRUE;
1608d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    }
1609d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1610d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1611d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1612d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Like _dbus_string_copy(), but can copy a segment from the middle of
1613d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the source string.
1614d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1615d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param source the source string
1616d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start where to start copying the source string
1617d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len length of segment to copy
1618d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param dest the destination string
1619d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param insert_at where to place the copied segment of source string
1620d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory
1621d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1622d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1623d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_copy_len (const DBusString *source,
1624d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               start,
1625d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               len,
1626d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       DBusString       *dest,
1627d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               insert_at)
1628d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1629d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1630d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
1631b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real_source->len);
1632b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real_source->len - start);
1633d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1634d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return copy (real_source, start, len,
1635d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington               real_dest,
1636d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington               insert_at);
1637d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1638d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
163950c25505f62786756519ef1e194883360eda82e0Havoc Pennington/**
164050c25505f62786756519ef1e194883360eda82e0Havoc Pennington * Replaces a segment of dest string with a segment of source string.
164150c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
164250c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @todo optimize the case where the two lengths are the same, and
164350c25505f62786756519ef1e194883360eda82e0Havoc Pennington * avoid memmoving the data in the trailing part of the string twice.
1644b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
1645b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo avoid inserting the source into dest, then deleting
1646b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * the replaced chunk of dest (which creates a potentially large
1647b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * intermediate string). Instead, extend the replaced chunk
1648b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * of dest with padding to the same size as the source chunk,
1649b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * then copy in the source bytes.
165050c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
165150c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param source the source string
165250c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param start where to start copying the source string
165350c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param len length of segment to copy
165450c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param dest the destination string
165550c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param replace_at start of segment of dest string to replace
165650c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param replace_len length of segment of dest string to replace
165750c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @returns #FALSE if not enough memory
165850c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
165950c25505f62786756519ef1e194883360eda82e0Havoc Pennington */
166050c25505f62786756519ef1e194883360eda82e0Havoc Penningtondbus_bool_t
166150c25505f62786756519ef1e194883360eda82e0Havoc Pennington_dbus_string_replace_len (const DBusString *source,
166250c25505f62786756519ef1e194883360eda82e0Havoc Pennington                          int               start,
166350c25505f62786756519ef1e194883360eda82e0Havoc Pennington                          int               len,
166450c25505f62786756519ef1e194883360eda82e0Havoc Pennington                          DBusString       *dest,
166550c25505f62786756519ef1e194883360eda82e0Havoc Pennington                          int               replace_at,
166650c25505f62786756519ef1e194883360eda82e0Havoc Pennington                          int               replace_len)
166750c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
166850c25505f62786756519ef1e194883360eda82e0Havoc Pennington  DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
166950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (len >= 0);
1670b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real_source->len);
1671b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real_source->len - start);
167250c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (replace_at >= 0);
1673b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (replace_at <= real_dest->len);
1674b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (replace_len <= real_dest->len - replace_at);
167550c25505f62786756519ef1e194883360eda82e0Havoc Pennington
167650c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!copy (real_source, start, len,
167750c25505f62786756519ef1e194883360eda82e0Havoc Pennington             real_dest, replace_at))
167850c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return FALSE;
167950c25505f62786756519ef1e194883360eda82e0Havoc Pennington
168050c25505f62786756519ef1e194883360eda82e0Havoc Pennington  delete (real_dest, replace_at + len, replace_len);
168150c25505f62786756519ef1e194883360eda82e0Havoc Pennington
168250c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return TRUE;
168350c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
168450c25505f62786756519ef1e194883360eda82e0Havoc Pennington
16850e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode/**
16860e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode * Looks for the first occurance of a byte, deletes that byte,
16870e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode * and moves everything after the byte to the beginning of a
16880e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode * separate string.  Both strings must be initialized, valid
16890e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode * strings.
16900e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode *
16910e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode * @param source the source string
16920e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode * @param byte the byte to remove and split the string at
16930e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode * @param tail the split off string
16940e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode * @returns #FALSE if not enough memory or if byte could not be found
16950e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode *
16960e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode */
16970e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strodedbus_bool_t
16980e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode_dbus_string_split_on_byte (DBusString        *source,
16990e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode                            unsigned char      byte,
17000e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode                            DBusString        *tail)
17010e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode{
17020e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  int byte_position;
17030e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  char byte_string[2] = "";
17040e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  int head_length;
17050e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  int tail_length;
17060e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode
17070e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  byte_string[0] = (char) byte;
17080e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode
17090e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  if (!_dbus_string_find (source, 0, byte_string, &byte_position))
17100e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode    return FALSE;
17110e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode
17120e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  head_length = byte_position;
17130e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  tail_length = _dbus_string_get_length (source) - head_length - 1;
17140e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode
17150e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  if (!_dbus_string_move_len (source, byte_position + 1, tail_length,
17160e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode                              tail, 0))
17170e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode    return FALSE;
17180e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode
17190e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  /* remove the trailing delimiter byte from the head now.
17200e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode   */
17210e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  if (!_dbus_string_set_length (source, head_length))
17220e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode    return FALSE;
17230e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode
17240e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode  return TRUE;
17250e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode}
17260e3ec9cec0f6740acd39d6e6983f419e20461282Ray Strode
1727021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington/* Unicode macros and utf8_validate() from GLib Owen Taylor, Havoc
1728021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington * Pennington, and Tom Tromey are the authors and authorized relicense.
1729021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington */
1730d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1731d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/** computes length and mask of a unicode character
1732d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Char the char
1733d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Mask the mask variable to assign to
1734d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Len the length variable to assign to
1735d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1736d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define UTF8_COMPUTE(Char, Mask, Len)					      \
1737d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (Char < 128)							      \
1738d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1739d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 1;								      \
1740d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x7f;							      \
1741d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
1742d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if ((Char & 0xe0) == 0xc0)					      \
1743d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1744d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 2;								      \
1745d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x1f;							      \
1746d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
1747d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if ((Char & 0xf0) == 0xe0)					      \
1748d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1749d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 3;								      \
1750d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x0f;							      \
1751d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
1752d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if ((Char & 0xf8) == 0xf0)					      \
1753d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1754d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 4;								      \
1755d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x07;							      \
1756d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
1757d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if ((Char & 0xfc) == 0xf8)					      \
1758d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1759d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 5;								      \
1760d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x03;							      \
1761d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
1762d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if ((Char & 0xfe) == 0xfc)					      \
1763d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1764d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 6;								      \
1765d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x01;							      \
1766d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
17671b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington  else                                                                        \
17681b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington    {                                                                         \
17691b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      Len = 0;                                                               \
17701b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      Mask = 0;                                                               \
17711b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington    }
1772d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1773d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1774d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * computes length of a unicode character in UTF-8
1775d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Char the char
1776d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1777d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define UTF8_LENGTH(Char)              \
1778d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  ((Char) < 0x80 ? 1 :                 \
1779d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   ((Char) < 0x800 ? 2 :               \
1780d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    ((Char) < 0x10000 ? 3 :            \
1781d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington     ((Char) < 0x200000 ? 4 :          \
1782d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      ((Char) < 0x4000000 ? 5 : 6)))))
1783d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1784d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1785d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Gets a UTF-8 value.
1786d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1787d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Result variable for extracted unicode char.
1788d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Chars the bytes to decode
1789d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Count counter variable
1790d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Mask mask for this char
1791d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Len length for this char in bytes
1792d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1793d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define UTF8_GET(Result, Chars, Count, Mask, Len)			      \
1794d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  (Result) = (Chars)[0] & (Mask);					      \
1795d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  for ((Count) = 1; (Count) < (Len); ++(Count))				      \
1796d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1797d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      if (((Chars)[(Count)] & 0xc0) != 0x80)				      \
1798d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington	{								      \
1799d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington	  (Result) = -1;						      \
1800d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington	  break;							      \
1801d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington	}								      \
1802d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      (Result) <<= 6;							      \
1803d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      (Result) |= ((Chars)[(Count)] & 0x3f);				      \
1804d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1805d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1806d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1807fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters * Check whether a Unicode (5.2) char is in a valid range.
1808fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters *
1809fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters * The first check comes from the Unicode guarantee to never encode
1810fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters * a point above 0x0010ffff, since UTF-16 couldn't represent it.
1811fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters *
1812fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters * The second check covers surrogate pairs (category Cs).
1813fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters *
1814fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters * The last two checks cover "Noncharacter": defined as:
1815fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters *   "A code point that is permanently reserved for
1816fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters *    internal use, and that should never be interchanged. In
1817fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters *    Unicode 3.1, these consist of the values U+nFFFE and U+nFFFF
1818fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters *    (where n is from 0 to 10_16) and the values U+FDD0..U+FDEF."
1819d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1820d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Char the character
1821d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1822d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define UNICODE_VALID(Char)                   \
1823d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    ((Char) < 0x110000 &&                     \
1824bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington     (((Char) & 0xFFFFF800) != 0xD800) &&     \
1825bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington     ((Char) < 0xFDD0 || (Char) > 0xFDEF) &&  \
1826fbeb13517ef667b8ed4136bcb9e52ff9924419c1Colin Walters     ((Char) & 0xFFFE) != 0xFFFE)
1827d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
18287bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
1829d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1830d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Gets a unicode character from a UTF-8 string. Does no validation;
1831d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * you must verify that the string is valid UTF-8 in advance and must
1832d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * pass in the start of a character.
1833d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1834d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
1835d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start the start of the UTF-8 character.
1836d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param ch_return location to return the character
1837d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param end_return location to return the byte index of next character
1838d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1839d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
1840d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_get_unichar (const DBusString *str,
1841d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                          int               start,
1842d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                          dbus_unichar_t   *ch_return,
1843d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                          int              *end_return)
1844d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1845d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  int i, mask, len;
1846d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  dbus_unichar_t result;
1847d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  unsigned char c;
1848d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  unsigned char *p;
1849d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
1850b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start >= 0);
1851b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
1852b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
1853d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (ch_return)
1854d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    *ch_return = 0;
1855d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (end_return)
1856d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    *end_return = real->len;
1857d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1858d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  mask = 0;
1859d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  p = real->str + start;
1860d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  c = *p;
1861d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1862d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  UTF8_COMPUTE (c, mask, len);
18631b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington  if (len == 0)
1864d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return;
1865d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  UTF8_GET (result, p, i, mask, len);
1866d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1867d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (result == (dbus_unichar_t)-1)
1868d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return;
1869d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1870d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (ch_return)
1871d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    *ch_return = result;
1872d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (end_return)
1873d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    *end_return = start + len;
1874d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
18757bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
1876d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
18772297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
18782297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Finds the given substring in the string,
18792297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * returning #TRUE and filling in the byte index
18802297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * where the substring was found, if it was found.
18812297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Returns #FALSE if the substring wasn't found.
18822297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Sets *start to the length of the string if the substring
18832297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * is not found.
18842297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
18852297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param str the string
18862297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param start where to start looking
18872297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param substr the substring
18882297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param found return location for where it was found, or #NULL
18892297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @returns #TRUE if found
18902297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
18912297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtondbus_bool_t
18922297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_find (const DBusString *str,
18932297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                   int               start,
18942297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                   const char       *substr,
18952297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                   int              *found)
18962297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
1897b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  return _dbus_string_find_to (str, start,
1898b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington                               ((const DBusRealString*)str)->len,
1899b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington                               substr, found);
19002297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
19012297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
19022297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
1903cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * Finds end of line ("\r\n" or "\n") in the string,
1904cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * returning #TRUE and filling in the byte index
1905cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * where the eol string was found, if it was found.
1906cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * Returns #FALSE if eol wasn't found.
1907cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker *
1908cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * @param str the string
1909cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * @param start where to start looking
1910cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * @param found return location for where eol was found or string length otherwise
1911cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * @param found_len return length of found eol string or zero otherwise
1912cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker * @returns #TRUE if found
1913cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker */
1914cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habackerdbus_bool_t
1915cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker_dbus_string_find_eol (const DBusString *str,
1916a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington                       int               start,
1917a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington                       int              *found,
1918a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington                       int              *found_len)
1919cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker{
1920cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  int i;
1921cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker
1922cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  DBUS_CONST_STRING_PREAMBLE (str);
1923cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  _dbus_assert (start <= real->len);
1924cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  _dbus_assert (start >= 0);
1925cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker
1926cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  i = start;
1927cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  while (i < real->len)
1928cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker    {
1929cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker      if (real->str[i] == '\r')
1930cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker        {
1931cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker          if ((i+1) < real->len && real->str[i+1] == '\n') /* "\r\n" */
1932cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker            {
1933cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker              if (found)
1934cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker                *found = i;
1935cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker              if (found_len)
1936cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker                *found_len = 2;
1937cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker              return TRUE;
1938cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker            }
1939cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker          else /* only "\r" */
1940cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker            {
1941cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker              if (found)
1942cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker                *found = i;
1943cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker              if (found_len)
1944cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker                *found_len = 1;
1945cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker              return TRUE;
1946cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker            }
1947cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker        }
1948cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker      else if (real->str[i] == '\n')  /* only "\n" */
1949cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker        {
1950cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker          if (found)
1951cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker            *found = i;
1952cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker          if (found_len)
1953cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker            *found_len = 1;
1954cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker          return TRUE;
1955a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington        }
1956cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker      ++i;
1957cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker    }
1958cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker
1959cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  if (found)
1960cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker    *found = real->len;
1961cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker
1962cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  if (found_len)
1963cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker    *found_len = 0;
1964cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker
1965cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker  return FALSE;
1966cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker}
1967cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker
1968cb39e60e1639fb982a46aa1625e3adec2bf0df46Ralf Habacker/**
19695ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * Finds the given substring in the string,
19705ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * up to a certain position,
19715ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * returning #TRUE and filling in the byte index
19725ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * where the substring was found, if it was found.
19735ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * Returns #FALSE if the substring wasn't found.
19745ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * Sets *start to the length of the string if the substring
19755ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * is not found.
19765ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson *
19775ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @param str the string
19785ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @param start where to start looking
19795ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @param end where to stop looking
19805ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @param substr the substring
19815ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @param found return location for where it was found, or #NULL
19825ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @returns #TRUE if found
19835ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson */
19845ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlssondbus_bool_t
19855ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson_dbus_string_find_to (const DBusString *str,
19865ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson		      int               start,
19875ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson		      int               end,
19885ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson		      const char       *substr,
19895ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson		      int              *found)
19905ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson{
19915ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  int i;
19925ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  DBUS_CONST_STRING_PREAMBLE (str);
19935ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  _dbus_assert (substr != NULL);
19945ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  _dbus_assert (start <= real->len);
1995b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start >= 0);
1996b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (substr != NULL);
19975ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  _dbus_assert (end <= real->len);
1998b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= end);
19995ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
20005ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  /* we always "find" an empty string */
20015ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  if (*substr == '\0')
20025ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    {
20035ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson      if (found)
2004b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington        *found = start;
20055ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson      return TRUE;
20065ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    }
20075ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
20085ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  i = start;
2009b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  while (i < end)
20105ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    {
20115ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson      if (real->str[i] == substr[0])
20125ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson        {
20135ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson          int j = i + 1;
20145ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
2015b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington          while (j < end)
20165ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson            {
20175ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson              if (substr[j - i] == '\0')
20185ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson                break;
20195ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson              else if (real->str[j] != substr[j - i])
20205ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson                break;
20215ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
20225ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson              ++j;
20235ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson            }
20245ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
20255ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson          if (substr[j - i] == '\0')
20265ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson            {
20275ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson              if (found)
20285ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson                *found = i;
20295ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson              return TRUE;
20305ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson            }
20315ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson        }
20325ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
20335ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson      ++i;
20345ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    }
20355ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
20365ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  if (found)
20375ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    *found = end;
20385ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
20395ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  return FALSE;
20405ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson}
20415ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
20425ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson/**
20432297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Finds a blank (space or tab) in the string. Returns #TRUE
20442297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * if found, #FALSE otherwise. If a blank is not found sets
20452297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * *found to the length of the string.
20462297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
20472297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param str the string
20482297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param start byte index to start looking
20492297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param found place to store the location of the first blank
20502297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @returns #TRUE if a blank was found
20512297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
20522297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtondbus_bool_t
20532297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_find_blank (const DBusString *str,
20542297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                         int               start,
20552297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                         int              *found)
20562297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
20572297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  int i;
20582297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
20592297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert (start <= real->len);
2060b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start >= 0);
20612297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
20622297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  i = start;
20632297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  while (i < real->len)
20642297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
20652297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      if (real->str[i] == ' ' ||
20662297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington          real->str[i] == '\t')
20672297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        {
20682297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington          if (found)
20692297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington            *found = i;
20702297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington          return TRUE;
20712297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        }
20722297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
20732297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++i;
20742297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
20752297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
20762297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (found)
20772297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    *found = real->len;
20782297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
20792297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  return FALSE;
20802297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
20812297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
20822297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
20832297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Skips blanks from start, storing the first non-blank in *end
2084bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * (blank is space or tab).
20852297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
20862297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param str the string
20872297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param start where to start
20882297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param end where to store the first non-blank byte index
20892297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
20902297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtonvoid
20912297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_skip_blank (const DBusString *str,
20922297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                         int               start,
20932297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                         int              *end)
20942297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
20952297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  int i;
20962297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
20972297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert (start <= real->len);
2098b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start >= 0);
20992297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
21002297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  i = start;
21012297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  while (i < real->len)
21022297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
2103d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington      if (!DBUS_IS_ASCII_BLANK (real->str[i]))
21042297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        break;
21052297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
21062297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++i;
21072297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
21082297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
2109d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_assert (i == real->len || !DBUS_IS_ASCII_WHITE (real->str[i]));
2110ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
21112297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (end)
21122297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    *end = i;
21132297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
21142297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
2115d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2116d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington/**
2117d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * Skips whitespace from start, storing the first non-whitespace in *end.
2118d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * (whitespace is space, tab, newline, CR).
2119d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington *
2120d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * @param str the string
2121d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * @param start where to start
2122d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * @param end where to store the first non-whitespace byte index
2123d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington */
2124d8155bf51bf6484a94e734601526bf211053a5e1Havoc Penningtonvoid
2125d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington_dbus_string_skip_white (const DBusString *str,
2126d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington                         int               start,
2127d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington                         int              *end)
2128d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington{
2129d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  int i;
2130d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
2131d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_assert (start <= real->len);
2132d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_assert (start >= 0);
2133d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2134d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  i = start;
2135d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  while (i < real->len)
2136d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington    {
2137d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington      if (!DBUS_IS_ASCII_WHITE (real->str[i]))
2138d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington        break;
2139d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2140d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington      ++i;
2141d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington    }
2142d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2143d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_assert (i == real->len || !(DBUS_IS_ASCII_WHITE (real->str[i])));
2144d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2145d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  if (end)
2146d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington    *end = i;
2147d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington}
2148d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2149d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington/**
2150d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * Skips whitespace from end, storing the start index of the trailing
2151d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * whitespace in *start. (whitespace is space, tab, newline, CR).
2152d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington *
2153d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * @param str the string
2154d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * @param end where to start scanning backward
2155d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * @param start where to store the start of whitespace chars
2156d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington */
2157d8155bf51bf6484a94e734601526bf211053a5e1Havoc Penningtonvoid
2158d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington_dbus_string_skip_white_reverse (const DBusString *str,
2159d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington                                 int               end,
2160d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington                                 int              *start)
2161d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington{
2162d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  int i;
2163d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
2164d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_assert (end <= real->len);
2165d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_assert (end >= 0);
2166d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2167d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  i = end;
2168d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  while (i > 0)
2169d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington    {
2170d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington      if (!DBUS_IS_ASCII_WHITE (real->str[i-1]))
2171d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington        break;
2172d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington      --i;
2173d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington    }
2174d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2175d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_assert (i >= 0 && (i == 0 || !(DBUS_IS_ASCII_WHITE (real->str[i-1]))));
2176d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2177d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  if (start)
2178d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington    *start = i;
2179d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington}
2180d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
21812297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
218285ab0327d82e4945ad16630e583d8cc68df25a90Havoc Pennington * Assigns a newline-terminated or \\r\\n-terminated line from the front
2183c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington * of the string to the given dest string. The dest string's previous
2184c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington * contents are deleted. If the source string contains no newline,
2185c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington * moves the entire source string to the dest string.
2186b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
2187b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo owen correctly notes that this is a stupid function (it was
2188b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * written purely for test code,
2189b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * e.g. dbus-message-builder.c). Probably should be enforced as test
219015ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington * code only with ifdef DBUS_BUILD_TESTS
21913791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington *
21923791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param source the source string
21933791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param dest the destination string (contents are replaced)
21943791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @returns #FALSE if no memory, or source has length 0
21953791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington */
21963791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Penningtondbus_bool_t
21973791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington_dbus_string_pop_line (DBusString *source,
21983791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington                       DBusString *dest)
21993791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington{
2200f2e17db66f2e07e165fc90bba030a9f1d430834bRalf Habacker  int eol, eol_len;
22013791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
22023791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  _dbus_string_set_length (dest, 0);
22033791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
22043791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  eol = 0;
2205a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington  eol_len = 0;
2206f2e17db66f2e07e165fc90bba030a9f1d430834bRalf Habacker  if (!_dbus_string_find_eol (source, 0, &eol, &eol_len))
2207a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington    {
2208a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington      _dbus_assert (eol == _dbus_string_get_length (source));
2209a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington      if (eol == 0)
2210a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington        {
2211a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington          /* If there's no newline and source has zero length, we're done */
2212a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington          return FALSE;
2213a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington        }
2214a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington      /* otherwise, the last line of the file has no eol characters */
2215a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington    }
22163791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
2217a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington  /* remember eol can be 0 if it's an empty line, but eol_len should not be zero also
2218a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington   * since find_eol returned TRUE
2219a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington   */
22203791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
2221f2e17db66f2e07e165fc90bba030a9f1d430834bRalf Habacker  if (!_dbus_string_move_len (source, 0, eol + eol_len, dest, 0))
2222a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington    return FALSE;
2223a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington
2224f2e17db66f2e07e165fc90bba030a9f1d430834bRalf Habacker  /* remove line ending */
2225a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington  if (!_dbus_string_set_length (dest, eol))
2226a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington    {
2227a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington      _dbus_assert_not_reached ("out of memory when shortening a string");
2228a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington      return FALSE;
2229a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington    }
2230a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington
2231a789b7b38cb4f4540a41444cbd64bf7ada2d60d2Havoc Pennington  return TRUE;
22323791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington}
22333791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
22347bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
22353791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington/**
22363791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * Deletes up to and including the first blank space
22373791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * in the string.
22383791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington *
22393791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param str the string
22403791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington */
22413791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Penningtonvoid
22423791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington_dbus_string_delete_first_word (DBusString *str)
22433791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington{
22443791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  int i;
22453791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
22463791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  if (_dbus_string_find_blank (str, 0, &i))
22473791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    _dbus_string_skip_blank (str, i, &i);
22483791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
22493791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  _dbus_string_delete (str, 0, i);
22503791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington}
22517bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif
22523791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
22537bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
22543791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington/**
22553791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * Deletes any leading blanks in the string
22563791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington *
22573791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param str the string
22583791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington */
22593791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Penningtonvoid
22603791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington_dbus_string_delete_leading_blanks (DBusString *str)
22613791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington{
22623791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  int i;
22633791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
22643791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  _dbus_string_skip_blank (str, 0, &i);
22653791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
22663791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  if (i > 0)
22673791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    _dbus_string_delete (str, 0, i);
22683791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington}
22697bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif
22703791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
22713791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington/**
2272d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * Deletes leading and trailing whitespace
2273d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington *
2274d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington * @param str the string
2275d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington */
2276d8155bf51bf6484a94e734601526bf211053a5e1Havoc Penningtonvoid
2277d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington_dbus_string_chop_white(DBusString *str)
2278d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington{
2279d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  int i;
2280d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2281d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_string_skip_white (str, 0, &i);
2282d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2283d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  if (i > 0)
2284d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington    _dbus_string_delete (str, 0, i);
2285d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2286d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_string_skip_white_reverse (str, _dbus_string_get_length (str), &i);
2287d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2288d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington  _dbus_string_set_length (str, i);
2289d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington}
2290d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington
2291d8155bf51bf6484a94e734601526bf211053a5e1Havoc Pennington/**
22922297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Tests two DBusString for equality.
22932297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
2294b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo memcmp is probably faster
2295b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
22962297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param a first string
22972297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param b second string
22982297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @returns #TRUE if equal
22992297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
23002297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtondbus_bool_t
23012297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_equal (const DBusString *a,
23022297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                    const DBusString *b)
23032297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
23042297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *ap;
23052297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *bp;
23062297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *a_end;
23072297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const DBusRealString *real_a = (const DBusRealString*) a;
23082297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const DBusRealString *real_b = (const DBusRealString*) b;
23092297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_a);
23102297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_b);
23112297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23122297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (real_a->len != real_b->len)
23132297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    return FALSE;
23142297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23152297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  ap = real_a->str;
23162297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  bp = real_b->str;
23172297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  a_end = real_a->str + real_a->len;
23182297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  while (ap != a_end)
23192297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
23202297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      if (*ap != *bp)
23212297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        return FALSE;
23222297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23232297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++ap;
23242297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++bp;
23252297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
23262297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23272297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  return TRUE;
23282297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
23292297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23302297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
23313791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * Tests two DBusString for equality up to the given length.
2332c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * The strings may be shorter than the given length.
23333791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington *
23343791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @todo write a unit test
23353791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington *
2336b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo memcmp is probably faster
2337b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
23383791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param a first string
23393791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param b second string
2340c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @param len the maximum length to look at
23413791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @returns #TRUE if equal for the given number of bytes
23423791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington */
23433791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Penningtondbus_bool_t
23443791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington_dbus_string_equal_len (const DBusString *a,
23453791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington                        const DBusString *b,
23463791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington                        int               len)
23473791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington{
23483791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  const unsigned char *ap;
23493791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  const unsigned char *bp;
23503791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  const unsigned char *a_end;
23513791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  const DBusRealString *real_a = (const DBusRealString*) a;
23523791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  const DBusRealString *real_b = (const DBusRealString*) b;
23533791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_a);
23543791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_b);
23553791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
23563791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  if (real_a->len != real_b->len &&
23573791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      (real_a->len < len || real_b->len < len))
23583791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    return FALSE;
23593791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
23603791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  ap = real_a->str;
23613791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  bp = real_b->str;
23623791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  a_end = real_a->str + MIN (real_a->len, len);
23633791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  while (ap != a_end)
23643791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    {
23653791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      if (*ap != *bp)
23663791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington        return FALSE;
23673791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
23683791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      ++ap;
23693791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      ++bp;
23703791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    }
23713791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
23723791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  return TRUE;
23733791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington}
23743791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
23753791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington/**
2376c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * Tests two sub-parts of two DBusString for equality.  The specified
2377c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * range of the first string must exist; the specified start position
2378c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * of the second string must exist.
2379c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington *
2380c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @todo write a unit test
2381c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington *
2382c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @todo memcmp is probably faster
2383c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington *
2384c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @param a first string
2385c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @param a_start where to start substring in first string
2386c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @param a_len length of substring in first string
2387c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @param b second string
2388c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @param b_start where to start substring in second string
2389c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington * @returns #TRUE if the two substrings are equal
2390c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington */
2391c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Penningtondbus_bool_t
2392c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington_dbus_string_equal_substring (const DBusString  *a,
2393c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington                              int                a_start,
2394c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington                              int                a_len,
2395c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington                              const DBusString  *b,
2396c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington                              int                b_start)
2397c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington{
2398c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  const unsigned char *ap;
2399c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  const unsigned char *bp;
2400c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  const unsigned char *a_end;
2401c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  const DBusRealString *real_a = (const DBusRealString*) a;
2402c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  const DBusRealString *real_b = (const DBusRealString*) b;
2403c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_a);
2404c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_b);
2405c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  _dbus_assert (a_start >= 0);
2406c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  _dbus_assert (a_len >= 0);
2407c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  _dbus_assert (a_start <= real_a->len);
2408c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  _dbus_assert (a_len <= real_a->len - a_start);
2409c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  _dbus_assert (b_start >= 0);
2410c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  _dbus_assert (b_start <= real_b->len);
2411c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington
2412c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  if (a_len > real_b->len - b_start)
2413c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington    return FALSE;
2414c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington
2415c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  ap = real_a->str + a_start;
2416c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  bp = real_b->str + b_start;
2417c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  a_end = ap + a_len;
2418c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  while (ap != a_end)
2419c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington    {
2420c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington      if (*ap != *bp)
2421c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington        return FALSE;
2422c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington
2423c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington      ++ap;
2424c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington      ++bp;
2425c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington    }
2426c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington
2427c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  _dbus_assert (bp <= (real_b->str + real_b->len));
2428c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington
2429c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington  return TRUE;
2430c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington}
2431c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington
2432c2a98e1103544277e8d36be53f8a24a32c2c6beaHavoc Pennington/**
24332297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Checks whether a string is equal to a C string.
24342297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
24352297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param a the string
24362297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param c_str the C string
24372297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @returns #TRUE if equal
24382297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
24392297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtondbus_bool_t
24402297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_equal_c_str (const DBusString *a,
24412297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                          const char       *c_str)
24422297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
24432297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *ap;
24442297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *bp;
24452297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *a_end;
24462297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const DBusRealString *real_a = (const DBusRealString*) a;
24472297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_a);
2448b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (c_str != NULL);
2449b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
24502297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  ap = real_a->str;
24512297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  bp = (const unsigned char*) c_str;
24522297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  a_end = real_a->str + real_a->len;
24532297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  while (ap != a_end && *bp)
24542297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
24552297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      if (*ap != *bp)
24562297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        return FALSE;
24572297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24582297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++ap;
24592297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++bp;
24602297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
24612297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
2462b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (ap != a_end || *bp)
24632297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    return FALSE;
24642297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24652297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  return TRUE;
24662297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
24672297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24687bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#ifdef DBUS_BUILD_TESTS
24692f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington/**
24702f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington * Checks whether a string starts with the given C string.
24712f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington *
24722f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington * @param a the string
24732f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington * @param c_str the C string
24742f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington * @returns #TRUE if string starts with it
24752f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington */
24762f440457d5fe45afb732820da64a147157e2e82dHavoc Penningtondbus_bool_t
24772f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington_dbus_string_starts_with_c_str (const DBusString *a,
24782f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington                                const char       *c_str)
24792f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington{
24802f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  const unsigned char *ap;
24812f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  const unsigned char *bp;
24822f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  const unsigned char *a_end;
24832f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  const DBusRealString *real_a = (const DBusRealString*) a;
24842f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_a);
2485b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (c_str != NULL);
2486b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
24872f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  ap = real_a->str;
24882f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  bp = (const unsigned char*) c_str;
24892f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  a_end = real_a->str + real_a->len;
24902f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  while (ap != a_end && *bp)
24912f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington    {
24922f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington      if (*ap != *bp)
24932f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington        return FALSE;
24942f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington
24952f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington      ++ap;
24962f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington      ++bp;
24972f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington    }
24982f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington
24992f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  if (*bp == '\0')
25002f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington    return TRUE;
25012f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  else
25022f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington    return FALSE;
25032f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington}
25047bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington#endif /* DBUS_BUILD_TESTS */
250505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
2506ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington/**
2507aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington * Appends a two-character hex digit to a string, where the hex digit
2508aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington * has the value of the given byte.
2509aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington *
2510aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington * @param str the string
2511aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington * @param byte the byte
2512aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington * @returns #FALSE if no memory
2513aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington */
2514aa4f823781185fb18187714798795d7e4b0c9b65Havoc Penningtondbus_bool_t
2515aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington_dbus_string_append_byte_as_hex (DBusString *str,
2516aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington                                 int         byte)
2517aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington{
2518aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington  const char hexdigits[16] = {
2519aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
2520aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington    'a', 'b', 'c', 'd', 'e', 'f'
2521aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington  };
2522aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington
2523aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington  if (!_dbus_string_append_byte (str,
2524aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington                                 hexdigits[(byte >> 4)]))
2525aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington    return FALSE;
2526aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington
2527aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington  if (!_dbus_string_append_byte (str,
2528aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington                                 hexdigits[(byte & 0x0f)]))
2529aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington    {
2530aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington      _dbus_string_set_length (str,
2531aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington                               _dbus_string_get_length (str) - 1);
2532aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington      return FALSE;
2533aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington    }
2534aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington
2535aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington  return TRUE;
2536aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington}
2537aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington
2538aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington/**
25392f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * Encodes a string in hex, the way MD5 and SHA-1 are usually
25402f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * encoded. (Each byte is two hex digits.)
25412f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington *
25422f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param source the string to encode
25432f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param start byte index to start encoding
25442f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param dest string where encoded data should be placed
25452f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param insert_at where to place encoded data
25462f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @returns #TRUE if encoding was successful, #FALSE if no memory etc.
25472f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington */
25482f38c959212d98e2194139daa9120fda37415b4fHavoc Penningtondbus_bool_t
25492f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington_dbus_string_hex_encode (const DBusString *source,
25502f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         int               start,
25512f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         DBusString       *dest,
25522f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         int               insert_at)
25532f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington{
25542f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  DBusString result;
25552f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  const unsigned char *p;
25562f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  const unsigned char *end;
25572f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  dbus_bool_t retval;
25582f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25592f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  _dbus_assert (start <= _dbus_string_get_length (source));
25602f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
2561fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&result))
25622f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    return FALSE;
25632f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25642f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  retval = FALSE;
25652f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
2566fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  p = (const unsigned char*) _dbus_string_get_const_data (source);
25672f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  end = p + _dbus_string_get_length (source);
25682f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  p += start;
25692f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25702f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  while (p != end)
25712f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    {
2572aa4f823781185fb18187714798795d7e4b0c9b65Havoc Pennington      if (!_dbus_string_append_byte_as_hex (&result, *p))
25732f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        goto out;
25742f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25752f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      ++p;
25762f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    }
25772f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25782f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  if (!_dbus_string_move (&result, 0, dest, insert_at))
25792f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    goto out;
25802f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25812f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  retval = TRUE;
25822f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25832f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington out:
25842f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  _dbus_string_free (&result);
25852f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  return retval;
25862f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington}
25872f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25882f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington/**
25892f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * Decodes a string from hex encoding.
25902f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington *
25912f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param source the string to decode
25922f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param start byte index to start decode
2593d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg * @param end_return return location of the end of the hex data, or #NULL
25942f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param dest string where decoded data should be placed
25952f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param insert_at where to place decoded data
2596d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg * @returns #TRUE if decoding was successful, #FALSE if no memory.
25972f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington */
25982f38c959212d98e2194139daa9120fda37415b4fHavoc Penningtondbus_bool_t
25992f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington_dbus_string_hex_decode (const DBusString *source,
26002f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         int               start,
2601d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg			 int              *end_return,
26022f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         DBusString       *dest,
26032f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         int               insert_at)
26042f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington{
26052f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  DBusString result;
26062f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  const unsigned char *p;
26072f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  const unsigned char *end;
26082f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  dbus_bool_t retval;
26092f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  dbus_bool_t high_bits;
26102f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26112f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  _dbus_assert (start <= _dbus_string_get_length (source));
26122f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
2613fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&result))
26142f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    return FALSE;
26152f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26162f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  retval = FALSE;
26172f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26182f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  high_bits = TRUE;
2619fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  p = (const unsigned char*) _dbus_string_get_const_data (source);
26202f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  end = p + _dbus_string_get_length (source);
26212f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  p += start;
26222f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26232f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  while (p != end)
26242f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    {
26252f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      unsigned int val;
26262f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26272f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      switch (*p)
26282f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        {
26292f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '0':
26302f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 0;
26312f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26322f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '1':
26332f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 1;
26342f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26352f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '2':
26362f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 2;
26372f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26382f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '3':
26392f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 3;
26402f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26412f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '4':
26422f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 4;
26432f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26442f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '5':
26452f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 5;
26462f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26472f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '6':
26482f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 6;
26492f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26502f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '7':
26512f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 7;
26522f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26532f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '8':
26542f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 8;
26552f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26562f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '9':
26572f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 9;
26582f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26592f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'a':
26602f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'A':
26612f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 10;
26622f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26632f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'b':
26642f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'B':
26652f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 11;
26662f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26672f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'c':
26682f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'C':
26692f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 12;
26702f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26712f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'd':
26722f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'D':
26732f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 13;
26742f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26752f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'e':
26762f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'E':
26772f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 14;
26782f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26792f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'f':
26802f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'F':
26812f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 15;
26822f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26832f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        default:
2684d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg          goto done;
26852f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        }
26862f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26872f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      if (high_bits)
26882f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        {
26892f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          if (!_dbus_string_append_byte (&result,
26902f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                                         val << 4))
2691d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg	    goto out;
26922f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        }
26932f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      else
26942f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        {
26952f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          int len;
26962f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          unsigned char b;
26972f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26982f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          len = _dbus_string_get_length (&result);
26992f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
27002f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          b = _dbus_string_get_byte (&result, len - 1);
27012f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
27022f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          b |= val;
27032f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
27042f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          _dbus_string_set_byte (&result, len - 1, b);
27052f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        }
27062f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
27072f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      high_bits = !high_bits;
27082f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
27092f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      ++p;
27102f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    }
27112f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
2712d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg done:
27132f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  if (!_dbus_string_move (&result, 0, dest, insert_at))
27142f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    goto out;
27152f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
2716d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg  if (end_return)
2717d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg    *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
2718d86fc4071ccb8590d922e3456c5c80c0f7bb9d6fKristian Høgsberg
27192f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  retval = TRUE;
27202f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
27212f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington out:
27222f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  _dbus_string_free (&result);
27232f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  return retval;
27242f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington}
27252f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
27262f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington/**
27272f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * Checks that the given range of the string is valid ASCII with no
2728b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * nul bytes. If the given range is not entirely contained in the
2729b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * string, returns #FALSE.
2730ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington *
2731b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo this is inconsistent with most of DBusString in that
2732dbdea921b5967ed25b24a9e5af5d6a3db54c5ec7Havoc Pennington * it allows a start,len range that extends past the string end.
2733b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
2734ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * @param str the string
2735ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * @param start first byte index to check
2736ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * @param len number of bytes to check
2737ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * @returns #TRUE if the byte range exists and is all valid ASCII
2738ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington */
2739ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Penningtondbus_bool_t
2740ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington_dbus_string_validate_ascii (const DBusString *str,
2741ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington                             int               start,
2742ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington                             int               len)
2743ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington{
2744ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  const unsigned char *s;
2745ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  const unsigned char *end;
2746ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
2747ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (start >= 0);
2748b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
2749ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (len >= 0);
2750ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
2751b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (len > real->len - start)
2752ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    return FALSE;
2753ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
2754ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  s = real->str + start;
2755ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  end = s + len;
2756ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  while (s != end)
2757ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    {
2758f3228b477df95ba247c90cc54189ce6d62059251Havoc Pennington      if (_DBUS_UNLIKELY (!_DBUS_ISASCII (*s)))
2759ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington        return FALSE;
2760ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
2761ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington      ++s;
2762ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    }
2763ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
2764ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  return TRUE;
2765ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington}
27662297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
27677ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington/**
2768a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker * Converts the given range of the string to lower case.
2769a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker *
2770a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker * @param str the string
2771a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker * @param start first byte index to convert
2772a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker * @param len number of bytes to convert
2773a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker */
2774a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habackervoid
2775a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker_dbus_string_tolower_ascii (const DBusString *str,
2776a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker                            int               start,
2777a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker                            int               len)
2778a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker{
2779a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  unsigned char *s;
2780a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  unsigned char *end;
2781a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  DBUS_STRING_PREAMBLE (str);
2782a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  _dbus_assert (start >= 0);
2783a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  _dbus_assert (start <= real->len);
2784a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  _dbus_assert (len >= 0);
2785a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  _dbus_assert (len <= real->len - start);
2786a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker
2787a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  s = real->str + start;
2788a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  end = s + len;
2789a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker
2790a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker  while (s != end)
2791a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker    {
2792a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker      if (*s >= 'A' && *s <= 'Z')
2793a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker          *s += 'a' - 'A';
2794a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker      ++s;
2795a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker    }
2796a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker}
2797a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker
2798a06c771d2b931f0e5ae600d22a3e07208f16b0a3Ralf Habacker/**
279947e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker * Converts the given range of the string to upper case.
280047e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker *
280147e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker * @param str the string
280247e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker * @param start first byte index to convert
280347e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker * @param len number of bytes to convert
280447e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker */
280547e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habackervoid
280647e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker_dbus_string_toupper_ascii (const DBusString *str,
280747e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker                            int               start,
280847e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker                            int               len)
280947e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker{
281047e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  unsigned char *s;
281147e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  unsigned char *end;
281247e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  DBUS_STRING_PREAMBLE (str);
281347e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  _dbus_assert (start >= 0);
281447e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  _dbus_assert (start <= real->len);
281547e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  _dbus_assert (len >= 0);
281647e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  _dbus_assert (len <= real->len - start);
281747e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker
281847e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  s = real->str + start;
281947e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  end = s + len;
282047e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker
282147e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker  while (s != end)
282247e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker    {
282347e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker      if (*s >= 'a' && *s <= 'z')
282447e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker          *s += 'A' - 'a';
282547e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker      ++s;
282647e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker    }
282747e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker}
282847e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker
282947e37899a3daf33ab799f674c2dc8ce869cdd5faRalf Habacker/**
2830b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * Checks that the given range of the string is valid UTF-8. If the
2831b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * given range is not entirely contained in the string, returns
2832b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * #FALSE. If the string contains any nul bytes in the given range,
2833021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington * returns #FALSE. If the start and start+len are not on character
2834021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington * boundaries, returns #FALSE.
2835b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
2836b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo this is inconsistent with most of DBusString in that
2837dbdea921b5967ed25b24a9e5af5d6a3db54c5ec7Havoc Pennington * it allows a start,len range that extends past the string end.
28387ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington *
28397ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param str the string
28407ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param start first byte index to check
28417ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param len number of bytes to check
28427ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @returns #TRUE if the byte range exists and is all valid UTF-8
28437ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington */
28447ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Penningtondbus_bool_t
28457ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington_dbus_string_validate_utf8  (const DBusString *str,
28467ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                             int               start,
28477ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                             int               len)
28487ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington{
2849021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  const unsigned char *p;
2850ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington  const unsigned char *end;
2851021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
2852021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  _dbus_assert (start >= 0);
2853021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  _dbus_assert (start <= real->len);
2854021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  _dbus_assert (len >= 0);
2855021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
285675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  /* we are doing _DBUS_UNLIKELY() here which might be
28577652304bff969afb3969603149bb385efe861fe8John (J   * dubious in a generic library like GLib, but in D-Bus
285875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   * we know we're validating messages and that it would
285975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   * only be evil/broken apps that would have invalid
286075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   * UTF-8. Also, this function seems to be a performance
286175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   * bottleneck in profiles.
286275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   */
286375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
286475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_DBUS_UNLIKELY (len > real->len - start))
2865021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington    return FALSE;
2866021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2867ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington  p = real->str + start;
2868ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington  end = p + len;
2869021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2870ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington  while (p < end)
2871021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington    {
28721b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      int i, mask, char_len;
2873021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington      dbus_unichar_t result;
28741b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington
287525c1f310aafc8b3d89ee19656a64244e6f108dbbHavoc Pennington      /* nul bytes considered invalid */
287625c1f310aafc8b3d89ee19656a64244e6f108dbbHavoc Pennington      if (*p == '\0')
28771b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington        break;
28781b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington
28791b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      /* Special-case ASCII; this makes us go a lot faster in
28807652304bff969afb3969603149bb385efe861fe8John (J       * D-Bus profiles where we are typically validating
28811b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington       * function names and such. We have to know that
28821b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington       * all following checks will pass for ASCII though,
288325c1f310aafc8b3d89ee19656a64244e6f108dbbHavoc Pennington       * comments follow ...
288425c1f310aafc8b3d89ee19656a64244e6f108dbbHavoc Pennington       */
288525c1f310aafc8b3d89ee19656a64244e6f108dbbHavoc Pennington      if (*p < 128)
28861b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington        {
28871b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington          ++p;
28881b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington          continue;
28891b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington        }
2890021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
289125c1f310aafc8b3d89ee19656a64244e6f108dbbHavoc Pennington      UTF8_COMPUTE (*p, mask, char_len);
2892e537e421ff4f092621fcd9f6b51526a017ad020cAnders Carlsson
28931b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      if (_DBUS_UNLIKELY (char_len == 0))  /* ASCII: char_len == 1 */
2894021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington        break;
2895021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2896ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington      /* check that the expected number of bytes exists in the remaining length */
28971b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      if (_DBUS_UNLIKELY ((end - p) < char_len)) /* ASCII: p < end and char_len == 1 */
2898021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington        break;
2899021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2900021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington      UTF8_GET (result, p, i, mask, char_len);
2901021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
29021b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      /* Check for overlong UTF-8 */
29031b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* ASCII: UTF8_LENGTH == 1 */
2904ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington        break;
29051b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington#if 0
29061b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      /* The UNICODE_VALID check below will catch this */
29071b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1)) /* ASCII: result = ascii value */
2908021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington        break;
29091b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington#endif
2910021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
29111b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      if (_DBUS_UNLIKELY (!UNICODE_VALID (result))) /* ASCII: always valid */
2912ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington        break;
29131b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington
29141b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      /* UNICODE_VALID should have caught it */
29151b1dfafc344ad7b60b8156a1bbdbfc1b364bfa98Havoc Pennington      _dbus_assert (result != (dbus_unichar_t)-1);
2916021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2917021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington      p += char_len;
2918021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington    }
2919021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2920021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  /* See that we covered the entire length if a length was
2921021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington   * passed in
2922021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington   */
292375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_DBUS_UNLIKELY (p != end))
2924021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington    return FALSE;
2925021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  else
2926021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington    return TRUE;
29277ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington}
29287ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
29297ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington/**
2930b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * Checks that the given range of the string is all nul bytes. If the
2931b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * given range is not entirely contained in the string, returns
2932b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * #FALSE.
2933b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
2934b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo this is inconsistent with most of DBusString in that
2935dbdea921b5967ed25b24a9e5af5d6a3db54c5ec7Havoc Pennington * it allows a start,len range that extends past the string end.
29367ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington *
29377ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param str the string
29387ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param start first byte index to check
29397ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param len number of bytes to check
29407ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @returns #TRUE if the byte range exists and is all nul bytes
29417ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington */
29427ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Penningtondbus_bool_t
29437ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington_dbus_string_validate_nul (const DBusString *str,
29447ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                           int               start,
29457ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                           int               len)
29467ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington{
29477ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  const unsigned char *s;
29487ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  const unsigned char *end;
29497ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
29507ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  _dbus_assert (start >= 0);
29517ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  _dbus_assert (len >= 0);
2952b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
29537ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
2954b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (len > real->len - start)
29557ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    return FALSE;
29567ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
29577ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  s = real->str + start;
29587ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  end = s + len;
29597ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  while (s != end)
29607ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    {
296175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (_DBUS_UNLIKELY (*s != '\0'))
29627ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington        return FALSE;
29637ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington      ++s;
29647ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    }
29657ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
29667ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  return TRUE;
29677ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington}
29687ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
296978e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington/**
297078e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington * Clears all allocated bytes in the string to zero.
297178e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington *
2972c21511c01ab56d75f3aa4643761e9fd096a7f8beHavoc Pennington * @param str the string
297378e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington */
297478e16e99e753175fa49e787eab256932eefaa03fHavoc Penningtonvoid
297578e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington_dbus_string_zero (DBusString *str)
297678e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington{
297778e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington  DBUS_STRING_PREAMBLE (str);
297878e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington
2979d3fb6f35716ff1d6f6644dea2043d539007811deHavoc Pennington  memset (real->str - real->align_offset, '\0', real->allocated);
298078e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington}
2981d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/** @} */
2982d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
29837bf62e31a3c820852271768fafc04ba95c31a19fHavoc Pennington/* tests are in dbus-string-util.c */
2984