00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00044 cwd = kvp_frame_new ();
00045
00046
00047 kvp_frame_set_time (cwd, "time", qt);
00048
00049
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
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
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
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
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