• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List

dbus-signature.c

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 

Generated on Sun Feb 20 2011 22:33:43 for D-Bus by  doxygen 1.7.1