Exemple #1
0
static GVariant *
gconf_settings_backend_simple_gconf_value_type_to_gvariant (GConfValue         *gconf_value,
                                                            const GVariantType *expected_type)
{
  /* Note: it's guaranteed that the types are compatible */
  GVariant *variant = NULL;

  if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BOOLEAN))
    variant = g_variant_new_boolean (gconf_value_get_bool (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTE))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < 0 || value > 255)
        return NULL;
      variant = g_variant_new_byte (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < G_MINSHORT || value > G_MAXSHORT)
        return NULL;
      variant = g_variant_new_int16 (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < 0 || value > G_MAXUSHORT)
        return NULL;
      variant = g_variant_new_uint16 (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
    variant = g_variant_new_int32 (gconf_value_get_int (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < 0)
        return NULL;
      variant = g_variant_new_uint32 (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
    variant = g_variant_new_int64 ((gint64) gconf_value_get_int (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < 0)
        return NULL;
      variant = g_variant_new_uint64 (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
    {
      int value = gconf_value_get_int (gconf_value);
      if (value < 0)
        return NULL;
      variant = g_variant_new_handle (value);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
    variant = g_variant_new_double (gconf_value_get_float (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_STRING))
    variant = g_variant_new_string (gconf_value_get_string (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_OBJECT_PATH))
    variant = g_variant_new_object_path (gconf_value_get_string (gconf_value));
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_SIGNATURE))
    variant = g_variant_new_signature (gconf_value_get_string (gconf_value));

  return variant;
}
Exemple #2
0
GVariant *
g_settings_set_mapping (const GValue       *value,
                        const GVariantType *expected_type,
                        gpointer            user_data)
{
  gchar *type_string;

  if (G_VALUE_HOLDS_BOOLEAN (value))
    {
      if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BOOLEAN))
        return g_variant_new_boolean (g_value_get_boolean (value));
    }

  else if (G_VALUE_HOLDS_CHAR (value)  ||
           G_VALUE_HOLDS_UCHAR (value))
    {
      if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTE))
        {
          if (G_VALUE_HOLDS_CHAR (value))
            return g_variant_new_byte (g_value_get_char (value));
          else
            return g_variant_new_byte (g_value_get_uchar (value));
        }
    }

  else if (G_VALUE_HOLDS_INT (value)   ||
           G_VALUE_HOLDS_INT64 (value))
    return g_settings_set_mapping_int (value, expected_type);

  else if (G_VALUE_HOLDS_DOUBLE (value))
    return g_settings_set_mapping_float (value, expected_type);

  else if (G_VALUE_HOLDS_UINT (value)  ||
           G_VALUE_HOLDS_UINT64 (value))
    return g_settings_set_mapping_unsigned_int (value, expected_type);

  else if (G_VALUE_HOLDS_STRING (value))
    {
      if (g_value_get_string (value) == NULL)
        return NULL;
      else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_STRING))
        return g_variant_new_string (g_value_get_string (value));
      else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTESTRING))
        return g_variant_new_bytestring (g_value_get_string (value));
      else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_OBJECT_PATH))
        return g_variant_new_object_path (g_value_get_string (value));
      else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_SIGNATURE))
        return g_variant_new_signature (g_value_get_string (value));
    }

  else if (G_VALUE_HOLDS (value, G_TYPE_STRV))
    {
      if (g_value_get_boxed (value) == NULL)
        return NULL;
      return g_variant_new_strv ((const gchar **) g_value_get_boxed (value),
                                 -1);
    }

  else if (G_VALUE_HOLDS_ENUM (value))
    {
      GEnumValue *enumval;
      GEnumClass *eclass;

      /* GParamSpecEnum holds a ref on the class so we just peek... */
      eclass = g_type_class_peek (G_VALUE_TYPE (value));
      enumval = g_enum_get_value (eclass, g_value_get_enum (value));

      if (enumval)
        return g_variant_new_string (enumval->value_nick);
      else
        return NULL;
    }

  else if (G_VALUE_HOLDS_FLAGS (value))
    {
      GVariantBuilder builder;
      GFlagsValue *flagsval;
      GFlagsClass *fclass;
      guint flags;

      fclass = g_type_class_peek (G_VALUE_TYPE (value));
      flags = g_value_get_flags (value);

      g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
      while (flags)
        {
          flagsval = g_flags_get_first_value (fclass, flags);

          if (flagsval == NULL)
            {
              g_variant_builder_clear (&builder);
              return NULL;
            }

          g_variant_builder_add (&builder, "s", flagsval->value_nick);
          flags &= ~flagsval->value;
        }

      return g_variant_builder_end (&builder);
    }

  type_string = g_variant_type_dup_string (expected_type);
  g_critical ("No GSettings bind handler for type \"%s\".", type_string);
  g_free (type_string);

  return NULL;
}
Exemple #3
0
/**
 * g_dbus_gvalue_to_gvariant:
 * @gvalue: A #GValue to convert to a #GVariant
 * @type: A #GVariantType
 *
 * Converts a #GValue to a #GVariant of the type indicated by the @type
 * parameter.
 *
 * The conversion is using the following rules:
 *
 * - #G_TYPE_STRING: 's', 'o', 'g' or 'ay'
 * - #G_TYPE_STRV: 'as', 'ao' or 'aay'
 * - #G_TYPE_BOOLEAN: 'b'
 * - #G_TYPE_UCHAR: 'y'
 * - #G_TYPE_INT: 'i', 'n'
 * - #G_TYPE_UINT: 'u', 'q'
 * - #G_TYPE_INT64 'x'
 * - #G_TYPE_UINT64: 't'
 * - #G_TYPE_DOUBLE: 'd'
 * - #G_TYPE_VARIANT: Any #GVariantType
 *
 * This can fail if e.g. @gvalue is of type #G_TYPE_STRING and @type
 * is ['i'][G-VARIANT-TYPE-INT32:CAPS]. It will also fail for any #GType
 * (including e.g. #G_TYPE_OBJECT and #G_TYPE_BOXED derived-types) not
 * in the table above.
 *
 * Note that if @gvalue is of type #G_TYPE_VARIANT and its value is
 * %NULL, the empty #GVariant instance (never %NULL) for @type is
 * returned (e.g. 0 for scalar types, the empty string for string types,
 * '/' for object path types, the empty array for any array type and so on).
 *
 * See the g_dbus_gvariant_to_gvalue() function for how to convert a
 * #GVariant to a #GValue.
 *
 * Returns: A #GVariant (never floating) of #GVariantType @type holding
 *     the data from @gvalue or %NULL in case of failure. Free with
 *     g_variant_unref().
 *
 * Since: 2.30
 */
GVariant *
g_dbus_gvalue_to_gvariant (const GValue       *gvalue,
                           const GVariantType *type)
{
  GVariant *ret;
  const gchar *s;
  const gchar * const *as;
  const gchar *empty_strv[1] = {NULL};

  g_return_val_if_fail (gvalue != NULL, NULL);
  g_return_val_if_fail (type != NULL, NULL);

  ret = NULL;

  /* @type can easily be e.g. "s" with the GValue holding a GVariant - for example this
   * can happen when using the org.gtk.GDBus.C.ForceGVariant annotation with the
   * gdbus-codegen(1) tool.
   */
  if (G_VALUE_TYPE (gvalue) == G_TYPE_VARIANT)
    {
      ret = g_value_dup_variant (gvalue);
    }
  else
    {
      switch (g_variant_type_peek_string (type)[0])
        {
        case G_VARIANT_CLASS_BOOLEAN:
          ret = g_variant_ref_sink (g_variant_new_boolean (g_value_get_boolean (gvalue)));
          break;

        case G_VARIANT_CLASS_BYTE:
          ret = g_variant_ref_sink (g_variant_new_byte (g_value_get_uchar (gvalue)));
          break;

        case G_VARIANT_CLASS_INT16:
          ret = g_variant_ref_sink (g_variant_new_int16 (g_value_get_int (gvalue)));
          break;

        case G_VARIANT_CLASS_UINT16:
          ret = g_variant_ref_sink (g_variant_new_uint16 (g_value_get_uint (gvalue)));
          break;

        case G_VARIANT_CLASS_INT32:
          ret = g_variant_ref_sink (g_variant_new_int32 (g_value_get_int (gvalue)));
          break;

        case G_VARIANT_CLASS_UINT32:
          ret = g_variant_ref_sink (g_variant_new_uint32 (g_value_get_uint (gvalue)));
          break;

        case G_VARIANT_CLASS_INT64:
          ret = g_variant_ref_sink (g_variant_new_int64 (g_value_get_int64 (gvalue)));
          break;

        case G_VARIANT_CLASS_UINT64:
          ret = g_variant_ref_sink (g_variant_new_uint64 (g_value_get_uint64 (gvalue)));
          break;

        case G_VARIANT_CLASS_DOUBLE:
          ret = g_variant_ref_sink (g_variant_new_double (g_value_get_double (gvalue)));
          break;

        case G_VARIANT_CLASS_STRING:
          s = g_value_get_string (gvalue);
          if (s == NULL)
            s = "";
          ret = g_variant_ref_sink (g_variant_new_string (s));
          break;

        case G_VARIANT_CLASS_OBJECT_PATH:
          s = g_value_get_string (gvalue);
          if (s == NULL)
            s = "/";
          ret = g_variant_ref_sink (g_variant_new_object_path (s));
          break;

        case G_VARIANT_CLASS_SIGNATURE:
          s = g_value_get_string (gvalue);
          if (s == NULL)
            s = "";
          ret = g_variant_ref_sink (g_variant_new_signature (s));
          break;

        case G_VARIANT_CLASS_ARRAY:
          switch (g_variant_type_peek_string (type)[1])
            {
            case G_VARIANT_CLASS_BYTE:
              s = g_value_get_string (gvalue);
              if (s == NULL)
                s = "";
              ret = g_variant_ref_sink (g_variant_new_bytestring (s));
              break;

            case G_VARIANT_CLASS_STRING:
              as = g_value_get_boxed (gvalue);
              if (as == NULL)
                as = empty_strv;
              ret = g_variant_ref_sink (g_variant_new_strv (as, -1));
              break;

            case G_VARIANT_CLASS_OBJECT_PATH:
              as = g_value_get_boxed (gvalue);
              if (as == NULL)
                as = empty_strv;
              ret = g_variant_ref_sink (g_variant_new_objv (as, -1));
              break;

            case G_VARIANT_CLASS_ARRAY:
              switch (g_variant_type_peek_string (type)[2])
                {
                case G_VARIANT_CLASS_BYTE:
                  as = g_value_get_boxed (gvalue);
                  if (as == NULL)
                    as = empty_strv;
                  ret = g_variant_ref_sink (g_variant_new_bytestring_array (as, -1));
                  break;

                default:
                  ret = g_value_dup_variant (gvalue);
                  break;
                }
              break;

            default:
              ret = g_value_dup_variant (gvalue);
              break;
            }
          break;

        case G_VARIANT_CLASS_HANDLE:
        case G_VARIANT_CLASS_VARIANT:
        case G_VARIANT_CLASS_MAYBE:
        case G_VARIANT_CLASS_TUPLE:
        case G_VARIANT_CLASS_DICT_ENTRY:
          ret = g_value_dup_variant (gvalue);
          break;
        }
    }

  /* Could be that the GValue is holding a NULL GVariant - in that case,
   * we return an "empty" GVariant instead of a NULL GVariant
   */
  if (ret == NULL)
    {
      GVariant *untrusted_empty;
      untrusted_empty = g_variant_new_from_data (type, NULL, 0, FALSE, NULL, NULL);
      ret = g_variant_ref_sink (g_variant_get_normal_form (untrusted_empty));
      g_variant_unref (untrusted_empty);
    }

  g_assert (!g_variant_is_floating (ret));

  return ret;
}
static GVariant *
dconf_dbus_to_gv (DBusMessageIter  *iter,
                  GError          **error)
{
  gint arg_type;

  arg_type = dbus_message_iter_get_arg_type (iter);

  switch (dbus_message_iter_get_arg_type (iter))
    {
     case DBUS_TYPE_BOOLEAN:
      {
        dbus_bool_t value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_boolean (value);
      }

     case DBUS_TYPE_BYTE:
      {
        guchar value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_byte (value);
      }

     case DBUS_TYPE_INT16:
      {
        gint16 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_int16 (value);
      }

     case DBUS_TYPE_UINT16:
      {
        guint16 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_uint16 (value);
      }

     case DBUS_TYPE_INT32:
      {
        gint32 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_int32 (value);
      }

     case DBUS_TYPE_UINT32:
      {
        guint32 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_uint32 (value);
      }

     case DBUS_TYPE_INT64:
      {
        gint64 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_int64 (value);
      }

     case DBUS_TYPE_UINT64:
      {
        guint64 value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_uint64 (value);
      }

     case DBUS_TYPE_DOUBLE:
      {
        gdouble value;
        dbus_message_iter_get_basic (iter, &value);
        return g_variant_new_double (value);
      }

     case DBUS_TYPE_STRING:
      {
       const gchar *value;
       dbus_message_iter_get_basic (iter, &value);
       return g_variant_new_string (value);
      }

     case DBUS_TYPE_OBJECT_PATH:
      {
       const gchar *value;
       dbus_message_iter_get_basic (iter, &value);
       return g_variant_new_object_path (value);
      }

     case DBUS_TYPE_SIGNATURE:
      {
       const gchar *value;
       dbus_message_iter_get_basic (iter, &value);
       return g_variant_new_signature (value);
      }

     case DBUS_TYPE_VARIANT:
       {
        GVariantBuilder *builder;
        GVariantClass class;
        DBusMessageIter sub;
        char *type;
        GVariant *val;

        dbus_message_iter_recurse (iter, &sub);
        class = dbus_message_iter_get_arg_type (iter);
        type = dbus_message_iter_get_signature (&sub);
        builder = g_variant_builder_new (G_VARIANT_TYPE_VARIANT);
        dbus_free (type);

        while (dbus_message_iter_get_arg_type (&sub))
          {
            val = dconf_dbus_to_gv (&sub, error);
            if (val == NULL)
              {
                g_variant_builder_cancel (builder);
                goto fail;
              }
            g_variant_builder_add_value (builder, val);
            dbus_message_iter_next (&sub);
          }

        return g_variant_builder_end (builder);
       }

     case DBUS_TYPE_ARRAY:
     case DBUS_TYPE_STRUCT:
     case DBUS_TYPE_DICT_ENTRY:
      {
        GVariantBuilder *builder;
        GVariantClass class;
        DBusMessageIter sub;
        char *type;
        GVariant *val;

        dbus_message_iter_recurse (iter, &sub);
        class = dbus_message_iter_get_arg_type (iter);
        type = dbus_message_iter_get_signature (iter);
        builder = g_variant_builder_new (G_VARIANT_TYPE (type));
        dbus_free (type);

        while (dbus_message_iter_get_arg_type (&sub))
          {
            val = dconf_dbus_to_gv (&sub, error);
            if (val == NULL)
              {
                g_variant_builder_cancel (builder);
                goto fail;
              }
            g_variant_builder_add_value (builder, val);
            dbus_message_iter_next (&sub);
          }

        return g_variant_builder_end (builder);
      }

     default:
       g_set_error (error,
                    G_DBUS_ERROR,
                    G_DBUS_ERROR_CONVERSION_FAILED,
                    _("Error serializing D-Bus message to GVariant. Unsupported arg type `%c' (%d)"),
                    arg_type,
                    arg_type);
      goto fail;
    }

  g_assert_not_reached ();

 fail:
  return NULL;
}
Exemple #5
0
static GVariant *
parse_json (JsonNode *node,
            const GVariantType *type,
            GError **error)
{
  const GVariantType *element_type;
  const gchar *str;

  if (!g_variant_type_is_definite (type))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                   "Indefinite type '%.*s' is not supported",
                   (int)g_variant_type_get_string_length (type),
                   g_variant_type_peek_string (type));
      return NULL;
    }

  if (g_variant_type_is_basic (type))
    {
      if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_BOOLEAN, error))
            return g_variant_new_boolean (json_node_get_boolean (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_byte (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_int16 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_uint16 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_int32 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_uint32 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_int64 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_uint64 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, NULL))
            return g_variant_new_double (json_node_get_int (node));
          else if (check_type (node, JSON_NODE_VALUE, G_TYPE_DOUBLE, error))
            return g_variant_new_double (json_node_get_double (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_STRING, error))
            return g_variant_new_string (json_node_get_string (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_STRING, error))
            {
              str = json_node_get_string (node);
              if (g_variant_is_object_path (str))
                return g_variant_new_object_path (str);
              else
                {
                  g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                               "Invalid object path '%s'", str);
                  return NULL;
                }
            }
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_STRING, error))
            {
              str = json_node_get_string (node);
              if (g_variant_is_signature (str))
                return g_variant_new_signature (str);
              else
                {
                  g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                               "Invalid signature '%s'", str);
                  return NULL;
                }
            }
        }
      else
        {
          parse_not_supported (type, error);
        }
    }
  else if (g_variant_type_is_variant (type))
    {
      return parse_json_variant (node, error);
    }
  else if (g_variant_type_is_array (type))
    {
      element_type = g_variant_type_element (type);
      if (g_variant_type_is_dict_entry (element_type))
        return parse_json_dictionary (node, element_type, error);
      else
        return parse_json_array (node, element_type, error);
    }
  else if (g_variant_type_is_tuple (type))
    {
      return parse_json_tuple (node, g_variant_type_first (type), error);
    }
  else
    {
      parse_not_supported (type, error);
    }

  return NULL;
}