KVP: Key-Value Pairs
[Query Object Framework]


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.


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

KvpFrame Basic Value Storing

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

KvpFrame Glist Bag Storing

#define kvp_frame_add_gnc_numeric   kvp_frame_add_numeric
#define kvp_frame_add_str   kvp_frame_add_string
void kvp_frame_add_gint64 (KvpFrame *frame, const char *path, gint64 ival)
void kvp_frame_add_double (KvpFrame *frame, const char *path, double dval)
void kvp_frame_add_numeric (KvpFrame *frame, const char *path, gnc_numeric nval)
void kvp_frame_add_timespec (KvpFrame *frame, const char *path, Timespec ts)
void kvp_frame_add_string (KvpFrame *frame, const char *path, const char *str)
 Copy of the string to the glist bag at the indicated path.
void kvp_frame_add_guid (KvpFrame *frame, const char *path, const GUID *guid)
void kvp_frame_add_frame (KvpFrame *frame, const char *path, KvpFrame *chld)
void kvp_frame_add_frame_nc (KvpFrame *frame, const char *path, KvpFrame *chld)
KvpFramekvp_frame_add_value (KvpFrame *frame, const char *path, KvpValue *value)
KvpFramekvp_frame_add_value_nc (KvpFrame *frame, const char *path, KvpValue *value)

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.

#define kvp_value_new_gnc_numeric   kvp_value_new_numeric
KvpValuekvp_value_new_gint64 (gint64 value)
KvpValuekvp_value_new_double (double value)
KvpValuekvp_value_new_numeric (gnc_numeric value)
KvpValuekvp_value_new_string (const char *value)
KvpValuekvp_value_new_guid (const GUID *guid)
KvpValuekvp_value_new_timespec (Timespec timespec)
KvpValuekvp_value_new_binary (const void *data, guint64 datasize)
KvpValuekvp_value_new_frame (const KvpFrame *value)
KvpValuekvp_value_new_glist (const GList *value)
KvpValuekvp_value_new_binary_nc (void *data, guint64 datasize)
KvpValuekvp_value_new_glist_nc (GList *lst)
KvpValuekvp_value_new_frame_nc (KvpFrame *value)
void kvp_value_delete (KvpValue *value)
KvpValuekvp_value_copy (const KvpValue *value)
KvpFramekvp_value_replace_frame_nc (KvpValue *value, KvpFrame *newframe)
GList * kvp_value_replace_glist_nc (KvpValue *value, GList *newlist)

KvpBag Bags of GUID Pointers

KvpFramegnc_kvp_bag_add (KvpFrame *kvp_root, const char *path, time_t secs, const char *first_name,...)
void gnc_kvp_bag_merge (KvpFrame *kvp_into, const char *intopath, KvpFrame *kvp_from, const char *frompath)
KvpFramegnc_kvp_bag_find_by_guid (KvpFrame *root, const char *path, const char *guid_name, GUID *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

KvpFramekvp_frame_new (void)
void kvp_frame_delete (KvpFrame *frame)
KvpFramekvp_frame_copy (const KvpFrame *frame)
gboolean kvp_frame_is_empty (KvpFrame *frame)

KvpFrame URL handling

void kvp_frame_add_url_encoding (KvpFrame *frame, const char *enc)

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 GUID, 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 char *path)
double kvp_frame_get_double (const KvpFrame *frame, const char *path)
gnc_numeric kvp_frame_get_numeric (const KvpFrame *frame, const char *path)
char * kvp_frame_get_string (const KvpFrame *frame, const char *path)
GUIDkvp_frame_get_guid (const KvpFrame *frame, const char *path)
void * kvp_frame_get_binary (const KvpFrame *frame, const char *path, guint64 *size_return)
Timespec kvp_frame_get_timespec (const KvpFrame *frame, const char *path)
KvpValuekvp_frame_get_value (const KvpFrame *frame, const char *path)
KvpFramekvp_frame_get_frame (const KvpFrame *frame, const char *path)
KvpFramekvp_frame_get_frame_path (KvpFrame *frame, const char *,...)
KvpFramekvp_frame_get_frame_gslist (KvpFrame *frame, GSList *key_path)
KvpFramekvp_frame_get_frame_slash (KvpFrame *frame, const char *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().

KvpValuekvp_frame_replace_slot_nc (KvpFrame *frame, const char *slot, KvpValue *new_value)
void kvp_frame_set_slot (KvpFrame *frame, const char *key, const KvpValue *value)
void kvp_frame_set_slot_nc (KvpFrame *frame, const char *key, KvpValue *value)
void kvp_frame_set_slot_path (KvpFrame *frame, const KvpValue *value, const char *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.

KvpValuekvp_frame_get_slot (const KvpFrame *frame, const char *key)
KvpValuekvp_frame_get_slot_path (KvpFrame *frame, const char *first_key,...)
KvpValuekvp_frame_get_slot_path_gslist (KvpFrame *frame, 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 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)
GUIDkvp_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)
KvpFramekvp_value_get_frame (const KvpValue *value)
Timespec kvp_value_get_timespec (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 char *key, KvpValue *value, gpointer data), gpointer data)

Defines

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

Typedefs

typedef _KvpFrame KvpFrame
typedef _KvpValue KvpValue

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
}
 possible types in the union KvpValue More...

Functions

gchar * kvp_value_to_bare_string (const KvpValue *val)
 General purpose function to convert any KvpValue to a string.
gchar * kvp_value_to_string (const KvpValue *val)
 Debug version of kvp_value_to_string.
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)
gchar * kvp_value_glist_to_string (const GList *list)
GHashTable * kvp_frame_get_hash (const KvpFrame *frame)


Define Documentation

#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.

#define kvp_frame_add_gnc_numeric   kvp_frame_add_numeric
 

Deprecated:
Use kvp_frame_add_numeric instead of kvp_frame_add_gnc_numeric

Definition at line 272 of file kvp_frame.h.

#define kvp_frame_add_str   kvp_frame_add_string
 

Deprecated:
Use kvp_frame_add_string instead of kvp_frame_add_str

Definition at line 281 of file kvp_frame.h.

#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.

#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.

#define kvp_value   KvpValue
 

Deprecated:
Deprecated backwards compat token

Definition at line 108 of file kvp_frame.h.

#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 560 of file kvp_frame.h.

#define kvp_value_t   KvpValueType
 

Deprecated:
Deprecated backwards compat token

Definition at line 110 of file kvp_frame.h.


Typedef Documentation

typedef struct _KvpFrame KvpFrame
 

Opaque frame structure

Definition at line 73 of file kvp_frame.h.

typedef struct _KvpValue KvpValue
 

A KvpValue is a union with possible types enumerated in the KvpValueType enum.

Definition at line 77 of file kvp_frame.h.


Enumeration Type Documentation

enum 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.

Definition at line 90 of file kvp_frame.h.


Function Documentation

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.

00222 {
00223   GSList *result_list = NULL;
00224   g_hash_table_foreach(table, kv_pair_helper, &result_list);
00225   return result_list;
00226 }

KvpFrame* gnc_kvp_bag_add KvpFrame kvp_root,
const char *  path,
time_t  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 GUID. 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 GUID pointer (const GUID *). 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.

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 }

KvpFrame* gnc_kvp_bag_find_by_guid KvpFrame root,
const char *  path,
const char *  guid_name,
GUID 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.

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   /* Its gotta be a single isolated frame, or a list of them. */
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 }

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.

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 }

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.

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   /* Its gotta be a single isolated frame, or a list of them. */
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 }

void kvp_frame_add_gint64 KvpFrame frame,
const char *  path,
gint64  ival
 

The kvp_frame_add_gint64() routine will add the value of the gint64 to the glist bag of values at the indicated path. If not all frame components of the path exist, they are created. If the value previously stored at this path was not a glist bag, then a bag will be formed there, the old value placed in the bag, and the new value added to the bag.

Similarly, the add_double, add_numeric, and add_timespec routines perform the same function, for each of the respective types.

Definition at line 569 of file kvp_frame.c.

00570 {
00571   KvpValue *value;
00572   value = kvp_value_new_gint64 (ival);
00573   frame = kvp_frame_add_value_nc (frame, path, value);
00574   if (!frame) kvp_value_delete (value);
00575 }

void kvp_frame_add_string KvpFrame frame,
const char *  path,
const char *  str
 

Copy of the string to the glist bag at the indicated path.

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.

Similarly, the add_guid and add_frame will make copies and add those.

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

Definition at line 596 of file kvp_frame.c.

00597 {
00598   KvpValue *value;
00599   value = kvp_value_new_string (str);
00600   frame = kvp_frame_add_value_nc (frame, path, value);
00601   if (!frame) kvp_value_delete (value);
00602 }

void kvp_frame_add_url_encoding KvpFrame frame,
const char *  enc
 

The kvp_frame_add_url_encoding() routine will parse the value string, assuming it to be URL-encoded in the standard way, turning it into a set of key-value pairs, and adding those to the indicated frame. URL-encoded strings are the things that are returned by web browsers when a form is filled out. For example, 'start-date=June&end-date=November' consists of two keys, 'start-date' and 'end-date', which have the values 'June' and 'November', respectively. This routine also handles % encoding.

This routine treats all values as strings; it does *not* attempt to perform any type-conversion.

Definition at line 820 of file kvp_frame.c.

00821 {
00822         char *buff, *p;
00823         if (!frame || !enc) return;
00824 
00825         /* Loop over all key-value pairs in the encoded string */
00826         buff = g_strdup (enc);
00827         p = buff;
00828         while (*p)
00829         {
00830                 char *n, *v;
00831                 n = strchr (p, '&');  /* n = next key-value */
00832                 if (n) *n = 0x0;
00833 
00834                 v = strchr (p, '=');  /* v =  pointer to value */
00835                 if (!v) break;
00836                 *v = 0x0;
00837                 v ++;
00838                 
00839                 decode (p);
00840                 decode (v);
00841                 kvp_frame_set_slot_nc (frame, p, kvp_value_new_string(v));
00842 
00843                 if (!n) break; /* no next key, we are done */
00844                 p = ++n;
00845         }
00846         
00847         g_free(buff);
00848 }

gint kvp_frame_compare const KvpFrame fa,
const KvpFrame fb
 

Similar returns as strcmp.

Definition at line 1567 of file kvp_frame.c.

01568 {
01569   kvp_frame_cmp_status status;
01570 
01571   if(fa == fb) return 0;
01572   /* nothing is always less than something */
01573   if(!fa && fb) return -1;
01574   if(fa && !fb) return 1;
01575 
01576   /* nothing is always less than something */
01577   if(!fa->hash && fb->hash) return -1;
01578   if(fa->hash && !fb->hash) return 1;
01579 
01580   status.compare = 0;
01581   status.other_frame = (KvpFrame *) fb;
01582 
01583   kvp_frame_for_each_slot((KvpFrame *) fa, kvp_frame_compare_helper, &status);
01584 
01585   if (status.compare != 0)
01586     return status.compare;
01587 
01588   status.other_frame = (KvpFrame *) fa;
01589 
01590   kvp_frame_for_each_slot((KvpFrame *) fb, kvp_frame_compare_helper, &status);
01591 
01592   return(-status.compare);
01593 }

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 156 of file kvp_frame.c.

00157 {
00158   KvpFrame * retval = kvp_frame_new();
00159 
00160   if (!frame) return retval;
00161 
00162   if(frame->hash) 
00163   {
00164     if(!init_frame_body_if_needed(retval)) return(NULL);
00165     g_hash_table_foreach(frame->hash,
00166                          & kvp_frame_copy_worker, 
00167                          (gpointer)retval);
00168   }
00169   return retval;
00170 }

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 121 of file kvp_frame.c.

00122 {
00123   if (!frame) return;
00124 
00125   if(frame->hash) 
00126   {
00127     /* free any allocated resource for frame or its children */
00128     g_hash_table_foreach(frame->hash, & kvp_frame_delete_worker, 
00129                          (gpointer)frame);
00130     
00131     /* delete the hash table */
00132     g_hash_table_destroy(frame->hash);
00133     frame->hash = NULL;
00134   }
00135   g_free(frame);
00136 }

void kvp_frame_for_each_slot KvpFrame f,
void(*)(const char *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.

Definition at line 1471 of file kvp_frame.c.

01476 {
01477   if(!f) return;
01478   if(!proc) return;
01479   if(!(f->hash)) return;
01480 
01481   g_hash_table_foreach(f->hash, (GHFunc) proc, data);
01482 }

KvpFrame* kvp_frame_get_frame const KvpFrame frame,
const char *  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.

Definition at line 911 of file kvp_frame.c.

00912 {
00913   char *key = NULL;
00914   frame = get_trailer_or_null (frame, path, &key);
00915   return kvp_value_get_frame(kvp_frame_get_slot (frame, key));
00916 }

KvpFrame* kvp_frame_get_frame_gslist KvpFrame frame,
GSList *  key_path
 

This routine returns the last frame of the path. If the frame path doesn't exist, it is created. Note that this is *VERY DIFFERENT FROM* kvp_frame_get_frame()

Definition at line 929 of file kvp_frame.c.

00930 {
00931   if (!frame) return frame;
00932 
00933   while (key_path) 
00934   {
00935     const char *key = key_path->data;
00936 
00937     if (!key) return frame;  /* an unusual but valid exit for this routine. */
00938 
00939     frame = get_or_make (frame, key);
00940     if (!frame) return frame;  /* this should never happen */
00941 
00942     key_path = key_path->next;
00943   }
00944   return frame;  /* this is the normal exit for this func */
00945 }

KvpFrame* kvp_frame_get_frame_path KvpFrame frame,
const char *  ,
  ...
 

This routine returns the last frame of the path. If the frame path doesn't exist, it is created. Note that this is *VERY DIFFERENT FROM* like kvp_frame_get_frame()

Note:
The semantics of this function implemented the gnucash-1.8 behaviour of kvp_frame_get_frame: In gnucash-1.8, if the KvpFrame did not exist, kvp_frame_get_frame automatically created one and returned it. However, now that one will return NULL in this case and the caller has to create a KvpFrame on his own. The old functionality is implemented by this kvp_frame_get_frame_path(). This happened on 2003-09-14, revision 1.31.

Definition at line 948 of file kvp_frame.c.

00949 {
00950   va_list ap;
00951   if (!frame || !key) return frame;
00952 
00953   va_start (ap, key);
00954 
00955   while (key) 
00956   {
00957     frame = get_or_make (frame, key);
00958     if (!frame) break;     /* error, should never occur */
00959     key = va_arg (ap, const char *);
00960   }
00961 
00962   va_end (ap);
00963   return frame;
00964 }

KvpFrame* kvp_frame_get_frame_slash KvpFrame frame,
const char *  path
 

This routine returns the last frame of the path. If the frame path doesn't exist, it is created. Note that this is *VERY DIFFERENT FROM* kvp_frame_get_frame()

The kvp_frame_get_frame_slash() routine takes a single string where the keys are separated by slashes; thus, for example: /this/is/a/valid/path and///so//is////this/ Multiple slashes are compresed. Leading slash is optional. The pointers . and .. are *not* currently followed/obeyed. (This is a bug that needs fixing).

Definition at line 967 of file kvp_frame.c.

00968 {
00969   char *root;
00970   if (!frame || !key_path) return frame;
00971 
00972   root = g_strdup (key_path);
00973   frame = kvp_frame_get_frame_slash_trash (frame, root);
00974   g_free(root);
00975   return frame;
00976 }

KvpValue* kvp_frame_get_slot_path KvpFrame frame,
const char *  first_key,
  ...
 

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 981 of file kvp_frame.c.

00983 {
00984   va_list ap;
00985   KvpValue *value;
00986   const char *key;
00987 
00988   if (!frame || !first_key) return NULL;
00989 
00990   va_start (ap, first_key);
00991 
00992   key = first_key;
00993   value = NULL;
00994 
00995   while (TRUE) 
00996   {
00997     value = kvp_frame_get_slot (frame, key);
00998     if (!value) break;
00999 
01000     key = va_arg (ap, const char *);
01001     if (!key) break;
01002 
01003     frame = kvp_value_get_frame (value);
01004     if (!frame)
01005     {
01006       value = NULL;
01007       break;
01008     }
01009   }
01010 
01011   va_end (ap);
01012 
01013   return value;
01014 }

KvpValue* kvp_frame_get_slot_path_gslist KvpFrame frame,
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 1017 of file kvp_frame.c.

01019 {
01020   if (!frame || !key_path) return NULL;
01021 
01022   while (TRUE) 
01023   {
01024     const char *key = key_path->data;
01025     KvpValue *value;
01026 
01027     if (!key) return NULL;
01028 
01029     value = kvp_frame_get_slot (frame, key);
01030     if (!value) return NULL;
01031 
01032     key_path = key_path->next;
01033     if (!key_path) return value;
01034 
01035     frame = kvp_value_get_frame (value);
01036     if (!frame) return NULL;
01037   }
01038 }

gboolean kvp_frame_is_empty KvpFrame frame  ) 
 

Return TRUE if the KvpFrame is empty

Definition at line 139 of file kvp_frame.c.

00140 {
00141   if (!frame) return TRUE;
00142   if (!frame->hash) return TRUE;
00143   return FALSE;
00144 }

KvpFrame* kvp_frame_new void   ) 
 

Return a new empty instance of KvpFrame

Definition at line 104 of file kvp_frame.c.

00105 {
00106   KvpFrame * retval = g_new0(KvpFrame, 1);
00107 
00108   /* Save space until the frame is actually used */
00109   retval->hash = NULL;
00110   return retval;
00111 }

KvpValue* kvp_frame_replace_slot_nc KvpFrame frame,
const char *  slot,
KvpValue new_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.

Definition at line 177 of file kvp_frame.c.

00179 {
00180   gpointer orig_key;
00181   gpointer orig_value = NULL;
00182   int      key_exists;
00183 
00184   if (!frame || !slot) return NULL; 
00185   if (!init_frame_body_if_needed(frame)) return NULL; /* Error ... */
00186 
00187   key_exists = g_hash_table_lookup_extended(frame->hash, slot,
00188                                             & orig_key, & orig_value);
00189   if(key_exists) 
00190   {
00191     g_hash_table_remove(frame->hash, slot);
00192     gnc_string_cache_remove(orig_key);
00193   }
00194   else
00195   {
00196     orig_value = NULL;
00197   }
00198 
00199   if(new_value) 
00200   {
00201     g_hash_table_insert(frame->hash,
00202                         gnc_string_cache_insert((gpointer) slot),
00203                         new_value);
00204   }
00205 
00206   return (KvpValue *) orig_value;
00207 }

KvpValue* kvp_frame_replace_value_nc KvpFrame frame,
const char *  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).

Definition at line 494 of file kvp_frame.c.

00496 {
00497   KvpValue * old_value;
00498   char *last_key;
00499 
00500   last_key = NULL;
00501   if (new_value)
00502   {
00503      frame = get_trailer_make (frame, key_path, &last_key);
00504   }
00505   else
00506   {
00507      frame = (KvpFrame *) get_trailer_or_null (frame, key_path, &last_key);
00508   }
00509   if (!frame) return NULL;
00510 
00511   old_value = kvp_frame_replace_slot_nc (frame, last_key, new_value);
00512   return old_value;
00513 }

void kvp_frame_set_double KvpFrame frame,
const char *  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.

Definition at line 402 of file kvp_frame.c.

00403 {
00404   KvpValue *value;
00405   value = kvp_value_new_double (dval);
00406   frame = kvp_frame_set_value_nc (frame, path, value);
00407   if (!frame) kvp_value_delete (value);
00408 }

void kvp_frame_set_gint64 KvpFrame frame,
const char *  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.

Definition at line 393 of file kvp_frame.c.

00394 {
00395   KvpValue *value;
00396   value = kvp_value_new_gint64 (ival);
00397   frame = kvp_frame_set_value_nc (frame, path, value);
00398   if (!frame) kvp_value_delete (value);
00399 }

void kvp_frame_set_numeric KvpFrame frame,
const char *  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.

Definition at line 411 of file kvp_frame.c.

00412 {
00413   KvpValue *value;
00414   value = kvp_value_new_gnc_numeric (nval);
00415   frame = kvp_frame_set_value_nc (frame, path, value);
00416   if (!frame) kvp_value_delete (value);
00417 }

void kvp_frame_set_slot KvpFrame frame,
const char *  key,
const KvpValue value
 

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.

Definition at line 643 of file kvp_frame.c.

00645 {
00646   KvpValue *new_value = NULL;
00647 
00648   if (!frame) return;
00649 
00650   g_return_if_fail (slot && *slot != '\0');
00651 
00652   if(value) new_value = kvp_value_copy(value);
00653   kvp_frame_set_slot_destructively(frame, slot, new_value);
00654 }

void kvp_frame_set_slot_nc KvpFrame frame,
const char *  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.

Definition at line 657 of file kvp_frame.c.

00659 {
00660   if (!frame) return;
00661 
00662   g_return_if_fail (slot && *slot != '\0');
00663 
00664   kvp_frame_set_slot_destructively(frame, slot, value);
00665 }

void kvp_frame_set_slot_path KvpFrame frame,
const KvpValue value,
const char *  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.

Definition at line 680 of file kvp_frame.c.

00683 {
00684   va_list ap;
00685   const char *key;
00686 
00687   if (!frame) return;
00688 
00689   g_return_if_fail (first_key && *first_key != '\0');
00690 
00691   va_start (ap, first_key);
00692 
00693   key = first_key;
00694 
00695   while (TRUE) 
00696   {
00697     KvpValue *value;
00698     const char *next_key;
00699 
00700     next_key = va_arg (ap, const char *);
00701     if (!next_key) 
00702     {
00703       kvp_frame_set_slot (frame, key, new_value);
00704       break;
00705     }
00706 
00707     g_return_if_fail (*next_key != '\0');
00708 
00709     value = kvp_frame_get_slot (frame, key);
00710     if (!value) {
00711       KvpFrame *new_frame = kvp_frame_new ();
00712       KvpValue *frame_value = kvp_value_new_frame (new_frame);
00713 
00714       kvp_frame_set_slot_nc (frame, key, frame_value);
00715 
00716       value = kvp_frame_get_slot (frame, key);
00717       if (!value) break;
00718     }
00719 
00720     frame = kvp_value_get_frame (value);
00721     if (!frame) break;
00722 
00723     key = next_key;
00724   }
00725 
00726   va_end (ap);
00727 }

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 730 of file kvp_frame.c.

00733 {
00734   if (!frame || !key_path) return;
00735 
00736   while (TRUE) 
00737   {
00738     const char *key = key_path->data;
00739     KvpValue *value;
00740 
00741     if (!key)
00742       return;
00743 
00744     g_return_if_fail (*key != '\0');
00745 
00746     key_path = key_path->next;
00747     if (!key_path) 
00748     {
00749       kvp_frame_set_slot (frame, key, new_value);
00750       return;
00751     }
00752 
00753     value = kvp_frame_get_slot (frame, key);
00754     if (!value) 
00755     {
00756       KvpFrame *new_frame = kvp_frame_new ();
00757       KvpValue *frame_value = kvp_value_new_frame (new_frame);
00758 
00759       kvp_frame_set_slot_nc (frame, key, frame_value);
00760 
00761       value = kvp_frame_get_slot (frame, key);
00762       if (!value)
00763         return;
00764     }
00765 
00766     frame = kvp_value_get_frame (value);
00767     if (!frame)
00768       return;
00769   }
00770 }

void kvp_frame_set_string KvpFrame frame,
const char *  path,
const char *  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.

Definition at line 420 of file kvp_frame.c.

00421 {
00422   KvpValue *value;
00423   value = kvp_value_new_string (str);
00424   frame = kvp_frame_set_value_nc (frame, path, value);
00425   if (!frame) kvp_value_delete (value);
00426 }

void kvp_frame_set_timespec KvpFrame frame,
const char *  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.

Definition at line 438 of file kvp_frame.c.

00439 {
00440   KvpValue *value;
00441   value = kvp_value_new_timespec (ts);
00442   frame = kvp_frame_set_value_nc (frame, path, value);
00443   if (!frame) kvp_value_delete (value);
00444 }

KvpFrame* kvp_frame_set_value KvpFrame frame,
const char *  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.

Definition at line 479 of file kvp_frame.c.

00481 {
00482   KvpValue *new_value = NULL;
00483   char *last_key;
00484 
00485   frame = get_trailer_make (frame, key_path, &last_key);
00486   if (!frame) return NULL;
00487 
00488   if (value) new_value = kvp_value_copy(value);
00489   kvp_frame_set_slot_destructively(frame, last_key, new_value);
00490   return frame;
00491 }

KvpFrame* kvp_frame_set_value_nc KvpFrame frame,
const char *  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).

Definition at line 467 of file kvp_frame.c.

00469 {
00470   char *last_key;
00471 
00472   frame = get_trailer_make (frame, key_path, &last_key);
00473   if (!frame) return NULL;
00474   kvp_frame_set_slot_destructively(frame, last_key, value);
00475   return frame;
00476 }

gchar* kvp_frame_to_string const KvpFrame frame  ) 
 

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

Definition at line 1810 of file kvp_frame.c.

01811 {
01812     gchar *tmp1;
01813 
01814     g_return_val_if_fail (frame != NULL, NULL);
01815 
01816     tmp1 = g_strdup_printf("{\n");
01817 
01818     if (frame->hash)
01819       g_hash_table_foreach(frame->hash, kvp_frame_to_string_helper, &tmp1);
01820 
01821     {
01822         gchar *tmp2;
01823         tmp2 = g_strdup_printf("%s}\n", tmp1);
01824         g_free(tmp1);
01825         tmp1 = tmp2;
01826     }
01827 
01828     return tmp1;
01829 }

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 1062 of file kvp_frame.c.

01063 {
01064   GList * retval = NULL;
01065   GList * lptr;
01066 
01067   if (!list) return retval;
01068   
01069   /* Duplicate the backbone of the list (this duplicates the POINTERS
01070    * to the values; we need to deep-copy the values separately) */
01071   retval = g_list_copy((GList *) list);
01072   
01073   /* This step deep-copies the values */
01074   for(lptr = retval; lptr; lptr = lptr->next) 
01075   {
01076     lptr->data = kvp_value_copy(lptr->data);
01077   }
01078   
01079   return retval;
01080 }

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 1045 of file kvp_frame.c.

01046 {
01047   GList *node;
01048   if(!list) return;
01049   
01050   /* Delete the data in the list */
01051   for (node=list; node; node=node->next)
01052   {
01053     KvpValue *val = node->data;
01054     kvp_value_delete(val);
01055   }
01056   
01057   /* Free the backbone */
01058   g_list_free(list);
01059 }

gboolean kvp_value_binary_append KvpValue v,
void *  data,
guint64  size
 

Manipulator:

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

gint kvp_value_compare const KvpValue va,
const KvpValue vb
 

Similar returns as strcmp.

Definition at line 1494 of file kvp_frame.c.

01495 {
01496   if(kva == kvb) return 0;
01497   /* nothing is always less than something */
01498   if(!kva && kvb) return -1;
01499   if(kva && !kvb) return 1;
01500 
01501   if(kva->type < kvb->type) return -1;
01502   if(kva->type > kvb->type) return 1;
01503 
01504   switch(kva->type) {
01505   case KVP_TYPE_GINT64:
01506     if(kva->value.int64 < kvb->value.int64) return -1;
01507     if(kva->value.int64 > kvb->value.int64) return 1;
01508     return 0;
01509     break;
01510   case KVP_TYPE_DOUBLE:
01511     return double_compare(kva->value.dbl, kvb->value.dbl);
01512     break;
01513   case KVP_TYPE_NUMERIC:
01514     return gnc_numeric_compare (kva->value.numeric, kvb->value.numeric);
01515     break;
01516   case KVP_TYPE_STRING:
01517     return strcmp(kva->value.str, kvb->value.str);
01518     break;
01519   case KVP_TYPE_GUID:
01520     return guid_compare(kva->value.guid, kvb->value.guid);
01521     break;
01522   case KVP_TYPE_TIMESPEC:
01523     return timespec_cmp(&(kva->value.timespec), &(kvb->value.timespec));
01524     break;
01525   case KVP_TYPE_BINARY:
01526     /* I don't know that this is a good compare. Ab is bigger than Acef.
01527        But I'm not sure that actually matters here. */
01528     if(kva->value.binary.datasize < kvb->value.binary.datasize) return -1;
01529     if(kva->value.binary.datasize > kvb->value.binary.datasize) return 1;
01530     return memcmp(kva->value.binary.data,
01531                   kvb->value.binary.data,
01532                   kva->value.binary.datasize);
01533     break;
01534   case KVP_TYPE_GLIST:
01535     return kvp_glist_compare(kva->value.list, kvb->value.list);
01536     break;
01537   case KVP_TYPE_FRAME:
01538     return kvp_frame_compare(kva->value.frame, kvb->value.frame);
01539     break;
01540   }
01541   PERR ("reached unreachable code.");
01542   return FALSE;
01543 }

KvpValue* kvp_value_copy const KvpValue value  ) 
 

This is a deep value copy.

Definition at line 1433 of file kvp_frame.c.

01434 {
01435   if(!value) return NULL;
01436 
01437   switch(value->type) {
01438   case KVP_TYPE_GINT64:
01439     return kvp_value_new_gint64(value->value.int64);
01440     break;
01441   case KVP_TYPE_DOUBLE:
01442     return kvp_value_new_double(value->value.dbl);
01443     break;
01444   case KVP_TYPE_NUMERIC:
01445     return kvp_value_new_gnc_numeric(value->value.numeric);
01446     break;
01447   case KVP_TYPE_STRING:
01448     return kvp_value_new_string(value->value.str);
01449     break;
01450   case KVP_TYPE_GUID:
01451     return kvp_value_new_guid(value->value.guid);
01452     break;
01453   case KVP_TYPE_TIMESPEC:
01454     return kvp_value_new_timespec(value->value.timespec);
01455     break;
01456   case KVP_TYPE_BINARY:
01457     return kvp_value_new_binary(value->value.binary.data,
01458                                 value->value.binary.datasize);
01459     break;
01460   case KVP_TYPE_GLIST:
01461     return kvp_value_new_glist(value->value.list);
01462     break;
01463   case KVP_TYPE_FRAME:
01464     return kvp_value_new_frame(value->value.frame);
01465     break;
01466   }  
01467   return NULL;
01468 }

void kvp_value_delete KvpValue value  ) 
 

This is a deep (recursive) delete.

Definition at line 1251 of file kvp_frame.c.

01252 {
01253   if(!value) return;
01254 
01255   switch(value->type) 
01256   {
01257   case KVP_TYPE_STRING:
01258     g_free(value->value.str);
01259     break;
01260   case KVP_TYPE_GUID:
01261     g_free(value->value.guid);
01262     break;
01263   case KVP_TYPE_BINARY:
01264     g_free(value->value.binary.data);
01265     break;
01266   case KVP_TYPE_GLIST:
01267     kvp_glist_delete(value->value.list);
01268     break;
01269   case KVP_TYPE_FRAME:
01270     kvp_frame_delete(value->value.frame);
01271     break;
01272     
01273   case KVP_TYPE_GINT64:    
01274   case KVP_TYPE_DOUBLE:
01275   case KVP_TYPE_NUMERIC:
01276   default:
01277     break;
01278   }
01279   g_free(value);
01280 }

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 1361 of file kvp_frame.c.

01362 {
01363   if (!value)
01364   {
01365     if (size_return)
01366       *size_return = 0;
01367     return NULL;
01368   }
01369 
01370   if(value->type == KVP_TYPE_BINARY) {
01371     if (size_return)
01372       *size_return = value->value.binary.datasize;
01373     return value->value.binary.data;
01374   }
01375   else {
01376     if (size_return)
01377       *size_return = 0;
01378     return NULL;
01379   }
01380 }

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 1395 of file kvp_frame.c.

01396 {
01397   if (!value) return NULL;
01398   if(value->type == KVP_TYPE_FRAME) {
01399     return value->value.frame;
01400   }
01401   else {
01402     return NULL;
01403   }
01404 }

gint64 kvp_value_get_gint64 const KvpValue value  ) 
 

Value accessors. Those for GUID, 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 1290 of file kvp_frame.c.

01291 {
01292   if (!value) return 0;
01293   if(value->type == KVP_TYPE_GINT64) {
01294     return value->value.int64;
01295   }
01296   else {
01297     return 0;
01298   }
01299 }

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 1383 of file kvp_frame.c.

01384 {
01385   if (!value) return NULL;
01386   if(value->type == KVP_TYPE_GLIST) {
01387     return value->value.list;
01388   }
01389   else {
01390     return NULL;
01391   }
01392 }

GUID* kvp_value_get_guid const KvpValue value  ) 
 

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

Definition at line 1338 of file kvp_frame.c.

01339 {
01340   if (!value) return NULL;
01341   if(value->type == KVP_TYPE_GUID) {
01342     return value->value.guid;
01343   }
01344   else {
01345     return NULL;
01346   }
01347 }

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 1326 of file kvp_frame.c.

01327 {
01328   if (!value) return NULL;
01329   if(value->type == KVP_TYPE_STRING) {
01330     return value->value.str;
01331   }
01332   else { 
01333     return NULL; 
01334   }
01335 }

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 1190 of file kvp_frame.c.

01191 {
01192   KvpValue * retval;
01193   if (!value) return NULL;
01194 
01195   retval = g_new0(KvpValue, 1);
01196   retval->type = KVP_TYPE_BINARY;
01197   retval->value.binary.data = value;
01198   retval->value.binary.datasize = datasize;
01199   return retval;
01200 }

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 1239 of file kvp_frame.c.

01240 {
01241   KvpValue * retval;
01242   if (!value) return NULL;
01243 
01244   retval  = g_new0(KvpValue, 1);
01245   retval->type        = KVP_TYPE_FRAME;
01246   retval->value.frame = value;
01247   return retval;  
01248 }

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 1203 of file kvp_frame.c.

01204 {
01205   KvpValue * retval;
01206   if (!value) return NULL;
01207 
01208   retval = g_new0(KvpValue, 1);
01209   retval->type       = KVP_TYPE_GLIST;
01210   retval->value.list = kvp_glist_copy(value);
01211   return retval;
01212 }  

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 1215 of file kvp_frame.c.

01216 {
01217   KvpValue * retval;
01218   if (!value) return NULL;
01219 
01220   retval = g_new0(KvpValue, 1);
01221   retval->type       = KVP_TYPE_GLIST;
01222   retval->value.list = value;
01223   return retval;
01224 }  

KvpFrame* kvp_value_replace_frame_nc KvpValue value,
KvpFrame newframe
 

Replace old frame value with new, return old frame

Definition at line 1407 of file kvp_frame.c.

01408 {
01409   KvpFrame *oldframe;
01410   if (!value) return NULL;
01411   if (KVP_TYPE_FRAME != value->type) return NULL;
01412 
01413   oldframe = value->value.frame;
01414   value->value.frame = newframe;
01415   return oldframe;  
01416 }

GList* kvp_value_replace_glist_nc KvpValue value,
GList *  newlist
 

Replace old glist value with new, return old glist

Definition at line 1419 of file kvp_frame.c.

01420 {
01421   GList *oldlist;
01422   if (!value) return NULL;
01423   if (KVP_TYPE_GLIST != value->type) return NULL;
01424 
01425   oldlist = value->value.list;
01426   value->value.list = newlist;
01427   return oldlist;
01428 }

gchar* kvp_value_to_bare_string const KvpValue val  ) 
 

General purpose function to convert any KvpValue to a string.

Only the bare string is returned, there is no debugging information.

Definition at line 1639 of file kvp_frame.c.

01640 {
01641     gchar *tmp1;
01642     gchar *tmp2;
01643     const gchar *ctmp;
01644     
01645     g_return_val_if_fail(val, NULL);
01646     
01647     switch(kvp_value_get_type(val))
01648     {
01649     case KVP_TYPE_GINT64:
01650         return g_strdup_printf("%" G_GINT64_FORMAT, kvp_value_get_gint64(val));
01651         break;
01652 
01653     case KVP_TYPE_DOUBLE:
01654         return g_strdup_printf("(%g)", kvp_value_get_double(val));
01655         break;
01656 
01657     case KVP_TYPE_NUMERIC:
01658         tmp1 = gnc_numeric_to_string(kvp_value_get_numeric(val));
01659         tmp2 = g_strdup_printf("%s", tmp1 ? tmp1 : "");
01660         g_free(tmp1);
01661         return tmp2;
01662         break;
01663 
01664     case KVP_TYPE_STRING:
01665         tmp1 = kvp_value_get_string (val);
01666         return g_strdup_printf("%s", tmp1 ? tmp1 : "");
01667         break;
01668 
01669     case KVP_TYPE_GUID:
01670         ctmp = guid_to_string(kvp_value_get_guid(val));
01671         tmp2 = g_strdup_printf("%s", ctmp ? ctmp : "");
01672         return tmp2;
01673         break;
01674 
01675     case KVP_TYPE_TIMESPEC:
01676         tmp1 = g_new0 (char, 40);
01677         gnc_timespec_to_iso8601_buff (kvp_value_get_timespec (val), tmp1);
01678         tmp2 = g_strdup_printf("%s", tmp1);
01679         g_free(tmp1);
01680         return tmp2;
01681         break;
01682 
01683     case KVP_TYPE_BINARY:
01684     {
01685         guint64 len;
01686         void *data;
01687         data = kvp_value_get_binary(val, &len);
01688         tmp1 = binary_to_string(data, len);
01689         return g_strdup_printf("%s", tmp1 ? tmp1 : "");
01690     }
01691         break;
01692  
01693     case KVP_TYPE_GLIST:
01694         tmp1 = kvp_value_glist_to_string(kvp_value_get_glist(val));
01695         tmp2 = g_strdup_printf("%s", tmp1 ? tmp1 : "");
01696         g_free(tmp1);
01697         return tmp2;
01698         break;
01699 
01700     case KVP_TYPE_FRAME:
01701         tmp1 = kvp_frame_to_string(kvp_value_get_frame(val));
01702         tmp2 = g_strdup_printf("%s", tmp1 ? tmp1 : "");
01703         g_free(tmp1);
01704         return tmp2;
01705         break;
01706 
01707     default:
01708         return g_strdup_printf(" ");
01709         break;
01710     }
01711 }

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 1714 of file kvp_frame.c.

01715 {
01716     gchar *tmp1;
01717     gchar *tmp2;
01718     const gchar *ctmp;
01719     
01720     g_return_val_if_fail(val, NULL);
01721     
01722     switch(kvp_value_get_type(val))
01723     {
01724     case KVP_TYPE_GINT64:
01725         return g_strdup_printf("KVP_VALUE_GINT64(%" G_GINT64_FORMAT ")",
01726                                kvp_value_get_gint64(val));
01727         break;
01728 
01729     case KVP_TYPE_DOUBLE:
01730         return g_strdup_printf("KVP_VALUE_DOUBLE(%g)",
01731                                kvp_value_get_double(val));
01732         break;
01733 
01734     case KVP_TYPE_NUMERIC:
01735         tmp1 = gnc_numeric_to_string(kvp_value_get_numeric(val));
01736         tmp2 = g_strdup_printf("KVP_VALUE_NUMERIC(%s)", tmp1 ? tmp1 : "");
01737         g_free(tmp1);
01738         return tmp2;
01739         break;
01740 
01741     case KVP_TYPE_STRING:
01742         tmp1 = kvp_value_get_string (val);
01743         return g_strdup_printf("KVP_VALUE_STRING(%s)", tmp1 ? tmp1 : "");
01744         break;
01745 
01746     case KVP_TYPE_GUID:
01747                 /* THREAD-UNSAFE */
01748         ctmp = guid_to_string(kvp_value_get_guid(val));
01749         tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", ctmp ? ctmp : "");
01750         return tmp2;
01751         break;
01752 
01753     case KVP_TYPE_TIMESPEC:
01754         tmp1 = g_new0 (char, 40);
01755         gnc_timespec_to_iso8601_buff (kvp_value_get_timespec (val), tmp1);
01756         tmp2 = g_strdup_printf("KVP_VALUE_TIMESPEC(%s)", tmp1);
01757         g_free(tmp1);
01758         return tmp2;
01759         break;
01760 
01761     case KVP_TYPE_BINARY:
01762     {
01763         guint64 len;
01764         void *data;
01765         data = kvp_value_get_binary(val, &len);
01766         tmp1 = binary_to_string(data, len);
01767         return g_strdup_printf("KVP_VALUE_BINARY(%s)", tmp1 ? tmp1 : "");
01768     }
01769         break;
01770  
01771     case KVP_TYPE_GLIST:
01772         tmp1 = kvp_value_glist_to_string(kvp_value_get_glist(val));
01773         tmp2 = g_strdup_printf("KVP_VALUE_GLIST(%s)", tmp1 ? tmp1 : "");
01774         g_free(tmp1);
01775         return tmp2;
01776         break;
01777 
01778     case KVP_TYPE_FRAME:
01779         tmp1 = kvp_frame_to_string(kvp_value_get_frame(val));
01780         tmp2 = g_strdup_printf("KVP_VALUE_FRAME(%s)", tmp1 ? tmp1 : "");
01781         g_free(tmp1);
01782         return tmp2;
01783         break;
01784 
01785     default:
01786         return g_strdup_printf(" ");
01787         break;
01788     }
01789 }


Generated on Fri Oct 21 15:49:59 2005 for QOF by  doxygen 1.4.5