summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-message-builder.c
diff options
context:
space:
mode:
Diffstat (limited to 'dbus/dbus-message-builder.c')
-rw-r--r--dbus/dbus-message-builder.c1283
1 files changed, 0 insertions, 1283 deletions
diff --git a/dbus/dbus-message-builder.c b/dbus/dbus-message-builder.c
deleted file mode 100644
index 83b37aff..00000000
--- a/dbus/dbus-message-builder.c
+++ /dev/null
@@ -1,1283 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu" -*- */
-/* dbus-message-builder.c Build messages from text files for testing (internal to D-BUS implementation)
- *
- * Copyright (C) 2003, 2004 Red Hat, Inc.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include <config.h>
-
-#ifdef DBUS_BUILD_TESTS
-
-#include "dbus-message-builder.h"
-#include "dbus-hash.h"
-#include "dbus-internals.h"
-#include "dbus-marshal.h"
-
-/**
- * @defgroup DBusMessageBuilder code for loading test message data
- * @ingroup DBusInternals
- * @brief code for loading up test data for unit tests
- *
- * The code in here is used for unit testing, it loads
- * up message data from a description in a file.
- *
- * @{
- */
-
-/**
- * Saved length
- */
-typedef struct
-{
- DBusString name; /**< Name of the length */
- int start; /**< Calculate length since here */
- int length; /**< length to write */
- int offset; /**< where to write it into the data */
- int endian; /**< endianness to write with */
-} SavedLength;
-
-static void
-free_saved_length (void *data)
-{
- SavedLength *sl = data;
-
- if (sl == NULL)
- return; /* all hash free functions have to accept NULL */
-
- _dbus_string_free (&sl->name);
- dbus_free (sl);
-}
-
-static SavedLength*
-ensure_saved_length (DBusHashTable *hash,
- const DBusString *name)
-{
- SavedLength *sl;
- const char *s;
-
- s = _dbus_string_get_const_data (name);
-
- sl = _dbus_hash_table_lookup_string (hash, s);
- if (sl != NULL)
- return sl;
-
- sl = dbus_new0 (SavedLength, 1);
-
- if (!_dbus_string_init (&sl->name))
- {
- dbus_free (sl);
- return NULL;
- }
-
- if (!_dbus_string_copy (name, 0, &sl->name, 0))
- goto failed;
-
- s = _dbus_string_get_const_data (&sl->name);
-
- if (!_dbus_hash_table_insert_string (hash, (char*)s, sl))
- goto failed;
-
- sl->start = -1;
- sl->length = -1;
- sl->offset = -1;
- sl->endian = -1;
-
- return sl;
-
- failed:
- free_saved_length (sl);
- return NULL;
-}
-
-static dbus_bool_t
-save_start (DBusHashTable *hash,
- const DBusString *name,
- int start)
-{
- SavedLength *sl;
-
- sl = ensure_saved_length (hash, name);
-
- if (sl == NULL)
- return FALSE;
- else if (sl->start >= 0)
- {
- _dbus_warn ("Same START_LENGTH given twice\n");
- return FALSE;
- }
- else
- sl->start = start;
-
- return TRUE;
-}
-
-static dbus_bool_t
-save_length (DBusHashTable *hash,
- const DBusString *name,
- int length)
-{
- SavedLength *sl;
-
- sl = ensure_saved_length (hash, name);
-
- if (sl == NULL)
- return FALSE;
- else if (sl->length >= 0)
- {
- _dbus_warn ("Same END_LENGTH given twice\n");
- return FALSE;
- }
- else
- sl->length = length;
-
- return TRUE;
-}
-
-static dbus_bool_t
-save_offset (DBusHashTable *hash,
- const DBusString *name,
- int offset,
- int endian)
-{
- SavedLength *sl;
-
- sl = ensure_saved_length (hash, name);
-
- if (sl == NULL)
- return FALSE;
- else if (sl->offset >= 0)
- {
- _dbus_warn ("Same LENGTH given twice\n");
- return FALSE;
- }
- else
- {
- sl->offset = offset;
- sl->endian = endian;
- }
-
- return TRUE;
-}
-
-/** Saves the segment to delete in order to unalign the next item */
-#define SAVE_FOR_UNALIGN(str, boundary) \
- int align_pad_start = _dbus_string_get_length (str); \
- int align_pad_end = _DBUS_ALIGN_VALUE (align_pad_start, (boundary))
-
-/** Deletes the alignment padding */
-#define PERFORM_UNALIGN(str) \
- if (unalign) \
- { \
- _dbus_string_delete ((str), align_pad_start, \
- align_pad_end - align_pad_start); \
- unalign = FALSE; \
- }
-
-
-static dbus_bool_t
-append_quoted_string (DBusString *dest,
- const DBusString *quoted,
- int start_pos,
- int *new_pos)
-{
- dbus_bool_t in_quotes = FALSE;
- int i;
-
- /* FIXME: We might want to add escaping in case we want to put '
- * characters in our strings.
- */
-
- i = start_pos;
- while (i < _dbus_string_get_length (quoted))
- {
- unsigned char b;
-
- b = _dbus_string_get_byte (quoted, i);
-
- if (in_quotes)
- {
- if (b == '\'')
- break;
- else
- {
- if (!_dbus_string_append_byte (dest, b))
- return FALSE;
- }
- }
- else
- {
- if (b == '\'')
- in_quotes = TRUE;
- else if (b == ' ' || b == '\n' || b == '\t')
- break; /* end on whitespace if not quoted */
- else
- {
- if (!_dbus_string_append_byte (dest, b))
- return FALSE;
- }
- }
-
- ++i;
- }
-
- if (new_pos)
- *new_pos = i;
-
- if (!_dbus_string_append_byte (dest, '\0'))
- return FALSE;
- return TRUE;
-}
-
-static dbus_bool_t
-append_saved_length (DBusString *dest,
- DBusHashTable *length_hash,
- const DBusString *name,
- int offset,
- int endian)
-{
- if (!save_offset (length_hash, name,
- offset, endian))
- {
- _dbus_warn ("failed to save offset to LENGTH\n");
- return FALSE;
- }
-
- if (!_dbus_marshal_uint32 (dest, endian,
- -1))
- {
- _dbus_warn ("failed to append a length\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-static int
-message_type_from_string (const DBusString *str,
- int start)
-{
- const char *s;
-
- s = _dbus_string_get_const_data_len (str, start,
- _dbus_string_get_length (str) - start);
-
- if (strncmp (s, "method_call", strlen ("method_call")) == 0)
- return DBUS_MESSAGE_TYPE_METHOD_CALL;
- else if (strncmp (s, "method_return", strlen ("method_return")) == 0)
- return DBUS_MESSAGE_TYPE_METHOD_RETURN;
- else if (strncmp (s, "signal", strlen ("signal")) == 0)
- return DBUS_MESSAGE_TYPE_SIGNAL;
- else if (strncmp (s, "error", strlen ("error")) == 0)
- return DBUS_MESSAGE_TYPE_ERROR;
- else if (strncmp (s, "invalid", strlen ("invalid")) == 0)
- return DBUS_MESSAGE_TYPE_INVALID;
- else
- return -1;
-}
-
-static dbus_bool_t
-append_string_field (DBusString *dest,
- int endian,
- int field,
- int type,
- const char *value)
-{
- int len;
-
- if (!_dbus_string_append_byte (dest, field))
- {
- _dbus_warn ("couldn't append field name byte\n");
- return FALSE;
- }
-
- if (!_dbus_string_append_byte (dest, type))
- {
- _dbus_warn ("could not append typecode byte\n");
- return FALSE;
- }
-
- len = strlen (value);
-
- if (!_dbus_marshal_uint32 (dest, endian, len))
- {
- _dbus_warn ("couldn't append string length\n");
- return FALSE;
- }
-
- if (!_dbus_string_append (dest, value))
- {
- _dbus_warn ("couldn't append field value\n");
- return FALSE;
- }
-
- if (!_dbus_string_append_byte (dest, 0))
- {
- _dbus_warn ("couldn't append string nul term\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-#ifdef DBUS_BUILD_TESTS
-/**
- * Parses a basic type defined by type contained in a DBusString. The
- * end_return parameter may be #NULL if you aren't interested in it. The
- * type is parsed and stored in value_return. Return parameters are not
- * initialized if the function returns #FALSE.
- *
- * @param str the string
- * @param type the type of the basic type
- * @param start the byte index of the start of the type
- * @param value_return return location of the value or #NULL
- * @param end_return return location of the end of the type, or #NULL
- * @returns #TRUE on success
- */
-static dbus_bool_t
-_dbus_string_parse_basic_type (const DBusString *str,
- char type,
- int start,
- void *value,
- int *end_return)
-{
- int end = start;
-
- switch (type)
- {
- case DBUS_TYPE_BOOLEAN:
- {
- int len = _dbus_string_get_length (str) - start;
- if (len >= 5 && _dbus_string_find_to (str, start, start + 5, "false", NULL))
- {
- end += 5;
- *(unsigned char *) value = TRUE;
- }
- else if (len >= 4 && _dbus_string_find_to (str, start, start + 4, "true", NULL))
- {
- end += 4;
- *(unsigned char *) value = FALSE;
- }
- else
- _dbus_warn ("could not parse BOOLEAN\n");
- break;
- }
- case DBUS_TYPE_BYTE:
- {
- long val = 0;
-
- if (_dbus_string_get_byte (str, start) == '\'' &&
- _dbus_string_get_length (str) >= start + 4 &&
- _dbus_string_get_byte (str, start + 1) == '\\' &&
- _dbus_string_get_byte (str, start + 2) == '\'' &&
- _dbus_string_get_byte (str, start + 3) == '\'')
- {
- val = '\'';
- end += 4;
- }
- else if (_dbus_string_get_byte (str, start) == '\'' &&
- _dbus_string_get_length (str) >= start + 3 &&
- _dbus_string_get_byte (str, start + 2) == '\'')
- {
- val = _dbus_string_get_byte (str, start + 1);
- end += 3;
- }
- else
- {
- if (!_dbus_string_parse_int (str, start, &val, &end))
- _dbus_warn ("Failed to parse integer for BYTE\n");
- }
-
- if (val > 255)
- _dbus_warn ("A byte must be in range 0-255 not %ld\n", val);
-
- *(unsigned char *) value = val;
- break;
- }
- case DBUS_TYPE_INT32:
- {
- long val;
- if (_dbus_string_parse_int (str, start, &val, &end))
- *(dbus_int32_t *)value = val;
- break;
- }
- case DBUS_TYPE_UINT32:
- {
- unsigned long val;
- if (_dbus_string_parse_uint (str, start, &val, &end))
- *(dbus_uint32_t *)value = val;
- break;
- }
-#ifdef DBUS_HAVE_INT64
- case DBUS_TYPE_INT64:
- case DBUS_TYPE_UINT64:
- /* use stroll oull */
- _dbus_assert_not_reached ("string -> [u]int64 not supported yet");
- break;
-#endif /* DBUS_HAVE_INT64 */
- case DBUS_TYPE_DOUBLE:
- _dbus_string_parse_double (str, start, value, &end);
- break;
- default:
- _dbus_assert_not_reached ("not a basic type");
- break;
- }
- if (end_return)
- *end_return = end;
-
- return end != start;
-}
-#endif /* DBUS_BUILD_TESTS */
-
-static dbus_bool_t
-parse_basic_type (DBusString *src, char type,
- DBusString *dest, dbus_bool_t *unalign,
- int endian)
-{
- int align;
- int align_pad_start, align_pad_end;
- unsigned char data[16];
-
- switch (type)
- {
- case DBUS_TYPE_BYTE:
- align = 1;
- break;
- case DBUS_TYPE_BOOLEAN:
- case DBUS_TYPE_UINT32:
- case DBUS_TYPE_INT32:
- align = 4;
- break;
- case DBUS_TYPE_DOUBLE:
- align = 8;
- break;
- default:
- _dbus_assert_not_reached ("not a basic type");
- break;
- }
-
- align_pad_start = _dbus_string_get_length (dest);
- align_pad_end = _DBUS_ALIGN_VALUE (align_pad_start, align);
-
- _dbus_string_delete_first_word (src);
-
- if (!_dbus_string_parse_basic_type (src, type, 0, data, NULL))
- {
- _dbus_verbose ("failed to parse type '%c'", type);
- return FALSE;
- }
-
- if (!_dbus_marshal_basic_type (dest, type, data, endian))
- {
- _dbus_verbose ("failed to marshal type '%c'", type);
- return FALSE;
- }
-
- if (*unalign)
- {
- _dbus_string_delete (dest, align_pad_start,
- align_pad_end - align_pad_start);
- *unalign = FALSE;
- }
-
- return TRUE;
-}
-
-static dbus_bool_t
-parse_basic_array (DBusString *src, char type,
- DBusString *dest, dbus_bool_t *unalign,
- int endian)
-{
- int array_align, elem_size;
- int i, len, allocated;
- unsigned char *values, b;
- int values_offset;
- int align_pad_start, align_pad_end;
- dbus_bool_t retval = FALSE;
-
- array_align = 4; /* length */
- switch (type)
- {
- case DBUS_TYPE_BYTE:
- elem_size = 1;
- break;
- case DBUS_TYPE_BOOLEAN:
- case DBUS_TYPE_UINT32:
- case DBUS_TYPE_INT32:
- elem_size = 4;
- break;
- case DBUS_TYPE_DOUBLE:
- array_align = 8;
- elem_size = 8;
- break;
- default:
- _dbus_assert_not_reached ("not a basic type");
- break;
- }
-
- align_pad_start = _dbus_string_get_length (dest);
- align_pad_end = _DBUS_ALIGN_VALUE (align_pad_start, array_align);
-
- len = 0;
- allocated = 2;
- values = NULL;
- values_offset = 0;
-
- _dbus_string_delete_first_word (src);
- _dbus_string_skip_blank (src, 0, &i);
- b = _dbus_string_get_byte (src, i++);
-
- if (b != '{')
- goto failed;
-
- while (i < _dbus_string_get_length (src))
- {
- _dbus_string_skip_blank (src, i, &i);
-
- if (!values || len == allocated - 1)
- {
- allocated *= 2;
- values = dbus_realloc (values, allocated * elem_size);
- if (!values)
- {
- _dbus_warn ("could not allocate memory for '%c' ARRAY\n", type);
- goto failed;
- }
- }
-
- if (!_dbus_string_parse_basic_type (src, type, i, values + values_offset, &i))
- {
- _dbus_warn ("could not parse integer element %d of '%c' ARRAY\n", len, type);
- goto failed;
- }
-
- values_offset += elem_size;
- len++;
-
- _dbus_string_skip_blank (src, i, &i);
-
- b = _dbus_string_get_byte (src, i++);
-
- if (b == '}')
- break;
- else if (b != ',')
- goto failed;
- }
-
- if (!_dbus_marshal_basic_type_array (dest, type, values, len, endian))
- {
- _dbus_warn ("failed to append '%c' ARRAY\n", type);
- goto failed;
- }
-
- if (*unalign)
- {
- _dbus_string_delete (dest, align_pad_start,
- align_pad_end - align_pad_start);
- *unalign = FALSE;
- }
-
- retval = TRUE;
-
- failed:
- dbus_free (values);
- return retval;
-}
-
-static char
-lookup_basic_type (const DBusString *str, dbus_bool_t *is_array)
-{
- int i;
- char type = DBUS_TYPE_INVALID;
- static struct {
- const char *name;
- char type;
- } name_to_type[] = {
- { "BYTE", DBUS_TYPE_BYTE },
- { "BOOLEAN", DBUS_TYPE_BOOLEAN },
- { "INT32", DBUS_TYPE_INT32 },
- { "UINT32", DBUS_TYPE_UINT32 },
- { "DOUBLE", DBUS_TYPE_DOUBLE }
- };
-
- for (i = 0; i < _DBUS_N_ELEMENTS(name_to_type); i++)
- {
- const char *name = name_to_type[i].name;
- if (_dbus_string_starts_with_c_str (str, name))
- {
- int offset = strlen (name);
- type = name_to_type[i].type;
- if (is_array)
- *is_array = _dbus_string_find (str, offset, "_ARRAY", NULL);
- break;
- }
- }
-
- return type;
-}
-
-/**
- * Reads the given filename, which should be in "message description
- * language" (look at some examples), and builds up the message data
- * from it. The message data may be invalid, or valid.
- *
- * The parser isn't very strict, it's just a hack for test programs.
- *
- * The file format is:
- * @code
- * VALID_HEADER <type> normal header; byte order, type, padding, header len, body len, serial
- * REQUIRED_FIELDS add required fields with placeholder values
- * BIG_ENDIAN switch to big endian
- * LITTLE_ENDIAN switch to little endian
- * OPPOSITE_ENDIAN switch to opposite endian
- * ALIGN <N> aligns to the given value
- * UNALIGN skips alignment for the next marshal
- * BYTE <N> inserts the given integer in [0,255] or char in 'a' format
- * START_LENGTH <name> marks the start of a length to measure
- * END_LENGTH <name> records the length since START_LENGTH under the given name
- * (or if no START_LENGTH, absolute length)
- * LENGTH <name> inserts the saved length of the same name
- * CHOP <N> chops last N bytes off the data
- * HEADER_FIELD <fieldname> inserts a header field name byte
- * TYPE <typename> inserts a typecode byte
- * @endcode
- *
- * Following commands insert aligned data unless
- * preceded by "UNALIGN":
- * @code
- * INT32 <N> marshals an INT32
- * UINT32 <N> marshals a UINT32
- * INT64 <N> marshals an INT64
- * UINT64 <N> marshals a UINT64
- * DOUBLE <N> marshals a double
- * STRING 'Foo' marshals a string
- * OBJECT_PATH '/foo/bar' marshals an object path
- * BYTE_ARRAY { 'a', 3, 4, 5, 6} marshals a BYTE array
- * BOOLEAN_ARRAY { false, true, false} marshals a BOOLEAN array
- * INT32_ARRAY { 3, 4, 5, 6} marshals an INT32 array
- * UINT32_ARRAY { 3, 4, 5, 6} marshals an UINT32 array
- * DOUBLE_ARRAY { 1.0, 2.0, 3.0, 4.0} marshals a DOUBLE array
- * STRING_ARRAY { "foo", "bar", "gazonk"} marshals a STRING array
- * @endcode
- *
- * @todo add support for array types INT32_ARRAY { 3, 4, 5, 6 }
- * and so forth.
- *
- * @param dest the string to append the message data to
- * @param filename the filename to load
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_message_data_load (DBusString *dest,
- const DBusString *filename)
-{
- DBusString file;
- DBusError error;
- DBusString line;
- dbus_bool_t retval;
- int line_no;
- dbus_bool_t unalign;
- DBusHashTable *length_hash;
- int endian;
- DBusHashIter iter;
- char type;
- dbus_bool_t is_array;
-
- retval = FALSE;
- length_hash = NULL;
-
- if (!_dbus_string_init (&file))
- return FALSE;
-
- if (!_dbus_string_init (&line))
- {
- _dbus_string_free (&file);
- return FALSE;
- }
-
- _dbus_verbose ("Loading %s\n", _dbus_string_get_const_data (filename));
-
- dbus_error_init (&error);
- if (!_dbus_file_get_contents (&file, filename, &error))
- {
- _dbus_warn ("Getting contents of %s failed: %s\n",
- _dbus_string_get_const_data (filename), error.message);
- dbus_error_free (&error);
- goto out;
- }
-
- length_hash = _dbus_hash_table_new (DBUS_HASH_STRING,
- NULL,
- free_saved_length);
- if (length_hash == NULL)
- goto out;
-
- endian = DBUS_COMPILER_BYTE_ORDER;
- unalign = FALSE;
- line_no = 0;
- next_iteration:
- while (_dbus_string_pop_line (&file, &line))
- {
- dbus_bool_t just_set_unalign;
-
- just_set_unalign = FALSE;
- line_no += 1;
-
- _dbus_string_delete_leading_blanks (&line);
-
- if (_dbus_string_get_length (&line) == 0)
- {
- /* empty line */
- goto next_iteration;
- }
- else if (_dbus_string_starts_with_c_str (&line,
- "#"))
- {
- /* Ignore this comment */
- goto next_iteration;
- }
- else if (_dbus_string_starts_with_c_str (&line,
- "VALID_HEADER"))
- {
- int i;
- DBusString name;
- int message_type;
-
- if (_dbus_string_get_length (&line) < (int) strlen ("VALID_HEADER "))
- {
- _dbus_warn ("no args to VALID_HEADER\n");
- goto parse_failed;
- }
-
- if (!_dbus_string_append_byte (dest, endian))
- {
- _dbus_warn ("could not append endianness\n");
- goto parse_failed;
- }
-
- message_type = message_type_from_string (&line,
- strlen ("VALID_HEADER "));
- if (message_type < 0)
- {
- _dbus_warn ("VALID_HEADER not followed by space then known message type\n");
- goto parse_failed;
- }
-
- if (!_dbus_string_append_byte (dest, message_type))
- {
- _dbus_warn ("could not append message type\n");
- goto parse_failed;
- }
-
- i = 0;
- while (i < 2)
- {
- if (!_dbus_string_append_byte (dest, '\0'))
- {
- _dbus_warn ("could not append nul pad\n");
- goto parse_failed;
- }
- ++i;
- }
-
- _dbus_string_init_const (&name, "Header");
- if (!append_saved_length (dest, length_hash,
- &name, _dbus_string_get_length (dest),
- endian))
- goto parse_failed;
-
- _dbus_string_init_const (&name, "Body");
- if (!append_saved_length (dest, length_hash,
- &name, _dbus_string_get_length (dest),
- endian))
- goto parse_failed;
-
- /* client serial */
- if (!_dbus_marshal_uint32 (dest, endian, 1))
- {
- _dbus_warn ("couldn't append client serial\n");
- goto parse_failed;
- }
- }
- else if (_dbus_string_starts_with_c_str (&line,
- "REQUIRED_FIELDS"))
- {
- if (!append_string_field (dest, endian,
- DBUS_HEADER_FIELD_INTERFACE,
- DBUS_TYPE_STRING,
- "org.freedesktop.BlahBlahInterface"))
- goto parse_failed;
- if (!append_string_field (dest, endian,
- DBUS_HEADER_FIELD_MEMBER,
- DBUS_TYPE_STRING,
- "BlahBlahMethod"))
- goto parse_failed;
- if (!append_string_field (dest, endian,
- DBUS_HEADER_FIELD_PATH,
- DBUS_TYPE_OBJECT_PATH,
- "/blah/blah/path"))
- goto parse_failed;
-
- /* FIXME later we'll validate this, and then it will break
- * and the .message files will have to include the right thing
- */
- if (!append_string_field (dest, endian,
- DBUS_HEADER_FIELD_SIGNATURE,
- DBUS_TYPE_STRING,
- "iii"))
- goto parse_failed;
- }
- else if (_dbus_string_starts_with_c_str (&line,
- "BIG_ENDIAN"))
- {
- endian = DBUS_BIG_ENDIAN;
- }
- else if (_dbus_string_starts_with_c_str (&line,
- "LITTLE_ENDIAN"))
- {
- endian = DBUS_LITTLE_ENDIAN;
- }
- else if (_dbus_string_starts_with_c_str (&line,
- "OPPOSITE_ENDIAN"))
- {
- if (endian == DBUS_BIG_ENDIAN)
- endian = DBUS_LITTLE_ENDIAN;
- else
- endian = DBUS_BIG_ENDIAN;
- }
- else if (_dbus_string_starts_with_c_str (&line,
- "ALIGN"))
- {
- long val;
- int end;
- int orig_len;
-
- _dbus_string_delete_first_word (&line);
-
- if (!_dbus_string_parse_int (&line, 0, &val, &end))
- {
- _dbus_warn ("Failed to parse integer\n");
- goto parse_failed;
- }
-
- if (val > 8)
- {
- _dbus_warn ("Aligning to %ld boundary is crack\n",
- val);
- goto parse_failed;
- }
-
- orig_len = _dbus_string_get_length (dest);
-
- if (!_dbus_string_align_length (dest, val))
- goto parse_failed;
-
- if (_dbus_string_parse_int (&line, end, &val, NULL))
- {
- /* If there's an optional second int argument,
- * fill in align padding with that value
- */
- if (val < 0 || val > 255)
- {
- _dbus_warn ("can't fill align padding with %ld, must be a byte value\n", val);
- goto parse_failed;
- }
-
- end = orig_len;
- while (end < _dbus_string_get_length (dest))
- {
- _dbus_string_set_byte (dest, end, val);
- ++end;
- }
- }
- }
- else if (_dbus_string_starts_with_c_str (&line, "UNALIGN"))
- {
- unalign = TRUE;
- just_set_unalign = TRUE;
- }
- else if (_dbus_string_starts_with_c_str (&line, "CHOP"))
- {
- long val;
-
- /* FIXME if you CHOP the offset for a LENGTH
- * command, we segfault.
- */
-
- _dbus_string_delete_first_word (&line);
-
- if (!_dbus_string_parse_int (&line, 0, &val, NULL))
- {
- _dbus_warn ("Failed to parse integer to chop\n");
- goto parse_failed;
- }
-
- if (val > _dbus_string_get_length (dest))
- {
- _dbus_warn ("Trying to chop %ld bytes but we only have %d\n",
- val,
- _dbus_string_get_length (dest));
- goto parse_failed;
- }
-
- _dbus_string_shorten (dest, val);
- }
- else if (_dbus_string_starts_with_c_str (&line,
- "START_LENGTH"))
- {
- _dbus_string_delete_first_word (&line);
-
- if (!save_start (length_hash, &line,
- _dbus_string_get_length (dest)))
- {
- _dbus_warn ("failed to save length start\n");
- goto parse_failed;
- }
- }
- else if (_dbus_string_starts_with_c_str (&line,
- "END_LENGTH"))
- {
- _dbus_string_delete_first_word (&line);
-
- if (!save_length (length_hash, &line,
- _dbus_string_get_length (dest)))
- {
- _dbus_warn ("failed to save length end\n");
- goto parse_failed;
- }
- }
- else if (_dbus_string_starts_with_c_str (&line,
- "LENGTH"))
- {
- SAVE_FOR_UNALIGN (dest, 4);
-
- _dbus_string_delete_first_word (&line);
-
- if (!append_saved_length (dest, length_hash,
- &line,
- unalign ? align_pad_start : align_pad_end,
- endian))
- {
- _dbus_warn ("failed to add LENGTH\n");
- goto parse_failed;
- }
-
- PERFORM_UNALIGN (dest);
- }
- else if (_dbus_string_starts_with_c_str (&line,
- "HEADER_FIELD"))
- {
- int field;
-
- _dbus_string_delete_first_word (&line);
-
- if (_dbus_string_starts_with_c_str (&line, "INVALID"))
- field = DBUS_HEADER_FIELD_INVALID;
- else if (_dbus_string_starts_with_c_str (&line, "PATH"))
- field = DBUS_HEADER_FIELD_PATH;
- else if (_dbus_string_starts_with_c_str (&line, "INTERFACE"))
- field = DBUS_HEADER_FIELD_INTERFACE;
- else if (_dbus_string_starts_with_c_str (&line, "MEMBER"))
- field = DBUS_HEADER_FIELD_MEMBER;
- else if (_dbus_string_starts_with_c_str (&line, "ERROR_NAME"))
- field = DBUS_HEADER_FIELD_ERROR_NAME;
- else if (_dbus_string_starts_with_c_str (&line, "REPLY_SERIAL"))
- field = DBUS_HEADER_FIELD_REPLY_SERIAL;
- else if (_dbus_string_starts_with_c_str (&line, "DESTINATION"))
- field = DBUS_HEADER_FIELD_DESTINATION;
- else if (_dbus_string_starts_with_c_str (&line, "SENDER"))
- field = DBUS_HEADER_FIELD_SENDER;
- else if (_dbus_string_starts_with_c_str (&line, "SIGNATURE"))
- field = DBUS_HEADER_FIELD_SIGNATURE;
- else if (_dbus_string_starts_with_c_str (&line, "UNKNOWN"))
- field = 22; /* random unknown header field */
- else
- {
- _dbus_warn ("%s is not a valid header field name\n",
- _dbus_string_get_const_data (&line));
- goto parse_failed;
- }
-
- if (!_dbus_string_append_byte (dest, field))
- {
- _dbus_warn ("could not append header field name byte\n");
- goto parse_failed;
- }
- }
- else if (_dbus_string_starts_with_c_str (&line,
- "TYPE"))
- {
- int code;
-
- _dbus_string_delete_first_word (&line);
-
- if (_dbus_string_starts_with_c_str (&line, "INVALID"))
- code = DBUS_TYPE_INVALID;
- else if (_dbus_string_starts_with_c_str (&line, "NIL"))
- code = DBUS_TYPE_NIL;
- else if ((code = lookup_basic_type (&line, NULL)) != DBUS_TYPE_INVALID)
- ;
- else if (_dbus_string_starts_with_c_str (&line, "STRING"))
- code = DBUS_TYPE_STRING;
- else if (_dbus_string_starts_with_c_str (&line, "OBJECT_PATH"))
- code = DBUS_TYPE_OBJECT_PATH;
- else if (_dbus_string_starts_with_c_str (&line, "CUSTOM"))
- code = DBUS_TYPE_CUSTOM;
- else if (_dbus_string_starts_with_c_str (&line, "ARRAY"))
- code = DBUS_TYPE_ARRAY;
- else if (_dbus_string_starts_with_c_str (&line, "DICT"))
- code = DBUS_TYPE_DICT;
- else
- {
- _dbus_warn ("%s is not a valid type name\n", _dbus_string_get_const_data (&line));
- goto parse_failed;
- }
-
- if (!_dbus_string_append_byte (dest, code))
- {
- _dbus_warn ("could not append typecode byte\n");
- goto parse_failed;
- }
- }
- else if (_dbus_string_starts_with_c_str (&line,
- "STRING_ARRAY"))
- {
- SAVE_FOR_UNALIGN (dest, 4);
- int i, len, allocated;
- char **values;
- char *val;
- DBusString val_str;
- unsigned char b;
-
- allocated = 4;
- values = dbus_new (char *, allocated);
- if (!values)
- {
- _dbus_warn ("could not allocate memory for STRING_ARRAY\n");
- goto parse_failed;
- }
-
- len = 0;
-
- _dbus_string_delete_first_word (&line);
- _dbus_string_skip_blank (&line, 0, &i);
- b = _dbus_string_get_byte (&line, i++);
-
- if (b != '{')
- goto parse_failed;
-
- _dbus_string_init (&val_str);
- while (i < _dbus_string_get_length (&line))
- {
- _dbus_string_skip_blank (&line, i, &i);
-
- if (!append_quoted_string (&val_str, &line, i, &i))
- {
- _dbus_warn ("could not parse quoted string for STRING_ARRAY\n");
- goto parse_failed;
- }
- i++;
-
- if (!_dbus_string_steal_data (&val_str, &val))
- {
- _dbus_warn ("could not allocate memory for STRING_ARRAY string\n");
- goto parse_failed;
- }
-
- values[len++] = val;
- if (len == allocated)
- {
- allocated *= 2;
- values = dbus_realloc (values, allocated * sizeof (char *));
- if (!values)
- {
- _dbus_warn ("could not allocate memory for STRING_ARRAY\n");
- goto parse_failed;
- }
- }
-
- _dbus_string_skip_blank (&line, i, &i);
-
- b = _dbus_string_get_byte (&line, i++);
-
- if (b == '}')
- break;
- else if (b != ',')
- {
- _dbus_warn ("missing comma when parsing STRING_ARRAY\n");
- goto parse_failed;
- }
- }
- _dbus_string_free (&val_str);
-
- if (!_dbus_marshal_string_array (dest, endian, (const char **)values, len))
- {
- _dbus_warn ("failed to append STRING_ARRAY\n");
- goto parse_failed;
- }
-
- values[len] = NULL;
- dbus_free_string_array (values);
-
- PERFORM_UNALIGN (dest);
- }
- else if (_dbus_string_starts_with_c_str (&line,
- "STRING"))
- {
- SAVE_FOR_UNALIGN (dest, 4);
- int size_offset;
- int old_len;
-
- _dbus_string_delete_first_word (&line);
-
- size_offset = _dbus_string_get_length (dest);
- size_offset = _DBUS_ALIGN_VALUE (size_offset, 4);
- if (!_dbus_marshal_uint32 (dest, endian, 0))
- {
- _dbus_warn ("Failed to append string size\n");
- goto parse_failed;
- }
-
- old_len = _dbus_string_get_length (dest);
- if (!append_quoted_string (dest, &line, 0, NULL))
- {
- _dbus_warn ("Failed to append quoted string\n");
- goto parse_failed;
- }
-
- _dbus_marshal_set_uint32 (dest, size_offset,
- /* subtract 1 for nul */
- _dbus_string_get_length (dest) - old_len - 1,
- endian);
-
- PERFORM_UNALIGN (dest);
- }
- else if ((type = lookup_basic_type (&line, &is_array)) != DBUS_TYPE_INVALID)
- {
- if (is_array)
- {
- if (!parse_basic_array (&line, type, dest, &unalign, endian))
- goto parse_failed;
- }
- else
- {
- if (!parse_basic_type (&line, type, dest, &unalign, endian))
- goto parse_failed;
- }
- }
- else if (_dbus_string_starts_with_c_str (&line,
- "OBJECT_PATH"))
- {
- SAVE_FOR_UNALIGN (dest, 4);
- int size_offset;
- int old_len;
-
- _dbus_string_delete_first_word (&line);
-
- size_offset = _dbus_string_get_length (dest);
- size_offset = _DBUS_ALIGN_VALUE (size_offset, 4);
- if (!_dbus_marshal_uint32 (dest, endian, 0))
- {
- _dbus_warn ("Failed to append string size\n");
- goto parse_failed;
- }
-
- old_len = _dbus_string_get_length (dest);
- if (!append_quoted_string (dest, &line, 0, NULL))
- {
- _dbus_warn ("Failed to append quoted string\n");
- goto parse_failed;
- }
-
- _dbus_marshal_set_uint32 (dest, size_offset,
- /* subtract 1 for nul */
- _dbus_string_get_length (dest) - old_len - 1,
- endian);
-
- PERFORM_UNALIGN (dest);
- }
- else
- goto parse_failed;
-
- if (!just_set_unalign && unalign)
- {
- _dbus_warn ("UNALIGN prior to something that isn't aligned\n");
- goto parse_failed;
- }
-
- goto next_iteration; /* skip parse_failed */
-
- parse_failed:
- {
- _dbus_warn ("couldn't process line %d \"%s\"\n",
- line_no, _dbus_string_get_const_data (&line));
- goto out;
- }
- }
-
- _dbus_hash_iter_init (length_hash, &iter);
- while (_dbus_hash_iter_next (&iter))
- {
- SavedLength *sl = _dbus_hash_iter_get_value (&iter);
- const char *s;
-
- s = _dbus_string_get_const_data (&sl->name);
-
- if (sl->length < 0)
- {
- _dbus_warn ("Used LENGTH %s but never did END_LENGTH\n",
- s);
- goto out;
- }
- else if (sl->offset < 0)
- {
- _dbus_warn ("Did END_LENGTH %s but never used LENGTH\n",
- s);
- goto out;
- }
- else
- {
- if (sl->start < 0)
- sl->start = 0;
-
- _dbus_verbose ("Filling in length %s endian = %d offset = %d start = %d length = %d\n",
- s, sl->endian, sl->offset, sl->start, sl->length);
- _dbus_marshal_set_int32 (dest,
- sl->endian,
- sl->offset,
- sl->length - sl->start);
- }
-
- _dbus_hash_iter_remove_entry (&iter);
- }
-
- retval = TRUE;
-
- _dbus_verbose_bytes_of_string (dest, 0, _dbus_string_get_length (dest));
-
- out:
- if (length_hash != NULL)
- _dbus_hash_table_unref (length_hash);
-
- _dbus_string_free (&file);
- _dbus_string_free (&line);
- return retval;
-}
-
-/** @} */
-#endif /* DBUS_BUILD_TESTS */