D-Bus 1.4.20
|
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 <config.h> 00025 00026 #include "dbus-signature.h" 00027 #include "dbus-marshal-recursive.h" 00028 #include "dbus-marshal-basic.h" 00029 #include "dbus-internals.h" 00030 #include "dbus-test.h" 00031 00035 typedef struct 00036 { 00037 const char *pos; 00038 unsigned int finished : 1; 00039 unsigned int in_array : 1; 00040 } DBusSignatureRealIter; 00041 00043 #define TYPE_IS_CONTAINER(typecode) \ 00044 ((typecode) == DBUS_TYPE_STRUCT || \ 00045 (typecode) == DBUS_TYPE_DICT_ENTRY || \ 00046 (typecode) == DBUS_TYPE_VARIANT || \ 00047 (typecode) == DBUS_TYPE_ARRAY) 00048 00049 00066 void 00067 dbus_signature_iter_init (DBusSignatureIter *iter, 00068 const char *signature) 00069 { 00070 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00071 00072 real_iter->pos = signature; 00073 real_iter->finished = FALSE; 00074 real_iter->in_array = FALSE; 00075 } 00076 00091 int 00092 dbus_signature_iter_get_current_type (const DBusSignatureIter *iter) 00093 { 00094 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00095 00096 return _dbus_first_type_in_signature_c_str (real_iter->pos, 0); 00097 } 00098 00111 char * 00112 dbus_signature_iter_get_signature (const DBusSignatureIter *iter) 00113 { 00114 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00115 DBusString str; 00116 char *ret; 00117 int pos; 00118 00119 if (!_dbus_string_init (&str)) 00120 return NULL; 00121 00122 pos = 0; 00123 _dbus_type_signature_next (real_iter->pos, &pos); 00124 00125 if (!_dbus_string_append_len (&str, real_iter->pos, pos)) 00126 return NULL; 00127 if (!_dbus_string_steal_data (&str, &ret)) 00128 ret = NULL; 00129 _dbus_string_free (&str); 00130 00131 return ret; 00132 } 00133 00145 int 00146 dbus_signature_iter_get_element_type (const DBusSignatureIter *iter) 00147 { 00148 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00149 00150 _dbus_return_val_if_fail (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID); 00151 00152 return _dbus_first_type_in_signature_c_str (real_iter->pos, 1); 00153 } 00154 00163 dbus_bool_t 00164 dbus_signature_iter_next (DBusSignatureIter *iter) 00165 { 00166 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00167 00168 if (real_iter->finished) 00169 return FALSE; 00170 else 00171 { 00172 int pos; 00173 00174 if (real_iter->in_array) 00175 { 00176 real_iter->finished = TRUE; 00177 return FALSE; 00178 } 00179 00180 pos = 0; 00181 _dbus_type_signature_next (real_iter->pos, &pos); 00182 real_iter->pos += pos; 00183 00184 if (*real_iter->pos == DBUS_STRUCT_END_CHAR 00185 || *real_iter->pos == DBUS_DICT_ENTRY_END_CHAR) 00186 { 00187 real_iter->finished = TRUE; 00188 return FALSE; 00189 } 00190 00191 return *real_iter->pos != DBUS_TYPE_INVALID; 00192 } 00193 } 00194 00206 void 00207 dbus_signature_iter_recurse (const DBusSignatureIter *iter, 00208 DBusSignatureIter *subiter) 00209 { 00210 DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; 00211 DBusSignatureRealIter *real_sub_iter = (DBusSignatureRealIter *) subiter; 00212 00213 _dbus_return_if_fail (dbus_type_is_container (dbus_signature_iter_get_current_type (iter))); 00214 00215 *real_sub_iter = *real_iter; 00216 real_sub_iter->in_array = FALSE; 00217 real_sub_iter->pos++; 00218 00219 if (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY) 00220 real_sub_iter->in_array = TRUE; 00221 } 00222 00232 dbus_bool_t 00233 dbus_signature_validate (const char *signature, 00234 DBusError *error) 00235 00236 { 00237 DBusString str; 00238 DBusValidity reason; 00239 00240 _dbus_string_init_const (&str, signature); 00241 reason = _dbus_validate_signature_with_reason (&str, 0, _dbus_string_get_length (&str)); 00242 00243 if (reason == DBUS_VALID) 00244 return TRUE; 00245 else 00246 { 00247 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, _dbus_validity_to_error_message (reason)); 00248 return FALSE; 00249 } 00250 } 00251 00263 dbus_bool_t 00264 dbus_signature_validate_single (const char *signature, 00265 DBusError *error) 00266 { 00267 DBusSignatureIter iter; 00268 00269 if (!dbus_signature_validate (signature, error)) 00270 return FALSE; 00271 00272 dbus_signature_iter_init (&iter, signature); 00273 if (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID) 00274 goto lose; 00275 if (!dbus_signature_iter_next (&iter)) 00276 return TRUE; 00277 lose: 00278 dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Exactly one complete type required in signature"); 00279 return FALSE; 00280 } 00281 00292 dbus_bool_t 00293 dbus_type_is_container (int typecode) 00294 { 00295 /* only reasonable (non-line-noise) typecodes are allowed */ 00296 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, 00297 FALSE); 00298 return TYPE_IS_CONTAINER (typecode); 00299 } 00300 00315 dbus_bool_t 00316 dbus_type_is_basic (int typecode) 00317 { 00318 /* only reasonable (non-line-noise) typecodes are allowed */ 00319 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, 00320 FALSE); 00321 00322 /* everything that isn't invalid or a container */ 00323 return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode)); 00324 } 00325 00345 dbus_bool_t 00346 dbus_type_is_fixed (int typecode) 00347 { 00348 /* only reasonable (non-line-noise) typecodes are allowed */ 00349 _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, 00350 FALSE); 00351 00352 switch (typecode) 00353 { 00354 case DBUS_TYPE_BYTE: 00355 case DBUS_TYPE_BOOLEAN: 00356 case DBUS_TYPE_INT16: 00357 case DBUS_TYPE_UINT16: 00358 case DBUS_TYPE_INT32: 00359 case DBUS_TYPE_UINT32: 00360 case DBUS_TYPE_INT64: 00361 case DBUS_TYPE_UINT64: 00362 case DBUS_TYPE_DOUBLE: 00363 case DBUS_TYPE_UNIX_FD: 00364 return TRUE; 00365 default: 00366 return FALSE; 00367 } 00368 } 00369 /* end of DBusSignature group */ 00371 00372 #ifdef DBUS_BUILD_TESTS 00373 00380 dbus_bool_t 00381 _dbus_signature_test (void) 00382 { 00383 DBusSignatureIter iter; 00384 DBusSignatureIter subiter; 00385 DBusSignatureIter subsubiter; 00386 DBusSignatureIter subsubsubiter; 00387 const char *sig; 00388 dbus_bool_t boolres; 00389 00390 _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter)); 00391 00392 sig = ""; 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_INVALID); 00397 00398 sig = DBUS_TYPE_STRING_AS_STRING; 00399 _dbus_assert (dbus_signature_validate (sig, NULL)); 00400 _dbus_assert (dbus_signature_validate_single (sig, NULL)); 00401 dbus_signature_iter_init (&iter, sig); 00402 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING); 00403 00404 sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_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_STRING); 00408 boolres = dbus_signature_iter_next (&iter); 00409 _dbus_assert (boolres); 00410 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE); 00411 00412 sig = DBUS_TYPE_UINT16_AS_STRING 00413 DBUS_STRUCT_BEGIN_CHAR_AS_STRING 00414 DBUS_TYPE_STRING_AS_STRING 00415 DBUS_TYPE_UINT32_AS_STRING 00416 DBUS_TYPE_VARIANT_AS_STRING 00417 DBUS_TYPE_DOUBLE_AS_STRING 00418 DBUS_STRUCT_END_CHAR_AS_STRING; 00419 _dbus_assert (dbus_signature_validate (sig, NULL)); 00420 dbus_signature_iter_init (&iter, sig); 00421 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16); 00422 boolres = dbus_signature_iter_next (&iter); 00423 _dbus_assert (boolres); 00424 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT); 00425 dbus_signature_iter_recurse (&iter, &subiter); 00426 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING); 00427 boolres = dbus_signature_iter_next (&subiter); 00428 _dbus_assert (boolres); 00429 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32); 00430 boolres = dbus_signature_iter_next (&subiter); 00431 _dbus_assert (boolres); 00432 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT); 00433 boolres = dbus_signature_iter_next (&subiter); 00434 _dbus_assert (boolres); 00435 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE); 00436 00437 sig = DBUS_TYPE_UINT16_AS_STRING 00438 DBUS_STRUCT_BEGIN_CHAR_AS_STRING 00439 DBUS_TYPE_UINT32_AS_STRING 00440 DBUS_TYPE_BYTE_AS_STRING 00441 DBUS_TYPE_ARRAY_AS_STRING 00442 DBUS_TYPE_ARRAY_AS_STRING 00443 DBUS_TYPE_DOUBLE_AS_STRING 00444 DBUS_STRUCT_BEGIN_CHAR_AS_STRING 00445 DBUS_TYPE_BYTE_AS_STRING 00446 DBUS_STRUCT_END_CHAR_AS_STRING 00447 DBUS_STRUCT_END_CHAR_AS_STRING; 00448 _dbus_assert (dbus_signature_validate (sig, NULL)); 00449 dbus_signature_iter_init (&iter, sig); 00450 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16); 00451 boolres = dbus_signature_iter_next (&iter); 00452 _dbus_assert (boolres); 00453 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT); 00454 dbus_signature_iter_recurse (&iter, &subiter); 00455 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32); 00456 boolres = dbus_signature_iter_next (&subiter); 00457 _dbus_assert (boolres); 00458 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE); 00459 boolres = dbus_signature_iter_next (&subiter); 00460 _dbus_assert (boolres); 00461 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY); 00462 _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY); 00463 00464 dbus_signature_iter_recurse (&subiter, &subsubiter); 00465 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY); 00466 _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE); 00467 00468 dbus_signature_iter_recurse (&subsubiter, &subsubsubiter); 00469 _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE); 00470 boolres = dbus_signature_iter_next (&subiter); 00471 _dbus_assert (boolres); 00472 _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT); 00473 dbus_signature_iter_recurse (&subiter, &subsubiter); 00474 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE); 00475 00476 sig = DBUS_TYPE_ARRAY_AS_STRING 00477 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 00478 DBUS_TYPE_INT16_AS_STRING 00479 DBUS_TYPE_STRING_AS_STRING 00480 DBUS_DICT_ENTRY_END_CHAR_AS_STRING 00481 DBUS_TYPE_VARIANT_AS_STRING; 00482 _dbus_assert (dbus_signature_validate (sig, NULL)); 00483 _dbus_assert (!dbus_signature_validate_single (sig, NULL)); 00484 dbus_signature_iter_init (&iter, sig); 00485 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY); 00486 _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY); 00487 00488 dbus_signature_iter_recurse (&iter, &subiter); 00489 dbus_signature_iter_recurse (&subiter, &subsubiter); 00490 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16); 00491 boolres = dbus_signature_iter_next (&subsubiter); 00492 _dbus_assert (boolres); 00493 _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING); 00494 boolres = dbus_signature_iter_next (&subsubiter); 00495 _dbus_assert (!boolres); 00496 00497 boolres = dbus_signature_iter_next (&iter); 00498 _dbus_assert (boolres); 00499 _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT); 00500 boolres = dbus_signature_iter_next (&iter); 00501 _dbus_assert (!boolres); 00502 00503 sig = DBUS_TYPE_DICT_ENTRY_AS_STRING; 00504 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00505 00506 sig = DBUS_TYPE_ARRAY_AS_STRING; 00507 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00508 00509 sig = DBUS_TYPE_UINT32_AS_STRING 00510 DBUS_TYPE_ARRAY_AS_STRING; 00511 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00512 00513 sig = DBUS_TYPE_ARRAY_AS_STRING 00514 DBUS_TYPE_DICT_ENTRY_AS_STRING; 00515 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00516 00517 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING; 00518 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00519 00520 sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING; 00521 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00522 00523 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 00524 DBUS_TYPE_INT32_AS_STRING; 00525 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00526 00527 sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 00528 DBUS_TYPE_INT32_AS_STRING 00529 DBUS_TYPE_STRING_AS_STRING; 00530 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00531 00532 sig = DBUS_STRUCT_END_CHAR_AS_STRING 00533 DBUS_STRUCT_BEGIN_CHAR_AS_STRING; 00534 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00535 00536 sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING 00537 DBUS_TYPE_BOOLEAN_AS_STRING; 00538 _dbus_assert (!dbus_signature_validate (sig, NULL)); 00539 return TRUE; 00540 #if 0 00541 oom: 00542 _dbus_assert_not_reached ("out of memory"); 00543 return FALSE; 00544 #endif 00545 } 00546 00547 #endif 00548