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 
00346   _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter));
00347 
00348   sig = "";
00349   _dbus_assert (dbus_signature_validate (sig, NULL));
00350   _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00351   dbus_signature_iter_init (&iter, sig);
00352   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID);
00353 
00354   sig = DBUS_TYPE_STRING_AS_STRING;
00355   _dbus_assert (dbus_signature_validate (sig, NULL));
00356   _dbus_assert (dbus_signature_validate_single (sig, NULL));
00357   dbus_signature_iter_init (&iter, sig);
00358   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00359 
00360   sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
00361   _dbus_assert (dbus_signature_validate (sig, NULL));
00362   dbus_signature_iter_init (&iter, sig);
00363   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00364   _dbus_assert (dbus_signature_iter_next (&iter));
00365   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE);
00366 
00367   sig = DBUS_TYPE_UINT16_AS_STRING
00368     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00369     DBUS_TYPE_STRING_AS_STRING
00370     DBUS_TYPE_UINT32_AS_STRING
00371     DBUS_TYPE_VARIANT_AS_STRING
00372     DBUS_TYPE_DOUBLE_AS_STRING
00373     DBUS_STRUCT_END_CHAR_AS_STRING;
00374   _dbus_assert (dbus_signature_validate (sig, NULL));
00375   dbus_signature_iter_init (&iter, sig);
00376   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00377   _dbus_assert (dbus_signature_iter_next (&iter));
00378   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00379   dbus_signature_iter_recurse (&iter, &subiter);
00380   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING);
00381   _dbus_assert (dbus_signature_iter_next (&subiter));
00382   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00383   _dbus_assert (dbus_signature_iter_next (&subiter));
00384   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT);
00385   _dbus_assert (dbus_signature_iter_next (&subiter));
00386   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE);
00387 
00388   sig = DBUS_TYPE_UINT16_AS_STRING
00389     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00390     DBUS_TYPE_UINT32_AS_STRING
00391     DBUS_TYPE_BYTE_AS_STRING
00392     DBUS_TYPE_ARRAY_AS_STRING
00393     DBUS_TYPE_ARRAY_AS_STRING
00394     DBUS_TYPE_DOUBLE_AS_STRING
00395     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00396     DBUS_TYPE_BYTE_AS_STRING
00397     DBUS_STRUCT_END_CHAR_AS_STRING
00398     DBUS_STRUCT_END_CHAR_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_UINT16);
00402   _dbus_assert (dbus_signature_iter_next (&iter));
00403   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00404   dbus_signature_iter_recurse (&iter, &subiter);
00405   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00406   _dbus_assert (dbus_signature_iter_next (&subiter));
00407   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE);
00408   _dbus_assert (dbus_signature_iter_next (&subiter));
00409   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY);
00410   _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY);
00411 
00412   dbus_signature_iter_recurse (&subiter, &subsubiter);
00413   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY);
00414   _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE);
00415 
00416   dbus_signature_iter_recurse (&subsubiter, &subsubsubiter);
00417   _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE);
00418   _dbus_assert (dbus_signature_iter_next (&subiter));
00419   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT);
00420   dbus_signature_iter_recurse (&subiter, &subsubiter);
00421   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE);
00422 
00423   sig = DBUS_TYPE_ARRAY_AS_STRING
00424     DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00425     DBUS_TYPE_INT16_AS_STRING
00426     DBUS_TYPE_STRING_AS_STRING
00427     DBUS_DICT_ENTRY_END_CHAR_AS_STRING
00428     DBUS_TYPE_VARIANT_AS_STRING;
00429   _dbus_assert (dbus_signature_validate (sig, NULL));
00430   _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00431   dbus_signature_iter_init (&iter, sig);
00432   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY);
00433   _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY);
00434 
00435   dbus_signature_iter_recurse (&iter, &subiter);
00436   dbus_signature_iter_recurse (&subiter, &subsubiter);
00437   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16);
00438   _dbus_assert (dbus_signature_iter_next (&subsubiter));
00439   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING);
00440   _dbus_assert (!dbus_signature_iter_next (&subsubiter));
00441 
00442   _dbus_assert (dbus_signature_iter_next (&iter));
00443   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT);
00444   _dbus_assert (!dbus_signature_iter_next (&iter));
00445 
00446   sig = DBUS_TYPE_DICT_ENTRY_AS_STRING;
00447   _dbus_assert (!dbus_signature_validate (sig, NULL));
00448 
00449   sig = DBUS_TYPE_ARRAY_AS_STRING;
00450   _dbus_assert (!dbus_signature_validate (sig, NULL));
00451 
00452   sig = DBUS_TYPE_UINT32_AS_STRING
00453     DBUS_TYPE_ARRAY_AS_STRING;
00454   _dbus_assert (!dbus_signature_validate (sig, NULL));
00455 
00456   sig = DBUS_TYPE_ARRAY_AS_STRING
00457     DBUS_TYPE_DICT_ENTRY_AS_STRING;
00458   _dbus_assert (!dbus_signature_validate (sig, NULL));
00459 
00460   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING;
00461   _dbus_assert (!dbus_signature_validate (sig, NULL));
00462 
00463   sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
00464   _dbus_assert (!dbus_signature_validate (sig, NULL));
00465 
00466   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00467     DBUS_TYPE_INT32_AS_STRING;
00468   _dbus_assert (!dbus_signature_validate (sig, NULL));
00469 
00470   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00471     DBUS_TYPE_INT32_AS_STRING
00472     DBUS_TYPE_STRING_AS_STRING;
00473   _dbus_assert (!dbus_signature_validate (sig, NULL));
00474 
00475   sig = DBUS_STRUCT_END_CHAR_AS_STRING
00476     DBUS_STRUCT_BEGIN_CHAR_AS_STRING;
00477   _dbus_assert (!dbus_signature_validate (sig, NULL));
00478 
00479   sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00480     DBUS_TYPE_BOOLEAN_AS_STRING;
00481   _dbus_assert (!dbus_signature_validate (sig, NULL));
00482   return TRUE;
00483 #if 0
00484  oom:
00485   _dbus_assert_not_reached ("out of memory");
00486   return FALSE;
00487 #endif
00488 }
00489 
00490 #endif
00491  /* end of DBusSignature group */
00493 

Generated on Wed Feb 27 10:13:37 2008 for D-BUS by  doxygen 1.4.6