00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <config.h>
00024
00025 #ifdef DBUS_BUILD_TESTS
00026
00027 #include "dbus-message-builder.h"
00028 #include "dbus-hash.h"
00029 #include "dbus-internals.h"
00030 #include "dbus-marshal.h"
00031
00046 typedef struct
00047 {
00048 DBusString name;
00049 int start;
00050 int length;
00051 int offset;
00052 int endian;
00053 } SavedLength;
00054
00055 static void
00056 free_saved_length (void *data)
00057 {
00058 SavedLength *sl = data;
00059
00060 if (sl == NULL)
00061 return;
00062
00063 _dbus_string_free (&sl->name);
00064 dbus_free (sl);
00065 }
00066
00067 static SavedLength*
00068 ensure_saved_length (DBusHashTable *hash,
00069 const DBusString *name)
00070 {
00071 SavedLength *sl;
00072 const char *s;
00073
00074 s = _dbus_string_get_const_data (name);
00075
00076 sl = _dbus_hash_table_lookup_string (hash, s);
00077 if (sl != NULL)
00078 return sl;
00079
00080 sl = dbus_new0 (SavedLength, 1);
00081
00082 if (!_dbus_string_init (&sl->name))
00083 {
00084 dbus_free (sl);
00085 return NULL;
00086 }
00087
00088 if (!_dbus_string_copy (name, 0, &sl->name, 0))
00089 goto failed;
00090
00091 s = _dbus_string_get_const_data (&sl->name);
00092
00093 if (!_dbus_hash_table_insert_string (hash, (char*)s, sl))
00094 goto failed;
00095
00096 sl->start = -1;
00097 sl->length = -1;
00098 sl->offset = -1;
00099 sl->endian = -1;
00100
00101 return sl;
00102
00103 failed:
00104 free_saved_length (sl);
00105 return NULL;
00106 }
00107
00108 static dbus_bool_t
00109 save_start (DBusHashTable *hash,
00110 const DBusString *name,
00111 int start)
00112 {
00113 SavedLength *sl;
00114
00115 sl = ensure_saved_length (hash, name);
00116
00117 if (sl == NULL)
00118 return FALSE;
00119 else if (sl->start >= 0)
00120 {
00121 _dbus_warn ("Same START_LENGTH given twice\n");
00122 return FALSE;
00123 }
00124 else
00125 sl->start = start;
00126
00127 return TRUE;
00128 }
00129
00130 static dbus_bool_t
00131 save_length (DBusHashTable *hash,
00132 const DBusString *name,
00133 int length)
00134 {
00135 SavedLength *sl;
00136
00137 sl = ensure_saved_length (hash, name);
00138
00139 if (sl == NULL)
00140 return FALSE;
00141 else if (sl->length >= 0)
00142 {
00143 _dbus_warn ("Same END_LENGTH given twice\n");
00144 return FALSE;
00145 }
00146 else
00147 sl->length = length;
00148
00149 return TRUE;
00150 }
00151
00152 static dbus_bool_t
00153 save_offset (DBusHashTable *hash,
00154 const DBusString *name,
00155 int offset,
00156 int endian)
00157 {
00158 SavedLength *sl;
00159
00160 sl = ensure_saved_length (hash, name);
00161
00162 if (sl == NULL)
00163 return FALSE;
00164 else if (sl->offset >= 0)
00165 {
00166 _dbus_warn ("Same LENGTH given twice\n");
00167 return FALSE;
00168 }
00169 else
00170 {
00171 sl->offset = offset;
00172 sl->endian = endian;
00173 }
00174
00175 return TRUE;
00176 }
00177
00179 #define SAVE_FOR_UNALIGN(str, boundary) \
00180 int align_pad_start = _dbus_string_get_length (str); \
00181 int align_pad_end = _DBUS_ALIGN_VALUE (align_pad_start, (boundary))
00182
00184 #define PERFORM_UNALIGN(str) \
00185 if (unalign) \
00186 { \
00187 _dbus_string_delete ((str), align_pad_start, \
00188 align_pad_end - align_pad_start); \
00189 unalign = FALSE; \
00190 }
00191
00192
00193 static dbus_bool_t
00194 append_quoted_string (DBusString *dest,
00195 const DBusString *quoted,
00196 int start_pos,
00197 int *new_pos)
00198 {
00199 dbus_bool_t in_quotes = FALSE;
00200 int i;
00201
00202
00203
00204
00205
00206 i = start_pos;
00207 while (i < _dbus_string_get_length (quoted))
00208 {
00209 unsigned char b;
00210
00211 b = _dbus_string_get_byte (quoted, i);
00212
00213 if (in_quotes)
00214 {
00215 if (b == '\'')
00216 break;
00217 else
00218 {
00219 if (!_dbus_string_append_byte (dest, b))
00220 return FALSE;
00221 }
00222 }
00223 else
00224 {
00225 if (b == '\'')
00226 in_quotes = TRUE;
00227 else if (b == ' ' || b == '\n' || b == '\t')
00228 break;
00229 else
00230 {
00231 if (!_dbus_string_append_byte (dest, b))
00232 return FALSE;
00233 }
00234 }
00235
00236 ++i;
00237 }
00238
00239 if (new_pos)
00240 *new_pos = i;
00241
00242 if (!_dbus_string_append_byte (dest, '\0'))
00243 return FALSE;
00244 return TRUE;
00245 }
00246
00247 static dbus_bool_t
00248 append_saved_length (DBusString *dest,
00249 DBusHashTable *length_hash,
00250 const DBusString *name,
00251 int offset,
00252 int endian)
00253 {
00254 if (!save_offset (length_hash, name,
00255 offset, endian))
00256 {
00257 _dbus_warn ("failed to save offset to LENGTH\n");
00258 return FALSE;
00259 }
00260
00261 if (!_dbus_marshal_uint32 (dest, endian,
00262 -1))
00263 {
00264 _dbus_warn ("failed to append a length\n");
00265 return FALSE;
00266 }
00267
00268 return TRUE;
00269 }
00270
00271 static int
00272 message_type_from_string (const DBusString *str,
00273 int start)
00274 {
00275 const char *s;
00276
00277 s = _dbus_string_get_const_data_len (str, start,
00278 _dbus_string_get_length (str) - start);
00279
00280 if (strncmp (s, "method_call", strlen ("method_call")) == 0)
00281 return DBUS_MESSAGE_TYPE_METHOD_CALL;
00282 else if (strncmp (s, "method_return", strlen ("method_return")) == 0)
00283 return DBUS_MESSAGE_TYPE_METHOD_RETURN;
00284 else if (strncmp (s, "signal", strlen ("signal")) == 0)
00285 return DBUS_MESSAGE_TYPE_SIGNAL;
00286 else if (strncmp (s, "error", strlen ("error")) == 0)
00287 return DBUS_MESSAGE_TYPE_ERROR;
00288 else if (strncmp (s, "invalid", strlen ("invalid")) == 0)
00289 return DBUS_MESSAGE_TYPE_INVALID;
00290 else
00291 return -1;
00292 }
00293
00294 static dbus_bool_t
00295 append_string_field (DBusString *dest,
00296 int endian,
00297 int field,
00298 int type,
00299 const char *value)
00300 {
00301 int len;
00302
00303 if (!_dbus_string_append_byte (dest, field))
00304 {
00305 _dbus_warn ("couldn't append field name byte\n");
00306 return FALSE;
00307 }
00308
00309 if (!_dbus_string_append_byte (dest, type))
00310 {
00311 _dbus_warn ("could not append typecode byte\n");
00312 return FALSE;
00313 }
00314
00315 len = strlen (value);
00316
00317 if (!_dbus_marshal_uint32 (dest, endian, len))
00318 {
00319 _dbus_warn ("couldn't append string length\n");
00320 return FALSE;
00321 }
00322
00323 if (!_dbus_string_append (dest, value))
00324 {
00325 _dbus_warn ("couldn't append field value\n");
00326 return FALSE;
00327 }
00328
00329 if (!_dbus_string_append_byte (dest, 0))
00330 {
00331 _dbus_warn ("couldn't append string nul term\n");
00332 return FALSE;
00333 }
00334
00335 return TRUE;
00336 }
00337
00389 dbus_bool_t
00390 _dbus_message_data_load (DBusString *dest,
00391 const DBusString *filename)
00392 {
00393 DBusString file;
00394 DBusError error;
00395 DBusString line;
00396 dbus_bool_t retval;
00397 int line_no;
00398 dbus_bool_t unalign;
00399 DBusHashTable *length_hash;
00400 int endian;
00401 DBusHashIter iter;
00402
00403 retval = FALSE;
00404 length_hash = NULL;
00405
00406 if (!_dbus_string_init (&file))
00407 return FALSE;
00408
00409 if (!_dbus_string_init (&line))
00410 {
00411 _dbus_string_free (&file);
00412 return FALSE;
00413 }
00414
00415 _dbus_verbose ("Loading %s\n", _dbus_string_get_const_data (filename));
00416
00417 dbus_error_init (&error);
00418 if (!_dbus_file_get_contents (&file, filename, &error))
00419 {
00420 _dbus_warn ("Getting contents of %s failed: %s\n",
00421 _dbus_string_get_const_data (filename), error.message);
00422 dbus_error_free (&error);
00423 goto out;
00424 }
00425
00426 length_hash = _dbus_hash_table_new (DBUS_HASH_STRING,
00427 NULL,
00428 free_saved_length);
00429 if (length_hash == NULL)
00430 goto out;
00431
00432 endian = DBUS_COMPILER_BYTE_ORDER;
00433 unalign = FALSE;
00434 line_no = 0;
00435 next_iteration:
00436 while (_dbus_string_pop_line (&file, &line))
00437 {
00438 dbus_bool_t just_set_unalign;
00439
00440 just_set_unalign = FALSE;
00441 line_no += 1;
00442
00443 _dbus_string_delete_leading_blanks (&line);
00444
00445 if (_dbus_string_get_length (&line) == 0)
00446 {
00447
00448 goto next_iteration;
00449 }
00450 else if (_dbus_string_starts_with_c_str (&line,
00451 "#"))
00452 {
00453
00454 goto next_iteration;
00455 }
00456 else if (_dbus_string_starts_with_c_str (&line,
00457 "VALID_HEADER"))
00458 {
00459 int i;
00460 DBusString name;
00461 int message_type;
00462
00463 if (_dbus_string_get_length (&line) < (int) strlen ("VALID_HEADER "))
00464 {
00465 _dbus_warn ("no args to VALID_HEADER\n");
00466 goto parse_failed;
00467 }
00468
00469 if (!_dbus_string_append_byte (dest, endian))
00470 {
00471 _dbus_warn ("could not append endianness\n");
00472 goto parse_failed;
00473 }
00474
00475 message_type = message_type_from_string (&line,
00476 strlen ("VALID_HEADER "));
00477 if (message_type < 0)
00478 {
00479 _dbus_warn ("VALID_HEADER not followed by space then known message type\n");
00480 goto parse_failed;
00481 }
00482
00483 if (!_dbus_string_append_byte (dest, message_type))
00484 {
00485 _dbus_warn ("could not append message type\n");
00486 goto parse_failed;
00487 }
00488
00489 i = 0;
00490 while (i < 2)
00491 {
00492 if (!_dbus_string_append_byte (dest, '\0'))
00493 {
00494 _dbus_warn ("could not append nul pad\n");
00495 goto parse_failed;
00496 }
00497 ++i;
00498 }
00499
00500 _dbus_string_init_const (&name, "Header");
00501 if (!append_saved_length (dest, length_hash,
00502 &name, _dbus_string_get_length (dest),
00503 endian))
00504 goto parse_failed;
00505
00506 _dbus_string_init_const (&name, "Body");
00507 if (!append_saved_length (dest, length_hash,
00508 &name, _dbus_string_get_length (dest),
00509 endian))
00510 goto parse_failed;
00511
00512
00513 if (!_dbus_marshal_int32 (dest, endian, 1))
00514 {
00515 _dbus_warn ("couldn't append client serial\n");
00516 goto parse_failed;
00517 }
00518 }
00519 else if (_dbus_string_starts_with_c_str (&line,
00520 "REQUIRED_FIELDS"))
00521 {
00522 if (!append_string_field (dest, endian,
00523 DBUS_HEADER_FIELD_INTERFACE,
00524 DBUS_TYPE_STRING,
00525 "org.freedesktop.BlahBlahInterface"))
00526 goto parse_failed;
00527 if (!append_string_field (dest, endian,
00528 DBUS_HEADER_FIELD_MEMBER,
00529 DBUS_TYPE_STRING,
00530 "BlahBlahMethod"))
00531 goto parse_failed;
00532 if (!append_string_field (dest, endian,
00533 DBUS_HEADER_FIELD_PATH,
00534 DBUS_TYPE_OBJECT_PATH,
00535 "/blah/blah/path"))
00536 goto parse_failed;
00537 }
00538 else if (_dbus_string_starts_with_c_str (&line,
00539 "BIG_ENDIAN"))
00540 {
00541 endian = DBUS_BIG_ENDIAN;
00542 }
00543 else if (_dbus_string_starts_with_c_str (&line,
00544 "LITTLE_ENDIAN"))
00545 {
00546 endian = DBUS_LITTLE_ENDIAN;
00547 }
00548 else if (_dbus_string_starts_with_c_str (&line,
00549 "OPPOSITE_ENDIAN"))
00550 {
00551 if (endian == DBUS_BIG_ENDIAN)
00552 endian = DBUS_LITTLE_ENDIAN;
00553 else
00554 endian = DBUS_BIG_ENDIAN;
00555 }
00556 else if (_dbus_string_starts_with_c_str (&line,
00557 "ALIGN"))
00558 {
00559 long val;
00560 int end;
00561 int orig_len;
00562
00563 _dbus_string_delete_first_word (&line);
00564
00565 if (!_dbus_string_parse_int (&line, 0, &val, &end))
00566 {
00567 _dbus_warn ("Failed to parse integer\n");
00568 goto parse_failed;
00569 }
00570
00571 if (val > 8)
00572 {
00573 _dbus_warn ("Aligning to %ld boundary is crack\n",
00574 val);
00575 goto parse_failed;
00576 }
00577
00578 orig_len = _dbus_string_get_length (dest);
00579
00580 if (!_dbus_string_align_length (dest, val))
00581 goto parse_failed;
00582
00583 if (_dbus_string_parse_int (&line, end, &val, NULL))
00584 {
00585
00586
00587
00588 if (val < 0 || val > 255)
00589 {
00590 _dbus_warn ("can't fill align padding with %ld, must be a byte value\n", val);
00591 goto parse_failed;
00592 }
00593
00594 end = orig_len;
00595 while (end < _dbus_string_get_length (dest))
00596 {
00597 _dbus_string_set_byte (dest, end, val);
00598 ++end;
00599 }
00600 }
00601 }
00602 else if (_dbus_string_starts_with_c_str (&line, "UNALIGN"))
00603 {
00604 unalign = TRUE;
00605 just_set_unalign = TRUE;
00606 }
00607 else if (_dbus_string_starts_with_c_str (&line, "CHOP"))
00608 {
00609 long val;
00610
00611
00612
00613
00614
00615 _dbus_string_delete_first_word (&line);
00616
00617 if (!_dbus_string_parse_int (&line, 0, &val, NULL))
00618 {
00619 _dbus_warn ("Failed to parse integer to chop\n");
00620 goto parse_failed;
00621 }
00622
00623 if (val > _dbus_string_get_length (dest))
00624 {
00625 _dbus_warn ("Trying to chop %ld bytes but we only have %d\n",
00626 val,
00627 _dbus_string_get_length (dest));
00628 goto parse_failed;
00629 }
00630
00631 _dbus_string_shorten (dest, val);
00632 }
00633 else if (_dbus_string_starts_with_c_str (&line,
00634 "START_LENGTH"))
00635 {
00636 _dbus_string_delete_first_word (&line);
00637
00638 if (!save_start (length_hash, &line,
00639 _dbus_string_get_length (dest)))
00640 {
00641 _dbus_warn ("failed to save length start\n");
00642 goto parse_failed;
00643 }
00644 }
00645 else if (_dbus_string_starts_with_c_str (&line,
00646 "END_LENGTH"))
00647 {
00648 _dbus_string_delete_first_word (&line);
00649
00650 if (!save_length (length_hash, &line,
00651 _dbus_string_get_length (dest)))
00652 {
00653 _dbus_warn ("failed to save length end\n");
00654 goto parse_failed;
00655 }
00656 }
00657 else if (_dbus_string_starts_with_c_str (&line,
00658 "LENGTH"))
00659 {
00660 SAVE_FOR_UNALIGN (dest, 4);
00661
00662 _dbus_string_delete_first_word (&line);
00663
00664 if (!append_saved_length (dest, length_hash,
00665 &line,
00666 unalign ? align_pad_start : align_pad_end,
00667 endian))
00668 {
00669 _dbus_warn ("failed to add LENGTH\n");
00670 goto parse_failed;
00671 }
00672
00673 PERFORM_UNALIGN (dest);
00674 }
00675 else if (_dbus_string_starts_with_c_str (&line,
00676 "HEADER_FIELD"))
00677 {
00678 int field;
00679
00680 _dbus_string_delete_first_word (&line);
00681
00682 if (_dbus_string_starts_with_c_str (&line, "INVALID"))
00683 field = DBUS_HEADER_FIELD_INVALID;
00684 else if (_dbus_string_starts_with_c_str (&line, "PATH"))
00685 field = DBUS_HEADER_FIELD_PATH;
00686 else if (_dbus_string_starts_with_c_str (&line, "INTERFACE"))
00687 field = DBUS_HEADER_FIELD_INTERFACE;
00688 else if (_dbus_string_starts_with_c_str (&line, "MEMBER"))
00689 field = DBUS_HEADER_FIELD_MEMBER;
00690 else if (_dbus_string_starts_with_c_str (&line, "ERROR_NAME"))
00691 field = DBUS_HEADER_FIELD_ERROR_NAME;
00692 else if (_dbus_string_starts_with_c_str (&line, "REPLY_SERIAL"))
00693 field = DBUS_HEADER_FIELD_REPLY_SERIAL;
00694 else if (_dbus_string_starts_with_c_str (&line, "SERVICE"))
00695 field = DBUS_HEADER_FIELD_SERVICE;
00696 else if (_dbus_string_starts_with_c_str (&line, "SENDER_SERVICE"))
00697 field = DBUS_HEADER_FIELD_SENDER_SERVICE;
00698 else if (_dbus_string_starts_with_c_str (&line, "UNKNOWN"))
00699 field = 22;
00700 else
00701 {
00702 _dbus_warn ("%s is not a valid header field name\n",
00703 _dbus_string_get_const_data (&line));
00704 goto parse_failed;
00705 }
00706
00707 if (!_dbus_string_append_byte (dest, field))
00708 {
00709 _dbus_warn ("could not append header field name byte\n");
00710 goto parse_failed;
00711 }
00712 }
00713 else if (_dbus_string_starts_with_c_str (&line,
00714 "TYPE"))
00715 {
00716 int code;
00717
00718 _dbus_string_delete_first_word (&line);
00719
00720 if (_dbus_string_starts_with_c_str (&line, "INVALID"))
00721 code = DBUS_TYPE_INVALID;
00722 else if (_dbus_string_starts_with_c_str (&line, "NIL"))
00723 code = DBUS_TYPE_NIL;
00724 else if (_dbus_string_starts_with_c_str (&line, "BYTE"))
00725 code = DBUS_TYPE_BYTE;
00726 else if (_dbus_string_starts_with_c_str (&line, "BOOLEAN"))
00727 code = DBUS_TYPE_BOOLEAN;
00728 else if (_dbus_string_starts_with_c_str (&line, "INT32"))
00729 code = DBUS_TYPE_INT32;
00730 else if (_dbus_string_starts_with_c_str (&line, "UINT32"))
00731 code = DBUS_TYPE_UINT32;
00732 else if (_dbus_string_starts_with_c_str (&line, "DOUBLE"))
00733 code = DBUS_TYPE_DOUBLE;
00734 else if (_dbus_string_starts_with_c_str (&line, "STRING"))
00735 code = DBUS_TYPE_STRING;
00736 else if (_dbus_string_starts_with_c_str (&line, "OBJECT_PATH"))
00737 code = DBUS_TYPE_OBJECT_PATH;
00738 else if (_dbus_string_starts_with_c_str (&line, "CUSTOM"))
00739 code = DBUS_TYPE_CUSTOM;
00740 else if (_dbus_string_starts_with_c_str (&line, "ARRAY"))
00741 code = DBUS_TYPE_ARRAY;
00742 else if (_dbus_string_starts_with_c_str (&line, "DICT"))
00743 code = DBUS_TYPE_DICT;
00744 else
00745 {
00746 _dbus_warn ("%s is not a valid type name\n", _dbus_string_get_const_data (&line));
00747 goto parse_failed;
00748 }
00749
00750 if (!_dbus_string_append_byte (dest, code))
00751 {
00752 _dbus_warn ("could not append typecode byte\n");
00753 goto parse_failed;
00754 }
00755 }
00756 else if (_dbus_string_starts_with_c_str (&line,
00757 "BYTE_ARRAY"))
00758 {
00759 SAVE_FOR_UNALIGN (dest, 4);
00760 int i, len, allocated;
00761 unsigned char *values;
00762 unsigned char b;
00763 long val;
00764
00765 allocated = 4;
00766 values = dbus_new (unsigned char, allocated);
00767 if (!values)
00768 {
00769 _dbus_warn ("could not allocate memory for BYTE_ARRAY\n");
00770 goto parse_failed;
00771 }
00772
00773 len = 0;
00774
00775 _dbus_string_delete_first_word (&line);
00776 _dbus_string_skip_blank (&line, 0, &i);
00777 b = _dbus_string_get_byte (&line, i++);
00778
00779 if (b != '{')
00780 goto parse_failed;
00781
00782 while (i < _dbus_string_get_length (&line))
00783 {
00784 _dbus_string_skip_blank (&line, i, &i);
00785
00786 if (_dbus_string_get_byte (&line, i) == '\'' &&
00787 _dbus_string_get_length (&line) >= i + 4 &&
00788 _dbus_string_get_byte (&line, i + 1) == '\\' &&
00789 _dbus_string_get_byte (&line, i + 2) == '\'' &&
00790 _dbus_string_get_byte (&line, i + 3) == '\'')
00791 {
00792 val = '\'';
00793 i += 4;
00794 }
00795 else if (_dbus_string_get_byte (&line, i) == '\'' &&
00796 _dbus_string_get_length (&line) >= i + 3 &&
00797 _dbus_string_get_byte (&line, i + 2) == '\'')
00798 {
00799 val = _dbus_string_get_byte (&line, i + 1);
00800 i += 3;
00801 }
00802 else
00803 {
00804 if (!_dbus_string_parse_int (&line, i, &val, &i))
00805 {
00806 _dbus_warn ("Failed to parse integer for BYTE_ARRAY\n");
00807 goto parse_failed;
00808 }
00809
00810 if (val < 0 || val > 255)
00811 {
00812 _dbus_warn ("A byte must be in range 0-255 not %ld\n",
00813 val);
00814 goto parse_failed;
00815 }
00816 }
00817
00818 values[len++] = val;
00819 if (len == allocated)
00820 {
00821 allocated *= 2;
00822 values = dbus_realloc (values, allocated * sizeof (unsigned char));
00823 if (!values)
00824 {
00825 _dbus_warn ("could not allocate memory for BYTE_ARRAY\n");
00826 goto parse_failed;
00827 }
00828 }
00829
00830 _dbus_string_skip_blank (&line, i, &i);
00831
00832 b = _dbus_string_get_byte (&line, i++);
00833
00834 if (b == '}')
00835 break;
00836 else if (b != ',')
00837 goto parse_failed;
00838 }
00839
00840 if (!_dbus_marshal_int32 (dest, endian, len) ||
00841 !_dbus_string_append_len (dest, values, len))
00842 {
00843 _dbus_warn ("failed to append BYTE_ARRAY\n");
00844 goto parse_failed;
00845 }
00846 dbus_free (values);
00847
00848 PERFORM_UNALIGN (dest);
00849 }
00850 else if (_dbus_string_starts_with_c_str (&line,
00851 "BOOLEAN_ARRAY"))
00852 {
00853 SAVE_FOR_UNALIGN (dest, 4);
00854 int i, len, allocated;
00855 unsigned char *values;
00856 unsigned char b, val;
00857
00858 allocated = 4;
00859 values = dbus_new (unsigned char, allocated);
00860 if (!values)
00861 {
00862 _dbus_warn ("could not allocate memory for BOOLEAN_ARRAY\n");
00863 goto parse_failed;
00864 }
00865
00866 len = 0;
00867
00868 _dbus_string_delete_first_word (&line);
00869 _dbus_string_skip_blank (&line, 0, &i);
00870 b = _dbus_string_get_byte (&line, i++);
00871
00872 if (b != '{')
00873 goto parse_failed;
00874
00875 while (i < _dbus_string_get_length (&line))
00876 {
00877 _dbus_string_skip_blank (&line, i, &i);
00878
00879 if (_dbus_string_find_to (&line, i, i + 5,
00880 "false", NULL))
00881 {
00882 i += 5;
00883 val = TRUE;
00884 }
00885 else if (_dbus_string_find_to (&line, i, i + 4,
00886 "true", NULL))
00887 {
00888 i += 4;
00889 val = FALSE;
00890 }
00891 else
00892 {
00893 _dbus_warn ("could not parse BOOLEAN_ARRAY\n");
00894 goto parse_failed;
00895 }
00896
00897 values[len++] = val;
00898 if (len == allocated)
00899 {
00900 allocated *= 2;
00901 values = dbus_realloc (values, allocated * sizeof (unsigned char));
00902 if (!values)
00903 {
00904 _dbus_warn ("could not allocate memory for BOOLEAN_ARRAY\n");
00905 goto parse_failed;
00906 }
00907 }
00908
00909 _dbus_string_skip_blank (&line, i, &i);
00910
00911 b = _dbus_string_get_byte (&line, i++);
00912
00913 if (b == '}')
00914 break;
00915 else if (b != ',')
00916 goto parse_failed;
00917 }
00918
00919 if (!_dbus_marshal_int32 (dest, endian, len) ||
00920 !_dbus_string_append_len (dest, values, len))
00921 {
00922 _dbus_warn ("failed to append BOOLEAN_ARRAY\n");
00923 goto parse_failed;
00924 }
00925 dbus_free (values);
00926
00927 PERFORM_UNALIGN (dest);
00928 }
00929 else if (_dbus_string_starts_with_c_str (&line,
00930 "INT32_ARRAY"))
00931 {
00932 SAVE_FOR_UNALIGN (dest, 4);
00933 int i, len, allocated;
00934 dbus_int32_t *values;
00935 long val;
00936 unsigned char b;
00937
00938 allocated = 4;
00939 values = dbus_new (dbus_int32_t, allocated);
00940 if (!values)
00941 {
00942 _dbus_warn ("could not allocate memory for INT32_ARRAY\n");
00943 goto parse_failed;
00944 }
00945
00946 len = 0;
00947
00948 _dbus_string_delete_first_word (&line);
00949 _dbus_string_skip_blank (&line, 0, &i);
00950 b = _dbus_string_get_byte (&line, i++);
00951
00952 if (b != '{')
00953 goto parse_failed;
00954
00955 while (i < _dbus_string_get_length (&line))
00956 {
00957 _dbus_string_skip_blank (&line, i, &i);
00958
00959 if (!_dbus_string_parse_int (&line, i, &val, &i))
00960 {
00961 _dbus_warn ("could not parse integer for INT32_ARRAY\n");
00962 goto parse_failed;
00963 }
00964
00965 values[len++] = val;
00966 if (len == allocated)
00967 {
00968 allocated *= 2;
00969 values = dbus_realloc (values, allocated * sizeof (dbus_int32_t));
00970 if (!values)
00971 {
00972 _dbus_warn ("could not allocate memory for INT32_ARRAY\n");
00973 goto parse_failed;
00974 }
00975 }
00976
00977 _dbus_string_skip_blank (&line, i, &i);
00978
00979 b = _dbus_string_get_byte (&line, i++);
00980
00981 if (b == '}')
00982 break;
00983 else if (b != ',')
00984 goto parse_failed;
00985 }
00986
00987 if (!_dbus_marshal_int32_array (dest, endian, values, len))
00988 {
00989 _dbus_warn ("failed to append INT32_ARRAY\n");
00990 goto parse_failed;
00991 }
00992 dbus_free (values);
00993
00994 PERFORM_UNALIGN (dest);
00995 }
00996 else if (_dbus_string_starts_with_c_str (&line,
00997 "UINT32_ARRAY"))
00998 {
00999 SAVE_FOR_UNALIGN (dest, 4);
01000 int i, len, allocated;
01001 dbus_uint32_t *values;
01002 long val;
01003 unsigned char b;
01004
01005 allocated = 4;
01006 values = dbus_new (dbus_uint32_t, allocated);
01007 if (!values)
01008 {
01009 _dbus_warn ("could not allocate memory for UINT32_ARRAY\n");
01010 goto parse_failed;
01011 }
01012
01013 len = 0;
01014
01015 _dbus_string_delete_first_word (&line);
01016 _dbus_string_skip_blank (&line, 0, &i);
01017 b = _dbus_string_get_byte (&line, i++);
01018
01019 if (b != '{')
01020 goto parse_failed;
01021
01022 while (i < _dbus_string_get_length (&line))
01023 {
01024 _dbus_string_skip_blank (&line, i, &i);
01025
01026 if (!_dbus_string_parse_int (&line, i, &val, &i))
01027 {
01028 _dbus_warn ("could not parse integer for UINT32_ARRAY\n");
01029 goto parse_failed;
01030 }
01031
01032 values[len++] = val;
01033 if (len == allocated)
01034 {
01035 allocated *= 2;
01036 values = dbus_realloc (values, allocated * sizeof (dbus_uint32_t));
01037 if (!values)
01038 {
01039 _dbus_warn ("could not allocate memory for UINT32_ARRAY\n");
01040 goto parse_failed;
01041 }
01042 }
01043
01044 _dbus_string_skip_blank (&line, i, &i);
01045
01046 b = _dbus_string_get_byte (&line, i++);
01047
01048 if (b == '}')
01049 break;
01050 else if (b != ',')
01051 goto parse_failed;
01052 }
01053
01054 if (!_dbus_marshal_uint32_array (dest, endian, values, len))
01055 {
01056 _dbus_warn ("failed to append UINT32_ARRAY\n");
01057 goto parse_failed;
01058 }
01059 dbus_free (values);
01060
01061 PERFORM_UNALIGN (dest);
01062 }
01063 else if (_dbus_string_starts_with_c_str (&line,
01064 "DOUBLE_ARRAY"))
01065 {
01066 SAVE_FOR_UNALIGN (dest, 8);
01067 int i, len, allocated;
01068 double *values;
01069 double val;
01070 unsigned char b;
01071
01072 allocated = 4;
01073 values = dbus_new (double, allocated);
01074 if (!values)
01075 {
01076 _dbus_warn ("could not allocate memory for DOUBLE_ARRAY\n");
01077 goto parse_failed;
01078 }
01079
01080 len = 0;
01081
01082 _dbus_string_delete_first_word (&line);
01083 _dbus_string_skip_blank (&line, 0, &i);
01084 b = _dbus_string_get_byte (&line, i++);
01085
01086 if (b != '{')
01087 goto parse_failed;
01088
01089 while (i < _dbus_string_get_length (&line))
01090 {
01091 _dbus_string_skip_blank (&line, i, &i);
01092
01093 if (!_dbus_string_parse_double (&line, i, &val, &i))
01094 {
01095 _dbus_warn ("could not parse double for DOUBLE_ARRAY\n");
01096 goto parse_failed;
01097 }
01098
01099 values[len++] = val;
01100 if (len == allocated)
01101 {
01102 allocated *= 2;
01103 values = dbus_realloc (values, allocated * sizeof (double));
01104 if (!values)
01105 {
01106 _dbus_warn ("could not allocate memory for DOUBLE_ARRAY\n");
01107 goto parse_failed;
01108 }
01109 }
01110
01111 _dbus_string_skip_blank (&line, i, &i);
01112
01113 b = _dbus_string_get_byte (&line, i++);
01114
01115 if (b == '}')
01116 break;
01117 else if (b != ',')
01118 goto parse_failed;
01119 }
01120
01121 if (!_dbus_marshal_double_array (dest, endian, values, len))
01122 {
01123 _dbus_warn ("failed to append DOUBLE_ARRAY\n");
01124 goto parse_failed;
01125 }
01126 dbus_free (values);
01127
01128 PERFORM_UNALIGN (dest);
01129 }
01130 else if (_dbus_string_starts_with_c_str (&line,
01131 "STRING_ARRAY"))
01132 {
01133 SAVE_FOR_UNALIGN (dest, 4);
01134 int i, len, allocated;
01135 char **values;
01136 char *val;
01137 DBusString val_str;
01138 unsigned char b;
01139
01140 allocated = 4;
01141 values = dbus_new (char *, allocated);
01142 if (!values)
01143 {
01144 _dbus_warn ("could not allocate memory for STRING_ARRAY\n");
01145 goto parse_failed;
01146 }
01147
01148 len = 0;
01149
01150 _dbus_string_delete_first_word (&line);
01151 _dbus_string_skip_blank (&line, 0, &i);
01152 b = _dbus_string_get_byte (&line, i++);
01153
01154 if (b != '{')
01155 goto parse_failed;
01156
01157 _dbus_string_init (&val_str);
01158 while (i < _dbus_string_get_length (&line))
01159 {
01160 _dbus_string_skip_blank (&line, i, &i);
01161
01162 if (!append_quoted_string (&val_str, &line, i, &i))
01163 {
01164 _dbus_warn ("could not parse quoted string for STRING_ARRAY\n");
01165 goto parse_failed;
01166 }
01167 i++;
01168
01169 if (!_dbus_string_steal_data (&val_str, &val))
01170 {
01171 _dbus_warn ("could not allocate memory for STRING_ARRAY string\n");
01172 goto parse_failed;
01173 }
01174
01175 values[len++] = val;
01176 if (len == allocated)
01177 {
01178 allocated *= 2;
01179 values = dbus_realloc (values, allocated * sizeof (char *));
01180 if (!values)
01181 {
01182 _dbus_warn ("could not allocate memory for STRING_ARRAY\n");
01183 goto parse_failed;
01184 }
01185 }
01186
01187 _dbus_string_skip_blank (&line, i, &i);
01188
01189 b = _dbus_string_get_byte (&line, i++);
01190
01191 if (b == '}')
01192 break;
01193 else if (b != ',')
01194 {
01195 _dbus_warn ("missing comma when parsing STRING_ARRAY\n");
01196 goto parse_failed;
01197 }
01198 }
01199 _dbus_string_free (&val_str);
01200
01201 if (!_dbus_marshal_string_array (dest, endian, (const char **)values, len))
01202 {
01203 _dbus_warn ("failed to append STRING_ARRAY\n");
01204 goto parse_failed;
01205 }
01206
01207 values[len] = NULL;
01208 dbus_free_string_array (values);
01209
01210 PERFORM_UNALIGN (dest);
01211 }
01212 else if (_dbus_string_starts_with_c_str (&line, "BYTE"))
01213 {
01214 unsigned char the_byte;
01215
01216 _dbus_string_delete_first_word (&line);
01217
01218 if (_dbus_string_equal_c_str (&line, "'\\''"))
01219 the_byte = '\'';
01220 else if (_dbus_string_get_byte (&line, 0) == '\'' &&
01221 _dbus_string_get_length (&line) >= 3 &&
01222 _dbus_string_get_byte (&line, 2) == '\'')
01223 the_byte = _dbus_string_get_byte (&line, 1);
01224 else
01225 {
01226 long val;
01227 if (!_dbus_string_parse_int (&line, 0, &val, NULL))
01228 {
01229 _dbus_warn ("Failed to parse integer for BYTE\n");
01230 goto parse_failed;
01231 }
01232
01233 if (val > 255)
01234 {
01235 _dbus_warn ("A byte must be in range 0-255 not %ld\n",
01236 val);
01237 goto parse_failed;
01238 }
01239 the_byte = (unsigned char) val;
01240 }
01241
01242 _dbus_string_append_byte (dest, the_byte);
01243 }
01244 else if (_dbus_string_starts_with_c_str (&line,
01245 "BOOLEAN"))
01246 {
01247 unsigned char val;
01248
01249 _dbus_string_delete_first_word (&line);
01250
01251 if (_dbus_string_starts_with_c_str (&line, "true"))
01252 val = TRUE;
01253 else if (_dbus_string_starts_with_c_str (&line, "false"))
01254 val = FALSE;
01255 else
01256 {
01257 _dbus_warn ("could not parse BOOLEAN\n");
01258 goto parse_failed;
01259 }
01260 if (!_dbus_string_append_byte (dest, val))
01261 {
01262 _dbus_warn ("failed to append BOOLEAN\n");
01263 goto parse_failed;
01264 }
01265 }
01266
01267 else if (_dbus_string_starts_with_c_str (&line,
01268 "INT32"))
01269 {
01270 SAVE_FOR_UNALIGN (dest, 4);
01271 long val;
01272
01273 _dbus_string_delete_first_word (&line);
01274
01275 if (!_dbus_string_parse_int (&line, 0, &val, NULL))
01276 {
01277 _dbus_warn ("could not parse integer for INT32\n");
01278 goto parse_failed;
01279 }
01280
01281 if (!_dbus_marshal_int32 (dest, endian,
01282 val))
01283 {
01284 _dbus_warn ("failed to append INT32\n");
01285 goto parse_failed;
01286 }
01287
01288 PERFORM_UNALIGN (dest);
01289 }
01290 else if (_dbus_string_starts_with_c_str (&line,
01291 "UINT32"))
01292 {
01293 SAVE_FOR_UNALIGN (dest, 4);
01294 unsigned long val;
01295
01296 _dbus_string_delete_first_word (&line);
01297
01298 if (!_dbus_string_parse_uint (&line, 0, &val, NULL))
01299 goto parse_failed;
01300
01301 if (!_dbus_marshal_uint32 (dest, endian,
01302 val))
01303 {
01304 _dbus_warn ("failed to append UINT32\n");
01305 goto parse_failed;
01306 }
01307
01308 PERFORM_UNALIGN (dest);
01309 }
01310 else if (_dbus_string_starts_with_c_str (&line,
01311 "DOUBLE"))
01312 {
01313 SAVE_FOR_UNALIGN (dest, 8);
01314 double val;
01315
01316 _dbus_string_delete_first_word (&line);
01317
01318 if (!_dbus_string_parse_double (&line, 0, &val, NULL))
01319 goto parse_failed;
01320
01321 if (!_dbus_marshal_double (dest, endian,
01322 val))
01323 {
01324 _dbus_warn ("failed to append DOUBLE\n");
01325 goto parse_failed;
01326 }
01327
01328 PERFORM_UNALIGN (dest);
01329 }
01330 else if (_dbus_string_starts_with_c_str (&line,
01331 "STRING"))
01332 {
01333 SAVE_FOR_UNALIGN (dest, 4);
01334 int size_offset;
01335 int old_len;
01336
01337 _dbus_string_delete_first_word (&line);
01338
01339 size_offset = _dbus_string_get_length (dest);
01340 size_offset = _DBUS_ALIGN_VALUE (size_offset, 4);
01341 if (!_dbus_marshal_uint32 (dest, endian, 0))
01342 {
01343 _dbus_warn ("Failed to append string size\n");
01344 goto parse_failed;
01345 }
01346
01347 old_len = _dbus_string_get_length (dest);
01348 if (!append_quoted_string (dest, &line, 0, NULL))
01349 {
01350 _dbus_warn ("Failed to append quoted string\n");
01351 goto parse_failed;
01352 }
01353
01354 _dbus_marshal_set_uint32 (dest, endian, size_offset,
01355
01356 _dbus_string_get_length (dest) - old_len - 1);
01357
01358 PERFORM_UNALIGN (dest);
01359 }
01360 else if (_dbus_string_starts_with_c_str (&line,
01361 "OBJECT_PATH"))
01362 {
01363 SAVE_FOR_UNALIGN (dest, 4);
01364 int size_offset;
01365 int old_len;
01366
01367 _dbus_string_delete_first_word (&line);
01368
01369 size_offset = _dbus_string_get_length (dest);
01370 size_offset = _DBUS_ALIGN_VALUE (size_offset, 4);
01371 if (!_dbus_marshal_uint32 (dest, endian, 0))
01372 {
01373 _dbus_warn ("Failed to append string size\n");
01374 goto parse_failed;
01375 }
01376
01377 old_len = _dbus_string_get_length (dest);
01378 if (!append_quoted_string (dest, &line, 0, NULL))
01379 {
01380 _dbus_warn ("Failed to append quoted string\n");
01381 goto parse_failed;
01382 }
01383
01384 _dbus_marshal_set_uint32 (dest, endian, size_offset,
01385
01386 _dbus_string_get_length (dest) - old_len - 1);
01387
01388 PERFORM_UNALIGN (dest);
01389 }
01390 else
01391 goto parse_failed;
01392
01393 if (!just_set_unalign && unalign)
01394 {
01395 _dbus_warn ("UNALIGN prior to something that isn't aligned\n");
01396 goto parse_failed;
01397 }
01398
01399 goto next_iteration;
01400
01401 parse_failed:
01402 {
01403 _dbus_warn ("couldn't process line %d \"%s\"\n",
01404 line_no, _dbus_string_get_const_data (&line));
01405 goto out;
01406 }
01407 }
01408
01409 _dbus_hash_iter_init (length_hash, &iter);
01410 while (_dbus_hash_iter_next (&iter))
01411 {
01412 SavedLength *sl = _dbus_hash_iter_get_value (&iter);
01413 const char *s;
01414
01415 s = _dbus_string_get_const_data (&sl->name);
01416
01417 if (sl->length < 0)
01418 {
01419 _dbus_warn ("Used LENGTH %s but never did END_LENGTH\n",
01420 s);
01421 goto out;
01422 }
01423 else if (sl->offset < 0)
01424 {
01425 _dbus_warn ("Did END_LENGTH %s but never used LENGTH\n",
01426 s);
01427 goto out;
01428 }
01429 else
01430 {
01431 if (sl->start < 0)
01432 sl->start = 0;
01433
01434 _dbus_verbose ("Filling in length %s endian = %d offset = %d start = %d length = %d\n",
01435 s, sl->endian, sl->offset, sl->start, sl->length);
01436 _dbus_marshal_set_int32 (dest,
01437 sl->endian,
01438 sl->offset,
01439 sl->length - sl->start);
01440 }
01441
01442 _dbus_hash_iter_remove_entry (&iter);
01443 }
01444
01445 retval = TRUE;
01446
01447 _dbus_verbose_bytes_of_string (dest, 0, _dbus_string_get_length (dest));
01448
01449 out:
01450 if (length_hash != NULL)
01451 _dbus_hash_table_unref (length_hash);
01452
01453 _dbus_string_free (&file);
01454 _dbus_string_free (&line);
01455 return retval;
01456 }
01457
01459 #endif