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

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 Basic Value Storing

void kvp_frame_set_gint64 (KvpFrame *frame, const gchar *path, gint64 ival)
void kvp_frame_set_double (KvpFrame *frame, const gchar *path, double dval)
void kvp_frame_set_numeric (KvpFrame *frame, const gchar *path, QofNumeric 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)
#define kvp_frame_set_gnc_numeric   kvp_frame_set_numeric
#define kvp_frame_set_str   kvp_frame_set_string

KvpFrame URL handling

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

KvpFrame Glist Bag Storing

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, QofNumeric 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)
#define kvp_frame_add_gnc_numeric   kvp_frame_add_numeric
#define kvp_frame_add_str   kvp_frame_add_string

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)
gdouble kvp_frame_get_double (const KvpFrame *frame, const gchar *path)
QofNumeric 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 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.

KvpValuekvp_value_new_gint64 (gint64 value)
KvpValuekvp_value_new_double (double value)
KvpValuekvp_value_new_numeric (QofNumeric 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)
#define kvp_value_new_gnc_numeric   kvp_value_new_numeric

KvpValue Value access

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

KvpValueType kvp_value_get_type (const KvpValue *value)
gint64 kvp_value_get_gint64 (const KvpValue *value)
double kvp_value_get_double (const KvpValue *value)
QofNumeric 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 648 of file kvp_frame.c.

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

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.

Definition at line 888 of file kvp_frame.c.

00889 {
00890     char *buff, *p;
00891     if (!frame || !enc)
00892         return;
00893 
00894     /* Loop over all key-value pairs in the encoded string */
00895     buff = g_strdup (enc);
00896     p = buff;
00897     while (*p)
00898     {
00899         char *n, *v;
00900         n = strchr (p, '&');    /* n = next key-value */
00901         if (n)
00902             *n = 0x0;
00903 
00904         v = strchr (p, '=');    /* v =  pointer to value */
00905         if (!v)
00906             break;
00907         *v = 0x0;
00908         v++;
00909 
00910         decode (p);
00911         decode (v);
00912         kvp_frame_set_slot_nc (frame, p, kvp_value_new_string (v));
00913 
00914         if (!n)
00915             break;              /* no next key, we are done */
00916         p = ++n;
00917     }
00918 
00919     g_free (buff);
00920 }

gint kvp_frame_compare ( const KvpFrame fa,
const KvpFrame fb 
)

Similar returns as strcmp.

Definition at line 1733 of file kvp_frame.c.

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

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

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

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

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

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

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

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

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

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

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

gboolean kvp_frame_is_empty ( KvpFrame frame  ) 

Return TRUE if the KvpFrame is empty

Definition at line 138 of file kvp_frame.c.

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

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,
QofNumeric  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 445 of file kvp_frame.c.

00447 {
00448     KvpValue *value;
00449     value = kvp_value_new_gnc_numeric (nval);
00450     frame = kvp_frame_set_value_nc (frame, path, value);
00451     if (!frame)
00452         kvp_value_delete (value);
00453 }

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

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

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

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

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

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

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

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

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

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

KvpValue* kvp_value_copy ( const KvpValue value  ) 

This is a deep value copy.

Definition at line 1567 of file kvp_frame.c.

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

void kvp_value_delete ( KvpValue value  ) 

This is a deep (recursive) delete.

Definition at line 1352 of file kvp_frame.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

KvpFrame* kvp_value_replace_frame_nc ( KvpValue value,
KvpFrame newframe 
)

Replace old frame value with new, return old frame

Definition at line 1537 of file kvp_frame.c.

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

GList* kvp_value_replace_glist_nc ( KvpValue value,
GList *  newlist 
)

Replace old glist value with new, return old glist

Definition at line 1551 of file kvp_frame.c.

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

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

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

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

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

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 Nov 10 04:06:04 2006 for QOF by  doxygen 1.5.1