LCOV - code coverage report
Current view: top level - pkcs11/gkm - gkm-memory-store.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 91.0 % 111 101
Test Date: 2024-04-08 13:24:42 Functions: 88.9 % 18 16

            Line data    Source code
       1              : /*
       2              :  * gnome-keyring
       3              :  *
       4              :  * Copyright (C) 2008 Stefan Walter
       5              :  *
       6              :  * This program is free software; you can redistribute it and/or modify
       7              :  * it under the terms of the GNU Lesser General Public License as
       8              :  * published by the Free Software Foundation; either version 2.1 of
       9              :  * the License, or (at your option) any later version.
      10              :  *
      11              :  * This program is distributed in the hope that it will be useful, but
      12              :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14              :  * Lesser General Public License for more details.
      15              :  *
      16              :  * You should have received a copy of the GNU Lesser General Public
      17              :  * License along with this program; if not, see
      18              :  * <http://www.gnu.org/licenses/>.
      19              :  */
      20              : 
      21              : #include "config.h"
      22              : 
      23              : #include "gkm-attributes.h"
      24              : #define DEBUG_FLAG GKM_DEBUG_OBJECT
      25              : #include "gkm-debug.h"
      26              : #include "gkm-object.h"
      27              : #include "gkm-memory-store.h"
      28              : #include "gkm-transaction.h"
      29              : #include "gkm-util.h"
      30              : 
      31              : struct _GkmMemoryStore {
      32              :         GkmStore parent;
      33              :         GHashTable *entries;
      34              : };
      35              : 
      36              : typedef struct _Revert {
      37              :         GHashTable *attributes;
      38              :         CK_ATTRIBUTE_TYPE type;
      39              :         CK_ATTRIBUTE_PTR attr;
      40              : } Revert;
      41              : 
      42         2192 : G_DEFINE_TYPE (GkmMemoryStore, gkm_memory_store, GKM_TYPE_STORE);
      43              : 
      44              : /* -----------------------------------------------------------------------------
      45              :  * INTERNAL
      46              :  */
      47              : 
      48              : static void
      49           16 : attribute_free (gpointer data)
      50              : {
      51           16 :         CK_ATTRIBUTE_PTR attr = data;
      52           16 :         if (attr) {
      53            8 :                 g_free (attr->pValue);
      54            8 :                 g_slice_free (CK_ATTRIBUTE, attr);
      55              :         }
      56           16 : }
      57              : 
      58              : static CK_ATTRIBUTE_PTR
      59            8 : attribute_dup (CK_ATTRIBUTE_PTR attr)
      60              : {
      61              :         CK_ATTRIBUTE_PTR copy;
      62            8 :         g_assert (attr);
      63            8 :         copy = g_slice_new (CK_ATTRIBUTE);
      64            8 :         copy->ulValueLen = attr->ulValueLen;
      65            8 :         copy->pValue = g_memdup (attr->pValue, copy->ulValueLen);
      66            8 :         copy->type = attr->type;
      67            8 :         return copy;
      68              : }
      69              : 
      70              : static void
      71            1 : object_gone (gpointer data, GObject *was_object)
      72              : {
      73              :         GkmMemoryStore *self;
      74              : 
      75            1 :         g_assert (GKM_IS_MEMORY_STORE (data));
      76            1 :         self = GKM_MEMORY_STORE (data);
      77              : 
      78            1 :         if (!g_hash_table_remove (self->entries, was_object))
      79            0 :                 g_return_if_reached ();
      80              : }
      81              : 
      82              : static gboolean
      83            5 : remove_each_object (gpointer key, gpointer value, gpointer user_data)
      84              : {
      85            5 :         g_assert (GKM_IS_OBJECT (key));
      86            5 :         g_assert (GKM_IS_MEMORY_STORE (user_data));
      87              : 
      88            5 :         g_object_weak_unref (key, object_gone, user_data);
      89            5 :         return TRUE;
      90              : }
      91              : 
      92              : static gboolean
      93            8 : complete_set (GkmTransaction *transaction, GkmObject *object, Revert *revert)
      94              : {
      95            8 :         g_assert (GKM_IS_OBJECT (object));
      96              : 
      97            8 :         if (gkm_transaction_get_failed (transaction)) {
      98            4 :                 if (revert->attr)
      99            2 :                         g_hash_table_replace (revert->attributes, &(revert->attr->type), revert->attr);
     100              :                 else
     101            2 :                         g_hash_table_remove (revert->attributes, &(revert->type));
     102              : 
     103            4 :                 gkm_object_notify_attribute (object, revert->type);
     104              : 
     105            4 :                 revert->attr = NULL;
     106            4 :                 revert->type = 0;
     107              :         }
     108              : 
     109            8 :         g_hash_table_unref (revert->attributes);
     110            8 :         attribute_free (revert->attr);
     111            8 :         g_slice_free (Revert, revert);
     112            8 :         return TRUE;
     113              : }
     114              : 
     115              : /* -----------------------------------------------------------------------------
     116              :  * OBJECT
     117              :  */
     118              : 
     119              : static CK_RV
     120           15 : gkm_memory_store_real_read_value (GkmStore *base, GkmObject *object, CK_ATTRIBUTE_PTR attr)
     121              : {
     122           15 :         GkmMemoryStore *self = GKM_MEMORY_STORE (base);
     123              :         GHashTable *attributes;
     124              :         CK_ATTRIBUTE_PTR at;
     125              : 
     126           15 :         attributes = g_hash_table_lookup (self->entries, object);
     127           15 :         if (attributes == NULL) {
     128            5 :                 gkm_debug ("CKR_ATTRIBUTE_TYPE_INVALID: no object");
     129            5 :                 return CKR_ATTRIBUTE_TYPE_INVALID;
     130              :         }
     131              : 
     132           10 :         at = g_hash_table_lookup (attributes, &(attr->type));
     133           10 :         if (at == NULL) {
     134            1 :                 gkm_debug ("CKR_ATTRIBUTE_TYPE_INVALID: no attribute: %s",
     135              :                            gkm_log_attr_type (attr->type));
     136            1 :                 return CKR_ATTRIBUTE_TYPE_INVALID;
     137              :         }
     138              : 
     139            9 :         g_assert (at->type == attr->type);
     140              : 
     141              :         /* Yes, we don't fill a buffer, just return pointer */
     142            9 :         attr->pValue = at->pValue;
     143            9 :         attr->ulValueLen = at->ulValueLen;
     144              : 
     145            9 :         return CKR_OK;
     146              : }
     147              : 
     148              : static void
     149            8 : gkm_memory_store_real_write_value (GkmStore *base, GkmTransaction *transaction,
     150              :                                    GkmObject *object, CK_ATTRIBUTE_PTR attr)
     151              : {
     152            8 :         GkmMemoryStore *self = GKM_MEMORY_STORE (base);
     153              :         GHashTable *attributes;
     154              :         CK_ATTRIBUTE_PTR at;
     155              :         Revert *revert;
     156              : 
     157            8 :         g_return_if_fail (!gkm_transaction_get_failed (transaction));
     158              : 
     159            8 :         attributes = g_hash_table_lookup (self->entries, object);
     160            8 :         if (attributes == NULL) {
     161            6 :                 g_object_weak_ref (G_OBJECT (object), object_gone, self);
     162            6 :                 attributes = g_hash_table_new_full (gkm_util_ulong_hash, gkm_util_ulong_equal,
     163              :                                                     NULL, attribute_free);
     164            6 :                 g_hash_table_replace (self->entries, object, attributes);
     165              :         }
     166              : 
     167              :         /* No need to go any further if no change */
     168            8 :         at = g_hash_table_lookup (attributes, &(attr->type));
     169            8 :         if (at != NULL && gkm_attribute_equal (at, attr))
     170            0 :                 return;
     171              : 
     172            8 :         revert = g_slice_new0 (Revert);
     173            8 :         revert->attributes = g_hash_table_ref (attributes);
     174            8 :         revert->type = attr->type;
     175            8 :         revert->attr = at;
     176            8 :         g_hash_table_steal (attributes, &(attr->type));
     177            8 :         gkm_transaction_add (transaction, object, (GkmTransactionFunc)complete_set, revert);
     178              : 
     179            8 :         attr = attribute_dup (attr);
     180            8 :         g_hash_table_replace (attributes, &(attr->type), attr);
     181            8 :         gkm_object_notify_attribute (object, attr->type);
     182              : }
     183              : 
     184              : static GObject*
     185          517 : gkm_memory_store_constructor (GType type, guint n_props, GObjectConstructParam *props)
     186              : {
     187          517 :         GkmMemoryStore *self = GKM_MEMORY_STORE (G_OBJECT_CLASS (gkm_memory_store_parent_class)->constructor(type, n_props, props));
     188          517 :         g_return_val_if_fail (self, NULL);
     189              : 
     190          517 :         return G_OBJECT (self);
     191              : }
     192              : 
     193              : static void
     194          517 : gkm_memory_store_init (GkmMemoryStore *self)
     195              : {
     196          517 :         self->entries = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)g_hash_table_unref);
     197          517 : }
     198              : 
     199              : static void
     200          517 : gkm_memory_store_dispose (GObject *obj)
     201              : {
     202          517 :         GkmMemoryStore *self = GKM_MEMORY_STORE (obj);
     203              : 
     204          517 :         g_hash_table_foreach_remove (self->entries, remove_each_object, self);
     205              : 
     206          517 :         G_OBJECT_CLASS (gkm_memory_store_parent_class)->dispose (obj);
     207          517 : }
     208              : 
     209              : static void
     210          517 : gkm_memory_store_finalize (GObject *obj)
     211              : {
     212          517 :         GkmMemoryStore *self = GKM_MEMORY_STORE (obj);
     213              : 
     214          517 :         g_assert (g_hash_table_size (self->entries) == 0);
     215          517 :         g_hash_table_destroy (self->entries);
     216          517 :         self->entries = NULL;
     217              : 
     218          517 :         G_OBJECT_CLASS (gkm_memory_store_parent_class)->finalize (obj);
     219          517 : }
     220              : 
     221              : static void
     222            0 : gkm_memory_store_set_property (GObject *obj, guint prop_id, const GValue *value,
     223              :                                GParamSpec *pspec)
     224              : {
     225              :         switch (prop_id) {
     226              :         default:
     227            0 :                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
     228            0 :                 break;
     229              :         }
     230            0 : }
     231              : 
     232              : static void
     233            0 : gkm_memory_store_get_property (GObject *obj, guint prop_id, GValue *value,
     234              :                                GParamSpec *pspec)
     235              : {
     236              :         switch (prop_id) {
     237              :         default:
     238            0 :                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
     239            0 :                 break;
     240              :         }
     241            0 : }
     242              : 
     243              : static void
     244           47 : gkm_memory_store_class_init (GkmMemoryStoreClass *klass)
     245              : {
     246           47 :         GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
     247           47 :         GkmStoreClass *store_class = GKM_STORE_CLASS (klass);
     248              : 
     249           47 :         gobject_class->constructor = gkm_memory_store_constructor;
     250           47 :         gobject_class->dispose = gkm_memory_store_dispose;
     251           47 :         gobject_class->finalize = gkm_memory_store_finalize;
     252           47 :         gobject_class->set_property = gkm_memory_store_set_property;
     253           47 :         gobject_class->get_property = gkm_memory_store_get_property;
     254              : 
     255           47 :         store_class->read_value = gkm_memory_store_real_read_value;
     256           47 :         store_class->write_value = gkm_memory_store_real_write_value;
     257           47 : }
     258              : 
     259              : /* -----------------------------------------------------------------------------
     260              :  * PUBLIC
     261              :  */
     262              : 
     263              : GkmMemoryStore*
     264          517 : gkm_memory_store_new (void)
     265              : {
     266          517 :         return g_object_new (GKM_TYPE_MEMORY_STORE, NULL);
     267              : }
        

Generated by: LCOV version 2.0-1