dbus-signature.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 
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   /* only reasonable (non-line-noise) typecodes are allowed */
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   /* only reasonable (non-line-noise) typecodes are allowed */
00291   _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00292                             FALSE);
00293 
00294   /* everything that isn't invalid or a container */
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   dbus_bool_t boolres;
00346 
00347   _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter));
00348 
00349   sig = "";
00350   _dbus_assert (dbus_signature_validate (sig, NULL));
00351   _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00352   dbus_signature_iter_init (&iter, sig);
00353   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID);
00354 
00355   sig = DBUS_TYPE_STRING_AS_STRING;
00356   _dbus_assert (dbus_signature_validate (sig, NULL));
00357   _dbus_assert (dbus_signature_validate_single (sig, NULL));
00358   dbus_signature_iter_init (&iter, sig);
00359   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00360 
00361   sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
00362   _dbus_assert (dbus_signature_validate (sig, NULL));
00363   dbus_signature_iter_init (&iter, sig);
00364   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00365   boolres = dbus_signature_iter_next (&iter);
00366   _dbus_assert (boolres);
00367   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE);
00368 
00369   sig = DBUS_TYPE_UINT16_AS_STRING
00370     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00371     DBUS_TYPE_STRING_AS_STRING
00372     DBUS_TYPE_UINT32_AS_STRING
00373     DBUS_TYPE_VARIANT_AS_STRING
00374     DBUS_TYPE_DOUBLE_AS_STRING
00375     DBUS_STRUCT_END_CHAR_AS_STRING;
00376   _dbus_assert (dbus_signature_validate (sig, NULL));
00377   dbus_signature_iter_init (&iter, sig);
00378   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00379   boolres = dbus_signature_iter_next (&iter);
00380   _dbus_assert (boolres);
00381   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00382   dbus_signature_iter_recurse (&iter, &subiter);
00383   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING);
00384   boolres = dbus_signature_iter_next (&subiter);
00385   _dbus_assert (boolres);
00386   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00387   boolres = dbus_signature_iter_next (&subiter);
00388   _dbus_assert (boolres);
00389   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT);
00390   boolres = dbus_signature_iter_next (&subiter);
00391   _dbus_assert (boolres);
00392   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE);
00393 
00394   sig = DBUS_TYPE_UINT16_AS_STRING
00395     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00396     DBUS_TYPE_UINT32_AS_STRING
00397     DBUS_TYPE_BYTE_AS_STRING
00398     DBUS_TYPE_ARRAY_AS_STRING
00399     DBUS_TYPE_ARRAY_AS_STRING
00400     DBUS_TYPE_DOUBLE_AS_STRING
00401     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00402     DBUS_TYPE_BYTE_AS_STRING
00403     DBUS_STRUCT_END_CHAR_AS_STRING
00404     DBUS_STRUCT_END_CHAR_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_UINT16);
00408   boolres = dbus_signature_iter_next (&iter);
00409   _dbus_assert (boolres);
00410   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00411   dbus_signature_iter_recurse (&iter, &subiter);
00412   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00413   boolres = dbus_signature_iter_next (&subiter);
00414   _dbus_assert (boolres);
00415   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE);
00416   boolres = dbus_signature_iter_next (&subiter);
00417   _dbus_assert (boolres);
00418   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY);
00419   _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY);
00420 
00421   dbus_signature_iter_recurse (&subiter, &subsubiter);
00422   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY);
00423   _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE);
00424 
00425   dbus_signature_iter_recurse (&subsubiter, &subsubsubiter);
00426   _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE);
00427   boolres = dbus_signature_iter_next (&subiter);
00428   _dbus_assert (boolres);
00429   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT);
00430   dbus_signature_iter_recurse (&subiter, &subsubiter);
00431   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE);
00432 
00433   sig = DBUS_TYPE_ARRAY_AS_STRING
00434     DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00435     DBUS_TYPE_INT16_AS_STRING
00436     DBUS_TYPE_STRING_AS_STRING
00437     DBUS_DICT_ENTRY_END_CHAR_AS_STRING
00438     DBUS_TYPE_VARIANT_AS_STRING;
00439   _dbus_assert (dbus_signature_validate (sig, NULL));
00440   _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00441   dbus_signature_iter_init (&iter, sig);
00442   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY);
00443   _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY);
00444 
00445   dbus_signature_iter_recurse (&iter, &subiter);
00446   dbus_signature_iter_recurse (&subiter, &subsubiter);
00447   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16);
00448   boolres = dbus_signature_iter_next (&subsubiter);
00449   _dbus_assert (boolres);
00450   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING);
00451   boolres = dbus_signature_iter_next (&subsubiter);
00452   _dbus_assert (!boolres);
00453 
00454   boolres = dbus_signature_iter_next (&iter);
00455   _dbus_assert (boolres);
00456   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT);
00457   boolres = dbus_signature_iter_next (&iter);
00458   _dbus_assert (!boolres);
00459 
00460   sig = DBUS_TYPE_DICT_ENTRY_AS_STRING;
00461   _dbus_assert (!dbus_signature_validate (sig, NULL));
00462 
00463   sig = DBUS_TYPE_ARRAY_AS_STRING;
00464   _dbus_assert (!dbus_signature_validate (sig, NULL));
00465 
00466   sig = DBUS_TYPE_UINT32_AS_STRING
00467     DBUS_TYPE_ARRAY_AS_STRING;
00468   _dbus_assert (!dbus_signature_validate (sig, NULL));
00469 
00470   sig = DBUS_TYPE_ARRAY_AS_STRING
00471     DBUS_TYPE_DICT_ENTRY_AS_STRING;
00472   _dbus_assert (!dbus_signature_validate (sig, NULL));
00473 
00474   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING;
00475   _dbus_assert (!dbus_signature_validate (sig, NULL));
00476 
00477   sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
00478   _dbus_assert (!dbus_signature_validate (sig, NULL));
00479 
00480   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00481     DBUS_TYPE_INT32_AS_STRING;
00482   _dbus_assert (!dbus_signature_validate (sig, NULL));
00483 
00484   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00485     DBUS_TYPE_INT32_AS_STRING
00486     DBUS_TYPE_STRING_AS_STRING;
00487   _dbus_assert (!dbus_signature_validate (sig, NULL));
00488 
00489   sig = DBUS_STRUCT_END_CHAR_AS_STRING
00490     DBUS_STRUCT_BEGIN_CHAR_AS_STRING;
00491   _dbus_assert (!dbus_signature_validate (sig, NULL));
00492 
00493   sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00494     DBUS_TYPE_BOOLEAN_AS_STRING;
00495   _dbus_assert (!dbus_signature_validate (sig, NULL));
00496   return TRUE;
00497 #if 0
00498  oom:
00499   _dbus_assert_not_reached ("out of memory");
00500   return FALSE;
00501 #endif
00502 }
00503 
00504 #endif
00505  /* end of DBusSignature group */
00507 

Generated on Wed Jan 3 04:58:29 2007 for D-Bus by  doxygen 1.4.7