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 DBusValidity reason;
00237
00238 _dbus_string_init_const (&str, signature);
00239 reason = _dbus_validate_signature_with_reason (&str, 0, _dbus_string_get_length (&str));
00240
00241 if (reason == DBUS_VALID)
00242 return TRUE;
00243 else
00244 {
00245 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, _dbus_validity_to_error_message (reason));
00246 return FALSE;
00247 }
00248 }
00249
00261 dbus_bool_t
00262 dbus_signature_validate_single (const char *signature,
00263 DBusError *error)
00264 {
00265 DBusSignatureIter iter;
00266
00267 if (!dbus_signature_validate (signature, error))
00268 return FALSE;
00269
00270 dbus_signature_iter_init (&iter, signature);
00271 if (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID)
00272 goto lose;
00273 if (!dbus_signature_iter_next (&iter))
00274 return TRUE;
00275 lose:
00276 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Exactly one complete type required in signature");
00277 return FALSE;
00278 }
00279
00289 dbus_bool_t
00290 dbus_type_is_container (int typecode)
00291 {
00292
00293 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00294 FALSE);
00295 return TYPE_IS_CONTAINER (typecode);
00296 }
00297
00311 dbus_bool_t
00312 dbus_type_is_basic (int typecode)
00313 {
00314
00315 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00316 FALSE);
00317
00318
00319 return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode));
00320 }
00321
00340 dbus_bool_t
00341 dbus_type_is_fixed (int typecode)
00342 {
00343
00344 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00345 FALSE);
00346
00347 switch (typecode)
00348 {
00349 case DBUS_TYPE_BYTE:
00350 case DBUS_TYPE_BOOLEAN:
00351 case DBUS_TYPE_INT16:
00352 case DBUS_TYPE_UINT16:
00353 case DBUS_TYPE_INT32:
00354 case DBUS_TYPE_UINT32:
00355 case DBUS_TYPE_INT64:
00356 case DBUS_TYPE_UINT64:
00357 case DBUS_TYPE_DOUBLE:
00358 return TRUE;
00359 default:
00360 return FALSE;
00361 }
00362 }
00363
00365
00366 #ifdef DBUS_BUILD_TESTS
00367
00374 dbus_bool_t
00375 _dbus_signature_test (void)
00376 {
00377 DBusSignatureIter iter;
00378 DBusSignatureIter subiter;
00379 DBusSignatureIter subsubiter;
00380 DBusSignatureIter subsubsubiter;
00381 const char *sig;
00382 dbus_bool_t boolres;
00383
00384 _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter));
00385
00386 sig = "";
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_INVALID);
00391
00392 sig = DBUS_TYPE_STRING_AS_STRING;
00393 _dbus_assert (dbus_signature_validate (sig, NULL));
00394 _dbus_assert (dbus_signature_validate_single (sig, NULL));
00395 dbus_signature_iter_init (&iter, sig);
00396 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00397
00398 sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
00399 _dbus_assert (dbus_signature_validate (sig, NULL));
00400 dbus_signature_iter_init (&iter, sig);
00401 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00402 boolres = dbus_signature_iter_next (&iter);
00403 _dbus_assert (boolres);
00404 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE);
00405
00406 sig = DBUS_TYPE_UINT16_AS_STRING
00407 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00408 DBUS_TYPE_STRING_AS_STRING
00409 DBUS_TYPE_UINT32_AS_STRING
00410 DBUS_TYPE_VARIANT_AS_STRING
00411 DBUS_TYPE_DOUBLE_AS_STRING
00412 DBUS_STRUCT_END_CHAR_AS_STRING;
00413 _dbus_assert (dbus_signature_validate (sig, NULL));
00414 dbus_signature_iter_init (&iter, sig);
00415 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00416 boolres = dbus_signature_iter_next (&iter);
00417 _dbus_assert (boolres);
00418 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00419 dbus_signature_iter_recurse (&iter, &subiter);
00420 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING);
00421 boolres = dbus_signature_iter_next (&subiter);
00422 _dbus_assert (boolres);
00423 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00424 boolres = dbus_signature_iter_next (&subiter);
00425 _dbus_assert (boolres);
00426 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT);
00427 boolres = dbus_signature_iter_next (&subiter);
00428 _dbus_assert (boolres);
00429 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE);
00430
00431 sig = DBUS_TYPE_UINT16_AS_STRING
00432 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00433 DBUS_TYPE_UINT32_AS_STRING
00434 DBUS_TYPE_BYTE_AS_STRING
00435 DBUS_TYPE_ARRAY_AS_STRING
00436 DBUS_TYPE_ARRAY_AS_STRING
00437 DBUS_TYPE_DOUBLE_AS_STRING
00438 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00439 DBUS_TYPE_BYTE_AS_STRING
00440 DBUS_STRUCT_END_CHAR_AS_STRING
00441 DBUS_STRUCT_END_CHAR_AS_STRING;
00442 _dbus_assert (dbus_signature_validate (sig, NULL));
00443 dbus_signature_iter_init (&iter, sig);
00444 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00445 boolres = dbus_signature_iter_next (&iter);
00446 _dbus_assert (boolres);
00447 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00448 dbus_signature_iter_recurse (&iter, &subiter);
00449 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00450 boolres = dbus_signature_iter_next (&subiter);
00451 _dbus_assert (boolres);
00452 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE);
00453 boolres = dbus_signature_iter_next (&subiter);
00454 _dbus_assert (boolres);
00455 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY);
00456 _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY);
00457
00458 dbus_signature_iter_recurse (&subiter, &subsubiter);
00459 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY);
00460 _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE);
00461
00462 dbus_signature_iter_recurse (&subsubiter, &subsubsubiter);
00463 _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE);
00464 boolres = dbus_signature_iter_next (&subiter);
00465 _dbus_assert (boolres);
00466 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT);
00467 dbus_signature_iter_recurse (&subiter, &subsubiter);
00468 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE);
00469
00470 sig = DBUS_TYPE_ARRAY_AS_STRING
00471 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00472 DBUS_TYPE_INT16_AS_STRING
00473 DBUS_TYPE_STRING_AS_STRING
00474 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
00475 DBUS_TYPE_VARIANT_AS_STRING;
00476 _dbus_assert (dbus_signature_validate (sig, NULL));
00477 _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00478 dbus_signature_iter_init (&iter, sig);
00479 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY);
00480 _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY);
00481
00482 dbus_signature_iter_recurse (&iter, &subiter);
00483 dbus_signature_iter_recurse (&subiter, &subsubiter);
00484 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16);
00485 boolres = dbus_signature_iter_next (&subsubiter);
00486 _dbus_assert (boolres);
00487 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING);
00488 boolres = dbus_signature_iter_next (&subsubiter);
00489 _dbus_assert (!boolres);
00490
00491 boolres = dbus_signature_iter_next (&iter);
00492 _dbus_assert (boolres);
00493 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT);
00494 boolres = dbus_signature_iter_next (&iter);
00495 _dbus_assert (!boolres);
00496
00497 sig = DBUS_TYPE_DICT_ENTRY_AS_STRING;
00498 _dbus_assert (!dbus_signature_validate (sig, NULL));
00499
00500 sig = DBUS_TYPE_ARRAY_AS_STRING;
00501 _dbus_assert (!dbus_signature_validate (sig, NULL));
00502
00503 sig = DBUS_TYPE_UINT32_AS_STRING
00504 DBUS_TYPE_ARRAY_AS_STRING;
00505 _dbus_assert (!dbus_signature_validate (sig, NULL));
00506
00507 sig = DBUS_TYPE_ARRAY_AS_STRING
00508 DBUS_TYPE_DICT_ENTRY_AS_STRING;
00509 _dbus_assert (!dbus_signature_validate (sig, NULL));
00510
00511 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING;
00512 _dbus_assert (!dbus_signature_validate (sig, NULL));
00513
00514 sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
00515 _dbus_assert (!dbus_signature_validate (sig, NULL));
00516
00517 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00518 DBUS_TYPE_INT32_AS_STRING;
00519 _dbus_assert (!dbus_signature_validate (sig, NULL));
00520
00521 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00522 DBUS_TYPE_INT32_AS_STRING
00523 DBUS_TYPE_STRING_AS_STRING;
00524 _dbus_assert (!dbus_signature_validate (sig, NULL));
00525
00526 sig = DBUS_STRUCT_END_CHAR_AS_STRING
00527 DBUS_STRUCT_BEGIN_CHAR_AS_STRING;
00528 _dbus_assert (!dbus_signature_validate (sig, NULL));
00529
00530 sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00531 DBUS_TYPE_BOOLEAN_AS_STRING;
00532 _dbus_assert (!dbus_signature_validate (sig, NULL));
00533 return TRUE;
00534 #if 0
00535 oom:
00536 _dbus_assert_not_reached ("out of memory");
00537 return FALSE;
00538 #endif
00539 }
00540
00541 #endif
00542