Exemple #1
0
const char *
xdp_entry_get_path (XdgAppDbEntry *entry)
{
  g_autoptr(GVariant) v = xdg_app_db_entry_get_data (entry);
  g_autoptr(GVariant) c = g_variant_get_child_value (v, 0);
  return g_variant_get_bytestring (c);
}
static GVariant *
read_xattrs_cb (OstreeRepo     *repo,
                const char     *relpath,
                GFileInfo      *file_info,
                gpointer        user_data)
{
    int rootfs_fd = GPOINTER_TO_INT (user_data);
    /* Hardcoded at the moment, we're only taking file caps */
    static const char *accepted_xattrs[] = { "security.capability" };
    guint i;
    gs_unref_variant GVariant *existing_xattrs = NULL;
    gs_free_variant_iter GVariantIter *viter = NULL;
    GError *local_error = NULL;
    GError **error = &local_error;
    GVariant *key, *value;
    GVariantBuilder builder;

    if (relpath[0] == '/')
        relpath++;

    g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)"));

    if (!*relpath)
    {
        if (!gs_fd_get_all_xattrs (rootfs_fd, &existing_xattrs, NULL, error))
            goto out;
    }
    else
    {
        if (!gs_dfd_and_name_get_all_xattrs (rootfs_fd, relpath, &existing_xattrs,
                                             NULL, error))
            goto out;
    }

    viter = g_variant_iter_new (existing_xattrs);

    while (g_variant_iter_loop (viter, "(@ay@ay)", &key, &value))
    {
        for (i = 0; i < G_N_ELEMENTS (accepted_xattrs); i++)
        {
            const char *validkey = accepted_xattrs[i];
            const char *attrkey = g_variant_get_bytestring (key);
            if (g_str_equal (validkey, attrkey))
                g_variant_builder_add (&builder, "(@ay@ay)", key, value);
        }
    }

out:
    if (local_error)
    {
        g_variant_builder_clear (&builder);
        /* Unfortunately we have no way to throw from this callback */
        g_printerr ("Failed to read xattrs of '%s': %s\n",
                    relpath, local_error->message);
        exit (1);
    }
    return g_variant_ref_sink (g_variant_builder_end (&builder));
}
Exemple #3
0
static int init(struct sr_output *o, GHashTable *options)
{
	struct out_context *outc;

	outc = g_malloc0(sizeof(struct out_context));
	o->priv = outc;
    outc->filename = g_strdup(g_variant_get_bytestring(g_hash_table_lookup(options, "filename")));
	if (strlen(outc->filename) == 0)
		return SR_ERR_ARG;

	return SR_OK;
}
Exemple #4
0
static void
test_parse_bin(StateWrapper *wrapper, gconstpointer user_data)
{
    guchar buffer[] = { 0x00, 0x06, 0x00, 0x73, 0x6f, 0x6f, 0x73, 0x68, 0x69 };
    wrapper->state->buffer = g_byte_array_append(wrapper->state->buffer, buffer, sizeof(buffer));

    SooshiNode *node = g_new0(SooshiNode, 1);
    node->type = VAL_BIN;

    sooshi_node_bytes_to_value(node, wrapper->state->buffer, &node->value);

    g_assert_nonnull(node->value);
    g_assert_true(g_variant_is_of_type(node->value, G_VARIANT_TYPE_BYTESTRING));
    const gchar *mem = g_variant_get_bytestring(node->value);
    g_assert_cmpmem(mem, strlen(mem), buffer + 3, sizeof(buffer) - 3);

    g_free(node);
}
Exemple #5
0
void smartcard_cb (GObject *gobj, GAsyncResult *res, 
			gpointer userdata)
{
	DBG("smartcard callback");
	GError *error;
	GVariant *result;
	error = NULL;
	result = g_dbus_proxy_call_finish (dbProxy, res, &error);
	const gchar * smartcard_response = g_variant_get_bytestring(result);
	DBG("received response %s", smartcard_response);

	//TODO: write back to the hw_channel
	struct ofono_modem *modem = userdata;
	struct telit_data *data = ofono_modem_get_data(modem);
	gsize bytes_written;

	g_io_channel_write_chars(data->bt_io, smartcard_response,
					strlen(smartcard_response), &bytes_written, NULL);
}
static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
                      struct sr_channel *ch,
                      const struct sr_channel_group *cg)
{
	struct session_vdev *vdev;

	vdev = sdi->priv;

	switch (id) {
	case SR_CONF_SAMPLERATE:
		vdev->samplerate = g_variant_get_uint64(data);
        samplerates[0] = vdev->samplerate;
		sr_info("Setting samplerate to %" PRIu64 ".", vdev->samplerate);
		break;
    case SR_CONF_TIMEBASE:
        vdev->timebase = g_variant_get_uint64(data);
        sr_info("Setting timebase to %" PRIu64 ".", vdev->timebase);
        break;
    case SR_CONF_SESSIONFILE:
        vdev->sessionfile = g_strdup(g_variant_get_bytestring(data));
		sr_info("Setting sessionfile to '%s'.", vdev->sessionfile);
		break;
	case SR_CONF_CAPTUREFILE:
        vdev->capturefile = g_strdup(g_variant_get_bytestring(data));
		sr_info("Setting capturefile to '%s'.", vdev->capturefile);
		break;
	case SR_CONF_CAPTURE_UNITSIZE:
		vdev->unitsize = g_variant_get_uint64(data);
		break;
    case SR_CONF_LIMIT_SAMPLES:
        vdev->total_samples = g_variant_get_uint64(data);
        samplecounts[0] = vdev->total_samples;
        sr_info("Setting limit samples to %" PRIu64 ".", vdev->total_samples);
        break;
	case SR_CONF_CAPTURE_NUM_PROBES:
		vdev->num_probes = g_variant_get_uint64(data);
		break;
    case SR_CONF_EN_CH:
        ch->enabled = g_variant_get_boolean(data);
        break;
    case SR_CONF_COUPLING:
        ch->coupling = g_variant_get_byte(data);
        break;
    case SR_CONF_VDIV:
        ch->vdiv = g_variant_get_uint64(data);
        break;
    case SR_CONF_FACTOR:
        ch->vfactor = g_variant_get_uint64(data);
        break;
    case SR_CONF_VPOS:
        ch->vpos = g_variant_get_double(data);
        break;
    case SR_CONF_STATUS_PERIOD:
        if (ch->index == 0)
            vdev->mstatus.ch0_period = g_variant_get_uint64(data);
        else
            vdev->mstatus.ch1_period = g_variant_get_uint64(data);
        break;
    case SR_CONF_STATUS_PCNT:
        if (ch->index == 0)
            vdev->mstatus.ch0_pcnt = g_variant_get_uint64(data);
        else
            vdev->mstatus.ch1_pcnt = g_variant_get_uint64(data);
        break;
    case SR_CONF_STATUS_MAX:
        if (ch->index == 0)
            vdev->mstatus.ch0_max = g_variant_get_uint64(data);
        else
            vdev->mstatus.ch1_max = g_variant_get_uint64(data);
        break;
    case SR_CONF_STATUS_MIN:
        if (ch->index == 0)
            vdev->mstatus.ch0_min = g_variant_get_uint64(data);
        else
            vdev->mstatus.ch1_min = g_variant_get_uint64(data);
        break;
    default:
		sr_err("Unknown capability: %d.", id);
		return SR_ERR;
	}

	return SR_OK;
}
Exemple #7
0
/**
 *Translating the gvariant to Scheme Object
 */
Scheme_Object *
gvariant_to_schemeobj (GVariant *ivalue)
{
  gint32 i;
  GVariant *temp;
  const gchar *fstring;
  gsize length = 0;
  gsize size = 0;
  gint32 r1 = 0;
  gdouble r2 = 0;
  Scheme_Object *fint;
  Scheme_Object *fstringss;
  Scheme_Object *fdouble;
  Scheme_Object *sflist = NULL;
  gchar *tmp;

  //scheme_signal_error ("Not tuple yet");

  tmp = g_variant_print (ivalue, FALSE);
  fprintf (stderr, "gvariant_to_schemobj(%s)\n", tmp);
  g_free (tmp);
  
  size = g_variant_get_size (ivalue);
  //  fprintf (stderr, "Exploring the return value.\n");
  /* if (ivalue == NULL)
    {
      fprintf (stderr, "Return value is <NULL>\n");
    } // if (ivalue == NULL)
  else // if (ivalue != NULL)
    {
      type = g_variant_get_type (ivalue);
      typestring = g_variant_type_dup_string (type);
      fprintf (stderr, "Got type %s\n", typestring);
      g_free (typestring);
      description = g_variant_print (ivalue, TRUE);
      fprintf (stderr, "Got value %s\n", description);
      g_free (description);
      } // if (ivalue != NULL)*/
    
  if (ivalue == NULL)
    {
      return scheme_void;
    }
  
  if (g_variant_is_of_type  (ivalue, G_VARIANT_TYPE_INT32))
    {
      r1 = g_variant_get_int32 (ivalue);
      fint = scheme_make_integer_value(r1); 
      return fint;
    }// else if
  else if (g_variant_is_of_type (ivalue, G_VARIANT_TYPE_STRING))
    {
      fprintf ( stderr, "Type_string\n");
     
      // scheme_signal_error ("%d", size);
      fstring  = g_variant_get_string(ivalue, &size);
      fstringss = scheme_make_locale_string(fstring);
      return fstringss;
    }// else if
  else if (g_variant_is_of_type (ivalue, G_VARIANT_TYPE_BYTESTRING))
    {
      fprintf (stderr, "Bytestring\n");
      scheme_signal_error("stringbyeerror");
      fstring = g_variant_get_bytestring (ivalue);
      fstringss = scheme_make_locale_string(fstring);
      return fstringss;
    }// else if
  
  
  else if (g_variant_is_of_type (ivalue, G_VARIANT_TYPE_DOUBLE))
    {
      r2 = g_variant_get_double (ivalue);
      fdouble = scheme_make_double (r2);
      return fdouble; 
    }// else if
  
  else if (g_variant_is_of_type (ivalue, G_VARIANT_TYPE_TUPLE))
    {
      int i;
      Scheme_Object *result;  // The list we're building
      Scheme_Object *element; // One element of that list

      fprintf (stderr, "Handling a tuple.\n");

      result = scheme_null;
      for (i = g_variant_n_children (ivalue) - 1; i >= 0; i--)
	{
	  fprintf (stderr, "Handling child %d\n", i);
	  element = gvariant_to_schemeobj (g_variant_get_child_value (ivalue, i));
	  result = scheme_make_pair (element, result);
	} // for
      
      return result;
    } // if it's a tuple
  
      // Default.  Give up
  else
    {
      scheme_signal_error ("could not convert type");
    } // default
} //gvariant_to_schemeobj
Exemple #8
0
static gboolean deja_dup_config_rel_path_real_set_from_config_co (DejaDupConfigRelPathSetFromConfigData* _data_) {
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_tmp0_ = ((DejaDupConfigWidget*) _data_->self)->settings;
	_data_->_tmp1_ = deja_dup_config_widget_get_key ((DejaDupConfigWidget*) _data_->self);
	_data_->_tmp2_ = _data_->_tmp1_;
	_data_->_tmp3_ = NULL;
	_data_->_tmp3_ = g_settings_get_value ((GSettings*) _data_->_tmp0_, _data_->_tmp2_);
	_data_->byte_val = _data_->_tmp3_;
	_data_->val = NULL;
	{
		_data_->_tmp4_ = NULL;
		_data_->_tmp4_ = g_variant_get_bytestring (_data_->byte_val);
		_data_->_tmp5_ = NULL;
		_data_->_tmp5_ = g_filename_to_utf8 (_data_->_tmp4_, (gssize) (-1), NULL, NULL, &_data_->_inner_error_);
		_data_->_tmp6_ = _data_->_tmp5_;
		if (_data_->_inner_error_ != NULL) {
			goto __catch6_g_error;
		}
		_g_free0 (_data_->val);
		_data_->val = _data_->_tmp6_;
	}
	goto __finally6;
	__catch6_g_error:
	{
		_data_->e = _data_->_inner_error_;
		_data_->_inner_error_ = NULL;
		_data_->_tmp7_ = _data_->e;
		_data_->_tmp8_ = _data_->_tmp7_->message;
		g_warning ("ConfigRelPath.vala:39: %s\n", _data_->_tmp8_);
		_g_error_free0 (_data_->e);
	}
	__finally6:
	if (_data_->_inner_error_ != NULL) {
		_g_free0 (_data_->val);
		_g_variant_unref0 (_data_->byte_val);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _data_->_inner_error_->message, g_quark_to_string (_data_->_inner_error_->domain), _data_->_inner_error_->code);
		g_clear_error (&_data_->_inner_error_);
		return FALSE;
	}
	_data_->_tmp9_ = _data_->val;
	if (_data_->_tmp9_ == NULL) {
		_data_->_tmp10_ = g_strdup ("");
		_g_free0 (_data_->val);
		_data_->val = _data_->_tmp10_;
	}
	_data_->_tmp11_ = ((DejaDupConfigEntry*) _data_->self)->entry;
	_data_->_tmp12_ = _data_->val;
	gtk_entry_set_text (_data_->_tmp11_, _data_->_tmp12_);
	_g_free0 (_data_->val);
	_g_variant_unref0 (_data_->byte_val);
	if (_data_->_state_ == 0) {
		g_simple_async_result_complete_in_idle (_data_->_async_result);
	} else {
		g_simple_async_result_complete (_data_->_async_result);
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}
Exemple #9
0
static void
portal_add_named (GDBusMethodInvocation *invocation,
                  GVariant *parameters,
                  const char *app_id)
{
  GDBusMessage *message;
  GUnixFDList *fd_list;
  g_autofree char *id = NULL;
  g_autofree char *proc_path = NULL;
  int parent_fd_id, parent_fd, fds_len, fd_flags;
  const int *fds;
  char parent_path_buffer[PATH_MAX+1];
  g_autofree char *path = NULL;
  ssize_t symlink_size;
  struct stat parent_st_buf;
  const char *filename;
  gboolean reuse_existing, persistent;
  g_autoptr(GVariant) filename_v = NULL;

  g_variant_get (parameters, "(h@aybb)", &parent_fd_id, &filename_v, &reuse_existing, &persistent);
  filename = g_variant_get_bytestring (filename_v);

  /* This is only allowed from the host, or else we could leak existance of files */
  if (*app_id != 0)
    {
      g_dbus_method_invocation_return_error (invocation, XDG_APP_PORTAL_ERROR, XDG_APP_PORTAL_ERROR_NOT_ALLOWED,
                                             "Not enough permissions");
      return;
    }

  message = g_dbus_method_invocation_get_message (invocation);
  fd_list = g_dbus_message_get_unix_fd_list (message);

  parent_fd = -1;
  if (fd_list != NULL)
    {
      fds = g_unix_fd_list_peek_fds (fd_list, &fds_len);
      if (parent_fd_id < fds_len)
        parent_fd = fds[parent_fd_id];
    }

  if (strchr (filename, '/') != NULL)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             XDG_APP_PORTAL_ERROR, XDG_APP_PORTAL_ERROR_INVALID_ARGUMENT,
                                             "Invalid filename passed");
      return;
    }

  proc_path = g_strdup_printf ("/proc/self/fd/%d", parent_fd);

  if (parent_fd == -1 ||
      /* Must be able to get fd flags */
      (fd_flags = fcntl (parent_fd, F_GETFL)) == -1 ||
      /* Must be O_PATH */
      ((fd_flags & O_PATH) != O_PATH) ||
      /* Must not be O_NOFOLLOW (because we want the target file) */
      ((fd_flags & O_NOFOLLOW) == O_PATH) ||
      /* Must be able to fstat */
      fstat (parent_fd, &parent_st_buf) < 0 ||
      /* Must be a directory file */
      (parent_st_buf.st_mode & S_IFMT) != S_IFDIR ||
      /* Must be able to read path from /proc/self/fd */
      /* This is an absolute and (at least at open time) symlink-expanded path */
      (symlink_size = readlink (proc_path, parent_path_buffer, sizeof (parent_path_buffer) - 1)) < 0)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             XDG_APP_PORTAL_ERROR, XDG_APP_PORTAL_ERROR_INVALID_ARGUMENT,
                                             "Invalid fd passed");
      return;
    }

  if (parent_st_buf.st_dev == fuse_dev)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             XDG_APP_PORTAL_ERROR, XDG_APP_PORTAL_ERROR_INVALID_ARGUMENT,
                                             "Invalid fd passed");
      return;
    }

  parent_path_buffer[symlink_size] = 0;

  path = g_build_filename (parent_path_buffer, filename, NULL);

  g_debug ("portal_add_named %s", path);

  AUTOLOCK(db);

  id = do_create_doc (&parent_st_buf, path, reuse_existing, persistent);

  g_dbus_method_invocation_return_value (invocation,
                                         g_variant_new ("(s)", id));
}
QT_BEGIN_NAMESPACE

QVariant convertValue(GVariant *value)
{
    if (!value)
        return QVariant(QVariant::Invalid);

    switch (g_variant_classify(value)) {
    case G_VARIANT_CLASS_BOOLEAN:
        return QVariant((bool)g_variant_get_boolean(value));
    case G_VARIANT_CLASS_BYTE:
        return QVariant(QLatin1Char(g_variant_get_byte(value)));
    case G_VARIANT_CLASS_INT16:
        return QVariant((int)g_variant_get_int16(value));
    case G_VARIANT_CLASS_UINT16:
        return QVariant((uint)g_variant_get_uint16(value));
    case G_VARIANT_CLASS_INT32:
        return QVariant((int)g_variant_get_int32(value));
    case G_VARIANT_CLASS_UINT32:
        return QVariant((uint)g_variant_get_uint32(value));
    case G_VARIANT_CLASS_INT64:
        return QVariant((qlonglong)g_variant_get_int64(value));
    case G_VARIANT_CLASS_UINT64:
        return QVariant((qulonglong)g_variant_get_uint64(value));
    case G_VARIANT_CLASS_DOUBLE:
        return QVariant(g_variant_get_double(value));
    case G_VARIANT_CLASS_STRING:
        return QVariant(QString::fromUtf8(g_variant_get_string(value, NULL)));
    case G_VARIANT_CLASS_ARRAY:
        if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING_ARRAY)) {
            GVariantIter iter;
            QStringList list;
            const gchar *str;

            g_variant_iter_init(&iter, value);

            while (g_variant_iter_next(&iter, "&s", &str))
                list.append(QString::fromUtf8(str));

            return QVariant(list);
        } else if (g_variant_is_of_type(value, G_VARIANT_TYPE_BYTESTRING_ARRAY)) {
            GVariantIter iter;
            QVariantList list;
            const gchar *item;

            g_variant_iter_init(&iter, value);

            while (g_variant_iter_next(&iter, "&y", &item))
                list.append(QByteArray(item));

            return list;
#ifndef QT_NO_DATASTREAM
        } else if (g_variant_is_of_type(value, G_VARIANT_TYPE_BYTESTRING)) {
            QByteArray a(g_variant_get_bytestring(value));
            QDataStream s(&a, QIODevice::ReadOnly);
            s.setVersion(QDataStream::Qt_4_0);
            QVariant result;
            s >> result;
            return result;
#else
        Q_ASSERT(!"QConfiguration: Cannot load custom types without QDataStream support");
#endif
        }
    default:
        break;
    }

    return QVariant(QVariant::Invalid);
}
Exemple #11
0
gboolean
g_settings_get_mapping (GValue   *value,
                        GVariant *variant,
                        gpointer  user_data)
{
  if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN))
    {
      if (!G_VALUE_HOLDS_BOOLEAN (value))
        return FALSE;
      g_value_set_boolean (value, g_variant_get_boolean (variant));
      return TRUE;
    }

  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTE))
    {
      if (G_VALUE_HOLDS_UCHAR (value))
        g_value_set_uchar (value, g_variant_get_byte (variant));
      else if (G_VALUE_HOLDS_CHAR (value))
        g_value_set_char (value, (gchar) g_variant_get_byte (variant));
      else
        return FALSE;
      return TRUE;
    }

  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT16)  ||
           g_variant_is_of_type (variant, G_VARIANT_TYPE_INT32)  ||
           g_variant_is_of_type (variant, G_VARIANT_TYPE_INT64))
    return g_settings_get_mapping_int (value, variant);

  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_DOUBLE))
    return g_settings_get_mapping_float (value, variant);

  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT16) ||
           g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32) ||
           g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT64) ||
           g_variant_is_of_type (variant, G_VARIANT_TYPE_HANDLE))
    return g_settings_get_mapping_unsigned_int (value, variant);

  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING)      ||
           g_variant_is_of_type (variant, G_VARIANT_TYPE_OBJECT_PATH) ||
           g_variant_is_of_type (variant, G_VARIANT_TYPE_SIGNATURE))
    {
      if (G_VALUE_HOLDS_STRING (value))
        {
          g_value_set_string (value, g_variant_get_string (variant, NULL));
          return TRUE;
        }

      else if (G_VALUE_HOLDS_ENUM (value))
        {
          GEnumClass *eclass;
          GEnumValue *evalue;
          const gchar *nick;

          /* GParamSpecEnum holds a ref on the class so we just peek... */
          eclass = g_type_class_peek (G_VALUE_TYPE (value));
          nick = g_variant_get_string (variant, NULL);
          evalue = g_enum_get_value_by_nick (eclass, nick);

          if (evalue)
            {
             g_value_set_enum (value, evalue->value);
             return TRUE;
            }

          g_warning ("Unable to lookup enum nick '%s' via GType\n", nick);
          return FALSE;
        }
    }
  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE ("as")))
    {
      if (G_VALUE_HOLDS (value, G_TYPE_STRV))
        {
          g_value_take_boxed (value, g_variant_dup_strv (variant, NULL));
          return TRUE;
        }

      else if (G_VALUE_HOLDS_FLAGS (value))
        {
          GFlagsClass *fclass;
          GFlagsValue *fvalue;
          const gchar *nick;
          GVariantIter iter;
          guint flags = 0;

          fclass = g_type_class_peek (G_VALUE_TYPE (value));

          g_variant_iter_init (&iter, variant);
          while (g_variant_iter_next (&iter, "&s", &nick))
            {
              fvalue = g_flags_get_value_by_nick (fclass, nick);

              if (fvalue)
                flags |= fvalue->value;

              else
                {
                  g_warning ("Unable to lookup flags nick '%s' via GType\n",
                             nick);
                  return FALSE;
                }
            }

          g_value_set_flags (value, flags);
          return TRUE;
        }
    }
  else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTESTRING))
    {
      g_value_set_string (value, g_variant_get_bytestring (variant));
      return TRUE;
    }

  g_critical ("No GSettings bind handler for type \"%s\".",
              g_variant_get_type_string (variant));

  return FALSE;
}
Exemple #12
0
/**
 * g_dbus_gvariant_to_gvalue:
 * @value: A #GVariant.
 * @out_gvalue: (out): Return location pointing to a zero-filled (uninitialized) #GValue.
 *
 * Converts a #GVariant to a #GValue. If @value is floating, it is consumed.
 *
 * The rules specified in the g_dbus_gvalue_to_gvariant() function are
 * used - this function is essentially its reverse form.
 *
 * The conversion never fails - a valid #GValue is always returned in
 * @out_gvalue.
 *
 * Since: 2.30
 */
void
g_dbus_gvariant_to_gvalue (GVariant  *value,
                           GValue    *out_gvalue)
{
  const GVariantType *type;
  gchar **array;

  g_return_if_fail (value != NULL);
  g_return_if_fail (out_gvalue != NULL);

  memset (out_gvalue, '\0', sizeof (GValue));

  switch (g_variant_classify (value))
    {
    case G_VARIANT_CLASS_BOOLEAN:
      g_value_init (out_gvalue, G_TYPE_BOOLEAN);
      g_value_set_boolean (out_gvalue, g_variant_get_boolean (value));
      break;

    case G_VARIANT_CLASS_BYTE:
      g_value_init (out_gvalue, G_TYPE_UCHAR);
      g_value_set_uchar (out_gvalue, g_variant_get_byte (value));
      break;

    case G_VARIANT_CLASS_INT16:
      g_value_init (out_gvalue, G_TYPE_INT);
      g_value_set_int (out_gvalue, g_variant_get_int16 (value));
      break;

    case G_VARIANT_CLASS_UINT16:
      g_value_init (out_gvalue, G_TYPE_UINT);
      g_value_set_uint (out_gvalue, g_variant_get_uint16 (value));
      break;

    case G_VARIANT_CLASS_INT32:
      g_value_init (out_gvalue, G_TYPE_INT);
      g_value_set_int (out_gvalue, g_variant_get_int32 (value));
      break;

    case G_VARIANT_CLASS_UINT32:
      g_value_init (out_gvalue, G_TYPE_UINT);
      g_value_set_uint (out_gvalue, g_variant_get_uint32 (value));
      break;

    case G_VARIANT_CLASS_INT64:
      g_value_init (out_gvalue, G_TYPE_INT64);
      g_value_set_int64 (out_gvalue, g_variant_get_int64 (value));
      break;

    case G_VARIANT_CLASS_UINT64:
      g_value_init (out_gvalue, G_TYPE_UINT64);
      g_value_set_uint64 (out_gvalue, g_variant_get_uint64 (value));
      break;

    case G_VARIANT_CLASS_DOUBLE:
      g_value_init (out_gvalue, G_TYPE_DOUBLE);
      g_value_set_double (out_gvalue, g_variant_get_double (value));
      break;

    case G_VARIANT_CLASS_STRING:
      g_value_init (out_gvalue, G_TYPE_STRING);
      g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
      break;

    case G_VARIANT_CLASS_OBJECT_PATH:
      g_value_init (out_gvalue, G_TYPE_STRING);
      g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
      break;

    case G_VARIANT_CLASS_SIGNATURE:
      g_value_init (out_gvalue, G_TYPE_STRING);
      g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
      break;

    case G_VARIANT_CLASS_ARRAY:
      type = g_variant_get_type (value);
      switch (g_variant_type_peek_string (type)[1])
        {
        case G_VARIANT_CLASS_BYTE:
          g_value_init (out_gvalue, G_TYPE_STRING);
          g_value_set_string (out_gvalue, g_variant_get_bytestring (value));
          break;

        case G_VARIANT_CLASS_STRING:
          g_value_init (out_gvalue, G_TYPE_STRV);
          array = g_variant_dup_strv (value, NULL);
          g_value_take_boxed (out_gvalue, array);
          break;

        case G_VARIANT_CLASS_OBJECT_PATH:
          g_value_init (out_gvalue, G_TYPE_STRV);
          array = g_variant_dup_objv (value, NULL);
          g_value_take_boxed (out_gvalue, array);
          break;

        case G_VARIANT_CLASS_ARRAY:
          switch (g_variant_type_peek_string (type)[2])
            {
            case G_VARIANT_CLASS_BYTE:
              g_value_init (out_gvalue, G_TYPE_STRV);
              array = g_variant_dup_bytestring_array (value, NULL);
              g_value_take_boxed (out_gvalue, array);
              break;

            default:
              g_value_init (out_gvalue, G_TYPE_VARIANT);
              g_value_set_variant (out_gvalue, value);
              break;
            }
          break;

        default:
          g_value_init (out_gvalue, G_TYPE_VARIANT);
          g_value_set_variant (out_gvalue, value);
          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:
      g_value_init (out_gvalue, G_TYPE_VARIANT);
      g_value_set_variant (out_gvalue, value);
      break;
    }
}