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 <config.h>
00025
00026 #include "dbus-signature.h"
00027 #include "dbus-marshal-recursive.h"
00028 #include "dbus-marshal-basic.h"
00029 #include "dbus-internals.h"
00030 #include "dbus-test.h"
00031
00035 typedef struct
00036 {
00037 const char *pos;
00038 unsigned int finished : 1;
00039 unsigned int in_array : 1;
00040 } DBusSignatureRealIter;
00041
00043 #define TYPE_IS_CONTAINER(typecode) \
00044 ((typecode) == DBUS_TYPE_STRUCT || \
00045 (typecode) == DBUS_TYPE_DICT_ENTRY || \
00046 (typecode) == DBUS_TYPE_VARIANT || \
00047 (typecode) == DBUS_TYPE_ARRAY)
00048
00049
00066 void
00067 dbus_signature_iter_init (DBusSignatureIter *iter,
00068 const char *signature)
00069 {
00070 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00071
00072 real_iter->pos = signature;
00073 real_iter->finished = FALSE;
00074 real_iter->in_array = FALSE;
00075 }
00076
00091 int
00092 dbus_signature_iter_get_current_type (const DBusSignatureIter *iter)
00093 {
00094 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00095
00096 return _dbus_first_type_in_signature_c_str (real_iter->pos, 0);
00097 }
00098
00111 char *
00112 dbus_signature_iter_get_signature (const DBusSignatureIter *iter)
00113 {
00114 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00115 DBusString str;
00116 char *ret;
00117 int pos;
00118
00119 if (!_dbus_string_init (&str))
00120 return NULL;
00121
00122 pos = 0;
00123 _dbus_type_signature_next (real_iter->pos, &pos);
00124
00125 if (!_dbus_string_append_len (&str, real_iter->pos, pos))
00126 return NULL;
00127 if (!_dbus_string_steal_data (&str, &ret))
00128 ret = NULL;
00129 _dbus_string_free (&str);
00130
00131 return ret;
00132 }
00133
00145 int
00146 dbus_signature_iter_get_element_type (const DBusSignatureIter *iter)
00147 {
00148 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00149
00150 _dbus_return_val_if_fail (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
00151
00152 return _dbus_first_type_in_signature_c_str (real_iter->pos, 1);
00153 }
00154
00163 dbus_bool_t
00164 dbus_signature_iter_next (DBusSignatureIter *iter)
00165 {
00166 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00167
00168 if (real_iter->finished)
00169 return FALSE;
00170 else
00171 {
00172 int pos;
00173
00174 if (real_iter->in_array)
00175 {
00176 real_iter->finished = TRUE;
00177 return FALSE;
00178 }
00179
00180 pos = 0;
00181 _dbus_type_signature_next (real_iter->pos, &pos);
00182 real_iter->pos += pos;
00183
00184 if (*real_iter->pos == DBUS_STRUCT_END_CHAR
00185 || *real_iter->pos == DBUS_DICT_ENTRY_END_CHAR)
00186 {
00187 real_iter->finished = TRUE;
00188 return FALSE;
00189 }
00190
00191 return *real_iter->pos != DBUS_TYPE_INVALID;
00192 }
00193 }
00194
00206 void
00207 dbus_signature_iter_recurse (const DBusSignatureIter *iter,
00208 DBusSignatureIter *subiter)
00209 {
00210 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00211 DBusSignatureRealIter *real_sub_iter = (DBusSignatureRealIter *) subiter;
00212
00213 _dbus_return_if_fail (dbus_type_is_container (dbus_signature_iter_get_current_type (iter)));
00214
00215 *real_sub_iter = *real_iter;
00216 real_sub_iter->in_array = FALSE;
00217 real_sub_iter->pos++;
00218
00219 if (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY)
00220 real_sub_iter->in_array = TRUE;
00221 }
00222
00232 dbus_bool_t
00233 dbus_signature_validate (const char *signature,
00234 DBusError *error)
00235
00236 {
00237 DBusString str;
00238 DBusValidity reason;
00239
00240 _dbus_string_init_const (&str, signature);
00241 reason = _dbus_validate_signature_with_reason (&str, 0, _dbus_string_get_length (&str));
00242
00243 if (reason == DBUS_VALID)
00244 return TRUE;
00245 else
00246 {
00247 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, _dbus_validity_to_error_message (reason));
00248 return FALSE;
00249 }
00250 }
00251
00263 dbus_bool_t
00264 dbus_signature_validate_single (const char *signature,
00265 DBusError *error)
00266 {
00267 DBusSignatureIter iter;
00268
00269 if (!dbus_signature_validate (signature, error))
00270 return FALSE;
00271
00272 dbus_signature_iter_init (&iter, signature);
00273 if (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID)
00274 goto lose;
00275 if (!dbus_signature_iter_next (&iter))
00276 return TRUE;
00277 lose:
00278 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Exactly one complete type required in signature");
00279 return FALSE;
00280 }
00281
00291 dbus_bool_t
00292 dbus_type_is_container (int typecode)
00293 {
00294
00295 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00296 FALSE);
00297 return TYPE_IS_CONTAINER (typecode);
00298 }
00299
00313 dbus_bool_t
00314 dbus_type_is_basic (int typecode)
00315 {
00316
00317 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00318 FALSE);
00319
00320
00321 return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode));
00322 }
00323
00342 dbus_bool_t
00343 dbus_type_is_fixed (int typecode)
00344 {
00345
00346 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00347 FALSE);
00348
00349 switch (typecode)
00350 {
00351 case DBUS_TYPE_BYTE:
00352 case DBUS_TYPE_BOOLEAN:
00353 case DBUS_TYPE_INT16:
00354 case DBUS_TYPE_UINT16:
00355 case DBUS_TYPE_INT32:
00356 case DBUS_TYPE_UINT32:
00357 case DBUS_TYPE_INT64:
00358 case DBUS_TYPE_UINT64:
00359 case DBUS_TYPE_DOUBLE:
00360 case DBUS_TYPE_UNIX_FD:
00361 return TRUE;
00362 default:
00363 return FALSE;
00364 }
00365 }
00366
00368
00369 #ifdef DBUS_BUILD_TESTS
00370
00377 dbus_bool_t
00378 _dbus_signature_test (void)
00379 {
00380 DBusSignatureIter iter;
00381 DBusSignatureIter subiter;
00382 DBusSignatureIter subsubiter;
00383 DBusSignatureIter subsubsubiter;
00384 const char *sig;
00385 dbus_bool_t boolres;
00386
00387 _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter));
00388
00389 sig = "";
00390 _dbus_assert (dbus_signature_validate (sig, NULL));
00391 _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00392 dbus_signature_iter_init (&iter, sig);
00393 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID);
00394
00395 sig = DBUS_TYPE_STRING_AS_STRING;
00396 _dbus_assert (dbus_signature_validate (sig, NULL));
00397 _dbus_assert (dbus_signature_validate_single (sig, NULL));
00398 dbus_signature_iter_init (&iter, sig);
00399 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00400
00401 sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
00402 _dbus_assert (dbus_signature_validate (sig, NULL));
00403 dbus_signature_iter_init (&iter, sig);
00404 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00405 boolres = dbus_signature_iter_next (&iter);
00406 _dbus_assert (boolres);
00407 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE);
00408
00409 sig = DBUS_TYPE_UINT16_AS_STRING
00410 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00411 DBUS_TYPE_STRING_AS_STRING
00412 DBUS_TYPE_UINT32_AS_STRING
00413 DBUS_TYPE_VARIANT_AS_STRING
00414 DBUS_TYPE_DOUBLE_AS_STRING
00415 DBUS_STRUCT_END_CHAR_AS_STRING;
00416 _dbus_assert (dbus_signature_validate (sig, NULL));
00417 dbus_signature_iter_init (&iter, sig);
00418 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00419 boolres = dbus_signature_iter_next (&iter);
00420 _dbus_assert (boolres);
00421 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00422 dbus_signature_iter_recurse (&iter, &subiter);
00423 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING);
00424 boolres = dbus_signature_iter_next (&subiter);
00425 _dbus_assert (boolres);
00426 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00427 boolres = dbus_signature_iter_next (&subiter);
00428 _dbus_assert (boolres);
00429 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT);
00430 boolres = dbus_signature_iter_next (&subiter);
00431 _dbus_assert (boolres);
00432 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE);
00433
00434 sig = DBUS_TYPE_UINT16_AS_STRING
00435 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00436 DBUS_TYPE_UINT32_AS_STRING
00437 DBUS_TYPE_BYTE_AS_STRING
00438 DBUS_TYPE_ARRAY_AS_STRING
00439 DBUS_TYPE_ARRAY_AS_STRING
00440 DBUS_TYPE_DOUBLE_AS_STRING
00441 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00442 DBUS_TYPE_BYTE_AS_STRING
00443 DBUS_STRUCT_END_CHAR_AS_STRING
00444 DBUS_STRUCT_END_CHAR_AS_STRING;
00445 _dbus_assert (dbus_signature_validate (sig, NULL));
00446 dbus_signature_iter_init (&iter, sig);
00447 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00448 boolres = dbus_signature_iter_next (&iter);
00449 _dbus_assert (boolres);
00450 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00451 dbus_signature_iter_recurse (&iter, &subiter);
00452 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00453 boolres = dbus_signature_iter_next (&subiter);
00454 _dbus_assert (boolres);
00455 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE);
00456 boolres = dbus_signature_iter_next (&subiter);
00457 _dbus_assert (boolres);
00458 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY);
00459 _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY);
00460
00461 dbus_signature_iter_recurse (&subiter, &subsubiter);
00462 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY);
00463 _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE);
00464
00465 dbus_signature_iter_recurse (&subsubiter, &subsubsubiter);
00466 _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE);
00467 boolres = dbus_signature_iter_next (&subiter);
00468 _dbus_assert (boolres);
00469 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT);
00470 dbus_signature_iter_recurse (&subiter, &subsubiter);
00471 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE);
00472
00473 sig = DBUS_TYPE_ARRAY_AS_STRING
00474 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00475 DBUS_TYPE_INT16_AS_STRING
00476 DBUS_TYPE_STRING_AS_STRING
00477 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
00478 DBUS_TYPE_VARIANT_AS_STRING;
00479 _dbus_assert (dbus_signature_validate (sig, NULL));
00480 _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00481 dbus_signature_iter_init (&iter, sig);
00482 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY);
00483 _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY);
00484
00485 dbus_signature_iter_recurse (&iter, &subiter);
00486 dbus_signature_iter_recurse (&subiter, &subsubiter);
00487 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16);
00488 boolres = dbus_signature_iter_next (&subsubiter);
00489 _dbus_assert (boolres);
00490 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING);
00491 boolres = dbus_signature_iter_next (&subsubiter);
00492 _dbus_assert (!boolres);
00493
00494 boolres = dbus_signature_iter_next (&iter);
00495 _dbus_assert (boolres);
00496 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT);
00497 boolres = dbus_signature_iter_next (&iter);
00498 _dbus_assert (!boolres);
00499
00500 sig = DBUS_TYPE_DICT_ENTRY_AS_STRING;
00501 _dbus_assert (!dbus_signature_validate (sig, NULL));
00502
00503 sig = DBUS_TYPE_ARRAY_AS_STRING;
00504 _dbus_assert (!dbus_signature_validate (sig, NULL));
00505
00506 sig = DBUS_TYPE_UINT32_AS_STRING
00507 DBUS_TYPE_ARRAY_AS_STRING;
00508 _dbus_assert (!dbus_signature_validate (sig, NULL));
00509
00510 sig = DBUS_TYPE_ARRAY_AS_STRING
00511 DBUS_TYPE_DICT_ENTRY_AS_STRING;
00512 _dbus_assert (!dbus_signature_validate (sig, NULL));
00513
00514 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING;
00515 _dbus_assert (!dbus_signature_validate (sig, NULL));
00516
00517 sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
00518 _dbus_assert (!dbus_signature_validate (sig, NULL));
00519
00520 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00521 DBUS_TYPE_INT32_AS_STRING;
00522 _dbus_assert (!dbus_signature_validate (sig, NULL));
00523
00524 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00525 DBUS_TYPE_INT32_AS_STRING
00526 DBUS_TYPE_STRING_AS_STRING;
00527 _dbus_assert (!dbus_signature_validate (sig, NULL));
00528
00529 sig = DBUS_STRUCT_END_CHAR_AS_STRING
00530 DBUS_STRUCT_BEGIN_CHAR_AS_STRING;
00531 _dbus_assert (!dbus_signature_validate (sig, NULL));
00532
00533 sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00534 DBUS_TYPE_BOOLEAN_AS_STRING;
00535 _dbus_assert (!dbus_signature_validate (sig, NULL));
00536 return TRUE;
00537 #if 0
00538 oom:
00539 _dbus_assert_not_reached ("out of memory");
00540 return FALSE;
00541 #endif
00542 }
00543
00544 #endif
00545