00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "dbus-signature.h"
00025 #include "dbus-marshal-recursive.h"
00026 #include "dbus-marshal-basic.h"
00027 #include "dbus-internals.h"
00028 #include "dbus-test.h"
00029
00033 typedef struct
00034 {
00035 const char *pos;
00036 unsigned int finished : 1;
00037 unsigned int in_array : 1;
00038 } DBusSignatureRealIter;
00039
00041 #define TYPE_IS_CONTAINER(typecode) \
00042 ((typecode) == DBUS_TYPE_STRUCT || \
00043 (typecode) == DBUS_TYPE_DICT_ENTRY || \
00044 (typecode) == DBUS_TYPE_VARIANT || \
00045 (typecode) == DBUS_TYPE_ARRAY)
00046
00047
00064 void
00065 dbus_signature_iter_init (DBusSignatureIter *iter,
00066 const char *signature)
00067 {
00068 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00069
00070 real_iter->pos = signature;
00071 real_iter->finished = FALSE;
00072 real_iter->in_array = FALSE;
00073 }
00074
00089 int
00090 dbus_signature_iter_get_current_type (const DBusSignatureIter *iter)
00091 {
00092 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00093
00094 return _dbus_first_type_in_signature_c_str (real_iter->pos, 0);
00095 }
00096
00109 char *
00110 dbus_signature_iter_get_signature (const DBusSignatureIter *iter)
00111 {
00112 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00113 DBusString str;
00114 char *ret;
00115 int pos;
00116
00117 if (!_dbus_string_init (&str))
00118 return NULL;
00119
00120 pos = 0;
00121 _dbus_type_signature_next (real_iter->pos, &pos);
00122
00123 if (!_dbus_string_append_len (&str, real_iter->pos, pos))
00124 return NULL;
00125 if (!_dbus_string_steal_data (&str, &ret))
00126 ret = NULL;
00127 _dbus_string_free (&str);
00128
00129 return ret;
00130 }
00131
00143 int
00144 dbus_signature_iter_get_element_type (const DBusSignatureIter *iter)
00145 {
00146 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00147
00148 _dbus_return_val_if_fail (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
00149
00150 return _dbus_first_type_in_signature_c_str (real_iter->pos, 1);
00151 }
00152
00161 dbus_bool_t
00162 dbus_signature_iter_next (DBusSignatureIter *iter)
00163 {
00164 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00165
00166 if (real_iter->finished)
00167 return FALSE;
00168 else
00169 {
00170 int pos;
00171
00172 if (real_iter->in_array)
00173 {
00174 real_iter->finished = TRUE;
00175 return FALSE;
00176 }
00177
00178 pos = 0;
00179 _dbus_type_signature_next (real_iter->pos, &pos);
00180 real_iter->pos += pos;
00181
00182 if (*real_iter->pos == DBUS_STRUCT_END_CHAR
00183 || *real_iter->pos == DBUS_DICT_ENTRY_END_CHAR)
00184 {
00185 real_iter->finished = TRUE;
00186 return FALSE;
00187 }
00188
00189 return *real_iter->pos != DBUS_TYPE_INVALID;
00190 }
00191 }
00192
00204 void
00205 dbus_signature_iter_recurse (const DBusSignatureIter *iter,
00206 DBusSignatureIter *subiter)
00207 {
00208 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00209 DBusSignatureRealIter *real_sub_iter = (DBusSignatureRealIter *) subiter;
00210
00211 _dbus_return_if_fail (dbus_type_is_container (dbus_signature_iter_get_current_type (iter)));
00212
00213 *real_sub_iter = *real_iter;
00214 real_sub_iter->in_array = FALSE;
00215 real_sub_iter->pos++;
00216
00217 if (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY)
00218 real_sub_iter->in_array = TRUE;
00219 }
00220
00230 dbus_bool_t
00231 dbus_signature_validate (const char *signature,
00232 DBusError *error)
00233
00234 {
00235 DBusString str;
00236
00237 _dbus_string_init_const (&str, signature);
00238 if (_dbus_validate_signature (&str, 0, _dbus_string_get_length (&str)))
00239 return TRUE;
00240 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Corrupt type signature");
00241 return FALSE;
00242 }
00243
00255 dbus_bool_t
00256 dbus_signature_validate_single (const char *signature,
00257 DBusError *error)
00258 {
00259 DBusSignatureIter iter;
00260
00261 if (!dbus_signature_validate (signature, error))
00262 return FALSE;
00263
00264 dbus_signature_iter_init (&iter, signature);
00265 if (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID)
00266 goto lose;
00267 if (!dbus_signature_iter_next (&iter))
00268 return TRUE;
00269 lose:
00270 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Exactly one complete type required in signature");
00271 return FALSE;
00272 }
00273
00283 dbus_bool_t
00284 dbus_type_is_container (int typecode)
00285 {
00286
00287 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00288 FALSE);
00289 return TYPE_IS_CONTAINER (typecode);
00290 }
00291
00305 dbus_bool_t
00306 dbus_type_is_basic (int typecode)
00307 {
00308
00309 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00310 FALSE);
00311
00312
00313 return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode));
00314 }
00315
00334 dbus_bool_t
00335 dbus_type_is_fixed (int typecode)
00336 {
00337
00338 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00339 FALSE);
00340
00341 switch (typecode)
00342 {
00343 case DBUS_TYPE_BYTE:
00344 case DBUS_TYPE_BOOLEAN:
00345 case DBUS_TYPE_INT16:
00346 case DBUS_TYPE_UINT16:
00347 case DBUS_TYPE_INT32:
00348 case DBUS_TYPE_UINT32:
00349 case DBUS_TYPE_INT64:
00350 case DBUS_TYPE_UINT64:
00351 case DBUS_TYPE_DOUBLE:
00352 return TRUE;
00353 default:
00354 return FALSE;
00355 }
00356 }
00357
00359
00360 #ifdef DBUS_BUILD_TESTS
00361
00368 dbus_bool_t
00369 _dbus_signature_test (void)
00370 {
00371 DBusSignatureIter iter;
00372 DBusSignatureIter subiter;
00373 DBusSignatureIter subsubiter;
00374 DBusSignatureIter subsubsubiter;
00375 const char *sig;
00376 dbus_bool_t boolres;
00377
00378 _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter));
00379
00380 sig = "";
00381 _dbus_assert (dbus_signature_validate (sig, NULL));
00382 _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00383 dbus_signature_iter_init (&iter, sig);
00384 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID);
00385
00386 sig = DBUS_TYPE_STRING_AS_STRING;
00387 _dbus_assert (dbus_signature_validate (sig, NULL));
00388 _dbus_assert (dbus_signature_validate_single (sig, NULL));
00389 dbus_signature_iter_init (&iter, sig);
00390 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00391
00392 sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
00393 _dbus_assert (dbus_signature_validate (sig, NULL));
00394 dbus_signature_iter_init (&iter, sig);
00395 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00396 boolres = dbus_signature_iter_next (&iter);
00397 _dbus_assert (boolres);
00398 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE);
00399
00400 sig = DBUS_TYPE_UINT16_AS_STRING
00401 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00402 DBUS_TYPE_STRING_AS_STRING
00403 DBUS_TYPE_UINT32_AS_STRING
00404 DBUS_TYPE_VARIANT_AS_STRING
00405 DBUS_TYPE_DOUBLE_AS_STRING
00406 DBUS_STRUCT_END_CHAR_AS_STRING;
00407 _dbus_assert (dbus_signature_validate (sig, NULL));
00408 dbus_signature_iter_init (&iter, sig);
00409 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00410 boolres = dbus_signature_iter_next (&iter);
00411 _dbus_assert (boolres);
00412 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00413 dbus_signature_iter_recurse (&iter, &subiter);
00414 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING);
00415 boolres = dbus_signature_iter_next (&subiter);
00416 _dbus_assert (boolres);
00417 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00418 boolres = dbus_signature_iter_next (&subiter);
00419 _dbus_assert (boolres);
00420 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT);
00421 boolres = dbus_signature_iter_next (&subiter);
00422 _dbus_assert (boolres);
00423 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE);
00424
00425 sig = DBUS_TYPE_UINT16_AS_STRING
00426 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00427 DBUS_TYPE_UINT32_AS_STRING
00428 DBUS_TYPE_BYTE_AS_STRING
00429 DBUS_TYPE_ARRAY_AS_STRING
00430 DBUS_TYPE_ARRAY_AS_STRING
00431 DBUS_TYPE_DOUBLE_AS_STRING
00432 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00433 DBUS_TYPE_BYTE_AS_STRING
00434 DBUS_STRUCT_END_CHAR_AS_STRING
00435 DBUS_STRUCT_END_CHAR_AS_STRING;
00436 _dbus_assert (dbus_signature_validate (sig, NULL));
00437 dbus_signature_iter_init (&iter, sig);
00438 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00439 boolres = dbus_signature_iter_next (&iter);
00440 _dbus_assert (boolres);
00441 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00442 dbus_signature_iter_recurse (&iter, &subiter);
00443 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00444 boolres = dbus_signature_iter_next (&subiter);
00445 _dbus_assert (boolres);
00446 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE);
00447 boolres = dbus_signature_iter_next (&subiter);
00448 _dbus_assert (boolres);
00449 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY);
00450 _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY);
00451
00452 dbus_signature_iter_recurse (&subiter, &subsubiter);
00453 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY);
00454 _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE);
00455
00456 dbus_signature_iter_recurse (&subsubiter, &subsubsubiter);
00457 _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE);
00458 boolres = dbus_signature_iter_next (&subiter);
00459 _dbus_assert (boolres);
00460 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT);
00461 dbus_signature_iter_recurse (&subiter, &subsubiter);
00462 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE);
00463
00464 sig = DBUS_TYPE_ARRAY_AS_STRING
00465 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00466 DBUS_TYPE_INT16_AS_STRING
00467 DBUS_TYPE_STRING_AS_STRING
00468 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
00469 DBUS_TYPE_VARIANT_AS_STRING;
00470 _dbus_assert (dbus_signature_validate (sig, NULL));
00471 _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00472 dbus_signature_iter_init (&iter, sig);
00473 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY);
00474 _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY);
00475
00476 dbus_signature_iter_recurse (&iter, &subiter);
00477 dbus_signature_iter_recurse (&subiter, &subsubiter);
00478 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16);
00479 boolres = dbus_signature_iter_next (&subsubiter);
00480 _dbus_assert (boolres);
00481 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING);
00482 boolres = dbus_signature_iter_next (&subsubiter);
00483 _dbus_assert (!boolres);
00484
00485 boolres = dbus_signature_iter_next (&iter);
00486 _dbus_assert (boolres);
00487 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT);
00488 boolres = dbus_signature_iter_next (&iter);
00489 _dbus_assert (!boolres);
00490
00491 sig = DBUS_TYPE_DICT_ENTRY_AS_STRING;
00492 _dbus_assert (!dbus_signature_validate (sig, NULL));
00493
00494 sig = DBUS_TYPE_ARRAY_AS_STRING;
00495 _dbus_assert (!dbus_signature_validate (sig, NULL));
00496
00497 sig = DBUS_TYPE_UINT32_AS_STRING
00498 DBUS_TYPE_ARRAY_AS_STRING;
00499 _dbus_assert (!dbus_signature_validate (sig, NULL));
00500
00501 sig = DBUS_TYPE_ARRAY_AS_STRING
00502 DBUS_TYPE_DICT_ENTRY_AS_STRING;
00503 _dbus_assert (!dbus_signature_validate (sig, NULL));
00504
00505 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING;
00506 _dbus_assert (!dbus_signature_validate (sig, NULL));
00507
00508 sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
00509 _dbus_assert (!dbus_signature_validate (sig, NULL));
00510
00511 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00512 DBUS_TYPE_INT32_AS_STRING;
00513 _dbus_assert (!dbus_signature_validate (sig, NULL));
00514
00515 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00516 DBUS_TYPE_INT32_AS_STRING
00517 DBUS_TYPE_STRING_AS_STRING;
00518 _dbus_assert (!dbus_signature_validate (sig, NULL));
00519
00520 sig = DBUS_STRUCT_END_CHAR_AS_STRING
00521 DBUS_STRUCT_BEGIN_CHAR_AS_STRING;
00522 _dbus_assert (!dbus_signature_validate (sig, NULL));
00523
00524 sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00525 DBUS_TYPE_BOOLEAN_AS_STRING;
00526 _dbus_assert (!dbus_signature_validate (sig, NULL));
00527 return TRUE;
00528 #if 0
00529 oom:
00530 _dbus_assert_not_reached ("out of memory");
00531 return FALSE;
00532 #endif
00533 }
00534
00535 #endif
00536