D-Bus 1.2.24
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 00002 /* dbus-signature.c Routines for reading recursive type signatures 00003 * 00004 * Copyright (C) 2005 Red Hat, Inc. 00005 * 00006 * Licensed under the Academic Free License version 2.1 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 00033 typedef struct 00034 { 00035 const char *pos; 00036 unsigned int finished : 1; 00037 unsigned int in_array : 1; 00038 } DBusSignatureRealIter; 00039 00041 #define TYPE_IS_CONTAINER(typecode) \ 00042 ((typecode) == DBUS_TYPE_STRUCT || \ 00043 (typecode) == DBUS_TYPE_DICT_ENTRY || \ 00044 (typecode) == DBUS_TYPE_VARIANT || \ 00045 (typecode) == DBUS_TYPE_ARRAY) 00046 00047 00064 void 00065 dbus_signature_iter_init (DBusSignatureIter *iter, 00066 const char *signature) 00067 { 00068 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00069 00070 real_iter->pos = signature; 00071 real_iter->finished = FALSE; 00072 real_iter->in_array = FALSE; 00073 } 00074 00089 int 00090 dbus_signature_iter_get_current_type (const DBusSignatureIter *iter) 00091 { 00092 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00093 00094 return _dbus_first_type_in_signature_c_str (real_iter->pos, 0); 00095 } 00096 00109 char * 00110 dbus_signature_iter_get_signature (const DBusSignatureIter *iter) 00111 { 00112 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00113 DBusString str; 00114 char *ret; 00115 int pos; 00116 00117 if (!_dbus_string_init (&str)) 00118 return NULL; 00119 00120 pos = 0; 00121 _dbus_type_signature_next (real_iter->pos, &pos); 00122 00123 if (!_dbus_string_append_len (&str, real_iter->pos, pos)) 00124 return NULL; 00125 if (!_dbus_string_steal_data (&str, &ret)) 00126 ret = NULL; 00127 _dbus_string_free (&str); 00128 00129 return ret; 00130 } 00131 00143 int 00144 dbus_signature_iter_get_element_type (const DBusSignatureIter *iter) 00145 { 00146 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00147 00148 _dbus_return_val_if_fail (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID); 00149 00150 return _dbus_first_type_in_signature_c_str (real_iter->pos, 1); 00151 } 00152 00161 dbus_bool_t 00162 dbus_signature_iter_next (DBusSignatureIter *iter) 00163 { 00164 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00165 00166 if (real_iter->finished) 00167 return FALSE; 00168 else 00169 { 00170 int pos; 00171 00172 if (real_iter->in_array) 00173 { 00174 real_iter->finished = TRUE; 00175 return FALSE; 00176 } 00177 00178 pos = 0; 00179 _dbus_type_signature_next (real_iter->pos, &pos); 00180 real_iter->pos += pos; 00181 00182 if (*real_iter->pos == DBUS_STRUCT_END_CHAR 00183 || *real_iter->pos == DBUS_DICT_ENTRY_END_CHAR) 00184 { 00185 real_iter->finished = TRUE; 00186 return FALSE; 00187 } 00188 00189 return *real_iter->pos != DBUS_TYPE_INVALID; 00190 } 00191 } 00192 00204 void 00205 dbus_signature_iter_recurse (const DBusSignatureIter *iter, 00206 DBusSignatureIter *subiter) 00207 { 00208 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00209 DBusSignatureRealIter *real_sub_iter = (DBusSignatureRealIter *) subiter; 00210 00211 _dbus_return_if_fail (dbus_type_is_container (dbus_signature_iter_get_current_type (iter))); 00212 00213 *real_sub_iter = *real_iter; 00214 real_sub_iter->in_array = FALSE; 00215 real_sub_iter->pos++; 00216 00217 if (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY) 00218 real_sub_iter->in_array = TRUE; 00219 } 00220 00230 dbus_bool_t 00231 dbus_signature_validate (const char *signature, 00232 DBusError *error) 00233 00234 { 00235 DBusString str; 00236 DBusValidity reason; 00237 00238 _dbus_string_init_const (&str, signature); 00239 reason = _dbus_validate_signature_with_reason (&str, 0, _dbus_string_get_length (&str)); 00240 00241 if (reason == DBUS_VALID) 00242 return TRUE; 00243 else 00244 { 00245 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, _dbus_validity_to_error_message (reason)); 00246 return FALSE; 00247 } 00248 } 00249 00261 dbus_bool_t 00262 dbus_signature_validate_single (const char *signature, 00263 DBusError *error) 00264 { 00265 DBusSignatureIter iter; 00266 00267 if (!dbus_signature_validate (signature, error)) 00268 return FALSE; 00269 00270 dbus_signature_iter_init (&iter, signature); 00271 if (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID) 00272 goto lose; 00273 if (!dbus_signature_iter_next (&iter)) 00274 return TRUE; 00275 lose: 00276 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Exactly one complete type required in signature"); 00277 return FALSE; 00278 } 00279 00289 dbus_bool_t 00290 dbus_type_is_container (int typecode) 00291 { 00292 /* only reasonable (non-line-noise) typecodes are allowed */ 00293 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, 00294 FALSE); 00295 return TYPE_IS_CONTAINER (typecode); 00296 } 00297 00311 dbus_bool_t 00312 dbus_type_is_basic (int typecode) 00313 { 00314 /* only reasonable (non-line-noise) typecodes are allowed */ 00315 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, 00316 FALSE); 00317 00318 /* everything that isn't invalid or a container */ 00319 return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode)); 00320 } 00321 00340 dbus_bool_t 00341 dbus_type_is_fixed (int typecode) 00342 { 00343 /* only reasonable (non-line-noise) typecodes are allowed */ 00344 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, 00345 FALSE); 00346 00347 switch (typecode) 00348 { 00349 case DBUS_TYPE_BYTE: 00350 case DBUS_TYPE_BOOLEAN: 00351 case DBUS_TYPE_INT16: 00352 case DBUS_TYPE_UINT16: 00353 case DBUS_TYPE_INT32: 00354 case DBUS_TYPE_UINT32: 00355 case DBUS_TYPE_INT64: 00356 case DBUS_TYPE_UINT64: 00357 case DBUS_TYPE_DOUBLE: 00358 return TRUE; 00359 default: 00360 return FALSE; 00361 } 00362 } 00363 /* end of DBusSignature group */ 00365 00366 #ifdef DBUS_BUILD_TESTS 00367 00374 dbus_bool_t 00375 _dbus_signature_test (void) 00376 { 00377 DBusSignatureIter iter; 00378 DBusSignatureIter subiter; 00379 DBusSignatureIter subsubiter; 00380 DBusSignatureIter subsubsubiter; 00381 const char *sig; 00382 dbus_bool_t boolres; 00383 00384 _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter)); 00385 00386 sig = ""; 00387 _dbus_assert (dbus_signature_validate (sig, NULL)); 00388 _dbus_assert (!dbus_signature_validate_single (sig, NULL)); 00389 dbus_signature_iter_init (&iter, sig); 00390 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID); 00391 00392 sig = DBUS_TYPE_STRING_AS_STRING; 00393 _dbus_assert (dbus_signature_validate (sig, NULL)); 00394 _dbus_assert (dbus_signature_validate_single (sig, NULL)); 00395 dbus_signature_iter_init (&iter, sig); 00396 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING); 00397 00398 sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_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_STRING); 00402 boolres = dbus_signature_iter_next (&iter); 00403 _dbus_assert (boolres); 00404 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE); 00405 00406 sig = DBUS_TYPE_UINT16_AS_STRING 00407 DBUS_STRUCT_BEGIN_CHAR_AS_STRING 00408 DBUS_TYPE_STRING_AS_STRING 00409 DBUS_TYPE_UINT32_AS_STRING 00410 DBUS_TYPE_VARIANT_AS_STRING 00411 DBUS_TYPE_DOUBLE_AS_STRING 00412 DBUS_STRUCT_END_CHAR_AS_STRING; 00413 _dbus_assert (dbus_signature_validate (sig, NULL)); 00414 dbus_signature_iter_init (&iter, sig); 00415 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16); 00416 boolres = dbus_signature_iter_next (&iter); 00417 _dbus_assert (boolres); 00418 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT); 00419 dbus_signature_iter_recurse (&iter, &subiter); 00420 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING); 00421 boolres = dbus_signature_iter_next (&subiter); 00422 _dbus_assert (boolres); 00423 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32); 00424 boolres = dbus_signature_iter_next (&subiter); 00425 _dbus_assert (boolres); 00426 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT); 00427 boolres = dbus_signature_iter_next (&subiter); 00428 _dbus_assert (boolres); 00429 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE); 00430 00431 sig = DBUS_TYPE_UINT16_AS_STRING 00432 DBUS_STRUCT_BEGIN_CHAR_AS_STRING 00433 DBUS_TYPE_UINT32_AS_STRING 00434 DBUS_TYPE_BYTE_AS_STRING 00435 DBUS_TYPE_ARRAY_AS_STRING 00436 DBUS_TYPE_ARRAY_AS_STRING 00437 DBUS_TYPE_DOUBLE_AS_STRING 00438 DBUS_STRUCT_BEGIN_CHAR_AS_STRING 00439 DBUS_TYPE_BYTE_AS_STRING 00440 DBUS_STRUCT_END_CHAR_AS_STRING 00441 DBUS_STRUCT_END_CHAR_AS_STRING; 00442 _dbus_assert (dbus_signature_validate (sig, NULL)); 00443 dbus_signature_iter_init (&iter, sig); 00444 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16); 00445 boolres = dbus_signature_iter_next (&iter); 00446 _dbus_assert (boolres); 00447 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT); 00448 dbus_signature_iter_recurse (&iter, &subiter); 00449 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32); 00450 boolres = dbus_signature_iter_next (&subiter); 00451 _dbus_assert (boolres); 00452 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE); 00453 boolres = dbus_signature_iter_next (&subiter); 00454 _dbus_assert (boolres); 00455 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY); 00456 _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY); 00457 00458 dbus_signature_iter_recurse (&subiter, &subsubiter); 00459 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY); 00460 _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE); 00461 00462 dbus_signature_iter_recurse (&subsubiter, &subsubsubiter); 00463 _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE); 00464 boolres = dbus_signature_iter_next (&subiter); 00465 _dbus_assert (boolres); 00466 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT); 00467 dbus_signature_iter_recurse (&subiter, &subsubiter); 00468 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE); 00469 00470 sig = DBUS_TYPE_ARRAY_AS_STRING 00471 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 00472 DBUS_TYPE_INT16_AS_STRING 00473 DBUS_TYPE_STRING_AS_STRING 00474 DBUS_DICT_ENTRY_END_CHAR_AS_STRING 00475 DBUS_TYPE_VARIANT_AS_STRING; 00476 _dbus_assert (dbus_signature_validate (sig, NULL)); 00477 _dbus_assert (!dbus_signature_validate_single (sig, NULL)); 00478 dbus_signature_iter_init (&iter, sig); 00479 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY); 00480 _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY); 00481 00482 dbus_signature_iter_recurse (&iter, &subiter); 00483 dbus_signature_iter_recurse (&subiter, &subsubiter); 00484 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16); 00485 boolres = dbus_signature_iter_next (&subsubiter); 00486 _dbus_assert (boolres); 00487 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING); 00488 boolres = dbus_signature_iter_next (&subsubiter); 00489 _dbus_assert (!boolres); 00490 00491 boolres = dbus_signature_iter_next (&iter); 00492 _dbus_assert (boolres); 00493 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT); 00494 boolres = dbus_signature_iter_next (&iter); 00495 _dbus_assert (!boolres); 00496 00497 sig = DBUS_TYPE_DICT_ENTRY_AS_STRING; 00498 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00499 00500 sig = DBUS_TYPE_ARRAY_AS_STRING; 00501 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00502 00503 sig = DBUS_TYPE_UINT32_AS_STRING 00504 DBUS_TYPE_ARRAY_AS_STRING; 00505 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00506 00507 sig = DBUS_TYPE_ARRAY_AS_STRING 00508 DBUS_TYPE_DICT_ENTRY_AS_STRING; 00509 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00510 00511 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING; 00512 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00513 00514 sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING; 00515 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00516 00517 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 00518 DBUS_TYPE_INT32_AS_STRING; 00519 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00520 00521 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 00522 DBUS_TYPE_INT32_AS_STRING 00523 DBUS_TYPE_STRING_AS_STRING; 00524 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00525 00526 sig = DBUS_STRUCT_END_CHAR_AS_STRING 00527 DBUS_STRUCT_BEGIN_CHAR_AS_STRING; 00528 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00529 00530 sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING 00531 DBUS_TYPE_BOOLEAN_AS_STRING; 00532 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00533 return TRUE; 00534 #if 0 00535 oom: 00536 _dbus_assert_not_reached ("out of memory"); 00537 return FALSE; 00538 #endif 00539 } 00540 00541 #endif 00542