D-Bus  1.4.18
dbus-signature.c
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00021  *
00022  */
00023 
00024 #include <config.h>
00025 
00026 #include "dbus-signature.h"
00027 #include "dbus-marshal-recursive.h"
00028 #include "dbus-marshal-basic.h"
00029 #include "dbus-internals.h"
00030 #include "dbus-test.h"
00031 
00035 typedef struct
00036 { 
00037   const char *pos;           
00038   unsigned int finished : 1; 
00039   unsigned int in_array : 1; 
00040 } DBusSignatureRealIter;
00041 
00043 #define TYPE_IS_CONTAINER(typecode)             \
00044     ((typecode) == DBUS_TYPE_STRUCT ||          \
00045      (typecode) == DBUS_TYPE_DICT_ENTRY ||      \
00046      (typecode) == DBUS_TYPE_VARIANT ||         \
00047      (typecode) == DBUS_TYPE_ARRAY)
00048 
00049 
00066 void
00067 dbus_signature_iter_init (DBusSignatureIter *iter,
00068                           const char        *signature)
00069 {
00070   DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00071 
00072   real_iter->pos = signature;
00073   real_iter->finished = FALSE;
00074   real_iter->in_array = FALSE;
00075 }
00076 
00091 int
00092 dbus_signature_iter_get_current_type (const DBusSignatureIter *iter)
00093 {
00094   DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00095 
00096   return _dbus_first_type_in_signature_c_str (real_iter->pos, 0);
00097 }
00098 
00111 char *
00112 dbus_signature_iter_get_signature (const DBusSignatureIter *iter)
00113 {
00114   DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00115   DBusString str;
00116   char *ret;
00117   int pos;
00118   
00119   if (!_dbus_string_init (&str))
00120     return NULL;
00121 
00122   pos = 0;
00123   _dbus_type_signature_next (real_iter->pos, &pos);
00124 
00125   if (!_dbus_string_append_len (&str, real_iter->pos, pos))
00126     return NULL;
00127   if (!_dbus_string_steal_data (&str, &ret))
00128     ret = NULL;
00129   _dbus_string_free (&str);
00130 
00131   return ret; 
00132 }
00133 
00145 int
00146 dbus_signature_iter_get_element_type (const DBusSignatureIter *iter)
00147 {
00148   DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00149 
00150   _dbus_return_val_if_fail (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
00151 
00152   return _dbus_first_type_in_signature_c_str (real_iter->pos, 1);
00153 }
00154 
00163 dbus_bool_t
00164 dbus_signature_iter_next (DBusSignatureIter *iter)
00165 {
00166   DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00167 
00168   if (real_iter->finished)
00169     return FALSE;
00170   else
00171     {
00172       int pos;
00173 
00174       if (real_iter->in_array)
00175         {
00176           real_iter->finished = TRUE;
00177           return FALSE;
00178         }
00179 
00180       pos = 0;
00181       _dbus_type_signature_next (real_iter->pos, &pos);
00182       real_iter->pos += pos;
00183 
00184       if (*real_iter->pos == DBUS_STRUCT_END_CHAR
00185           || *real_iter->pos == DBUS_DICT_ENTRY_END_CHAR)
00186         {
00187           real_iter->finished = TRUE;
00188           return FALSE;
00189         }
00190 
00191       return *real_iter->pos != DBUS_TYPE_INVALID;
00192     }
00193 }
00194 
00206 void
00207 dbus_signature_iter_recurse (const DBusSignatureIter *iter,
00208                              DBusSignatureIter       *subiter)
00209 {
00210   DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter;
00211   DBusSignatureRealIter *real_sub_iter = (DBusSignatureRealIter *) subiter;
00212 
00213   _dbus_return_if_fail (dbus_type_is_container (dbus_signature_iter_get_current_type (iter)));
00214 
00215   *real_sub_iter = *real_iter;
00216   real_sub_iter->in_array = FALSE;
00217   real_sub_iter->pos++;
00218 
00219   if (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY)
00220     real_sub_iter->in_array = TRUE;
00221 }
00222 
00232 dbus_bool_t
00233 dbus_signature_validate (const char       *signature,
00234                          DBusError        *error)
00235                          
00236 {
00237   DBusString str;
00238   DBusValidity reason;
00239 
00240   _dbus_string_init_const (&str, signature);
00241   reason = _dbus_validate_signature_with_reason (&str, 0, _dbus_string_get_length (&str));
00242 
00243   if (reason == DBUS_VALID)
00244     return TRUE;
00245   else
00246     {
00247       dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, _dbus_validity_to_error_message (reason));
00248       return FALSE;
00249     }
00250 }
00251 
00263 dbus_bool_t
00264 dbus_signature_validate_single (const char       *signature,
00265                                 DBusError        *error)
00266 {
00267   DBusSignatureIter iter;
00268 
00269   if (!dbus_signature_validate (signature, error))
00270     return FALSE;
00271 
00272   dbus_signature_iter_init (&iter, signature);
00273   if (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID)
00274     goto lose;
00275   if (!dbus_signature_iter_next (&iter))
00276     return TRUE;
00277  lose:
00278   dbus_set_error (error, DBUS_ERROR_INVALID_SIGNATURE, "Exactly one complete type required in signature");
00279   return FALSE;
00280 }
00281 
00292 dbus_bool_t
00293 dbus_type_is_container (int typecode)
00294 {
00295   /* only reasonable (non-line-noise) typecodes are allowed */
00296   _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00297                             FALSE);
00298   return TYPE_IS_CONTAINER (typecode);
00299 }
00300 
00315 dbus_bool_t
00316 dbus_type_is_basic (int typecode)
00317 {
00318   /* only reasonable (non-line-noise) typecodes are allowed */
00319   _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00320                             FALSE);
00321 
00322   /* everything that isn't invalid or a container */
00323   return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode));
00324 }
00325 
00345 dbus_bool_t
00346 dbus_type_is_fixed (int typecode)
00347 {
00348   /* only reasonable (non-line-noise) typecodes are allowed */
00349   _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID,
00350                             FALSE);
00351   
00352   switch (typecode)
00353     {
00354     case DBUS_TYPE_BYTE:
00355     case DBUS_TYPE_BOOLEAN:
00356     case DBUS_TYPE_INT16:
00357     case DBUS_TYPE_UINT16:
00358     case DBUS_TYPE_INT32:
00359     case DBUS_TYPE_UINT32:
00360     case DBUS_TYPE_INT64:
00361     case DBUS_TYPE_UINT64:
00362     case DBUS_TYPE_DOUBLE:
00363     case DBUS_TYPE_UNIX_FD:
00364       return TRUE;
00365     default:
00366       return FALSE;
00367     }
00368 }
00369  /* end of DBusSignature group */
00371 
00372 #ifdef DBUS_BUILD_TESTS
00373 
00380 dbus_bool_t
00381 _dbus_signature_test (void)
00382 {
00383   DBusSignatureIter iter;
00384   DBusSignatureIter subiter;
00385   DBusSignatureIter subsubiter;
00386   DBusSignatureIter subsubsubiter;
00387   const char *sig;
00388   dbus_bool_t boolres;
00389 
00390   _dbus_assert (sizeof (DBusSignatureIter) >= sizeof (DBusSignatureRealIter));
00391 
00392   sig = "";
00393   _dbus_assert (dbus_signature_validate (sig, NULL));
00394   _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00395   dbus_signature_iter_init (&iter, sig);
00396   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_INVALID);
00397 
00398   sig = DBUS_TYPE_STRING_AS_STRING;
00399   _dbus_assert (dbus_signature_validate (sig, NULL));
00400   _dbus_assert (dbus_signature_validate_single (sig, NULL));
00401   dbus_signature_iter_init (&iter, sig);
00402   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRING);
00403 
00404   sig = DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_BYTE_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_STRING);
00408   boolres = dbus_signature_iter_next (&iter);
00409   _dbus_assert (boolres);
00410   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_BYTE);
00411 
00412   sig = DBUS_TYPE_UINT16_AS_STRING
00413     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00414     DBUS_TYPE_STRING_AS_STRING
00415     DBUS_TYPE_UINT32_AS_STRING
00416     DBUS_TYPE_VARIANT_AS_STRING
00417     DBUS_TYPE_DOUBLE_AS_STRING
00418     DBUS_STRUCT_END_CHAR_AS_STRING;
00419   _dbus_assert (dbus_signature_validate (sig, NULL));
00420   dbus_signature_iter_init (&iter, sig);
00421   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00422   boolres = dbus_signature_iter_next (&iter);
00423   _dbus_assert (boolres);
00424   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00425   dbus_signature_iter_recurse (&iter, &subiter);
00426   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRING);
00427   boolres = dbus_signature_iter_next (&subiter);
00428   _dbus_assert (boolres);
00429   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00430   boolres = dbus_signature_iter_next (&subiter);
00431   _dbus_assert (boolres);
00432   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_VARIANT);
00433   boolres = dbus_signature_iter_next (&subiter);
00434   _dbus_assert (boolres);
00435   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_DOUBLE);
00436 
00437   sig = DBUS_TYPE_UINT16_AS_STRING
00438     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00439     DBUS_TYPE_UINT32_AS_STRING
00440     DBUS_TYPE_BYTE_AS_STRING
00441     DBUS_TYPE_ARRAY_AS_STRING
00442     DBUS_TYPE_ARRAY_AS_STRING
00443     DBUS_TYPE_DOUBLE_AS_STRING
00444     DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00445     DBUS_TYPE_BYTE_AS_STRING
00446     DBUS_STRUCT_END_CHAR_AS_STRING
00447     DBUS_STRUCT_END_CHAR_AS_STRING;
00448   _dbus_assert (dbus_signature_validate (sig, NULL));
00449   dbus_signature_iter_init (&iter, sig);
00450   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_UINT16);
00451   boolres = dbus_signature_iter_next (&iter);
00452   _dbus_assert (boolres);
00453   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_STRUCT);
00454   dbus_signature_iter_recurse (&iter, &subiter);
00455   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_UINT32);
00456   boolres = dbus_signature_iter_next (&subiter);
00457   _dbus_assert (boolres);
00458   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_BYTE);
00459   boolres = dbus_signature_iter_next (&subiter);
00460   _dbus_assert (boolres);
00461   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_ARRAY);
00462   _dbus_assert (dbus_signature_iter_get_element_type (&subiter) == DBUS_TYPE_ARRAY);
00463 
00464   dbus_signature_iter_recurse (&subiter, &subsubiter);
00465   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_ARRAY);
00466   _dbus_assert (dbus_signature_iter_get_element_type (&subsubiter) == DBUS_TYPE_DOUBLE);
00467 
00468   dbus_signature_iter_recurse (&subsubiter, &subsubsubiter);
00469   _dbus_assert (dbus_signature_iter_get_current_type (&subsubsubiter) == DBUS_TYPE_DOUBLE);
00470   boolres = dbus_signature_iter_next (&subiter);
00471   _dbus_assert (boolres);
00472   _dbus_assert (dbus_signature_iter_get_current_type (&subiter) == DBUS_TYPE_STRUCT);
00473   dbus_signature_iter_recurse (&subiter, &subsubiter);
00474   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_BYTE);
00475 
00476   sig = DBUS_TYPE_ARRAY_AS_STRING
00477     DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00478     DBUS_TYPE_INT16_AS_STRING
00479     DBUS_TYPE_STRING_AS_STRING
00480     DBUS_DICT_ENTRY_END_CHAR_AS_STRING
00481     DBUS_TYPE_VARIANT_AS_STRING;
00482   _dbus_assert (dbus_signature_validate (sig, NULL));
00483   _dbus_assert (!dbus_signature_validate_single (sig, NULL));
00484   dbus_signature_iter_init (&iter, sig);
00485   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_ARRAY);
00486   _dbus_assert (dbus_signature_iter_get_element_type (&iter) == DBUS_TYPE_DICT_ENTRY);
00487 
00488   dbus_signature_iter_recurse (&iter, &subiter);
00489   dbus_signature_iter_recurse (&subiter, &subsubiter);
00490   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_INT16);
00491   boolres = dbus_signature_iter_next (&subsubiter);
00492   _dbus_assert (boolres);
00493   _dbus_assert (dbus_signature_iter_get_current_type (&subsubiter) == DBUS_TYPE_STRING);
00494   boolres = dbus_signature_iter_next (&subsubiter);
00495   _dbus_assert (!boolres);
00496 
00497   boolres = dbus_signature_iter_next (&iter);
00498   _dbus_assert (boolres);
00499   _dbus_assert (dbus_signature_iter_get_current_type (&iter) == DBUS_TYPE_VARIANT);
00500   boolres = dbus_signature_iter_next (&iter);
00501   _dbus_assert (!boolres);
00502 
00503   sig = DBUS_TYPE_DICT_ENTRY_AS_STRING;
00504   _dbus_assert (!dbus_signature_validate (sig, NULL));
00505 
00506   sig = DBUS_TYPE_ARRAY_AS_STRING;
00507   _dbus_assert (!dbus_signature_validate (sig, NULL));
00508 
00509   sig = DBUS_TYPE_UINT32_AS_STRING
00510     DBUS_TYPE_ARRAY_AS_STRING;
00511   _dbus_assert (!dbus_signature_validate (sig, NULL));
00512 
00513   sig = DBUS_TYPE_ARRAY_AS_STRING
00514     DBUS_TYPE_DICT_ENTRY_AS_STRING;
00515   _dbus_assert (!dbus_signature_validate (sig, NULL));
00516 
00517   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING;
00518   _dbus_assert (!dbus_signature_validate (sig, NULL));
00519 
00520   sig = DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
00521   _dbus_assert (!dbus_signature_validate (sig, NULL));
00522 
00523   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00524     DBUS_TYPE_INT32_AS_STRING;
00525   _dbus_assert (!dbus_signature_validate (sig, NULL));
00526 
00527   sig = DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00528     DBUS_TYPE_INT32_AS_STRING
00529     DBUS_TYPE_STRING_AS_STRING;
00530   _dbus_assert (!dbus_signature_validate (sig, NULL));
00531 
00532   sig = DBUS_STRUCT_END_CHAR_AS_STRING
00533     DBUS_STRUCT_BEGIN_CHAR_AS_STRING;
00534   _dbus_assert (!dbus_signature_validate (sig, NULL));
00535 
00536   sig = DBUS_STRUCT_BEGIN_CHAR_AS_STRING
00537     DBUS_TYPE_BOOLEAN_AS_STRING;
00538   _dbus_assert (!dbus_signature_validate (sig, NULL));
00539   return TRUE;
00540 #if 0
00541  oom:
00542   _dbus_assert_not_reached ("out of memory");
00543   return FALSE;
00544 #endif
00545 }
00546 
00547 #endif
00548