dbus-string.c revision 75742242000e782719bc1656f0a7da72b059e88e
1d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/* -*- mode: C; c-file-style: "gnu" -*- */
2d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/* dbus-string.c String utility class (internal to D-BUS implementation)
3d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
4b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * Copyright (C) 2002, 2003 Red Hat, Inc.
5d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
6d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Licensed under the Academic Free License version 1.2
7d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
8d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * This program is free software; you can redistribute it and/or modify
9d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * it under the terms of the GNU General Public License as published by
10d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the Free Software Foundation; either version 2 of the License, or
11d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * (at your option) any later version.
12d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
13d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * This program is distributed in the hope that it will be useful,
14d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * but WITHOUT ANY WARRANTY; without even the implied warranty of
15d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * GNU General Public License for more details.
17d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
18d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * You should have received a copy of the GNU General Public License
19d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * along with this program; if not, write to the Free Software
20d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
22d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
23d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
24271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington#include "dbus-internals.h"
25d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#include "dbus-string.h"
26d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/* we allow a system header here, for speed/convenience */
27d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#include <string.h>
281d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington/* for vsnprintf */
291d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington#include <stdio.h>
3013f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington#include "dbus-marshal.h"
3113f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington#define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
3213f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington#include "dbus-string-private.h"
33b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington#include "dbus-protocol.h"
34d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
35d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
36d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @defgroup DBusString string class
37d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @ingroup  DBusInternals
38d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @brief DBusString data structure
39d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
40d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Types and functions related to DBusString. DBusString is intended
41d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * to be a string class that makes it hard to mess up security issues
42d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * (and just in general harder to write buggy code).  It should be
43d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * used (or extended and then used) rather than the libc stuff in
44d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * string.h.  The string class is a bit inconvenient at spots because
45d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * it handles out-of-memory failures and tries to be extra-robust.
46d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
47d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * A DBusString has a maximum length set at initialization time; this
48d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * can be used to ensure that a buffer doesn't get too big.  The
49d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * _dbus_string_lengthen() method checks for overflow, and for max
50d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * length being exceeded.
51d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
52d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Try to avoid conversion to a plain C string, i.e. add methods on
53d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the string object instead, only convert to C string when passing
54d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * things out to the public API. In particular, no sprintf, strcpy,
55d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * strcat, any of that should be used. The GString feature of
56d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * accepting negative numbers for "length of string" is also absent,
57d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * because it could keep us from detecting bogus huge lengths. i.e. if
58d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * we passed in some bogus huge length it would be taken to mean
59d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * "current length of string" instead of "broken crack"
60d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
61d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
62d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
63d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @defgroup DBusStringInternals DBusString implementation details
64d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @ingroup  DBusInternals
65d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @brief DBusString implementation details
66d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
67d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * The guts of DBusString.
68d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
69d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @{
70d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
71d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
72d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
73b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * We allocate 1 byte for nul termination, plus 7 bytes for possible
74b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * align_offset, so we always need 8 bytes on top of the string's
75b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * length to be in the allocated block.
76b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington */
77b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington#define ALLOCATION_PADDING 8
78b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
79b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington/**
80b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * This is the maximum max length (and thus also the maximum length)
81b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * of a DBusString
82b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington */
83b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington#define MAX_MAX_LENGTH (_DBUS_INT_MAX - ALLOCATION_PADDING)
84b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
85b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington/**
86d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Checks a bunch of assertions about a string object
87d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
88d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param real the DBusRealString
89d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
90b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington#define DBUS_GENERIC_STRING_PREAMBLE(real) _dbus_assert ((real) != NULL); _dbus_assert (!(real)->invalid); _dbus_assert ((real)->len >= 0); _dbus_assert ((real)->allocated >= 0); _dbus_assert ((real)->max_length >= 0); _dbus_assert ((real)->len <= ((real)->allocated - ALLOCATION_PADDING)); _dbus_assert ((real)->len <= (real)->max_length)
91d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
92d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
93d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Checks assertions about a string object that needs to be
94d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * modifiable - may not be locked or const. Also declares
95d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the "real" variable pointing to DBusRealString.
96d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
97d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
98d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define DBUS_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \
99d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real);                                          \
100d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (!(real)->constant);                                             \
101d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (!(real)->locked)
102d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
103d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
104d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Checks assertions about a string object that may be locked but
105d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * can't be const. i.e. a string object that we can free.  Also
106d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * declares the "real" variable pointing to DBusRealString.
107d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
108d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
109d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
110d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define DBUS_LOCKED_STRING_PREAMBLE(str) DBusRealString *real = (DBusRealString*) str; \
111d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real);                                                 \
112d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (!(real)->constant)
113d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
114d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
115d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Checks assertions about a string that may be const or locked.  Also
116d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * declares the "real" variable pointing to DBusRealString.
117d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string.
118d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
119d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define DBUS_CONST_STRING_PREAMBLE(str) const DBusRealString *real = (DBusRealString*) str; \
120d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real)
121d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
122d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/** @} */
123d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
124d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
125d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @addtogroup DBusString
126d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @{
127d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
128d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
129b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Penningtonstatic void
130b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Penningtonfixup_alignment (DBusRealString *real)
131b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington{
132b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  char *aligned;
133b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  char *real_block;
134b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  unsigned int old_align_offset;
135b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
136b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  /* we have to have extra space in real->allocated for the align offset and nul byte */
137b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (real->len <= real->allocated - ALLOCATION_PADDING);
138b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
139b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  old_align_offset = real->align_offset;
140b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  real_block = real->str - old_align_offset;
141b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
142b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  aligned = _DBUS_ALIGN_ADDRESS (real_block, 8);
143b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
144b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  real->align_offset = aligned - real_block;
145b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  real->str = aligned;
146b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
147b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (old_align_offset != real->align_offset)
148b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    {
149b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington      /* Here comes the suck */
150b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington      memmove (real_block + real->align_offset,
151b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington               real_block + old_align_offset,
152b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington               real->len + 1);
153b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    }
154b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
155b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (real->align_offset < 8);
156b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (_DBUS_ALIGN_ADDRESS (real->str, 8) == real->str);
157b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington}
158650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington
15913f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Penningtonstatic void
16013f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Penningtonundo_alignment (DBusRealString *real)
16113f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington{
16213f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington  if (real->align_offset != 0)
16313f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington    {
16413f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington      memmove (real->str - real->align_offset,
16513f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington               real->str,
16613f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington               real->len + 1);
16713f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington
16813f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington      real->str = real->str - real->align_offset;
169ce173b29fc1e9432cb5956952afdbe775da12415Havoc Pennington      real->align_offset = 0;
17013f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington    }
17113f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington}
17213f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington
173d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
174d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * Initializes a string that can be up to the given allocation size
175d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * before it has to realloc. The string starts life with zero length.
176d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * The string must eventually be freed with _dbus_string_free().
1771d2478ae4f2da8869eab94ca455a1329230c179eHavoc Pennington *
178d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str memory to hold the string
179d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param allocate_size amount to preallocate
180fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * @returns #TRUE on success, #FALSE if no memory
181fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington */
182d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
183d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington_dbus_string_init_preallocated (DBusString *str,
184d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                                int         allocate_size)
185d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
186d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusRealString *real;
187d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
188d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (str != NULL);
189d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
190d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (sizeof (DBusString) == sizeof (DBusRealString));
191d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
192d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real = (DBusRealString*) str;
193d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
194d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* It's very important not to touch anything
195d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   * other than real->str if we're going to fail,
196d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   * since we also use this function to reset
197d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   * an existing string, e.g. in _dbus_string_steal_data()
198d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   */
199d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
200d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  real->str = dbus_malloc (ALLOCATION_PADDING + allocate_size);
201d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (real->str == NULL)
202650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington    return FALSE;
203650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington
204d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  real->allocated = ALLOCATION_PADDING + allocate_size;
205d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->len = 0;
206d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->str[real->len] = '\0';
207d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
208fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  real->max_length = MAX_MAX_LENGTH;
209d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->constant = FALSE;
210d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->locked = FALSE;
211d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->invalid = FALSE;
212b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  real->align_offset = 0;
213b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
214b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  fixup_alignment (real);
215650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington
216d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
217d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
218d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
219d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington/**
220d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * Initializes a string. The string starts life with zero length.  The
221d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * string must eventually be freed with _dbus_string_free().
222d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington *
223d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param str memory to hold the string
224d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @returns #TRUE on success, #FALSE if no memory
225d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington */
226d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtondbus_bool_t
227d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington_dbus_string_init (DBusString *str)
228d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington{
229d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  return _dbus_string_init_preallocated (str, 0);
230d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington}
231d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
232fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington/* The max length thing is sort of a historical artifact
233fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * from a feature that turned out to be dumb; perhaps
234fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * we should purge it entirely. The problem with
235fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * the feature is that it looks like memory allocation
236fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * failure, but is not a transient or resolvable failure.
237fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington */
238fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonstatic void
239fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonset_max_length (DBusString *str,
240fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington                int         max_length)
241fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington{
242fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  DBusRealString *real;
243fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
244fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  real = (DBusRealString*) str;
245fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
246fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  real->max_length = max_length;
247fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington}
248fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
249d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
250d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Initializes a constant string. The value parameter is not copied
251d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * (should be static), and the string may never be modified.
252d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * It is safe but not necessary to call _dbus_string_free()
253b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * on a const string. The string has a length limit of MAXINT - 8.
254d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
255d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str memory to use for the string
256d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param value a string to be stored in str (not copied!!!)
257d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
258d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
259d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_init_const (DBusString *str,
260d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                         const char *value)
261d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
262b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (value != NULL);
263b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
26450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_string_init_const_len (str, value,
26550c25505f62786756519ef1e194883360eda82e0Havoc Pennington                               strlen (value));
26650c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
26750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
26850c25505f62786756519ef1e194883360eda82e0Havoc Pennington/**
26950c25505f62786756519ef1e194883360eda82e0Havoc Pennington * Initializes a constant string with a length. The value parameter is
27050c25505f62786756519ef1e194883360eda82e0Havoc Pennington * not copied (should be static), and the string may never be
27150c25505f62786756519ef1e194883360eda82e0Havoc Pennington * modified.  It is safe but not necessary to call _dbus_string_free()
27250c25505f62786756519ef1e194883360eda82e0Havoc Pennington * on a const string.
27350c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
27450c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param str memory to use for the string
27550c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param value a string to be stored in str (not copied!!!)
27650c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param len the length to use
27750c25505f62786756519ef1e194883360eda82e0Havoc Pennington */
27850c25505f62786756519ef1e194883360eda82e0Havoc Penningtonvoid
27950c25505f62786756519ef1e194883360eda82e0Havoc Pennington_dbus_string_init_const_len (DBusString *str,
28050c25505f62786756519ef1e194883360eda82e0Havoc Pennington                             const char *value,
28150c25505f62786756519ef1e194883360eda82e0Havoc Pennington                             int         len)
28250c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
283d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusRealString *real;
284d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
285d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (str != NULL);
286d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (value != NULL);
287b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= MAX_MAX_LENGTH);
288b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len >= 0);
289b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
290d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real = (DBusRealString*) str;
291d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
292d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->str = (char*) value;
29350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  real->len = len;
294b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  real->allocated = real->len + ALLOCATION_PADDING; /* a lie, just to avoid special-case assertions... */
295b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  real->max_length = real->len + 1;
296d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->constant = TRUE;
297d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->invalid = FALSE;
298650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington
299650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington  /* We don't require const strings to be 8-byte aligned as the
300650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington   * memory is coming from elsewhere.
301650c2745b8e1065b957779e26413a5040fd97f30Havoc Pennington   */
302d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
303d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
304d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
305d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Frees a string created by _dbus_string_init().
306d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
307d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str memory where the string is stored.
308d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
309d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
310d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_free (DBusString *str)
311d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
31205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  DBusRealString *real = (DBusRealString*) str;
31305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real);
314d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
315d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (real->constant)
316d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return;
31713f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington  dbus_free (real->str - real->align_offset);
318d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
319d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->invalid = TRUE;
320d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
321d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
322d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington#ifdef DBUS_BUILD_TESTS
323d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington/* Not using this feature at the moment,
324d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington * so marked DBUS_BUILD_TESTS-only
325d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington */
326d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
327b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * Locks a string such that any attempts to change the string will
328b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * result in aborting the program. Also, if the string is wasting a
329b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * lot of memory (allocation is sufficiently larger than what the
330b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * string is really using), _dbus_string_lock() will realloc the
331b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * string's data to "compact" it.
332d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
333d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string to lock.
334d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
335d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
336d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_lock (DBusString *str)
337d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
338d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_LOCKED_STRING_PREAMBLE (str); /* can lock multiple times */
339d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
340d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->locked = TRUE;
341d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
342d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* Try to realloc to avoid excess memory usage, since
343d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   * we know we won't change the string further
344d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   */
345b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington#define MAX_WASTE 48
346b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (real->allocated - MAX_WASTE > real->len)
347d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
348d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      char *new_str;
349d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      int new_allocated;
350d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
351b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington      new_allocated = real->len + ALLOCATION_PADDING;
352d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
353b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington      new_str = dbus_realloc (real->str - real->align_offset,
354b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington                              new_allocated);
355d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      if (new_str != NULL)
356d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        {
357b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington          real->str = new_str + real->align_offset;
358d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington          real->allocated = new_allocated;
359b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington          fixup_alignment (real);
360d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        }
361d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
362d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
363d1c7eefb66483c3ea4d9e7fb6dca23dcfac8cad5Havoc Pennington#endif /* DBUS_BUILD_TESTS */
364d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
365e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtonstatic dbus_bool_t
366d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtonreallocate_for_length (DBusRealString *real,
367d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                       int             new_length)
368e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington{
369d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  int new_allocated;
370d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  char *new_str;
371b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
372d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  /* at least double our old allocation to avoid O(n), avoiding
373d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington   * overflow
374d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington   */
375d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  if (real->allocated > (MAX_MAX_LENGTH + ALLOCATION_PADDING) / 2)
376d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    new_allocated = MAX_MAX_LENGTH + ALLOCATION_PADDING;
377d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  else
378d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    new_allocated = real->allocated * 2;
379b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
380d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  /* if you change the code just above here, run the tests without
381d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington   * the following before you commit
382d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington   */
38321cef58bc1b46ba4d5e7371463920c7744904d32Havoc Pennington#ifdef DBUS_BUILD_TESTS
384d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  new_allocated = 0; /* ensure a realloc every time so that we go
385d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                      * through all malloc failure codepaths
386d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                      */
38721cef58bc1b46ba4d5e7371463920c7744904d32Havoc Pennington#endif
38821cef58bc1b46ba4d5e7371463920c7744904d32Havoc Pennington
389d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  /* But be sure we always alloc at least space for the new length */
390d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  new_allocated = MAX (new_allocated, new_length + ALLOCATION_PADDING);
391e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
392d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  _dbus_assert (new_allocated >= real->allocated); /* code relies on this */
393d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  new_str = dbus_realloc (real->str - real->align_offset, new_allocated);
394d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  if (new_str == NULL)
395d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
396e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
397d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  real->str = new_str + real->align_offset;
398d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  real->allocated = new_allocated;
399d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  fixup_alignment (real);
400e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
401e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  return TRUE;
402e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington}
403e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
404e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtonstatic dbus_bool_t
405d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtonset_length (DBusRealString *real,
406d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington            int             new_length)
407d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington{
408d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  /* Note, we are setting the length not including nul termination */
409d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
410d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  /* exceeding max length is the same as failure to allocate memory */
411d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  if (new_length > real->max_length)
412d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
413d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  else if (new_length > (real->allocated - ALLOCATION_PADDING) &&
414d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington           !reallocate_for_length (real, new_length))
415d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
416d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  else
417d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    {
418d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      real->len = new_length;
419d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      real->str[real->len] = '\0';
420d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      return TRUE;
421d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    }
422d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington}
423d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
424d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtonstatic dbus_bool_t
425e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtonopen_gap (int             len,
426e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington          DBusRealString *dest,
427e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington          int             insert_at)
428e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington{
429e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  if (len == 0)
430e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington    return TRUE;
431e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
432b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (len > dest->max_length - dest->len)
433b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    return FALSE; /* detected overflow of dest->len + len below */
434b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
435e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  if (!set_length (dest, dest->len + len))
436e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington    return FALSE;
437e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
438e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  memmove (dest->str + insert_at + len,
439e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington           dest->str + insert_at,
440e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington           dest->len - len - insert_at);
441e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
442e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  return TRUE;
443e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington}
444e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
445d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
446d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Gets the raw character buffer from the string.  The returned buffer
447d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * will be nul-terminated, but note that strings may contain binary
448d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * data so there may be extra nul characters prior to the termination.
449d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * This function should be little-used, extend DBusString or add
450d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * stuff to dbus-sysdeps.c instead. It's an error to use this
451d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * function on a const string.
452d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
453d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
454fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * @returns the data
455d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
456fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonchar*
457fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington_dbus_string_get_data (DBusString *str)
458d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
459d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
460d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
461fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  return real->str;
462d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
463d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
464d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
465a07bc460ae1a3d3582a6dac7e48ed1ea117990efHavoc Pennington * Gets the raw character buffer from a const string.
466a07bc460ae1a3d3582a6dac7e48ed1ea117990efHavoc Pennington *
467d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
468fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * @returns the string data
469d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
470fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonconst char*
471fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington_dbus_string_get_const_data (const DBusString  *str)
472d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
473d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
474d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
475fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  return real->str;
476d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
477d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
478d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
479d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Gets a sub-portion of the raw character buffer from the
480d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * string. The "len" field is required simply for error
481d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * checking, to be sure you don't try to use more
482d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * string than exists. The nul termination of the
483d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * returned buffer remains at the end of the entire
484d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * string, not at start + len.
485d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
486d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
487d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start byte offset to return
488d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len length of segment to return
489fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * @returns the string data
490d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
491fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonchar*
492d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_get_data_len (DBusString *str,
493d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                           int         start,
494d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                           int         len)
495d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
496d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
497d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (start >= 0);
498d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
499b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
500b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real->len - start);
501d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
502fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  return real->str + start;
503d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
504d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
505d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
506d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * const version of _dbus_string_get_data_len().
507d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
508d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
509d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start byte offset to return
510d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len length of segment to return
511fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington * @returns the string data
512d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
513fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Penningtonconst char*
514d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_get_const_data_len (const DBusString  *str,
515d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                                 int                start,
516d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                                 int                len)
517d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
518d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
519d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (start >= 0);
520d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
521b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
522b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real->len - start);
523d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
524fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  return real->str + start;
525d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
526d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
527d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
528e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * Sets the value of the byte at the given position.
529e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington *
530e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param str the string
531e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param i the position
532e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param byte the new value
533e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington */
534e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtonvoid
535e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington_dbus_string_set_byte (DBusString    *str,
536e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington                       int            i,
537e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington                       unsigned char  byte)
538e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington{
539e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  DBUS_STRING_PREAMBLE (str);
540e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_assert (i < real->len);
541b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (i >= 0);
542b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
543e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  real->str[i] = byte;
544e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington}
545e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
546e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington/**
54775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * Gets the byte at the given position. It is
54875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * allowed to ask for the nul byte at the end of
54975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * the string.
55050c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
55150c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param str the string
55250c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param start the position
55350c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @returns the byte at that position
55450c25505f62786756519ef1e194883360eda82e0Havoc Pennington */
555e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtonunsigned char
55650c25505f62786756519ef1e194883360eda82e0Havoc Pennington_dbus_string_get_byte (const DBusString  *str,
55750c25505f62786756519ef1e194883360eda82e0Havoc Pennington                       int                start)
55850c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
55950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
56075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  _dbus_assert (start <= real->len);
561b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start >= 0);
562b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
56350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return real->str[start];
56450c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
56550c25505f62786756519ef1e194883360eda82e0Havoc Pennington
56650c25505f62786756519ef1e194883360eda82e0Havoc Pennington/**
56746c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin * Inserts a number of bytes of a given value at the
56846c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin * given position.
569e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington *
570e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param str the string
571e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param i the position
57246c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin * @param n_bytes number of bytes
573e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @param byte the value to insert
574e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington * @returns #TRUE on success
575e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington */
576e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Penningtondbus_bool_t
57746c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin_dbus_string_insert_bytes (DBusString   *str,
57846c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin			   int           i,
57946c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin			   int           n_bytes,
58046c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin			   unsigned char byte)
581e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington{
582e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  DBUS_STRING_PREAMBLE (str);
583e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_assert (i <= real->len);
584b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (i >= 0);
58546c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  _dbus_assert (n_bytes > 0);
586b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
58746c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  if (!open_gap (n_bytes, real, i))
588e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington    return FALSE;
589e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
59046c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  memset (real->str + i, byte, n_bytes);
591e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
592e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  return TRUE;
593e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington}
594e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
595e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington/**
596d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Like _dbus_string_get_data(), but removes the
597d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * gotten data from the original string. The caller
598d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * must free the data returned. This function may
599d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * fail due to lack of memory, and return #FALSE.
600d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
601d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
602d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param data_return location to return the buffer
603d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #TRUE on success
604d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
605d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
606d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_steal_data (DBusString        *str,
607d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                         char             **data_return)
608d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
609fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  int old_max_length;
610d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
611d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (data_return != NULL);
61213f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington
61313f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington  undo_alignment (real);
614d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
615d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  *data_return = real->str;
616d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
617fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  old_max_length = real->max_length;
618fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
619d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* reset the string */
620fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (str))
621d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
622d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      /* hrm, put it back then */
623d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      real->str = *data_return;
624d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      *data_return = NULL;
62513f70ce711630d7f70c0b11fa57639fad95e4afdHavoc Pennington      fixup_alignment (real);
626d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      return FALSE;
627d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
628d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
629fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  real->max_length = old_max_length;
630fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
631d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
632d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
633d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
634d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
635d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Like _dbus_string_get_data_len(), but removes the gotten data from
636d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the original string. The caller must free the data returned. This
637d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * function may fail due to lack of memory, and return #FALSE.
638d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * The returned string is nul-terminated and has length len.
639d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
640b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo this function is broken because on failure it
641b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * may corrupt the source string.
642b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
643d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
644d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param data_return location to return the buffer
645d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start the start of segment to steal
646d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len the length of segment to steal
647d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #TRUE on success
648d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
649d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
650d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_steal_data_len (DBusString        *str,
651d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                             char             **data_return,
652d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                             int                start,
653d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                             int                len)
654d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
655d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusString dest;
656d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
657d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (data_return != NULL);
658d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (start >= 0);
659d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
660b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
661b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real->len - start);
662d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
663fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&dest))
664d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return FALSE;
665d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
666fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  set_max_length (&dest, real->max_length);
667fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
668d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_move_len (str, start, len, &dest, 0))
669d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
670d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      _dbus_string_free (&dest);
671d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      return FALSE;
672d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
673b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
674bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_warn ("Broken code in _dbus_string_steal_data_len(), see @todo, FIXME\n");
675bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  if (!_dbus_string_steal_data (&dest, data_return))
676bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    {
677bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington      _dbus_string_free (&dest);
678bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington      return FALSE;
679bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    }
680bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
681bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_string_free (&dest);
682bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  return TRUE;
683bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington}
684bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
685bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
686bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington/**
687bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * Copies the data from the string into a char*
688bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington *
689bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param str the string
690bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param data_return place to return the data
691bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @returns #TRUE on success, #FALSE on no memory
692bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington */
693bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Penningtondbus_bool_t
694bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington_dbus_string_copy_data (const DBusString  *str,
695bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington                        char             **data_return)
696bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington{
697bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
698bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (data_return != NULL);
699bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
700bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  *data_return = dbus_malloc (real->len + 1);
701bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  if (*data_return == NULL)
702bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    return FALSE;
703bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
704bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  memcpy (*data_return, real->str, real->len + 1);
705bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
706bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  return TRUE;
707bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington}
708bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
709bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington/**
710bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * Copies a segment of the string into a char*
711bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington *
712bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param str the string
713bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param data_return place to return the data
714bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param start start index
715bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param len length to copy
716bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @returns #FALSE if no memory
717bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington */
718bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Penningtondbus_bool_t
719bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington_dbus_string_copy_data_len (const DBusString  *str,
720bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington                            char             **data_return,
721bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington                            int                start,
722bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington                            int                len)
723bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington{
724bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  DBusString dest;
725bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
726bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
727bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (data_return != NULL);
728bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (start >= 0);
729bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (len >= 0);
730bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (start <= real->len);
731bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (len <= real->len - start);
732bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
733fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&dest))
734bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    return FALSE;
735bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
736fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  set_max_length (&dest, real->max_length);
737fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
738bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  if (!_dbus_string_copy_len (str, start, len, &dest, 0))
739bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    {
740bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington      _dbus_string_free (&dest);
741bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington      return FALSE;
742bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    }
743bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
744d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_steal_data (&dest, data_return))
745d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
746d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      _dbus_string_free (&dest);
747d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      return FALSE;
748d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
749d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
750d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_string_free (&dest);
751d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
752d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
753d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
754d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
755d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Gets the length of a string (not including nul termination).
756d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
757d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns the length.
758d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
759d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonint
760d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_get_length (const DBusString  *str)
761d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
762d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
763d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
764d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return real->len;
765d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
766d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
767d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
768d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Makes a string longer by the given number of bytes.  Checks whether
769d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * adding additional_length to the current length would overflow an
770d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * integer, and checks for exceeding a string's max length.
771d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * The new bytes are not initialized, other than nul-terminating
772d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the end of the string. The uninitialized bytes may contain
773b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * nul bytes or other junk.
774d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
775d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str a string
776d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param additional_length length to add to the string.
777d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #TRUE on success.
778d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
779d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
780d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_lengthen (DBusString *str,
781d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int         additional_length)
782d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
783d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
784d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (additional_length >= 0);
785b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
786b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (additional_length > real->max_length - real->len)
787b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    return FALSE; /* would overflow */
788d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
789d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return set_length (real,
790d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                     real->len + additional_length);
791d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
792d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
793d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
794d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Makes a string shorter by the given number of bytes.
795d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
796d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str a string
797d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param length_to_remove length to remove from the string.
798d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
799d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
800d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_shorten (DBusString *str,
801d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                      int         length_to_remove)
802d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
803d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
804d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (length_to_remove >= 0);
805d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (length_to_remove <= real->len);
806d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
807d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  set_length (real,
808d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington              real->len - length_to_remove);
809d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
810d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
811d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
812d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Sets the length of a string. Can be used to truncate or lengthen
813d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the string. If the string is lengthened, the function may fail and
814d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * return #FALSE. Newly-added bytes are not initialized, as with
815d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * _dbus_string_lengthen().
816d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
817d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str a string
818d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param length new length of the string.
819d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE on failure.
820d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
821d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
822d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_set_length (DBusString *str,
823d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                         int         length)
824d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
825d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
826d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (length >= 0);
827d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
828d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return set_length (real, length);
829d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
830d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
831d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtonstatic dbus_bool_t
832d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtonalign_length_then_lengthen (DBusString *str,
833d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                            int         alignment,
834d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                            int         then_lengthen_by)
835993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington{
836b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  unsigned long new_len; /* ulong to avoid _DBUS_ALIGN_VALUE overflow */
837993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  int delta;
838993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  DBUS_STRING_PREAMBLE (str);
839993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  _dbus_assert (alignment >= 1);
8407ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  _dbus_assert (alignment <= 8); /* it has to be a bug if > 8 */
841993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
842993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  new_len = _DBUS_ALIGN_VALUE (real->len, alignment);
843d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  if (new_len > (unsigned long) real->max_length - then_lengthen_by)
844b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    return FALSE;
845d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  new_len += then_lengthen_by;
846b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
847993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  delta = new_len - real->len;
848993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  _dbus_assert (delta >= 0);
849993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
850993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  if (delta == 0)
851993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington    return TRUE;
852993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
853993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  if (!set_length (real, new_len))
854993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington    return FALSE;
855993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
856d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  /* delta == padding + then_lengthen_by
857d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington   * new_len == old_len + padding + then_lengthen_by
858d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington   */
859d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  if (then_lengthen_by < delta)
860d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    {
861d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      unsigned int i;
862d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      i = new_len - delta;
863d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      while (i < (new_len - then_lengthen_by))
864d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        {
865d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington          real->str[i] = '\0';
866d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington          ++i;
867d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        }
868d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    }
869d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
870993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington  return TRUE;
871993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington}
872993be1059afcb0e9a5b67f5287fb1122d6c48ce6Havoc Pennington
873d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington/**
874d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * Align the length of a string to a specific alignment (typically 4 or 8)
875d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * by appending nul bytes to the string.
876d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington *
877d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param str a string
878d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param alignment the alignment
879d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @returns #FALSE if no memory
880d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington */
881d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtondbus_bool_t
882d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington_dbus_string_align_length (DBusString *str,
883d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                           int         alignment)
884d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington{
885d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  return align_length_then_lengthen (str, alignment, 0);
886d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington}
887d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
888d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonstatic dbus_bool_t
889d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonappend (DBusRealString *real,
890d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        const char     *buffer,
891d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        int             buffer_len)
892d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
893d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (buffer_len == 0)
894d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return TRUE;
895d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
896d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_lengthen ((DBusString*)real, buffer_len))
897d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return FALSE;
898d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
899d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  memcpy (real->str + (real->len - buffer_len),
900d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington          buffer,
901d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington          buffer_len);
902d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
903d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
904d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
905d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
906d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
907d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Appends a nul-terminated C-style string to a DBusString.
908d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
909d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the DBusString
910d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param buffer the nul-terminated characters to append
911d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory.
912d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
913d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
914d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_append (DBusString *str,
915d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                     const char *buffer)
916d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
917b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  unsigned long buffer_len;
918d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
919d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
920d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (buffer != NULL);
921d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
922d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  buffer_len = strlen (buffer);
923b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (buffer_len > (unsigned long) real->max_length)
924b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    return FALSE;
925b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
926d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return append (real, buffer, buffer_len);
927d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
928d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
929d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
930d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * Appends 4 bytes aligned on a 4 byte boundary
931d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * with any alignment padding initialized to 0.
932d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington *
933d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param str the DBusString
934d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param octets 4 bytes to append
935d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @returns #FALSE if not enough memory.
936d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington */
937d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtondbus_bool_t
938d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington_dbus_string_append_4_aligned (DBusString         *str,
939d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                               const unsigned char octets[4])
940d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington{
941d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  dbus_uint32_t *p;
942d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  DBUS_STRING_PREAMBLE (str);
943d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
944d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  if (!align_length_then_lengthen (str, 4, 4))
945d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
946d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
947d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  p = (dbus_uint32_t*) (real->str + (real->len - 4));
948d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  *p = *((dbus_uint32_t*)octets);
949d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
950d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  return TRUE;
951d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington}
952d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
953d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington/**
954d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * Appends 8 bytes aligned on an 8 byte boundary
955d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * with any alignment padding initialized to 0.
956d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington *
957d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param str the DBusString
958d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @param octets 4 bytes to append
959d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @returns #FALSE if not enough memory.
960d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington */
961d4e80132af03363a2f861cfd611847ee8758aed9Havoc Penningtondbus_bool_t
962d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington_dbus_string_append_8_aligned (DBusString         *str,
963d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                               const unsigned char octets[8])
964d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington{
965d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington#ifdef DBUS_HAVE_INT64
966d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  dbus_uint64_t *p;
967d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  DBUS_STRING_PREAMBLE (str);
968d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
969d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  if (!align_length_then_lengthen (str, 8, 8))
970d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
971d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
972d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  p = (dbus_uint64_t*) (real->str + (real->len - 8));
973d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  *p = *((dbus_uint64_t*)octets);
974d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington#else
975fe195a911d86d0a71349988360de65cfac1b3f86Havoc Pennington  unsigned char *p;
976d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  DBUS_STRING_PREAMBLE (str);
977d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
978d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  if (!align_length_then_lengthen (str, 8, 8))
979d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    return FALSE;
980d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
981d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  p = real->str + (real->len - 8);
982d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
983d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  *p++ = octets[0];
984d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  *p++ = octets[1];
985d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  *p++ = octets[2];
986d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  *p++ = octets[3];
987d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  *p++ = octets[4];
988d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  *p++ = octets[5];
989d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  *p++ = octets[6];
990d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  *p++ = octets[7];
991d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  _dbus_assert (p == (real->str + real->len));
992d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington#endif
993d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
994d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  return TRUE;
995d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington}
996d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
997d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington/**
9981d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * Appends a printf-style formatted string
9991d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * to the #DBusString.
10001d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington *
10011d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @param str the string
10021d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @param format printf format
10031d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @param args variable argument list
10041d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @returns #FALSE if no memory
10051d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington */
10061d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Penningtondbus_bool_t
10071d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington_dbus_string_append_printf_valist  (DBusString        *str,
10081d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington                                    const char        *format,
10091d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington                                    va_list            args)
10101d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington{
10111d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  int len;
10121d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  char c;
101324f411a6a10e4838f57595720642ce83ceae814cHavoc Pennington  DBUS_STRING_PREAMBLE (str);
10141d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
10151d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  /* Measure the message length without terminating nul */
10161d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  len = vsnprintf (&c, 1, format, args);
10171d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
10181d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  if (!_dbus_string_lengthen (str, len))
10191d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington    return FALSE;
10201d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
10211d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  vsprintf (real->str + (real->len - len),
10221d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington            format, args);
10231d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
10241d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  return TRUE;
10251d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington}
10261d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
10271d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington/**
10281d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * Appends a printf-style formatted string
10291d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * to the #DBusString.
10301d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington *
10311d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @param str the string
10321d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @param format printf format
10331d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington * @returns #FALSE if no memory
10341d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington */
10351d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Penningtondbus_bool_t
10361d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington_dbus_string_append_printf (DBusString        *str,
10371d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington                            const char        *format,
10381d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington                            ...)
10391d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington{
10401d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  va_list args;
10411d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  dbus_bool_t retval;
10421d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
10431d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  va_start (args, format);
10441d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  retval = _dbus_string_append_printf_valist (str, format, args);
10451d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  va_end (args);
10461d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
10471d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington  return retval;
10481d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington}
10491d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington
10501d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48Havoc Pennington/**
1051d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Appends block of bytes with the given length to a DBusString.
1052d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1053d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the DBusString
1054d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param buffer the bytes to append
1055d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len the number of bytes to append
1056d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory.
1057d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1058d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1059d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_append_len (DBusString *str,
1060d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                         const char *buffer,
1061d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                         int         len)
1062d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1063d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
1064d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (buffer != NULL);
1065d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
1066d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1067d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return append (real, buffer, len);
1068d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1069d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1070d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1071d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Appends a single byte to the string, returning #FALSE
1072d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * if not enough memory.
1073d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1074d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
1075d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param byte the byte to append
1076d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #TRUE on success
1077d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1078d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1079d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_append_byte (DBusString    *str,
1080d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                          unsigned char  byte)
1081d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1082d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
1083d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1084d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!set_length (real, real->len + 1))
1085d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return FALSE;
1086d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1087d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->str[real->len-1] = byte;
1088d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1089d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
1090d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1091d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1092d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1093d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Appends a single Unicode character, encoding the character
1094d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * in UTF-8 format.
1095d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1096d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
1097d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param ch the Unicode character
1098d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1099d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1100d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_append_unichar (DBusString    *str,
1101d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                             dbus_unichar_t ch)
1102d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1103d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  int len;
1104d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  int first;
1105d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  int i;
1106d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  char *out;
1107d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1108d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
1109d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1110d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* this code is from GLib but is pretty standard I think */
1111d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1112d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  len = 0;
1113d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1114d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (ch < 0x80)
1115d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1116d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0;
1117d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 1;
1118d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1119d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if (ch < 0x800)
1120d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1121d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0xc0;
1122d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 2;
1123d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1124d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if (ch < 0x10000)
1125d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1126d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0xe0;
1127d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 3;
1128d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1129d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   else if (ch < 0x200000)
1130d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1131d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0xf0;
1132d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 4;
1133d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1134d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if (ch < 0x4000000)
1135d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1136d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0xf8;
1137d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 5;
1138d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1139d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else
1140d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1141d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      first = 0xfc;
1142d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      len = 6;
1143d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1144d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1145b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (len > (real->max_length - real->len))
1146b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    return FALSE; /* real->len + len would overflow */
1147b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
1148d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!set_length (real, real->len + len))
1149d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return FALSE;
1150d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1151d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  out = real->str + (real->len - len);
1152d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1153d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  for (i = len - 1; i > 0; --i)
1154d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
1155d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      out[i] = (ch & 0x3f) | 0x80;
1156d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      ch >>= 6;
1157d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1158d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  out[0] = ch | first;
1159d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1160d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
1161d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1162d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1163d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonstatic void
1164d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondelete (DBusRealString *real,
1165d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        int             start,
1166d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        int             len)
1167d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1168d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (len == 0)
1169d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return;
1170d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1171d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  memmove (real->str + start, real->str + start + len, real->len - (start + len));
1172d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->len -= len;
1173d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  real->str[real->len] = '\0';
1174d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1175d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1176d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1177d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Deletes a segment of a DBusString with length len starting at
1178d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * start. (Hint: to clear an entire string, setting length to 0
1179d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * with _dbus_string_set_length() is easier.)
1180d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1181d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the DBusString
1182d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start where to start deleting
1183d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len the number of bytes to delete
1184d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1185d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
1186d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_delete (DBusString       *str,
1187d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                     int               start,
1188d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                     int               len)
1189d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1190d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_PREAMBLE (str);
1191d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (start >= 0);
1192d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
1193b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
1194b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real->len - start);
119550c25505f62786756519ef1e194883360eda82e0Havoc Pennington
1196d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  delete (real, start, len);
1197d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1198d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1199d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonstatic dbus_bool_t
12002297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtoncopy (DBusRealString *source,
12012297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      int             start,
12022297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      int             len,
12032297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      DBusRealString *dest,
12042297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      int             insert_at)
12052297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
120650c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (len == 0)
120750c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return TRUE;
120850c25505f62786756519ef1e194883360eda82e0Havoc Pennington
12092297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!open_gap (len, dest, insert_at))
12102297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    return FALSE;
121150c25505f62786756519ef1e194883360eda82e0Havoc Pennington
1212d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  memcpy (dest->str + insert_at,
1213d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington          source->str + start,
1214d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington          len);
1215d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1216d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
1217d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1218d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1219d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1220d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Checks assertions for two strings we're copying a segment between,
1221d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * and declares real_source/real_dest variables.
1222d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1223d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param source the source string
1224d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start the starting offset
1225d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param dest the dest string
1226d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param insert_at where the copied segment is inserted
1227d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1228d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define DBUS_STRING_COPY_PREAMBLE(source, start, dest, insert_at)       \
1229d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusRealString *real_source = (DBusRealString*) source;               \
1230d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusRealString *real_dest = (DBusRealString*) dest;                   \
1231d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((source) != (dest));                                    \
1232d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_source);                           \
1233d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_dest);                             \
1234d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (!real_dest->constant);                                  \
1235d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (!real_dest->locked);                                    \
1236d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((start) >= 0);                                          \
1237d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((start) <= real_source->len);                           \
1238d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((insert_at) >= 0);                                      \
1239d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((insert_at) <= real_dest->len)
1240d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1241d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1242d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Moves the end of one string into another string. Both strings
1243d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * must be initialized, valid strings.
1244d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1245d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param source the source string
1246d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start where to chop off the source string
1247d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param dest the destination string
1248d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param insert_at where to move the chopped-off part of source string
1249d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory
1250d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1251d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1252d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_move (DBusString       *source,
1253d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   int               start,
1254d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   DBusString       *dest,
1255d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   int               insert_at)
1256d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1257d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  DBusRealString *real_source = (DBusRealString*) source;
1258d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  _dbus_assert (start <= real_source->len);
1259d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1260d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  return _dbus_string_move_len (source, start,
1261d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                                real_source->len - start,
1262d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                                dest, insert_at);
1263d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1264d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1265d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1266d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Like _dbus_string_move(), but does not delete the section
1267d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * of the source string that's copied to the dest string.
1268d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1269d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param source the source string
1270d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start where to start copying the source string
1271d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param dest the destination string
1272d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param insert_at where to place the copied part of source string
1273d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory
1274d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1275d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1276d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_copy (const DBusString *source,
1277d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   int               start,
1278d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   DBusString       *dest,
1279d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                   int               insert_at)
1280d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1281d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1282d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1283d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return copy (real_source, start,
1284d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington               real_source->len - start,
1285d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington               real_dest,
1286d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington               insert_at);
1287d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1288d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1289d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1290d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Like _dbus_string_move(), but can move a segment from
1291d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the middle of the source string.
1292d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington *
1293d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * @todo this doesn't do anything with max_length field.
1294d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington * we should probably just kill the max_length field though.
1295d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1296d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param source the source string
1297d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start first byte of source string to move
1298d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len length of segment to move
1299d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param dest the destination string
1300d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param insert_at where to move the bytes from the source string
1301d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory
1302d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1303d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1304d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_move_len (DBusString       *source,
1305d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               start,
1306d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               len,
1307d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       DBusString       *dest,
1308d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               insert_at)
1309d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1310d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1311d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1312d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
1313d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert ((start + len) <= real_source->len);
1314d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1315d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1316d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  if (len == 0)
1317d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    {
1318d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      return TRUE;
1319d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    }
1320d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  else if (start == 0 &&
1321d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington           len == real_source->len &&
1322d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington           real_dest->len == 0)
1323d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    {
1324d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      /* Short-circuit moving an entire existing string to an empty string
1325d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington       * by just swapping the buffers.
1326d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington       */
1327d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      /* we assume ->constant doesn't matter as you can't have
1328d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington       * a constant string involved in a move.
1329d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington       */
1330d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington#define ASSIGN_DATA(a, b) do {                  \
1331d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        (a)->str = (b)->str;                    \
1332d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        (a)->len = (b)->len;                    \
1333d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        (a)->allocated = (b)->allocated;        \
1334d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        (a)->align_offset = (b)->align_offset;  \
1335d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      } while (0)
1336d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1337d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      DBusRealString tmp;
1338d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1339d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      ASSIGN_DATA (&tmp, real_source);
1340d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      ASSIGN_DATA (real_source, real_dest);
1341d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      ASSIGN_DATA (real_dest, &tmp);
1342d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1343d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      return TRUE;
1344d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    }
1345d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington  else
1346d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    {
1347d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      if (!copy (real_source, start, len,
1348d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                 real_dest,
1349d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington                 insert_at))
1350d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington        return FALSE;
1351d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1352d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      delete (real_source, start,
1353d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington              len);
1354d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington
1355d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington      return TRUE;
1356d4e80132af03363a2f861cfd611847ee8758aed9Havoc Pennington    }
1357d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1358d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1359d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1360d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Like _dbus_string_copy(), but can copy a segment from the middle of
1361d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * the source string.
1362d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1363d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param source the source string
1364d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start where to start copying the source string
1365d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param len length of segment to copy
1366d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param dest the destination string
1367d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param insert_at where to place the copied segment of source string
1368d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #FALSE if not enough memory
1369d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1370d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
1371d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_copy_len (const DBusString *source,
1372d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               start,
1373d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               len,
1374d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       DBusString       *dest,
1375d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                       int               insert_at)
1376d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1377d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
1378d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (len >= 0);
1379b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real_source->len);
1380b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real_source->len - start);
1381d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1382d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return copy (real_source, start, len,
1383d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington               real_dest,
1384d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington               insert_at);
1385d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1386d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
138750c25505f62786756519ef1e194883360eda82e0Havoc Pennington/**
138850c25505f62786756519ef1e194883360eda82e0Havoc Pennington * Replaces a segment of dest string with a segment of source string.
138950c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
139050c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @todo optimize the case where the two lengths are the same, and
139150c25505f62786756519ef1e194883360eda82e0Havoc Pennington * avoid memmoving the data in the trailing part of the string twice.
1392b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
1393b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo avoid inserting the source into dest, then deleting
1394b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * the replaced chunk of dest (which creates a potentially large
1395b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * intermediate string). Instead, extend the replaced chunk
1396b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * of dest with padding to the same size as the source chunk,
1397b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * then copy in the source bytes.
139850c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
139950c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param source the source string
140050c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param start where to start copying the source string
140150c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param len length of segment to copy
140250c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param dest the destination string
140350c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param replace_at start of segment of dest string to replace
140450c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @param replace_len length of segment of dest string to replace
140550c25505f62786756519ef1e194883360eda82e0Havoc Pennington * @returns #FALSE if not enough memory
140650c25505f62786756519ef1e194883360eda82e0Havoc Pennington *
140750c25505f62786756519ef1e194883360eda82e0Havoc Pennington */
140850c25505f62786756519ef1e194883360eda82e0Havoc Penningtondbus_bool_t
140950c25505f62786756519ef1e194883360eda82e0Havoc Pennington_dbus_string_replace_len (const DBusString *source,
141050c25505f62786756519ef1e194883360eda82e0Havoc Pennington                          int               start,
141150c25505f62786756519ef1e194883360eda82e0Havoc Pennington                          int               len,
141250c25505f62786756519ef1e194883360eda82e0Havoc Pennington                          DBusString       *dest,
141350c25505f62786756519ef1e194883360eda82e0Havoc Pennington                          int               replace_at,
141450c25505f62786756519ef1e194883360eda82e0Havoc Pennington                          int               replace_len)
141550c25505f62786756519ef1e194883360eda82e0Havoc Pennington{
141650c25505f62786756519ef1e194883360eda82e0Havoc Pennington  DBUS_STRING_COPY_PREAMBLE (source, start, dest, replace_at);
141750c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (len >= 0);
1418b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real_source->len);
1419b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (len <= real_source->len - start);
142050c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (replace_at >= 0);
1421b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (replace_at <= real_dest->len);
1422b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (replace_len <= real_dest->len - replace_at);
142350c25505f62786756519ef1e194883360eda82e0Havoc Pennington
142450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!copy (real_source, start, len,
142550c25505f62786756519ef1e194883360eda82e0Havoc Pennington             real_dest, replace_at))
142650c25505f62786756519ef1e194883360eda82e0Havoc Pennington    return FALSE;
142750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
142850c25505f62786756519ef1e194883360eda82e0Havoc Pennington  delete (real_dest, replace_at + len, replace_len);
142950c25505f62786756519ef1e194883360eda82e0Havoc Pennington
143050c25505f62786756519ef1e194883360eda82e0Havoc Pennington  return TRUE;
143150c25505f62786756519ef1e194883360eda82e0Havoc Pennington}
143250c25505f62786756519ef1e194883360eda82e0Havoc Pennington
1433021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington/* Unicode macros and utf8_validate() from GLib Owen Taylor, Havoc
1434021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington * Pennington, and Tom Tromey are the authors and authorized relicense.
1435021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington */
1436d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1437d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/** computes length and mask of a unicode character
1438d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Char the char
1439d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Mask the mask variable to assign to
1440d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Len the length variable to assign to
1441d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1442d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define UTF8_COMPUTE(Char, Mask, Len)					      \
1443d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (Char < 128)							      \
1444d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1445d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 1;								      \
1446d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x7f;							      \
1447d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
1448d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if ((Char & 0xe0) == 0xc0)					      \
1449d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1450d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 2;								      \
1451d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x1f;							      \
1452d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
1453d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if ((Char & 0xf0) == 0xe0)					      \
1454d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1455d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 3;								      \
1456d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x0f;							      \
1457d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
1458d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if ((Char & 0xf8) == 0xf0)					      \
1459d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1460d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 4;								      \
1461d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x07;							      \
1462d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
1463d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if ((Char & 0xfc) == 0xf8)					      \
1464d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1465d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 5;								      \
1466d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x03;							      \
1467d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
1468d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else if ((Char & 0xfe) == 0xfc)					      \
1469d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1470d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Len = 6;								      \
1471d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      Mask = 0x01;							      \
1472d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }									      \
1473d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  else									      \
1474d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    Len = -1;
1475d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1476d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1477d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * computes length of a unicode character in UTF-8
1478d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Char the char
1479d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1480d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define UTF8_LENGTH(Char)              \
1481d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  ((Char) < 0x80 ? 1 :                 \
1482d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington   ((Char) < 0x800 ? 2 :               \
1483d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    ((Char) < 0x10000 ? 3 :            \
1484d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington     ((Char) < 0x200000 ? 4 :          \
1485d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      ((Char) < 0x4000000 ? 5 : 6)))))
1486d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1487d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1488d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Gets a UTF-8 value.
1489d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1490d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Result variable for extracted unicode char.
1491d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Chars the bytes to decode
1492d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Count counter variable
1493d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Mask mask for this char
1494d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Len length for this char in bytes
1495d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1496d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define UTF8_GET(Result, Chars, Count, Mask, Len)			      \
1497d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  (Result) = (Chars)[0] & (Mask);					      \
1498d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  for ((Count) = 1; (Count) < (Len); ++(Count))				      \
1499d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {									      \
1500d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      if (((Chars)[(Count)] & 0xc0) != 0x80)				      \
1501d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington	{								      \
1502d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington	  (Result) = -1;						      \
1503d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington	  break;							      \
1504d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington	}								      \
1505d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      (Result) <<= 6;							      \
1506d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      (Result) |= ((Chars)[(Count)] & 0x3f);				      \
1507d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
1508d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1509d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1510d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Check whether a unicode char is in a valid range.
1511d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1512d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param Char the character
1513d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1514d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#define UNICODE_VALID(Char)                   \
1515d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    ((Char) < 0x110000 &&                     \
1516bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington     (((Char) & 0xFFFFF800) != 0xD800) &&     \
1517bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington     ((Char) < 0xFDD0 || (Char) > 0xFDEF) &&  \
1518bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington     ((Char) & 0xFFFF) != 0xFFFF)
1519d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1520d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
1521d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Gets a unicode character from a UTF-8 string. Does no validation;
1522d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * you must verify that the string is valid UTF-8 in advance and must
1523d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * pass in the start of a character.
1524d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
1525d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param str the string
1526d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param start the start of the UTF-8 character.
1527d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param ch_return location to return the character
1528d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @param end_return location to return the byte index of next character
1529d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
1530d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonvoid
1531d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_get_unichar (const DBusString *str,
1532d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                          int               start,
1533d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                          dbus_unichar_t   *ch_return,
1534d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington                          int              *end_return)
1535d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
1536d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  int i, mask, len;
1537d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  dbus_unichar_t result;
1538d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  unsigned char c;
1539d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  unsigned char *p;
1540d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
1541b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start >= 0);
1542b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
1543b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
1544d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (ch_return)
1545d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    *ch_return = 0;
1546d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (end_return)
1547d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    *end_return = real->len;
1548d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1549d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  mask = 0;
1550d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  p = real->str + start;
1551d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  c = *p;
1552d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1553d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  UTF8_COMPUTE (c, mask, len);
1554d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (len == -1)
1555d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return;
1556d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  UTF8_GET (result, p, i, mask, len);
1557d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1558d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (result == (dbus_unichar_t)-1)
1559d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    return;
1560d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
1561d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (ch_return)
1562d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    *ch_return = result;
1563d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (end_return)
1564d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    *end_return = start + len;
1565d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
1566d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
15672297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
15682297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Finds the given substring in the string,
15692297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * returning #TRUE and filling in the byte index
15702297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * where the substring was found, if it was found.
15712297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Returns #FALSE if the substring wasn't found.
15722297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Sets *start to the length of the string if the substring
15732297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * is not found.
15742297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
15752297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param str the string
15762297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param start where to start looking
15772297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param substr the substring
15782297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param found return location for where it was found, or #NULL
15792297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @returns #TRUE if found
15802297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
15812297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtondbus_bool_t
15822297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_find (const DBusString *str,
15832297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                   int               start,
15842297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                   const char       *substr,
15852297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                   int              *found)
15862297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
1587b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  return _dbus_string_find_to (str, start,
1588b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington                               ((const DBusRealString*)str)->len,
1589b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington                               substr, found);
15902297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
15912297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
15922297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
15935ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * Finds the given substring in the string,
15945ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * up to a certain position,
15955ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * returning #TRUE and filling in the byte index
15965ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * where the substring was found, if it was found.
15975ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * Returns #FALSE if the substring wasn't found.
15985ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * Sets *start to the length of the string if the substring
15995ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * is not found.
16005ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson *
16015ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @param str the string
16025ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @param start where to start looking
16035ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @param end where to stop looking
16045ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @param substr the substring
16055ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @param found return location for where it was found, or #NULL
16065ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson * @returns #TRUE if found
16075ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson */
16085ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlssondbus_bool_t
16095ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson_dbus_string_find_to (const DBusString *str,
16105ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson		      int               start,
16115ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson		      int               end,
16125ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson		      const char       *substr,
16135ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson		      int              *found)
16145ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson{
16155ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  int i;
16165ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  DBUS_CONST_STRING_PREAMBLE (str);
16175ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  _dbus_assert (substr != NULL);
16185ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  _dbus_assert (start <= real->len);
1619b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start >= 0);
1620b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (substr != NULL);
16215ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  _dbus_assert (end <= real->len);
1622b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= end);
16235ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
16245ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  /* we always "find" an empty string */
16255ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  if (*substr == '\0')
16265ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    {
16275ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson      if (found)
1628b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington        *found = start;
16295ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson      return TRUE;
16305ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    }
16315ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
16325ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  i = start;
1633b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  while (i < end)
16345ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    {
16355ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson      if (real->str[i] == substr[0])
16365ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson        {
16375ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson          int j = i + 1;
16385ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
1639b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington          while (j < end)
16405ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson            {
16415ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson              if (substr[j - i] == '\0')
16425ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson                break;
16435ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson              else if (real->str[j] != substr[j - i])
16445ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson                break;
16455ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
16465ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson              ++j;
16475ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson            }
16485ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
16495ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson          if (substr[j - i] == '\0')
16505ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson            {
16515ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson              if (found)
16525ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson                *found = i;
16535ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson              return TRUE;
16545ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson            }
16555ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson        }
16565ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
16575ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson      ++i;
16585ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    }
16595ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
16605ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  if (found)
16615ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    *found = end;
16625ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
16635ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  return FALSE;
16645ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson}
16655ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
16665ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson/**
166794790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington * Find the given byte scanning backward from the given start.
166894790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington * Sets *found to -1 if the byte is not found.
166994790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington *
167094790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington * @param str the string
167135ab7c6fab22dca58fc4b5c22b9e8587a6fd1492Havoc Pennington * @param start the place to start scanning (will not find the byte at this point)
167294790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington * @param byte the byte to find
167394790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington * @param found return location for where it was found
167494790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington * @returns #TRUE if found
167594790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington */
167694790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Penningtondbus_bool_t
167794790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington_dbus_string_find_byte_backward (const DBusString  *str,
167894790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington                                 int                start,
167994790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington                                 unsigned char      byte,
168094790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington                                 int               *found)
168194790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington{
168294790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  int i;
168394790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
168494790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  _dbus_assert (start <= real->len);
168594790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  _dbus_assert (start >= 0);
168694790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  _dbus_assert (found != NULL);
168794790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington
168894790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  i = start - 1;
168994790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  while (i >= 0)
169094790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington    {
169194790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington      if (real->str[i] == byte)
169294790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington        break;
169394790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington
169494790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington      --i;
169594790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington    }
169694790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington
169794790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  if (found)
169894790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington    *found = i;
169994790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington
170094790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  return i >= 0;
170194790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington}
170294790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington
170394790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington/**
17042297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Finds a blank (space or tab) in the string. Returns #TRUE
17052297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * if found, #FALSE otherwise. If a blank is not found sets
17062297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * *found to the length of the string.
17072297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
17082297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param str the string
17092297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param start byte index to start looking
17102297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param found place to store the location of the first blank
17112297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @returns #TRUE if a blank was found
17122297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
17132297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtondbus_bool_t
17142297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_find_blank (const DBusString *str,
17152297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                         int               start,
17162297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                         int              *found)
17172297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
17182297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  int i;
17192297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
17202297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert (start <= real->len);
1721b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start >= 0);
17222297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
17232297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  i = start;
17242297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  while (i < real->len)
17252297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
17262297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      if (real->str[i] == ' ' ||
17272297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington          real->str[i] == '\t')
17282297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        {
17292297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington          if (found)
17302297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington            *found = i;
17312297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington          return TRUE;
17322297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        }
17332297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
17342297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++i;
17352297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
17362297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
17372297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (found)
17382297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    *found = real->len;
17392297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
17402297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  return FALSE;
17412297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
17422297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
17432297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
17442297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Skips blanks from start, storing the first non-blank in *end
1745bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * (blank is space or tab).
17462297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
17472297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param str the string
17482297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param start where to start
17492297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param end where to store the first non-blank byte index
17502297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
17512297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtonvoid
17522297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_skip_blank (const DBusString *str,
17532297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                         int               start,
17542297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                         int              *end)
17552297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
17562297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  int i;
17572297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
17582297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert (start <= real->len);
1759b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start >= 0);
17602297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
17612297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  i = start;
17622297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  while (i < real->len)
17632297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
1764ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington      if (!(real->str[i] == ' ' ||
1765ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington            real->str[i] == '\t'))
17662297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        break;
17672297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
17682297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++i;
17692297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
17702297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
1771ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (i == real->len || !(real->str[i] == ' ' ||
1772ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington                                    real->str[i] == '\t'));
1773ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
17742297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (end)
17752297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    *end = i;
17762297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
17772297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
17782297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
1779bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * Skips whitespace from start, storing the first non-whitespace in *end.
1780bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * (whitespace is space, tab, newline, CR).
1781bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington *
1782bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param str the string
1783bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param start where to start
1784bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington * @param end where to store the first non-whitespace byte index
1785bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington */
1786bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Penningtonvoid
1787bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington_dbus_string_skip_white (const DBusString *str,
1788bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington                         int               start,
1789bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington                         int              *end)
1790bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington{
1791bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  int i;
1792bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
1793bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (start <= real->len);
1794bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (start >= 0);
1795bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
1796bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  i = start;
1797bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  while (i < real->len)
1798bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    {
1799bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington      if (!(real->str[i] == ' ' ||
1800bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington            real->str[i] == '\n' ||
1801bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington            real->str[i] == '\r' ||
1802bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington            real->str[i] == '\t'))
1803bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington        break;
1804bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
1805bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington      ++i;
1806bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    }
1807bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
1808bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  _dbus_assert (i == real->len || !(real->str[i] == ' ' ||
1809bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington                                    real->str[i] == '\t'));
1810bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
1811bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington  if (end)
1812bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington    *end = i;
1813bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington}
1814bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington
1815bc86794f23fa538a405813fb61b531c2eacc9ae1Havoc Pennington/**
181685ab0327d82e4945ad16630e583d8cc68df25a90Havoc Pennington * Assigns a newline-terminated or \\r\\n-terminated line from the front
1817c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington * of the string to the given dest string. The dest string's previous
1818c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington * contents are deleted. If the source string contains no newline,
1819c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington * moves the entire source string to the dest string.
1820b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
1821b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo owen correctly notes that this is a stupid function (it was
1822b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * written purely for test code,
1823b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * e.g. dbus-message-builder.c). Probably should be enforced as test
1824b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * code only with #ifdef DBUS_BUILD_TESTS
18253791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington *
18263791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param source the source string
18273791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param dest the destination string (contents are replaced)
18283791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @returns #FALSE if no memory, or source has length 0
18293791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington */
18303791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Penningtondbus_bool_t
18313791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington_dbus_string_pop_line (DBusString *source,
18323791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington                       DBusString *dest)
18333791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington{
18343791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  int eol;
18353791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  dbus_bool_t have_newline;
18363791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
18373791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  _dbus_string_set_length (dest, 0);
18383791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
18393791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  eol = 0;
18403791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  if (_dbus_string_find (source, 0, "\n", &eol))
18413791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    {
18423791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      have_newline = TRUE;
18433791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      eol += 1; /* include newline */
18443791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    }
18453791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  else
18463791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    {
18473791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      eol = _dbus_string_get_length (source);
18483791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      have_newline = FALSE;
18493791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    }
18503791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
18513791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  if (eol == 0)
18523791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    return FALSE; /* eof */
18533791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
18543791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  if (!_dbus_string_move_len (source, 0, eol,
18553791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington                              dest, 0))
18563791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    {
18573791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      return FALSE;
18583791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    }
18593791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
1860c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington  /* dump the newline and the \r if we have one */
18613791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  if (have_newline)
18623791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    {
1863c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington      dbus_bool_t have_cr;
1864c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington
18653791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      _dbus_assert (_dbus_string_get_length (dest) > 0);
1866c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington
1867c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington      if (_dbus_string_get_length (dest) > 1 &&
1868c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington          _dbus_string_get_byte (dest,
1869c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington                                 _dbus_string_get_length (dest) - 2) == '\r')
1870c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington        have_cr = TRUE;
1871c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington      else
1872c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington        have_cr = FALSE;
1873c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington
18743791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      _dbus_string_set_length (dest,
1875c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington                               _dbus_string_get_length (dest) -
1876c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington                               (have_cr ? 2 : 1));
18773791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    }
18783791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
18793791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  return TRUE;
18803791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington}
18813791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
18823791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington/**
18833791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * Deletes up to and including the first blank space
18843791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * in the string.
18853791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington *
18863791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param str the string
18873791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington */
18883791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Penningtonvoid
18893791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington_dbus_string_delete_first_word (DBusString *str)
18903791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington{
18913791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  int i;
18923791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
18933791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  if (_dbus_string_find_blank (str, 0, &i))
18943791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    _dbus_string_skip_blank (str, i, &i);
18953791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
18963791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  _dbus_string_delete (str, 0, i);
18973791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington}
18983791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
18993791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington/**
19003791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * Deletes any leading blanks in the string
19013791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington *
19023791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param str the string
19033791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington */
19043791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Penningtonvoid
19053791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington_dbus_string_delete_leading_blanks (DBusString *str)
19063791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington{
19073791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  int i;
19083791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
19093791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  _dbus_string_skip_blank (str, 0, &i);
19103791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
19113791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  if (i > 0)
19123791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    _dbus_string_delete (str, 0, i);
19133791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington}
19143791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
19153791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington/**
19162297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Tests two DBusString for equality.
19172297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
1918b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo memcmp is probably faster
1919b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
19202297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param a first string
19212297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param b second string
19222297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @returns #TRUE if equal
19232297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
19242297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtondbus_bool_t
19252297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_equal (const DBusString *a,
19262297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                    const DBusString *b)
19272297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
19282297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *ap;
19292297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *bp;
19302297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *a_end;
19312297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const DBusRealString *real_a = (const DBusRealString*) a;
19322297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const DBusRealString *real_b = (const DBusRealString*) b;
19332297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_a);
19342297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_b);
19352297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
19362297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (real_a->len != real_b->len)
19372297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    return FALSE;
19382297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
19392297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  ap = real_a->str;
19402297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  bp = real_b->str;
19412297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  a_end = real_a->str + real_a->len;
19422297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  while (ap != a_end)
19432297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
19442297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      if (*ap != *bp)
19452297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        return FALSE;
19462297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
19472297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++ap;
19482297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++bp;
19492297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
19502297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
19512297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  return TRUE;
19522297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
19532297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
19542297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
19553791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * Tests two DBusString for equality up to the given length.
19563791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington *
19573791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @todo write a unit test
19583791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington *
1959b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo memcmp is probably faster
1960b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
19613791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param a first string
19623791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @param b second string
1963a7c05492537b149f67760ecb1958350900843173Anders Carlsson * @param len the lengh
19643791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington * @returns #TRUE if equal for the given number of bytes
19653791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington */
19663791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Penningtondbus_bool_t
19673791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington_dbus_string_equal_len (const DBusString *a,
19683791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington                        const DBusString *b,
19693791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington                        int               len)
19703791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington{
19713791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  const unsigned char *ap;
19723791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  const unsigned char *bp;
19733791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  const unsigned char *a_end;
19743791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  const DBusRealString *real_a = (const DBusRealString*) a;
19753791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  const DBusRealString *real_b = (const DBusRealString*) b;
19763791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_a);
19773791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_b);
19783791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
19793791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  if (real_a->len != real_b->len &&
19803791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      (real_a->len < len || real_b->len < len))
19813791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    return FALSE;
19823791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
19833791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  ap = real_a->str;
19843791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  bp = real_b->str;
19853791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  a_end = real_a->str + MIN (real_a->len, len);
19863791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  while (ap != a_end)
19873791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    {
19883791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      if (*ap != *bp)
19893791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington        return FALSE;
19903791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
19913791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      ++ap;
19923791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington      ++bp;
19933791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington    }
19943791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
19953791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington  return TRUE;
19963791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington}
19973791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington
19983791dcca16cb46b0ff7305beff75d1aa2645940cHavoc Pennington/**
19992297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Checks whether a string is equal to a C string.
20002297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
20012297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param a the string
20022297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param c_str the C string
20032297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @returns #TRUE if equal
20042297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
20052297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtondbus_bool_t
20062297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_equal_c_str (const DBusString *a,
20072297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                          const char       *c_str)
20082297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
20092297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *ap;
20102297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *bp;
20112297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *a_end;
20122297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const DBusRealString *real_a = (const DBusRealString*) a;
20132297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_a);
2014b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (c_str != NULL);
2015b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
20162297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  ap = real_a->str;
20172297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  bp = (const unsigned char*) c_str;
20182297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  a_end = real_a->str + real_a->len;
20192297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  while (ap != a_end && *bp)
20202297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
20212297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      if (*ap != *bp)
20222297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        return FALSE;
20232297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
20242297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++ap;
20252297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++bp;
20262297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
20272297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
2028b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (ap != a_end || *bp)
20292297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    return FALSE;
20302297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
20312297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  return TRUE;
20322297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
20332297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
20342f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington/**
20352f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington * Checks whether a string starts with the given C string.
20362f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington *
20372f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington * @param a the string
20382f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington * @param c_str the C string
20392f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington * @returns #TRUE if string starts with it
20402f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington */
20412f440457d5fe45afb732820da64a147157e2e82dHavoc Penningtondbus_bool_t
20422f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington_dbus_string_starts_with_c_str (const DBusString *a,
20432f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington                                const char       *c_str)
20442f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington{
20452f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  const unsigned char *ap;
20462f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  const unsigned char *bp;
20472f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  const unsigned char *a_end;
20482f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  const DBusRealString *real_a = (const DBusRealString*) a;
20492f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_a);
2050b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (c_str != NULL);
2051b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
20522f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  ap = real_a->str;
20532f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  bp = (const unsigned char*) c_str;
20542f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  a_end = real_a->str + real_a->len;
20552f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  while (ap != a_end && *bp)
20562f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington    {
20572f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington      if (*ap != *bp)
20582f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington        return FALSE;
20592f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington
20602f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington      ++ap;
20612f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington      ++bp;
20622f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington    }
20632f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington
20642f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  if (*bp == '\0')
20652f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington    return TRUE;
20662f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington  else
20672f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington    return FALSE;
20682f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington}
20692f440457d5fe45afb732820da64a147157e2e82dHavoc Pennington
207005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington/**
207105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington * Returns whether a string ends with the given suffix
207205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington *
2073b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo memcmp might make this faster.
2074b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
207505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington * @param a the string
207605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington * @param c_str the C-style string
207705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington * @returns #TRUE if the string ends with the suffix
207805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington */
207905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Penningtondbus_bool_t
208005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington_dbus_string_ends_with_c_str (const DBusString *a,
208105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington                              const char       *c_str)
208205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington{
208305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  const unsigned char *ap;
208405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  const unsigned char *bp;
208505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  const unsigned char *a_end;
2086b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  unsigned long c_str_len;
208705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  const DBusRealString *real_a = (const DBusRealString*) a;
208805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  DBUS_GENERIC_STRING_PREAMBLE (real_a);
2089b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (c_str != NULL);
2090b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
209105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  c_str_len = strlen (c_str);
2092b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (((unsigned long)real_a->len) < c_str_len)
209305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    return FALSE;
209405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
209505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  ap = real_a->str + (real_a->len - c_str_len);
209605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  bp = (const unsigned char*) c_str;
209705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  a_end = real_a->str + real_a->len;
209805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  while (ap != a_end)
209905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    {
210005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      if (*ap != *bp)
210105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington        return FALSE;
210205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
210305a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      ++ap;
210405a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington      ++bp;
210505a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington    }
210605a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
210705a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  _dbus_assert (*ap == '\0');
210805a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  _dbus_assert (*bp == '\0');
210905a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
211005a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington  return TRUE;
211105a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington}
211205a4ad6994919b352b5229d0b1b0a8ebebe2a42fHavoc Pennington
21132297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtonstatic const signed char base64_table[] = {
21142297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 0 */ 'A',
21152297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 1 */ 'B',
21162297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 2 */ 'C',
21172297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 3 */ 'D',
21182297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 4 */ 'E',
21192297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 5 */ 'F',
21202297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 6 */ 'G',
21212297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 7 */ 'H',
21222297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 8 */ 'I',
21232297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 9 */ 'J',
21242297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 10 */ 'K',
21252297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 11 */ 'L',
21262297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 12 */ 'M',
21272297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 13 */ 'N',
21282297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 14 */ 'O',
21292297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 15 */ 'P',
21302297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 16 */ 'Q',
21312297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 17 */ 'R',
21322297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 18 */ 'S',
21332297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 19 */ 'T',
21342297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 20 */ 'U',
21352297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 21 */ 'V',
21362297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 22 */ 'W',
21372297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 23 */ 'X',
21382297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 24 */ 'Y',
21392297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 25 */ 'Z',
21402297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 26 */ 'a',
21412297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 27 */ 'b',
21422297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 28 */ 'c',
21432297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 29 */ 'd',
21442297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 30 */ 'e',
21452297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 31 */ 'f',
21462297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 32 */ 'g',
21472297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 33 */ 'h',
21482297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 34 */ 'i',
21492297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 35 */ 'j',
21502297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 36 */ 'k',
21512297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 37 */ 'l',
21522297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 38 */ 'm',
21532297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 39 */ 'n',
21542297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 40 */ 'o',
21552297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 41 */ 'p',
21562297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 42 */ 'q',
21572297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 43 */ 'r',
21582297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 44 */ 's',
21592297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 45 */ 't',
21602297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 46 */ 'u',
21612297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 47 */ 'v',
21622297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 48 */ 'w',
21632297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 49 */ 'x',
21642297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 50 */ 'y',
21652297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 51 */ 'z',
21662297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 52 */ '0',
21672297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 53 */ '1',
21682297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 54 */ '2',
21692297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 55 */ '3',
21702297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 56 */ '4',
21712297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 57 */ '5',
21722297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 58 */ '6',
21732297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 59 */ '7',
21742297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 60 */ '8',
21752297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 61 */ '9',
21762297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 62 */ '+',
21772297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 63 */ '/'
21782297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington};
21792297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
21802297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/** The minimum char that's a valid char in Base64-encoded text */
21812297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington#define UNBASE64_MIN_CHAR (43)
21822297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/** The maximum char that's a valid char in Base64-encoded text */
21832297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington#define UNBASE64_MAX_CHAR (122)
21842297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/** Must subtract this from a char's integer value before offsetting
21852297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * into unbase64_table
21862297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
21872297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington#define UNBASE64_TABLE_OFFSET UNBASE64_MIN_CHAR
21882297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtonstatic const signed char unbase64_table[] = {
21892297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 43 + */ 62,
21902297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 44 , */ -1,
21912297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 45 - */ -1,
21922297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 46 . */ -1,
21932297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 47 / */ 63,
21942297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 48 0 */ 52,
21952297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 49 1 */ 53,
21962297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 50 2 */ 54,
21972297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 51 3 */ 55,
21982297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 52 4 */ 56,
21992297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 53 5 */ 57,
22002297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 54 6 */ 58,
22012297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 55 7 */ 59,
22022297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 56 8 */ 60,
22032297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 57 9 */ 61,
22042297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 58 : */ -1,
22052297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 59 ; */ -1,
22062297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 60 < */ -1,
22072297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 61 = */ -1,
22082297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 62 > */ -1,
22092297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 63 ? */ -1,
22102297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 64 @ */ -1,
22112297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 65 A */ 0,
22122297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 66 B */ 1,
22132297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 67 C */ 2,
22142297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 68 D */ 3,
22152297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 69 E */ 4,
22162297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 70 F */ 5,
22172297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 71 G */ 6,
22182297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 72 H */ 7,
22192297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 73 I */ 8,
22202297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 74 J */ 9,
22212297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 75 K */ 10,
22222297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 76 L */ 11,
22232297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 77 M */ 12,
22242297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 78 N */ 13,
22252297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 79 O */ 14,
22262297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 80 P */ 15,
22272297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 81 Q */ 16,
22282297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 82 R */ 17,
22292297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 83 S */ 18,
22302297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 84 T */ 19,
22312297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 85 U */ 20,
22322297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 86 V */ 21,
22332297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 87 W */ 22,
22342297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 88 X */ 23,
22352297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 89 Y */ 24,
22362297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 90 Z */ 25,
22372297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 91 [ */ -1,
22382297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 92 \ */ -1,
22392297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 93 ] */ -1,
22402297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 94 ^ */ -1,
22412297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 95 _ */ -1,
22422297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 96 ` */ -1,
22432297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 97 a */ 26,
22442297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 98 b */ 27,
22452297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 99 c */ 28,
22462297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 100 d */ 29,
22472297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 101 e */ 30,
22482297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 102 f */ 31,
22492297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 103 g */ 32,
22502297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 104 h */ 33,
22512297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 105 i */ 34,
22522297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 106 j */ 35,
22532297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 107 k */ 36,
22542297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 108 l */ 37,
22552297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 109 m */ 38,
22562297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 110 n */ 39,
22572297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 111 o */ 40,
22582297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 112 p */ 41,
22592297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 113 q */ 42,
22602297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 114 r */ 43,
22612297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 115 s */ 44,
22622297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 116 t */ 45,
22632297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 117 u */ 46,
22642297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 118 v */ 47,
22652297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 119 w */ 48,
22662297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 120 x */ 49,
22672297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 121 y */ 50,
22682297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* 122 z */ 51
22692297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington};
22702297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
22712297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
22722297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Encodes a string using Base64, as documented in RFC 2045.
22732297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
22742297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param source the string to encode
22752297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param start byte index to start encoding
22762297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param dest string where encoded data should be placed
22772297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param insert_at where to place encoded data
22782297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @returns #TRUE if encoding was successful, #FALSE if no memory etc.
22792297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
22802297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtondbus_bool_t
22812297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_base64_encode (const DBusString *source,
22822297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                            int               start,
22832297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                            DBusString       *dest,
22842297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                            int               insert_at)
22852297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
22862297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  int source_len;
2287b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  unsigned int dest_len; /* unsigned for overflow checks below */
22882297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *s;
22892297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  unsigned char *d;
22902297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *triplet_end;
22912297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const unsigned char *final_end;
22922297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
2293b3ef8b0e9bd2719d502c7f2e0cf829e151386162Havoc Pennington  _dbus_assert (source != dest);
22942297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
2295b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  /* For each 24 bits (3 bytes) of input, we have 4 bytes of
22962297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington   * output.
22972297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington   */
22982297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  source_len = real_source->len - start;
22992297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  dest_len = (source_len / 3) * 4;
23002297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (source_len % 3 != 0)
23012297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    dest_len += 4;
23022297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
2303b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (dest_len > (unsigned int) real_dest->max_length)
2304b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington    return FALSE;
2305b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
23062297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (source_len == 0)
23072297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    return TRUE;
23082297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23092297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!open_gap (dest_len, real_dest, insert_at))
23102297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    return FALSE;
23112297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23122297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  d = real_dest->str + insert_at;
23132297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  s = real_source->str + start;
23142297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  final_end = real_source->str + (start + source_len);
23152297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  triplet_end = final_end - (source_len % 3);
23162297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert (triplet_end <= final_end);
23172297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert ((final_end - triplet_end) < 3);
23182297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23192297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington#define ENCODE_64(v) (base64_table[ (unsigned char) (v) ])
23202297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington#define SIX_BITS_MASK (0x3f)
23212297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert (SIX_BITS_MASK < _DBUS_N_ELEMENTS (base64_table));
23222297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23232297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  while (s != triplet_end)
23242297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
23252297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      unsigned int triplet;
23262297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
2327def834b73b7e306790437b3d02613b14a94e6655Havoc Pennington      triplet = s[2] | (s[1] << 8) | (s[0] << 16);
2328def834b73b7e306790437b3d02613b14a94e6655Havoc Pennington
2329def834b73b7e306790437b3d02613b14a94e6655Havoc Pennington      /* Encode each 6 bits. */
23302297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23312297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      *d++ = ENCODE_64 (triplet >> 18);
23322297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      *d++ = ENCODE_64 ((triplet >> 12) & SIX_BITS_MASK);
23332297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      *d++ = ENCODE_64 ((triplet >> 6) & SIX_BITS_MASK);
23342297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      *d++ = ENCODE_64 (triplet & SIX_BITS_MASK);
23352297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23362297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      s += 3;
23372297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
23382297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23392297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  switch (final_end - triplet_end)
23402297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
23412297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    case 2:
23422297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      {
23432297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        unsigned int doublet;
23442297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
2345def834b73b7e306790437b3d02613b14a94e6655Havoc Pennington        doublet = s[1] | (s[0] << 8);
2346def834b73b7e306790437b3d02613b14a94e6655Havoc Pennington
23472297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        *d++ = ENCODE_64 (doublet >> 12);
23482297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        *d++ = ENCODE_64 ((doublet >> 6) & SIX_BITS_MASK);
23492297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        *d++ = ENCODE_64 (doublet & SIX_BITS_MASK);
23502297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        *d++ = '=';
23512297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      }
23522297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      break;
23532297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    case 1:
23542297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      {
23552297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        unsigned int singlet;
23562297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23572297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        singlet = s[0];
2358def834b73b7e306790437b3d02613b14a94e6655Havoc Pennington
23592297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        *d++ = ENCODE_64 ((singlet >> 6) & SIX_BITS_MASK);
23602297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        *d++ = ENCODE_64 (singlet & SIX_BITS_MASK);
23612297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        *d++ = '=';
23622297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        *d++ = '=';
23632297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      }
23642297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      break;
23652297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    case 0:
23662297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      break;
23672297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
23682297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23692297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert (d == (real_dest->str + (insert_at + dest_len)));
23702297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23712297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  return TRUE;
23722297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
23732297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
23742297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington/**
23752297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * Decodes a string from Base64, as documented in RFC 2045.
23762297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington *
2377b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo sort out the AUDIT comment in here. The case it mentions
2378b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * ("====" or "x===") is not allowed in correct base64, so need to
2379b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * decide what to do with that kind of input. Probably ignore it
2380b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * since we ignore any other junk seen.
2381b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
23822297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param source the string to decode
23832297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param start byte index to start decode
23842297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param dest string where decoded data should be placed
23852297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @param insert_at where to place decoded data
23862297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington * @returns #TRUE if decoding was successful, #FALSE if no memory etc.
23872297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington */
23882297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtondbus_bool_t
23892297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington_dbus_string_base64_decode (const DBusString *source,
23902297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                            int               start,
23912297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                            DBusString       *dest,
23922297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                            int               insert_at)
23932297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
23942297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  int source_len;
23952297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const char *s;
23962297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  const char *end;
23972297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBusString result;
23982297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  unsigned int triplet = 0;
23992297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  int sextet_count;
24002297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  int pad_count;
24012297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
2402b3ef8b0e9bd2719d502c7f2e0cf829e151386162Havoc Pennington  _dbus_assert (source != dest);
24032297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24042297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  source_len = real_source->len - start;
24052297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  s = real_source->str + start;
24062297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  end = real_source->str + source_len;
24072297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24082297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (source_len == 0)
24092297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    return TRUE;
24102297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
2411fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&result))
24122297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    return FALSE;
24132297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24142297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  pad_count = 0;
24152297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  sextet_count = 0;
24162297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  while (s != end)
24172297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
24182297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      /* The idea is to just skip anything that isn't
24192297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington       * a base64 char - it's allowed to have whitespace,
24202297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington       * newlines, etc. in here. We also ignore trailing
24212297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington       * base64 chars, though that's suspicious.
24222297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington       */
24232297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24242297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      if (*s >= UNBASE64_MIN_CHAR &&
24252297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington          *s <= UNBASE64_MAX_CHAR)
24262297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        {
24272297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington          if (*s == '=')
24282297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington            {
24292297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington              /* '=' is padding, doesn't represent additional data
24302297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington               * but does increment our count.
24312297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington               */
24322297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington              pad_count += 1;
24332297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington              sextet_count += 1;
24342297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington            }
24352297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington          else
24362297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington            {
24372297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington              int val;
24382297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24392297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington              val = unbase64_table[(*s) - UNBASE64_TABLE_OFFSET];
24402297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24412297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington              if (val >= 0)
24422297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                {
24432297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                  triplet <<= 6;
24442297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                  triplet |= (unsigned int) val;
24452297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                  sextet_count += 1;
24462297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                }
24472297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington            }
24482297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24492297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington          if (sextet_count == 4)
24502297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington            {
24512297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington              /* no pad = 3 bytes, 1 pad = 2 bytes, 2 pad = 1 byte */
2452b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
2453b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
2454b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington	      /* AUDIT: Comment doesn't mention 4 pad => 0,
2455b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington	       *         3 pad => 1 byte, though the code should
2456b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington	       *        work fine if those are the required outputs.
2457b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington	       *
2458b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington	       *        I assume that the spec requires dropping
2459b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington	       *        the top two bits of, say, ///= which is > 2
2460b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington	       *        bytes worth of bits. (Or otherwise, you couldn't
2461b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington	       *        actually represent 2 byte sequences.
2462b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington	       */
2463b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington
2464def834b73b7e306790437b3d02613b14a94e6655Havoc Pennington              if (pad_count < 1)
2465bf99381351b802fb3348a24037898222aae631e2Havoc Pennington                {
2466bf99381351b802fb3348a24037898222aae631e2Havoc Pennington                  if (!_dbus_string_append_byte (&result,
2467bf99381351b802fb3348a24037898222aae631e2Havoc Pennington                                                 triplet >> 16))
2468bf99381351b802fb3348a24037898222aae631e2Havoc Pennington                    goto failed;
2469bf99381351b802fb3348a24037898222aae631e2Havoc Pennington                }
2470def834b73b7e306790437b3d02613b14a94e6655Havoc Pennington
2471def834b73b7e306790437b3d02613b14a94e6655Havoc Pennington              if (pad_count < 2)
2472bf99381351b802fb3348a24037898222aae631e2Havoc Pennington                {
2473bf99381351b802fb3348a24037898222aae631e2Havoc Pennington                  if (!_dbus_string_append_byte (&result,
2474bf99381351b802fb3348a24037898222aae631e2Havoc Pennington                                                 (triplet >> 8) & 0xff))
2475bf99381351b802fb3348a24037898222aae631e2Havoc Pennington                    goto failed;
2476bf99381351b802fb3348a24037898222aae631e2Havoc Pennington                }
24772297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
2478bf99381351b802fb3348a24037898222aae631e2Havoc Pennington              if (!_dbus_string_append_byte (&result,
2479bf99381351b802fb3348a24037898222aae631e2Havoc Pennington                                             triplet & 0xff))
2480bf99381351b802fb3348a24037898222aae631e2Havoc Pennington                goto failed;
24812297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24822297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington              sextet_count = 0;
24832297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington              pad_count = 0;
24842297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington              triplet = 0;
24852297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington            }
24862297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington        }
24872297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24882297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      ++s;
24892297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
24902297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24912297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!_dbus_string_move (&result, 0, dest, insert_at))
24922297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
24932297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      _dbus_string_free (&result);
24942297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      return FALSE;
24952297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
24962297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24972297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_string_free (&result);
24982297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
24992297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  return TRUE;
2500bf99381351b802fb3348a24037898222aae631e2Havoc Pennington
2501bf99381351b802fb3348a24037898222aae631e2Havoc Pennington failed:
2502bf99381351b802fb3348a24037898222aae631e2Havoc Pennington  _dbus_string_free (&result);
2503bf99381351b802fb3348a24037898222aae631e2Havoc Pennington
2504bf99381351b802fb3348a24037898222aae631e2Havoc Pennington  return FALSE;
25052297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
25062297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
2507ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington/**
25082f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * Encodes a string in hex, the way MD5 and SHA-1 are usually
25092f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * encoded. (Each byte is two hex digits.)
25102f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington *
25112f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param source the string to encode
25122f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param start byte index to start encoding
25132f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param dest string where encoded data should be placed
25142f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param insert_at where to place encoded data
25152f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @returns #TRUE if encoding was successful, #FALSE if no memory etc.
25162f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington */
25172f38c959212d98e2194139daa9120fda37415b4fHavoc Penningtondbus_bool_t
25182f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington_dbus_string_hex_encode (const DBusString *source,
25192f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         int               start,
25202f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         DBusString       *dest,
25212f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         int               insert_at)
25222f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington{
25232f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  DBusString result;
25242f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  const char hexdigits[16] = {
25252f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
25262f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    'a', 'b', 'c', 'd', 'e', 'f'
25272f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  };
25282f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  const unsigned char *p;
25292f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  const unsigned char *end;
25302f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  dbus_bool_t retval;
25312f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25322f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  _dbus_assert (start <= _dbus_string_get_length (source));
25332f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
2534fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&result))
25352f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    return FALSE;
25362f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25372f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  retval = FALSE;
25382f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
2539fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  p = (const unsigned char*) _dbus_string_get_const_data (source);
25402f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  end = p + _dbus_string_get_length (source);
25412f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  p += start;
25422f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25432f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  while (p != end)
25442f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    {
25452f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      if (!_dbus_string_append_byte (&result,
25462f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                                     hexdigits[(*p >> 4)]))
25472f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        goto out;
25482f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25492f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      if (!_dbus_string_append_byte (&result,
25502f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                                     hexdigits[(*p & 0x0f)]))
25512f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        goto out;
25522f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25532f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      ++p;
25542f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    }
25552f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25562f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  if (!_dbus_string_move (&result, 0, dest, insert_at))
25572f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    goto out;
25582f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25592f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  retval = TRUE;
25602f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25612f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington out:
25622f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  _dbus_string_free (&result);
25632f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  return retval;
25642f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington}
25652f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25662f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington/**
25672f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * Decodes a string from hex encoding.
25682f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington *
25692f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param source the string to decode
25702f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param start byte index to start decode
25712f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param dest string where decoded data should be placed
25722f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @param insert_at where to place decoded data
25732f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * @returns #TRUE if decoding was successful, #FALSE if no memory etc.
25742f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington */
25752f38c959212d98e2194139daa9120fda37415b4fHavoc Penningtondbus_bool_t
25762f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington_dbus_string_hex_decode (const DBusString *source,
25772f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         int               start,
25782f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         DBusString       *dest,
25792f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         int               insert_at)
25802f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington{
25812f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  DBusString result;
25822f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  const unsigned char *p;
25832f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  const unsigned char *end;
25842f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  dbus_bool_t retval;
25852f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  dbus_bool_t high_bits;
25862f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25872f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  _dbus_assert (start <= _dbus_string_get_length (source));
25882f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
2589fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&result))
25902f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    return FALSE;
25912f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25922f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  retval = FALSE;
25932f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25942f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  high_bits = TRUE;
2595fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  p = (const unsigned char*) _dbus_string_get_const_data (source);
25962f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  end = p + _dbus_string_get_length (source);
25972f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  p += start;
25982f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
25992f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  while (p != end)
26002f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    {
26012f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      unsigned int val;
26022f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26032f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      switch (*p)
26042f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        {
26052f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '0':
26062f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 0;
26072f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26082f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '1':
26092f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 1;
26102f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26112f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '2':
26122f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 2;
26132f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26142f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '3':
26152f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 3;
26162f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26172f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '4':
26182f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 4;
26192f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26202f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '5':
26212f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 5;
26222f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26232f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '6':
26242f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 6;
26252f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26262f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '7':
26272f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 7;
26282f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26292f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '8':
26302f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 8;
26312f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26322f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case '9':
26332f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 9;
26342f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26352f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'a':
26362f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'A':
26372f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 10;
26382f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26392f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'b':
26402f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'B':
26412f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 11;
26422f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26432f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'c':
26442f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'C':
26452f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 12;
26462f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26472f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'd':
26482f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'D':
26492f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 13;
26502f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26512f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'e':
26522f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'E':
26532f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 14;
26542f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26552f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'f':
26562f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        case 'F':
26572f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 15;
26582f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          break;
26592f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        default:
26602f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          val = 0;
26612f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          _dbus_verbose ("invalid character '%c' in hex encoded text\n",
26622f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                         *p);
26632f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          goto out;
26642f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        }
26652f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26662f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      if (high_bits)
26672f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        {
26682f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          if (!_dbus_string_append_byte (&result,
26692f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                                         val << 4))
26702f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington            goto out;
26712f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        }
26722f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      else
26732f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        {
26742f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          int len;
26752f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          unsigned char b;
26762f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26772f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          len = _dbus_string_get_length (&result);
26782f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26792f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          b = _dbus_string_get_byte (&result, len - 1);
26802f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26812f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          b |= val;
26822f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26832f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington          _dbus_string_set_byte (&result, len - 1, b);
26842f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        }
26852f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26862f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      high_bits = !high_bits;
26872f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26882f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      ++p;
26892f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    }
26902f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26912f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  if (!_dbus_string_move (&result, 0, dest, insert_at))
26922f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    goto out;
26932f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26942f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  retval = TRUE;
26952f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
26962f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington out:
26972f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  _dbus_string_free (&result);
26982f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  return retval;
26992f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington}
27002f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
27012f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington/**
27022f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington * Checks that the given range of the string is valid ASCII with no
2703b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * nul bytes. If the given range is not entirely contained in the
2704b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * string, returns #FALSE.
2705ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington *
2706b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo this is inconsistent with most of DBusString in that
2707b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * it allows a start,len range that isn't in the string.
2708b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
2709ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * @param str the string
2710ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * @param start first byte index to check
2711ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * @param len number of bytes to check
2712ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington * @returns #TRUE if the byte range exists and is all valid ASCII
2713ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington */
2714ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Penningtondbus_bool_t
2715ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington_dbus_string_validate_ascii (const DBusString *str,
2716ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington                             int               start,
2717ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington                             int               len)
2718ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington{
2719ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  const unsigned char *s;
2720ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  const unsigned char *end;
2721ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
2722ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (start >= 0);
2723b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
2724ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (len >= 0);
2725ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
2726b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (len > real->len - start)
2727ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    return FALSE;
2728ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
2729ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  s = real->str + start;
2730ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  end = s + len;
2731ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  while (s != end)
2732ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    {
273375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (_DBUS_UNLIKELY (*s == '\0' ||
273475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington                          ((*s & ~0x7f) != 0)))
2735ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington        return FALSE;
2736ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
2737ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington      ++s;
2738ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    }
2739ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
2740ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  return TRUE;
2741ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington}
27422297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
27437ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington/**
2744b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * Checks that the given range of the string is valid UTF-8. If the
2745b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * given range is not entirely contained in the string, returns
2746b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * #FALSE. If the string contains any nul bytes in the given range,
2747021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington * returns #FALSE. If the start and start+len are not on character
2748021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington * boundaries, returns #FALSE.
2749b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
2750b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo this is inconsistent with most of DBusString in that
2751b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * it allows a start,len range that isn't in the string.
27527ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington *
27537ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param str the string
27547ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param start first byte index to check
27557ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param len number of bytes to check
27567ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @returns #TRUE if the byte range exists and is all valid UTF-8
27577ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington */
27587ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Penningtondbus_bool_t
27597ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington_dbus_string_validate_utf8  (const DBusString *str,
27607ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                             int               start,
27617ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                             int               len)
27627ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington{
2763021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  const unsigned char *p;
2764ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington  const unsigned char *end;
2765021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
2766021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  _dbus_assert (start >= 0);
2767021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  _dbus_assert (start <= real->len);
2768021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  _dbus_assert (len >= 0);
2769021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
277075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  /* we are doing _DBUS_UNLIKELY() here which might be
277175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   * dubious in a generic library like GLib, but in D-BUS
277275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   * we know we're validating messages and that it would
277375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   * only be evil/broken apps that would have invalid
277475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   * UTF-8. Also, this function seems to be a performance
277575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   * bottleneck in profiles.
277675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   */
277775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
277875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_DBUS_UNLIKELY (len > real->len - start))
2779021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington    return FALSE;
2780021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2781ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington  p = real->str + start;
2782ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington  end = p + len;
2783021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2784ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington  while (p < end)
2785021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington    {
2786021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington      int i, mask = 0, char_len;
2787021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington      dbus_unichar_t result;
2788021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington      unsigned char c = (unsigned char) *p;
2789021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2790021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington      UTF8_COMPUTE (c, mask, char_len);
2791e537e421ff4f092621fcd9f6b51526a017ad020cAnders Carlsson
279275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (_DBUS_UNLIKELY (char_len == -1))
2793021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington        break;
2794021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2795ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington      /* check that the expected number of bytes exists in the remaining length */
279675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (_DBUS_UNLIKELY ((end - p) < char_len))
2797021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington        break;
2798021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2799021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington      UTF8_GET (result, p, i, mask, char_len);
2800021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
280175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (_DBUS_UNLIKELY (UTF8_LENGTH (result) != char_len)) /* Check for overlong UTF-8 */
2802ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington        break;
2803021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
280475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (_DBUS_UNLIKELY (result == (dbus_unichar_t)-1))
2805021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington        break;
2806021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
280775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (_DBUS_UNLIKELY (!UNICODE_VALID (result)))
2808ebb57e719c32becd95a1efe3dd269c21e5a011b6Havoc Pennington        break;
2809021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2810021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington      p += char_len;
2811021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington    }
2812021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington
2813021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  /* See that we covered the entire length if a length was
2814021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington   * passed in
2815021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington   */
281675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_DBUS_UNLIKELY (p != end))
2817021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington    return FALSE;
2818021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington  else
2819021305e5686fc4847fec942922d2115ae5c9c2bbHavoc Pennington    return TRUE;
28207ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington}
28217ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
28227ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington/**
2823b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * Checks that the given range of the string is all nul bytes. If the
2824b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * given range is not entirely contained in the string, returns
2825b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * #FALSE.
2826b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington *
2827b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * @todo this is inconsistent with most of DBusString in that
2828b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington * it allows a start,len range that isn't in the string.
28297ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington *
28307ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param str the string
28317ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param start first byte index to check
28327ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @param len number of bytes to check
28337ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington * @returns #TRUE if the byte range exists and is all nul bytes
28347ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington */
28357ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Penningtondbus_bool_t
28367ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington_dbus_string_validate_nul (const DBusString *str,
28377ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                           int               start,
28387ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington                           int               len)
28397ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington{
28407ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  const unsigned char *s;
28417ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  const unsigned char *end;
28427ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
28437ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  _dbus_assert (start >= 0);
28447ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  _dbus_assert (len >= 0);
2845b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  _dbus_assert (start <= real->len);
28467ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
2847b7bc5ba7a323c6a17a442310c40585b67edff5d4Havoc Pennington  if (len > real->len - start)
28487ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    return FALSE;
28497ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
28507ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  s = real->str + start;
28517ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  end = s + len;
28527ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  while (s != end)
28537ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    {
285475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (_DBUS_UNLIKELY (*s != '\0'))
28557ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington        return FALSE;
28567ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington      ++s;
28577ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington    }
28587ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
28597ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington  return TRUE;
28607ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington}
28617ba714ad7fe8256edfaad7d9a0f09aeb9611ca44Havoc Pennington
286278e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington/**
28635fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington * Checks that the given range of the string is a valid object path
28645fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington * name in the D-BUS protocol. This includes a length restriction,
28655fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington * etc., see the specification. It does not validate UTF-8, that has
28665fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington * to be done separately for now.
28675fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington *
28685fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington * @todo this is inconsistent with most of DBusString in that
28695fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington * it allows a start,len range that isn't in the string.
28705fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington *
28715fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington * @todo change spec to disallow more things, such as spaces in the
28725fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington * path name
28735fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington *
28745fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington * @param str the string
28755fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington * @param start first byte index to check
28765fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington * @param len number of bytes to check
28775fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington * @returns #TRUE if the byte range exists and is a valid name
28785fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington */
28795fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Penningtondbus_bool_t
28805fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington_dbus_string_validate_path (const DBusString  *str,
28815fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington                            int                start,
28825fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington                            int                len)
28835fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington{
28845fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  const unsigned char *s;
28855fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  const unsigned char *end;
28865fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  const unsigned char *last_slash;
28875fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
28885fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
28895fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  _dbus_assert (start >= 0);
28905fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  _dbus_assert (len >= 0);
28915fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  _dbus_assert (start <= real->len);
28925fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
28935fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  if (len > real->len - start)
28945fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    return FALSE;
28955fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
28965fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  if (len > DBUS_MAXIMUM_NAME_LENGTH)
28975fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    return FALSE;
28985fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
28995fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  if (len == 0)
29005fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    return FALSE;
29015fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
29025fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  s = real->str + start;
29035fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  end = s + len;
29045fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
29055fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  if (*s != '/')
29065fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    return FALSE;
29075fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  last_slash = s;
29085fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  ++s;
29095fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
29105fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  while (s != end)
29115fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    {
29125fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington      if (*s == '/')
29135fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington        {
29145fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington          if ((s - last_slash) < 2)
29155fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington            return FALSE; /* no empty path components allowed */
29165fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
29175fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington          last_slash = s;
29185fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington        }
29195fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
29205fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington      ++s;
29215fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    }
29225fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
29235fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  if ((end - last_slash) < 2 &&
29245fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington      len > 1)
29255fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    return FALSE; /* trailing slash not allowed unless the string is "/" */
29265fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
29275fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  return TRUE;
29285fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington}
29295fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
293075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington#define VALID_INITIAL_NAME_CHARACTER(c)         \
293175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  ( ((c) >= 'A' && (c) <= 'Z') ||               \
293275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ((c) >= 'a' && (c) <= 'z') ||               \
293375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ((c) == '_') )
293475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
293575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington#define VALID_NAME_CHARACTER(c)                 \
293675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  ( ((c) >= '0' && (c) <= '9') ||               \
293775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ((c) >= 'A' && (c) <= 'Z') ||               \
293875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ((c) >= 'a' && (c) <= 'z') ||               \
293975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ((c) == '_') )
294075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
29415fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington/**
294295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * Checks that the given range of the string is a valid interface name
294375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * in the D-BUS protocol. This includes a length restriction and an
294475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * ASCII subset, see the specification.
2945b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington *
2946b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington * @todo this is inconsistent with most of DBusString in that
2947b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington * it allows a start,len range that isn't in the string.
2948b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington *
2949b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington * @param str the string
2950b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington * @param start first byte index to check
2951b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington * @param len number of bytes to check
2952b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington * @returns #TRUE if the byte range exists and is a valid name
2953b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington */
2954b3a3969897930eeda308113acbbb3f98069ee1abHavoc Penningtondbus_bool_t
295595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington_dbus_string_validate_interface (const DBusString  *str,
295695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                 int                start,
295795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                 int                len)
295875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington{
2959b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  const unsigned char *s;
2960b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  const unsigned char *end;
296175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  const unsigned char *iface;
296275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  const unsigned char *last_dot;
2963b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
2964b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
2965b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  _dbus_assert (start >= 0);
2966b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  _dbus_assert (len >= 0);
2967b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  _dbus_assert (start <= real->len);
2968b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
2969b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  if (len > real->len - start)
2970b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington    return FALSE;
2971b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
2972b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  if (len > DBUS_MAXIMUM_NAME_LENGTH)
2973b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington    return FALSE;
2974b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
2975b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  if (len == 0)
2976b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington    return FALSE;
2977b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
297875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  last_dot = NULL;
297975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  iface = real->str + start;
298075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  end = iface + len;
298175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  s = iface;
298275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
298375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  /* check special cases of first char so it doesn't have to be done
298475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   * in the loop. Note we know len > 0
298575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   */
298675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_DBUS_UNLIKELY (*s == '.')) /* disallow starting with a . */
298775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    return FALSE;
298875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
298975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    return FALSE;
299075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  else
299175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ++s;
299275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
2993b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  while (s != end)
2994b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington    {
2995b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington      if (*s == '.')
2996b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington        {
299775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          if (_DBUS_UNLIKELY ((s + 1) == end))
299875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington            return FALSE;
299975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*(s + 1))))
300075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington            return FALSE;
300175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          last_dot = s;
300275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          ++s; /* we just validated the next char, so skip two */
300375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        }
300475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
300575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        {
300675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          return FALSE;
3007b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington        }
3008b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
3009b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington      ++s;
3010b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington    }
3011b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
301275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_DBUS_UNLIKELY (last_dot == NULL))
3013b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington    return FALSE;
3014b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
3015b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  return TRUE;
3016b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington}
3017b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
301895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington/**
301995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * Checks that the given range of the string is a valid member name
302095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * in the D-BUS protocol. This includes a length restriction, etc.,
302175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * see the specification.
302295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington *
302395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @todo this is inconsistent with most of DBusString in that
302495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * it allows a start,len range that isn't in the string.
302595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington *
302695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @param str the string
302795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @param start first byte index to check
302895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @param len number of bytes to check
302995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @returns #TRUE if the byte range exists and is a valid name
303095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington */
303195717a938b237d12211935f6a7467ef610288fe5Havoc Penningtondbus_bool_t
303295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington_dbus_string_validate_member (const DBusString  *str,
303395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                              int                start,
303495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                              int                len)
303595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington{
303695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  const unsigned char *s;
303795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  const unsigned char *end;
303875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  const unsigned char *member;
303995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
304095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
304195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  _dbus_assert (start >= 0);
304295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  _dbus_assert (len >= 0);
304395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  _dbus_assert (start <= real->len);
304495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
304595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  if (len > real->len - start)
304695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    return FALSE;
304795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
304895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  if (len > DBUS_MAXIMUM_NAME_LENGTH)
304995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    return FALSE;
305095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
305195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  if (len == 0)
305295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    return FALSE;
305395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
305475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  member = real->str + start;
305575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  end = member + len;
305675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  s = member;
305775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
305875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  /* check special cases of first char so it doesn't have to be done
305975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   * in the loop. Note we know len > 0
306075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   */
306175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
306275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
306375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    return FALSE;
306475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  else
306575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ++s;
306675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
306795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  while (s != end)
306895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    {
306975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
307095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington        {
307175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          return FALSE;
307295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington        }
307395717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
307495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington      ++s;
307595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington    }
307695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
307795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  return TRUE;
307895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington}
307995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington
308095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington/**
308195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * Checks that the given range of the string is a valid error name
308295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * in the D-BUS protocol. This includes a length restriction, etc.,
308375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * see the specification.
308495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington *
308595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @todo this is inconsistent with most of DBusString in that
308695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * it allows a start,len range that isn't in the string.
308795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington *
308895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @param str the string
308995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @param start first byte index to check
309095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @param len number of bytes to check
309195717a938b237d12211935f6a7467ef610288fe5Havoc Pennington * @returns #TRUE if the byte range exists and is a valid name
309295717a938b237d12211935f6a7467ef610288fe5Havoc Pennington */
309395717a938b237d12211935f6a7467ef610288fe5Havoc Penningtondbus_bool_t
309495717a938b237d12211935f6a7467ef610288fe5Havoc Pennington_dbus_string_validate_error_name (const DBusString  *str,
309595717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                  int                start,
309695717a938b237d12211935f6a7467ef610288fe5Havoc Pennington                                  int                len)
309795717a938b237d12211935f6a7467ef610288fe5Havoc Pennington{
309895717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  /* Same restrictions as interface name at the moment */
309995717a938b237d12211935f6a7467ef610288fe5Havoc Pennington  return _dbus_string_validate_interface (str, start, len);
310095717a938b237d12211935f6a7467ef610288fe5Havoc Pennington}
3101b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
310275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington/* This assumes the first char exists and is ':' */
310375742242000e782719bc1656f0a7da72b059e88eHavoc Penningtonstatic dbus_bool_t
310475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington_dbus_string_validate_base_service (const DBusString  *str,
310575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington                                    int                start,
310675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington                                    int                len)
3107b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington{
3108b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  const unsigned char *s;
3109b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  const unsigned char *end;
311075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  const unsigned char *service;
3111b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
3112b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  DBUS_CONST_STRING_PREAMBLE (str);
3113b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  _dbus_assert (start >= 0);
3114b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  _dbus_assert (len >= 0);
3115b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  _dbus_assert (start <= real->len);
3116b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
3117b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  if (len > real->len - start)
3118b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington    return FALSE;
3119b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
3120b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  if (len > DBUS_MAXIMUM_NAME_LENGTH)
3121b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington    return FALSE;
3122b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
312375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  _dbus_assert (len > 0);
3124b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
312575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  service = real->str + start;
312675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  end = service + len;
312775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  _dbus_assert (*service == ':');
312875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  s = service + 1;
3129b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
3130b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington  while (s != end)
3131b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington    {
3132b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington      if (*s == '.')
3133b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington        {
313475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          if (_DBUS_UNLIKELY ((s + 1) == end))
313575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington            return FALSE;
313675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*(s + 1))))
313775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington            return FALSE;
313875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          ++s; /* we just validated the next char, so skip two */
313975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        }
314075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
314175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        {
314275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          return FALSE;
3143b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington        }
3144b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
3145b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington      ++s;
3146b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington    }
3147b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
314875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  return TRUE;
314975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington}
315075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
315175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington/**
315275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * Checks that the given range of the string is a valid service name
315375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * in the D-BUS protocol. This includes a length restriction, etc.,
315475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * see the specification.
315575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington *
315675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * @todo this is inconsistent with most of DBusString in that
315775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * it allows a start,len range that isn't in the string.
315875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington *
315975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * @param str the string
316075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * @param start first byte index to check
316175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * @param len number of bytes to check
316275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington * @returns #TRUE if the byte range exists and is a valid name
316375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington */
316475742242000e782719bc1656f0a7da72b059e88eHavoc Penningtondbus_bool_t
316575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington_dbus_string_validate_service (const DBusString  *str,
316675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington                               int                start,
316775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington                               int                len)
316875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington{
316975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_DBUS_UNLIKELY (len == 0))
317075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    return FALSE;
317175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_dbus_string_get_byte (str, start) == ':')
317275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    return _dbus_string_validate_base_service (str, start, len);
317375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  else
317475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    return _dbus_string_validate_interface (str, start, len);
3175b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington}
3176b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington
3177b3a3969897930eeda308113acbbb3f98069ee1abHavoc Pennington/**
317878e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington * Clears all allocated bytes in the string to zero.
317978e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington *
3180c21511c01ab56d75f3aa4643761e9fd096a7f8beHavoc Pennington * @param str the string
318178e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington */
318278e16e99e753175fa49e787eab256932eefaa03fHavoc Penningtonvoid
318378e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington_dbus_string_zero (DBusString *str)
318478e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington{
318578e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington  DBUS_STRING_PREAMBLE (str);
318678e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington
3187d3fb6f35716ff1d6f6644dea2043d539007811deHavoc Pennington  memset (real->str - real->align_offset, '\0', real->allocated);
318878e16e99e753175fa49e787eab256932eefaa03fHavoc Pennington}
3189d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/** @} */
3190d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3191d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#ifdef DBUS_BUILD_TESTS
3192d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#include "dbus-test.h"
3193d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#include <stdio.h>
3194d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3195d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtonstatic void
3196d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtontest_max_len (DBusString *str,
3197d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington              int         max_len)
3198d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
3199d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (max_len > 0)
3200d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
3201d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      if (!_dbus_string_set_length (str, max_len - 1))
3202d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        _dbus_assert_not_reached ("setting len to one less than max should have worked");
3203d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
3204d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3205d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_set_length (str, max_len))
3206d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("setting len to max len should have worked");
3207d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3208d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (_dbus_string_set_length (str, max_len + 1))
3209d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("setting len to one more than max len should not have worked");
3210d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3211d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_set_length (str, 0))
3212d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("setting len to zero should have worked");
3213d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
3214d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
32152297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtonstatic void
32162297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Penningtontest_base64_roundtrip (const unsigned char *data,
32172297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington                       int                  len)
32182297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington{
32192297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBusString orig;
32202297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBusString encoded;
32212297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  DBusString decoded;
32222297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
32232297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (len < 0)
32242297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    len = strlen (data);
32252297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
3226fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&orig))
32272297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("could not init string");
32282297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
3229fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&encoded))
32302297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("could not init string");
32312297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
3232fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&decoded))
32332297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("could not init string");
32342297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
32352297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!_dbus_string_append_len (&orig, data, len))
32362297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("couldn't append orig data");
32372297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
32382297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!_dbus_string_base64_encode (&orig, 0, &encoded, 0))
32392297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("could not encode");
32402297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
32412297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!_dbus_string_base64_decode (&encoded, 0, &decoded, 0))
32422297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("could not decode");
32432297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
32442297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!_dbus_string_equal (&orig, &decoded))
32452297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    {
32462297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      const char *s;
32472297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
32482297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
32492297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington              _dbus_string_get_length (&orig),
32502297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington              _dbus_string_get_length (&encoded),
32512297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington              _dbus_string_get_length (&decoded));
32522297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      printf ("Original: %s\n", data);
3253fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington      s = _dbus_string_get_const_data (&decoded);
32542297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      printf ("Decoded: %s\n", s);
32552297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington      _dbus_assert_not_reached ("original string not the same as string decoded from base64");
32562297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    }
32572297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
32582297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_string_free (&orig);
32592297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_string_free (&encoded);
32602297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_string_free (&decoded);
32612297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington}
32622297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
32632f38c959212d98e2194139daa9120fda37415b4fHavoc Penningtonstatic void
32642f38c959212d98e2194139daa9120fda37415b4fHavoc Penningtontest_hex_roundtrip (const unsigned char *data,
32652f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                    int                  len)
32662f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington{
32672f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  DBusString orig;
32682f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  DBusString encoded;
32692f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  DBusString decoded;
32702f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
32712f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  if (len < 0)
32722f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    len = strlen (data);
32732f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
3274fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&orig))
32752f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    _dbus_assert_not_reached ("could not init string");
32762f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
3277fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&encoded))
32782f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    _dbus_assert_not_reached ("could not init string");
32792f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
3280fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&decoded))
32812f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    _dbus_assert_not_reached ("could not init string");
32822f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
32832f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  if (!_dbus_string_append_len (&orig, data, len))
32842f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    _dbus_assert_not_reached ("couldn't append orig data");
32852f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
32862f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))
32872f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    _dbus_assert_not_reached ("could not encode");
32882f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
32892f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  if (!_dbus_string_hex_decode (&encoded, 0, &decoded, 0))
32902f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    _dbus_assert_not_reached ("could not decode");
32912f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
32922f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  if (!_dbus_string_equal (&orig, &decoded))
32932f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    {
32942f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      const char *s;
32952f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
32962f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
32972f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington              _dbus_string_get_length (&orig),
32982f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington              _dbus_string_get_length (&encoded),
32992f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington              _dbus_string_get_length (&decoded));
33002f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      printf ("Original: %s\n", data);
3301fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington      s = _dbus_string_get_const_data (&decoded);
33022f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      printf ("Decoded: %s\n", s);
33032f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      _dbus_assert_not_reached ("original string not the same as string decoded from base64");
33042f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    }
33052f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
33062f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  _dbus_string_free (&orig);
33072f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  _dbus_string_free (&encoded);
33082f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  _dbus_string_free (&decoded);
33092f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington}
33102f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
33112f38c959212d98e2194139daa9120fda37415b4fHavoc Penningtontypedef void (* TestRoundtripFunc) (const unsigned char *data,
33122f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington                                    int                  len);
33132f38c959212d98e2194139daa9120fda37415b4fHavoc Penningtonstatic void
33142f38c959212d98e2194139daa9120fda37415b4fHavoc Penningtontest_roundtrips (TestRoundtripFunc func)
33152f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington{
33162f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("Hello this is a string\n", -1);
33172f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("Hello this is a string\n1", -1);
33182f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("Hello this is a string\n12", -1);
33192f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("Hello this is a string\n123", -1);
33202f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("Hello this is a string\n1234", -1);
33212f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("Hello this is a string\n12345", -1);
33222f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("", 0);
33232f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("1", 1);
33242f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("12", 2);
33252f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("123", 3);
33262f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("1234", 4);
33272f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("12345", 5);
33282f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("", 1);
33292f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("1", 2);
33302f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("12", 3);
33312f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("123", 4);
33322f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("1234", 5);
33332f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  (* func) ("12345", 6);
33342f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  {
33352f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    unsigned char buf[512];
33362f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    int i;
33372f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
33382f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    i = 0;
33392f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    while (i < _DBUS_N_ELEMENTS (buf))
33402f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      {
33412f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        buf[i] = i;
33422f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        ++i;
33432f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      }
33442f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    i = 0;
33452f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington    while (i < _DBUS_N_ELEMENTS (buf))
33462f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      {
33472f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        (* func) (buf, i);
33482f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington        ++i;
33492f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington      }
33502f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  }
33512f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington}
33522f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
33532f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington
3354d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington/**
3355d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @ingroup DBusStringInternals
3356d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * Unit test for DBusString.
3357d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
3358d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @todo Need to write tests for _dbus_string_copy() and
3359d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * _dbus_string_move() moving to/from each of start/middle/end of a
33608a587f6415dd806ad3b77049a5dd47ae24540ae4Anders Carlsson * string. Also need tests for _dbus_string_move_len ()
3361d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington *
3362d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington * @returns #TRUE on success.
3363d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington */
3364d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Penningtondbus_bool_t
3365d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington_dbus_string_test (void)
3366d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington{
3367d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusString str;
3368d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  DBusString other;
3369d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  int i, end;
3370d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  long v;
3371d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  double d;
3372d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  int lens[] = { 0, 1, 2, 3, 4, 5, 10, 16, 17, 18, 25, 31, 32, 33, 34, 35, 63, 64, 65, 66, 67, 68, 69, 70, 71, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136 };
3373d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  char *s;
3374d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  dbus_unichar_t ch;
33755fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  const char *valid_paths[] = {
33765fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    "/",
33775fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    "/foo/bar",
33785fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    "/foo",
33795fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    "/foo/bar/baz"
33805fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  };
33815fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  const char *invalid_paths[] = {
33825fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    "bar",
33835fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    "bar/baz",
33845fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    "/foo/bar/",
33855fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    "/foo/"
33865fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    "foo/",
33875fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    "boo//blah",
33885fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    "//",
33895fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    "///",
33905fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    "foo///blah/",
339175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "Hello World",
339275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "",
339375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "   ",
339475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "foo bar"
339575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  };
339675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
339775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  const char *valid_interfaces[] = {
339875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "org.freedesktop.Foo",
339975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "Bar.Baz",
340075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "Blah.Blah.Blah.Blah.Blah",
340175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "a.b",
340275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "a.b.c.d.e.f.g",
340375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "a0.b1.c2.d3.e4.f5.g6",
340475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "abc123.foo27"
340575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  };
340675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  const char *invalid_interfaces[] = {
340775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ".",
340875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "",
340975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "..",
341075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ".Foo.Bar",
341175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "..Foo.Bar",
341275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "Foo.Bar.",
341375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "Foo.Bar..",
341475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "Foo",
341575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "9foo.bar.baz",
341675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "foo.bar..baz",
341775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "foo.bar...baz",
341875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "foo.bar.b..blah",
341975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":",
342075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":0-1",
342175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "10",
342275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":11.34324",
342375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "0.0.0",
342475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "0..0",
342575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "foo.Bar.%",
342675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "foo.Bar!!",
342775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "!Foo.bar.bz",
342875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "foo.$.blah",
342975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "",
343075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "   ",
343175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "foo bar"
343275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  };
343375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
343475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  const char *valid_base_services[] = {
343575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":0",
343675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":a",
343775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":",
343875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":.a",
343975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":.1",
344075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":0.1",
344175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":000.2222",
344275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":.blah",
344375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":abce.freedesktop.blah"
344475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  };
344575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  const char *invalid_base_services[] = {
344675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":-",
344775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":!",
344875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":0-10",
344975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":blah.",
345075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":blah.",
345175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":blah..org",
345275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":blah.org..",
345375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ":..blah.org",
345475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "",
345575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "   ",
345675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "foo bar"
345775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  };
345875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
345975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  const char *valid_members[] = {
346075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "Hello",
346175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "Bar",
346275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "foobar",
346375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "_foobar",
346475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "foo89"
346575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  };
346675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
346775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  const char *invalid_members[] = {
346875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "9Hello",
346975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "10",
347075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "1",
347175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "foo-bar",
347275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "blah.org",
347375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    ".blah",
347475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "blah.",
347575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "Hello.",
347675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "!foo",
347775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "",
347875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "   ",
347975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    "foo bar"
34805fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  };
3481d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3482d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  i = 0;
3483d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  while (i < _DBUS_N_ELEMENTS (lens))
3484d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
3485fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington      if (!_dbus_string_init (&str))
3486d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        _dbus_assert_not_reached ("failed to init string");
3487fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
3488fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington      set_max_length (&str, lens[i]);
3489d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3490d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      test_max_len (&str, lens[i]);
3491d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      _dbus_string_free (&str);
3492d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3493d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      ++i;
3494d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
3495d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3496d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* Test shortening and setting length */
3497d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  i = 0;
3498d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  while (i < _DBUS_N_ELEMENTS (lens))
3499d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
3500d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      int j;
3501d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3502fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington      if (!_dbus_string_init (&str))
3503d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        _dbus_assert_not_reached ("failed to init string");
3504fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington
3505fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington      set_max_length (&str, lens[i]);
3506d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3507d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      if (!_dbus_string_set_length (&str, lens[i]))
3508d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        _dbus_assert_not_reached ("failed to set string length");
3509d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3510d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      j = lens[i];
3511d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      while (j > 0)
3512d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        {
3513d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington          _dbus_assert (_dbus_string_get_length (&str) == j);
3514d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington          if (j > 0)
3515d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington            {
3516d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington              _dbus_string_shorten (&str, 1);
3517d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington              _dbus_assert (_dbus_string_get_length (&str) == (j - 1));
3518d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington            }
3519d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington          --j;
3520d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        }
3521d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3522d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      _dbus_string_free (&str);
3523d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3524d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      ++i;
3525d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
3526d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3527d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* Test appending data */
3528fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&str))
3529d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("failed to init string");
3530d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3531d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  i = 0;
3532d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  while (i < 10)
3533d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    {
3534d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      if (!_dbus_string_append (&str, "a"))
3535d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        _dbus_assert_not_reached ("failed to append string to string\n");
3536d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3537d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1);
3538d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3539d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      if (!_dbus_string_append_byte (&str, 'b'))
3540d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington        _dbus_assert_not_reached ("failed to append byte to string\n");
3541d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3542d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2);
3543d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3544d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington      ++i;
3545d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    }
3546d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3547d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_string_free (&str);
3548d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3549d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* Check steal_data */
3550d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3551fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&str))
3552d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("failed to init string");
3553d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3554d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_append (&str, "Hello World"))
3555d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("could not append to string");
3556d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3557d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  i = _dbus_string_get_length (&str);
3558d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3559d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_steal_data (&str, &s))
3560d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("failed to steal data");
3561d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3562d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (_dbus_string_get_length (&str) == 0);
3563d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (((int)strlen (s)) == i);
3564d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3565d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  dbus_free (s);
3566d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3567d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* Check move */
3568d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3569d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_append (&str, "Hello World"))
3570d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("could not append to string");
3571d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3572d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  i = _dbus_string_get_length (&str);
3573d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3574fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&other))
3575d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("could not init string");
3576d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3577d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_move (&str, 0, &other, 0))
3578d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("could not move");
3579d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3580d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (_dbus_string_get_length (&str) == 0);
3581d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (_dbus_string_get_length (&other) == i);
3582d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3583ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  if (!_dbus_string_append (&str, "Hello World"))
3584ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    _dbus_assert_not_reached ("could not append to string");
3585ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
3586ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other)))
3587ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    _dbus_assert_not_reached ("could not move");
3588ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
3589ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (_dbus_string_get_length (&str) == 0);
3590ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (_dbus_string_get_length (&other) == i * 2);
3591ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
3592ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    if (!_dbus_string_append (&str, "Hello World"))
3593ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    _dbus_assert_not_reached ("could not append to string");
3594ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
3595ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2))
3596ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    _dbus_assert_not_reached ("could not move");
3597ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
3598ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (_dbus_string_get_length (&str) == 0);
3599ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (_dbus_string_get_length (&other) == i * 3);
3600ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
3601d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_string_free (&other);
3602d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3603d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* Check copy */
3604d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3605d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_append (&str, "Hello World"))
3606d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("could not append to string");
3607d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3608d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  i = _dbus_string_get_length (&str);
3609d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3610fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&other))
3611d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("could not init string");
3612d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3613d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_copy (&str, 0, &other, 0))
3614d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("could not copy");
3615d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3616d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (_dbus_string_get_length (&str) == i);
3617d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (_dbus_string_get_length (&other) == i);
3618ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
3619ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other)))
3620ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    _dbus_assert_not_reached ("could not copy");
3621ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
3622ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (_dbus_string_get_length (&str) == i);
3623ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (_dbus_string_get_length (&other) == i * 2);
3624ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (_dbus_string_equal_c_str (&other,
3625ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington                                          "Hello WorldHello World"));
3626ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
3627ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2))
3628ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington    _dbus_assert_not_reached ("could not copy");
3629ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington
3630ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (_dbus_string_get_length (&str) == i);
3631ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (_dbus_string_get_length (&other) == i * 3);
3632ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington  _dbus_assert (_dbus_string_equal_c_str (&other,
3633ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington                                          "Hello WorldHello WorldHello World"));
3634d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3635d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_string_free (&str);
3636d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_string_free (&other);
3637d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
363850c25505f62786756519ef1e194883360eda82e0Havoc Pennington  /* Check replace */
363950c25505f62786756519ef1e194883360eda82e0Havoc Pennington
3640fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&str))
364150c25505f62786756519ef1e194883360eda82e0Havoc Pennington    _dbus_assert_not_reached ("failed to init string");
364250c25505f62786756519ef1e194883360eda82e0Havoc Pennington
364350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!_dbus_string_append (&str, "Hello World"))
364450c25505f62786756519ef1e194883360eda82e0Havoc Pennington    _dbus_assert_not_reached ("could not append to string");
364550c25505f62786756519ef1e194883360eda82e0Havoc Pennington
364650c25505f62786756519ef1e194883360eda82e0Havoc Pennington  i = _dbus_string_get_length (&str);
364750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
3648fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&other))
364950c25505f62786756519ef1e194883360eda82e0Havoc Pennington    _dbus_assert_not_reached ("could not init string");
365050c25505f62786756519ef1e194883360eda82e0Havoc Pennington
365150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
365250c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                 &other, 0, _dbus_string_get_length (&other)))
365350c25505f62786756519ef1e194883360eda82e0Havoc Pennington    _dbus_assert_not_reached ("could not replace");
365450c25505f62786756519ef1e194883360eda82e0Havoc Pennington
365550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (_dbus_string_get_length (&str) == i);
365650c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (_dbus_string_get_length (&other) == i);
365750c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World"));
365850c25505f62786756519ef1e194883360eda82e0Havoc Pennington
365950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
366050c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                 &other, 5, 1))
366150c25505f62786756519ef1e194883360eda82e0Havoc Pennington    _dbus_assert_not_reached ("could not replace center space");
366250c25505f62786756519ef1e194883360eda82e0Havoc Pennington
366350c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (_dbus_string_get_length (&str) == i);
366450c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
366550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (_dbus_string_equal_c_str (&other,
366650c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                          "HelloHello WorldWorld"));
366750c25505f62786756519ef1e194883360eda82e0Havoc Pennington
366850c25505f62786756519ef1e194883360eda82e0Havoc Pennington
366950c25505f62786756519ef1e194883360eda82e0Havoc Pennington  if (!_dbus_string_replace_len (&str, 1, 1,
367050c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                 &other,
367150c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                 _dbus_string_get_length (&other) - 1,
367250c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                 1))
367350c25505f62786756519ef1e194883360eda82e0Havoc Pennington    _dbus_assert_not_reached ("could not replace end character");
367450c25505f62786756519ef1e194883360eda82e0Havoc Pennington
367550c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (_dbus_string_get_length (&str) == i);
367650c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
367750c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_assert (_dbus_string_equal_c_str (&other,
367850c25505f62786756519ef1e194883360eda82e0Havoc Pennington                                          "HelloHello WorldWorle"));
367950c25505f62786756519ef1e194883360eda82e0Havoc Pennington
368050c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_string_free (&str);
368150c25505f62786756519ef1e194883360eda82e0Havoc Pennington  _dbus_string_free (&other);
368250c25505f62786756519ef1e194883360eda82e0Havoc Pennington
3683d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* Check append/get unichar */
3684d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3685fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&str))
3686d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("failed to init string");
3687d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3688d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  ch = 0;
3689d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_append_unichar (&str, 0xfffc))
3690d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("failed to append unichar");
3691d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3692d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_string_get_unichar (&str, 0, &ch, &i);
3693d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3694d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (ch == 0xfffc);
3695d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (i == _dbus_string_get_length (&str));
3696d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3697d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_string_free (&str);
3698e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
3699e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  /* Check insert/set/get byte */
3700e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
3701fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&str))
3702e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington    _dbus_assert_not_reached ("failed to init string");
3703e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
3704e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  if (!_dbus_string_append (&str, "Hello"))
3705e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington    _dbus_assert_not_reached ("failed to append Hello");
3706e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
3707e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H');
3708e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e');
3709e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l');
3710e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l');
3711e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o');
3712e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
3713e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_string_set_byte (&str, 1, 'q');
3714e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');
3715e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
371646c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  if (!_dbus_string_insert_bytes (&str, 0, 1, 255))
3717e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington    _dbus_assert_not_reached ("can't insert byte");
3718e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
371946c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z'))
3720e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington    _dbus_assert_not_reached ("can't insert byte");
3721e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
372246c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W'))
3723e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington    _dbus_assert_not_reached ("can't insert byte");
3724e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
3725e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
3726e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
3727e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
372846c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z');
372946c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z');
373046c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z');
373146c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q');
373246c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l');
373346c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l');
373446c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o');
373546c072e1136ca101aefd5fdae35c457899d55bbbMark McLoughlin  _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W');
3736e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington
3737e0ffb6eb1472e6766d79346e1fae418c129ef536Havoc Pennington  _dbus_string_free (&str);
3738d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3739d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  /* Check append/parse int/double */
3740d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3741fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&str))
3742d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("failed to init string");
3743d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3744d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_append_int (&str, 27))
3745d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("failed to append int");
3746d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3747d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  i = _dbus_string_get_length (&str);
3748d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3749d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_parse_int (&str, 0, &v, &end))
3750d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("failed to parse int");
3751d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3752d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (v == 27);
3753d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (end == i);
3754d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
375517fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington  _dbus_string_free (&str);
375617fbe2b702cdc880abd6cbe117e620b6432f42e0Havoc Pennington
3757fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&str))
3758d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("failed to init string");
3759d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3760d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_append_double (&str, 50.3))
3761d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("failed to append float");
3762d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3763d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  i = _dbus_string_get_length (&str);
3764d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3765d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  if (!_dbus_string_parse_double (&str, 0, &d, &end))
3766d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington    _dbus_assert_not_reached ("failed to parse float");
3767d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3768d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6));
3769d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_assert (end == i);
3770d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
3771d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  _dbus_string_free (&str);
3772d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
37732297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  /* Test find */
3774fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&str))
37752297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("failed to init string");
37762297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
37772297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!_dbus_string_append (&str, "Hello"))
37782297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("couldn't append to string");
37792297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
37802297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!_dbus_string_find (&str, 0, "He", &i))
37812297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("didn't find 'He'");
37822297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert (i == 0);
37832297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
3784c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington  if (!_dbus_string_find (&str, 0, "Hello", &i))
3785c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington    _dbus_assert_not_reached ("didn't find 'Hello'");
3786c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington  _dbus_assert (i == 0);
3787c9ea8fac502c6109713aa372c4c8cfafd0b86858Havoc Pennington
37882297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!_dbus_string_find (&str, 0, "ello", &i))
37892297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("didn't find 'ello'");
37902297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert (i == 1);
37912297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
37922297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!_dbus_string_find (&str, 0, "lo", &i))
37932297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("didn't find 'lo'");
37942297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert (i == 3);
37952297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
37962297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!_dbus_string_find (&str, 2, "lo", &i))
37972297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("didn't find 'lo'");
37982297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert (i == 3);
37992297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
38002297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (_dbus_string_find (&str, 4, "lo", &i))
38012297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("did find 'lo'");
38022297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
38032297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!_dbus_string_find (&str, 0, "l", &i))
38042297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("didn't find 'l'");
38052297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert (i == 2);
38062297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
38072297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!_dbus_string_find (&str, 0, "H", &i))
38082297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("didn't find 'H'");
38092297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert (i == 0);
38102297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
38112297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (!_dbus_string_find (&str, 0, "", &i))
38122297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("didn't find ''");
38132297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_assert (i == 0);
38142297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
38152297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (_dbus_string_find (&str, 0, "Hello!", NULL))
38162297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("Did find 'Hello!'");
38172297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
38182297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
38192297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("Did find 'Oh, Hello'");
38202297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
38212297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (_dbus_string_find (&str, 0, "ill", NULL))
38222297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("Did find 'ill'");
38232297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
38242297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  if (_dbus_string_find (&str, 0, "q", NULL))
38252297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington    _dbus_assert_not_reached ("Did find 'q'");
38265ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
38275ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  if (!_dbus_string_find_to (&str, 0, 2, "He", NULL))
38285ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    _dbus_assert_not_reached ("Didn't find 'He'");
38295ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson
38305ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson  if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL))
38315ebb5748c2a7587c734eeed9c66f2a1fc0635d09Anders Carlsson    _dbus_assert_not_reached ("Did find 'Hello'");
383294790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington
383394790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i))
383494790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington    _dbus_assert_not_reached ("Did not find 'H'");
383594790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  _dbus_assert (i == 0);
383694790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington
383794790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i))
383894790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington    _dbus_assert_not_reached ("Did not find 'o'");
383994790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  _dbus_assert (i == _dbus_string_get_length (&str) - 1);
384094790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington
384194790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i))
384294790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington    _dbus_assert_not_reached ("Did find 'o'");
384394790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  _dbus_assert (i == -1);
384494790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington
384594790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  if (_dbus_string_find_byte_backward (&str, 1, 'e', &i))
384694790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington    _dbus_assert_not_reached ("Did find 'e'");
384794790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  _dbus_assert (i == -1);
384894790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington
384994790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i))
385094790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington    _dbus_assert_not_reached ("Didn't find 'e'");
385194790fef4a846ef2bed9bf1825c4c2b0ca7b8566Havoc Pennington  _dbus_assert (i == 1);
38522297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
38532297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington  _dbus_string_free (&str);
38542297787455989c9ec47ea899b2ad6f3f6ef72c05Havoc Pennington
38552f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  /* Base 64 and Hex encoding */
38562f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  test_roundtrips (test_base64_roundtrip);
38572f38c959212d98e2194139daa9120fda37415b4fHavoc Pennington  test_roundtrips (test_hex_roundtrip);
38585fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
38595fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  /* Path validation */
38605fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  i = 0;
38615fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  while (i < (int) _DBUS_N_ELEMENTS (valid_paths))
38625fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    {
38635fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington      _dbus_string_init_const (&str, valid_paths[i]);
38645fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
38655fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington      if (!_dbus_string_validate_path (&str, 0,
38665fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington                                       _dbus_string_get_length (&str)))
38675fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington        {
38685fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington          _dbus_warn ("Path \"%s\" should have been valid\n", valid_paths[i]);
38695fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington          _dbus_assert_not_reached ("invalid path");
38705fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington        }
38715fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
38725fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington      ++i;
38735fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    }
38745fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
38755fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  i = 0;
38765fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington  while (i < (int) _DBUS_N_ELEMENTS (invalid_paths))
38775fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    {
38785fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington      _dbus_string_init_const (&str, invalid_paths[i]);
38795fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
38805fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington      if (_dbus_string_validate_path (&str, 0,
38815fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington                                      _dbus_string_get_length (&str)))
38825fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington        {
38835fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington          _dbus_warn ("Path \"%s\" should have been invalid\n", invalid_paths[i]);
38845fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington          _dbus_assert_not_reached ("valid path");
38855fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington        }
38865fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington
38875fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington      ++i;
38885fd1e389e1c1c12ad4a55c2af6abdc8e7a2f6d41Havoc Pennington    }
388975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
389075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  /* Interface validation */
389175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  i = 0;
389275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
389375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    {
389475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      _dbus_string_init_const (&str, valid_interfaces[i]);
389575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
389675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (!_dbus_string_validate_interface (&str, 0,
389775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington                                            _dbus_string_get_length (&str)))
389875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        {
389975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_warn ("Interface \"%s\" should have been valid\n", valid_interfaces[i]);
390075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_assert_not_reached ("invalid interface");
390175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        }
390275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
390375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      ++i;
390475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    }
390575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
390675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  i = 0;
390775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
390875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    {
390975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      _dbus_string_init_const (&str, invalid_interfaces[i]);
391075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
391175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (_dbus_string_validate_interface (&str, 0,
391275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington                                           _dbus_string_get_length (&str)))
391375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        {
391475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_warn ("Interface \"%s\" should have been invalid\n", invalid_interfaces[i]);
391575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_assert_not_reached ("valid interface");
391675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        }
391775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
391875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      ++i;
391975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    }
392075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
392175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  /* Service validation (check that valid interfaces are valid services,
392275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   * and invalid interfaces are invalid services except if they start with ':')
392375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   */
392475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  i = 0;
392575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
392675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    {
392775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      _dbus_string_init_const (&str, valid_interfaces[i]);
392875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
392975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (!_dbus_string_validate_service (&str, 0,
393075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington                                          _dbus_string_get_length (&str)))
393175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        {
393275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_warn ("Service \"%s\" should have been valid\n", valid_interfaces[i]);
393375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_assert_not_reached ("invalid service");
393475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        }
393575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
393675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      ++i;
393775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    }
393875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
393975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  i = 0;
394075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
394175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    {
394275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (invalid_interfaces[i][0] != ':')
394375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        {
394475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_string_init_const (&str, invalid_interfaces[i]);
394575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
394675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          if (_dbus_string_validate_service (&str, 0,
394775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington                                             _dbus_string_get_length (&str)))
394875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington            {
394975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington              _dbus_warn ("Service \"%s\" should have been invalid\n", invalid_interfaces[i]);
395075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington              _dbus_assert_not_reached ("valid service");
395175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington            }
395275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        }
395375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
395475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      ++i;
395575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    }
395675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
395775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  /* Base service validation */
395875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  i = 0;
395975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  while (i < (int) _DBUS_N_ELEMENTS (valid_base_services))
396075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    {
396175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      _dbus_string_init_const (&str, valid_base_services[i]);
396275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
396375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (!_dbus_string_validate_service (&str, 0,
396475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington                                          _dbus_string_get_length (&str)))
396575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        {
396675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_warn ("Service \"%s\" should have been valid\n", valid_base_services[i]);
396775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_assert_not_reached ("invalid base service");
396875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        }
396975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
397075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      ++i;
397175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    }
397275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
397375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  i = 0;
397475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  while (i < (int) _DBUS_N_ELEMENTS (invalid_base_services))
397575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    {
397675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      _dbus_string_init_const (&str, invalid_base_services[i]);
397775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
397875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (_dbus_string_validate_service (&str, 0,
397975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington                                         _dbus_string_get_length (&str)))
398075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        {
398175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_warn ("Service \"%s\" should have been invalid\n", invalid_base_services[i]);
398275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_assert_not_reached ("valid base service");
398375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        }
398475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
398575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      ++i;
398675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    }
398775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
398875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
398975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  /* Error name validation (currently identical to interfaces)
399075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington   */
399175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  i = 0;
399275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
399375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    {
399475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      _dbus_string_init_const (&str, valid_interfaces[i]);
399575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
399675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (!_dbus_string_validate_error_name (&str, 0,
399775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington                                             _dbus_string_get_length (&str)))
399875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        {
399975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_warn ("Error name \"%s\" should have been valid\n", valid_interfaces[i]);
400075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_assert_not_reached ("invalid error name");
400175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        }
400275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
400375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      ++i;
400475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    }
400575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
400675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  i = 0;
400775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
400875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    {
400975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (invalid_interfaces[i][0] != ':')
401075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        {
401175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_string_init_const (&str, invalid_interfaces[i]);
401275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
401375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          if (_dbus_string_validate_error_name (&str, 0,
401475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington                                                _dbus_string_get_length (&str)))
401575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington            {
401675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington              _dbus_warn ("Error name \"%s\" should have been invalid\n", invalid_interfaces[i]);
401775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington              _dbus_assert_not_reached ("valid error name");
401875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington            }
401975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        }
402075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
402175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      ++i;
402275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    }
402375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
402475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  /* Member validation */
402575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  i = 0;
402675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  while (i < (int) _DBUS_N_ELEMENTS (valid_members))
402775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    {
402875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      _dbus_string_init_const (&str, valid_members[i]);
402975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
403075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (!_dbus_string_validate_member (&str, 0,
403175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington                                         _dbus_string_get_length (&str)))
403275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        {
403375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_warn ("Member \"%s\" should have been valid\n", valid_members[i]);
403475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_assert_not_reached ("invalid member");
403575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        }
403675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
403775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      ++i;
403875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    }
403975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
404075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  i = 0;
404175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  while (i < (int) _DBUS_N_ELEMENTS (invalid_members))
404275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    {
404375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      _dbus_string_init_const (&str, invalid_members[i]);
404475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
404575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      if (_dbus_string_validate_member (&str, 0,
404675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington                                        _dbus_string_get_length (&str)))
404775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        {
404875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_warn ("Member \"%s\" should have been invalid\n", invalid_members[i]);
404975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington          _dbus_assert_not_reached ("valid member");
405075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington        }
405175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
405275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      ++i;
405375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    }
405475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
405575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  /* Validate claimed length longer than real length */
405675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  _dbus_string_init_const (&str, "abc.efg");
405775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_dbus_string_validate_service (&str, 0, 8))
405875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    _dbus_assert_not_reached ("validated too-long string");
405975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_dbus_string_validate_interface (&str, 0, 8))
406075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    _dbus_assert_not_reached ("validated too-long string");
406175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_dbus_string_validate_error_name (&str, 0, 8))
406275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    _dbus_assert_not_reached ("validated too-long string");
406375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
406475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  _dbus_string_init_const (&str, "abc");
406575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_dbus_string_validate_member (&str, 0, 4))
406675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    _dbus_assert_not_reached ("validated too-long string");
406775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
406875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  /* Validate string exceeding max name length */
406975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (!_dbus_string_init (&str))
407075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    _dbus_assert_not_reached ("no memory");
407175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
407275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
407375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    if (!_dbus_string_append (&str, "abc.def"))
407475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      _dbus_assert_not_reached ("no memory");
407575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
407675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_dbus_string_validate_service (&str, 0, _dbus_string_get_length (&str)))
407775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    _dbus_assert_not_reached ("validated overmax string");
407875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_dbus_string_validate_interface (&str, 0, _dbus_string_get_length (&str)))
407975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    _dbus_assert_not_reached ("validated overmax string");
408075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_dbus_string_validate_error_name (&str, 0, _dbus_string_get_length (&str)))
408175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    _dbus_assert_not_reached ("validated overmax string");
408275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
408375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  /* overlong member */
408475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  _dbus_string_set_length (&str, 0);
408575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
408675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    if (!_dbus_string_append (&str, "abc"))
408775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      _dbus_assert_not_reached ("no memory");
408875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
408975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_dbus_string_validate_member (&str, 0, _dbus_string_get_length (&str)))
409075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    _dbus_assert_not_reached ("validated overmax string");
409175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
409275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  /* overlong base service */
409375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  _dbus_string_set_length (&str, 0);
409475742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  _dbus_string_append (&str, ":");
409575742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
409675742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    if (!_dbus_string_append (&str, "abc"))
409775742242000e782719bc1656f0a7da72b059e88eHavoc Pennington      _dbus_assert_not_reached ("no memory");
409875742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
409975742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  if (_dbus_string_validate_service (&str, 0, _dbus_string_get_length (&str)))
410075742242000e782719bc1656f0a7da72b059e88eHavoc Pennington    _dbus_assert_not_reached ("validated overmax string");
410175742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
410275742242000e782719bc1656f0a7da72b059e88eHavoc Pennington  _dbus_string_free (&str);
410375742242000e782719bc1656f0a7da72b059e88eHavoc Pennington
4104d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington  return TRUE;
4105d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington}
4106d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington
4107d4b870e7f91b7018524f7b85dc00b90cc64453bfHavoc Pennington#endif /* DBUS_BUILD_TESTS */
4108