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
00043 typedef struct
00044 {
00045 DBusString name;
00046 int start;
00047 int length;
00048 int offset;
00049 int endian;
00050 } SavedLength;
00051
00052 static void
00053 free_saved_length (void *data)
00054 {
00055 SavedLength *sl = data;
00056
00057 if (sl == NULL)
00058 return;
00059
00060 _dbus_string_free (&sl->name);
00061 dbus_free (sl);
00062 }
00063
00064 static SavedLength*
00065 ensure_saved_length (DBusHashTable *hash,
00066 const DBusString *name)
00067 {
00068 SavedLength *sl;
00069 const char *s;
00070
00071 s = _dbus_string_get_const_data (name);
00072
00073 sl = _dbus_hash_table_lookup_string (hash, s);
00074 if (sl != NULL)
00075 return sl;
00076
00077 sl = dbus_new0 (SavedLength, 1);
00078
00079 if (!_dbus_string_init (&sl->name))
00080 {
00081 dbus_free (sl);
00082 return NULL;
00083 }
00084
00085 if (!_dbus_string_copy (name, 0, &sl->name, 0))
00086 goto failed;
00087
00088 s = _dbus_string_get_const_data (&sl->name);
00089
00090 if (!_dbus_hash_table_insert_string (hash, (char*)s, sl))
00091 goto failed;
00092
00093 sl->start = -1;
00094 sl->length = -1;
00095 sl->offset = -1;
00096 sl->endian = -1;
00097
00098 return sl;
00099
00100 failed:
00101 free_saved_length (sl);
00102 return NULL;
00103 }
00104
00105 static dbus_bool_t
00106 save_start (DBusHashTable *hash,
00107 const DBusString *name,
00108 int start)
00109 {
00110 SavedLength *sl;
00111
00112 sl = ensure_saved_length (hash, name);
00113
00114 if (sl == NULL)
00115 return FALSE;
00116 else if (sl->start >= 0)
00117 {
00118 _dbus_warn ("Same START_LENGTH given twice\n");
00119 return FALSE;
00120 }
00121 else
00122 sl->start = start;
00123
00124 return TRUE;
00125 }
00126
00127 static dbus_bool_t
00128 save_length (DBusHashTable *hash,
00129 const DBusString *name,
00130 int length)
00131 {
00132 SavedLength *sl;
00133
00134 sl = ensure_saved_length (hash, name);
00135
00136 if (sl == NULL)
00137 return FALSE;
00138 else if (sl->length >= 0)
00139 {
00140 _dbus_warn ("Same END_LENGTH given twice\n");
00141 return FALSE;
00142 }
00143 else
00144 sl->length = length;
00145
00146 return TRUE;
00147 }
00148
00149 static dbus_bool_t
00150 save_offset (DBusHashTable *hash,
00151 const DBusString *name,
00152 int offset,
00153 int endian)
00154 {
00155 SavedLength *sl;
00156
00157 sl = ensure_saved_length (hash, name);
00158
00159 if (sl == NULL)
00160 return FALSE;
00161 else if (sl->offset >= 0)
00162 {
00163 _dbus_warn ("Same LENGTH given twice\n");
00164 return FALSE;
00165 }
00166 else
00167 {
00168 sl->offset = offset;
00169 sl->endian = endian;
00170 }
00171
00172 return TRUE;
00173 }
00174
00176 #define SAVE_FOR_UNALIGN(str, boundary) \
00177 int align_pad_start = _dbus_string_get_length (str); \
00178 int align_pad_end = _DBUS_ALIGN_VALUE (align_pad_start, (boundary))
00179
00181 #define PERFORM_UNALIGN(str) \
00182 if (unalign) \
00183 { \
00184 _dbus_string_delete ((str), align_pad_start, \
00185 align_pad_end - align_pad_start); \
00186 unalign = FALSE; \
00187 }
00188
00189
00190 static dbus_bool_t
00191 append_quoted_string (DBusString *dest,
00192 const DBusString *quoted,
00193 int start_pos,
00194 int *new_pos)
00195 {
00196 dbus_bool_t in_quotes = FALSE;
00197 int i;
00198
00199
00200
00201
00202
00203 i = start_pos;
00204 while (i < _dbus_string_get_length (quoted))
00205 {
00206 unsigned char b;
00207
00208 b = _dbus_string_get_byte (quoted, i);
00209
00210 if (in_quotes)
00211 {
00212 if (b == '\'')
00213 break;
00214 else
00215 {
00216 if (!_dbus_string_append_byte (dest, b))
00217 return FALSE;
00218 }
00219 }
00220 else
00221 {
00222 if (b == '\'')
00223 in_quotes = TRUE;
00224 else if (b == ' ' || b == '\n' || b == '\t')
00225 break;
00226 else
00227 {
00228 if (!_dbus_string_append_byte (dest, b))
00229 return FALSE;
00230 }
00231 }
00232
00233 ++i;
00234 }
00235
00236 if (new_pos)
00237 *new_pos = i;
00238
00239 if (!_dbus_string_append_byte (dest, '\0'))
00240 return FALSE;
00241 return TRUE;
00242 }
00243
00244 static dbus_bool_t
00245 append_saved_length (DBusString *dest,
00246 DBusHashTable *length_hash,
00247 const DBusString *name,
00248 int offset,
00249 int endian)
00250 {
00251 if (!save_offset (length_hash, name,
00252 offset, endian))
00253 {
00254 _dbus_warn ("failed to save offset to LENGTH\n");
00255 return FALSE;
00256 }
00257
00258 if (!_dbus_marshal_uint32 (dest, endian,
00259 -1))
00260 {
00261 _dbus_warn ("failed to append a length\n");
00262 return FALSE;
00263 }
00264
00265 return TRUE;
00266 }
00267
00317 dbus_bool_t
00318 _dbus_message_data_load (DBusString *dest,
00319 const DBusString *filename)
00320 {
00321 DBusString file;
00322 DBusError error;
00323 DBusString line;
00324 dbus_bool_t retval;
00325 int line_no;
00326 dbus_bool_t unalign;
00327 DBusHashTable *length_hash;
00328 int endian;
00329 DBusHashIter iter;
00330
00331 retval = FALSE;
00332 length_hash = NULL;
00333
00334 if (!_dbus_string_init (&file))
00335 return FALSE;
00336
00337 if (!_dbus_string_init (&line))
00338 {
00339 _dbus_string_free (&file);
00340 return FALSE;
00341 }
00342
00343 _dbus_verbose ("Loading %s\n", _dbus_string_get_const_data (filename));
00344
00345 dbus_error_init (&error);
00346 if (!_dbus_file_get_contents (&file, filename, &error))
00347 {
00348 _dbus_warn ("Getting contents of %s failed: %s\n",
00349 _dbus_string_get_const_data (filename), error.message);
00350 dbus_error_free (&error);
00351 goto out;
00352 }
00353
00354 length_hash = _dbus_hash_table_new (DBUS_HASH_STRING,
00355 NULL,
00356 free_saved_length);
00357 if (length_hash == NULL)
00358 goto out;
00359
00360 endian = DBUS_COMPILER_BYTE_ORDER;
00361 unalign = FALSE;
00362 line_no = 0;
00363 next_iteration:
00364 while (_dbus_string_pop_line (&file, &line))
00365 {
00366 dbus_bool_t just_set_unalign;
00367
00368 just_set_unalign = FALSE;
00369 line_no += 1;
00370
00371 _dbus_string_delete_leading_blanks (&line);
00372
00373 if (_dbus_string_get_length (&line) == 0)
00374 {
00375
00376 goto next_iteration;
00377 }
00378 else if (_dbus_string_starts_with_c_str (&line,
00379 "#"))
00380 {
00381
00382 goto next_iteration;
00383 }
00384 else if (_dbus_string_starts_with_c_str (&line,
00385 "VALID_HEADER"))
00386 {
00387 int i;
00388 DBusString name;
00389
00390 if (!_dbus_string_append_byte (dest, endian))
00391 {
00392 _dbus_warn ("could not append endianness\n");
00393 goto parse_failed;
00394 }
00395
00396 i = 0;
00397 while (i < 3)
00398 {
00399 if (!_dbus_string_append_byte (dest, '\0'))
00400 {
00401 _dbus_warn ("could not append nul pad\n");
00402 goto parse_failed;
00403 }
00404 ++i;
00405 }
00406
00407 _dbus_string_init_const (&name, "Header");
00408 if (!append_saved_length (dest, length_hash,
00409 &name, _dbus_string_get_length (dest),
00410 endian))
00411 goto parse_failed;
00412
00413 _dbus_string_init_const (&name, "Body");
00414 if (!append_saved_length (dest, length_hash,
00415 &name, _dbus_string_get_length (dest),
00416 endian))
00417 goto parse_failed;
00418
00419
00420 if (!_dbus_marshal_int32 (dest, endian, 1))
00421 {
00422 _dbus_warn ("couldn't append client serial\n");
00423 goto parse_failed;
00424 }
00425 }
00426 else if (_dbus_string_starts_with_c_str (&line,
00427 "BIG_ENDIAN"))
00428 {
00429 endian = DBUS_BIG_ENDIAN;
00430 }
00431 else if (_dbus_string_starts_with_c_str (&line,
00432 "LITTLE_ENDIAN"))
00433 {
00434 endian = DBUS_LITTLE_ENDIAN;
00435 }
00436 else if (_dbus_string_starts_with_c_str (&line,
00437 "OPPOSITE_ENDIAN"))
00438 {
00439 if (endian == DBUS_BIG_ENDIAN)
00440 endian = DBUS_LITTLE_ENDIAN;
00441 else
00442 endian = DBUS_BIG_ENDIAN;
00443 }
00444 else if (_dbus_string_starts_with_c_str (&line,
00445 "ALIGN"))
00446 {
00447 long val;
00448 int end;
00449 int orig_len;
00450
00451 _dbus_string_delete_first_word (&line);
00452
00453 if (!_dbus_string_parse_int (&line, 0, &val, &end))
00454 {
00455 _dbus_warn ("Failed to parse integer\n");
00456 goto parse_failed;
00457 }
00458
00459 if (val > 8)
00460 {
00461 _dbus_warn ("Aligning to %ld boundary is crack\n",
00462 val);
00463 goto parse_failed;
00464 }
00465
00466 orig_len = _dbus_string_get_length (dest);
00467
00468 if (!_dbus_string_align_length (dest, val))
00469 goto parse_failed;
00470
00471 if (_dbus_string_parse_int (&line, end, &val, NULL))
00472 {
00473
00474
00475
00476 if (val < 0 || val > 255)
00477 {
00478 _dbus_warn ("can't fill align padding with %ld, must be a byte value\n", val);
00479 goto parse_failed;
00480 }
00481
00482 end = orig_len;
00483 while (end < _dbus_string_get_length (dest))
00484 {
00485 _dbus_string_set_byte (dest, end, val);
00486 ++end;
00487 }
00488 }
00489 }
00490 else if (_dbus_string_starts_with_c_str (&line, "UNALIGN"))
00491 {
00492 unalign = TRUE;
00493 just_set_unalign = TRUE;
00494 }
00495 else if (_dbus_string_starts_with_c_str (&line, "CHOP"))
00496 {
00497 long val;
00498
00499
00500
00501
00502
00503 _dbus_string_delete_first_word (&line);
00504
00505 if (!_dbus_string_parse_int (&line, 0, &val, NULL))
00506 {
00507 _dbus_warn ("Failed to parse integer to chop\n");
00508 goto parse_failed;
00509 }
00510
00511 if (val > _dbus_string_get_length (dest))
00512 {
00513 _dbus_warn ("Trying to chop %ld bytes but we only have %d\n",
00514 val,
00515 _dbus_string_get_length (dest));
00516 goto parse_failed;
00517 }
00518
00519 _dbus_string_shorten (dest, val);
00520 }
00521 else if (_dbus_string_starts_with_c_str (&line,
00522 "START_LENGTH"))
00523 {
00524 _dbus_string_delete_first_word (&line);
00525
00526 if (!save_start (length_hash, &line,
00527 _dbus_string_get_length (dest)))
00528 {
00529 _dbus_warn ("failed to save length start\n");
00530 goto parse_failed;
00531 }
00532 }
00533 else if (_dbus_string_starts_with_c_str (&line,
00534 "END_LENGTH"))
00535 {
00536 _dbus_string_delete_first_word (&line);
00537
00538 if (!save_length (length_hash, &line,
00539 _dbus_string_get_length (dest)))
00540 {
00541 _dbus_warn ("failed to save length end\n");
00542 goto parse_failed;
00543 }
00544 }
00545 else if (_dbus_string_starts_with_c_str (&line,
00546 "LENGTH"))
00547 {
00548 SAVE_FOR_UNALIGN (dest, 4);
00549
00550 _dbus_string_delete_first_word (&line);
00551
00552 if (!append_saved_length (dest, length_hash,
00553 &line,
00554 unalign ? align_pad_start : align_pad_end,
00555 endian))
00556 {
00557 _dbus_warn ("failed to add LENGTH\n");
00558 goto parse_failed;
00559 }
00560
00561 PERFORM_UNALIGN (dest);
00562 }
00563 else if (_dbus_string_starts_with_c_str (&line,
00564 "FIELD_NAME"))
00565 {
00566 _dbus_string_delete_first_word (&line);
00567
00568 if (_dbus_string_get_length (&line) != 4)
00569 {
00570 _dbus_warn ("Field name must be four characters not \"%s\"\n",
00571 _dbus_string_get_const_data (&line));
00572 goto parse_failed;
00573 }
00574
00575 if (unalign)
00576 unalign = FALSE;
00577 else
00578 _dbus_string_align_length (dest, 4);
00579
00580 if (!_dbus_string_copy (&line, 0, dest,
00581 _dbus_string_get_length (dest)))
00582 goto parse_failed;
00583 }
00584 else if (_dbus_string_starts_with_c_str (&line,
00585 "TYPE"))
00586 {
00587 int code;
00588
00589 _dbus_string_delete_first_word (&line);
00590
00591 if (_dbus_string_starts_with_c_str (&line, "INVALID"))
00592 code = DBUS_TYPE_INVALID;
00593 else if (_dbus_string_starts_with_c_str (&line, "NIL"))
00594 code = DBUS_TYPE_NIL;
00595 else if (_dbus_string_starts_with_c_str (&line, "BYTE"))
00596 code = DBUS_TYPE_BYTE;
00597 else if (_dbus_string_starts_with_c_str (&line, "BOOLEAN"))
00598 code = DBUS_TYPE_BOOLEAN;
00599 else if (_dbus_string_starts_with_c_str (&line, "INT32"))
00600 code = DBUS_TYPE_INT32;
00601 else if (_dbus_string_starts_with_c_str (&line, "UINT32"))
00602 code = DBUS_TYPE_UINT32;
00603 else if (_dbus_string_starts_with_c_str (&line, "DOUBLE"))
00604 code = DBUS_TYPE_DOUBLE;
00605 else if (_dbus_string_starts_with_c_str (&line, "STRING"))
00606 code = DBUS_TYPE_STRING;
00607 else if (_dbus_string_starts_with_c_str (&line, "NAMED"))
00608 code = DBUS_TYPE_NAMED;
00609 else if (_dbus_string_starts_with_c_str (&line, "ARRAY"))
00610 code = DBUS_TYPE_ARRAY;
00611 else if (_dbus_string_starts_with_c_str (&line, "DICT"))
00612 code = DBUS_TYPE_DICT;
00613 else
00614 {
00615 _dbus_warn ("%s is not a valid type name\n", _dbus_string_get_const_data (&line));
00616 goto parse_failed;
00617 }
00618
00619 if (!_dbus_string_append_byte (dest, code))
00620 {
00621 _dbus_warn ("could not append typecode byte\n");
00622 goto parse_failed;
00623 }
00624 }
00625 else if (_dbus_string_starts_with_c_str (&line,
00626 "BYTE_ARRAY"))
00627 {
00628 SAVE_FOR_UNALIGN (dest, 4);
00629 int i, len, allocated;
00630 unsigned char *values;
00631 unsigned char b;
00632 long val;
00633
00634 allocated = 4;
00635 values = dbus_new (unsigned char, allocated);
00636 if (!values)
00637 {
00638 _dbus_warn ("could not allocate memory for BYTE_ARRAY\n");
00639 goto parse_failed;
00640 }
00641
00642 len = 0;
00643
00644 _dbus_string_delete_first_word (&line);
00645 _dbus_string_skip_blank (&line, 0, &i);
00646 b = _dbus_string_get_byte (&line, i++);
00647
00648 if (b != '{')
00649 goto parse_failed;
00650
00651 while (i < _dbus_string_get_length (&line))
00652 {
00653 _dbus_string_skip_blank (&line, i, &i);
00654
00655 if (_dbus_string_get_byte (&line, i) == '\'' &&
00656 _dbus_string_get_length (&line) >= i + 4 &&
00657 _dbus_string_get_byte (&line, i + 1) == '\\' &&
00658 _dbus_string_get_byte (&line, i + 2) == '\'' &&
00659 _dbus_string_get_byte (&line, i + 3) == '\'')
00660 {
00661 val = '\'';
00662 i += 4;
00663 }
00664 else if (_dbus_string_get_byte (&line, i) == '\'' &&
00665 _dbus_string_get_length (&line) >= i + 3 &&
00666 _dbus_string_get_byte (&line, i + 2) == '\'')
00667 {
00668 val = _dbus_string_get_byte (&line, i + 1);
00669 i += 3;
00670 }
00671 else
00672 {
00673 if (!_dbus_string_parse_int (&line, i, &val, &i))
00674 {
00675 _dbus_warn ("Failed to parse integer for BYTE_ARRAY\n");
00676 goto parse_failed;
00677 }
00678
00679 if (val < 0 || val > 255)
00680 {
00681 _dbus_warn ("A byte must be in range 0-255 not %ld\n",
00682 val);
00683 goto parse_failed;
00684 }
00685 }
00686
00687 values[len++] = val;
00688 if (len == allocated)
00689 {
00690 allocated *= 2;
00691 values = dbus_realloc (values, allocated * sizeof (unsigned char));
00692 if (!values)
00693 {
00694 _dbus_warn ("could not allocate memory for BYTE_ARRAY\n");
00695 goto parse_failed;
00696 }
00697 }
00698
00699 _dbus_string_skip_blank (&line, i, &i);
00700
00701 b = _dbus_string_get_byte (&line, i++);
00702
00703 if (b == '}')
00704 break;
00705 else if (b != ',')
00706 goto parse_failed;
00707 }
00708
00709 if (!_dbus_marshal_int32 (dest, endian, len) ||
00710 !_dbus_string_append_len (dest, values, len))
00711 {
00712 _dbus_warn ("failed to append BYTE_ARRAY\n");
00713 goto parse_failed;
00714 }
00715 dbus_free (values);
00716
00717 PERFORM_UNALIGN (dest);
00718 }
00719 else if (_dbus_string_starts_with_c_str (&line,
00720 "BOOLEAN_ARRAY"))
00721 {
00722 SAVE_FOR_UNALIGN (dest, 4);
00723 int i, len, allocated;
00724 unsigned char *values;
00725 unsigned char b, val;
00726
00727 allocated = 4;
00728 values = dbus_new (unsigned char, allocated);
00729 if (!values)
00730 {
00731 _dbus_warn ("could not allocate memory for BOOLEAN_ARRAY\n");
00732 goto parse_failed;
00733 }
00734
00735 len = 0;
00736
00737 _dbus_string_delete_first_word (&line);
00738 _dbus_string_skip_blank (&line, 0, &i);
00739 b = _dbus_string_get_byte (&line, i++);
00740
00741 if (b != '{')
00742 goto parse_failed;
00743
00744 while (i < _dbus_string_get_length (&line))
00745 {
00746 _dbus_string_skip_blank (&line, i, &i);
00747
00748 if (_dbus_string_find_to (&line, i, i + 5,
00749 "false", NULL))
00750 {
00751 i += 5;
00752 val = TRUE;
00753 }
00754 else if (_dbus_string_find_to (&line, i, i + 4,
00755 "true", NULL))
00756 {
00757 i += 4;
00758 val = FALSE;
00759 }
00760 else
00761 {
00762 _dbus_warn ("could not parse BOOLEAN_ARRAY\n");
00763 goto parse_failed;
00764 }
00765
00766 values[len++] = val;
00767 if (len == allocated)
00768 {
00769 allocated *= 2;
00770 values = dbus_realloc (values, allocated * sizeof (unsigned char));
00771 if (!values)
00772 {
00773 _dbus_warn ("could not allocate memory for BOOLEAN_ARRAY\n");
00774 goto parse_failed;
00775 }
00776 }
00777
00778 _dbus_string_skip_blank (&line, i, &i);
00779
00780 b = _dbus_string_get_byte (&line, i++);
00781
00782 if (b == '}')
00783 break;
00784 else if (b != ',')
00785 goto parse_failed;
00786 }
00787
00788 if (!_dbus_marshal_int32 (dest, endian, len) ||
00789 !_dbus_string_append_len (dest, values, len))
00790 {
00791 _dbus_warn ("failed to append BOOLEAN_ARRAY\n");
00792 goto parse_failed;
00793 }
00794 dbus_free (values);
00795
00796 PERFORM_UNALIGN (dest);
00797 }
00798 else if (_dbus_string_starts_with_c_str (&line,
00799 "INT32_ARRAY"))
00800 {
00801 SAVE_FOR_UNALIGN (dest, 4);
00802 int i, len, allocated;
00803 dbus_int32_t *values;
00804 long val;
00805 unsigned char b;
00806
00807 allocated = 4;
00808 values = dbus_new (dbus_int32_t, allocated);
00809 if (!values)
00810 {
00811 _dbus_warn ("could not allocate memory for INT32_ARRAY\n");
00812 goto parse_failed;
00813 }
00814
00815 len = 0;
00816
00817 _dbus_string_delete_first_word (&line);
00818 _dbus_string_skip_blank (&line, 0, &i);
00819 b = _dbus_string_get_byte (&line, i++);
00820
00821 if (b != '{')
00822 goto parse_failed;
00823
00824 while (i < _dbus_string_get_length (&line))
00825 {
00826 _dbus_string_skip_blank (&line, i, &i);
00827
00828 if (!_dbus_string_parse_int (&line, i, &val, &i))
00829 {
00830 _dbus_warn ("could not parse integer for INT32_ARRAY\n");
00831 goto parse_failed;
00832 }
00833
00834 values[len++] = val;
00835 if (len == allocated)
00836 {
00837 allocated *= 2;
00838 values = dbus_realloc (values, allocated * sizeof (dbus_int32_t));
00839 if (!values)
00840 {
00841 _dbus_warn ("could not allocate memory for INT32_ARRAY\n");
00842 goto parse_failed;
00843 }
00844 }
00845
00846 _dbus_string_skip_blank (&line, i, &i);
00847
00848 b = _dbus_string_get_byte (&line, i++);
00849
00850 if (b == '}')
00851 break;
00852 else if (b != ',')
00853 goto parse_failed;
00854 }
00855
00856 if (!_dbus_marshal_int32_array (dest, endian, values, len))
00857 {
00858 _dbus_warn ("failed to append INT32_ARRAY\n");
00859 goto parse_failed;
00860 }
00861 dbus_free (values);
00862
00863 PERFORM_UNALIGN (dest);
00864 }
00865 else if (_dbus_string_starts_with_c_str (&line,
00866 "UINT32_ARRAY"))
00867 {
00868 SAVE_FOR_UNALIGN (dest, 4);
00869 int i, len, allocated;
00870 dbus_uint32_t *values;
00871 long val;
00872 unsigned char b;
00873
00874 allocated = 4;
00875 values = dbus_new (dbus_uint32_t, allocated);
00876 if (!values)
00877 {
00878 _dbus_warn ("could not allocate memory for UINT32_ARRAY\n");
00879 goto parse_failed;
00880 }
00881
00882 len = 0;
00883
00884 _dbus_string_delete_first_word (&line);
00885 _dbus_string_skip_blank (&line, 0, &i);
00886 b = _dbus_string_get_byte (&line, i++);
00887
00888 if (b != '{')
00889 goto parse_failed;
00890
00891 while (i < _dbus_string_get_length (&line))
00892 {
00893 _dbus_string_skip_blank (&line, i, &i);
00894
00895 if (!_dbus_string_parse_int (&line, i, &val, &i))
00896 {
00897 _dbus_warn ("could not parse integer for UINT32_ARRAY\n");
00898 goto parse_failed;
00899 }
00900
00901 values[len++] = val;
00902 if (len == allocated)
00903 {
00904 allocated *= 2;
00905 values = dbus_realloc (values, allocated * sizeof (dbus_uint32_t));
00906 if (!values)
00907 {
00908 _dbus_warn ("could not allocate memory for UINT32_ARRAY\n");
00909 goto parse_failed;
00910 }
00911 }
00912
00913 _dbus_string_skip_blank (&line, i, &i);
00914
00915 b = _dbus_string_get_byte (&line, i++);
00916
00917 if (b == '}')
00918 break;
00919 else if (b != ',')
00920 goto parse_failed;
00921 }
00922
00923 if (!_dbus_marshal_uint32_array (dest, endian, values, len))
00924 {
00925 _dbus_warn ("failed to append UINT32_ARRAY\n");
00926 goto parse_failed;
00927 }
00928 dbus_free (values);
00929
00930 PERFORM_UNALIGN (dest);
00931 }
00932 else if (_dbus_string_starts_with_c_str (&line,
00933 "DOUBLE_ARRAY"))
00934 {
00935 SAVE_FOR_UNALIGN (dest, 8);
00936 int i, len, allocated;
00937 double *values;
00938 double val;
00939 unsigned char b;
00940
00941 allocated = 4;
00942 values = dbus_new (double, allocated);
00943 if (!values)
00944 {
00945 _dbus_warn ("could not allocate memory for DOUBLE_ARRAY\n");
00946 goto parse_failed;
00947 }
00948
00949 len = 0;
00950
00951 _dbus_string_delete_first_word (&line);
00952 _dbus_string_skip_blank (&line, 0, &i);
00953 b = _dbus_string_get_byte (&line, i++);
00954
00955 if (b != '{')
00956 goto parse_failed;
00957
00958 while (i < _dbus_string_get_length (&line))
00959 {
00960 _dbus_string_skip_blank (&line, i, &i);
00961
00962 if (!_dbus_string_parse_double (&line, i, &val, &i))
00963 {
00964 _dbus_warn ("could not parse double for DOUBLE_ARRAY\n");
00965 goto parse_failed;
00966 }
00967
00968 values[len++] = val;
00969 if (len == allocated)
00970 {
00971 allocated *= 2;
00972 values = dbus_realloc (values, allocated * sizeof (double));
00973 if (!values)
00974 {
00975 _dbus_warn ("could not allocate memory for DOUBLE_ARRAY\n");
00976 goto parse_failed;
00977 }
00978 }
00979
00980 _dbus_string_skip_blank (&line, i, &i);
00981
00982 b = _dbus_string_get_byte (&line, i++);
00983
00984 if (b == '}')
00985 break;
00986 else if (b != ',')
00987 goto parse_failed;
00988 }
00989
00990 if (!_dbus_marshal_double_array (dest, endian, values, len))
00991 {
00992 _dbus_warn ("failed to append DOUBLE_ARRAY\n");
00993 goto parse_failed;
00994 }
00995 dbus_free (values);
00996
00997 PERFORM_UNALIGN (dest);
00998 }
00999 else if (_dbus_string_starts_with_c_str (&line,
01000 "STRING_ARRAY"))
01001 {
01002 SAVE_FOR_UNALIGN (dest, 4);
01003 int i, len, allocated;
01004 char **values;
01005 char *val;
01006 DBusString val_str;
01007 unsigned char b;
01008
01009 allocated = 4;
01010 values = dbus_new (char *, allocated);
01011 if (!values)
01012 {
01013 _dbus_warn ("could not allocate memory for STRING_ARRAY\n");
01014 goto parse_failed;
01015 }
01016
01017 len = 0;
01018
01019 _dbus_string_delete_first_word (&line);
01020 _dbus_string_skip_blank (&line, 0, &i);
01021 b = _dbus_string_get_byte (&line, i++);
01022
01023 if (b != '{')
01024 goto parse_failed;
01025
01026 _dbus_string_init (&val_str);
01027 while (i < _dbus_string_get_length (&line))
01028 {
01029 _dbus_string_skip_blank (&line, i, &i);
01030
01031 if (!append_quoted_string (&val_str, &line, i, &i))
01032 {
01033 _dbus_warn ("could not parse quoted string for STRING_ARRAY\n");
01034 goto parse_failed;
01035 }
01036 i++;
01037
01038 if (!_dbus_string_steal_data (&val_str, &val))
01039 {
01040 _dbus_warn ("could not allocate memory for STRING_ARRAY string\n");
01041 goto parse_failed;
01042 }
01043
01044 values[len++] = val;
01045 if (len == allocated)
01046 {
01047 allocated *= 2;
01048 values = dbus_realloc (values, allocated * sizeof (char *));
01049 if (!values)
01050 {
01051 _dbus_warn ("could not allocate memory for STRING_ARRAY\n");
01052 goto parse_failed;
01053 }
01054 }
01055
01056 _dbus_string_skip_blank (&line, i, &i);
01057
01058 b = _dbus_string_get_byte (&line, i++);
01059
01060 if (b == '}')
01061 break;
01062 else if (b != ',')
01063 {
01064 _dbus_warn ("missing comma when parsing STRING_ARRAY\n");
01065 goto parse_failed;
01066 }
01067 }
01068 _dbus_string_free (&val_str);
01069
01070 if (!_dbus_marshal_string_array (dest, endian, (const char **)values, len))
01071 {
01072 _dbus_warn ("failed to append STRING_ARRAY\n");
01073 goto parse_failed;
01074 }
01075
01076 values[len] = NULL;
01077 dbus_free_string_array (values);
01078
01079 PERFORM_UNALIGN (dest);
01080 }
01081 else if (_dbus_string_starts_with_c_str (&line, "BYTE"))
01082 {
01083 unsigned char the_byte;
01084
01085 _dbus_string_delete_first_word (&line);
01086
01087 if (_dbus_string_equal_c_str (&line, "'\\''"))
01088 the_byte = '\'';
01089 else if (_dbus_string_get_byte (&line, 0) == '\'' &&
01090 _dbus_string_get_length (&line) >= 3 &&
01091 _dbus_string_get_byte (&line, 2) == '\'')
01092 the_byte = _dbus_string_get_byte (&line, 1);
01093 else
01094 {
01095 long val;
01096 if (!_dbus_string_parse_int (&line, 0, &val, NULL))
01097 {
01098 _dbus_warn ("Failed to parse integer for BYTE\n");
01099 goto parse_failed;
01100 }
01101
01102 if (val > 255)
01103 {
01104 _dbus_warn ("A byte must be in range 0-255 not %ld\n",
01105 val);
01106 goto parse_failed;
01107 }
01108 the_byte = (unsigned char) val;
01109 }
01110
01111 _dbus_string_append_byte (dest, the_byte);
01112 }
01113 else if (_dbus_string_starts_with_c_str (&line,
01114 "BOOLEAN"))
01115 {
01116 unsigned char val;
01117
01118 _dbus_string_delete_first_word (&line);
01119
01120 if (_dbus_string_starts_with_c_str (&line, "true"))
01121 val = TRUE;
01122 else if (_dbus_string_starts_with_c_str (&line, "false"))
01123 val = FALSE;
01124 else
01125 {
01126 _dbus_warn ("could not parse BOOLEAN\n");
01127 goto parse_failed;
01128 }
01129 if (!_dbus_string_append_byte (dest, val))
01130 {
01131 _dbus_warn ("failed to append BOOLEAN\n");
01132 goto parse_failed;
01133 }
01134 }
01135
01136 else if (_dbus_string_starts_with_c_str (&line,
01137 "INT32"))
01138 {
01139 SAVE_FOR_UNALIGN (dest, 4);
01140 long val;
01141
01142 _dbus_string_delete_first_word (&line);
01143
01144 if (!_dbus_string_parse_int (&line, 0, &val, NULL))
01145 {
01146 _dbus_warn ("could not parse integer for INT32\n");
01147 goto parse_failed;
01148 }
01149
01150 if (!_dbus_marshal_int32 (dest, endian,
01151 val))
01152 {
01153 _dbus_warn ("failed to append INT32\n");
01154 goto parse_failed;
01155 }
01156
01157 PERFORM_UNALIGN (dest);
01158 }
01159 else if (_dbus_string_starts_with_c_str (&line,
01160 "UINT32"))
01161 {
01162 SAVE_FOR_UNALIGN (dest, 4);
01163 unsigned long val;
01164
01165 _dbus_string_delete_first_word (&line);
01166
01167 if (!_dbus_string_parse_uint (&line, 0, &val, NULL))
01168 goto parse_failed;
01169
01170 if (!_dbus_marshal_uint32 (dest, endian,
01171 val))
01172 {
01173 _dbus_warn ("failed to append UINT32\n");
01174 goto parse_failed;
01175 }
01176
01177 PERFORM_UNALIGN (dest);
01178 }
01179 else if (_dbus_string_starts_with_c_str (&line,
01180 "DOUBLE"))
01181 {
01182 SAVE_FOR_UNALIGN (dest, 8);
01183 double val;
01184
01185 _dbus_string_delete_first_word (&line);
01186
01187 if (!_dbus_string_parse_double (&line, 0, &val, NULL))
01188 goto parse_failed;
01189
01190 if (!_dbus_marshal_double (dest, endian,
01191 val))
01192 {
01193 _dbus_warn ("failed to append DOUBLE\n");
01194 goto parse_failed;
01195 }
01196
01197 PERFORM_UNALIGN (dest);
01198 }
01199 else if (_dbus_string_starts_with_c_str (&line,
01200 "STRING"))
01201 {
01202 SAVE_FOR_UNALIGN (dest, 4);
01203 int size_offset;
01204 int old_len;
01205
01206 _dbus_string_delete_first_word (&line);
01207
01208 size_offset = _dbus_string_get_length (dest);
01209 size_offset = _DBUS_ALIGN_VALUE (size_offset, 4);
01210 if (!_dbus_marshal_uint32 (dest, endian, 0))
01211 {
01212 _dbus_warn ("Failed to append string size\n");
01213 goto parse_failed;
01214 }
01215
01216 old_len = _dbus_string_get_length (dest);
01217 if (!append_quoted_string (dest, &line, 0, NULL))
01218 {
01219 _dbus_warn ("Failed to append quoted string\n");
01220 goto parse_failed;
01221 }
01222
01223 _dbus_marshal_set_uint32 (dest, endian, size_offset,
01224
01225 _dbus_string_get_length (dest) - old_len - 1);
01226
01227 PERFORM_UNALIGN (dest);
01228 }
01229 else
01230 goto parse_failed;
01231
01232 if (!just_set_unalign && unalign)
01233 {
01234 _dbus_warn ("UNALIGN prior to something that isn't aligned\n");
01235 goto parse_failed;
01236 }
01237
01238 goto next_iteration;
01239
01240 parse_failed:
01241 {
01242 _dbus_warn ("couldn't process line %d \"%s\"\n",
01243 line_no, _dbus_string_get_const_data (&line));
01244 goto out;
01245 }
01246 }
01247
01248 _dbus_hash_iter_init (length_hash, &iter);
01249 while (_dbus_hash_iter_next (&iter))
01250 {
01251 SavedLength *sl = _dbus_hash_iter_get_value (&iter);
01252 const char *s;
01253
01254 s = _dbus_string_get_const_data (&sl->name);
01255
01256 if (sl->length < 0)
01257 {
01258 _dbus_warn ("Used LENGTH %s but never did END_LENGTH\n",
01259 s);
01260 goto out;
01261 }
01262 else if (sl->offset < 0)
01263 {
01264 _dbus_warn ("Did END_LENGTH %s but never used LENGTH\n",
01265 s);
01266 goto out;
01267 }
01268 else
01269 {
01270 if (sl->start < 0)
01271 sl->start = 0;
01272
01273 _dbus_verbose ("Filling in length %s endian = %d offset = %d start = %d length = %d\n",
01274 s, sl->endian, sl->offset, sl->start, sl->length);
01275 _dbus_marshal_set_int32 (dest,
01276 sl->endian,
01277 sl->offset,
01278 sl->length - sl->start);
01279 }
01280
01281 _dbus_hash_iter_remove_entry (&iter);
01282 }
01283
01284 retval = TRUE;
01285
01286 _dbus_verbose_bytes_of_string (dest, 0, _dbus_string_get_length (dest));
01287
01288 out:
01289 if (length_hash != NULL)
01290 _dbus_hash_table_unref (length_hash);
01291
01292 _dbus_string_free (&file);
01293 _dbus_string_free (&line);
01294 return retval;
01295 }
01296
01298 #endif