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 
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 
00237   _dbus_string_init_const (&str, signature);
00238   if (_dbus_validate_signature (&str, 0, _dbus_string_get_length (&str)))
00239     return TRUE;
00240   dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Corrupt type signature");
00241   return FALSE;
00242 }
00243 
00255 dbus_bool_t
00256 dbus_signature_validate_single (const char       *signature,
00257                                 DBusError        *error)
00258 {
00259   DBusSignatureIter iter;
00260 
00261   if (!dbus_signature_validate (signature, error))
00262     return FALSE;
00263 
00264   dbus_signature_iter_init (&iter, signature);
00265   if (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID)
00266     goto lose;
00267   if (!dbus_signature_iter_next (&iter))
00268     return TRUE;
00269  lose:
00270   dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Exactly one complete type required in signature");
00271   return FALSE;
00272 }
00273 
00283 dbus_bool_t
00284 dbus_type_is_container (int typecode)
00285 {
00286   /* only reasonable (non-line-noise) typecodes are allowed */
00287   _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00288                             FALSE);
00289   return TYPE_IS_CONTAINER (typecode);
00290 }
00291 
00305 dbus_bool_t
00306 dbus_type_is_basic (int typecode)
00307 {
00308   /* only reasonable (non-line-noise) typecodes are allowed */
00309   _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00310                             FALSE);
00311 
00312   /* everything that isn't invalid or a container */
00313   return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode));
00314 }
00315 
00334 dbus_bool_t
00335 dbus_type_is_fixed (int typecode)
00336 {
00337   /* only reasonable (non-line-noise) typecodes are allowed */
00338   _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00339                             FALSE);
00340   
00341   switch (typecode)
00342     {
00343     case DBUS_TYPE_BYTE:
00344     case DBUS_TYPE_BOOLEAN:
00345     case DBUS_TYPE_INT16:
00346     case DBUS_TYPE_UINT16:
00347     case DBUS_TYPE_INT32:
00348     case DBUS_TYPE_UINT32:
00349     case DBUS_TYPE_INT64:
00350     case DBUS_TYPE_UINT64:
00351     case DBUS_TYPE_DOUBLE:
00352       return TRUE;
00353     default:
00354       return FALSE;
00355     }
00356 }
00357  /* end of DBusSignature group */
00359 
00360 #ifdef DBUS_BUILD_TESTS
00361 
00368 dbus_bool_t
00369 _dbus_signature_test (void)
00370 {
00371   DBusSignatureIter iter;
00372   DBusSignatureIter subiter;
00373   DBusSignatureIter subsubiter;
00374   DBusSignatureIter subsubsubiter;
00375   const char *sig;
00376   dbus_bool_t boolres;
00377 
00378   _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter));
00379 
00380   sig = "";
00381   _dbus_assert (dbus_signature_validate (sig, NULL));
00382   _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00383   dbus_signature_iter_init (&iter, sig);
00384   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID);
00385 
00386   sig = DBUS_TYPE_STRING_AS_STRING;
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_STRING);
00391 
00392   sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
00393   _dbus_assert (dbus_signature_validate (sig, NULL));
00394   dbus_signature_iter_init (&iter, sig);
00395   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00396   boolres = dbus_signature_iter_next (&iter);
00397   _dbus_assert (boolres);
00398   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE);
00399 
00400   sig = DBUS_TYPE_UINT16_AS_STRING
00401     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00402     DBUS_TYPE_STRING_AS_STRING
00403     DBUS_TYPE_UINT32_AS_STRING
00404     DBUS_TYPE_VARIANT_AS_STRING
00405     DBUS_TYPE_DOUBLE_AS_STRING
00406     DBUS_STRUCT_END_CHAR_AS_STRING;
00407   _dbus_assert (dbus_signature_validate (sig, NULL));
00408   dbus_signature_iter_init (&iter, sig);
00409   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00410   boolres = dbus_signature_iter_next (&iter);
00411   _dbus_assert (boolres);
00412   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00413   dbus_signature_iter_recurse (&iter, &subiter);
00414   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING);
00415   boolres = dbus_signature_iter_next (&subiter);
00416   _dbus_assert (boolres);
00417   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00418   boolres = dbus_signature_iter_next (&subiter);
00419   _dbus_assert (boolres);
00420   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT);
00421   boolres = dbus_signature_iter_next (&subiter);
00422   _dbus_assert (boolres);
00423   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE);
00424 
00425   sig = DBUS_TYPE_UINT16_AS_STRING
00426     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00427     DBUS_TYPE_UINT32_AS_STRING
00428     DBUS_TYPE_BYTE_AS_STRING
00429     DBUS_TYPE_ARRAY_AS_STRING
00430     DBUS_TYPE_ARRAY_AS_STRING
00431     DBUS_TYPE_DOUBLE_AS_STRING
00432     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00433     DBUS_TYPE_BYTE_AS_STRING
00434     DBUS_STRUCT_END_CHAR_AS_STRING
00435     DBUS_STRUCT_END_CHAR_AS_STRING;
00436   _dbus_assert (dbus_signature_validate (sig, NULL));
00437   dbus_signature_iter_init (&iter, sig);
00438   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00439   boolres = dbus_signature_iter_next (&iter);
00440   _dbus_assert (boolres);
00441   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00442   dbus_signature_iter_recurse (&iter, &subiter);
00443   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00444   boolres = dbus_signature_iter_next (&subiter);
00445   _dbus_assert (boolres);
00446   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE);
00447   boolres = dbus_signature_iter_next (&subiter);
00448   _dbus_assert (boolres);
00449   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY);
00450   _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY);
00451 
00452   dbus_signature_iter_recurse (&subiter, &subsubiter);
00453   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY);
00454   _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE);
00455 
00456   dbus_signature_iter_recurse (&subsubiter, &subsubsubiter);
00457   _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE);
00458   boolres = dbus_signature_iter_next (&subiter);
00459   _dbus_assert (boolres);
00460   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT);
00461   dbus_signature_iter_recurse (&subiter, &subsubiter);
00462   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE);
00463 
00464   sig = DBUS_TYPE_ARRAY_AS_STRING
00465     DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00466     DBUS_TYPE_INT16_AS_STRING
00467     DBUS_TYPE_STRING_AS_STRING
00468     DBUS_DICT_ENTRY_END_CHAR_AS_STRING
00469     DBUS_TYPE_VARIANT_AS_STRING;
00470   _dbus_assert (dbus_signature_validate (sig, NULL));
00471   _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00472   dbus_signature_iter_init (&iter, sig);
00473   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY);
00474   _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY);
00475 
00476   dbus_signature_iter_recurse (&iter, &subiter);
00477   dbus_signature_iter_recurse (&subiter, &subsubiter);
00478   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16);
00479   boolres = dbus_signature_iter_next (&subsubiter);
00480   _dbus_assert (boolres);
00481   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING);
00482   boolres = dbus_signature_iter_next (&subsubiter);
00483   _dbus_assert (!boolres);
00484 
00485   boolres = dbus_signature_iter_next (&iter);
00486   _dbus_assert (boolres);
00487   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT);
00488   boolres = dbus_signature_iter_next (&iter);
00489   _dbus_assert (!boolres);
00490 
00491   sig = DBUS_TYPE_DICT_ENTRY_AS_STRING;
00492   _dbus_assert (!dbus_signature_validate (sig, NULL));
00493 
00494   sig = DBUS_TYPE_ARRAY_AS_STRING;
00495   _dbus_assert (!dbus_signature_validate (sig, NULL));
00496 
00497   sig = DBUS_TYPE_UINT32_AS_STRING
00498     DBUS_TYPE_ARRAY_AS_STRING;
00499   _dbus_assert (!dbus_signature_validate (sig, NULL));
00500 
00501   sig = DBUS_TYPE_ARRAY_AS_STRING
00502     DBUS_TYPE_DICT_ENTRY_AS_STRING;
00503   _dbus_assert (!dbus_signature_validate (sig, NULL));
00504 
00505   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING;
00506   _dbus_assert (!dbus_signature_validate (sig, NULL));
00507 
00508   sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
00509   _dbus_assert (!dbus_signature_validate (sig, NULL));
00510 
00511   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00512     DBUS_TYPE_INT32_AS_STRING;
00513   _dbus_assert (!dbus_signature_validate (sig, NULL));
00514 
00515   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00516     DBUS_TYPE_INT32_AS_STRING
00517     DBUS_TYPE_STRING_AS_STRING;
00518   _dbus_assert (!dbus_signature_validate (sig, NULL));
00519 
00520   sig = DBUS_STRUCT_END_CHAR_AS_STRING
00521     DBUS_STRUCT_BEGIN_CHAR_AS_STRING;
00522   _dbus_assert (!dbus_signature_validate (sig, NULL));
00523 
00524   sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00525     DBUS_TYPE_BOOLEAN_AS_STRING;
00526   _dbus_assert (!dbus_signature_validate (sig, NULL));
00527   return TRUE;
00528 #if 0
00529  oom:
00530   _dbus_assert_not_reached ("out of memory");
00531   return FALSE;
00532 #endif
00533 }
00534 
00535 #endif
00536 

Generated on Fri Sep 21 18:12:13 2007 for D-Bus by  doxygen 1.5.1