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
00026 #include <glib.h>
00027 #include <stdio.h>
00028
00029 #include "kvp_frame.h"
00030 #include "kvp-util.h"
00031 #include "kvp-util-p.h"
00032
00033
00034
00035 static KvpFrame *
00036 gnc_kvp_array_va (KvpFrame *kvp_root, const char * path,
00037 time_t secs, const char * first_name, va_list ap)
00038 {
00039 KvpFrame *cwd;
00040 Timespec ts;
00041 const char *name;
00042
00043 if (!kvp_root) return NULL;
00044 if (!first_name) return NULL;
00045
00046
00047 cwd = kvp_frame_new();
00048
00049
00050 ts.tv_sec = secs;
00051 ts.tv_nsec = 0;
00052 kvp_frame_set_timespec (cwd, "date", ts);
00053
00054
00055 name = first_name;
00056 while (name)
00057 {
00058 const GUID *guid;
00059 guid = va_arg (ap, const GUID *);
00060
00061 kvp_frame_set_guid (cwd, name, guid);
00062
00063 name = va_arg (ap, const char *);
00064 }
00065
00066
00067 kvp_frame_add_frame_nc (kvp_root, path, cwd);
00068 return cwd;
00069 }
00070
00071
00072
00073 KvpFrame *
00074 gnc_kvp_bag_add (KvpFrame *pwd, const char * path,
00075 time_t secs, const char *first_name, ...)
00076 {
00077 KvpFrame *cwd;
00078 va_list ap;
00079 va_start (ap, first_name);
00080 cwd = gnc_kvp_array_va (pwd, path, secs, first_name, ap);
00081 va_end (ap);
00082 return cwd;
00083 }
00084
00085
00086
00087 #define MATCH_GUID(elt) { \
00088 KvpFrame *fr = kvp_value_get_frame (elt); \
00089 if (fr) { \
00090 GUID *guid = kvp_frame_get_guid (fr, guid_name); \
00091 if (guid && guid_equal (desired_guid, guid)) return fr; \
00092 } \
00093 }
00094
00095 KvpFrame *
00096 gnc_kvp_bag_find_by_guid (KvpFrame *root, const char * path,
00097 const char *guid_name, GUID *desired_guid)
00098 {
00099 KvpValue *arr;
00100 KvpValueType valtype;
00101 GList *node;
00102
00103 arr = kvp_frame_get_value (root, path);
00104 valtype = kvp_value_get_type (arr);
00105 if (KVP_TYPE_FRAME == valtype)
00106 {
00107 MATCH_GUID (arr);
00108 return NULL;
00109 }
00110
00111
00112 if (KVP_TYPE_GLIST != valtype) return NULL;
00113
00114 for (node = kvp_value_get_glist(arr); node; node=node->next)
00115 {
00116 KvpValue *va = node->data;
00117 MATCH_GUID (va);
00118 }
00119 return NULL;
00120 }
00121
00122
00123
00124 void
00125 gnc_kvp_bag_remove_frame (KvpFrame *root, const char *path, KvpFrame *fr)
00126 {
00127 KvpValue *arr;
00128 KvpValueType valtype;
00129 GList *node, *listhead;
00130
00131 arr = kvp_frame_get_value (root, path);
00132 valtype = kvp_value_get_type (arr);
00133 if (KVP_TYPE_FRAME == valtype)
00134 {
00135 if (fr == kvp_value_get_frame (arr))
00136 {
00137 KvpValue *old_val = kvp_frame_replace_value_nc (root, path, NULL);
00138 kvp_value_replace_frame_nc (old_val, NULL);
00139 kvp_value_delete (old_val);
00140 }
00141 return;
00142 }
00143
00144
00145 if (KVP_TYPE_GLIST != valtype) return;
00146
00147 listhead = kvp_value_get_glist(arr);
00148 for (node = listhead; node; node=node->next)
00149 {
00150 KvpValue *va = node->data;
00151 if (fr == kvp_value_get_frame (va))
00152 {
00153 listhead = g_list_remove_link (listhead, node);
00154 g_list_free_1 (node);
00155 kvp_value_replace_glist_nc (arr, listhead);
00156 kvp_value_replace_frame_nc (va, NULL);
00157 kvp_value_delete (va);
00158 return;
00159 }
00160 }
00161 }
00162
00163
00164
00165 static KvpFrame *
00166 gnc_kvp_bag_get_first (KvpFrame *root, const char * path)
00167 {
00168 KvpValue *arr, *va;
00169 KvpValueType valtype;
00170 GList *node;
00171
00172 arr = kvp_frame_get_value (root, path);
00173 valtype = kvp_value_get_type (arr);
00174 if (KVP_TYPE_FRAME == valtype)
00175 {
00176 return kvp_value_get_frame(arr);
00177 }
00178
00179
00180 if (KVP_TYPE_GLIST != valtype) return NULL;
00181
00182 node = kvp_value_get_glist(arr);
00183 if (NULL == node) return NULL;
00184
00185 va = node->data;
00186 return kvp_value_get_frame(va);
00187 }
00188
00189 void
00190 gnc_kvp_bag_merge (KvpFrame *kvp_into, const char *intopath,
00191 KvpFrame *kvp_from, const char *frompath)
00192 {
00193 KvpFrame *fr;
00194
00195 fr = gnc_kvp_bag_get_first (kvp_from, frompath);
00196 while (fr)
00197 {
00198 gnc_kvp_bag_remove_frame (kvp_from, frompath, fr);
00199 kvp_frame_add_frame_nc (kvp_into, intopath, fr);
00200 fr = gnc_kvp_bag_get_first (kvp_from, frompath);
00201 }
00202 }
00203
00204
00205
00206
00207
00208
00209 static void
00210 kv_pair_helper(gpointer key, gpointer val, gpointer user_data)
00211 {
00212 GSList **result = (GSList **) user_data;
00213 GHashTableKVPair *kvp = g_new(GHashTableKVPair, 1);
00214
00215 kvp->key = key;
00216 kvp->value = val;
00217 *result = g_slist_prepend(*result, kvp);
00218 }
00219
00220 GSList *
00221 g_hash_table_key_value_pairs(GHashTable *table)
00222 {
00223 GSList *result_list = NULL;
00224 g_hash_table_foreach(table, kv_pair_helper, &result_list);
00225 return result_list;
00226 }
00227
00228 void
00229 g_hash_table_kv_pair_free_gfunc(gpointer data, gpointer user_data)
00230 {
00231 GHashTableKVPair *kvp = (GHashTableKVPair *) data;
00232 g_free(kvp);
00233 }
00234
00235