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
00030 typedef struct
00031 {
00032 const char *pos;
00033 unsigned int finished : 1;
00034 unsigned int in_array : 1;
00035 } DBusSignatureRealIter;
00036
00053 void
00054 dbus_signature_iter_init (DBusSignatureIter *iter,
00055 const char *signature)
00056 {
00057 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00058
00059 real_iter->pos = signature;
00060 real_iter->finished = FALSE;
00061 real_iter->in_array = FALSE;
00062 }
00063
00078 int
00079 dbus_signature_iter_get_current_type (const DBusSignatureIter *iter)
00080 {
00081 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00082
00083 return _dbus_first_type_in_signature_c_str (real_iter->pos, 0);
00084 }
00085
00093 char *
00094 dbus_signature_iter_get_signature (const DBusSignatureIter *iter)
00095 {
00096 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00097 DBusString str;
00098 char *ret;
00099 int pos;
00100
00101 if (!_dbus_string_init (&str))
00102 return NULL;
00103
00104 pos = 0;
00105 _dbus_type_signature_next (real_iter->pos, &pos);
00106
00107 if (!_dbus_string_append_len (&str, real_iter->pos, pos))
00108 return NULL;
00109 if (!_dbus_string_steal_data (&str, &ret))
00110 ret = NULL;
00111 _dbus_string_free (&str);
00112
00113 return ret;
00114 }
00115
00127 int
00128 dbus_signature_iter_get_element_type (const DBusSignatureIter *iter)
00129 {
00130 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00131
00132 _dbus_return_val_if_fail (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
00133
00134 return _dbus_first_type_in_signature_c_str (real_iter->pos, 1);
00135 }
00136
00145 dbus_bool_t
00146 dbus_signature_iter_next (DBusSignatureIter *iter)
00147 {
00148 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00149
00150 if (real_iter->finished)
00151 return FALSE;
00152 else
00153 {
00154 int pos;
00155
00156 if (real_iter->in_array)
00157 {
00158 real_iter->finished = TRUE;
00159 return FALSE;
00160 }
00161
00162 pos = 0;
00163 _dbus_type_signature_next (real_iter->pos, &pos);
00164 real_iter->pos += pos;
00165
00166 if (*real_iter->pos == DBUS_STRUCT_END_CHAR
00167 || *real_iter->pos == DBUS_DICT_ENTRY_END_CHAR)
00168 {
00169 real_iter->finished = TRUE;
00170 return FALSE;
00171 }
00172
00173 return *real_iter->pos != DBUS_TYPE_INVALID;
00174 }
00175 }
00176
00185 void
00186 dbus_signature_iter_recurse (const DBusSignatureIter *iter,
00187 DBusSignatureIter *subiter)
00188 {
00189 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00190 DBusSignatureRealIter *real_sub_iter = (DBusSignatureRealIter *) subiter;
00191
00192 _dbus_return_if_fail (dbus_type_is_container (dbus_signature_iter_get_current_type (iter)));
00193
00194 *real_sub_iter = *real_iter;
00195 real_sub_iter->pos++;
00196
00197 if (dbus_signature_iter_get_current_type (subiter) == DBUS_TYPE_ARRAY)
00198 real_sub_iter->in_array = TRUE;
00199 }
00200
00208 dbus_bool_t
00209 dbus_signature_validate (const char *signature,
00210 DBusError *error)
00211
00212 {
00213 DBusString str;
00214
00215 _dbus_string_init_const (&str, signature);
00216 if (_dbus_validate_signature (&str, 0, _dbus_string_get_length (&str)))
00217 return TRUE;
00218 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Corrupt type signature");
00219 return FALSE;
00220 }
00221
00230 dbus_bool_t
00231 dbus_signature_validate_single (const char *signature,
00232 DBusError *error)
00233 {
00234 DBusSignatureIter iter;
00235
00236 if (!dbus_signature_validate (signature, error))
00237 return FALSE;
00238
00239 dbus_signature_iter_init (&iter, signature);
00240 if (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID)
00241 goto lose;
00242 if (!dbus_signature_iter_next (&iter))
00243 return TRUE;
00244 lose:
00245 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Exactly one complete type required in signature");
00246 return FALSE;
00247 }
00248
00250 #define TYPE_IS_CONTAINER(typecode) \
00251 ((typecode) == DBUS_TYPE_STRUCT || \
00252 (typecode) == DBUS_TYPE_DICT_ENTRY || \
00253 (typecode) == DBUS_TYPE_VARIANT || \
00254 (typecode) == DBUS_TYPE_ARRAY)
00255
00264 dbus_bool_t
00265 dbus_type_is_container (int typecode)
00266 {
00267
00268 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00269 FALSE);
00270 return TYPE_IS_CONTAINER (typecode);
00271 }
00272
00286 dbus_bool_t
00287 dbus_type_is_basic (int typecode)
00288 {
00289
00290 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00291 FALSE);
00292
00293
00294 return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode));
00295 }
00296
00308 dbus_bool_t
00309 dbus_type_is_fixed (int typecode)
00310 {
00311 switch (typecode)
00312 {
00313 case DBUS_TYPE_BYTE:
00314 case DBUS_TYPE_BOOLEAN:
00315 case DBUS_TYPE_INT16:
00316 case DBUS_TYPE_UINT16:
00317 case DBUS_TYPE_INT32:
00318 case DBUS_TYPE_UINT32:
00319 case DBUS_TYPE_INT64:
00320 case DBUS_TYPE_UINT64:
00321 case DBUS_TYPE_DOUBLE:
00322 return TRUE;
00323 default:
00324 return FALSE;
00325 }
00326 }
00327
00328 #ifdef DBUS_BUILD_TESTS
00329
00336 dbus_bool_t
00337 _dbus_signature_test (void)
00338 {
00339 DBusSignatureIter iter;
00340 DBusSignatureIter subiter;
00341 DBusSignatureIter subsubiter;
00342 DBusSignatureIter subsubsubiter;
00343 const char *sig;
00344
00345 _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter));
00346
00347 sig = "";
00348 _dbus_assert (dbus_signature_validate (sig, NULL));
00349 _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00350 dbus_signature_iter_init (&iter, sig);
00351 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID);
00352
00353 sig = DBUS_TYPE_STRING_AS_STRING;
00354 _dbus_assert (dbus_signature_validate (sig, NULL));
00355 _dbus_assert (dbus_signature_validate_single (sig, NULL));
00356 dbus_signature_iter_init (&iter, sig);
00357 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00358
00359 sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
00360 _dbus_assert (dbus_signature_validate (sig, NULL));
00361 dbus_signature_iter_init (&iter, sig);
00362 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00363 _dbus_assert (dbus_signature_iter_next (&iter));
00364 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE);
00365
00366 sig = DBUS_TYPE_UINT16_AS_STRING
00367 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00368 DBUS_TYPE_STRING_AS_STRING
00369 DBUS_TYPE_UINT32_AS_STRING
00370 DBUS_TYPE_VARIANT_AS_STRING
00371 DBUS_TYPE_DOUBLE_AS_STRING
00372 DBUS_STRUCT_END_CHAR_AS_STRING;
00373 _dbus_assert (dbus_signature_validate (sig, NULL));
00374 dbus_signature_iter_init (&iter, sig);
00375 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00376 _dbus_assert (dbus_signature_iter_next (&iter));
00377 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00378 dbus_signature_iter_recurse (&iter, &subiter);
00379 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING);
00380 _dbus_assert (dbus_signature_iter_next (&subiter));
00381 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00382 _dbus_assert (dbus_signature_iter_next (&subiter));
00383 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT);
00384 _dbus_assert (dbus_signature_iter_next (&subiter));
00385 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE);
00386
00387 sig = DBUS_TYPE_UINT16_AS_STRING
00388 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00389 DBUS_TYPE_UINT32_AS_STRING
00390 DBUS_TYPE_BYTE_AS_STRING
00391 DBUS_TYPE_ARRAY_AS_STRING
00392 DBUS_TYPE_ARRAY_AS_STRING
00393 DBUS_TYPE_DOUBLE_AS_STRING
00394 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00395 DBUS_TYPE_BYTE_AS_STRING
00396 DBUS_STRUCT_END_CHAR_AS_STRING
00397 DBUS_STRUCT_END_CHAR_AS_STRING;
00398 _dbus_assert (dbus_signature_validate (sig, NULL));
00399 dbus_signature_iter_init (&iter, sig);
00400 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00401 _dbus_assert (dbus_signature_iter_next (&iter));
00402 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00403 dbus_signature_iter_recurse (&iter, &subiter);
00404 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00405 _dbus_assert (dbus_signature_iter_next (&subiter));
00406 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE);
00407 _dbus_assert (dbus_signature_iter_next (&subiter));
00408 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY);
00409 _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY);
00410
00411 dbus_signature_iter_recurse (&subiter, &subsubiter);
00412 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY);
00413 _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE);
00414
00415 dbus_signature_iter_recurse (&subsubiter, &subsubsubiter);
00416 _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE);
00417 _dbus_assert (dbus_signature_iter_next (&subiter));
00418 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT);
00419 dbus_signature_iter_recurse (&subiter, &subsubiter);
00420 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE);
00421
00422 sig = DBUS_TYPE_ARRAY_AS_STRING
00423 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00424 DBUS_TYPE_INT16_AS_STRING
00425 DBUS_TYPE_STRING_AS_STRING
00426 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
00427 DBUS_TYPE_VARIANT_AS_STRING;
00428 _dbus_assert (dbus_signature_validate (sig, NULL));
00429 _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00430 dbus_signature_iter_init (&iter, sig);
00431 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY);
00432 _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY);
00433
00434 dbus_signature_iter_recurse (&iter, &subiter);
00435 dbus_signature_iter_recurse (&subiter, &subsubiter);
00436 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16);
00437 _dbus_assert (dbus_signature_iter_next (&subsubiter));
00438 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING);
00439 _dbus_assert (!dbus_signature_iter_next (&subsubiter));
00440
00441 _dbus_assert (dbus_signature_iter_next (&iter));
00442 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT);
00443 _dbus_assert (!dbus_signature_iter_next (&iter));
00444
00445 sig = DBUS_TYPE_DICT_ENTRY_AS_STRING;
00446 _dbus_assert (!dbus_signature_validate (sig, NULL));
00447
00448 sig = DBUS_TYPE_ARRAY_AS_STRING;
00449 _dbus_assert (!dbus_signature_validate (sig, NULL));
00450
00451 sig = DBUS_TYPE_UINT32_AS_STRING
00452 DBUS_TYPE_ARRAY_AS_STRING;
00453 _dbus_assert (!dbus_signature_validate (sig, NULL));
00454
00455 sig = DBUS_TYPE_ARRAY_AS_STRING
00456 DBUS_TYPE_DICT_ENTRY_AS_STRING;
00457 _dbus_assert (!dbus_signature_validate (sig, NULL));
00458
00459 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING;
00460 _dbus_assert (!dbus_signature_validate (sig, NULL));
00461
00462 sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
00463 _dbus_assert (!dbus_signature_validate (sig, NULL));
00464
00465 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00466 DBUS_TYPE_INT32_AS_STRING;
00467 _dbus_assert (!dbus_signature_validate (sig, NULL));
00468
00469 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00470 DBUS_TYPE_INT32_AS_STRING
00471 DBUS_TYPE_STRING_AS_STRING;
00472 _dbus_assert (!dbus_signature_validate (sig, NULL));
00473
00474 sig = DBUS_STRUCT_END_CHAR_AS_STRING
00475 DBUS_STRUCT_BEGIN_CHAR_AS_STRING;
00476 _dbus_assert (!dbus_signature_validate (sig, NULL));
00477
00478 sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00479 DBUS_TYPE_BOOLEAN_AS_STRING;
00480 _dbus_assert (!dbus_signature_validate (sig, NULL));
00481 return TRUE;
00482 #if 0
00483 oom:
00484 _dbus_assert_not_reached ("out of memory");
00485 return FALSE;
00486 #endif
00487 }
00488
00489 #endif
00490
00492