kvputil.c

00001 /********************************************************************\
00002  * kvp_util.c -- misc odd-job kvp utils                             *
00003  * Copyright (C) 2001 Linas Vepstas <linas@linas.org>               *
00004  * Copyright (C) 2006 Neil Williams <linux@codehelp.co.uk>          *
00005  *                                                                  *
00006  * This program is free software; you can redistribute it and/or    *
00007  * modify it under the terms of the GNU General Public License as   *
00008  * published by the Free Software Foundation; either version 2 of   *
00009  * the License, or (at your option) any later version.              *
00010  *                                                                  *
00011  * This program is distributed in the hope that it will be useful,  *
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00014  * GNU General Public License for more details.                     *
00015  *                                                                  *
00016  * You should have received a copy of the GNU General Public License*
00017  * along with this program; if not, contact:                        *
00018  *                                                                  *
00019  * Free Software Foundation           Voice:  +1-617-542-5942       *
00020  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
00021  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
00022  *                                                                  *
00023 \********************************************************************/
00024 
00025 #include "config.h"
00026 #include <glib.h>
00027 #include <stdio.h>
00028 #include "qof.h"
00029 #include "kvputil-p.h"
00030 
00031 static KvpFrame *
00032 qof_kvp_array_va (KvpFrame * kvp_root, const gchar *path,
00033     QofTime *qt, const gchar *first_name, va_list ap)
00034 {
00035     KvpFrame *cwd;
00036     const gchar *name;
00037 
00038     if (!kvp_root)
00039         return NULL;
00040     if (!first_name)
00041         return NULL;
00042 
00043     /* Create subdirectory and put the actual data */
00044     cwd = kvp_frame_new ();
00045 
00046     /* Record the time */
00047     kvp_frame_set_time (cwd, "time", qt);
00048 
00049     /* Loop over the args */
00050     name = first_name;
00051     while (name)
00052     {
00053         const GUID *guid;
00054         guid = va_arg (ap, const GUID *);
00055 
00056         kvp_frame_set_guid (cwd, name, guid);
00057 
00058         name = va_arg (ap, const char *);
00059     }
00060 
00061     /* Attach cwd into the array */
00062     kvp_frame_add_frame_nc (kvp_root, path, cwd);
00063     return cwd;
00064 }
00065 
00066 KvpFrame *
00067 qof_kvp_bag_add (KvpFrame * pwd, const gchar *path,
00068     QofTime *qt, const gchar *first_name, ...)
00069 {
00070     KvpFrame *cwd;
00071     va_list ap;
00072     va_start (ap, first_name);
00073     cwd = qof_kvp_array_va (pwd, path, qt, first_name, ap);
00074     va_end (ap);
00075     return cwd;
00076 }
00077 
00078 /* ================================================================ */
00079 
00080 #define MATCH_GUID(elt) {                                       \
00081   KvpFrame *fr = kvp_value_get_frame (elt);                     \
00082   if (fr) {                                                     \
00083      GUID *guid = kvp_frame_get_guid (fr, guid_name);           \
00084      if (guid && guid_equal (desired_guid, guid)) return fr;    \
00085   }                                                             \
00086 }
00087 
00088 KvpFrame *
00089 qof_kvp_bag_find_by_guid (KvpFrame * root, const gchar *path,
00090     const gchar *guid_name, GUID * desired_guid)
00091 {
00092     KvpValue *arr;
00093     KvpValueType valtype;
00094     GList *node;
00095 
00096     arr = kvp_frame_get_value (root, path);
00097     valtype = kvp_value_get_type (arr);
00098     if (KVP_TYPE_FRAME == valtype)
00099     {
00100         MATCH_GUID (arr);
00101         return NULL;
00102     }
00103 
00104     /* Its got to be a single isolated frame, or a list of them. */
00105     if (KVP_TYPE_GLIST != valtype)
00106         return NULL;
00107 
00108     for (node = kvp_value_get_glist (arr); node; node = node->next)
00109     {
00110         KvpValue *va = node->data;
00111         MATCH_GUID (va);
00112     }
00113     return NULL;
00114 }
00115 
00116 /* ================================================================ */
00117 
00118 void
00119 qof_kvp_bag_remove_frame (KvpFrame * root, const gchar *path, KvpFrame * fr)
00120 {
00121     KvpValue *arr;
00122     KvpValueType valtype;
00123     GList *node, *listhead;
00124 
00125     arr = kvp_frame_get_value (root, path);
00126     valtype = kvp_value_get_type (arr);
00127     if (KVP_TYPE_FRAME == valtype)
00128     {
00129         if (fr == kvp_value_get_frame (arr))
00130         {
00131             KvpValue *old_val =
00132                 kvp_frame_replace_value_nc (root, path, NULL);
00133             kvp_value_replace_frame_nc (old_val, NULL);
00134             kvp_value_delete (old_val);
00135         }
00136         return;
00137     }
00138 
00139     /* Its got to be a single isolated frame, or a list of them. */
00140     if (KVP_TYPE_GLIST != valtype)
00141         return;
00142 
00143     listhead = kvp_value_get_glist (arr);
00144     for (node = listhead; node; node = node->next)
00145     {
00146         KvpValue *va = node->data;
00147         if (fr == kvp_value_get_frame (va))
00148         {
00149             listhead = g_list_remove_link (listhead, node);
00150             g_list_free_1 (node);
00151             kvp_value_replace_glist_nc (arr, listhead);
00152             kvp_value_replace_frame_nc (va, NULL);
00153             kvp_value_delete (va);
00154             return;
00155         }
00156     }
00157 }
00158 
00159 /* ================================================================ */
00160 
00161 static KvpFrame *
00162 qof_kvp_bag_get_first (KvpFrame * root, const gchar *path)
00163 {
00164     KvpValue *arr, *va;
00165     KvpValueType valtype;
00166     GList *node;
00167 
00168     arr = kvp_frame_get_value (root, path);
00169     valtype = kvp_value_get_type (arr);
00170     if (KVP_TYPE_FRAME == valtype)
00171         return kvp_value_get_frame (arr);
00172 
00173     /* Its gotta be a single isolated frame, or a list of them. */
00174     if (KVP_TYPE_GLIST != valtype)
00175         return NULL;
00176 
00177     node = kvp_value_get_glist (arr);
00178     if (NULL == node)
00179         return NULL;
00180 
00181     va = node->data;
00182     return kvp_value_get_frame (va);
00183 }
00184 
00185 void
00186 qof_kvp_bag_merge (KvpFrame * kvp_into, const gchar *intopath,
00187     KvpFrame * kvp_from, const gchar *frompath)
00188 {
00189     KvpFrame *fr;
00190 
00191     fr = qof_kvp_bag_get_first (kvp_from, frompath);
00192     while (fr)
00193     {
00194         qof_kvp_bag_remove_frame (kvp_from, frompath, fr);
00195         kvp_frame_add_frame_nc (kvp_into, intopath, fr);
00196         fr = qof_kvp_bag_get_first (kvp_from, frompath);
00197     }
00198 }
00199 
00200 static void
00201 kv_pair_helper (gpointer key, gpointer val, gpointer user_data)
00202 {
00203     GSList **result = (GSList **) user_data;
00204     GHashTableKVPair *kvp = g_new0 (GHashTableKVPair, 1);
00205 
00206     kvp->key = key;
00207     kvp->value = val;
00208     *result = g_slist_prepend (*result, kvp);
00209 }
00210 
00211 GSList *
00212 g_hash_table_key_value_pairs (GHashTable * table)
00213 {
00214     GSList *result_list = NULL;
00215     g_hash_table_foreach (table, kv_pair_helper, &result_list);
00216     return result_list;
00217 }
00218 
00219 void
00220 g_hash_table_kv_pair_free_gfunc (gpointer data, gpointer user_data
00221     __attribute__ ((unused)))
00222 {
00223     GHashTableKVPair *kvp = (GHashTableKVPair *) data;
00224     g_free (kvp);
00225 }
00226 
00227 /*======================== END OF FILE =============================*/

Generated on Thu Jan 31 22:50:25 2008 for QOF by  doxygen 1.5.4