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->in_array = FALSE;
00196 real_sub_iter->pos++;
00197
00198 if (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY)
00199 real_sub_iter->in_array = TRUE;
00200 }
00201
00209 dbus_bool_t
00210 dbus_signature_validate (const char *signature,
00211 DBusError *error)
00212
00213 {
00214 DBusString str;
00215
00216 _dbus_string_init_const (&str, signature);
00217 if (_dbus_validate_signature (&str, 0, _dbus_string_get_length (&str)))
00218 return TRUE;
00219 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Corrupt type signature");
00220 return FALSE;
00221 }
00222
00231 dbus_bool_t
00232 dbus_signature_validate_single (const char *signature,
00233 DBusError *error)
00234 {
00235 DBusSignatureIter iter;
00236
00237 if (!dbus_signature_validate (signature, error))
00238 return FALSE;
00239
00240 dbus_signature_iter_init (&iter, signature);
00241 if (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID)
00242 goto lose;
00243 if (!dbus_signature_iter_next (&iter))
00244 return TRUE;
00245 lose:
00246 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Exactly one complete type required in signature");
00247 return FALSE;
00248 }
00249
00251 #define TYPE_IS_CONTAINER(typecode) \
00252 ((typecode) == DBUS_TYPE_STRUCT || \
00253 (typecode) == DBUS_TYPE_DICT_ENTRY || \
00254 (typecode) == DBUS_TYPE_VARIANT || \
00255 (typecode) == DBUS_TYPE_ARRAY)
00256
00265 dbus_bool_t
00266 dbus_type_is_container (int typecode)
00267 {
00268
00269 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00270 FALSE);
00271 return TYPE_IS_CONTAINER (typecode);
00272 }
00273
00287 dbus_bool_t
00288 dbus_type_is_basic (int typecode)
00289 {
00290
00291 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00292 FALSE);
00293
00294
00295 return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode));
00296 }
00297
00309 dbus_bool_t
00310 dbus_type_is_fixed (int typecode)
00311 {
00312 switch (typecode)
00313 {
00314 case DBUS_TYPE_BYTE:
00315 case DBUS_TYPE_BOOLEAN:
00316 case DBUS_TYPE_INT16:
00317 case DBUS_TYPE_UINT16:
00318 case DBUS_TYPE_INT32:
00319 case DBUS_TYPE_UINT32:
00320 case DBUS_TYPE_INT64:
00321 case DBUS_TYPE_UINT64:
00322 case DBUS_TYPE_DOUBLE:
00323 return TRUE;
00324 default:
00325 return FALSE;
00326 }
00327 }
00328
00329 #ifdef DBUS_BUILD_TESTS
00330
00337 dbus_bool_t
00338 _dbus_signature_test (void)
00339 {
00340 DBusSignatureIter iter;
00341 DBusSignatureIter subiter;
00342 DBusSignatureIter subsubiter;
00343 DBusSignatureIter subsubsubiter;
00344 const char *sig;
00345 dbus_bool_t boolres;
00346
00347 _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter));
00348
00349 sig = "";
00350 _dbus_assert (dbus_signature_validate (sig, NULL));
00351 _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00352 dbus_signature_iter_init (&iter, sig);
00353 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID);
00354
00355 sig = DBUS_TYPE_STRING_AS_STRING;
00356 _dbus_assert (dbus_signature_validate (sig, NULL));
00357 _dbus_assert (dbus_signature_validate_single (sig, NULL));
00358 dbus_signature_iter_init (&iter, sig);
00359 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00360
00361 sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
00362 _dbus_assert (dbus_signature_validate (sig, NULL));
00363 dbus_signature_iter_init (&iter, sig);
00364 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00365 boolres = dbus_signature_iter_next (&iter);
00366 _dbus_assert (boolres);
00367 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE);
00368
00369 sig = DBUS_TYPE_UINT16_AS_STRING
00370 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00371 DBUS_TYPE_STRING_AS_STRING
00372 DBUS_TYPE_UINT32_AS_STRING
00373 DBUS_TYPE_VARIANT_AS_STRING
00374 DBUS_TYPE_DOUBLE_AS_STRING
00375 DBUS_STRUCT_END_CHAR_AS_STRING;
00376 _dbus_assert (dbus_signature_validate (sig, NULL));
00377 dbus_signature_iter_init (&iter, sig);
00378 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00379 boolres = dbus_signature_iter_next (&iter);
00380 _dbus_assert (boolres);
00381 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00382 dbus_signature_iter_recurse (&iter, &subiter);
00383 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING);
00384 boolres = dbus_signature_iter_next (&subiter);
00385 _dbus_assert (boolres);
00386 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00387 boolres = dbus_signature_iter_next (&subiter);
00388 _dbus_assert (boolres);
00389 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT);
00390 boolres = dbus_signature_iter_next (&subiter);
00391 _dbus_assert (boolres);
00392 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE);
00393
00394 sig = DBUS_TYPE_UINT16_AS_STRING
00395 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00396 DBUS_TYPE_UINT32_AS_STRING
00397 DBUS_TYPE_BYTE_AS_STRING
00398 DBUS_TYPE_ARRAY_AS_STRING
00399 DBUS_TYPE_ARRAY_AS_STRING
00400 DBUS_TYPE_DOUBLE_AS_STRING
00401 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00402 DBUS_TYPE_BYTE_AS_STRING
00403 DBUS_STRUCT_END_CHAR_AS_STRING
00404 DBUS_STRUCT_END_CHAR_AS_STRING;
00405 _dbus_assert (dbus_signature_validate (sig, NULL));
00406 dbus_signature_iter_init (&iter, sig);
00407 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00408 boolres = dbus_signature_iter_next (&iter);
00409 _dbus_assert (boolres);
00410 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00411 dbus_signature_iter_recurse (&iter, &subiter);
00412 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00413 boolres = dbus_signature_iter_next (&subiter);
00414 _dbus_assert (boolres);
00415 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE);
00416 boolres = dbus_signature_iter_next (&subiter);
00417 _dbus_assert (boolres);
00418 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY);
00419 _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY);
00420
00421 dbus_signature_iter_recurse (&subiter, &subsubiter);
00422 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY);
00423 _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE);
00424
00425 dbus_signature_iter_recurse (&subsubiter, &subsubsubiter);
00426 _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE);
00427 boolres = dbus_signature_iter_next (&subiter);
00428 _dbus_assert (boolres);
00429 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT);
00430 dbus_signature_iter_recurse (&subiter, &subsubiter);
00431 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE);
00432
00433 sig = DBUS_TYPE_ARRAY_AS_STRING
00434 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00435 DBUS_TYPE_INT16_AS_STRING
00436 DBUS_TYPE_STRING_AS_STRING
00437 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
00438 DBUS_TYPE_VARIANT_AS_STRING;
00439 _dbus_assert (dbus_signature_validate (sig, NULL));
00440 _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00441 dbus_signature_iter_init (&iter, sig);
00442 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY);
00443 _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY);
00444
00445 dbus_signature_iter_recurse (&iter, &subiter);
00446 dbus_signature_iter_recurse (&subiter, &subsubiter);
00447 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16);
00448 boolres = dbus_signature_iter_next (&subsubiter);
00449 _dbus_assert (boolres);
00450 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING);
00451 boolres = dbus_signature_iter_next (&subsubiter);
00452 _dbus_assert (!boolres);
00453
00454 boolres = dbus_signature_iter_next (&iter);
00455 _dbus_assert (boolres);
00456 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT);
00457 boolres = dbus_signature_iter_next (&iter);
00458 _dbus_assert (!boolres);
00459
00460 sig = DBUS_TYPE_DICT_ENTRY_AS_STRING;
00461 _dbus_assert (!dbus_signature_validate (sig, NULL));
00462
00463 sig = DBUS_TYPE_ARRAY_AS_STRING;
00464 _dbus_assert (!dbus_signature_validate (sig, NULL));
00465
00466 sig = DBUS_TYPE_UINT32_AS_STRING
00467 DBUS_TYPE_ARRAY_AS_STRING;
00468 _dbus_assert (!dbus_signature_validate (sig, NULL));
00469
00470 sig = DBUS_TYPE_ARRAY_AS_STRING
00471 DBUS_TYPE_DICT_ENTRY_AS_STRING;
00472 _dbus_assert (!dbus_signature_validate (sig, NULL));
00473
00474 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING;
00475 _dbus_assert (!dbus_signature_validate (sig, NULL));
00476
00477 sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
00478 _dbus_assert (!dbus_signature_validate (sig, NULL));
00479
00480 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00481 DBUS_TYPE_INT32_AS_STRING;
00482 _dbus_assert (!dbus_signature_validate (sig, NULL));
00483
00484 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00485 DBUS_TYPE_INT32_AS_STRING
00486 DBUS_TYPE_STRING_AS_STRING;
00487 _dbus_assert (!dbus_signature_validate (sig, NULL));
00488
00489 sig = DBUS_STRUCT_END_CHAR_AS_STRING
00490 DBUS_STRUCT_BEGIN_CHAR_AS_STRING;
00491 _dbus_assert (!dbus_signature_validate (sig, NULL));
00492
00493 sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00494 DBUS_TYPE_BOOLEAN_AS_STRING;
00495 _dbus_assert (!dbus_signature_validate (sig, NULL));
00496 return TRUE;
00497 #if 0
00498 oom:
00499 _dbus_assert_not_reached ("out of memory");
00500 return FALSE;
00501 #endif
00502 }
00503
00504 #endif
00505
00507