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
00293 dbus_bool_t
00294 dbus_type_is_container (int typecode)
00295 {
00296
00297 _dbus_return_val_if_fail (dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00298 FALSE);
00299 return TYPE_IS_CONTAINER (typecode);
00300 }
00301
00317 dbus_bool_t
00318 dbus_type_is_basic (int typecode)
00319 {
00320
00321 _dbus_return_val_if_fail (dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00322 FALSE);
00323
00324
00325 return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode));
00326 }
00327
00348 dbus_bool_t
00349 dbus_type_is_fixed (int typecode)
00350 {
00351
00352 _dbus_return_val_if_fail (dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00353 FALSE);
00354
00355 switch (typecode)
00356 {
00357 case DBUS_TYPE_BYTE:
00358 case DBUS_TYPE_BOOLEAN:
00359 case DBUS_TYPE_INT16:
00360 case DBUS_TYPE_UINT16:
00361 case DBUS_TYPE_INT32:
00362 case DBUS_TYPE_UINT32:
00363 case DBUS_TYPE_INT64:
00364 case DBUS_TYPE_UINT64:
00365 case DBUS_TYPE_DOUBLE:
00366 case DBUS_TYPE_UNIX_FD:
00367 return TRUE;
00368 default:
00369 return FALSE;
00370 }
00371 }
00372
00382 dbus_bool_t
00383 dbus_type_is_valid (int typecode)
00384 {
00385 switch (typecode)
00386 {
00387 case DBUS_TYPE_BYTE:
00388 case DBUS_TYPE_BOOLEAN:
00389 case DBUS_TYPE_INT16:
00390 case DBUS_TYPE_UINT16:
00391 case DBUS_TYPE_INT32:
00392 case DBUS_TYPE_UINT32:
00393 case DBUS_TYPE_INT64:
00394 case DBUS_TYPE_UINT64:
00395 case DBUS_TYPE_DOUBLE:
00396 case DBUS_TYPE_STRING:
00397 case DBUS_TYPE_OBJECT_PATH:
00398 case DBUS_TYPE_SIGNATURE:
00399 case DBUS_TYPE_ARRAY:
00400 case DBUS_TYPE_STRUCT:
00401 case DBUS_TYPE_DICT_ENTRY:
00402 case DBUS_TYPE_VARIANT:
00403 case DBUS_TYPE_UNIX_FD:
00404 return TRUE;
00405
00406 default:
00407 return FALSE;
00408 }
00409 }
00410
00412
00413 #ifdef DBUS_BUILD_TESTS
00414
00421 dbus_bool_t
00422 _dbus_signature_test (void)
00423 {
00424 DBusSignatureIter iter;
00425 DBusSignatureIter subiter;
00426 DBusSignatureIter subsubiter;
00427 DBusSignatureIter subsubsubiter;
00428 const char *sig;
00429 dbus_bool_t boolres;
00430
00431 _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter));
00432
00433 sig = "";
00434 _dbus_assert (dbus_signature_validate (sig, NULL));
00435 _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00436 dbus_signature_iter_init (&iter, sig);
00437 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID);
00438
00439 sig = DBUS_TYPE_STRING_AS_STRING;
00440 _dbus_assert (dbus_signature_validate (sig, NULL));
00441 _dbus_assert (dbus_signature_validate_single (sig, NULL));
00442 dbus_signature_iter_init (&iter, sig);
00443 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00444
00445 sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
00446 _dbus_assert (dbus_signature_validate (sig, NULL));
00447 dbus_signature_iter_init (&iter, sig);
00448 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00449 boolres = dbus_signature_iter_next (&iter);
00450 _dbus_assert (boolres);
00451 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE);
00452
00453 sig = DBUS_TYPE_UINT16_AS_STRING
00454 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00455 DBUS_TYPE_STRING_AS_STRING
00456 DBUS_TYPE_UINT32_AS_STRING
00457 DBUS_TYPE_VARIANT_AS_STRING
00458 DBUS_TYPE_DOUBLE_AS_STRING
00459 DBUS_STRUCT_END_CHAR_AS_STRING;
00460 _dbus_assert (dbus_signature_validate (sig, NULL));
00461 dbus_signature_iter_init (&iter, sig);
00462 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00463 boolres = dbus_signature_iter_next (&iter);
00464 _dbus_assert (boolres);
00465 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00466 dbus_signature_iter_recurse (&iter, &subiter);
00467 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING);
00468 boolres = dbus_signature_iter_next (&subiter);
00469 _dbus_assert (boolres);
00470 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00471 boolres = dbus_signature_iter_next (&subiter);
00472 _dbus_assert (boolres);
00473 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT);
00474 boolres = dbus_signature_iter_next (&subiter);
00475 _dbus_assert (boolres);
00476 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE);
00477
00478 sig = DBUS_TYPE_UINT16_AS_STRING
00479 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00480 DBUS_TYPE_UINT32_AS_STRING
00481 DBUS_TYPE_BYTE_AS_STRING
00482 DBUS_TYPE_ARRAY_AS_STRING
00483 DBUS_TYPE_ARRAY_AS_STRING
00484 DBUS_TYPE_DOUBLE_AS_STRING
00485 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00486 DBUS_TYPE_BYTE_AS_STRING
00487 DBUS_STRUCT_END_CHAR_AS_STRING
00488 DBUS_STRUCT_END_CHAR_AS_STRING;
00489 _dbus_assert (dbus_signature_validate (sig, NULL));
00490 dbus_signature_iter_init (&iter, sig);
00491 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00492 boolres = dbus_signature_iter_next (&iter);
00493 _dbus_assert (boolres);
00494 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00495 dbus_signature_iter_recurse (&iter, &subiter);
00496 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00497 boolres = dbus_signature_iter_next (&subiter);
00498 _dbus_assert (boolres);
00499 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE);
00500 boolres = dbus_signature_iter_next (&subiter);
00501 _dbus_assert (boolres);
00502 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY);
00503 _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY);
00504
00505 dbus_signature_iter_recurse (&subiter, &subsubiter);
00506 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY);
00507 _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE);
00508
00509 dbus_signature_iter_recurse (&subsubiter, &subsubsubiter);
00510 _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE);
00511 boolres = dbus_signature_iter_next (&subiter);
00512 _dbus_assert (boolres);
00513 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT);
00514 dbus_signature_iter_recurse (&subiter, &subsubiter);
00515 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE);
00516
00517 sig = DBUS_TYPE_ARRAY_AS_STRING
00518 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00519 DBUS_TYPE_INT16_AS_STRING
00520 DBUS_TYPE_STRING_AS_STRING
00521 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
00522 DBUS_TYPE_VARIANT_AS_STRING;
00523 _dbus_assert (dbus_signature_validate (sig, NULL));
00524 _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00525 dbus_signature_iter_init (&iter, sig);
00526 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY);
00527 _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY);
00528
00529 dbus_signature_iter_recurse (&iter, &subiter);
00530 dbus_signature_iter_recurse (&subiter, &subsubiter);
00531 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16);
00532 boolres = dbus_signature_iter_next (&subsubiter);
00533 _dbus_assert (boolres);
00534 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING);
00535 boolres = dbus_signature_iter_next (&subsubiter);
00536 _dbus_assert (!boolres);
00537
00538 boolres = dbus_signature_iter_next (&iter);
00539 _dbus_assert (boolres);
00540 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT);
00541 boolres = dbus_signature_iter_next (&iter);
00542 _dbus_assert (!boolres);
00543
00544 sig = DBUS_TYPE_DICT_ENTRY_AS_STRING;
00545 _dbus_assert (!dbus_signature_validate (sig, NULL));
00546
00547 sig = DBUS_TYPE_ARRAY_AS_STRING;
00548 _dbus_assert (!dbus_signature_validate (sig, NULL));
00549
00550 sig = DBUS_TYPE_UINT32_AS_STRING
00551 DBUS_TYPE_ARRAY_AS_STRING;
00552 _dbus_assert (!dbus_signature_validate (sig, NULL));
00553
00554 sig = DBUS_TYPE_ARRAY_AS_STRING
00555 DBUS_TYPE_DICT_ENTRY_AS_STRING;
00556 _dbus_assert (!dbus_signature_validate (sig, NULL));
00557
00558 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING;
00559 _dbus_assert (!dbus_signature_validate (sig, NULL));
00560
00561 sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
00562 _dbus_assert (!dbus_signature_validate (sig, NULL));
00563
00564 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00565 DBUS_TYPE_INT32_AS_STRING;
00566 _dbus_assert (!dbus_signature_validate (sig, NULL));
00567
00568 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00569 DBUS_TYPE_INT32_AS_STRING
00570 DBUS_TYPE_STRING_AS_STRING;
00571 _dbus_assert (!dbus_signature_validate (sig, NULL));
00572
00573 sig = DBUS_STRUCT_END_CHAR_AS_STRING
00574 DBUS_STRUCT_BEGIN_CHAR_AS_STRING;
00575 _dbus_assert (!dbus_signature_validate (sig, NULL));
00576
00577 sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00578 DBUS_TYPE_BOOLEAN_AS_STRING;
00579 _dbus_assert (!dbus_signature_validate (sig, NULL));
00580 return TRUE;
00581 #if 0
00582 oom:
00583 _dbus_assert_not_reached ("out of memory");
00584 return FALSE;
00585 #endif
00586 }
00587
00588 #endif
00589