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
00338
static dbus_bool_t
00339 parse_basic_type (
DBusString *src,
char type,
00340
DBusString *dest, dbus_bool_t *unalign,
00341
int endian)
00342 {
00343
int align;
00344
int align_pad_start, align_pad_end;
00345
unsigned char data[16];
00346
00347
switch (type)
00348 {
00349
case DBUS_TYPE_BYTE:
00350
case DBUS_TYPE_BOOLEAN:
00351 align = 1;
00352
break;
00353
case DBUS_TYPE_UINT32:
00354
case DBUS_TYPE_INT32:
00355 align = 4;
00356
break;
00357
case DBUS_TYPE_DOUBLE:
00358 align = 8;
00359
break;
00360
default:
00361
_dbus_assert_not_reached (
"not a basic type");
00362
break;
00363 }
00364
00365 align_pad_start =
_dbus_string_get_length (dest);
00366 align_pad_end = _DBUS_ALIGN_VALUE (align_pad_start, align);
00367
00368
_dbus_string_delete_first_word (src);
00369
00370
if (!_dbus_string_parse_basic_type (src, type, 0, data, NULL))
00371 {
00372 _dbus_verbose (
"failed to parse type '%c'", type);
00373
return FALSE;
00374 }
00375
00376
if (!
_dbus_marshal_basic_type (dest, type, data, endian))
00377 {
00378 _dbus_verbose (
"failed to marshal type '%c'", type);
00379
return FALSE;
00380 }
00381
00382
if (*unalign)
00383 {
00384
_dbus_string_delete (dest, align_pad_start,
00385 align_pad_end - align_pad_start);
00386 *unalign =
FALSE;
00387 }
00388
00389
return TRUE;
00390 }
00391
00392
static dbus_bool_t
00393 parse_basic_array (
DBusString *src,
char type,
00394
DBusString *dest, dbus_bool_t *unalign,
00395
int endian)
00396 {
00397
int array_align, elem_size;
00398
int i, len, allocated;
00399
unsigned char *values, b;
00400
int values_offset;
00401
int align_pad_start, align_pad_end;
00402
dbus_bool_t retval =
FALSE;
00403
00404 array_align = 4;
00405
switch (type)
00406 {
00407
case DBUS_TYPE_BYTE:
00408
case DBUS_TYPE_BOOLEAN:
00409 elem_size = 1;
00410
break;
00411
case DBUS_TYPE_UINT32:
00412
case DBUS_TYPE_INT32:
00413 elem_size = 4;
00414
break;
00415
case DBUS_TYPE_DOUBLE:
00416 array_align = 8;
00417 elem_size = 8;
00418
break;
00419
default:
00420
_dbus_assert_not_reached (
"not a basic type");
00421
break;
00422 }
00423
00424 align_pad_start =
_dbus_string_get_length (dest);
00425 align_pad_end = _DBUS_ALIGN_VALUE (align_pad_start, array_align);
00426
00427 len = 0;
00428 allocated = 2;
00429 values =
NULL;
00430 values_offset = 0;
00431
00432
_dbus_string_delete_first_word (src);
00433
_dbus_string_skip_blank (src, 0, &i);
00434 b =
_dbus_string_get_byte (src, i++);
00435
00436
if (b !=
'{')
00437
goto failed;
00438
00439
while (i <
_dbus_string_get_length (src))
00440 {
00441
_dbus_string_skip_blank (src, i, &i);
00442
00443
if (!values || len == allocated - 1)
00444 {
00445 allocated *= 2;
00446 values =
dbus_realloc (values, allocated * elem_size);
00447
if (!values)
00448 {
00449
_dbus_warn (
"could not allocate memory for '%c' ARRAY\n", type);
00450
goto failed;
00451 }
00452 }
00453
00454
if (!_dbus_string_parse_basic_type (src, type, i, values + values_offset, &i))
00455 {
00456
_dbus_warn (
"could not parse integer element %d of '%c' ARRAY\n", len, type);
00457
goto failed;
00458 }
00459
00460 values_offset += elem_size;
00461 len++;
00462
00463
_dbus_string_skip_blank (src, i, &i);
00464
00465 b =
_dbus_string_get_byte (src, i++);
00466
00467
if (b ==
'}')
00468
break;
00469
else if (b !=
',')
00470
goto failed;
00471 }
00472
00473
if (!
_dbus_marshal_basic_type_array (dest, type, values, len, endian))
00474 {
00475
_dbus_warn (
"failed to append '%c' ARRAY\n", type);
00476
goto failed;
00477 }
00478
00479
if (*unalign)
00480 {
00481
_dbus_string_delete (dest, align_pad_start,
00482 align_pad_end - align_pad_start);
00483 *unalign =
FALSE;
00484 }
00485
00486 retval =
TRUE;
00487
00488 failed:
00489
dbus_free (values);
00490
return retval;
00491 }
00492
00493
static char
00494 lookup_basic_type (
const DBusString *str, dbus_bool_t *is_array)
00495 {
00496
int i;
00497
char type = DBUS_TYPE_INVALID;
00498
static struct {
00499
const char *name;
00500
char type;
00501 } name_to_type[] = {
00502 {
"BYTE", DBUS_TYPE_BYTE },
00503 {
"BOOLEAN", DBUS_TYPE_BOOLEAN },
00504 {
"INT32", DBUS_TYPE_INT32 },
00505 {
"UINT32", DBUS_TYPE_UINT32 },
00506 {
"DOUBLE", DBUS_TYPE_DOUBLE }
00507 };
00508
00509
for (i = 0; i <
_DBUS_N_ELEMENTS(name_to_type); i++)
00510 {
00511
const char *name = name_to_type[i].name;
00512
if (
_dbus_string_starts_with_c_str (str, name))
00513 {
00514
int offset = strlen (name);
00515 type = name_to_type[i].type;
00516
if (is_array)
00517 *is_array =
_dbus_string_find (str, offset,
"_ARRAY", NULL);
00518
break;
00519 }
00520 }
00521
00522
return type;
00523 }
00524
00576
dbus_bool_t
00577 _dbus_message_data_load (
DBusString *dest,
00578
const DBusString *filename)
00579 {
00580
DBusString file;
00581
DBusError error;
00582
DBusString line;
00583
dbus_bool_t retval;
00584
int line_no;
00585
dbus_bool_t unalign;
00586
DBusHashTable *length_hash;
00587
int endian;
00588
DBusHashIter iter;
00589
char type;
00590
dbus_bool_t is_array;
00591
00592 retval =
FALSE;
00593 length_hash =
NULL;
00594
00595
if (!
_dbus_string_init (&file))
00596
return FALSE;
00597
00598
if (!
_dbus_string_init (&line))
00599 {
00600
_dbus_string_free (&file);
00601
return FALSE;
00602 }
00603
00604 _dbus_verbose (
"Loading %s\n", _dbus_string_get_const_data (filename));
00605
00606
dbus_error_init (&error);
00607
if (!
_dbus_file_get_contents (&file, filename, &error))
00608 {
00609
_dbus_warn (
"Getting contents of %s failed: %s\n",
00610 _dbus_string_get_const_data (filename), error.
message);
00611
dbus_error_free (&error);
00612
goto out;
00613 }
00614
00615 length_hash =
_dbus_hash_table_new (DBUS_HASH_STRING,
00616 NULL,
00617 free_saved_length);
00618
if (length_hash ==
NULL)
00619
goto out;
00620
00621 endian = DBUS_COMPILER_BYTE_ORDER;
00622 unalign =
FALSE;
00623 line_no = 0;
00624 next_iteration:
00625
while (
_dbus_string_pop_line (&file, &line))
00626 {
00627
dbus_bool_t just_set_unalign;
00628
00629 just_set_unalign =
FALSE;
00630 line_no += 1;
00631
00632
_dbus_string_delete_leading_blanks (&line);
00633
00634
if (
_dbus_string_get_length (&line) == 0)
00635 {
00636
00637
goto next_iteration;
00638 }
00639
else if (
_dbus_string_starts_with_c_str (&line,
00640
"#"))
00641 {
00642
00643
goto next_iteration;
00644 }
00645
else if (
_dbus_string_starts_with_c_str (&line,
00646
"VALID_HEADER"))
00647 {
00648
int i;
00649
DBusString name;
00650
int message_type;
00651
00652
if (
_dbus_string_get_length (&line) < (
int) strlen (
"VALID_HEADER "))
00653 {
00654
_dbus_warn (
"no args to VALID_HEADER\n");
00655
goto parse_failed;
00656 }
00657
00658
if (!
_dbus_string_append_byte (dest, endian))
00659 {
00660
_dbus_warn (
"could not append endianness\n");
00661
goto parse_failed;
00662 }
00663
00664 message_type = message_type_from_string (&line,
00665 strlen (
"VALID_HEADER "));
00666
if (message_type < 0)
00667 {
00668
_dbus_warn (
"VALID_HEADER not followed by space then known message type\n");
00669
goto parse_failed;
00670 }
00671
00672
if (!
_dbus_string_append_byte (dest, message_type))
00673 {
00674
_dbus_warn (
"could not append message type\n");
00675
goto parse_failed;
00676 }
00677
00678 i = 0;
00679
while (i < 2)
00680 {
00681
if (!
_dbus_string_append_byte (dest,
'\0'))
00682 {
00683
_dbus_warn (
"could not append nul pad\n");
00684
goto parse_failed;
00685 }
00686 ++i;
00687 }
00688
00689
_dbus_string_init_const (&name,
"Header");
00690
if (!append_saved_length (dest, length_hash,
00691 &name, _dbus_string_get_length (dest),
00692 endian))
00693
goto parse_failed;
00694
00695
_dbus_string_init_const (&name,
"Body");
00696
if (!append_saved_length (dest, length_hash,
00697 &name, _dbus_string_get_length (dest),
00698 endian))
00699
goto parse_failed;
00700
00701
00702
if (!
_dbus_marshal_uint32 (dest, endian, 1))
00703 {
00704
_dbus_warn (
"couldn't append client serial\n");
00705
goto parse_failed;
00706 }
00707 }
00708
else if (
_dbus_string_starts_with_c_str (&line,
00709
"REQUIRED_FIELDS"))
00710 {
00711
if (!append_string_field (dest, endian,
00712 DBUS_HEADER_FIELD_INTERFACE,
00713 DBUS_TYPE_STRING,
00714
"org.freedesktop.BlahBlahInterface"))
00715
goto parse_failed;
00716
if (!append_string_field (dest, endian,
00717 DBUS_HEADER_FIELD_MEMBER,
00718 DBUS_TYPE_STRING,
00719
"BlahBlahMethod"))
00720
goto parse_failed;
00721
if (!append_string_field (dest, endian,
00722 DBUS_HEADER_FIELD_PATH,
00723 DBUS_TYPE_OBJECT_PATH,
00724
"/blah/blah/path"))
00725
goto parse_failed;
00726
00727
00728
00729
00730
if (!append_string_field (dest, endian,
00731 DBUS_HEADER_FIELD_SIGNATURE,
00732 DBUS_TYPE_STRING,
00733
"iii"))
00734
goto parse_failed;
00735 }
00736
else if (
_dbus_string_starts_with_c_str (&line,
00737
"BIG_ENDIAN"))
00738 {
00739 endian = DBUS_BIG_ENDIAN;
00740 }
00741
else if (
_dbus_string_starts_with_c_str (&line,
00742
"LITTLE_ENDIAN"))
00743 {
00744 endian = DBUS_LITTLE_ENDIAN;
00745 }
00746
else if (
_dbus_string_starts_with_c_str (&line,
00747
"OPPOSITE_ENDIAN"))
00748 {
00749
if (endian == DBUS_BIG_ENDIAN)
00750 endian = DBUS_LITTLE_ENDIAN;
00751
else
00752 endian = DBUS_BIG_ENDIAN;
00753 }
00754
else if (
_dbus_string_starts_with_c_str (&line,
00755
"ALIGN"))
00756 {
00757
long val;
00758
int end;
00759
int orig_len;
00760
00761
_dbus_string_delete_first_word (&line);
00762
00763
if (!
_dbus_string_parse_int (&line, 0, &val, &end))
00764 {
00765
_dbus_warn (
"Failed to parse integer\n");
00766
goto parse_failed;
00767 }
00768
00769
if (val > 8)
00770 {
00771
_dbus_warn (
"Aligning to %ld boundary is crack\n",
00772 val);
00773
goto parse_failed;
00774 }
00775
00776 orig_len =
_dbus_string_get_length (dest);
00777
00778
if (!
_dbus_string_align_length (dest, val))
00779
goto parse_failed;
00780
00781
if (
_dbus_string_parse_int (&line, end, &val, NULL))
00782 {
00783
00784
00785
00786
if (val < 0 || val > 255)
00787 {
00788
_dbus_warn (
"can't fill align padding with %ld, must be a byte value\n", val);
00789
goto parse_failed;
00790 }
00791
00792 end = orig_len;
00793
while (end <
_dbus_string_get_length (dest))
00794 {
00795
_dbus_string_set_byte (dest, end, val);
00796 ++end;
00797 }
00798 }
00799 }
00800
else if (
_dbus_string_starts_with_c_str (&line,
"UNALIGN"))
00801 {
00802 unalign =
TRUE;
00803 just_set_unalign =
TRUE;
00804 }
00805
else if (
_dbus_string_starts_with_c_str (&line,
"CHOP"))
00806 {
00807
long val;
00808
00809
00810
00811
00812
00813
_dbus_string_delete_first_word (&line);
00814
00815
if (!
_dbus_string_parse_int (&line, 0, &val, NULL))
00816 {
00817
_dbus_warn (
"Failed to parse integer to chop\n");
00818
goto parse_failed;
00819 }
00820
00821
if (val >
_dbus_string_get_length (dest))
00822 {
00823
_dbus_warn (
"Trying to chop %ld bytes but we only have %d\n",
00824 val,
00825 _dbus_string_get_length (dest));
00826
goto parse_failed;
00827 }
00828
00829
_dbus_string_shorten (dest, val);
00830 }
00831
else if (
_dbus_string_starts_with_c_str (&line,
00832
"START_LENGTH"))
00833 {
00834
_dbus_string_delete_first_word (&line);
00835
00836
if (!save_start (length_hash, &line,
00837 _dbus_string_get_length (dest)))
00838 {
00839
_dbus_warn (
"failed to save length start\n");
00840
goto parse_failed;
00841 }
00842 }
00843
else if (
_dbus_string_starts_with_c_str (&line,
00844
"END_LENGTH"))
00845 {
00846
_dbus_string_delete_first_word (&line);
00847
00848
if (!save_length (length_hash, &line,
00849 _dbus_string_get_length (dest)))
00850 {
00851
_dbus_warn (
"failed to save length end\n");
00852
goto parse_failed;
00853 }
00854 }
00855
else if (
_dbus_string_starts_with_c_str (&line,
00856
"LENGTH"))
00857 {
00858 SAVE_FOR_UNALIGN (dest, 4);
00859
00860
_dbus_string_delete_first_word (&line);
00861
00862
if (!append_saved_length (dest, length_hash,
00863 &line,
00864 unalign ? align_pad_start : align_pad_end,
00865 endian))
00866 {
00867
_dbus_warn (
"failed to add LENGTH\n");
00868
goto parse_failed;
00869 }
00870
00871 PERFORM_UNALIGN (dest);
00872 }
00873
else if (
_dbus_string_starts_with_c_str (&line,
00874
"HEADER_FIELD"))
00875 {
00876
int field;
00877
00878
_dbus_string_delete_first_word (&line);
00879
00880
if (
_dbus_string_starts_with_c_str (&line,
"INVALID"))
00881 field = DBUS_HEADER_FIELD_INVALID;
00882
else if (
_dbus_string_starts_with_c_str (&line,
"PATH"))
00883 field = DBUS_HEADER_FIELD_PATH;
00884
else if (
_dbus_string_starts_with_c_str (&line,
"INTERFACE"))
00885 field = DBUS_HEADER_FIELD_INTERFACE;
00886
else if (
_dbus_string_starts_with_c_str (&line,
"MEMBER"))
00887 field = DBUS_HEADER_FIELD_MEMBER;
00888
else if (
_dbus_string_starts_with_c_str (&line,
"ERROR_NAME"))
00889 field = DBUS_HEADER_FIELD_ERROR_NAME;
00890
else if (
_dbus_string_starts_with_c_str (&line,
"REPLY_SERIAL"))
00891 field = DBUS_HEADER_FIELD_REPLY_SERIAL;
00892
else if (
_dbus_string_starts_with_c_str (&line,
"DESTINATION"))
00893 field = DBUS_HEADER_FIELD_DESTINATION;
00894
else if (
_dbus_string_starts_with_c_str (&line,
"SENDER"))
00895 field = DBUS_HEADER_FIELD_SENDER;
00896
else if (
_dbus_string_starts_with_c_str (&line,
"SIGNATURE"))
00897 field = DBUS_HEADER_FIELD_SIGNATURE;
00898
else if (
_dbus_string_starts_with_c_str (&line,
"UNKNOWN"))
00899 field = 22;
00900
else
00901 {
00902
_dbus_warn (
"%s is not a valid header field name\n",
00903 _dbus_string_get_const_data (&line));
00904
goto parse_failed;
00905 }
00906
00907
if (!
_dbus_string_append_byte (dest, field))
00908 {
00909
_dbus_warn (
"could not append header field name byte\n");
00910
goto parse_failed;
00911 }
00912 }
00913
else if (
_dbus_string_starts_with_c_str (&line,
00914
"TYPE"))
00915 {
00916
int code;
00917
00918
_dbus_string_delete_first_word (&line);
00919
00920
if (
_dbus_string_starts_with_c_str (&line,
"INVALID"))
00921 code = DBUS_TYPE_INVALID;
00922
else if (
_dbus_string_starts_with_c_str (&line,
"NIL"))
00923 code = DBUS_TYPE_NIL;
00924
else if ((code = lookup_basic_type (&line, NULL)) != DBUS_TYPE_INVALID)
00925 ;
00926
else if (
_dbus_string_starts_with_c_str (&line,
"STRING"))
00927 code = DBUS_TYPE_STRING;
00928
else if (
_dbus_string_starts_with_c_str (&line,
"OBJECT_PATH"))
00929 code = DBUS_TYPE_OBJECT_PATH;
00930
else if (
_dbus_string_starts_with_c_str (&line,
"CUSTOM"))
00931 code = DBUS_TYPE_CUSTOM;
00932
else if (
_dbus_string_starts_with_c_str (&line,
"ARRAY"))
00933 code = DBUS_TYPE_ARRAY;
00934
else if (
_dbus_string_starts_with_c_str (&line,
"DICT"))
00935 code = DBUS_TYPE_DICT;
00936
else
00937 {
00938
_dbus_warn (
"%s is not a valid type name\n", _dbus_string_get_const_data (&line));
00939
goto parse_failed;
00940 }
00941
00942
if (!
_dbus_string_append_byte (dest, code))
00943 {
00944
_dbus_warn (
"could not append typecode byte\n");
00945
goto parse_failed;
00946 }
00947 }
00948
else if (
_dbus_string_starts_with_c_str (&line,
00949
"STRING_ARRAY"))
00950 {
00951 SAVE_FOR_UNALIGN (dest, 4);
00952
int i, len, allocated;
00953
char **values;
00954
char *val;
00955
DBusString val_str;
00956
unsigned char b;
00957
00958 allocated = 4;
00959 values =
dbus_new (
char *, allocated);
00960
if (!values)
00961 {
00962
_dbus_warn (
"could not allocate memory for STRING_ARRAY\n");
00963
goto parse_failed;
00964 }
00965
00966 len = 0;
00967
00968
_dbus_string_delete_first_word (&line);
00969
_dbus_string_skip_blank (&line, 0, &i);
00970 b =
_dbus_string_get_byte (&line, i++);
00971
00972
if (b !=
'{')
00973
goto parse_failed;
00974
00975
_dbus_string_init (&val_str);
00976
while (i <
_dbus_string_get_length (&line))
00977 {
00978
_dbus_string_skip_blank (&line, i, &i);
00979
00980
if (!append_quoted_string (&val_str, &line, i, &i))
00981 {
00982
_dbus_warn (
"could not parse quoted string for STRING_ARRAY\n");
00983
goto parse_failed;
00984 }
00985 i++;
00986
00987
if (!
_dbus_string_steal_data (&val_str, &val))
00988 {
00989
_dbus_warn (
"could not allocate memory for STRING_ARRAY string\n");
00990
goto parse_failed;
00991 }
00992
00993 values[len++] = val;
00994
if (len == allocated)
00995 {
00996 allocated *= 2;
00997 values =
dbus_realloc (values, allocated *
sizeof (
char *));
00998
if (!values)
00999 {
01000
_dbus_warn (
"could not allocate memory for STRING_ARRAY\n");
01001
goto parse_failed;
01002 }
01003 }
01004
01005
_dbus_string_skip_blank (&line, i, &i);
01006
01007 b =
_dbus_string_get_byte (&line, i++);
01008
01009
if (b ==
'}')
01010
break;
01011
else if (b !=
',')
01012 {
01013
_dbus_warn (
"missing comma when parsing STRING_ARRAY\n");
01014
goto parse_failed;
01015 }
01016 }
01017
_dbus_string_free (&val_str);
01018
01019
if (!
_dbus_marshal_string_array (dest, endian, (
const char **)values, len))
01020 {
01021
_dbus_warn (
"failed to append STRING_ARRAY\n");
01022
goto parse_failed;
01023 }
01024
01025 values[len] =
NULL;
01026
dbus_free_string_array (values);
01027
01028 PERFORM_UNALIGN (dest);
01029 }
01030
else if (
_dbus_string_starts_with_c_str (&line,
01031
"STRING"))
01032 {
01033 SAVE_FOR_UNALIGN (dest, 4);
01034
int size_offset;
01035
int old_len;
01036
01037
_dbus_string_delete_first_word (&line);
01038
01039 size_offset =
_dbus_string_get_length (dest);
01040 size_offset = _DBUS_ALIGN_VALUE (size_offset, 4);
01041
if (!
_dbus_marshal_uint32 (dest, endian, 0))
01042 {
01043
_dbus_warn (
"Failed to append string size\n");
01044
goto parse_failed;
01045 }
01046
01047 old_len =
_dbus_string_get_length (dest);
01048
if (!append_quoted_string (dest, &line, 0, NULL))
01049 {
01050
_dbus_warn (
"Failed to append quoted string\n");
01051
goto parse_failed;
01052 }
01053
01054
_dbus_marshal_set_uint32 (dest, endian, size_offset,
01055
01056 _dbus_string_get_length (dest) - old_len - 1);
01057
01058 PERFORM_UNALIGN (dest);
01059 }
01060
else if ((type = lookup_basic_type (&line, &is_array)) != DBUS_TYPE_INVALID)
01061 {
01062
if (is_array)
01063 {
01064
if (!parse_basic_array (&line, type, dest, &unalign, endian))
01065
goto parse_failed;
01066 }
01067
else
01068 {
01069
if (!parse_basic_type (&line, type, dest, &unalign, endian))
01070
goto parse_failed;
01071 }
01072 }
01073
else if (
_dbus_string_starts_with_c_str (&line,
01074
"OBJECT_PATH"))
01075 {
01076 SAVE_FOR_UNALIGN (dest, 4);
01077
int size_offset;
01078
int old_len;
01079
01080
_dbus_string_delete_first_word (&line);
01081
01082 size_offset =
_dbus_string_get_length (dest);
01083 size_offset = _DBUS_ALIGN_VALUE (size_offset, 4);
01084
if (!
_dbus_marshal_uint32 (dest, endian, 0))
01085 {
01086
_dbus_warn (
"Failed to append string size\n");
01087
goto parse_failed;
01088 }
01089
01090 old_len =
_dbus_string_get_length (dest);
01091
if (!append_quoted_string (dest, &line, 0, NULL))
01092 {
01093
_dbus_warn (
"Failed to append quoted string\n");
01094
goto parse_failed;
01095 }
01096
01097
_dbus_marshal_set_uint32 (dest, endian, size_offset,
01098
01099 _dbus_string_get_length (dest) - old_len - 1);
01100
01101 PERFORM_UNALIGN (dest);
01102 }
01103
else
01104
goto parse_failed;
01105
01106
if (!just_set_unalign && unalign)
01107 {
01108
_dbus_warn (
"UNALIGN prior to something that isn't aligned\n");
01109
goto parse_failed;
01110 }
01111
01112
goto next_iteration;
01113
01114 parse_failed:
01115 {
01116
_dbus_warn (
"couldn't process line %d \"%s\"\n",
01117 line_no, _dbus_string_get_const_data (&line));
01118
goto out;
01119 }
01120 }
01121
01122
_dbus_hash_iter_init (length_hash, &iter);
01123
while (
_dbus_hash_iter_next (&iter))
01124 {
01125 SavedLength *sl =
_dbus_hash_iter_get_value (&iter);
01126
const char *s;
01127
01128 s =
_dbus_string_get_const_data (&sl->name);
01129
01130
if (sl->length < 0)
01131 {
01132
_dbus_warn (
"Used LENGTH %s but never did END_LENGTH\n",
01133 s);
01134
goto out;
01135 }
01136
else if (sl->offset < 0)
01137 {
01138
_dbus_warn (
"Did END_LENGTH %s but never used LENGTH\n",
01139 s);
01140
goto out;
01141 }
01142
else
01143 {
01144
if (sl->start < 0)
01145 sl->start = 0;
01146
01147 _dbus_verbose (
"Filling in length %s endian = %d offset = %d start = %d length = %d\n",
01148 s, sl->endian, sl->offset, sl->start, sl->length);
01149
_dbus_marshal_set_int32 (dest,
01150 sl->endian,
01151 sl->offset,
01152 sl->length - sl->start);
01153 }
01154
01155
_dbus_hash_iter_remove_entry (&iter);
01156 }
01157
01158 retval =
TRUE;
01159
01160
_dbus_verbose_bytes_of_string (dest, 0, _dbus_string_get_length (dest));
01161
01162 out:
01163
if (length_hash !=
NULL)
01164
_dbus_hash_table_unref (length_hash);
01165
01166
_dbus_string_free (&file);
01167
_dbus_string_free (&line);
01168
return retval;
01169 }
01170
01172
#endif