blob: 4d42bb0b573ce8923443aba043f70af1fdbaa65f [file] [log] [blame] [edit]
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* dbus-string-util.c Would be in dbus-string.c, but not used in libdbus
*
* Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
* Copyright (C) 2006 Ralf Habacker <ralf.habacker@freenet.de>
*
* Licensed under the Academic Free License version 2.1
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <config.h>
#include "dbus-internals.h"
#include "dbus-string.h"
#define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
#include "dbus-string-private.h"
/**
* @addtogroup DBusString
* @{
*/
/**
* Returns whether a string ends with the given suffix
*
* @todo memcmp might make this faster.
*
* @param a the string
* @param c_str the C-style string
* @returns #TRUE if the string ends with the suffix
*/
dbus_bool_t
_dbus_string_ends_with_c_str (const DBusString *a,
const char *c_str)
{
const unsigned char *ap;
const unsigned char *bp;
const unsigned char *a_end;
unsigned long c_str_len;
const DBusRealString *real_a = (const DBusRealString*) a;
DBUS_GENERIC_STRING_PREAMBLE (real_a);
_dbus_assert (c_str != NULL);
c_str_len = strlen (c_str);
if (((unsigned long)real_a->len) < c_str_len)
return FALSE;
ap = real_a->str + (real_a->len - c_str_len);
bp = (const unsigned char*) c_str;
a_end = real_a->str + real_a->len;
while (ap != a_end)
{
if (*ap != *bp)
return FALSE;
++ap;
++bp;
}
_dbus_assert (*ap == '\0');
_dbus_assert (*bp == '\0');
return TRUE;
}
/**
* Find the given byte scanning backward from the given start.
* Sets *found to -1 if the byte is not found.
*
* @param str the string
* @param start the place to start scanning (will not find the byte at this point)
* @param byte the byte to find
* @param found return location for where it was found
* @returns #TRUE if found
*/
dbus_bool_t
_dbus_string_find_byte_backward (const DBusString *str,
int start,
unsigned char byte,
int *found)
{
int i;
DBUS_CONST_STRING_PREAMBLE (str);
_dbus_assert (start <= real->len);
_dbus_assert (start >= 0);
_dbus_assert (found != NULL);
i = start - 1;
while (i >= 0)
{
if (real->str[i] == byte)
break;
--i;
}
if (found)
*found = i;
return i >= 0;
}
/** @} */
#ifdef DBUS_BUILD_TESTS
#include "dbus-test.h"
#include <stdio.h>
static void
test_max_len (DBusString *str,
int max_len)
{
if (max_len > 0)
{
if (!_dbus_string_set_length (str, max_len - 1))
_dbus_assert_not_reached ("setting len to one less than max should have worked");
}
if (!_dbus_string_set_length (str, max_len))
_dbus_assert_not_reached ("setting len to max len should have worked");
if (_dbus_string_set_length (str, max_len + 1))
_dbus_assert_not_reached ("setting len to one more than max len should not have worked");
if (!_dbus_string_set_length (str, 0))
_dbus_assert_not_reached ("setting len to zero should have worked");
}
static void
test_hex_roundtrip (const unsigned char *data,
int len)
{
DBusString orig;
DBusString encoded;
DBusString decoded;
int end;
if (len < 0)
len = strlen (data);
if (!_dbus_string_init (&orig))
_dbus_assert_not_reached ("could not init string");
if (!_dbus_string_init (&encoded))
_dbus_assert_not_reached ("could not init string");
if (!_dbus_string_init (&decoded))
_dbus_assert_not_reached ("could not init string");
if (!_dbus_string_append_len (&orig, data, len))
_dbus_assert_not_reached ("couldn't append orig data");
if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))
_dbus_assert_not_reached ("could not encode");
if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0))
_dbus_assert_not_reached ("could not decode");
_dbus_assert (_dbus_string_get_length (&encoded) == end);
if (!_dbus_string_equal (&orig, &decoded))
{
const char *s;
printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
_dbus_string_get_length (&orig),
_dbus_string_get_length (&encoded),
_dbus_string_get_length (&decoded));
printf ("Original: %s\n", data);
s = _dbus_string_get_const_data (&decoded);
printf ("Decoded: %s\n", s);
_dbus_assert_not_reached ("original string not the same as string decoded from hex");
}
_dbus_string_free (&orig);
_dbus_string_free (&encoded);
_dbus_string_free (&decoded);
}
typedef void (* TestRoundtripFunc) (const unsigned char *data,
int len);
static void
test_roundtrips (TestRoundtripFunc func)
{
(* func) ("Hello this is a string\n", -1);
(* func) ("Hello this is a string\n1", -1);
(* func) ("Hello this is a string\n12", -1);
(* func) ("Hello this is a string\n123", -1);
(* func) ("Hello this is a string\n1234", -1);
(* func) ("Hello this is a string\n12345", -1);
(* func) ("", 0);
(* func) ("1", 1);
(* func) ("12", 2);
(* func) ("123", 3);
(* func) ("1234", 4);
(* func) ("12345", 5);
(* func) ("", 1);
(* func) ("1", 2);
(* func) ("12", 3);
(* func) ("123", 4);
(* func) ("1234", 5);
(* func) ("12345", 6);
{
unsigned char buf[512];
int i;
i = 0;
while (i < _DBUS_N_ELEMENTS (buf))
{
buf[i] = i;
++i;
}
i = 0;
while (i < _DBUS_N_ELEMENTS (buf))
{
(* func) (buf, i);
++i;
}
}
}
#ifdef DBUS_BUILD_TESTS
/* The max length thing is sort of a historical artifact
* from a feature that turned out to be dumb; perhaps
* we should purge it entirely. The problem with
* the feature is that it looks like memory allocation
* failure, but is not a transient or resolvable failure.
*/
static void
set_max_length (DBusString *str,
int max_length)
{
DBusRealString *real;
real = (DBusRealString*) str;
real->max_length = max_length;
}
#endif /* DBUS_BUILD_TESTS */
/**
* @ingroup DBusStringInternals
* Unit test for DBusString.
*
* @todo Need to write tests for _dbus_string_copy() and
* _dbus_string_move() moving to/from each of start/middle/end of a
* string. Also need tests for _dbus_string_move_len ()
*
* @returns #TRUE on success.
*/
dbus_bool_t
_dbus_string_test (void)
{
DBusString str;
DBusString other;
int i, end;
long v;
double d;
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 };
char *s;
dbus_unichar_t ch;
i = 0;
while (i < _DBUS_N_ELEMENTS (lens))
{
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("failed to init string");
set_max_length (&str, lens[i]);
test_max_len (&str, lens[i]);
_dbus_string_free (&str);
++i;
}
/* Test shortening and setting length */
i = 0;
while (i < _DBUS_N_ELEMENTS (lens))
{
int j;
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("failed to init string");
set_max_length (&str, lens[i]);
if (!_dbus_string_set_length (&str, lens[i]))
_dbus_assert_not_reached ("failed to set string length");
j = lens[i];
while (j > 0)
{
_dbus_assert (_dbus_string_get_length (&str) == j);
if (j > 0)
{
_dbus_string_shorten (&str, 1);
_dbus_assert (_dbus_string_get_length (&str) == (j - 1));
}
--j;
}
_dbus_string_free (&str);
++i;
}
/* Test equality */
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("oom");
if (!_dbus_string_append (&str, "Hello World"))
_dbus_assert_not_reached ("oom");
_dbus_string_init_const (&other, "H");
_dbus_assert (_dbus_string_equal_substring (&str, 0, 1, &other, 0));
_dbus_assert (_dbus_string_equal_substring (&str, 1, 0, &other, 1));
_dbus_string_init_const (&other, "Hello");
_dbus_assert (_dbus_string_equal_substring (&str, 0, 5, &other, 0));
_dbus_assert (_dbus_string_equal_substring (&str, 1, 4, &other, 1));
_dbus_assert (_dbus_string_equal_substring (&str, 2, 3, &other, 2));
_dbus_assert (_dbus_string_equal_substring (&str, 3, 2, &other, 3));
_dbus_assert (_dbus_string_equal_substring (&str, 4, 1, &other, 4));
_dbus_assert (_dbus_string_equal_substring (&str, 5, 0, &other, 5));
_dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 0));
_dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 1));
_dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 2));
_dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 3));
_dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 4));
_dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 5));
_dbus_string_init_const (&other, "World");
_dbus_assert (_dbus_string_equal_substring (&str, 6, 5, &other, 0));
_dbus_assert (_dbus_string_equal_substring (&str, 7, 4, &other, 1));
_dbus_assert (_dbus_string_equal_substring (&str, 8, 3, &other, 2));
_dbus_assert (_dbus_string_equal_substring (&str, 9, 2, &other, 3));
_dbus_assert (_dbus_string_equal_substring (&str, 10, 1, &other, 4));
_dbus_assert (_dbus_string_equal_substring (&str, 11, 0, &other, 5));
_dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 6));
_dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 7));
_dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 8));
_dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 9));
_dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 10));
_dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 11));
_dbus_string_free (&str);
/* Test appending data */
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("failed to init string");
i = 0;
while (i < 10)
{
if (!_dbus_string_append (&str, "a"))
_dbus_assert_not_reached ("failed to append string to string\n");
_dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1);
if (!_dbus_string_append_byte (&str, 'b'))
_dbus_assert_not_reached ("failed to append byte to string\n");
_dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2);
++i;
}
_dbus_string_free (&str);
/* Check steal_data */
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("failed to init string");
if (!_dbus_string_append (&str, "Hello World"))
_dbus_assert_not_reached ("could not append to string");
i = _dbus_string_get_length (&str);
if (!_dbus_string_steal_data (&str, &s))
_dbus_assert_not_reached ("failed to steal data");
_dbus_assert (_dbus_string_get_length (&str) == 0);
_dbus_assert (((int)strlen (s)) == i);
dbus_free (s);
/* Check move */
if (!_dbus_string_append (&str, "Hello World"))
_dbus_assert_not_reached ("could not append to string");
i = _dbus_string_get_length (&str);
if (!_dbus_string_init (&other))
_dbus_assert_not_reached ("could not init string");
if (!_dbus_string_move (&str, 0, &other, 0))
_dbus_assert_not_reached ("could not move");
_dbus_assert (_dbus_string_get_length (&str) == 0);
_dbus_assert (_dbus_string_get_length (&other) == i);
if (!_dbus_string_append (&str, "Hello World"))
_dbus_assert_not_reached ("could not append to string");
if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other)))
_dbus_assert_not_reached ("could not move");
_dbus_assert (_dbus_string_get_length (&str) == 0);
_dbus_assert (_dbus_string_get_length (&other) == i * 2);
if (!_dbus_string_append (&str, "Hello World"))
_dbus_assert_not_reached ("could not append to string");
if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2))
_dbus_assert_not_reached ("could not move");
_dbus_assert (_dbus_string_get_length (&str) == 0);
_dbus_assert (_dbus_string_get_length (&other) == i * 3);
_dbus_string_free (&other);
/* Check copy */
if (!_dbus_string_append (&str, "Hello World"))
_dbus_assert_not_reached ("could not append to string");
i = _dbus_string_get_length (&str);
if (!_dbus_string_init (&other))
_dbus_assert_not_reached ("could not init string");
if (!_dbus_string_copy (&str, 0, &other, 0))
_dbus_assert_not_reached ("could not copy");
_dbus_assert (_dbus_string_get_length (&str) == i);
_dbus_assert (_dbus_string_get_length (&other) == i);
if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other)))
_dbus_assert_not_reached ("could not copy");
_dbus_assert (_dbus_string_get_length (&str) == i);
_dbus_assert (_dbus_string_get_length (&other) == i * 2);
_dbus_assert (_dbus_string_equal_c_str (&other,
"Hello WorldHello World"));
if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2))
_dbus_assert_not_reached ("could not copy");
_dbus_assert (_dbus_string_get_length (&str) == i);
_dbus_assert (_dbus_string_get_length (&other) == i * 3);
_dbus_assert (_dbus_string_equal_c_str (&other,
"Hello WorldHello WorldHello World"));
_dbus_string_free (&str);
_dbus_string_free (&other);
/* Check replace */
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("failed to init string");
if (!_dbus_string_append (&str, "Hello World"))
_dbus_assert_not_reached ("could not append to string");
i = _dbus_string_get_length (&str);
if (!_dbus_string_init (&other))
_dbus_assert_not_reached ("could not init string");
if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
&other, 0, _dbus_string_get_length (&other)))
_dbus_assert_not_reached ("could not replace");
_dbus_assert (_dbus_string_get_length (&str) == i);
_dbus_assert (_dbus_string_get_length (&other) == i);
_dbus_assert (_dbus_string_equal_c_str (&other, "Hello World"));
if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str),
&other, 5, 1))
_dbus_assert_not_reached ("could not replace center space");
_dbus_assert (_dbus_string_get_length (&str) == i);
_dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
_dbus_assert (_dbus_string_equal_c_str (&other,
"HelloHello WorldWorld"));
if (!_dbus_string_replace_len (&str, 1, 1,
&other,
_dbus_string_get_length (&other) - 1,
1))
_dbus_assert_not_reached ("could not replace end character");
_dbus_assert (_dbus_string_get_length (&str) == i);
_dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1);
_dbus_assert (_dbus_string_equal_c_str (&other,
"HelloHello WorldWorle"));
_dbus_string_free (&str);
_dbus_string_free (&other);
/* Check append/get unichar */
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("failed to init string");
ch = 0;
if (!_dbus_string_append_unichar (&str, 0xfffc))
_dbus_assert_not_reached ("failed to append unichar");
_dbus_string_get_unichar (&str, 0, &ch, &i);
_dbus_assert (ch == 0xfffc);
_dbus_assert (i == _dbus_string_get_length (&str));
_dbus_string_free (&str);
/* Check insert/set/get byte */
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("failed to init string");
if (!_dbus_string_append (&str, "Hello"))
_dbus_assert_not_reached ("failed to append Hello");
_dbus_assert (_dbus_string_get_byte (&str, 0) == 'H');
_dbus_assert (_dbus_string_get_byte (&str, 1) == 'e');
_dbus_assert (_dbus_string_get_byte (&str, 2) == 'l');
_dbus_assert (_dbus_string_get_byte (&str, 3) == 'l');
_dbus_assert (_dbus_string_get_byte (&str, 4) == 'o');
_dbus_string_set_byte (&str, 1, 'q');
_dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');
if (!_dbus_string_insert_bytes (&str, 0, 1, 255))
_dbus_assert_not_reached ("can't insert byte");
if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z'))
_dbus_assert_not_reached ("can't insert byte");
if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W'))
_dbus_assert_not_reached ("can't insert byte");
_dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
_dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
_dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
_dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z');
_dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z');
_dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z');
_dbus_assert (_dbus_string_get_byte (&str, 6) == 'q');
_dbus_assert (_dbus_string_get_byte (&str, 7) == 'l');
_dbus_assert (_dbus_string_get_byte (&str, 8) == 'l');
_dbus_assert (_dbus_string_get_byte (&str, 9) == 'o');
_dbus_assert (_dbus_string_get_byte (&str, 10) == 'W');
_dbus_string_free (&str);
/* Check append/parse int/double */
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("failed to init string");
if (!_dbus_string_append_int (&str, 27))
_dbus_assert_not_reached ("failed to append int");
i = _dbus_string_get_length (&str);
if (!_dbus_string_parse_int (&str, 0, &v, &end))
_dbus_assert_not_reached ("failed to parse int");
_dbus_assert (v == 27);
_dbus_assert (end == i);
_dbus_string_free (&str);
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("failed to init string");
if (!_dbus_string_append_double (&str, 50.3))
_dbus_assert_not_reached ("failed to append float");
i = _dbus_string_get_length (&str);
if (!_dbus_string_parse_double (&str, 0, &d, &end))
_dbus_assert_not_reached ("failed to parse float");
_dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6));
_dbus_assert (end == i);
_dbus_string_free (&str);
/* Test find */
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("failed to init string");
if (!_dbus_string_append (&str, "Hello"))
_dbus_assert_not_reached ("couldn't append to string");
if (!_dbus_string_find (&str, 0, "He", &i))
_dbus_assert_not_reached ("didn't find 'He'");
_dbus_assert (i == 0);
if (!_dbus_string_find (&str, 0, "Hello", &i))
_dbus_assert_not_reached ("didn't find 'Hello'");
_dbus_assert (i == 0);
if (!_dbus_string_find (&str, 0, "ello", &i))
_dbus_assert_not_reached ("didn't find 'ello'");
_dbus_assert (i == 1);
if (!_dbus_string_find (&str, 0, "lo", &i))
_dbus_assert_not_reached ("didn't find 'lo'");
_dbus_assert (i == 3);
if (!_dbus_string_find (&str, 2, "lo", &i))
_dbus_assert_not_reached ("didn't find 'lo'");
_dbus_assert (i == 3);
if (_dbus_string_find (&str, 4, "lo", &i))
_dbus_assert_not_reached ("did find 'lo'");
if (!_dbus_string_find (&str, 0, "l", &i))
_dbus_assert_not_reached ("didn't find 'l'");
_dbus_assert (i == 2);
if (!_dbus_string_find (&str, 0, "H", &i))
_dbus_assert_not_reached ("didn't find 'H'");
_dbus_assert (i == 0);
if (!_dbus_string_find (&str, 0, "", &i))
_dbus_assert_not_reached ("didn't find ''");
_dbus_assert (i == 0);
if (_dbus_string_find (&str, 0, "Hello!", NULL))
_dbus_assert_not_reached ("Did find 'Hello!'");
if (_dbus_string_find (&str, 0, "Oh, Hello", NULL))
_dbus_assert_not_reached ("Did find 'Oh, Hello'");
if (_dbus_string_find (&str, 0, "ill", NULL))
_dbus_assert_not_reached ("Did find 'ill'");
if (_dbus_string_find (&str, 0, "q", NULL))
_dbus_assert_not_reached ("Did find 'q'");
if (!_dbus_string_find_to (&str, 0, 2, "He", NULL))
_dbus_assert_not_reached ("Didn't find 'He'");
if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL))
_dbus_assert_not_reached ("Did find 'Hello'");
if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i))
_dbus_assert_not_reached ("Did not find 'H'");
_dbus_assert (i == 0);
if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i))
_dbus_assert_not_reached ("Did not find 'o'");
_dbus_assert (i == _dbus_string_get_length (&str) - 1);
if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i))
_dbus_assert_not_reached ("Did find 'o'");
_dbus_assert (i == -1);
if (_dbus_string_find_byte_backward (&str, 1, 'e', &i))
_dbus_assert_not_reached ("Did find 'e'");
_dbus_assert (i == -1);
if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i))
_dbus_assert_not_reached ("Didn't find 'e'");
_dbus_assert (i == 1);
_dbus_string_free (&str);
/* Hex encoding */
_dbus_string_init_const (&str, "cafebabe, this is a bogus hex string");
if (!_dbus_string_init (&other))
_dbus_assert_not_reached ("could not init string");
if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0))
_dbus_assert_not_reached ("deccoded bogus hex string with no error");
_dbus_assert (end == 8);
_dbus_string_free (&other);
test_roundtrips (test_hex_roundtrip);
_dbus_string_free (&str);
{
int found, found_len;
_dbus_string_init_const (&str, "012\r\n567\n90");
if (!_dbus_string_find_eol (&str, 0, &found, &found_len) || found != 3 || found_len != 2)
_dbus_assert_not_reached ("Did not find '\\r\\n'");
if (found != 3 || found_len != 2)
_dbus_assert_not_reached ("invalid return values");
if (!_dbus_string_find_eol (&str, 5, &found, &found_len))
_dbus_assert_not_reached ("Did not find '\\n'");
if (found != 8 || found_len != 1)
_dbus_assert_not_reached ("invalid return values");
if (_dbus_string_find_eol (&str, 9, &found, &found_len))
_dbus_assert_not_reached ("Found not expected '\\n'");
else if (found != 11 || found_len != 0)
_dbus_assert_not_reached ("invalid return values '\\n'");
found = -1;
found_len = -1;
_dbus_string_init_const (&str, "");
if (_dbus_string_find_eol (&str, 0, &found, &found_len))
_dbus_assert_not_reached ("found an eol in an empty string");
_dbus_assert (found == 0);
_dbus_assert (found_len == 0);
found = -1;
found_len = -1;
_dbus_string_init_const (&str, "foobar");
if (_dbus_string_find_eol (&str, 0, &found, &found_len))
_dbus_assert_not_reached ("found eol in string that lacks one");
_dbus_assert (found == 6);
_dbus_assert (found_len == 0);
found = -1;
found_len = -1;
_dbus_string_init_const (&str, "foobar\n");
if (!_dbus_string_find_eol (&str, 0, &found, &found_len))
_dbus_assert_not_reached ("did not find eol in string that has one at end");
_dbus_assert (found == 6);
_dbus_assert (found_len == 1);
}
{
DBusString line;
#define FIRST_LINE "this is a line"
#define SECOND_LINE "this is a second line"
/* third line is empty */
#define THIRD_LINE ""
#define FOURTH_LINE "this is a fourth line"
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("no memory");
if (!_dbus_string_append (&str, FIRST_LINE "\n" SECOND_LINE "\r\n" THIRD_LINE "\n" FOURTH_LINE))
_dbus_assert_not_reached ("no memory");
if (!_dbus_string_init (&line))
_dbus_assert_not_reached ("no memory");
if (!_dbus_string_pop_line (&str, &line))
_dbus_assert_not_reached ("failed to pop first line");
_dbus_assert (_dbus_string_equal_c_str (&line, FIRST_LINE));
if (!_dbus_string_pop_line (&str, &line))
_dbus_assert_not_reached ("failed to pop second line");
_dbus_assert (_dbus_string_equal_c_str (&line, SECOND_LINE));
if (!_dbus_string_pop_line (&str, &line))
_dbus_assert_not_reached ("failed to pop third line");
_dbus_assert (_dbus_string_equal_c_str (&line, THIRD_LINE));
if (!_dbus_string_pop_line (&str, &line))
_dbus_assert_not_reached ("failed to pop fourth line");
_dbus_assert (_dbus_string_equal_c_str (&line, FOURTH_LINE));
_dbus_string_free (&str);
_dbus_string_free (&line);
}
{
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("no memory");
for (i = 0; i < 10000; i++)
if (!_dbus_string_append (&str, "abcdefghijklmnopqrstuvwxyz"))
_dbus_assert_not_reached ("no memory");
if (!_dbus_string_set_length (&str, 10))
_dbus_assert_not_reached ("failed to set length");
/* actually compact */
if (!_dbus_string_compact (&str, 2048))
_dbus_assert_not_reached ("failed to compact after set_length");
/* peek inside to make sure it worked */
if (((DBusRealString *)&str)->allocated > 30)
_dbus_assert_not_reached ("compacting string didn't do anything");
if (!_dbus_string_equal_c_str (&str, "abcdefghij"))
_dbus_assert_not_reached ("unexpected content after compact");
/* compact nothing */
if (!_dbus_string_compact (&str, 2048))
_dbus_assert_not_reached ("failed to compact 2nd time");
if (!_dbus_string_equal_c_str (&str, "abcdefghij"))
_dbus_assert_not_reached ("unexpected content after 2nd compact");
/* and make sure it still works...*/
if (!_dbus_string_append (&str, "123456"))
_dbus_assert_not_reached ("failed to append after compact");
if (!_dbus_string_equal_c_str (&str, "abcdefghij123456"))
_dbus_assert_not_reached ("unexpected content after append");
/* after growing automatically, this should do nothing */
if (!_dbus_string_compact (&str, 20000))
_dbus_assert_not_reached ("failed to compact after grow");
/* but this one will do something */
if (!_dbus_string_compact (&str, 0))
_dbus_assert_not_reached ("failed to compact after grow");
if (!_dbus_string_equal_c_str (&str, "abcdefghij123456"))
_dbus_assert_not_reached ("unexpected content");
if (!_dbus_string_append (&str, "!@#$%"))
_dbus_assert_not_reached ("failed to append after compact");
if (!_dbus_string_equal_c_str (&str, "abcdefghij123456!@#$%"))
_dbus_assert_not_reached ("unexpected content");
_dbus_string_free (&str);
}
{
const char two_strings[] = "one\ttwo";
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("no memory");
if (!_dbus_string_init (&other))
_dbus_assert_not_reached ("no memory");
if (!_dbus_string_append (&str, two_strings))
_dbus_assert_not_reached ("no memory");
if (!_dbus_string_split_on_byte (&str, '\t', &other))
_dbus_assert_not_reached ("no memory or delimiter not found");
if (strcmp (_dbus_string_get_data (&str), "one") != 0)
_dbus_assert_not_reached ("left side after split on tab is wrong");
if (strcmp (_dbus_string_get_data (&other), "two") != 0)
_dbus_assert_not_reached ("right side after split on tab is wrong");
_dbus_string_free (&str);
_dbus_string_free (&other);
}
{
const char upper_string[] = "TOUPPERSTRING";
const char lower_string[] = "toupperstring";
const char lower2_string[] = "toupperSTRING";
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("no memory");
if (!_dbus_string_append (&str, upper_string))
_dbus_assert_not_reached ("no memory");
_dbus_string_tolower_ascii (&str, 0, _dbus_string_get_length(&str));
if (!_dbus_string_equal_c_str (&str, lower_string))
_dbus_assert_not_reached ("_dbus_string_tolower_ascii failed");
_dbus_string_free (&str);
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("no memory");
if (!_dbus_string_append (&str, upper_string))
_dbus_assert_not_reached ("no memory");
_dbus_string_tolower_ascii (&str, 0, 7);
if (!_dbus_string_equal_c_str (&str, lower2_string))
_dbus_assert_not_reached ("_dbus_string_tolower_ascii failed in partial conversion");
_dbus_string_free (&str);
}
{
const char lower_string[] = "toupperstring";
const char upper_string[] = "TOUPPERSTRING";
const char upper2_string[] = "TOUPPERstring";
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("no memory");
if (!_dbus_string_append (&str, lower_string))
_dbus_assert_not_reached ("no memory");
_dbus_string_toupper_ascii (&str, 0, _dbus_string_get_length(&str));
if (!_dbus_string_equal_c_str (&str, upper_string))
_dbus_assert_not_reached ("_dbus_string_toupper_ascii failed");
_dbus_string_free (&str);
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("no memory");
if (!_dbus_string_append (&str, lower_string))
_dbus_assert_not_reached ("no memory");
_dbus_string_toupper_ascii (&str, 0, 7);
if (!_dbus_string_equal_c_str (&str, upper2_string))
_dbus_assert_not_reached ("_dbus_string_toupper_ascii failed in partial conversion");
_dbus_string_free (&str);
}
return TRUE;
}
#endif /* DBUS_BUILD_TESTS */