kvp-util.c

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

Generated on Fri Nov 10 04:06:03 2006 for QOF by  doxygen 1.5.1