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 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_string (KvpFrame *frame, const gchar *path, const gchar *str)
 Store a copy of the string at the indicated path.
void kvp_frame_set_guid (KvpFrame *frame, const gchar *path, const GUID *guid)
void kvp_frame_set_time (KvpFrame *frame, const gchar *path, QofTime *qt)
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)
KvpFramekvp_frame_set_value (KvpFrame *frame, const gchar *path, const KvpValue *value)
KvpFramekvp_frame_set_value_nc (KvpFrame *frame, const gchar *path, KvpValue *value)
KvpValuekvp_frame_replace_value_nc (KvpFrame *frame, const gchar *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 gchar *path, gint64 ival)
void kvp_frame_add_double (KvpFrame *frame, const gchar *path, double dval)
void kvp_frame_add_numeric (KvpFrame *frame, const gchar *path, gnc_numeric nval)
void kvp_frame_add_time (KvpFrame *frame, const gchar *path, QofTime *qt)
void kvp_frame_add_string (KvpFrame *frame, const gchar *path, const gchar *str)
 Copy of the string to the glist bag at the indicated path.
void kvp_frame_add_guid (KvpFrame *frame, const gchar *path, const GUID *guid)
void kvp_frame_add_frame (KvpFrame *frame, const gchar *path, KvpFrame *chld)
void kvp_frame_add_frame_nc (KvpFrame *frame, const gchar *path, KvpFrame *chld)
KvpFramekvp_frame_add_value (KvpFrame *frame, const gchar *path, KvpValue *value)
KvpFramekvp_frame_add_value_nc (KvpFrame *frame, const gchar *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 gchar *value)
KvpValuekvp_value_new_guid (const GUID *guid)
KvpValuekvp_value_new_time (QofTime *value)
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

KvpFrameqof_kvp_bag_add (KvpFrame *kvp_root, const gchar *path, QofTime *qt, const gchar *first_name,...)
void qof_kvp_bag_merge (KvpFrame *kvp_into, const gchar *intopath, KvpFrame *kvp_from, const gchar *frompath)
KvpFrameqof_kvp_bag_find_by_guid (KvpFrame *root, const gchar *path, const gchar *guid_name, GUID *desired_guid)
void qof_kvp_bag_remove_frame (KvpFrame *root, const gchar *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 gchar *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 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)
gchar * kvp_frame_get_string (const KvpFrame *frame, const gchar *path)
GUIDkvp_frame_get_guid (const KvpFrame *frame, const gchar *path)
void * kvp_frame_get_binary (const KvpFrame *frame, const gchar *path, guint64 *size_return)
QofTimekvp_frame_get_time (const KvpFrame *frame, const gchar *path)
KvpValuekvp_frame_get_value (const KvpFrame *frame, const gchar *path)
KvpFramekvp_frame_get_frame (const KvpFrame *frame, const gchar *path)
KvpFramekvp_frame_get_frame_path (KvpFrame *frame, const gchar *,...)
KvpFramekvp_frame_get_frame_gslist (KvpFrame *frame, GSList *key_path)
KvpFramekvp_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().

KvpValuekvp_frame_replace_slot_nc (KvpFrame *frame, const gchar *slot, KvpValue *new_value)
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.

KvpValuekvp_frame_get_slot (const KvpFrame *frame, const gchar *key)
KvpValuekvp_frame_get_slot_path (KvpFrame *frame, const gchar *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)
QofTimekvp_value_get_time (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_TIME, 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 109 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 278 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 289 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 159 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 172 of file kvp_frame.h.

#define kvp_value   KvpValue

Deprecated:
Deprecated backwards compat token

Definition at line 111 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 574 of file kvp_frame.h.

#define kvp_value_t   KvpValueType

Deprecated:
Deprecated backwards compat token

Definition at line 113 of file kvp_frame.h.


Typedef Documentation

typedef struct _KvpFrame KvpFrame

Opaque frame structure

Definition at line 71 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 75 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 
Deprecated:
QOF_TYPE_DATE
KVP_TYPE_TIME  QOF_TYPE_TIME
KVP_TYPE_BINARY  no QOF equivalent.
KVP_TYPE_GLIST  no QOF equivalent.
KVP_TYPE_FRAME  no QOF equivalent.

Definition at line 88 of file kvp_frame.h.

00089 {
00090     KVP_TYPE_GINT64 = 1,
00092     KVP_TYPE_DOUBLE,   
00093     KVP_TYPE_NUMERIC,  
00094     KVP_TYPE_STRING,   
00095     KVP_TYPE_GUID,     
00096 #ifndef QOF_DISABLE_DEPRECATED
00097     KVP_TYPE_TIMESPEC, 
00098 #endif
00099     KVP_TYPE_TIME,     
00100     KVP_TYPE_BINARY,   
00101     KVP_TYPE_GLIST,    
00102     KVP_TYPE_FRAME     
00103 } KvpValueType;


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 214 of file kvp-util.c.

00215 {
00216     GSList *result_list = NULL;
00217     g_hash_table_foreach (table, kv_pair_helper, &result_list);
00218     return result_list;
00219 }

void kvp_frame_add_gint64 ( KvpFrame frame,
const gchar *  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_time routines perform the same function, for each of the respective types.

void kvp_frame_add_string ( KvpFrame frame,
const gchar *  path,
const gchar *  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 647 of file kvp_frame.c.

00648 {
00649     KvpValue *value;
00650     value = kvp_value_new_string (str);
00651     frame = kvp_frame_add_value_nc (frame, path, value);
00652     if (!frame)
00653         kvp_value_delete (value);
00654 }

void kvp_frame_add_url_encoding ( KvpFrame frame,
const gchar *  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.

gint kvp_frame_compare ( const KvpFrame fa,
const KvpFrame fb 
)

Similar returns as strcmp.

Definition at line 1732 of file kvp_frame.c.

01733 {
01734     kvp_frame_cmp_status status;
01735 
01736     if (fa == fb)
01737         return 0;
01738     /* nothing is always less than something */
01739     if (!fa && fb)
01740         return -1;
01741     if (fa && !fb)
01742         return 1;
01743 
01744     /* nothing is always less than something */
01745     if (!fa->hash && fb->hash)
01746         return -1;
01747     if (fa->hash && !fb->hash)
01748         return 1;
01749 
01750     status.compare = 0;
01751     status.other_frame = (KvpFrame *) fb;
01752 
01753     kvp_frame_for_each_slot ((KvpFrame *) fa, kvp_frame_compare_helper,
01754         &status);
01755 
01756     if (status.compare != 0)
01757         return status.compare;
01758 
01759     status.other_frame = (KvpFrame *) fa;
01760 
01761     kvp_frame_for_each_slot ((KvpFrame *) fb, kvp_frame_compare_helper,
01762         &status);
01763 
01764     return (-status.compare);
01765 }

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)
00161         return retval;
00162 
00163     if (frame->hash)
00164     {
00165         if (!init_frame_body_if_needed (retval))
00166             return (NULL);
00167         g_hash_table_foreach (frame->hash,
00168             &kvp_frame_copy_worker, (gpointer) retval);
00169     }
00170     return retval;
00171 }

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

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

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

01614 {
01615     if (!f)
01616         return;
01617     if (!proc)
01618         return;
01619     if (!(f->hash))
01620         return;
01621 
01622     g_hash_table_foreach (f->hash, (GHFunc) proc, data);
01623 }

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.

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

01002 {
01003     if (!frame)
01004         return frame;
01005 
01006     while (key_path)
01007     {
01008         const char *key = key_path->data;
01009 
01010         if (!key)
01011             return frame;       /* an unusual but valid exit for this routine. */
01012 
01013         frame = get_or_make (frame, key);
01014         if (!frame)
01015             return frame;       /* this should never happen */
01016 
01017         key_path = key_path->next;
01018     }
01019     return frame;               /* this is the normal exit for this func */
01020 }

KvpFrame* kvp_frame_get_frame_path ( KvpFrame frame,
const gchar *  ,
  ... 
)

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.

KvpFrame* kvp_frame_get_frame_slash ( KvpFrame frame,
const gchar *  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).

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.

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

01098 {
01099     if (!frame || !key_path)
01100         return NULL;
01101 
01102     while (TRUE)
01103     {
01104         const char *key = key_path->data;
01105         KvpValue *value;
01106 
01107         if (!key)
01108             return NULL;
01109 
01110         value = kvp_frame_get_slot (frame, key);
01111         if (!value)
01112             return NULL;
01113 
01114         key_path = key_path->next;
01115         if (!key_path)
01116             return value;
01117 
01118         frame = kvp_value_get_frame (value);
01119         if (!frame)
01120             return NULL;
01121     }
01122 }

gboolean kvp_frame_is_empty ( KvpFrame frame  ) 

Return TRUE if the KvpFrame is empty

Definition at line 137 of file kvp_frame.c.

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

KvpFrame* kvp_frame_new ( void   ) 

Return a new empty instance of KvpFrame

Definition at line 101 of file kvp_frame.c.

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

KvpValue* kvp_frame_replace_slot_nc ( KvpFrame frame,
const gchar *  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.

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

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.

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.

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.

void kvp_frame_set_slot ( KvpFrame frame,
const gchar *  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.

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.

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.

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

00786 {
00787     if (!frame || !key_path)
00788         return;
00789 
00790     while (TRUE)
00791     {
00792         const char *key = key_path->data;
00793         KvpValue *value;
00794 
00795         if (!key)
00796             return;
00797 
00798         g_return_if_fail (*key != '\0');
00799 
00800         key_path = key_path->next;
00801         if (!key_path)
00802         {
00803             kvp_frame_set_slot (frame, key, new_value);
00804             return;
00805         }
00806 
00807         value = kvp_frame_get_slot (frame, key);
00808         if (!value)
00809         {
00810             KvpFrame *new_frame = kvp_frame_new ();
00811             KvpValue *frame_value = kvp_value_new_frame (new_frame);
00812 
00813             kvp_frame_set_slot_nc (frame, key, frame_value);
00814 
00815             value = kvp_frame_get_slot (frame, key);
00816             if (!value)
00817                 return;
00818         }
00819 
00820         frame = kvp_value_get_frame (value);
00821         if (!frame)
00822             return;
00823     }
00824 }

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.

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.

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

gchar* kvp_frame_to_string ( const KvpFrame frame  ) 

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

Definition at line 2003 of file kvp_frame.c.

02004 {
02005     gchar *tmp1;
02006 
02007     g_return_val_if_fail (frame != NULL, NULL);
02008 
02009     tmp1 = g_strdup_printf ("{\n");
02010 
02011     if (frame->hash)
02012         g_hash_table_foreach (frame->hash, kvp_frame_to_string_helper,
02013             &tmp1);
02014 
02015     {
02016         gchar *tmp2;
02017         tmp2 = g_strdup_printf ("%s}\n", tmp1);
02018         g_free (tmp1);
02019         tmp1 = tmp2;
02020     }
02021 
02022     return tmp1;
02023 }

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

01148 {
01149     GList *retval = NULL;
01150     GList *lptr;
01151 
01152     if (!list)
01153         return retval;
01154 
01155     /* Duplicate the backbone of the list (this duplicates the POINTERS
01156      * to the values; we need to deep-copy the values separately) */
01157     retval = g_list_copy ((GList *) list);
01158 
01159     /* This step deep-copies the values */
01160     for (lptr = retval; lptr; lptr = lptr->next)
01161     {
01162         lptr->data = kvp_value_copy (lptr->data);
01163     }
01164 
01165     return retval;
01166 }

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

01130 {
01131     GList *node;
01132     if (!list)
01133         return;
01134 
01135     /* Delete the data in the list */
01136     for (node = list; node; node = node->next)
01137     {
01138         KvpValue *val = node->data;
01139         kvp_value_delete (val);
01140     }
01141 
01142     /* Free the backbone */
01143     g_list_free (list);
01144 }

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

01639 {
01640     if (kva == kvb)
01641         return 0;
01642     /* nothing is always less than something */
01643     if (!kva && kvb)
01644         return -1;
01645     if (kva && !kvb)
01646         return 1;
01647 
01648     if (kva->type < kvb->type)
01649         return -1;
01650     if (kva->type > kvb->type)
01651         return 1;
01652 
01653     switch (kva->type)
01654     {
01655     case KVP_TYPE_GINT64:
01656         if (kva->value.int64 < kvb->value.int64)
01657             return -1;
01658         if (kva->value.int64 > kvb->value.int64)
01659             return 1;
01660         return 0;
01661         break;
01662     case KVP_TYPE_DOUBLE:
01663         return double_compare (kva->value.dbl, kvb->value.dbl);
01664         break;
01665     case KVP_TYPE_NUMERIC:
01666         return gnc_numeric_compare (kva->value.numeric,
01667             kvb->value.numeric);
01668         break;
01669     case KVP_TYPE_STRING:
01670         return strcmp (kva->value.str, kvb->value.str);
01671         break;
01672     case KVP_TYPE_GUID:
01673         return guid_compare (kva->value.guid, kvb->value.guid);
01674         break;
01675     case KVP_TYPE_TIME :
01676         return qof_time_cmp (kva->value.qt, kvb->value.qt);
01677         break;
01678 #ifndef QOF_DISABLE_DEPRECATED
01679     case KVP_TYPE_TIMESPEC:
01680         return timespec_cmp (&(kva->value.timespec),
01681             &(kvb->value.timespec));
01682         break;
01683 #endif
01684     case KVP_TYPE_BINARY:
01685         /* I don't know that this is a good compare. Ab is bigger than Acef.
01686            But I'm not sure that actually matters here. */
01687         if (kva->value.binary.datasize < kvb->value.binary.datasize)
01688             return -1;
01689         if (kva->value.binary.datasize > kvb->value.binary.datasize)
01690             return 1;
01691         return memcmp (kva->value.binary.data,
01692             kvb->value.binary.data, kva->value.binary.datasize);
01693         break;
01694     case KVP_TYPE_GLIST:
01695         return kvp_glist_compare (kva->value.list, kvb->value.list);
01696         break;
01697     case KVP_TYPE_FRAME:
01698         return kvp_frame_compare (kva->value.frame, kvb->value.frame);
01699         break;
01700     }
01701     PERR ("reached unreachable code.");
01702     return FALSE;
01703 }

KvpValue* kvp_value_copy ( const KvpValue value  ) 

This is a deep value copy.

Definition at line 1566 of file kvp_frame.c.

01567 {
01568     if (!value)
01569         return NULL;
01570 
01571     switch (value->type)
01572     {
01573     case KVP_TYPE_GINT64:
01574         return kvp_value_new_gint64 (value->value.int64);
01575         break;
01576     case KVP_TYPE_DOUBLE:
01577         return kvp_value_new_double (value->value.dbl);
01578         break;
01579     case KVP_TYPE_NUMERIC:
01580         return kvp_value_new_gnc_numeric (value->value.numeric);
01581         break;
01582     case KVP_TYPE_STRING:
01583         return kvp_value_new_string (value->value.str);
01584         break;
01585     case KVP_TYPE_GUID:
01586         return kvp_value_new_guid (value->value.guid);
01587         break;
01588     case KVP_TYPE_TIME :
01589         return kvp_value_new_time (value->value.qt);
01590         break;
01591 #ifndef QOF_DISABLE_DEPRECATED
01592     case KVP_TYPE_TIMESPEC:
01593         return kvp_value_new_timespec (value->value.timespec);
01594         break;
01595 #endif
01596     case KVP_TYPE_BINARY:
01597         return kvp_value_new_binary (value->value.binary.data,
01598             value->value.binary.datasize);
01599         break;
01600     case KVP_TYPE_GLIST:
01601         return kvp_value_new_glist (value->value.list);
01602         break;
01603     case KVP_TYPE_FRAME:
01604         return kvp_value_new_frame (value->value.frame);
01605         break;
01606     }
01607     return NULL;
01608 }

void kvp_value_delete ( KvpValue value  ) 

This is a deep (recursive) delete.

Definition at line 1351 of file kvp_frame.c.

01352 {
01353     if (!value)
01354         return;
01355 
01356     switch (value->type)
01357     {
01358     case KVP_TYPE_STRING:
01359         g_free (value->value.str);
01360         break;
01361     case KVP_TYPE_GUID:
01362         g_free (value->value.guid);
01363         break;
01364     case KVP_TYPE_BINARY:
01365         g_free (value->value.binary.data);
01366         break;
01367     case KVP_TYPE_GLIST:
01368         kvp_glist_delete (value->value.list);
01369         break;
01370     case KVP_TYPE_FRAME:
01371         kvp_frame_delete (value->value.frame);
01372         break;
01373 
01374     case KVP_TYPE_GINT64:
01375     case KVP_TYPE_DOUBLE:
01376     case KVP_TYPE_NUMERIC:
01377     default:
01378         break;
01379     }
01380     g_free (value);
01381 }

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

01483 {
01484     if (!value)
01485     {
01486         if (size_return)
01487             *size_return = 0;
01488         return NULL;
01489     }
01490 
01491     if (value->type == KVP_TYPE_BINARY)
01492     {
01493         if (size_return)
01494             *size_return = value->value.binary.datasize;
01495         return value->value.binary.data;
01496     }
01497     else
01498     {
01499         if (size_return)
01500             *size_return = 0;
01501         return NULL;
01502     }
01503 }

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

01522 {
01523     if (!value)
01524         return NULL;
01525     if (value->type == KVP_TYPE_FRAME)
01526     {
01527         return value->value.frame;
01528     }
01529     else
01530     {
01531         return NULL;
01532     }
01533 }

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

01393 {
01394     if (!value)
01395         return 0;
01396     if (value->type == KVP_TYPE_GINT64)
01397     {
01398         return value->value.int64;
01399     }
01400     else
01401     {
01402         return 0;
01403     }
01404 }

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

01507 {
01508     if (!value)
01509         return NULL;
01510     if (value->type == KVP_TYPE_GLIST)
01511     {
01512         return value->value.list;
01513     }
01514     else
01515     {
01516         return NULL;
01517     }
01518 }

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

01453 {
01454     if (!value)
01455         return NULL;
01456     if (value->type == KVP_TYPE_GUID)
01457     {
01458         return value->value.guid;
01459     }
01460     else
01461     {
01462         return NULL;
01463     }
01464 }

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

01438 {
01439     if (!value)
01440         return NULL;
01441     if (value->type == KVP_TYPE_STRING)
01442     {
01443         return value->value.str;
01444     }
01445     else
01446     {
01447         return NULL;
01448     }
01449 }

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

01286 {
01287     KvpValue *retval;
01288     if (!value)
01289         return NULL;
01290 
01291     retval = g_new0 (KvpValue, 1);
01292     retval->type = KVP_TYPE_BINARY;
01293     retval->value.binary.data = value;
01294     retval->value.binary.datasize = datasize;
01295     return retval;
01296 }

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

01339 {
01340     KvpValue *retval;
01341     if (!value)
01342         return NULL;
01343 
01344     retval = g_new0 (KvpValue, 1);
01345     retval->type = KVP_TYPE_FRAME;
01346     retval->value.frame = value;
01347     return retval;
01348 }

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

01300 {
01301     KvpValue *retval;
01302     if (!value)
01303         return NULL;
01304 
01305     retval = g_new0 (KvpValue, 1);
01306     retval->type = KVP_TYPE_GLIST;
01307     retval->value.list = kvp_glist_copy (value);
01308     return retval;
01309 }

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

01313 {
01314     KvpValue *retval;
01315     if (!value)
01316         return NULL;
01317 
01318     retval = g_new0 (KvpValue, 1);
01319     retval->type = KVP_TYPE_GLIST;
01320     retval->value.list = value;
01321     return retval;
01322 }

KvpFrame* kvp_value_replace_frame_nc ( KvpValue value,
KvpFrame newframe 
)

Replace old frame value with new, return old frame

Definition at line 1536 of file kvp_frame.c.

01537 {
01538     KvpFrame *oldframe;
01539     if (!value)
01540         return NULL;
01541     if (KVP_TYPE_FRAME != value->type)
01542         return NULL;
01543 
01544     oldframe = value->value.frame;
01545     value->value.frame = newframe;
01546     return oldframe;
01547 }

GList* kvp_value_replace_glist_nc ( KvpValue value,
GList *  newlist 
)

Replace old glist value with new, return old glist

Definition at line 1550 of file kvp_frame.c.

01551 {
01552     GList *oldlist;
01553     if (!value)
01554         return NULL;
01555     if (KVP_TYPE_GLIST != value->type)
01556         return NULL;
01557 
01558     oldlist = value->value.list;
01559     value->value.list = newlist;
01560     return oldlist;
01561 }

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

01823 {
01824     gchar *tmp1;
01825     gchar *tmp2;
01826     const gchar *ctmp;
01827 
01828     g_return_val_if_fail (val, NULL);
01829     tmp1 = g_strdup ("");
01830     switch (kvp_value_get_type (val))
01831     {
01832     case KVP_TYPE_GINT64:
01833         return g_strdup_printf ("%" G_GINT64_FORMAT,
01834             kvp_value_get_gint64 (val));
01835         break;
01836 
01837     case KVP_TYPE_DOUBLE:
01838         return g_strdup_printf ("(%g)", kvp_value_get_double (val));
01839         break;
01840 
01841     case KVP_TYPE_NUMERIC:
01842         tmp1 = gnc_numeric_to_string (kvp_value_get_numeric (val));
01843         tmp2 = g_strdup_printf ("%s", tmp1 ? tmp1 : "");
01844         g_free (tmp1);
01845         return tmp2;
01846         break;
01847 
01848     case KVP_TYPE_STRING:
01849         tmp1 = kvp_value_get_string (val);
01850         return g_strdup_printf ("%s", tmp1 ? tmp1 : "");
01851         break;
01852 
01853     case KVP_TYPE_GUID:
01854         ctmp = guid_to_string (kvp_value_get_guid (val));
01855         tmp2 = g_strdup_printf ("%s", ctmp ? ctmp : "");
01856         return tmp2;
01857         break;
01858 #ifndef QOF_DISABLE_DEPRECATED
01859     case KVP_TYPE_TIMESPEC:
01860         {
01861             time_t t;
01862             t = timespecToTime_t (kvp_value_get_timespec (val));
01863             qof_date_format_set (QOF_DATE_FORMAT_UTC);
01864             return qof_print_date (t);
01865             break;
01866         }
01867 #endif
01868     case KVP_TYPE_BINARY:
01869         {
01870             guint64 len;
01871             void *data;
01872             data = kvp_value_get_binary (val, &len);
01873             tmp1 = binary_to_string (data, len);
01874             return g_strdup_printf ("%s", tmp1 ? tmp1 : "");
01875         }
01876         break;
01877 
01878     case KVP_TYPE_GLIST:
01879         /* borked. kvp_value_glist_to_string is a debug fcn */
01880         {
01881             tmp1 = kvp_value_glist_to_string (kvp_value_get_glist (val));
01882             tmp2 = g_strdup_printf ("%s", tmp1 ? tmp1 : "");
01883             g_free (tmp1);
01884             return tmp2;
01885             break;
01886         }
01887     case KVP_TYPE_FRAME:
01888         {
01889             KvpFrame *frame;
01890 
01891             frame = kvp_value_get_frame (val);
01892             if (frame->hash)
01893             {
01894                 tmp1 = g_strdup ("");
01895                 g_hash_table_foreach (frame->hash,
01896                     kvp_frame_to_bare_string_helper, &tmp1);
01897             }
01898             return tmp1;
01899             break;
01900         }
01901     default:
01902         return g_strdup_printf (" ");
01903         break;
01904     }
01905 }

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

01909 {
01910     gchar *tmp1;
01911     gchar *tmp2;
01912     const gchar *ctmp;
01913 
01914     g_return_val_if_fail (val, NULL);
01915 
01916     switch (kvp_value_get_type (val))
01917     {
01918     case KVP_TYPE_GINT64:
01919         return g_strdup_printf ("KVP_VALUE_GINT64(%" G_GINT64_FORMAT ")",
01920             kvp_value_get_gint64 (val));
01921         break;
01922 
01923     case KVP_TYPE_DOUBLE:
01924         return g_strdup_printf ("KVP_VALUE_DOUBLE(%g)",
01925             kvp_value_get_double (val));
01926         break;
01927 
01928     case KVP_TYPE_NUMERIC:
01929         tmp1 = gnc_numeric_to_string (kvp_value_get_numeric (val));
01930         tmp2 = g_strdup_printf ("KVP_VALUE_NUMERIC(%s)", tmp1 ? tmp1 : "");
01931         g_free (tmp1);
01932         return tmp2;
01933         break;
01934 
01935     case KVP_TYPE_STRING:
01936         tmp1 = kvp_value_get_string (val);
01937         return g_strdup_printf ("KVP_VALUE_STRING(%s)", tmp1 ? tmp1 : "");
01938         break;
01939 
01940     case KVP_TYPE_GUID:
01941         /* THREAD-UNSAFE */
01942         ctmp = guid_to_string (kvp_value_get_guid (val));
01943         tmp2 = g_strdup_printf ("KVP_VALUE_GUID(%s)", ctmp ? ctmp : "");
01944         return tmp2;
01945         break;
01946 #ifndef QOF_DISABLE_DEPRECATED
01947     case KVP_TYPE_TIMESPEC:
01948         tmp1 = g_new0 (char, 40);
01949         gnc_timespec_to_iso8601_buff (kvp_value_get_timespec (val), tmp1);
01950         tmp2 = g_strdup_printf ("KVP_VALUE_TIMESPEC(%s)", tmp1);
01951         g_free (tmp1);
01952         return tmp2;
01953         break;
01954 #endif
01955     case KVP_TYPE_BINARY:
01956         {
01957             guint64 len;
01958             void *data;
01959             data = kvp_value_get_binary (val, &len);
01960             tmp1 = binary_to_string (data, len);
01961             return g_strdup_printf ("KVP_VALUE_BINARY(%s)",
01962                 tmp1 ? tmp1 : "");
01963         }
01964         break;
01965 
01966     case KVP_TYPE_GLIST:
01967         tmp1 = kvp_value_glist_to_string (kvp_value_get_glist (val));
01968         tmp2 = g_strdup_printf ("KVP_VALUE_GLIST(%s)", tmp1 ? tmp1 : "");
01969         g_free (tmp1);
01970         return tmp2;
01971         break;
01972 
01973     case KVP_TYPE_FRAME:
01974         tmp1 = kvp_frame_to_string (kvp_value_get_frame (val));
01975         tmp2 = g_strdup_printf ("KVP_VALUE_FRAME(%s)", tmp1 ? tmp1 : "");
01976         g_free (tmp1);
01977         return tmp2;
01978         break;
01979 
01980     default:
01981         return g_strdup_printf (" ");
01982         break;
01983     }
01984 }

KvpFrame* qof_kvp_bag_add ( KvpFrame kvp_root,
const gchar *  path,
QofTime qt,
const gchar *  first_name,
  ... 
)

The qof_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:

qof_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 66 of file kvp-util.c.

00068 {
00069     KvpFrame *cwd;
00070     va_list ap;
00071     va_start (ap, first_name);
00072     cwd = qof_kvp_array_va (pwd, path, qt, first_name, ap);
00073     va_end (ap);
00074     return cwd;
00075 }

KvpFrame* qof_kvp_bag_find_by_guid ( KvpFrame root,
const gchar *  path,
const gchar *  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.

Todo:
rename qof_kvp_bag_find_by_guid

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

00090 {
00091     KvpValue *arr;
00092     KvpValueType valtype;
00093     GList *node;
00094 
00095     arr = kvp_frame_get_value (root, path);
00096     valtype = kvp_value_get_type (arr);
00097     if (KVP_TYPE_FRAME == valtype)
00098     {
00099         MATCH_GUID (arr);
00100         return NULL;
00101     }
00102 
00103     /* Its gotta be a single isolated frame, or a list of them. */
00104     if (KVP_TYPE_GLIST != valtype)
00105         return NULL;
00106 
00107     for (node = kvp_value_get_glist (arr); node; node = node->next)
00108     {
00109         KvpValue *va = node->data;
00110         MATCH_GUID (va);
00111     }
00112     return NULL;
00113 }

void qof_kvp_bag_merge ( KvpFrame kvp_into,
const gchar *  intopath,
KvpFrame kvp_from,
const gchar *  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.

Todo:
Rename qof_kvp_bag_merge

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

00190 {
00191     KvpFrame *fr;
00192 
00193     fr = gnc_kvp_bag_get_first (kvp_from, frompath);
00194     while (fr)
00195     {
00196         qof_kvp_bag_remove_frame (kvp_from, frompath, fr);
00197         kvp_frame_add_frame_nc (kvp_into, intopath, fr);
00198         fr = gnc_kvp_bag_get_first (kvp_from, frompath);
00199     }
00200 }

void qof_kvp_bag_remove_frame ( KvpFrame root,
const gchar *  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.


Generated on Fri Sep 1 15:09:03 2006 for QOF by  doxygen 1.4.7