Main Page | Modules | Data Structures | Directories | File List | Data Fields | Related Pages

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->pos++;
00196 
00197   if (dbus_signature_iter_get_current_type (subiter) == DBUS_TYPE_ARRAY)
00198     real_sub_iter->in_array = TRUE;
00199 }
00200 
00208 dbus_bool_t
00209 dbus_signature_validate (const char       *signature,
00210                          DBusError        *error)
00211                          
00212 {
00213   DBusString str;
00214 
00215   _dbus_string_init_const (&str, signature);
00216   if (_dbus_validate_signature (&str, 0, _dbus_string_get_length (&str)))
00217     return TRUE;
00218   dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Corrupt type signature");
00219   return FALSE;
00220 }
00221 
00230 dbus_bool_t
00231 dbus_signature_validate_single (const char       *signature,
00232                                 DBusError        *error)
00233 {
00234   DBusSignatureIter iter;
00235 
00236   if (!dbus_signature_validate (signature, error))
00237     return FALSE;
00238 
00239   dbus_signature_iter_init (&iter, signature);
00240   if (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID)
00241     goto lose;
00242   if (!dbus_signature_iter_next (&iter))
00243     return TRUE;
00244  lose:
00245   dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Exactly one complete type required in signature");
00246   return FALSE;
00247 }
00248 
00250 #define TYPE_IS_CONTAINER(typecode)             \
00251     ((typecode) == DBUS_TYPE_STRUCT ||          \
00252      (typecode) == DBUS_TYPE_DICT_ENTRY ||      \
00253      (typecode) == DBUS_TYPE_VARIANT ||         \
00254      (typecode) == DBUS_TYPE_ARRAY)
00255 
00264 dbus_bool_t
00265 dbus_type_is_container (int typecode)
00266 {
00267   /* only reasonable (non-line-noise) typecodes are allowed */
00268   _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00269                             FALSE);
00270   return TYPE_IS_CONTAINER (typecode);
00271 }
00272 
00286 dbus_bool_t
00287 dbus_type_is_basic (int typecode)
00288 {
00289   /* only reasonable (non-line-noise) typecodes are allowed */
00290   _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00291                             FALSE);
00292 
00293   /* everything that isn't invalid or a container */
00294   return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode));
00295 }
00296 
00308 dbus_bool_t
00309 dbus_type_is_fixed (int typecode)
00310 {
00311   switch (typecode)
00312     {
00313     case DBUS_TYPE_BYTE:
00314     case DBUS_TYPE_BOOLEAN:
00315     case DBUS_TYPE_INT16:
00316     case DBUS_TYPE_UINT16:
00317     case DBUS_TYPE_INT32:
00318     case DBUS_TYPE_UINT32:
00319     case DBUS_TYPE_INT64:
00320     case DBUS_TYPE_UINT64:
00321     case DBUS_TYPE_DOUBLE:
00322       return TRUE;
00323     default:
00324       return FALSE;
00325     }
00326 }
00327 
00328 #ifdef DBUS_BUILD_TESTS
00329 
00336 dbus_bool_t
00337 _dbus_signature_test (void)
00338 {
00339   DBusSignatureIter iter;
00340   DBusSignatureIter subiter;
00341   DBusSignatureIter subsubiter;
00342   DBusSignatureIter subsubsubiter;
00343   const char *sig;
00344 
00345   _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter));
00346 
00347   sig = "";
00348   _dbus_assert (dbus_signature_validate (sig, NULL));
00349   _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00350   dbus_signature_iter_init (&iter, sig);
00351   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID);
00352 
00353   sig = DBUS_TYPE_STRING_AS_STRING;
00354   _dbus_assert (dbus_signature_validate (sig, NULL));
00355   _dbus_assert (dbus_signature_validate_single (sig, NULL));
00356   dbus_signature_iter_init (&iter, sig);
00357   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00358 
00359   sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
00360   _dbus_assert (dbus_signature_validate (sig, NULL));
00361   dbus_signature_iter_init (&iter, sig);
00362   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00363   _dbus_assert (dbus_signature_iter_next (&iter));
00364   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE);
00365 
00366   sig = DBUS_TYPE_UINT16_AS_STRING
00367     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00368     DBUS_TYPE_STRING_AS_STRING
00369     DBUS_TYPE_UINT32_AS_STRING
00370     DBUS_TYPE_VARIANT_AS_STRING
00371     DBUS_TYPE_DOUBLE_AS_STRING
00372     DBUS_STRUCT_END_CHAR_AS_STRING;
00373   _dbus_assert (dbus_signature_validate (sig, NULL));
00374   dbus_signature_iter_init (&iter, sig);
00375   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00376   _dbus_assert (dbus_signature_iter_next (&iter));
00377   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00378   dbus_signature_iter_recurse (&iter, &subiter);
00379   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING);
00380   _dbus_assert (dbus_signature_iter_next (&subiter));
00381   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00382   _dbus_assert (dbus_signature_iter_next (&subiter));
00383   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT);
00384   _dbus_assert (dbus_signature_iter_next (&subiter));
00385   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE);
00386 
00387   sig = DBUS_TYPE_UINT16_AS_STRING
00388     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00389     DBUS_TYPE_UINT32_AS_STRING
00390     DBUS_TYPE_BYTE_AS_STRING
00391     DBUS_TYPE_ARRAY_AS_STRING
00392     DBUS_TYPE_ARRAY_AS_STRING
00393     DBUS_TYPE_DOUBLE_AS_STRING
00394     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00395     DBUS_TYPE_BYTE_AS_STRING
00396     DBUS_STRUCT_END_CHAR_AS_STRING
00397     DBUS_STRUCT_END_CHAR_AS_STRING;
00398   _dbus_assert (dbus_signature_validate (sig, NULL));
00399   dbus_signature_iter_init (&iter, sig);
00400   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00401   _dbus_assert (dbus_signature_iter_next (&iter));
00402   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00403   dbus_signature_iter_recurse (&iter, &subiter);
00404   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00405   _dbus_assert (dbus_signature_iter_next (&subiter));
00406   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE);
00407   _dbus_assert (dbus_signature_iter_next (&subiter));
00408   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY);
00409   _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY);
00410 
00411   dbus_signature_iter_recurse (&subiter, &subsubiter);
00412   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY);
00413   _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE);
00414 
00415   dbus_signature_iter_recurse (&subsubiter, &subsubsubiter);
00416   _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE);
00417   _dbus_assert (dbus_signature_iter_next (&subiter));
00418   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT);
00419   dbus_signature_iter_recurse (&subiter, &subsubiter);
00420   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE);
00421 
00422   sig = DBUS_TYPE_ARRAY_AS_STRING
00423     DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00424     DBUS_TYPE_INT16_AS_STRING
00425     DBUS_TYPE_STRING_AS_STRING
00426     DBUS_DICT_ENTRY_END_CHAR_AS_STRING
00427     DBUS_TYPE_VARIANT_AS_STRING;
00428   _dbus_assert (dbus_signature_validate (sig, NULL));
00429   _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00430   dbus_signature_iter_init (&iter, sig);
00431   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY);
00432   _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY);
00433 
00434   dbus_signature_iter_recurse (&iter, &subiter);
00435   dbus_signature_iter_recurse (&subiter, &subsubiter);
00436   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16);
00437   _dbus_assert (dbus_signature_iter_next (&subsubiter));
00438   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING);
00439   _dbus_assert (!dbus_signature_iter_next (&subsubiter));
00440 
00441   _dbus_assert (dbus_signature_iter_next (&iter));
00442   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT);
00443   _dbus_assert (!dbus_signature_iter_next (&iter));
00444 
00445   sig = DBUS_TYPE_DICT_ENTRY_AS_STRING;
00446   _dbus_assert (!dbus_signature_validate (sig, NULL));
00447 
00448   sig = DBUS_TYPE_ARRAY_AS_STRING;
00449   _dbus_assert (!dbus_signature_validate (sig, NULL));
00450 
00451   sig = DBUS_TYPE_UINT32_AS_STRING
00452     DBUS_TYPE_ARRAY_AS_STRING;
00453   _dbus_assert (!dbus_signature_validate (sig, NULL));
00454 
00455   sig = DBUS_TYPE_ARRAY_AS_STRING
00456     DBUS_TYPE_DICT_ENTRY_AS_STRING;
00457   _dbus_assert (!dbus_signature_validate (sig, NULL));
00458 
00459   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING;
00460   _dbus_assert (!dbus_signature_validate (sig, NULL));
00461 
00462   sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
00463   _dbus_assert (!dbus_signature_validate (sig, NULL));
00464 
00465   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00466     DBUS_TYPE_INT32_AS_STRING;
00467   _dbus_assert (!dbus_signature_validate (sig, NULL));
00468 
00469   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00470     DBUS_TYPE_INT32_AS_STRING
00471     DBUS_TYPE_STRING_AS_STRING;
00472   _dbus_assert (!dbus_signature_validate (sig, NULL));
00473 
00474   sig = DBUS_STRUCT_END_CHAR_AS_STRING
00475     DBUS_STRUCT_BEGIN_CHAR_AS_STRING;
00476   _dbus_assert (!dbus_signature_validate (sig, NULL));
00477 
00478   sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00479     DBUS_TYPE_BOOLEAN_AS_STRING;
00480   _dbus_assert (!dbus_signature_validate (sig, NULL));
00481   return TRUE;
00482 #if 0
00483  oom:
00484   _dbus_assert_not_reached ("out of memory");
00485   return FALSE;
00486 #endif
00487 }
00488 
00489 #endif
00490  /* end of DBusSignature group */
00492 

Generated on Wed Jan 3 04:49:05 2007 for D-BUS by  doxygen 1.4.4