polkitdetails.c 5.67 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
/*
 * Copyright (C) 2008 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: David Zeuthen <davidz@redhat.com>
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <string.h>
#include "polkitimplicitauthorization.h"
#include "polkitdetails.h"

#include "polkitprivate.h"

/**
 * SECTION:polkitdetails
 * @title: PolkitDetails
David Zeuthen's avatar
David Zeuthen committed
35 36
 * @short_description: Object used for passing details
 * @stability: Stable
37 38 39 40
 *
 * An object used for passing details around.
 */

David Zeuthen's avatar
David Zeuthen committed
41 42 43 44 45
/**
 * PolkitDetails:
 *
 * The #PolkitDetails struct should not be accessed directly.
 */
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
struct _PolkitDetails
{
  GObject parent_instance;

  GHashTable *hash;
};

struct _PolkitDetailsClass
{
  GObjectClass parent_class;
};

G_DEFINE_TYPE (PolkitDetails, polkit_details, G_TYPE_OBJECT);

static void
polkit_details_init (PolkitDetails *details)
{
}

static void
polkit_details_finalize (GObject *object)
{
  PolkitDetails *details;

  details = POLKIT_DETAILS (object);

72 73
  if (details->hash != NULL)
    g_hash_table_unref (details->hash);
74 75 76 77 78 79 80 81 82 83 84 85 86

  if (G_OBJECT_CLASS (polkit_details_parent_class)->finalize != NULL)
    G_OBJECT_CLASS (polkit_details_parent_class)->finalize (object);
}

static void
polkit_details_class_init (PolkitDetailsClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->finalize = polkit_details_finalize;
}

David Zeuthen's avatar
David Zeuthen committed
87 88 89 90 91 92 93
/**
 * polkit_details_new:
 *
 * Creates a new #PolkitDetails object.
 *
 * Returns: A #PolkitDetails object. Free with g_object_unref().
 */
94 95 96 97 98 99 100 101 102 103
PolkitDetails *
polkit_details_new (void)
{
  PolkitDetails *details;

  details = POLKIT_DETAILS (g_object_new (POLKIT_TYPE_DETAILS, NULL));

  return details;
}

David Zeuthen's avatar
David Zeuthen committed
104
/* private */
David Zeuthen's avatar
David Zeuthen committed
105
static PolkitDetails *
106 107 108 109 110 111 112 113 114 115 116
polkit_details_new_for_hash (GHashTable *hash)
{
  PolkitDetails *details;

  details = POLKIT_DETAILS (g_object_new (POLKIT_TYPE_DETAILS, NULL));
  if (hash != NULL)
    details->hash = g_hash_table_ref (hash);

  return details;
}

David Zeuthen's avatar
David Zeuthen committed
117 118 119 120 121 122 123
/**
 * polkit_details_lookup:
 * @details: A #PolkitDetails.
 * @key: A key.
 *
 * Gets the value for @key on @details.
 *
David Zeuthen's avatar
David Zeuthen committed
124
 * Returns: (allow-none): %NULL if there is no value for @key, otherwise a string owned by @details.
David Zeuthen's avatar
David Zeuthen committed
125
 */
126 127 128 129
const gchar *
polkit_details_lookup (PolkitDetails *details,
                       const gchar   *key)
{
130 131
  g_return_val_if_fail (POLKIT_IS_DETAILS (details), NULL);
  g_return_val_if_fail (key != NULL, NULL);
132 133 134 135 136 137
  if (details->hash == NULL)
    return NULL;
  else
    return g_hash_table_lookup (details->hash, key);
}

David Zeuthen's avatar
David Zeuthen committed
138 139 140 141
/**
 * polkit_details_insert:
 * @details: A #PolkitDetails.
 * @key: A key.
David Zeuthen's avatar
David Zeuthen committed
142
 * @value: (allow-none): A value.
David Zeuthen's avatar
David Zeuthen committed
143 144
 *
 * Inserts a copy of @key and @value on @details.
145 146
 *
 * If @value is %NULL, the key will be removed.
David Zeuthen's avatar
David Zeuthen committed
147
 */
148 149 150 151 152
void
polkit_details_insert (PolkitDetails *details,
                       const gchar   *key,
                       const gchar   *value)
{
153 154
  g_return_if_fail (POLKIT_IS_DETAILS (details));
  g_return_if_fail (key != NULL);
155 156 157 158 159
  if (details->hash == NULL)
    details->hash = g_hash_table_new_full (g_str_hash,
                                           g_str_equal,
                                           g_free,
                                           g_free);
160 161 162 163
  if (value != NULL)
    g_hash_table_insert (details->hash, g_strdup (key), g_strdup (value));
  else
    g_hash_table_remove (details->hash, key);
164 165
}

David Zeuthen's avatar
David Zeuthen committed
166 167 168 169 170 171
/**
 * polkit_details_get_keys:
 * @details: A #PolkitDetails.
 *
 * Gets a list of all keys on @details.
 *
172 173 174
 * Returns: (transfer full) (allow-none): %NULL if there are no keys
 * otherwise an array of strings that should be freed with
 * g_strfreev().
David Zeuthen's avatar
David Zeuthen committed
175
 */
176 177 178 179 180 181 182
gchar **
polkit_details_get_keys (PolkitDetails *details)
{
  GList *keys, *l;
  gchar **ret;
  guint n;

183 184
  g_return_val_if_fail (POLKIT_IS_DETAILS (details), NULL);

185 186 187 188 189 190 191 192 193 194 195 196
  if (details->hash == NULL)
    return NULL;

  keys = g_hash_table_get_keys (details->hash);
  ret = g_new0 (gchar*, g_list_length (keys) + 1);
  for (l = keys, n = 0; l != NULL; l = l->next, n++)
    ret[n] = g_strdup (l->data);

  g_list_free (keys);

  return ret;
}
David Zeuthen's avatar
David Zeuthen committed
197

198
/* Note that this returns a floating value. */
David Zeuthen's avatar
David Zeuthen committed
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
GVariant *
polkit_details_to_gvariant (PolkitDetails *details)
{
  GVariantBuilder builder;

  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
  if (details != NULL && details->hash != NULL)
    {
      GHashTableIter hash_iter;
      const gchar *key;
      const gchar *value;

      g_hash_table_iter_init (&hash_iter, details->hash);
      while (g_hash_table_iter_next (&hash_iter, (gpointer) &key, (gpointer) &value))
        g_variant_builder_add (&builder, "{ss}", key, value);
    }
215
  return g_variant_builder_end (&builder);
David Zeuthen's avatar
David Zeuthen committed
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
}

PolkitDetails *
polkit_details_new_for_gvariant (GVariant *value)
{
  PolkitDetails *ret;
  GHashTable *hash;
  GVariantIter iter;
  gchar *hash_key;
  gchar *hash_value;

  hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
  g_variant_iter_init (&iter, value);
  while (g_variant_iter_next (&iter, "{ss}", &hash_key, &hash_value))
    g_hash_table_insert (hash, hash_key, hash_value);
  ret = polkit_details_new_for_hash (hash);
  g_hash_table_unref (hash);
  return ret;
}