GnuCash  2.6.17
Files | Data Structures | Macros | Enumerations | Functions
KVP: Key-Value Pairs

Files

file  kvp-util-p.h
 misc odd-job kvp utils engine-private routines
 
file  kvp-util.h
 QOF KVP utility functions.
 
file  kvp_frame.h
 A key-value frame system.
 

Data Structures

struct  GHashTableKVPair
 

Macros

#define QOF_MOD_KVP   "qof.kvp"
 
#define kvp_frame   KvpFrame
 
#define kvp_value   KvpValue
 
#define kvp_value_t   KvpValueType
 

Enumerations

enum  KvpValueType {
  KVP_TYPE_GINT64 = 1, KVP_TYPE_DOUBLE, KVP_TYPE_NUMERIC, KVP_TYPE_STRING,
  KVP_TYPE_GUID, KVP_TYPE_TIMESPEC, KVP_TYPE_BINARY, KVP_TYPE_GLIST,
  KVP_TYPE_FRAME, KVP_TYPE_GDATE
}
 possible types in the union KvpValue More...
 

Functions

gchar * kvp_value_to_string (const KvpValue *val)
 Debug version of kvp_value_to_string. More...
 
gboolean kvp_value_binary_append (KvpValue *v, void *data, guint64 size)
 
gchar * kvp_frame_to_string (const KvpFrame *frame)
 
gchar * binary_to_string (const void *data, guint32 size)
 
GHashTable * kvp_frame_get_hash (const KvpFrame *frame)
 

KvpBag Bags of GncGUID Pointers

KvpFrame * gnc_kvp_bag_add (KvpFrame *kvp_root, const char *path, time64 secs, const char *first_name,...)
 
void gnc_kvp_bag_merge (KvpFrame *kvp_into, const char *intopath, KvpFrame *kvp_from, const char *frompath)
 
KvpFrame * gnc_kvp_bag_find_by_guid (KvpFrame *root, const char *path, const char *guid_name, const GncGUID *desired_guid)
 
void gnc_kvp_bag_remove_frame (KvpFrame *root, const char *path, KvpFrame *fr)
 

Hash Utilities

GSList * g_hash_table_key_value_pairs (GHashTable *table)
 
void g_hash_table_kv_pair_free_gfunc (gpointer data, gpointer user_data)
 

KvpFrame Constructors

KvpFrame * kvp_frame_new (void)
 
void kvp_frame_delete (KvpFrame *frame)
 
KvpFrame * kvp_frame_copy (const KvpFrame *frame)
 
gboolean kvp_frame_is_empty (const KvpFrame *frame)
 

KvpFrame Basic Value Storing

void kvp_frame_set_gint64 (KvpFrame *frame, const gchar *path, gint64 ival)
 
void kvp_frame_set_double (KvpFrame *frame, const gchar *path, double dval)
 
void kvp_frame_set_numeric (KvpFrame *frame, const gchar *path, gnc_numeric nval)
 
void kvp_frame_set_timespec (KvpFrame *frame, const gchar *path, Timespec ts)
 
void kvp_frame_set_string (KvpFrame *frame, const gchar *path, const gchar *str)
 Store a copy of the string at the indicated path. More...
 
void kvp_frame_set_guid (KvpFrame *frame, const gchar *path, const GncGUID *guid)
 
void kvp_frame_set_frame (KvpFrame *frame, const gchar *path, KvpFrame *chld)
 
void kvp_frame_set_frame_nc (KvpFrame *frame, const gchar *path, KvpFrame *chld)
 
KvpFrame * kvp_frame_set_value (KvpFrame *frame, const gchar *path, const KvpValue *value)
 
KvpFrame * kvp_frame_set_value_nc (KvpFrame *frame, const gchar *path, KvpValue *value)
 
KvpValue * kvp_frame_replace_value_nc (KvpFrame *frame, const gchar *slot, KvpValue *new_value)
 
#define kvp_frame_set_gnc_numeric   kvp_frame_set_numeric
 
#define kvp_frame_set_str   kvp_frame_set_string
 

KvpFrame Glist Bag Storing

void kvp_frame_add_frame_nc (KvpFrame *frame, const gchar *path, KvpFrame *chld)
 Store the given kvp_frame to the glist bag at the indicated path (non-copying) More...
 

KvpFrame Value Fetching

Value accessors. These all take a unix-style slash-separated path as an argument, and return the value stored at that location. If the object at the end of that path is not of the type that was asked for, then a NULL or a zero is returned. So, for example, asking for a string when the path stored an int will return a NULL. In some future date, this may be changed to a looser type system, such as perl's automatic re-typing (e.g. an integer value might be converted to a printed string representing that value).

If any part of the path does not exist, then NULL or zero will be returned.

The values returned for GncGUID, binary, GList, KvpFrame and string are "non-copying" – the returned item is the actual item stored. Do not delete this item unless you take the required care to avoid possible bad pointer derefrences (i.e. core dumps). Also, be careful hanging on to those references if you are also storing at the same path names: the referenced item will be freed during the store.

That is, if you get a string value (or guid, binary or frame), and then store something else at that path, the string that you've gotten will be freed during the store (internally, by the set_*() routines), and you will be left hanging onto an invalid pointer.

gint64 kvp_frame_get_gint64 (const KvpFrame *frame, const gchar *path)
 
double kvp_frame_get_double (const KvpFrame *frame, const gchar *path)
 
gnc_numeric kvp_frame_get_numeric (const KvpFrame *frame, const gchar *path)
 
const gchar * kvp_frame_get_string (const KvpFrame *frame, const gchar *path)
 
GncGUIDkvp_frame_get_guid (const KvpFrame *frame, const gchar *path)
 
Timespec kvp_frame_get_timespec (const KvpFrame *frame, const gchar *path)
 
KvpValue * kvp_frame_get_value (const KvpFrame *frame, const gchar *path)
 
KvpFrame * kvp_frame_get_frame (const KvpFrame *frame, const gchar *path)
 
KvpFrame * kvp_frame_get_frame_slash (KvpFrame *frame, const gchar *path)
 

KvpFrame KvpValue low-level storing routines.

You probably shouldn't be using these low-level routines

All of the kvp_frame_set_slot_*() routines set the slot values "destructively", in that if there was an old value there, that old value is destroyed (and the memory freed). Thus, one should not hang on to value pointers, as these will get trashed if set_slot is called on the corresponding key.

If you want the old value, use kvp_frame_replace_slot().

void kvp_frame_set_slot (KvpFrame *frame, const gchar *key, const KvpValue *value)
 
void kvp_frame_set_slot_nc (KvpFrame *frame, const gchar *key, KvpValue *value)
 
void kvp_frame_set_slot_path (KvpFrame *frame, const KvpValue *value, const gchar *first_key,...)
 
void kvp_frame_set_slot_path_gslist (KvpFrame *frame, const KvpValue *value, GSList *key_path)
 

KvpFrame KvpValue Low-Level Retrieval Routines

You probably shouldn't be using these low-level routines

Returns the KvpValue in the given KvpFrame 'frame' that is associated with 'key'. If there is no key in the frame, NULL is returned. If the value associated with the key is NULL, NULL is returned.

Pointers passed as arguments into get_slot are the responsibility of the caller. Pointers returned by get_slot are owned by the kvp_frame. Make copies as needed.

KvpValue * kvp_frame_get_slot (const KvpFrame *frame, const gchar *key)
 
KvpValue * kvp_frame_get_slot_path (KvpFrame *frame, const gchar *first_key,...)
 
KvpValue * kvp_frame_get_slot_path_gslist (KvpFrame *frame, const GSList *key_path)
 
gint kvp_frame_compare (const KvpFrame *fa, const KvpFrame *fb)
 
gint double_compare (double v1, double v2)
 

KvpValue List Convenience Functions

You probably shouldn't be using these low-level routines

kvp_glist_compare() compares GLists of kvp_values (not to be confused with GLists of something else): it iterates over the list elements, performing a kvp_value_compare on each.

gint kvp_glist_compare (const GList *list1, const GList *list2)
 
GList * kvp_glist_copy (const GList *list)
 
void kvp_glist_delete (GList *list)
 

KvpValue Constructors

You probably shouldn't be using these low-level routines

The following routines are constructors for kvp_value. Those with pointer arguments copy in the value. The *_nc() versions do not copy in thier values, but use them directly.

KvpValue * kvp_value_new_gint64 (gint64 value)
 
KvpValue * kvp_value_new_double (double value)
 
KvpValue * kvp_value_new_numeric (gnc_numeric value)
 
KvpValue * kvp_value_new_string (const gchar *value)
 
KvpValue * kvp_value_new_guid (const GncGUID *guid)
 
KvpValue * kvp_value_new_timespec (Timespec timespec)
 
KvpValue * kvp_value_new_binary (const void *data, guint64 datasize)
 
KvpValue * kvp_value_new_frame (const KvpFrame *value)
 
KvpValue * kvp_value_new_gdate (GDate date)
 
KvpValue * kvp_value_new_glist (const GList *value)
 
KvpValue * kvp_value_new_binary_nc (void *data, guint64 datasize)
 
KvpValue * kvp_value_new_glist_nc (GList *lst)
 
KvpValue * kvp_value_new_frame_nc (KvpFrame *value)
 
void kvp_value_delete (KvpValue *value)
 
KvpValue * kvp_value_copy (const KvpValue *value)
 
KvpFrame * kvp_value_replace_frame_nc (KvpValue *value, KvpFrame *newframe)
 
GList * kvp_value_replace_glist_nc (KvpValue *value, GList *newlist)
 
#define kvp_value_new_gnc_numeric   kvp_value_new_numeric
 

KvpValue Value access

You probably shouldn't be using these low-level routines

KvpValueType kvp_value_get_type (const KvpValue *value)
 
gint64 kvp_value_get_gint64 (const KvpValue *value)
 
double kvp_value_get_double (const KvpValue *value)
 
gnc_numeric kvp_value_get_numeric (const KvpValue *value)
 
char * kvp_value_get_string (const KvpValue *value)
 
GncGUIDkvp_value_get_guid (const KvpValue *value)
 
void * kvp_value_get_binary (const KvpValue *value, guint64 *size_return)
 
GList * kvp_value_get_glist (const KvpValue *value)
 
KvpFrame * kvp_value_get_frame (const KvpValue *value)
 
Timespec kvp_value_get_timespec (const KvpValue *value)
 
GDate kvp_value_get_gdate (const KvpValue *value)
 
gint kvp_value_compare (const KvpValue *va, const KvpValue *vb)
 

Iterators

void kvp_frame_for_each_slot (KvpFrame *f, void(*proc)(const gchar *key, KvpValue *value, gpointer data), gpointer data)
 

Detailed Description

A KvpFrame is a set of associations between character strings (keys) and KvpValue structures. A KvpValue is a union with possible types enumerated in the KvpValueType enum, and includes, among other things, ints, doubles, strings, guid's, lists, time and numeric values. KvpValues may also be other frames, so KVP is inherently hierarchical.

Values are stored in a 'slot' associated with a key. Pointers passed as arguments into set_slot and get_slot are the responsibility of the caller. Pointers returned by get_slot are owned by the kvp_frame. Make copies as needed.

A 'path' is a sequence of keys that can be followed to a value. Paths may be specified as varargs (variable number of arguments to a subrutine, NULL-terminated), as a GSList, or as a standard URL-like path name. The later is parsed and treated in the same way as file paths would be: / separates keys, /./ is treated as / and /../ means backup one level. Repeated slashes are treated as one slash.

Note that although, in principle, keys may contain the / and . and .. characters, doing so may lead to confusion, and will make path-string parsing routines fail. In other words, don't use a key such as 'some/key' or 'some/./other/../key' because you may get unexpected results.

To set a value into a frame, you will want to use one of the kvp_frame_set_xxx() routines. Most of the other routines provide only low-level access that you probably shouldn't use.

Macro Definition Documentation

◆ kvp_frame

#define kvp_frame   KvpFrame
Deprecated:
Deprecated backwards compat token

do not use these in new code.

Definition at line 106 of file kvp_frame.h.

◆ kvp_frame_set_gnc_numeric

#define kvp_frame_set_gnc_numeric   kvp_frame_set_numeric
Deprecated:

Use kvp_frame_set_numeric instead of kvp_frame_set_gnc_numeric

Definition at line 156 of file kvp_frame.h.

◆ kvp_frame_set_str

#define kvp_frame_set_str   kvp_frame_set_string
Deprecated:

Use kvp_frame_set_string instead of kvp_frame_set_str

Definition at line 174 of file kvp_frame.h.

◆ kvp_value

#define kvp_value   KvpValue
Deprecated:
Deprecated backwards compat token

Definition at line 108 of file kvp_frame.h.

◆ kvp_value_new_gnc_numeric

#define kvp_value_new_gnc_numeric   kvp_value_new_numeric
Deprecated:

Use kvp_value_new_numeric instead of kvp_value_new_gnc_numeric

Definition at line 458 of file kvp_frame.h.

◆ kvp_value_t

#define kvp_value_t   KvpValueType
Deprecated:
Deprecated backwards compat token

Definition at line 110 of file kvp_frame.h.

Enumeration Type Documentation

◆ KvpValueType

possible types in the union KvpValue

Todo:
: People have asked for boolean values, e.g. in xaccAccountSetAutoInterestXfer
Todo:
In the long run, this should be synchronized with the core QOF types, which in turn should be synced to the g_types in GLib. Unfortunately, this requires writing a pile of code to handle all of the different cases. An alternative might be to make kvp values inherit from the core g_types (i.e. add new core g_types) ??
Enumerator
KVP_TYPE_GINT64 

QOF_TYPE_INT64 gint64

KVP_TYPE_DOUBLE 

QOF_TYPE_DOUBLE gdouble

KVP_TYPE_NUMERIC 

QOF_TYPE_NUMERIC

KVP_TYPE_STRING 

QOF_TYPE_STRING gchar*

KVP_TYPE_GUID 

QOF_TYPE_GUID

KVP_TYPE_TIMESPEC 

QOF_TYPE_DATE

KVP_TYPE_BINARY 

no QOF equivalent.

KVP_TYPE_GLIST 

no QOF equivalent.

KVP_TYPE_FRAME 

no QOF equivalent.

KVP_TYPE_GDATE 

no QOF equivalent.

Definition at line 88 of file kvp_frame.h.

Function Documentation

◆ g_hash_table_key_value_pairs()

GSList* g_hash_table_key_value_pairs ( GHashTable *  table)

Returns a GSList* of all the keys and values in a given hash table. Data elements of lists are actual hash elements, so be careful, and deallocation of the GHashTableKVPairs in the result list are the caller's responsibility. A typical sequence might look like this:

GSList *kvps = g_hash_table_key_value_pairs(hash); ... use kvps->data->key and kvps->data->val, etc. here ... g_slist_foreach(kvps, g_hash_table_kv_pair_free_gfunc, NULL); g_slist_free(kvps);

Definition at line 221 of file kvp-util.c.

222 {
223  GSList *result_list = NULL;
224  g_hash_table_foreach(table, kv_pair_helper, &result_list);
225  return result_list;
226 }

◆ gnc_kvp_bag_add()

KvpFrame* gnc_kvp_bag_add ( KvpFrame *  kvp_root,
const char *  path,
time64  secs,
const char *  first_name,
  ... 
)

The gnc_kvp_bag_add() routine is used to maintain a collection of pointers in a kvp tree.

The thing being pointed at is uniquely identified by its GncGUID. This routine is typically used to create a linked list, and/or a collection of pointers to objects that are 'related' to each other in some way.

The var-args should be pairs of strings (const char *) followed by the corresponding GncGUID pointer (const GncGUID *). Terminate the varargs with a NULL as the last string argument.

The actual 'pointer' is stored in a subdirectory in a bag located at the node directory 'path'. A 'bag' is merely a collection of (unamed) values. The name of our bag is 'path'. A bag can contain any kind of values, including frames. This routine will create a frame, and put it in the bag. The frame will contain named data from the subroutine arguments. Thus, for example:

gnc_kvp_array (kvp, "foo", secs, "acct_guid", aguid, "book_guid", bguid, NULL);

will create a frame containing "/acct_guid" and "/book_guid", whose values are aguid and bguid respecitvely. The frame will also contain "/date", whose value will be secs. This frame will be placed into the bag located at "foo".

This routine returns a pointer to the frame that was created, or NULL if an error occured.

Definition at line 74 of file kvp-util.c.

76 {
77  KvpFrame *cwd;
78  va_list ap;
79  va_start (ap, first_name);
80  cwd = gnc_kvp_array_va (pwd, path, secs, first_name, ap);
81  va_end (ap);
82  return cwd;
83 }

◆ gnc_kvp_bag_find_by_guid()

KvpFrame* gnc_kvp_bag_find_by_guid ( KvpFrame *  root,
const char *  path,
const char *  guid_name,
const GncGUID desired_guid 
)

The gnc_kvp_bag_find_by_guid() routine examines the bag pointed located at root. It looks for a frame in that bag that has the guid value of "desired_guid" filed under the key name "guid_name". If it finds that matching guid, then it returns a pointer to the KVP frame that contains it. If it is not found, or if there is any other error, NULL is returned.

Definition at line 96 of file kvp-util.c.

98 {
99  KvpValue *arr;
100  KvpValueType valtype;
101  GList *node;
102 
103  arr = kvp_frame_get_value (root, path);
104  valtype = kvp_value_get_type (arr);
105  if (KVP_TYPE_FRAME == valtype)
106  {
107  MATCH_GUID (arr);
108  return NULL;
109  }
110 
111  /* Its gotta be a single isolated frame, or a list of them. */
112  if (KVP_TYPE_GLIST != valtype) return NULL;
113 
114  for (node = kvp_value_get_glist(arr); node; node = node->next)
115  {
116  KvpValue *va = node->data;
117  MATCH_GUID (va);
118  }
119  return NULL;
120 }
KvpValueType
possible types in the union KvpValue
Definition: kvp_frame.h:88
GList * kvp_value_get_glist(const KvpValue *value)
Definition: kvp_frame.c:1223

◆ gnc_kvp_bag_merge()

void gnc_kvp_bag_merge ( KvpFrame *  kvp_into,
const char *  intopath,
KvpFrame *  kvp_from,
const char *  frompath 
)

The gnc_kvp_bag_merge() routine will move the bag contents from the 'kvp_from', to the 'into' bag. It will then delete the 'from' bag from the kvp tree.

Definition at line 190 of file kvp-util.c.

192 {
193  KvpFrame *fr;
194 
195  fr = gnc_kvp_bag_get_first (kvp_from, frompath);
196  while (fr)
197  {
198  gnc_kvp_bag_remove_frame (kvp_from, frompath, fr);
199  kvp_frame_add_frame_nc (kvp_into, intopath, fr);
200  fr = gnc_kvp_bag_get_first (kvp_from, frompath);
201  }
202 }
void kvp_frame_add_frame_nc(KvpFrame *frame, const gchar *path, KvpFrame *chld)
Store the given kvp_frame to the glist bag at the indicated path (non-copying)
void gnc_kvp_bag_remove_frame(KvpFrame *root, const char *path, KvpFrame *fr)
Definition: kvp-util.c:125

◆ gnc_kvp_bag_remove_frame()

void gnc_kvp_bag_remove_frame ( KvpFrame *  root,
const char *  path,
KvpFrame *  fr 
)

Remove the given frame from the bag. The frame is removed, however, it is not deleted. Note that the frame pointer must be a pointer to the actual frame (for example, as returned by gnc_kvp_bag_find_by_guid() for by gnc_kvp_bag_add()), and not some copy of the frame.

Definition at line 125 of file kvp-util.c.

126 {
127  KvpValue *arr;
128  KvpValueType valtype;
129  GList *node, *listhead;
130 
131  arr = kvp_frame_get_value (root, path);
132  valtype = kvp_value_get_type (arr);
133  if (KVP_TYPE_FRAME == valtype)
134  {
135  if (fr == kvp_value_get_frame (arr))
136  {
137  KvpValue *old_val = kvp_frame_replace_value_nc (root, path, NULL);
138  kvp_value_replace_frame_nc (old_val, NULL);
139  kvp_value_delete (old_val);
140  }
141  return;
142  }
143 
144  /* Its gotta be a single isolated frame, or a list of them. */
145  if (KVP_TYPE_GLIST != valtype) return;
146 
147  listhead = kvp_value_get_glist(arr);
148  for (node = listhead; node; node = node->next)
149  {
150  KvpValue *va = node->data;
151  if (fr == kvp_value_get_frame (va))
152  {
153  listhead = g_list_remove_link (listhead, node);
154  g_list_free_1 (node);
155  kvp_value_replace_glist_nc (arr, listhead);
156  kvp_value_replace_frame_nc (va, NULL);
157  kvp_value_delete (va);
158  return;
159  }
160  }
161 }
GList * kvp_value_replace_glist_nc(KvpValue *value, GList *newlist)
Definition: kvp_frame.c:1263
KvpValueType
possible types in the union KvpValue
Definition: kvp_frame.h:88
KvpValue * kvp_frame_replace_value_nc(KvpFrame *frame, const gchar *slot, KvpValue *new_value)
GList * kvp_value_get_glist(const KvpValue *value)
Definition: kvp_frame.c:1223
KvpFrame * kvp_value_replace_frame_nc(KvpValue *value, KvpFrame *newframe)
Definition: kvp_frame.c:1251
KvpFrame * kvp_value_get_frame(const KvpValue *value)
Definition: kvp_frame.c:1237
void kvp_value_delete(KvpValue *value)
Definition: kvp_frame.c:1064

◆ kvp_frame_add_frame_nc()

void kvp_frame_add_frame_nc ( KvpFrame *  frame,
const gchar *  path,
KvpFrame *  chld 
)

Store the given kvp_frame to the glist bag at the indicated path (non-copying)

If not all frame components of the path exist, they are created. If there was another item previously stored at that path, then the path is converted to a bag, and the old value, along with the new value, is added to the bag.

This method does NOT copy the frame.

◆ kvp_frame_compare()

gint kvp_frame_compare ( const KvpFrame *  fa,
const KvpFrame *  fb 
)

Similar returns as strcmp.

Definition at line 1427 of file kvp_frame.c.

1428 {
1429  kvp_frame_cmp_status status;
1430 
1431  if (fa == fb) return 0;
1432  /* nothing is always less than something */
1433  if (!fa && fb) return -1;
1434  if (fa && !fb) return 1;
1435 
1436  /* nothing is always less than something */
1437  if (!fa->hash && fb->hash) return -1;
1438  if (fa->hash && !fb->hash) return 1;
1439 
1440  status.compare = 0;
1441  status.other_frame = (KvpFrame *) fb;
1442 
1443  kvp_frame_for_each_slot((KvpFrame *) fa, kvp_frame_compare_helper, &status);
1444 
1445  if (status.compare != 0)
1446  return status.compare;
1447 
1448  status.other_frame = (KvpFrame *) fa;
1449 
1450  kvp_frame_for_each_slot((KvpFrame *) fb, kvp_frame_compare_helper, &status);
1451 
1452  return(-status.compare);
1453 }
void kvp_frame_for_each_slot(KvpFrame *f, void(*proc)(const gchar *key, KvpValue *value, gpointer data), gpointer data)

◆ kvp_frame_copy()

KvpFrame* kvp_frame_copy ( const KvpFrame *  frame)

Perform a deep (recursive) value copy, copying the fraame, subframes, and the values as well.

Definition at line 151 of file kvp_frame.c.

152 {
153  KvpFrame * retval = kvp_frame_new();
154 
155  if (!frame) return retval;
156 
157  if (frame->hash)
158  {
159  if (!init_frame_body_if_needed(retval)) return(NULL);
160  g_hash_table_foreach(frame->hash,
161  & kvp_frame_copy_worker,
162  (gpointer)retval);
163  }
164  return retval;
165 }
KvpFrame * kvp_frame_new(void)
Definition: kvp_frame.c:99

◆ kvp_frame_delete()

void kvp_frame_delete ( KvpFrame *  frame)

Perform a deep (recursive) delete of the frame and any subframes.

kvp_frame_delete and kvp_value_delete are deep (recursive) deletes. kvp_frame_copy and kvp_value_copy are deep value copies.

Definition at line 116 of file kvp_frame.c.

117 {
118  if (!frame) return;
119 
120  if (frame->hash)
121  {
122  /* free any allocated resource for frame or its children */
123  g_hash_table_foreach(frame->hash, & kvp_frame_delete_worker,
124  (gpointer)frame);
125 
126  /* delete the hash table */
127  g_hash_table_destroy(frame->hash);
128  frame->hash = NULL;
129  }
130  g_free(frame);
131 }

◆ kvp_frame_for_each_slot()

void kvp_frame_for_each_slot ( KvpFrame *  f,
void(*)(const gchar *key, KvpValue *value, gpointer data)  proc,
gpointer  data 
)

Traverse all of the slots in the given kvp_frame. This function does not descend recursively to traverse any kvp_frames stored as slot values. You must handle that in proc, with a suitable recursive call if desired.

◆ kvp_frame_get_frame()

KvpFrame* kvp_frame_get_frame ( const KvpFrame *  frame,
const gchar *  path 
)

Value accessor. Takes a unix-style slash-separated path as an argument, and return the KvpFrame stored at that location. If the KvpFrame does not exist, then a NULL is returned.

Note
The semantics here have changed: In gnucash-1.8, if the KvpFrame did not exist, this function automatically created one and returned it. However, now this function will return NULL in this case and the caller has to create a KvpFrame on his own. The old functionality is now implemented by kvp_frame_get_frame_path(). This happened on 2003-09-14, revision 1.31. FIXME: Is it really a good idea to change the semantics of an existing function and move the old semantics to a new function??! It would save us a lot of trouble if the new semantics would have been available in a new function!
Returns
The KvpFrame at the specified path, or NULL if it doesn't exist.

◆ kvp_frame_get_slot_path()

KvpValue* kvp_frame_get_slot_path ( KvpFrame *  frame,
const gchar *  first_key,
  ... 
)

This routine return the value at the end of the path, or NULL if any portion of the path doesn't exist.

◆ kvp_frame_get_slot_path_gslist()

KvpValue* kvp_frame_get_slot_path_gslist ( KvpFrame *  frame,
const GSList *  key_path 
)

This routine return the value at the end of the path, or NULL if any portion of the path doesn't exist.

Definition at line 820 of file kvp_frame.c.

822 {
823  if (!frame || !key_path) return NULL;
824 
825  while (TRUE)
826  {
827  const char *key = key_path->data;
828  KvpValue *value;
829 
830  if (!key) break;
831 
832  value = kvp_frame_get_slot (frame, key);
833  if (!value) break;
834 
835  key_path = key_path->next;
836  if (!key_path) return value;
837 
838  frame = kvp_value_get_frame (value);
839  if (!frame) break;
840  }
841  return NULL;
842 }
KvpFrame * kvp_value_get_frame(const KvpValue *value)
Definition: kvp_frame.c:1237

◆ kvp_frame_is_empty()

gboolean kvp_frame_is_empty ( const KvpFrame *  frame)

Return TRUE if the KvpFrame is empty

Definition at line 134 of file kvp_frame.c.

135 {
136  if (!frame) return TRUE;
137  if (!frame->hash) return TRUE;
138  return FALSE;
139 }

◆ kvp_frame_new()

KvpFrame* kvp_frame_new ( void  )

Return a new empty instance of KvpFrame

Definition at line 99 of file kvp_frame.c.

100 {
101  KvpFrame * retval = g_new0(KvpFrame, 1);
102 
103  /* Save space until the frame is actually used */
104  retval->hash = NULL;
105  return retval;
106 }

◆ kvp_frame_replace_value_nc()

KvpValue* kvp_frame_replace_value_nc ( KvpFrame *  frame,
const gchar *  slot,
KvpValue *  new_value 
)

The kvp_frame_replace_value_nc() routine places the new value at the indicated path. It returns the old value, if any. It returns NULL if there was an error, or if there was no old value. If the path doesn't exist, it is created, unless new_value is NULL. Passing in a NULL new_value has the effect of deleting the trailing slot (i.e. the trailing path element).

◆ kvp_frame_set_double()

void kvp_frame_set_double ( KvpFrame *  frame,
const gchar *  path,
double  dval 
)

store the value of the double at the indicated path. If not all frame components of the path exist, they are created.

◆ kvp_frame_set_gint64()

void kvp_frame_set_gint64 ( KvpFrame *  frame,
const gchar *  path,
gint64  ival 
)

store the value of the gint64 at the indicated path. If not all frame components of the path exist, they are created.

◆ kvp_frame_set_numeric()

void kvp_frame_set_numeric ( KvpFrame *  frame,
const gchar *  path,
gnc_numeric  nval 
)

store the value of the gnc_numeric at the indicated path. If not all frame components of the path exist, they are created.

◆ kvp_frame_set_slot()

void kvp_frame_set_slot ( KvpFrame *  frame,
const gchar *  key,
const KvpValue *  value 
)

The kvp_frame_replace_slot_nc() routine places the new value into the indicated frame, for the given key. It returns the old value, if any. It returns NULL if the slot doesn't exist, if there was some other an error, or if there was no old value. Passing in a NULL new_value has the effect of deleting that slot.The kvp_frame_set_slot() routine copies the value into the frame, associating it with a copy of 'key'. Pointers passed as arguments into kvp_frame_set_slot are the responsibility of the caller; the pointers are not taken over or managed. The old value at this location, if any, is destroyed.

◆ kvp_frame_set_slot_nc()

void kvp_frame_set_slot_nc ( KvpFrame *  frame,
const gchar *  key,
KvpValue *  value 
)

The kvp_frame_set_slot_nc() routine puts the value (without copying it) into the frame, associating it with a copy of 'key'. This routine is handy for avoiding excess memory allocations & frees. Note that because the KvpValue was grabbed, you can't just delete unless you remove the key as well (or unless you replace the value). The old value at this location, if any, is destroyed.

◆ kvp_frame_set_slot_path()

void kvp_frame_set_slot_path ( KvpFrame *  frame,
const KvpValue *  value,
const gchar *  first_key,
  ... 
)

The kvp_frame_set_slot_path() routine walks the hierarchy, using the key values to pick each branch. When the terminal node is reached, the value is copied into it. The old value at this location, if any, is destroyed.

◆ kvp_frame_set_slot_path_gslist()

void kvp_frame_set_slot_path_gslist ( KvpFrame *  frame,
const KvpValue *  value,
GSList *  key_path 
)

The kvp_frame_set_slot_path_gslist() routine walks the hierarchy, using the key values to pick each branch. When the terminal node is reached, the value is copied into it. The old value at this location, if any, is destroyed.

Definition at line 662 of file kvp_frame.c.

665 {
666  if (!frame || !key_path) return;
667 
668  while (TRUE)
669  {
670  const char *key = key_path->data;
671  KvpValue *value;
672 
673  if (!key)
674  return;
675 
676  g_return_if_fail (*key != '\0');
677 
678  key_path = key_path->next;
679  if (!key_path)
680  {
681  kvp_frame_set_slot (frame, key, new_value);
682  return;
683  }
684 
685  value = kvp_frame_get_slot (frame, key);
686  if (!value)
687  {
688  KvpFrame *new_frame = kvp_frame_new ();
689  KvpValue *frame_value = kvp_value_new_frame (new_frame);
690 
691  kvp_frame_set_slot_nc (frame, key, frame_value);
692 
693  value = kvp_frame_get_slot (frame, key);
694  if (!value)
695  return;
696  }
697 
698  frame = kvp_value_get_frame (value);
699  if (!frame)
700  return;
701  }
702 }
void kvp_frame_set_slot(KvpFrame *frame, const gchar *key, const KvpValue *value)
void kvp_frame_set_slot_nc(KvpFrame *frame, const gchar *key, KvpValue *value)
KvpFrame * kvp_frame_new(void)
Definition: kvp_frame.c:99
KvpFrame * kvp_value_get_frame(const KvpValue *value)
Definition: kvp_frame.c:1237

◆ kvp_frame_set_string()

void kvp_frame_set_string ( KvpFrame *  frame,
const gchar *  path,
const gchar *  str 
)

Store a copy of the string at the indicated path.

If not all frame components of the path exist, they are created. If there was another string previously stored at that path, the old copy is deleted.

Similarly, the set_guid and set_frame will make copies and store those. Old copies, if any, are deleted.

The kvp_frame_set_frame_nc() routine works as above, but does NOT copy the frame.

◆ kvp_frame_set_timespec()

void kvp_frame_set_timespec ( KvpFrame *  frame,
const gchar *  path,
Timespec  ts 
)

store the value of the Timespec at the indicated path. If not all frame components of the path exist, they are created.

◆ kvp_frame_set_value()

KvpFrame* kvp_frame_set_value ( KvpFrame *  frame,
const gchar *  path,
const KvpValue *  value 
)

The kvp_frame_set_value() routine copies the value into the frame, at the location 'path'. If the path contains slashes '/', these are assumed to represent a sequence of keys. The returned value is a pointer to the actual frame into which the value was inserted; it is NULL if the frame couldn't be found (and thus the value wasn't inserted). The old value at this location, if any, is destroyed.

Pointers passed as arguments into this routine are the responsibility of the caller; the pointers are not taken over or managed.

◆ kvp_frame_set_value_nc()

KvpFrame* kvp_frame_set_value_nc ( KvpFrame *  frame,
const gchar *  path,
KvpValue *  value 
)

The kvp_frame_set_value_nc() routine puts the value (without copying it) into the frame, putting it at the location 'path'. If the path contains slashes '/', these are assumed to represent a sequence of keys. The returned value is a pointer to the actual frame into which the value was inserted; it is NULL if the frame couldn't be found (and thus the value wasn't inserted). The old value at this location, if any, is destroyed.

This routine is handy for avoiding excess memory allocations & frees. Note that because the KvpValue was grabbed, you can't just delete unless you remove the key as well (or unless you replace the value).

◆ kvp_frame_to_string()

gchar* kvp_frame_to_string ( const KvpFrame *  frame)

Internal helper routines, you probably shouldn't be using these.

Definition at line 1620 of file kvp_frame.c.

1621 {
1622  gchar *tmp1;
1623 
1624  g_return_val_if_fail (frame != NULL, NULL);
1625 
1626  tmp1 = g_strdup_printf("{\n");
1627 
1628  if (frame->hash)
1629  g_hash_table_foreach(frame->hash, kvp_frame_to_string_helper, &tmp1);
1630 
1631  {
1632  gchar *tmp2;
1633  tmp2 = g_strdup_printf("%s}\n", tmp1);
1634  g_free(tmp1);
1635  tmp1 = tmp2;
1636  }
1637 
1638  return tmp1;
1639 }

◆ kvp_glist_copy()

GList* kvp_glist_copy ( const GList *  list)

kvp_glist_copy() performs a deep copy of a GList of kvp_values (not to be confused with GLists of something else): same as mapping kvp_value_copy() over the elements and then copying the spine.

Definition at line 866 of file kvp_frame.c.

867 {
868  GList * retval = NULL;
869  GList * lptr;
870 
871  if (!list) return retval;
872 
873  /* Duplicate the backbone of the list (this duplicates the POINTERS
874  * to the values; we need to deep-copy the values separately) */
875  retval = g_list_copy((GList *) list);
876 
877  /* This step deep-copies the values */
878  for (lptr = retval; lptr; lptr = lptr->next)
879  {
880  lptr->data = kvp_value_copy(lptr->data);
881  }
882 
883  return retval;
884 }
KvpValue * kvp_value_copy(const KvpValue *value)
Definition: kvp_frame.c:1277

◆ kvp_glist_delete()

void kvp_glist_delete ( GList *  list)

kvp_glist_delete() performs a deep delete of a GList of kvp_values (not to be confused with GLists of something else): same as mapping * kvp_value_delete() over the elements and then deleting the GList.

Definition at line 849 of file kvp_frame.c.

850 {
851  GList *node;
852  if (!list) return;
853 
854  /* Delete the data in the list */
855  for (node = list; node; node = node->next)
856  {
857  KvpValue *val = node->data;
858  kvp_value_delete(val);
859  }
860 
861  /* Free the backbone */
862  g_list_free(list);
863 }
void kvp_value_delete(KvpValue *value)
Definition: kvp_frame.c:1064

◆ kvp_value_binary_append()

gboolean kvp_value_binary_append ( KvpValue *  v,
void *  data,
guint64  size 
)

Manipulator:

copying - but more efficient than creating a new KvpValue manually.

◆ kvp_value_compare()

gint kvp_value_compare ( const KvpValue *  va,
const KvpValue *  vb 
)

Similar returns as strcmp.

Definition at line 1345 of file kvp_frame.c.

1346 {
1347  if (kva == kvb) return 0;
1348  /* nothing is always less than something */
1349  if (!kva && kvb) return -1;
1350  if (kva && !kvb) return 1;
1351 
1352  if (kva->type < kvb->type) return -1;
1353  if (kva->type > kvb->type) return 1;
1354 
1355  switch (kva->type)
1356  {
1357  case KVP_TYPE_GINT64:
1358  if (kva->value.int64 < kvb->value.int64) return -1;
1359  if (kva->value.int64 > kvb->value.int64) return 1;
1360  return 0;
1361  break;
1362  case KVP_TYPE_DOUBLE:
1363  return double_compare(kva->value.dbl, kvb->value.dbl);
1364  break;
1365  case KVP_TYPE_NUMERIC:
1366  return gnc_numeric_compare (kva->value.numeric, kvb->value.numeric);
1367  break;
1368  case KVP_TYPE_STRING:
1369  return strcmp(kva->value.str, kvb->value.str);
1370  break;
1371  case KVP_TYPE_GUID:
1372  return guid_compare(kva->value.guid, kvb->value.guid);
1373  break;
1374  case KVP_TYPE_TIMESPEC:
1375  return timespec_cmp(&(kva->value.timespec), &(kvb->value.timespec));
1376  break;
1377  case KVP_TYPE_GDATE:
1378  return g_date_compare(&(kva->value.gdate), &(kvb->value.gdate));
1379  break;
1380  case KVP_TYPE_BINARY:
1381  /* I don't know that this is a good compare. Ab is bigger than Acef.
1382  But I'm not sure that actually matters here. */
1383  if (kva->value.binary.datasize < kvb->value.binary.datasize) return -1;
1384  if (kva->value.binary.datasize > kvb->value.binary.datasize) return 1;
1385  return memcmp(kva->value.binary.data,
1386  kvb->value.binary.data,
1387  kva->value.binary.datasize);
1388  break;
1389  case KVP_TYPE_GLIST:
1390  return kvp_glist_compare(kva->value.list, kvb->value.list);
1391  break;
1392  case KVP_TYPE_FRAME:
1393  return kvp_frame_compare(kva->value.frame, kvb->value.frame);
1394  break;
1395  }
1396  PERR ("reached unreachable code.");
1397  return FALSE;
1398 }
gint kvp_frame_compare(const KvpFrame *fa, const KvpFrame *fb)
Definition: kvp_frame.c:1427
int gnc_numeric_compare(gnc_numeric a, gnc_numeric b)
Definition: gnc-numeric.c:246
#define PERR(format, args...)
Definition: qoflog.h:232
gint timespec_cmp(const Timespec *ta, const Timespec *tb)
Definition: gnc-date.c:593

◆ kvp_value_copy()

KvpValue* kvp_value_copy ( const KvpValue *  value)

This is a deep value copy.

Definition at line 1277 of file kvp_frame.c.

1278 {
1279  if (!value) return NULL;
1280 
1281  switch (value->type)
1282  {
1283  case KVP_TYPE_GINT64:
1284  return kvp_value_new_gint64(value->value.int64);
1285  break;
1286  case KVP_TYPE_DOUBLE:
1287  return kvp_value_new_double(value->value.dbl);
1288  break;
1289  case KVP_TYPE_NUMERIC:
1290  return kvp_value_new_gnc_numeric(value->value.numeric);
1291  break;
1292  case KVP_TYPE_STRING:
1293  return kvp_value_new_string(value->value.str);
1294  break;
1295  case KVP_TYPE_GUID:
1296  return kvp_value_new_guid(value->value.guid);
1297  break;
1298  case KVP_TYPE_GDATE:
1299  return kvp_value_new_gdate(value->value.gdate);
1300  break;
1301  case KVP_TYPE_TIMESPEC:
1302  return kvp_value_new_timespec(value->value.timespec);
1303  break;
1304  case KVP_TYPE_BINARY:
1305  return kvp_value_new_binary(value->value.binary.data,
1306  value->value.binary.datasize);
1307  break;
1308  case KVP_TYPE_GLIST:
1309  return kvp_value_new_glist(value->value.list);
1310  break;
1311  case KVP_TYPE_FRAME:
1312  return kvp_value_new_frame(value->value.frame);
1313  break;
1314  }
1315  return NULL;
1316 }
#define kvp_value_new_gnc_numeric
Definition: kvp_frame.h:458
KvpValue * kvp_value_new_glist(const GList *value)
Definition: kvp_frame.c:1016

◆ kvp_value_delete()

void kvp_value_delete ( KvpValue *  value)

This is a deep (recursive) delete.

Definition at line 1064 of file kvp_frame.c.

1065 {
1066  if (!value) return;
1067 
1068  switch (value->type)
1069  {
1070  case KVP_TYPE_STRING:
1071  g_free(value->value.str);
1072  break;
1073  case KVP_TYPE_GUID:
1074  g_free(value->value.guid);
1075  break;
1076  case KVP_TYPE_BINARY:
1077  g_free(value->value.binary.data);
1078  break;
1079  case KVP_TYPE_GLIST:
1080  kvp_glist_delete(value->value.list);
1081  break;
1082  case KVP_TYPE_FRAME:
1083  kvp_frame_delete(value->value.frame);
1084  break;
1085 
1086  case KVP_TYPE_GINT64:
1087  case KVP_TYPE_DOUBLE:
1088  case KVP_TYPE_NUMERIC:
1089  case KVP_TYPE_TIMESPEC:
1090  case KVP_TYPE_GDATE:
1091  break;
1092  }
1093  g_free(value);
1094 }
void kvp_frame_delete(KvpFrame *frame)
Definition: kvp_frame.c:116
void kvp_glist_delete(GList *list)
Definition: kvp_frame.c:849

◆ kvp_value_get_binary()

void* kvp_value_get_binary ( const KvpValue *  value,
guint64 *  size_return 
)

Value accessor. This one is non-copying – the caller can modify the value directly.

Definition at line 1199 of file kvp_frame.c.

1200 {
1201  if (!value)
1202  {
1203  if (size_return)
1204  *size_return = 0;
1205  return NULL;
1206  }
1207 
1208  if (value->type == KVP_TYPE_BINARY)
1209  {
1210  if (size_return)
1211  *size_return = value->value.binary.datasize;
1212  return value->value.binary.data;
1213  }
1214  else
1215  {
1216  if (size_return)
1217  *size_return = 0;
1218  return NULL;
1219  }
1220 }

◆ kvp_value_get_frame()

KvpFrame* kvp_value_get_frame ( const KvpValue *  value)

Value accessor. This one is non-copying – the caller can modify the value directly.

Definition at line 1237 of file kvp_frame.c.

1238 {
1239  if (!value) return NULL;
1240  if (value->type == KVP_TYPE_FRAME)
1241  {
1242  return value->value.frame;
1243  }
1244  else
1245  {
1246  return NULL;
1247  }
1248 }

◆ kvp_value_get_gdate()

GDate kvp_value_get_gdate ( const KvpValue *  value)

Value accessor for GDate

Definition at line 1187 of file kvp_frame.c.

1188 {
1189  GDate date;
1190  g_date_clear(&date, 1);
1191  if (!value) return date;
1192  if (value->type == KVP_TYPE_GDATE)
1193  return value->value.gdate;
1194  else
1195  return date;
1196 }

◆ kvp_value_get_gint64()

gint64 kvp_value_get_gint64 ( const KvpValue *  value)

Value accessors. Those for GncGUID, binary, GList, KvpFrame and string are non-copying – the caller can modify the value directly. Just don't free it, or you screw up everything. Note that if another value is stored at the key location that this value came from, then this value will be uncermoniously deleted, and you will be left pointing to garbage. So don't store values at the same time you are examining their contents.

Definition at line 1104 of file kvp_frame.c.

1105 {
1106  if (!value) return 0;
1107  if (value->type == KVP_TYPE_GINT64)
1108  {
1109  return value->value.int64;
1110  }
1111  else
1112  {
1113  return 0;
1114  }
1115 }

◆ kvp_value_get_glist()

GList* kvp_value_get_glist ( const KvpValue *  value)

Returns the GList of kvp_frame's (not to be confused with GList's of something else!) from the given kvp_frame. This one is non-copying – the caller can modify the value directly.

Definition at line 1223 of file kvp_frame.c.

1224 {
1225  if (!value) return NULL;
1226  if (value->type == KVP_TYPE_GLIST)
1227  {
1228  return value->value.list;
1229  }
1230  else
1231  {
1232  return NULL;
1233  }
1234 }

◆ kvp_value_get_guid()

GncGUID* kvp_value_get_guid ( const KvpValue *  value)

Value accessor. This one is non-copying – the caller can modify the value directly.

Definition at line 1160 of file kvp_frame.c.

1161 {
1162  if (!value) return NULL;
1163  if (value->type == KVP_TYPE_GUID)
1164  {
1165  return value->value.guid;
1166  }
1167  else
1168  {
1169  return NULL;
1170  }
1171 }

◆ kvp_value_get_string()

char* kvp_value_get_string ( const KvpValue *  value)

Value accessor. This one is non-copying – the caller can modify the value directly.

Definition at line 1146 of file kvp_frame.c.

1147 {
1148  if (!value) return NULL;
1149  if (value->type == KVP_TYPE_STRING)
1150  {
1151  return value->value.str;
1152  }
1153  else
1154  {
1155  return NULL;
1156  }
1157 }

◆ kvp_value_new_binary_nc()

KvpValue* kvp_value_new_binary_nc ( void *  data,
guint64  datasize 
)

value constructors (non-copying - KvpValue takes pointer ownership) values must have been allocated via glib allocators! (gnew, etc.)

Definition at line 1003 of file kvp_frame.c.

1004 {
1005  KvpValue * retval;
1006  if (!value) return NULL;
1007 
1008  retval = g_new0(KvpValue, 1);
1009  retval->type = KVP_TYPE_BINARY;
1010  retval->value.binary.data = value;
1011  retval->value.binary.datasize = datasize;
1012  return retval;
1013 }

◆ kvp_value_new_frame_nc()

KvpValue* kvp_value_new_frame_nc ( KvpFrame *  value)

value constructors (non-copying - KvpValue takes pointer ownership) values must have been allocated via glib allocators! (gnew, etc.)

Definition at line 1052 of file kvp_frame.c.

1053 {
1054  KvpValue * retval;
1055  if (!value) return NULL;
1056 
1057  retval = g_new0(KvpValue, 1);
1058  retval->type = KVP_TYPE_FRAME;
1059  retval->value.frame = value;
1060  return retval;
1061 }

◆ kvp_value_new_glist()

KvpValue* kvp_value_new_glist ( const GList *  value)

Creates a KvpValue from a GList of kvp_value's! (Not to be confused with GList's of something else!)

Definition at line 1016 of file kvp_frame.c.

1017 {
1018  KvpValue * retval;
1019  if (!value) return NULL;
1020 
1021  retval = g_new0(KvpValue, 1);
1022  retval->type = KVP_TYPE_GLIST;
1023  retval->value.list = kvp_glist_copy(value);
1024  return retval;
1025 }
GList * kvp_glist_copy(const GList *list)
Definition: kvp_frame.c:866

◆ kvp_value_new_glist_nc()

KvpValue* kvp_value_new_glist_nc ( GList *  lst)

Creates a KvpValue from a GList of kvp_value's! (Not to be confused with GList's of something else!)

This value constructor is non-copying (KvpValue takes pointer ownership). The values must have been allocated via glib allocators! (gnew, etc.)

Definition at line 1028 of file kvp_frame.c.

1029 {
1030  KvpValue * retval;
1031  if (!value) return NULL;
1032 
1033  retval = g_new0(KvpValue, 1);
1034  retval->type = KVP_TYPE_GLIST;
1035  retval->value.list = value;
1036  return retval;
1037 }

◆ kvp_value_replace_frame_nc()

KvpFrame* kvp_value_replace_frame_nc ( KvpValue *  value,
KvpFrame *  newframe 
)

Replace old frame value with new, return old frame

Definition at line 1251 of file kvp_frame.c.

1252 {
1253  KvpFrame *oldframe;
1254  if (!value) return NULL;
1255  if (KVP_TYPE_FRAME != value->type) return NULL;
1256 
1257  oldframe = value->value.frame;
1258  value->value.frame = newframe;
1259  return oldframe;
1260 }

◆ kvp_value_replace_glist_nc()

GList* kvp_value_replace_glist_nc ( KvpValue *  value,
GList *  newlist 
)

Replace old glist value with new, return old glist

Definition at line 1263 of file kvp_frame.c.

1264 {
1265  GList *oldlist;
1266  if (!value) return NULL;
1267  if (KVP_TYPE_GLIST != value->type) return NULL;
1268 
1269  oldlist = value->value.list;
1270  value->value.list = newlist;
1271  return oldlist;
1272 }

◆ kvp_value_to_string()

gchar* kvp_value_to_string ( const KvpValue *  val)

Debug version of kvp_value_to_string.

This version is used only by ::qof_query_printValueForParam, itself a debugging and development utility function.

Definition at line 1520 of file kvp_frame.c.

1521 {
1522  gchar *tmp1;
1523  gchar *tmp2;
1524  const gchar *ctmp;
1525 
1526  g_return_val_if_fail(val, NULL);
1527 
1528  switch (kvp_value_get_type(val))
1529  {
1530  case KVP_TYPE_GINT64:
1531  return g_strdup_printf("KVP_VALUE_GINT64(%" G_GINT64_FORMAT ")",
1532  kvp_value_get_gint64(val));
1533  break;
1534 
1535  case KVP_TYPE_DOUBLE:
1536  return g_strdup_printf("KVP_VALUE_DOUBLE(%g)",
1537  kvp_value_get_double(val));
1538  break;
1539 
1540  case KVP_TYPE_NUMERIC:
1541  tmp1 = gnc_numeric_to_string(kvp_value_get_numeric(val));
1542  tmp2 = g_strdup_printf("KVP_VALUE_NUMERIC(%s)", tmp1 ? tmp1 : "");
1543  g_free(tmp1);
1544  return tmp2;
1545  break;
1546 
1547  case KVP_TYPE_STRING:
1548  tmp1 = kvp_value_get_string (val);
1549  return g_strdup_printf("KVP_VALUE_STRING(%s)", tmp1 ? tmp1 : "");
1550  break;
1551 
1552  case KVP_TYPE_GUID:
1553  /* THREAD-UNSAFE */
1554  ctmp = guid_to_string(kvp_value_get_guid(val));
1555  tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", ctmp ? ctmp : "");
1556  return tmp2;
1557  break;
1558 
1559  case KVP_TYPE_TIMESPEC:
1560  tmp1 = g_new0 (char, 40);
1561  gnc_timespec_to_iso8601_buff (kvp_value_get_timespec (val), tmp1);
1562  tmp2 = g_strdup_printf("KVP_VALUE_TIMESPEC(%s)", tmp1);
1563  g_free(tmp1);
1564  return tmp2;
1565  break;
1566 
1567  case KVP_TYPE_BINARY:
1568  {
1569  guint64 len;
1570  void *data;
1571  data = kvp_value_get_binary(val, &len);
1572  tmp1 = binary_to_string(data, len);
1573  return g_strdup_printf("KVP_VALUE_BINARY(%s)", tmp1 ? tmp1 : "");
1574  }
1575  break;
1576 
1577  case KVP_TYPE_GLIST:
1578  tmp1 = kvp_value_glist_to_string(kvp_value_get_glist(val));
1579  tmp2 = g_strdup_printf("KVP_VALUE_GLIST(%s)", tmp1 ? tmp1 : "");
1580  g_free(tmp1);
1581  return tmp2;
1582  break;
1583 
1584  case KVP_TYPE_FRAME:
1586  tmp2 = g_strdup_printf("KVP_VALUE_FRAME(%s)", tmp1 ? tmp1 : "");
1587  g_free(tmp1);
1588  return tmp2;
1589  break;
1590 
1591  case KVP_TYPE_GDATE:
1592  return g_strdup_printf("KVP_VALUE_GDATE(%04d-%02d-%02d)",
1593  g_date_get_year(&val->value.gdate),
1594  g_date_get_month(&val->value.gdate),
1595  g_date_get_day(&val->value.gdate));
1596  }
1597  g_assert(FALSE); /* must not be reached */
1598  return g_strdup("");
1599 }
void * kvp_value_get_binary(const KvpValue *value, guint64 *size_return)
Definition: kvp_frame.c:1199
gchar * gnc_timespec_to_iso8601_buff(Timespec ts, gchar *buff)
gchar * gnc_numeric_to_string(gnc_numeric n)
Definition: gnc-numeric.c:1371
gint64 kvp_value_get_gint64(const KvpValue *value)
Definition: kvp_frame.c:1104
char * kvp_value_get_string(const KvpValue *value)
Definition: kvp_frame.c:1146
const char * guid_to_string(const GncGUID *guid)
Definition: guid.c:656
GList * kvp_value_get_glist(const KvpValue *value)
Definition: kvp_frame.c:1223
GncGUID * kvp_value_get_guid(const KvpValue *value)
Definition: kvp_frame.c:1160
gchar * kvp_frame_to_string(const KvpFrame *frame)
Definition: kvp_frame.c:1620
KvpFrame * kvp_value_get_frame(const KvpValue *value)
Definition: kvp_frame.c:1237