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