Main Page | Modules | Namespace List | Class Hierarchy | Data Structures | Directories | File List | Namespace Members | 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 
00051 void
00052 dbus_signature_iter_init (DBusSignatureIter *iter,
00053                           const char        *signature)
00054 {
00055   DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00056 
00057   real_iter->pos = signature;
00058   real_iter->finished = FALSE;
00059   real_iter->in_array = FALSE;
00060 }
00061 
00076 int
00077 dbus_signature_iter_get_current_type (const DBusSignatureIter *iter)
00078 {
00079   DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00080 
00081   return _dbus_first_type_in_signature_c_str (real_iter->pos, 0);
00082 }
00083 
00091 char *
00092 dbus_signature_iter_get_signature (const DBusSignatureIter *iter)
00093 {
00094   DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00095   DBusString str;
00096   char *ret;
00097   int pos;
00098   
00099   if (!_dbus_string_init (&str))
00100     return NULL;
00101 
00102   pos = 0;
00103   _dbus_type_signature_next (real_iter->pos, &pos);
00104 
00105   if (!_dbus_string_append_len (&str, real_iter->pos, pos))
00106     return NULL;
00107   if (!_dbus_string_steal_data (&str, &ret))
00108     ret = NULL;
00109   _dbus_string_free (&str);
00110 
00111   return ret; 
00112 }
00113 
00125 int
00126 dbus_signature_iter_get_element_type (const DBusSignatureIter *iter)
00127 {
00128   DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00129 
00130   _dbus_return_val_if_fail (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
00131 
00132   return _dbus_first_type_in_signature_c_str (real_iter->pos, 1);
00133 }
00134 
00143 dbus_bool_t
00144 dbus_signature_iter_next (DBusSignatureIter *iter)
00145 {
00146   DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00147 
00148   if (real_iter->finished)
00149     return FALSE;
00150   else
00151     {
00152       int pos;
00153 
00154       if (real_iter->in_array)
00155         {
00156           real_iter->finished = TRUE;
00157           return FALSE;
00158         }
00159 
00160       pos = 0;
00161       _dbus_type_signature_next (real_iter->pos, &pos);
00162       real_iter->pos += pos;
00163 
00164       if (*real_iter->pos == DBUS_STRUCT_END_CHAR
00165           || *real_iter->pos == DBUS_DICT_ENTRY_END_CHAR)
00166         {
00167           real_iter->finished = TRUE;
00168           return FALSE;
00169         }
00170 
00171       return *real_iter->pos != DBUS_TYPE_INVALID;
00172     }
00173 }
00174 
00183 void
00184 dbus_signature_iter_recurse (const DBusSignatureIter *iter,
00185                              DBusSignatureIter       *subiter)
00186 {
00187   DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00188   DBusSignatureRealIter *real_sub_iter = (DBusSignatureRealIter *) subiter;
00189 
00190   _dbus_return_if_fail (dbus_type_is_container (dbus_signature_iter_get_current_type (iter)));
00191 
00192   *real_sub_iter = *real_iter;
00193   real_sub_iter->pos++;
00194 
00195   if (dbus_signature_iter_get_current_type (subiter) == DBUS_TYPE_ARRAY)
00196     real_sub_iter->in_array = TRUE;
00197 }
00198 
00206 dbus_bool_t
00207 dbus_signature_validate (const char       *signature,
00208                          DBusError        *error)
00209                          
00210 {
00211   DBusString str;
00212 
00213   _dbus_string_init_const (&str, signature);
00214   if (_dbus_validate_signature (&str, 0, _dbus_string_get_length (&str)))
00215     return TRUE;
00216   dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Corrupt type signature");
00217   return FALSE;
00218 }
00219 
00228 dbus_bool_t
00229 dbus_signature_validate_single (const char       *signature,
00230                                 DBusError        *error)
00231 {
00232   DBusSignatureIter iter;
00233 
00234   if (!dbus_signature_validate (signature, error))
00235     return FALSE;
00236 
00237   dbus_signature_iter_init (&iter, signature);
00238   if (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID)
00239     goto lose;
00240   if (!dbus_signature_iter_next (&iter))
00241     return TRUE;
00242  lose:
00243   dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Exactly one complete type required in signature");
00244   return FALSE;
00245 }
00246 
00248 #define TYPE_IS_CONTAINER(typecode)             \
00249     ((typecode) == DBUS_TYPE_STRUCT ||          \
00250      (typecode) == DBUS_TYPE_DICT_ENTRY ||      \
00251      (typecode) == DBUS_TYPE_VARIANT ||         \
00252      (typecode) == DBUS_TYPE_ARRAY)
00253 
00262 dbus_bool_t
00263 dbus_type_is_container (int typecode)
00264 {
00265   /* only reasonable (non-line-noise) typecodes are allowed */
00266   _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00267                             FALSE);
00268   return TYPE_IS_CONTAINER (typecode);
00269 }
00270 
00284 dbus_bool_t
00285 dbus_type_is_basic (int typecode)
00286 {
00287   /* only reasonable (non-line-noise) typecodes are allowed */
00288   _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00289                             FALSE);
00290 
00291   /* everything that isn't invalid or a container */
00292   return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode));
00293 }
00294 
00306 dbus_bool_t
00307 dbus_type_is_fixed (int typecode)
00308 {
00309   switch (typecode)
00310     {
00311     case DBUS_TYPE_BYTE:
00312     case DBUS_TYPE_BOOLEAN:
00313     case DBUS_TYPE_INT16:
00314     case DBUS_TYPE_UINT16:
00315     case DBUS_TYPE_INT32:
00316     case DBUS_TYPE_UINT32:
00317     case DBUS_TYPE_INT64:
00318     case DBUS_TYPE_UINT64:
00319     case DBUS_TYPE_DOUBLE:
00320       return TRUE;
00321     default:
00322       return FALSE;
00323     }
00324 }
00325 
00326 #ifdef DBUS_BUILD_TESTS
00327 
00334 dbus_bool_t
00335 _dbus_signature_test (void)
00336 {
00337   DBusSignatureIter iter;
00338   DBusSignatureIter subiter;
00339   DBusSignatureIter subsubiter;
00340   DBusSignatureIter subsubsubiter;
00341   const char *sig;
00342 
00343   _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter));
00344 
00345   sig = "";
00346   _dbus_assert (dbus_signature_validate (sig, NULL));
00347   _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00348   dbus_signature_iter_init (&iter, sig);
00349   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID);
00350 
00351   sig = DBUS_TYPE_STRING_AS_STRING;
00352   _dbus_assert (dbus_signature_validate (sig, NULL));
00353   _dbus_assert (dbus_signature_validate_single (sig, NULL));
00354   dbus_signature_iter_init (&iter, sig);
00355   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00356 
00357   sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
00358   _dbus_assert (dbus_signature_validate (sig, NULL));
00359   dbus_signature_iter_init (&iter, sig);
00360   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00361   _dbus_assert (dbus_signature_iter_next (&iter));
00362   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE);
00363 
00364   sig = DBUS_TYPE_UINT16_AS_STRING
00365     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00366     DBUS_TYPE_STRING_AS_STRING
00367     DBUS_TYPE_UINT32_AS_STRING
00368     DBUS_TYPE_VARIANT_AS_STRING
00369     DBUS_TYPE_DOUBLE_AS_STRING
00370     DBUS_STRUCT_END_CHAR_AS_STRING;
00371   _dbus_assert (dbus_signature_validate (sig, NULL));
00372   dbus_signature_iter_init (&iter, sig);
00373   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00374   _dbus_assert (dbus_signature_iter_next (&iter));
00375   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00376   dbus_signature_iter_recurse (&iter, &subiter);
00377   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING);
00378   _dbus_assert (dbus_signature_iter_next (&subiter));
00379   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00380   _dbus_assert (dbus_signature_iter_next (&subiter));
00381   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT);
00382   _dbus_assert (dbus_signature_iter_next (&subiter));
00383   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE);
00384 
00385   sig = DBUS_TYPE_UINT16_AS_STRING
00386     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00387     DBUS_TYPE_UINT32_AS_STRING
00388     DBUS_TYPE_BYTE_AS_STRING
00389     DBUS_TYPE_ARRAY_AS_STRING
00390     DBUS_TYPE_ARRAY_AS_STRING
00391     DBUS_TYPE_DOUBLE_AS_STRING
00392     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00393     DBUS_TYPE_BYTE_AS_STRING
00394     DBUS_STRUCT_END_CHAR_AS_STRING
00395     DBUS_STRUCT_END_CHAR_AS_STRING;
00396   _dbus_assert (dbus_signature_validate (sig, NULL));
00397   dbus_signature_iter_init (&iter, sig);
00398   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00399   _dbus_assert (dbus_signature_iter_next (&iter));
00400   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00401   dbus_signature_iter_recurse (&iter, &subiter);
00402   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00403   _dbus_assert (dbus_signature_iter_next (&subiter));
00404   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE);
00405   _dbus_assert (dbus_signature_iter_next (&subiter));
00406   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY);
00407   _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY);
00408 
00409   dbus_signature_iter_recurse (&subiter, &subsubiter);
00410   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY);
00411   _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE);
00412 
00413   dbus_signature_iter_recurse (&subsubiter, &subsubsubiter);
00414   _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE);
00415   _dbus_assert (dbus_signature_iter_next (&subiter));
00416   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT);
00417   dbus_signature_iter_recurse (&subiter, &subsubiter);
00418   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE);
00419 
00420   sig = DBUS_TYPE_ARRAY_AS_STRING
00421     DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00422     DBUS_TYPE_INT16_AS_STRING
00423     DBUS_TYPE_STRING_AS_STRING
00424     DBUS_DICT_ENTRY_END_CHAR_AS_STRING
00425     DBUS_TYPE_VARIANT_AS_STRING;
00426   _dbus_assert (dbus_signature_validate (sig, NULL));
00427   _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00428   dbus_signature_iter_init (&iter, sig);
00429   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY);
00430   _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY);
00431 
00432   dbus_signature_iter_recurse (&iter, &subiter);
00433   dbus_signature_iter_recurse (&subiter, &subsubiter);
00434   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16);
00435   _dbus_assert (dbus_signature_iter_next (&subsubiter));
00436   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING);
00437   _dbus_assert (!dbus_signature_iter_next (&subsubiter));
00438 
00439   _dbus_assert (dbus_signature_iter_next (&iter));
00440   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT);
00441   _dbus_assert (!dbus_signature_iter_next (&iter));
00442 
00443   sig = DBUS_TYPE_DICT_ENTRY_AS_STRING;
00444   _dbus_assert (!dbus_signature_validate (sig, NULL));
00445 
00446   sig = DBUS_TYPE_ARRAY_AS_STRING;
00447   _dbus_assert (!dbus_signature_validate (sig, NULL));
00448 
00449   sig = DBUS_TYPE_UINT32_AS_STRING
00450     DBUS_TYPE_ARRAY_AS_STRING;
00451   _dbus_assert (!dbus_signature_validate (sig, NULL));
00452 
00453   sig = DBUS_TYPE_ARRAY_AS_STRING
00454     DBUS_TYPE_DICT_ENTRY_AS_STRING;
00455   _dbus_assert (!dbus_signature_validate (sig, NULL));
00456 
00457   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING;
00458   _dbus_assert (!dbus_signature_validate (sig, NULL));
00459 
00460   sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
00461   _dbus_assert (!dbus_signature_validate (sig, NULL));
00462 
00463   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00464     DBUS_TYPE_INT32_AS_STRING;
00465   _dbus_assert (!dbus_signature_validate (sig, NULL));
00466 
00467   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00468     DBUS_TYPE_INT32_AS_STRING
00469     DBUS_TYPE_STRING_AS_STRING;
00470   _dbus_assert (!dbus_signature_validate (sig, NULL));
00471 
00472   sig = DBUS_STRUCT_END_CHAR_AS_STRING
00473     DBUS_STRUCT_BEGIN_CHAR_AS_STRING;
00474   _dbus_assert (!dbus_signature_validate (sig, NULL));
00475 
00476   sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00477     DBUS_TYPE_BOOLEAN_AS_STRING;
00478   _dbus_assert (!dbus_signature_validate (sig, NULL));
00479   return TRUE;
00480 #if 0
00481  oom:
00482   _dbus_assert_not_reached ("out of memory");
00483   return FALSE;
00484 #endif
00485 }
00486 
00487 #endif
00488  /* end of DBusSignature group */
00490 

Generated on Tue Sep 13 01:28:07 2005 for D-BUS by  doxygen 1.4.4