1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-message-builder.c Build messages from text files for testing (internal to D-BUS implementation)
4 * Copyright (C) 2003 Red Hat, Inc.
6 * Licensed under the Academic Free License version 1.2
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #ifdef DBUS_BUILD_TESTS
27 #include "dbus-message-builder.h"
28 #include "dbus-hash.h"
29 #include "dbus-internals.h"
30 #include "dbus-marshal.h"
33 * @defgroup DBusMessageBuilder code for loading test message data
34 * @ingroup DBusInternals
35 * @brief code for loading up test data for unit tests
37 * The code in here is used for unit testing, it loads
38 * up message data from a description in a file.
48 DBusString name; /**< Name of the length */
49 int start; /**< Calculate length since here */
50 int length; /**< length to write */
51 int offset; /**< where to write it into the data */
52 int endian; /**< endianness to write with */
56 free_saved_length (void *data)
58 SavedLength *sl = data;
61 return; /* all hash free functions have to accept NULL */
63 _dbus_string_free (&sl->name);
68 ensure_saved_length (DBusHashTable *hash,
69 const DBusString *name)
74 s = _dbus_string_get_const_data (name);
76 sl = _dbus_hash_table_lookup_string (hash, s);
80 sl = dbus_new0 (SavedLength, 1);
82 if (!_dbus_string_init (&sl->name))
88 if (!_dbus_string_copy (name, 0, &sl->name, 0))
91 s = _dbus_string_get_const_data (&sl->name);
93 if (!_dbus_hash_table_insert_string (hash, (char*)s, sl))
104 free_saved_length (sl);
109 save_start (DBusHashTable *hash,
110 const DBusString *name,
115 sl = ensure_saved_length (hash, name);
119 else if (sl->start >= 0)
121 _dbus_warn ("Same START_LENGTH given twice\n");
131 save_length (DBusHashTable *hash,
132 const DBusString *name,
137 sl = ensure_saved_length (hash, name);
141 else if (sl->length >= 0)
143 _dbus_warn ("Same END_LENGTH given twice\n");
153 save_offset (DBusHashTable *hash,
154 const DBusString *name,
160 sl = ensure_saved_length (hash, name);
164 else if (sl->offset >= 0)
166 _dbus_warn ("Same LENGTH given twice\n");
178 /** Saves the segment to delete in order to unalign the next item */
179 #define SAVE_FOR_UNALIGN(str, boundary) \
180 int align_pad_start = _dbus_string_get_length (str); \
181 int align_pad_end = _DBUS_ALIGN_VALUE (align_pad_start, (boundary))
183 /** Deletes the alignment padding */
184 #define PERFORM_UNALIGN(str) \
187 _dbus_string_delete ((str), align_pad_start, \
188 align_pad_end - align_pad_start); \
194 append_quoted_string (DBusString *dest,
195 const DBusString *quoted,
199 dbus_bool_t in_quotes = FALSE;
202 /* FIXME: We might want to add escaping in case we want to put '
203 * characters in our strings.
207 while (i < _dbus_string_get_length (quoted))
211 b = _dbus_string_get_byte (quoted, i);
219 if (!_dbus_string_append_byte (dest, b))
227 else if (b == ' ' || b == '\n' || b == '\t')
228 break; /* end on whitespace if not quoted */
231 if (!_dbus_string_append_byte (dest, b))
242 if (!_dbus_string_append_byte (dest, '\0'))
248 append_saved_length (DBusString *dest,
249 DBusHashTable *length_hash,
250 const DBusString *name,
254 if (!save_offset (length_hash, name,
257 _dbus_warn ("failed to save offset to LENGTH\n");
261 if (!_dbus_marshal_uint32 (dest, endian,
264 _dbus_warn ("failed to append a length\n");
272 message_type_from_string (const DBusString *str,
277 s = _dbus_string_get_const_data_len (str, start,
278 _dbus_string_get_length (str) - start);
280 if (strncmp (s, "method_call", strlen ("method_call")) == 0)
281 return DBUS_MESSAGE_TYPE_METHOD_CALL;
282 else if (strncmp (s, "method_return", strlen ("method_return")) == 0)
283 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
284 else if (strncmp (s, "signal", strlen ("signal")) == 0)
285 return DBUS_MESSAGE_TYPE_SIGNAL;
286 else if (strncmp (s, "error", strlen ("error")) == 0)
287 return DBUS_MESSAGE_TYPE_ERROR;
288 else if (strncmp (s, "invalid", strlen ("invalid")) == 0)
289 return DBUS_MESSAGE_TYPE_INVALID;
295 append_string_field (DBusString *dest,
303 if (!_dbus_string_append_byte (dest, field))
305 _dbus_warn ("couldn't append field name byte\n");
309 if (!_dbus_string_append_byte (dest, type))
311 _dbus_warn ("could not append typecode byte\n");
315 len = strlen (value);
317 if (!_dbus_marshal_uint32 (dest, endian, len))
319 _dbus_warn ("couldn't append string length\n");
323 if (!_dbus_string_append (dest, value))
325 _dbus_warn ("couldn't append field value\n");
329 if (!_dbus_string_append_byte (dest, 0))
331 _dbus_warn ("couldn't append string nul term\n");
339 * Reads the given filename, which should be in "message description
340 * language" (look at some examples), and builds up the message data
341 * from it. The message data may be invalid, or valid.
343 * The parser isn't very strict, it's just a hack for test programs.
345 * The file format is:
347 * VALID_HEADER <type> normal header; byte order, type, padding, header len, body len, serial
348 * REQUIRED_FIELDS add required fields with placeholder values
349 * BIG_ENDIAN switch to big endian
350 * LITTLE_ENDIAN switch to little endian
351 * OPPOSITE_ENDIAN switch to opposite endian
352 * ALIGN <N> aligns to the given value
353 * UNALIGN skips alignment for the next marshal
354 * BYTE <N> inserts the given integer in [0,255] or char in 'a' format
355 * START_LENGTH <name> marks the start of a length to measure
356 * END_LENGTH <name> records the length since START_LENGTH under the given name
357 * (or if no START_LENGTH, absolute length)
358 * LENGTH <name> inserts the saved length of the same name
359 * CHOP <N> chops last N bytes off the data
360 * HEADER_FIELD <fieldname> inserts a header field name byte
361 * TYPE <typename> inserts a typecode byte
364 * Following commands insert aligned data unless
365 * preceded by "UNALIGN":
367 * INT32 <N> marshals an INT32
368 * UINT32 <N> marshals a UINT32
369 * INT64 <N> marshals an INT64
370 * UINT64 <N> marshals a UINT64
371 * DOUBLE <N> marshals a double
372 * STRING 'Foo' marshals a string
373 * OBJECT_PATH '/foo/bar' marshals an object path
374 * BYTE_ARRAY { 'a', 3, 4, 5, 6} marshals a BYTE array
375 * BOOLEAN_ARRAY { false, true, false} marshals a BOOLEAN array
376 * INT32_ARRAY { 3, 4, 5, 6} marshals an INT32 array
377 * UINT32_ARRAY { 3, 4, 5, 6} marshals an UINT32 array
378 * DOUBLE_ARRAY { 1.0, 2.0, 3.0, 4.0} marshals a DOUBLE array
379 * STRING_ARRAY { "foo", "bar", "gazonk"} marshals a STRING array
382 * @todo add support for array types INT32_ARRAY { 3, 4, 5, 6 }
385 * @param dest the string to append the message data to
386 * @param filename the filename to load
387 * @returns #TRUE on success
390 _dbus_message_data_load (DBusString *dest,
391 const DBusString *filename)
399 DBusHashTable *length_hash;
406 if (!_dbus_string_init (&file))
409 if (!_dbus_string_init (&line))
411 _dbus_string_free (&file);
415 _dbus_verbose ("Loading %s\n", _dbus_string_get_const_data (filename));
417 dbus_error_init (&error);
418 if (!_dbus_file_get_contents (&file, filename, &error))
420 _dbus_warn ("Getting contents of %s failed: %s\n",
421 _dbus_string_get_const_data (filename), error.message);
422 dbus_error_free (&error);
426 length_hash = _dbus_hash_table_new (DBUS_HASH_STRING,
429 if (length_hash == NULL)
432 endian = DBUS_COMPILER_BYTE_ORDER;
436 while (_dbus_string_pop_line (&file, &line))
438 dbus_bool_t just_set_unalign;
440 just_set_unalign = FALSE;
443 _dbus_string_delete_leading_blanks (&line);
445 if (_dbus_string_get_length (&line) == 0)
450 else if (_dbus_string_starts_with_c_str (&line,
453 /* Ignore this comment */
456 else if (_dbus_string_starts_with_c_str (&line,
463 if (_dbus_string_get_length (&line) < (int) strlen ("VALID_HEADER "))
465 _dbus_warn ("no args to VALID_HEADER\n");
469 if (!_dbus_string_append_byte (dest, endian))
471 _dbus_warn ("could not append endianness\n");
475 message_type = message_type_from_string (&line,
476 strlen ("VALID_HEADER "));
477 if (message_type < 0)
479 _dbus_warn ("VALID_HEADER not followed by space then known message type\n");
483 if (!_dbus_string_append_byte (dest, message_type))
485 _dbus_warn ("could not append message type\n");
492 if (!_dbus_string_append_byte (dest, '\0'))
494 _dbus_warn ("could not append nul pad\n");
500 _dbus_string_init_const (&name, "Header");
501 if (!append_saved_length (dest, length_hash,
502 &name, _dbus_string_get_length (dest),
506 _dbus_string_init_const (&name, "Body");
507 if (!append_saved_length (dest, length_hash,
508 &name, _dbus_string_get_length (dest),
513 if (!_dbus_marshal_int32 (dest, endian, 1))
515 _dbus_warn ("couldn't append client serial\n");
519 else if (_dbus_string_starts_with_c_str (&line,
522 if (!append_string_field (dest, endian,
523 DBUS_HEADER_FIELD_INTERFACE,
525 "org.freedesktop.BlahBlahInterface"))
527 if (!append_string_field (dest, endian,
528 DBUS_HEADER_FIELD_MEMBER,
532 if (!append_string_field (dest, endian,
533 DBUS_HEADER_FIELD_PATH,
534 DBUS_TYPE_OBJECT_PATH,
538 else if (_dbus_string_starts_with_c_str (&line,
541 endian = DBUS_BIG_ENDIAN;
543 else if (_dbus_string_starts_with_c_str (&line,
546 endian = DBUS_LITTLE_ENDIAN;
548 else if (_dbus_string_starts_with_c_str (&line,
551 if (endian == DBUS_BIG_ENDIAN)
552 endian = DBUS_LITTLE_ENDIAN;
554 endian = DBUS_BIG_ENDIAN;
556 else if (_dbus_string_starts_with_c_str (&line,
563 _dbus_string_delete_first_word (&line);
565 if (!_dbus_string_parse_int (&line, 0, &val, &end))
567 _dbus_warn ("Failed to parse integer\n");
573 _dbus_warn ("Aligning to %ld boundary is crack\n",
578 orig_len = _dbus_string_get_length (dest);
580 if (!_dbus_string_align_length (dest, val))
583 if (_dbus_string_parse_int (&line, end, &val, NULL))
585 /* If there's an optional second int argument,
586 * fill in align padding with that value
588 if (val < 0 || val > 255)
590 _dbus_warn ("can't fill align padding with %ld, must be a byte value\n", val);
595 while (end < _dbus_string_get_length (dest))
597 _dbus_string_set_byte (dest, end, val);
602 else if (_dbus_string_starts_with_c_str (&line, "UNALIGN"))
605 just_set_unalign = TRUE;
607 else if (_dbus_string_starts_with_c_str (&line, "CHOP"))
611 /* FIXME if you CHOP the offset for a LENGTH
612 * command, we segfault.
615 _dbus_string_delete_first_word (&line);
617 if (!_dbus_string_parse_int (&line, 0, &val, NULL))
619 _dbus_warn ("Failed to parse integer to chop\n");
623 if (val > _dbus_string_get_length (dest))
625 _dbus_warn ("Trying to chop %ld bytes but we only have %d\n",
627 _dbus_string_get_length (dest));
631 _dbus_string_shorten (dest, val);
633 else if (_dbus_string_starts_with_c_str (&line,
636 _dbus_string_delete_first_word (&line);
638 if (!save_start (length_hash, &line,
639 _dbus_string_get_length (dest)))
641 _dbus_warn ("failed to save length start\n");
645 else if (_dbus_string_starts_with_c_str (&line,
648 _dbus_string_delete_first_word (&line);
650 if (!save_length (length_hash, &line,
651 _dbus_string_get_length (dest)))
653 _dbus_warn ("failed to save length end\n");
657 else if (_dbus_string_starts_with_c_str (&line,
660 SAVE_FOR_UNALIGN (dest, 4);
662 _dbus_string_delete_first_word (&line);
664 if (!append_saved_length (dest, length_hash,
666 unalign ? align_pad_start : align_pad_end,
669 _dbus_warn ("failed to add LENGTH\n");
673 PERFORM_UNALIGN (dest);
675 else if (_dbus_string_starts_with_c_str (&line,
680 _dbus_string_delete_first_word (&line);
682 if (_dbus_string_starts_with_c_str (&line, "INVALID"))
683 field = DBUS_HEADER_FIELD_INVALID;
684 else if (_dbus_string_starts_with_c_str (&line, "PATH"))
685 field = DBUS_HEADER_FIELD_PATH;
686 else if (_dbus_string_starts_with_c_str (&line, "INTERFACE"))
687 field = DBUS_HEADER_FIELD_INTERFACE;
688 else if (_dbus_string_starts_with_c_str (&line, "MEMBER"))
689 field = DBUS_HEADER_FIELD_MEMBER;
690 else if (_dbus_string_starts_with_c_str (&line, "ERROR_NAME"))
691 field = DBUS_HEADER_FIELD_ERROR_NAME;
692 else if (_dbus_string_starts_with_c_str (&line, "REPLY_SERIAL"))
693 field = DBUS_HEADER_FIELD_REPLY_SERIAL;
694 else if (_dbus_string_starts_with_c_str (&line, "SERVICE"))
695 field = DBUS_HEADER_FIELD_SERVICE;
696 else if (_dbus_string_starts_with_c_str (&line, "SENDER_SERVICE"))
697 field = DBUS_HEADER_FIELD_SENDER_SERVICE;
698 else if (_dbus_string_starts_with_c_str (&line, "UNKNOWN"))
699 field = 22; /* random unknown header field */
702 _dbus_warn ("%s is not a valid header field name\n",
703 _dbus_string_get_const_data (&line));
707 if (!_dbus_string_append_byte (dest, field))
709 _dbus_warn ("could not append header field name byte\n");
713 else if (_dbus_string_starts_with_c_str (&line,
718 _dbus_string_delete_first_word (&line);
720 if (_dbus_string_starts_with_c_str (&line, "INVALID"))
721 code = DBUS_TYPE_INVALID;
722 else if (_dbus_string_starts_with_c_str (&line, "NIL"))
723 code = DBUS_TYPE_NIL;
724 else if (_dbus_string_starts_with_c_str (&line, "BYTE"))
725 code = DBUS_TYPE_BYTE;
726 else if (_dbus_string_starts_with_c_str (&line, "BOOLEAN"))
727 code = DBUS_TYPE_BOOLEAN;
728 else if (_dbus_string_starts_with_c_str (&line, "INT32"))
729 code = DBUS_TYPE_INT32;
730 else if (_dbus_string_starts_with_c_str (&line, "UINT32"))
731 code = DBUS_TYPE_UINT32;
732 else if (_dbus_string_starts_with_c_str (&line, "DOUBLE"))
733 code = DBUS_TYPE_DOUBLE;
734 else if (_dbus_string_starts_with_c_str (&line, "STRING"))
735 code = DBUS_TYPE_STRING;
736 else if (_dbus_string_starts_with_c_str (&line, "OBJECT_PATH"))
737 code = DBUS_TYPE_OBJECT_PATH;
738 else if (_dbus_string_starts_with_c_str (&line, "NAMED"))
739 code = DBUS_TYPE_NAMED;
740 else if (_dbus_string_starts_with_c_str (&line, "ARRAY"))
741 code = DBUS_TYPE_ARRAY;
742 else if (_dbus_string_starts_with_c_str (&line, "DICT"))
743 code = DBUS_TYPE_DICT;
746 _dbus_warn ("%s is not a valid type name\n", _dbus_string_get_const_data (&line));
750 if (!_dbus_string_append_byte (dest, code))
752 _dbus_warn ("could not append typecode byte\n");
756 else if (_dbus_string_starts_with_c_str (&line,
759 SAVE_FOR_UNALIGN (dest, 4);
760 int i, len, allocated;
761 unsigned char *values;
766 values = dbus_new (unsigned char, allocated);
769 _dbus_warn ("could not allocate memory for BYTE_ARRAY\n");
775 _dbus_string_delete_first_word (&line);
776 _dbus_string_skip_blank (&line, 0, &i);
777 b = _dbus_string_get_byte (&line, i++);
782 while (i < _dbus_string_get_length (&line))
784 _dbus_string_skip_blank (&line, i, &i);
786 if (_dbus_string_get_byte (&line, i) == '\'' &&
787 _dbus_string_get_length (&line) >= i + 4 &&
788 _dbus_string_get_byte (&line, i + 1) == '\\' &&
789 _dbus_string_get_byte (&line, i + 2) == '\'' &&
790 _dbus_string_get_byte (&line, i + 3) == '\'')
795 else if (_dbus_string_get_byte (&line, i) == '\'' &&
796 _dbus_string_get_length (&line) >= i + 3 &&
797 _dbus_string_get_byte (&line, i + 2) == '\'')
799 val = _dbus_string_get_byte (&line, i + 1);
804 if (!_dbus_string_parse_int (&line, i, &val, &i))
806 _dbus_warn ("Failed to parse integer for BYTE_ARRAY\n");
810 if (val < 0 || val > 255)
812 _dbus_warn ("A byte must be in range 0-255 not %ld\n",
819 if (len == allocated)
822 values = dbus_realloc (values, allocated * sizeof (unsigned char));
825 _dbus_warn ("could not allocate memory for BYTE_ARRAY\n");
830 _dbus_string_skip_blank (&line, i, &i);
832 b = _dbus_string_get_byte (&line, i++);
840 if (!_dbus_marshal_int32 (dest, endian, len) ||
841 !_dbus_string_append_len (dest, values, len))
843 _dbus_warn ("failed to append BYTE_ARRAY\n");
848 PERFORM_UNALIGN (dest);
850 else if (_dbus_string_starts_with_c_str (&line,
853 SAVE_FOR_UNALIGN (dest, 4);
854 int i, len, allocated;
855 unsigned char *values;
856 unsigned char b, val;
859 values = dbus_new (unsigned char, allocated);
862 _dbus_warn ("could not allocate memory for BOOLEAN_ARRAY\n");
868 _dbus_string_delete_first_word (&line);
869 _dbus_string_skip_blank (&line, 0, &i);
870 b = _dbus_string_get_byte (&line, i++);
875 while (i < _dbus_string_get_length (&line))
877 _dbus_string_skip_blank (&line, i, &i);
879 if (_dbus_string_find_to (&line, i, i + 5,
885 else if (_dbus_string_find_to (&line, i, i + 4,
893 _dbus_warn ("could not parse BOOLEAN_ARRAY\n");
898 if (len == allocated)
901 values = dbus_realloc (values, allocated * sizeof (unsigned char));
904 _dbus_warn ("could not allocate memory for BOOLEAN_ARRAY\n");
909 _dbus_string_skip_blank (&line, i, &i);
911 b = _dbus_string_get_byte (&line, i++);
919 if (!_dbus_marshal_int32 (dest, endian, len) ||
920 !_dbus_string_append_len (dest, values, len))
922 _dbus_warn ("failed to append BOOLEAN_ARRAY\n");
927 PERFORM_UNALIGN (dest);
929 else if (_dbus_string_starts_with_c_str (&line,
932 SAVE_FOR_UNALIGN (dest, 4);
933 int i, len, allocated;
934 dbus_int32_t *values;
939 values = dbus_new (dbus_int32_t, allocated);
942 _dbus_warn ("could not allocate memory for INT32_ARRAY\n");
948 _dbus_string_delete_first_word (&line);
949 _dbus_string_skip_blank (&line, 0, &i);
950 b = _dbus_string_get_byte (&line, i++);
955 while (i < _dbus_string_get_length (&line))
957 _dbus_string_skip_blank (&line, i, &i);
959 if (!_dbus_string_parse_int (&line, i, &val, &i))
961 _dbus_warn ("could not parse integer for INT32_ARRAY\n");
966 if (len == allocated)
969 values = dbus_realloc (values, allocated * sizeof (dbus_int32_t));
972 _dbus_warn ("could not allocate memory for INT32_ARRAY\n");
977 _dbus_string_skip_blank (&line, i, &i);
979 b = _dbus_string_get_byte (&line, i++);
987 if (!_dbus_marshal_int32_array (dest, endian, values, len))
989 _dbus_warn ("failed to append INT32_ARRAY\n");
994 PERFORM_UNALIGN (dest);
996 else if (_dbus_string_starts_with_c_str (&line,
999 SAVE_FOR_UNALIGN (dest, 4);
1000 int i, len, allocated;
1001 dbus_uint32_t *values;
1006 values = dbus_new (dbus_uint32_t, allocated);
1009 _dbus_warn ("could not allocate memory for UINT32_ARRAY\n");
1015 _dbus_string_delete_first_word (&line);
1016 _dbus_string_skip_blank (&line, 0, &i);
1017 b = _dbus_string_get_byte (&line, i++);
1022 while (i < _dbus_string_get_length (&line))
1024 _dbus_string_skip_blank (&line, i, &i);
1026 if (!_dbus_string_parse_int (&line, i, &val, &i))
1028 _dbus_warn ("could not parse integer for UINT32_ARRAY\n");
1032 values[len++] = val;
1033 if (len == allocated)
1036 values = dbus_realloc (values, allocated * sizeof (dbus_uint32_t));
1039 _dbus_warn ("could not allocate memory for UINT32_ARRAY\n");
1044 _dbus_string_skip_blank (&line, i, &i);
1046 b = _dbus_string_get_byte (&line, i++);
1054 if (!_dbus_marshal_uint32_array (dest, endian, values, len))
1056 _dbus_warn ("failed to append UINT32_ARRAY\n");
1061 PERFORM_UNALIGN (dest);
1063 else if (_dbus_string_starts_with_c_str (&line,
1066 SAVE_FOR_UNALIGN (dest, 8);
1067 int i, len, allocated;
1073 values = dbus_new (double, allocated);
1076 _dbus_warn ("could not allocate memory for DOUBLE_ARRAY\n");
1082 _dbus_string_delete_first_word (&line);
1083 _dbus_string_skip_blank (&line, 0, &i);
1084 b = _dbus_string_get_byte (&line, i++);
1089 while (i < _dbus_string_get_length (&line))
1091 _dbus_string_skip_blank (&line, i, &i);
1093 if (!_dbus_string_parse_double (&line, i, &val, &i))
1095 _dbus_warn ("could not parse double for DOUBLE_ARRAY\n");
1099 values[len++] = val;
1100 if (len == allocated)
1103 values = dbus_realloc (values, allocated * sizeof (double));
1106 _dbus_warn ("could not allocate memory for DOUBLE_ARRAY\n");
1111 _dbus_string_skip_blank (&line, i, &i);
1113 b = _dbus_string_get_byte (&line, i++);
1121 if (!_dbus_marshal_double_array (dest, endian, values, len))
1123 _dbus_warn ("failed to append DOUBLE_ARRAY\n");
1128 PERFORM_UNALIGN (dest);
1130 else if (_dbus_string_starts_with_c_str (&line,
1133 SAVE_FOR_UNALIGN (dest, 4);
1134 int i, len, allocated;
1141 values = dbus_new (char *, allocated);
1144 _dbus_warn ("could not allocate memory for STRING_ARRAY\n");
1150 _dbus_string_delete_first_word (&line);
1151 _dbus_string_skip_blank (&line, 0, &i);
1152 b = _dbus_string_get_byte (&line, i++);
1157 _dbus_string_init (&val_str);
1158 while (i < _dbus_string_get_length (&line))
1160 _dbus_string_skip_blank (&line, i, &i);
1162 if (!append_quoted_string (&val_str, &line, i, &i))
1164 _dbus_warn ("could not parse quoted string for STRING_ARRAY\n");
1169 if (!_dbus_string_steal_data (&val_str, &val))
1171 _dbus_warn ("could not allocate memory for STRING_ARRAY string\n");
1175 values[len++] = val;
1176 if (len == allocated)
1179 values = dbus_realloc (values, allocated * sizeof (char *));
1182 _dbus_warn ("could not allocate memory for STRING_ARRAY\n");
1187 _dbus_string_skip_blank (&line, i, &i);
1189 b = _dbus_string_get_byte (&line, i++);
1195 _dbus_warn ("missing comma when parsing STRING_ARRAY\n");
1199 _dbus_string_free (&val_str);
1201 if (!_dbus_marshal_string_array (dest, endian, (const char **)values, len))
1203 _dbus_warn ("failed to append STRING_ARRAY\n");
1208 dbus_free_string_array (values);
1210 PERFORM_UNALIGN (dest);
1212 else if (_dbus_string_starts_with_c_str (&line, "BYTE"))
1214 unsigned char the_byte;
1216 _dbus_string_delete_first_word (&line);
1218 if (_dbus_string_equal_c_str (&line, "'\\''"))
1220 else if (_dbus_string_get_byte (&line, 0) == '\'' &&
1221 _dbus_string_get_length (&line) >= 3 &&
1222 _dbus_string_get_byte (&line, 2) == '\'')
1223 the_byte = _dbus_string_get_byte (&line, 1);
1227 if (!_dbus_string_parse_int (&line, 0, &val, NULL))
1229 _dbus_warn ("Failed to parse integer for BYTE\n");
1235 _dbus_warn ("A byte must be in range 0-255 not %ld\n",
1239 the_byte = (unsigned char) val;
1242 _dbus_string_append_byte (dest, the_byte);
1244 else if (_dbus_string_starts_with_c_str (&line,
1249 _dbus_string_delete_first_word (&line);
1251 if (_dbus_string_starts_with_c_str (&line, "true"))
1253 else if (_dbus_string_starts_with_c_str (&line, "false"))
1257 _dbus_warn ("could not parse BOOLEAN\n");
1260 if (!_dbus_string_append_byte (dest, val))
1262 _dbus_warn ("failed to append BOOLEAN\n");
1267 else if (_dbus_string_starts_with_c_str (&line,
1270 SAVE_FOR_UNALIGN (dest, 4);
1273 _dbus_string_delete_first_word (&line);
1275 if (!_dbus_string_parse_int (&line, 0, &val, NULL))
1277 _dbus_warn ("could not parse integer for INT32\n");
1281 if (!_dbus_marshal_int32 (dest, endian,
1284 _dbus_warn ("failed to append INT32\n");
1288 PERFORM_UNALIGN (dest);
1290 else if (_dbus_string_starts_with_c_str (&line,
1293 SAVE_FOR_UNALIGN (dest, 4);
1296 _dbus_string_delete_first_word (&line);
1298 if (!_dbus_string_parse_uint (&line, 0, &val, NULL))
1301 if (!_dbus_marshal_uint32 (dest, endian,
1304 _dbus_warn ("failed to append UINT32\n");
1308 PERFORM_UNALIGN (dest);
1310 else if (_dbus_string_starts_with_c_str (&line,
1313 SAVE_FOR_UNALIGN (dest, 8);
1316 _dbus_string_delete_first_word (&line);
1318 if (!_dbus_string_parse_double (&line, 0, &val, NULL))
1321 if (!_dbus_marshal_double (dest, endian,
1324 _dbus_warn ("failed to append DOUBLE\n");
1328 PERFORM_UNALIGN (dest);
1330 else if (_dbus_string_starts_with_c_str (&line,
1333 SAVE_FOR_UNALIGN (dest, 4);
1337 _dbus_string_delete_first_word (&line);
1339 size_offset = _dbus_string_get_length (dest);
1340 size_offset = _DBUS_ALIGN_VALUE (size_offset, 4);
1341 if (!_dbus_marshal_uint32 (dest, endian, 0))
1343 _dbus_warn ("Failed to append string size\n");
1347 old_len = _dbus_string_get_length (dest);
1348 if (!append_quoted_string (dest, &line, 0, NULL))
1350 _dbus_warn ("Failed to append quoted string\n");
1354 _dbus_marshal_set_uint32 (dest, endian, size_offset,
1355 /* subtract 1 for nul */
1356 _dbus_string_get_length (dest) - old_len - 1);
1358 PERFORM_UNALIGN (dest);
1360 else if (_dbus_string_starts_with_c_str (&line,
1363 SAVE_FOR_UNALIGN (dest, 4);
1367 _dbus_string_delete_first_word (&line);
1369 size_offset = _dbus_string_get_length (dest);
1370 size_offset = _DBUS_ALIGN_VALUE (size_offset, 4);
1371 if (!_dbus_marshal_uint32 (dest, endian, 0))
1373 _dbus_warn ("Failed to append string size\n");
1377 old_len = _dbus_string_get_length (dest);
1378 if (!append_quoted_string (dest, &line, 0, NULL))
1380 _dbus_warn ("Failed to append quoted string\n");
1384 _dbus_marshal_set_uint32 (dest, endian, size_offset,
1385 /* subtract 1 for nul */
1386 _dbus_string_get_length (dest) - old_len - 1);
1388 PERFORM_UNALIGN (dest);
1393 if (!just_set_unalign && unalign)
1395 _dbus_warn ("UNALIGN prior to something that isn't aligned\n");
1399 goto next_iteration; /* skip parse_failed */
1403 _dbus_warn ("couldn't process line %d \"%s\"\n",
1404 line_no, _dbus_string_get_const_data (&line));
1409 _dbus_hash_iter_init (length_hash, &iter);
1410 while (_dbus_hash_iter_next (&iter))
1412 SavedLength *sl = _dbus_hash_iter_get_value (&iter);
1415 s = _dbus_string_get_const_data (&sl->name);
1419 _dbus_warn ("Used LENGTH %s but never did END_LENGTH\n",
1423 else if (sl->offset < 0)
1425 _dbus_warn ("Did END_LENGTH %s but never used LENGTH\n",
1434 _dbus_verbose ("Filling in length %s endian = %d offset = %d start = %d length = %d\n",
1435 s, sl->endian, sl->offset, sl->start, sl->length);
1436 _dbus_marshal_set_int32 (dest,
1439 sl->length - sl->start);
1442 _dbus_hash_iter_remove_entry (&iter);
1447 _dbus_verbose_bytes_of_string (dest, 0, _dbus_string_get_length (dest));
1450 if (length_hash != NULL)
1451 _dbus_hash_table_unref (length_hash);
1453 _dbus_string_free (&file);
1454 _dbus_string_free (&line);
1459 #endif /* DBUS_BUILD_TESTS */