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