os/ossrv/ofdbus/dbus-glib/dbus/dbus-gsignature.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /* -*- mode: C; c-file-style: "gnu" -*- */
     2 /* dbus-gsignature.c Mapping from dbus type signatures to GType
     3  *
     4  * Copyright (C) 2005 Red Hat, Inc.
     5  *
     6  * Licensed under the Academic Free License version 2.1
     7  * 
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  * 
    18  * You should have received a copy of the GNU General Public License
    19  * along with this program; if not, write to the Free Software
    20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    21  *
    22  */
    23 
    24 #include "config.h"
    25 #include "dbus-gtest.h"
    26 #include "dbus-gsignature.h"
    27 #include "dbus-gvalue-utils.h"
    28 #include <string.h>
    29 #include <glib.h>
    30 
    31 #define MAP_BASIC(d_t, g_t)                     \
    32     case DBUS_TYPE_##d_t:                       \
    33       return G_TYPE_##g_t;
    34 static GType
    35 typecode_to_gtype (int type)
    36 {
    37   switch (type)
    38     {
    39       MAP_BASIC (BOOLEAN, BOOLEAN);
    40       MAP_BASIC (BYTE,    UCHAR);
    41       MAP_BASIC (INT16,   INT);
    42       MAP_BASIC (INT32,   INT);
    43       MAP_BASIC (UINT16,  UINT);
    44       MAP_BASIC (UINT32,  UINT);
    45       MAP_BASIC (INT64,   INT64);
    46       MAP_BASIC (UINT64,  UINT64);
    47       MAP_BASIC (DOUBLE,  DOUBLE);
    48       MAP_BASIC (STRING,  STRING);
    49     default:
    50       return G_TYPE_INVALID;
    51     }
    52 }
    53 #undef MAP_BASIC
    54 
    55 static gboolean
    56 dbus_typecode_maps_to_basic (int typecode)
    57 {
    58   return typecode_to_gtype (typecode) != G_TYPE_INVALID;
    59 }
    60 
    61 GType
    62 _dbus_gtype_from_basic_typecode (int typecode)
    63 {
    64   g_assert (dbus_type_is_basic (typecode));
    65   g_assert (dbus_typecode_maps_to_basic (typecode));
    66   return typecode_to_gtype (typecode);
    67 }
    68 
    69 static GType
    70 signature_iter_to_g_type_dict (const DBusSignatureIter *subiter, gboolean is_client)
    71 {
    72   DBusSignatureIter iter;
    73   GType key_gtype;
    74   GType value_gtype;
    75 
    76   g_assert (dbus_signature_iter_get_current_type (subiter) == DBUS_TYPE_DICT_ENTRY);
    77 
    78   dbus_signature_iter_recurse (subiter, &iter);
    79 
    80   key_gtype = _dbus_gtype_from_signature_iter (&iter, is_client); 
    81   if (key_gtype == G_TYPE_INVALID)
    82     return G_TYPE_INVALID;
    83 
    84   dbus_signature_iter_next (&iter);
    85   value_gtype = _dbus_gtype_from_signature_iter (&iter, is_client);
    86   if (value_gtype == G_TYPE_INVALID)
    87     return G_TYPE_INVALID;
    88 
    89   if (!_dbus_gtype_is_valid_hash_key (key_gtype)
    90       || !_dbus_gtype_is_valid_hash_value (value_gtype))
    91     /* Later we need to return DBUS_TYPE_G_VALUE */
    92     return G_TYPE_INVALID; 
    93 
    94   return dbus_g_type_get_map ("GHashTable", key_gtype, value_gtype);
    95 }
    96 
    97 static GType
    98 signature_iter_to_g_type_array (DBusSignatureIter *iter, gboolean is_client)
    99 {
   100   GType elt_gtype;
   101 
   102   elt_gtype = _dbus_gtype_from_signature_iter (iter, is_client);
   103   if (elt_gtype == G_TYPE_INVALID)
   104     return G_TYPE_INVALID;
   105 
   106   if (elt_gtype == G_TYPE_OBJECT)
   107     return DBUS_TYPE_G_OBJECT_ARRAY;
   108   if (elt_gtype == G_TYPE_STRING)
   109     return G_TYPE_STRV;
   110   if (_dbus_g_type_is_fixed (elt_gtype))
   111     return dbus_g_type_get_collection ("GArray", elt_gtype);
   112   else if (g_type_is_a (elt_gtype, G_TYPE_OBJECT)
   113 	   || g_type_is_a (elt_gtype, G_TYPE_BOXED))
   114     return dbus_g_type_get_collection ("GPtrArray", elt_gtype);
   115 
   116   /* Later we need to return DBUS_TYPE_G_VALUE */
   117   return G_TYPE_INVALID; 
   118 }
   119 
   120 static GType
   121 signature_iter_to_g_type_struct (DBusSignatureIter *iter, gboolean is_client)
   122 {
   123   GArray *types;
   124   GType ret;
   125   types = g_array_new (FALSE, FALSE, sizeof (GType));
   126   do
   127     {
   128       GType curtype;
   129       curtype = _dbus_gtype_from_signature_iter (iter, is_client);
   130       g_array_append_val (types, curtype);
   131     }
   132   while (dbus_signature_iter_next (iter));
   133 
   134   ret = dbus_g_type_get_structv ("GValueArray", types->len, (GType*) types->data);
   135   g_array_free (types, TRUE);
   136   return ret;
   137 }
   138 
   139 GType
   140 _dbus_gtype_from_signature_iter (DBusSignatureIter *iter, gboolean is_client)
   141 {
   142   int current_type;
   143 
   144   current_type = dbus_signature_iter_get_current_type (iter);
   145   /* TODO: handle type 0? */
   146   if (dbus_typecode_maps_to_basic (current_type))
   147     return _dbus_gtype_from_basic_typecode (current_type);
   148   else if (current_type == DBUS_TYPE_OBJECT_PATH)
   149     return DBUS_TYPE_G_OBJECT_PATH;
   150   else
   151     {
   152       DBusSignatureIter subiter;
   153 
   154       g_assert (dbus_type_is_container (current_type));
   155 
   156       if (current_type == DBUS_TYPE_VARIANT)
   157 	return G_TYPE_VALUE;
   158       
   159       dbus_signature_iter_recurse (iter, &subiter);
   160 
   161       if (current_type == DBUS_TYPE_ARRAY)
   162 	{
   163 	  int elt_type = dbus_signature_iter_get_current_type (&subiter);
   164 	  if (elt_type == DBUS_TYPE_DICT_ENTRY)
   165 	    return signature_iter_to_g_type_dict (&subiter, is_client);
   166 	  else 
   167 	    return signature_iter_to_g_type_array (&subiter, is_client);
   168 	}
   169       else if (current_type == DBUS_TYPE_STRUCT)
   170         {
   171           return signature_iter_to_g_type_struct (&subiter, is_client);
   172         }
   173       else
   174 	{
   175 	  g_assert_not_reached ();
   176 	  return G_TYPE_INVALID;
   177 	}
   178     }
   179 }
   180 
   181 GType
   182 _dbus_gtype_from_signature (const char *signature, gboolean is_client)
   183 {
   184   DBusSignatureIter iter;
   185 
   186   dbus_signature_iter_init (&iter, signature);
   187 
   188   return _dbus_gtype_from_signature_iter (&iter, is_client);
   189 }
   190 
   191 GArray *
   192 _dbus_gtypes_from_arg_signature (const char *argsig, gboolean is_client)
   193 {
   194   GArray *ret;
   195   int current_type;
   196   DBusSignatureIter sigiter;
   197 
   198   ret = g_array_new (FALSE, FALSE, sizeof (GType));
   199 
   200   dbus_signature_iter_init (&sigiter, argsig);
   201   while ((current_type = dbus_signature_iter_get_current_type (&sigiter)) != DBUS_TYPE_INVALID)
   202     {
   203       GType curtype;
   204 
   205       curtype = _dbus_gtype_from_signature_iter (&sigiter, is_client);
   206       g_array_append_val (ret, curtype);
   207       dbus_signature_iter_next (&sigiter);
   208     }
   209   return ret;
   210 }