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
00346 _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter));
00347
00348 sig = "";
00349 _dbus_assert (dbus_signature_validate (sig, NULL));
00350 _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00351 dbus_signature_iter_init (&iter, sig);
00352 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID);
00353
00354 sig = DBUS_TYPE_STRING_AS_STRING;
00355 _dbus_assert (dbus_signature_validate (sig, NULL));
00356 _dbus_assert (dbus_signature_validate_single (sig, NULL));
00357 dbus_signature_iter_init (&iter, sig);
00358 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00359
00360 sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
00361 _dbus_assert (dbus_signature_validate (sig, NULL));
00362 dbus_signature_iter_init (&iter, sig);
00363 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00364 _dbus_assert (dbus_signature_iter_next (&iter));
00365 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE);
00366
00367 sig = DBUS_TYPE_UINT16_AS_STRING
00368 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00369 DBUS_TYPE_STRING_AS_STRING
00370 DBUS_TYPE_UINT32_AS_STRING
00371 DBUS_TYPE_VARIANT_AS_STRING
00372 DBUS_TYPE_DOUBLE_AS_STRING
00373 DBUS_STRUCT_END_CHAR_AS_STRING;
00374 _dbus_assert (dbus_signature_validate (sig, NULL));
00375 dbus_signature_iter_init (&iter, sig);
00376 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00377 _dbus_assert (dbus_signature_iter_next (&iter));
00378 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00379 dbus_signature_iter_recurse (&iter, &subiter);
00380 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING);
00381 _dbus_assert (dbus_signature_iter_next (&subiter));
00382 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00383 _dbus_assert (dbus_signature_iter_next (&subiter));
00384 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT);
00385 _dbus_assert (dbus_signature_iter_next (&subiter));
00386 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE);
00387
00388 sig = DBUS_TYPE_UINT16_AS_STRING
00389 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00390 DBUS_TYPE_UINT32_AS_STRING
00391 DBUS_TYPE_BYTE_AS_STRING
00392 DBUS_TYPE_ARRAY_AS_STRING
00393 DBUS_TYPE_ARRAY_AS_STRING
00394 DBUS_TYPE_DOUBLE_AS_STRING
00395 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00396 DBUS_TYPE_BYTE_AS_STRING
00397 DBUS_STRUCT_END_CHAR_AS_STRING
00398 DBUS_STRUCT_END_CHAR_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_UINT16);
00402 _dbus_assert (dbus_signature_iter_next (&iter));
00403 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00404 dbus_signature_iter_recurse (&iter, &subiter);
00405 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00406 _dbus_assert (dbus_signature_iter_next (&subiter));
00407 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE);
00408 _dbus_assert (dbus_signature_iter_next (&subiter));
00409 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY);
00410 _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY);
00411
00412 dbus_signature_iter_recurse (&subiter, &subsubiter);
00413 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY);
00414 _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE);
00415
00416 dbus_signature_iter_recurse (&subsubiter, &subsubsubiter);
00417 _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE);
00418 _dbus_assert (dbus_signature_iter_next (&subiter));
00419 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT);
00420 dbus_signature_iter_recurse (&subiter, &subsubiter);
00421 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE);
00422
00423 sig = DBUS_TYPE_ARRAY_AS_STRING
00424 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00425 DBUS_TYPE_INT16_AS_STRING
00426 DBUS_TYPE_STRING_AS_STRING
00427 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
00428 DBUS_TYPE_VARIANT_AS_STRING;
00429 _dbus_assert (dbus_signature_validate (sig, NULL));
00430 _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00431 dbus_signature_iter_init (&iter, sig);
00432 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY);
00433 _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY);
00434
00435 dbus_signature_iter_recurse (&iter, &subiter);
00436 dbus_signature_iter_recurse (&subiter, &subsubiter);
00437 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16);
00438 _dbus_assert (dbus_signature_iter_next (&subsubiter));
00439 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING);
00440 _dbus_assert (!dbus_signature_iter_next (&subsubiter));
00441
00442 _dbus_assert (dbus_signature_iter_next (&iter));
00443 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT);
00444 _dbus_assert (!dbus_signature_iter_next (&iter));
00445
00446 sig = DBUS_TYPE_DICT_ENTRY_AS_STRING;
00447 _dbus_assert (!dbus_signature_validate (sig, NULL));
00448
00449 sig = DBUS_TYPE_ARRAY_AS_STRING;
00450 _dbus_assert (!dbus_signature_validate (sig, NULL));
00451
00452 sig = DBUS_TYPE_UINT32_AS_STRING
00453 DBUS_TYPE_ARRAY_AS_STRING;
00454 _dbus_assert (!dbus_signature_validate (sig, NULL));
00455
00456 sig = DBUS_TYPE_ARRAY_AS_STRING
00457 DBUS_TYPE_DICT_ENTRY_AS_STRING;
00458 _dbus_assert (!dbus_signature_validate (sig, NULL));
00459
00460 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING;
00461 _dbus_assert (!dbus_signature_validate (sig, NULL));
00462
00463 sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
00464 _dbus_assert (!dbus_signature_validate (sig, NULL));
00465
00466 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00467 DBUS_TYPE_INT32_AS_STRING;
00468 _dbus_assert (!dbus_signature_validate (sig, NULL));
00469
00470 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00471 DBUS_TYPE_INT32_AS_STRING
00472 DBUS_TYPE_STRING_AS_STRING;
00473 _dbus_assert (!dbus_signature_validate (sig, NULL));
00474
00475 sig = DBUS_STRUCT_END_CHAR_AS_STRING
00476 DBUS_STRUCT_BEGIN_CHAR_AS_STRING;
00477 _dbus_assert (!dbus_signature_validate (sig, NULL));
00478
00479 sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00480 DBUS_TYPE_BOOLEAN_AS_STRING;
00481 _dbus_assert (!dbus_signature_validate (sig, NULL));
00482 return TRUE;
00483 #if 0
00484 oom:
00485 _dbus_assert_not_reached ("out of memory");
00486 return FALSE;
00487 #endif
00488 }
00489
00490 #endif
00491
00493