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  kvpframe.h
 A key-value frame system.
file  kvputil-p.h
 misc odd-job kvp utils engine-private routines
file  kvputil.h
 QOF KVP utility functions.

Data Structures

struct  GHashTableKVPair

Iterators

typedef void(* KvpValueForeachCB )(const gchar *key, KvpValue *value, gpointer data)
void kvp_frame_for_each_slot (KvpFrame *f, KvpValueForeachCB, gpointer 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)
 store the value of the gint64 at the indicated path.
void kvp_frame_set_double (KvpFrame *frame, const gchar *path, gdouble dval)
 store the value of the double at the indicated path.
void kvp_frame_set_numeric (KvpFrame *frame, const gchar *path, QofNumeric nval)
 store the value of the QofNumeric at the indicated path.
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)
 Store a copy of the GUID at the indicated path.
void kvp_frame_set_time (KvpFrame *frame, const gchar *path, QofTime *qt)
 Store a copy of the QofTime at the indicated path.
void kvp_frame_set_boolean (KvpFrame *frame, const gchar *path, gboolean val)
 Store the value of the boolean at the indicated path.
void kvp_frame_set_frame (KvpFrame *frame, const gchar *path, KvpFrame *chld)
 Store a copy of the KvpFrame at the indicated path.
void kvp_frame_set_frame_nc (KvpFrame *frame, const gchar *path, KvpFrame *chld)
 Store a KvpFrame at the indicated path without copying.
KvpFramekvp_frame_set_value (KvpFrame *frame, const gchar *path, const KvpValue *value)
 Copy the KvpValue into the frame.
KvpFramekvp_frame_set_value_nc (KvpFrame *frame, const gchar *path, KvpValue *value)
 Store the KvpValue in the frame without copying.
KvpValuekvp_frame_replace_value_nc (KvpFrame *frame, const gchar *slot, KvpValue *new_value)

KvpFrame Glist Bag Storing

void kvp_frame_add_gint64 (KvpFrame *frame, const gchar *path, gint64 ival)
 add the value of the gint64 to the glist bag
void kvp_frame_add_double (KvpFrame *frame, const gchar *path, gdouble dval)
 Add the value of the double to the glist bag.
void kvp_frame_add_numeric (KvpFrame *frame, const gchar *path, QofNumeric nval)
 Add the value of the QofNumeric to the glist bag.
void kvp_frame_add_time (KvpFrame *frame, const gchar *path, QofTime *qt)
 Add the value of the QofTime to the glist bag.
void kvp_frame_add_string (KvpFrame *frame, const gchar *path, const gchar *str)
 Copy the string to the glist bag at the indicated path.
void kvp_frame_add_boolean (KvpFrame *frame, const gchar *path, gboolean val)
void kvp_frame_add_guid (KvpFrame *frame, const gchar *path, const GUID *guid)
 Copy the GUID to the glist bag at the indicated path.
void kvp_frame_add_frame (KvpFrame *frame, const gchar *path, KvpFrame *chld)
 Copy the frame to the glist bag at the indicated path.
void kvp_frame_add_frame_nc (KvpFrame *frame, const gchar *path, KvpFrame *chld)
 Add the frame to the glist bag without copying.
KvpFramekvp_frame_add_value (KvpFrame *frame, const gchar *path, KvpValue *value)
 Add a copy of the value to the glist bag.
KvpFramekvp_frame_add_value_nc (KvpFrame *frame, const gchar *path, KvpValue *value)

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)
GUID * kvp_frame_get_guid (const KvpFrame *frame, const gchar *path)
gpointer kvp_frame_get_binary (const KvpFrame *frame, const gchar *path, guint64 *size_return)
gboolean kvp_frame_get_boolean (const KvpFrame *frame, const gchar *path)
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_glist_compare (const GList *list1, const GList *list2)
GList * kvp_glist_copy (const GList *list)
void kvp_glist_delete (GList *list)

KvpValue Constructors

The following routines are constructors for kvp_value. Those with pointer arguments copy in the value. The *_nc() versions do *not* copy in their 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_boolean (gboolean 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)

KvpValue Value access

KvpValueType kvp_value_get_type (const KvpValue *value)
gint64 kvp_value_get_gint64 (const KvpValue *value)
gdouble kvp_value_get_double (const KvpValue *value)
QofNumeric kvp_value_get_numeric (const KvpValue *value)
gchar * kvp_value_get_string (const KvpValue *value)
GUID * kvp_value_get_guid (const KvpValue *value)
gpointer 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)
gboolean kvp_value_get_boolean (const KvpValue *value)
QofTimekvp_value_get_time (const KvpValue *value)
gint kvp_value_compare (const KvpValue *va, const KvpValue *vb)

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 URL handling

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

Defines

#define QOF_MOD_KVP   "qof-kvp"

Typedefs

typedef struct _KvpFrame KvpFrame
typedef struct _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, KVP_TYPE_BOOLEAN
}
 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.
gboolean kvp_value_binary_append (KvpValue *v, gpointer data, guint64 size)
gint kvp_frame_compare (const KvpFrame *fa, const KvpFrame *fb)
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)


Typedef Documentation

typedef struct _KvpFrame KvpFrame

Opaque frame structure

Definition at line 74 of file kvpframe.h.

typedef struct _KvpValue KvpValue

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

Definition at line 78 of file kvpframe.h.

typedef void(* KvpValueForeachCB)(const gchar *key, KvpValue *value, gpointer data)

Since:
0.7.2

Definition at line 770 of file kvpframe.h.


Enumeration Type Documentation

enum KvpValueType

possible types in the union KvpValue

Todo:
In the long run, this could be synchronised with the core QOF types, which in turn may or may not be synced to the GValue types in GLib. The QOF types currently unsupported are KVP_TYPE_GLIST and KVP_TYPE_BINARY.
Enumerator:
KVP_TYPE_GINT64  64bit integer
  • QofType : QOF_TYPE_INT64
  • GType : G_TYPE_INT64
  • GLib type : gint64
KVP_TYPE_DOUBLE  standard C double type
  • QofType : QOF_TYPE_DOUBLE
  • GType : G_TYPE_DOUBLE
  • GLib type : gdouble
KVP_TYPE_NUMERIC  128bit denominator/numerator maths.
  • QofType : QOF_TYPE_NUMERIC
  • GType : no direct equivalent, consider QOF_TYPE_DOUBLE
  • GLib type : no direct equivalent, consider QOF_TYPE_DOUBLE
KVP_TYPE_STRING  standard C string
  • QofType : QOF_TYPE_STRING
  • GType : G_TYPE_STRING
  • GLib type : gchar*
KVP_TYPE_GUID  Unique identifier.
  • QofType : QOF_TYPE_GUID
  • GType : no direct equivalent, can be stored as QOF_TYPE_STRING
  • GLib : no direct equivalent, can be stored as QOF_TYPE_STRING.
KVP_TYPE_TIMESPEC 
Deprecated:
QOF_TYPE_DATE
KVP_TYPE_TIME  64bit time/date handling.
  • QofType : QOF_TYPE_TIME
  • GType : No equivalent.
  • GLib type : GDate (not fully equivalent, see QofTime)
KVP_TYPE_BINARY  no QofType/GType/GLib equivalent.
KVP_TYPE_GLIST  no QofType/GType equivalent.
KVP_TYPE_FRAME  no QofType/GType/GLib equivalent.
KVP_TYPE_BOOLEAN  Simple boolean type.
  • QofType : QOF_TYPE_BOOLEAN
  • GType : G_TYPE_BOOLEAN
  • GLib type : gboolean.

Definition at line 87 of file kvpframe.h.

00088 {
00094     KVP_TYPE_GINT64 = 1,
00100     KVP_TYPE_DOUBLE,
00106     KVP_TYPE_NUMERIC,
00112     KVP_TYPE_STRING,
00118     KVP_TYPE_GUID,
00119 #ifndef QOF_DISABLE_DEPRECATED
00120 
00121     KVP_TYPE_TIMESPEC,
00122 #endif
00123 
00128     KVP_TYPE_TIME,
00130     KVP_TYPE_BINARY,
00132     KVP_TYPE_GLIST,
00134     KVP_TYPE_FRAME,
00140     KVP_TYPE_BOOLEAN
00141 } 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 212 of file kvputil.c.

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

void kvp_frame_add_double ( KvpFrame frame,
const gchar *  path,
gdouble  dval 
)

Add the value of the double to the glist bag.

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.

Definition at line 601 of file kvpframe.c.

00602 {
00603     KvpValue *value;
00604     value = kvp_value_new_double (dval);
00605     frame = kvp_frame_add_value_nc (frame, path, value);
00606     if (!frame)
00607         kvp_value_delete (value);
00608 }

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

Copy the frame 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.

Definition at line 662 of file kvpframe.c.

00663 {
00664     KvpValue *value;
00665     value = kvp_value_new_frame (fr);
00666     frame = kvp_frame_add_value_nc (frame, path, value);
00667     if (!frame)
00668         kvp_value_delete (value);
00669 }

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

Add the frame to the glist bag without copying.

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

Definition at line 672 of file kvpframe.c.

00673 {
00674     KvpValue *value;
00675     value = kvp_value_new_frame_nc (fr);
00676     frame = kvp_frame_add_value_nc (frame, path, value);
00677     if (!frame)
00678         kvp_value_delete (value);
00679 }

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

add the value of the gint64 to the glist bag

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.

Definition at line 591 of file kvpframe.c.

00592 {
00593     KvpValue *value;
00594     value = kvp_value_new_gint64 (ival);
00595     frame = kvp_frame_add_value_nc (frame, path, value);
00596     if (!frame)
00597         kvp_value_delete (value);
00598 }

void kvp_frame_add_guid ( KvpFrame frame,
const gchar *  path,
const GUID *  guid 
)

Copy the GUID 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.

Definition at line 652 of file kvpframe.c.

00653 {
00654     KvpValue *value;
00655     value = kvp_value_new_guid (guid);
00656     frame = kvp_frame_add_value_nc (frame, path, value);
00657     if (!frame)
00658         kvp_value_delete (value);
00659 }

void kvp_frame_add_numeric ( KvpFrame frame,
const gchar *  path,
QofNumeric  nval 
)

Add the value of the QofNumeric to the glist bag.

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.

Definition at line 611 of file kvpframe.c.

00613 {
00614     KvpValue *value;
00615     value = kvp_value_new_numeric (nval);
00616     frame = kvp_frame_add_value_nc (frame, path, value);
00617     if (!frame)
00618         kvp_value_delete (value);
00619 }

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

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

Definition at line 642 of file kvpframe.c.

00643 {
00644     KvpValue *value;
00645     value = kvp_value_new_string (str);
00646     frame = kvp_frame_add_value_nc (frame, path, value);
00647     if (!frame)
00648         kvp_value_delete (value);
00649 }

void kvp_frame_add_time ( KvpFrame frame,
const gchar *  path,
QofTime qt 
)

Add the value of the QofTime to the glist bag.

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.

Definition at line 622 of file kvpframe.c.

00623 {
00624     KvpValue *value;
00625     value = kvp_value_new_time (qt);
00626     frame = kvp_frame_add_value_nc (frame, path, value);
00627     if (!frame)
00628         kvp_value_delete (value);
00629 }

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 880 of file kvpframe.c.

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

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

Add a copy of the value to the glist bag.

If not all frame components of the path exist, they are created. If there was another item previously stored at that path, then the path is converted to a bag, and the old value, along with the new value, is added to the bag. This routine returns the pointer to the last frame (the actual frame to which the value was added), or NULL if there was an error of any sort (typically, a parse error in the path).

Definition at line 581 of file kvpframe.c.

00582 {
00583     value = kvp_value_copy (value);
00584     frame = kvp_frame_add_value_nc (frame, path, value);
00585     if (!frame)
00586         kvp_value_delete (value);
00587     return frame;
00588 }

gint kvp_frame_compare ( const KvpFrame fa,
const KvpFrame fb 
)

Similar returns as strcmp.

Definition at line 1757 of file kvpframe.c.

01758 {
01759     KvpFrameCompare status;
01760 
01761     if (fa == fb)
01762         return 0;
01763     /* nothing is always less than something */
01764     if (!fa && fb)
01765         return -1;
01766     if (fa && !fb)
01767         return 1;
01768 
01769     /* nothing is always less than something */
01770     if (!fa->hash && fb->hash)
01771         return -1;
01772     if (fa->hash && !fb->hash)
01773         return 1;
01774 
01775     status.compare = 0;
01776     status.other_frame = (KvpFrame *) fb;
01777 
01778     kvp_frame_for_each_slot ((KvpFrame *) fa, kvp_frame_compare_helper,
01779         &status);
01780 
01781     if (status.compare != 0)
01782         return status.compare;
01783 
01784     status.other_frame = (KvpFrame *) fa;
01785 
01786     kvp_frame_for_each_slot ((KvpFrame *) fb, kvp_frame_compare_helper,
01787         &status);
01788 
01789     return (-status.compare);
01790 }

KvpFrame* kvp_frame_copy ( const KvpFrame frame  ) 

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

Definition at line 156 of file kvpframe.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.

Definition at line 118 of file kvpframe.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,
KvpValueForeachCB  ,
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 1650 of file kvpframe.c.

01651 {
01652     if (!f)
01653         return;
01654     if (!proc)
01655         return;
01656     if (!(f->hash))
01657         return;
01658     g_hash_table_foreach (f->hash, (GHFunc) proc, data);
01659 }

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.

Returns:
The KvpFrame at the specified path, or NULL if it doesn't exist.

Definition at line 984 of file kvpframe.c.

00985 {
00986     gchar *key = NULL;
00987     frame = get_trailer_or_null (frame, path, &key);
00988     return kvp_value_get_frame (kvp_frame_get_slot (frame, key));
00989 }

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 kvpframe.c.

01003 {
01004     if (!frame)
01005         return frame;
01006 
01007     while (key_path)
01008     {
01009         const gchar *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* kvp_frame_get_frame()

Definition at line 1024 of file kvpframe.c.

01025 {
01026     va_list ap;
01027     if (!frame || !key)
01028         return frame;
01029 
01030     va_start (ap, key);
01031 
01032     while (key)
01033     {
01034         frame = get_or_make (frame, key);
01035         if (!frame)
01036             break;              /* error, should never occur */
01037         key = va_arg (ap, const char *);
01038     }
01039 
01040     va_end (ap);
01041     return frame;
01042 }

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

Definition at line 1045 of file kvpframe.c.

01046 {
01047     gchar *root;
01048     if (!frame || !key_path)
01049         return frame;
01050 
01051     root = g_strdup (key_path);
01052     frame = kvp_frame_get_frame_slash_trash (frame, root);
01053     g_free (root);
01054     return frame;
01055 }

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.

Definition at line 1060 of file kvpframe.c.

01061 {
01062     va_list ap;
01063     KvpValue *value;
01064     const gchar *key;
01065 
01066     if (!frame || !first_key)
01067         return NULL;
01068 
01069     va_start (ap, first_key);
01070 
01071     key = first_key;
01072     value = NULL;
01073 
01074     while (TRUE)
01075     {
01076         value = kvp_frame_get_slot (frame, key);
01077         if (!value)
01078             break;
01079 
01080         key = va_arg (ap, const gchar *);
01081         if (!key)
01082             break;
01083 
01084         frame = kvp_value_get_frame (value);
01085         if (!frame)
01086         {
01087             value = NULL;
01088             break;
01089         }
01090     }
01091 
01092     va_end (ap);
01093 
01094     return value;
01095 }

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 kvpframe.c.

01099 {
01100     if (!frame || !key_path)
01101         return NULL;
01102 
01103     while (TRUE)
01104     {
01105         const gchar *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 137 of file kvpframe.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 100 of file kvpframe.c.

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

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.

Definition at line 178 of file kvpframe.c.

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

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

Definition at line 516 of file kvpframe.c.

00518 {
00519     KvpValue *old_value;
00520     gchar *last_key;
00521 
00522     last_key = NULL;
00523     if (new_value)
00524         frame = get_trailer_make (frame, key_path, &last_key);
00525     else
00526         frame =
00527             (KvpFrame *) get_trailer_or_null (frame, key_path, &last_key);
00528     if (!frame)
00529         return NULL;
00530 
00531     old_value = kvp_frame_replace_slot_nc (frame, last_key, new_value);
00532     return old_value;
00533 }

void kvp_frame_set_boolean ( KvpFrame frame,
const gchar *  path,
gboolean  val 
)

Store the value of the boolean at the indicated path.

If not all frame components of the path exist, they are created.

Definition at line 431 of file kvpframe.c.

00433 {
00434     KvpValue * value;
00435     value = kvp_value_new_boolean (val);
00436     frame = kvp_frame_set_value_nc (frame, path, value);
00437     if (!frame)
00438         kvp_value_delete (value);
00439 }

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

store the value of the double at the indicated path.

If not all frame components of the path exist, they are created.

Definition at line 400 of file kvpframe.c.

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

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

Store a copy of the KvpFrame at the indicated path.

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

Definition at line 464 of file kvpframe.c.

00465 {
00466     KvpValue *value;
00467     value = kvp_value_new_frame (fr);
00468     frame = kvp_frame_set_value_nc (frame, path, value);
00469     if (!frame)
00470         kvp_value_delete (value);
00471 }

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

Store a KvpFrame at the indicated path without copying.

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

Definition at line 474 of file kvpframe.c.

00475 {
00476     KvpValue *value;
00477     value = kvp_value_new_frame_nc (fr);
00478     frame = kvp_frame_set_value_nc (frame, path, value);
00479     if (!frame)
00480         kvp_value_delete (value);
00481 }

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.

Definition at line 390 of file kvpframe.c.

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

void kvp_frame_set_guid ( KvpFrame frame,
const gchar *  path,
const GUID *  guid 
)

Store a copy of the GUID at the indicated path.

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

Definition at line 453 of file kvpframe.c.

00455 {
00456     KvpValue *value;
00457     value = kvp_value_new_guid (guid);
00458     frame = kvp_frame_set_value_nc (frame, path, value);
00459     if (!frame)
00460         kvp_value_delete (value);
00461 }

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

store the value of the QofNumeric at the indicated path.

If not all frame components of the path exist, they are created.

Definition at line 420 of file kvpframe.c.

00422 {
00423     KvpValue *value;
00424     value = kvp_value_new_numeric (nval);
00425     frame = kvp_frame_set_value_nc (frame, path, value);
00426     if (!frame)
00427         kvp_value_delete (value);
00428 }

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.

Definition at line 684 of file kvpframe.c.

00686 {
00687     KvpValue *new_value = NULL;
00688 
00689     if (!frame)
00690         return;
00691 
00692     g_return_if_fail (slot && *slot != '\0');
00693 
00694     if (value)
00695         new_value = kvp_value_copy (value);
00696     kvp_frame_set_slot_destructively (frame, slot, new_value);
00697 }

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.

Definition at line 700 of file kvpframe.c.

00702 {
00703     if (!frame)
00704         return;
00705 
00706     g_return_if_fail (slot && *slot != '\0');
00707 
00708     kvp_frame_set_slot_destructively (frame, slot, value);
00709 }

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.

Definition at line 726 of file kvpframe.c.

00728 {
00729     va_list ap;
00730     const gchar *key;
00731 
00732     if (!frame)
00733         return;
00734 
00735     g_return_if_fail (first_key && *first_key != '\0');
00736 
00737     va_start (ap, first_key);
00738 
00739     key = first_key;
00740 
00741     while (TRUE)
00742     {
00743         KvpValue *value;
00744         const gchar *next_key;
00745 
00746         next_key = va_arg (ap, const gchar *);
00747         if (!next_key)
00748         {
00749             kvp_frame_set_slot (frame, key, new_value);
00750             break;
00751         }
00752 
00753         g_return_if_fail (*next_key != '\0');
00754 
00755         value = kvp_frame_get_slot (frame, key);
00756         if (!value)
00757         {
00758             KvpFrame *new_frame = kvp_frame_new ();
00759             KvpValue *frame_value = kvp_value_new_frame (new_frame);
00760 
00761             kvp_frame_set_slot_nc (frame, key, frame_value);
00762 
00763             value = kvp_frame_get_slot (frame, key);
00764             if (!value)
00765                 break;
00766         }
00767 
00768         frame = kvp_value_get_frame (value);
00769         if (!frame)
00770             break;
00771 
00772         key = next_key;
00773     }
00774 
00775     va_end (ap);
00776 }

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 779 of file kvpframe.c.

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

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.

Definition at line 442 of file kvpframe.c.

00444 {
00445     KvpValue *value;
00446     value = kvp_value_new_string (str);
00447     frame = kvp_frame_set_value_nc (frame, path, value);
00448     if (!frame)
00449         kvp_value_delete (value);
00450 }

void kvp_frame_set_time ( KvpFrame frame,
const gchar *  path,
QofTime qt 
)

Store a copy of the QofTime at the indicated path.

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

Definition at line 410 of file kvpframe.c.

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

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

Copy the KvpValue into the frame.

If the path contains slashes '/', these are assumed to represent a sequence of keys. The old value at this location, if any, is destroyed.

Pointers passed as arguments into this routine remain the responsibility of the caller.

Parameters:
frame The frame to hold the copied value.
path The location of the value in the frame.
value The value to be copied.
Returns:
a pointer to the actual frame into which the value was inserted or NULL if the frame could not be found.

Definition at line 499 of file kvpframe.c.

00501 {
00502     KvpValue *new_value = NULL;
00503     gchar *last_key;
00504 
00505     frame = get_trailer_make (frame, key_path, &last_key);
00506     if (!frame)
00507         return NULL;
00508 
00509     if (value)
00510         new_value = kvp_value_copy (value);
00511     kvp_frame_set_slot_destructively (frame, last_key, new_value);
00512     return frame;
00513 }

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

Store the KvpValue in the frame without copying.

If the path contains slashes '/', these are assumed to represent a sequence of keys.

The returned value is a pointer to the actual frame into which the value was inserted; it is NULL if the frame couldn't be found (and thus the value wasn't inserted). The old value at this location, if any, is destroyed.

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

Definition at line 486 of file kvpframe.c.

00488 {
00489     gchar *last_key;
00490 
00491     frame = get_trailer_make (frame, key_path, &last_key);
00492     if (!frame)
00493         return NULL;
00494     kvp_frame_set_slot_destructively (frame, last_key, value);
00495     return frame;
00496 }

gint kvp_glist_compare ( const GList *  list1,
const GList *  list2 
)

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

Definition at line 1170 of file kvpframe.c.

01171 {
01172     const GList *lp1;
01173     const GList *lp2;
01174 
01175     if (list1 == list2)
01176         return 0;
01177 
01178     /* Nothing is always less than something */
01179     if (!list1 && list2)
01180         return -1;
01181     if (list1 && !list2)
01182         return 1;
01183 
01184     lp1 = list1;
01185     lp2 = list2;
01186     while (lp1 && lp2)
01187     {
01188         KvpValue *v1 = (KvpValue *) lp1->data;
01189         KvpValue *v2 = (KvpValue *) lp2->data;
01190         gint vcmp = kvp_value_compare (v1, v2);
01191         if (vcmp != 0)
01192             return vcmp;
01193         lp1 = lp1->next;
01194         lp2 = lp2->next;
01195     }
01196     if (!lp1 && lp2)
01197         return -1;
01198     if (!lp2 && lp1)
01199         return 1;
01200     return 0;
01201 }

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 kvpframe.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 kvpframe.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,
gpointer  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 1662 of file kvpframe.c.

01663 {
01664     if (kva == kvb)
01665         return 0;
01666     /* nothing is always less than something */
01667     if (!kva && kvb)
01668         return -1;
01669     if (kva && !kvb)
01670         return 1;
01671 
01672     if (kva->type < kvb->type)
01673         return -1;
01674     if (kva->type > kvb->type)
01675         return 1;
01676 
01677     switch (kva->type)
01678     {
01679     case KVP_TYPE_GINT64:
01680         if (kva->value.int64 < kvb->value.int64)
01681             return -1;
01682         if (kva->value.int64 > kvb->value.int64)
01683             return 1;
01684         return 0;
01685         break;
01686     case KVP_TYPE_DOUBLE:
01687         return qof_util_double_compare (kva->value.dbl, kvb->value.dbl);
01688         break;
01689     case KVP_TYPE_NUMERIC:
01690         return qof_numeric_compare (kva->value.numeric,
01691             kvb->value.numeric);
01692         break;
01693     case KVP_TYPE_STRING:
01694         return strcmp (kva->value.str, kvb->value.str);
01695         break;
01696     case KVP_TYPE_GUID:
01697         return guid_compare (kva->value.guid, kvb->value.guid);
01698         break;
01699     case KVP_TYPE_BOOLEAN:
01700     {
01701         /* true > false */
01702         if (kva->value.gbool != kvb->value.gbool)
01703             return (kva->value.gbool) ? 1 : -1;
01704         return 0;
01705         break;
01706     }
01707     case KVP_TYPE_TIME :
01708         return qof_time_cmp (kva->value.qt, kvb->value.qt);
01709         break;
01710 #ifndef QOF_DISABLE_DEPRECATED
01711     case KVP_TYPE_TIMESPEC:
01712         return timespec_cmp (&(kva->value.timespec),
01713             &(kvb->value.timespec));
01714         break;
01715 #endif
01716     case KVP_TYPE_BINARY:
01717         if (kva->value.binary.datasize < kvb->value.binary.datasize)
01718             return -1;
01719         if (kva->value.binary.datasize > kvb->value.binary.datasize)
01720             return 1;
01721         return memcmp (kva->value.binary.data,
01722             kvb->value.binary.data, kva->value.binary.datasize);
01723         break;
01724     case KVP_TYPE_GLIST:
01725         return kvp_glist_compare (kva->value.list, kvb->value.list);
01726         break;
01727     case KVP_TYPE_FRAME:
01728         return kvp_frame_compare (kva->value.frame, kvb->value.frame);
01729         break;
01730     }
01731     return 0;
01732 }

KvpValue* kvp_value_copy ( const KvpValue value  ) 

This is a deep value copy.

Definition at line 1601 of file kvpframe.c.

01602 {
01603     if (!value)
01604         return NULL;
01605 
01606     switch (value->type)
01607     {
01608     case KVP_TYPE_GINT64:
01609         return kvp_value_new_gint64 (value->value.int64);
01610         break;
01611     case KVP_TYPE_DOUBLE:
01612         return kvp_value_new_double (value->value.dbl);
01613         break;
01614     case KVP_TYPE_NUMERIC:
01615         return kvp_value_new_numeric (value->value.numeric);
01616         break;
01617     case KVP_TYPE_STRING:
01618         return kvp_value_new_string (value->value.str);
01619         break;
01620     case KVP_TYPE_GUID:
01621         return kvp_value_new_guid (value->value.guid);
01622         break;
01623     case KVP_TYPE_BOOLEAN:
01624         return NULL;
01625         return kvp_value_new_boolean (value->value.gbool);
01626         break;
01627     case KVP_TYPE_TIME :
01628         return kvp_value_new_time (value->value.qt);
01629         break;
01630 #ifndef QOF_DISABLE_DEPRECATED
01631     case KVP_TYPE_TIMESPEC:
01632         return kvp_value_new_timespec (value->value.timespec);
01633         break;
01634 #endif
01635     case KVP_TYPE_BINARY:
01636         return kvp_value_new_binary (value->value.binary.data,
01637             value->value.binary.datasize);
01638         break;
01639     case KVP_TYPE_GLIST:
01640         return kvp_value_new_glist (value->value.list);
01641         break;
01642     case KVP_TYPE_FRAME:
01643         return kvp_value_new_frame (value->value.frame);
01644         break;
01645     }
01646     return NULL;
01647 }

void kvp_value_delete ( KvpValue value  ) 

This is a deep (recursive) delete.

Definition at line 1361 of file kvpframe.c.

01362 {
01363     if (!value)
01364         return;
01365 
01366     switch (value->type)
01367     {
01368     case KVP_TYPE_STRING:
01369         g_free (value->value.str);
01370         break;
01371     case KVP_TYPE_GUID:
01372         g_free (value->value.guid);
01373         break;
01374     case KVP_TYPE_BINARY:
01375         g_free (value->value.binary.data);
01376         break;
01377     case KVP_TYPE_GLIST:
01378         kvp_glist_delete (value->value.list);
01379         break;
01380     case KVP_TYPE_FRAME:
01381         kvp_frame_delete (value->value.frame);
01382         break;
01383     case KVP_TYPE_BOOLEAN:
01384     case KVP_TYPE_GINT64:
01385     case KVP_TYPE_DOUBLE:
01386     case KVP_TYPE_NUMERIC:
01387     default:
01388         break;
01389     }
01390     g_free (value);
01391 }

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

01508 {
01509     if (!value)
01510     {
01511         if (size_return)
01512             *size_return = 0;
01513         PERR (" no size specified");
01514         return NULL;
01515     }
01516 
01517     if (value->type == KVP_TYPE_BINARY)
01518     {
01519         if (size_return)
01520             *size_return = value->value.binary.datasize;
01521         return value->value.binary.data;
01522     }
01523     else
01524     {
01525         if (size_return)
01526             *size_return = 0;
01527         PERR (" value type %d does not match KVP_TYPE_BINARY",
01528             value->type);
01529         return NULL;
01530     }
01531 }

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 1549 of file kvpframe.c.

01550 {
01551     if (!value)
01552         return NULL;
01553     if (value->type == KVP_TYPE_FRAME)
01554         return value->value.frame;
01555     else
01556     {
01557         PERR (" value type %d does not match KVP_TYPE_FRAME",
01558             value->type);
01559         return NULL;
01560     }
01561 }

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.

Todo:
kvp_value_get_ functions need to set QofError so that users can check that a NULL or zero value is actually a real value and not an error result.

Definition at line 1402 of file kvpframe.c.

01403 {
01404     if (!value)
01405         return 0;
01406     if (value->type == KVP_TYPE_GINT64)
01407         return value->value.int64;
01408     else
01409     {
01410         PERR (" value type %d does not match KVP_TYPE_GINT64",
01411             value->type);
01412         return 0;
01413     }
01414 }

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 1534 of file kvpframe.c.

01535 {
01536     if (!value)
01537         return NULL;
01538     if (value->type == KVP_TYPE_GLIST)
01539         return value->value.list;
01540     else
01541     {
01542         PERR (" value type %d does not match KVP_TYPE_GLIST",
01543             value->type);
01544         return NULL;
01545     }
01546 }

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 1477 of file kvpframe.c.

01478 {
01479     if (!value)
01480         return NULL;
01481     if (value->type == KVP_TYPE_GUID)
01482         return value->value.guid;
01483     else
01484     {
01485         PERR (" value type %d does not match KVP_TYPE_GUID",
01486             value->type);
01487         return NULL;
01488     }
01489 }

gchar* kvp_value_get_string ( const KvpValue value  ) 

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

Definition at line 1447 of file kvpframe.c.

01448 {
01449     if (!value)
01450         return NULL;
01451     if (value->type == KVP_TYPE_STRING)
01452         return value->value.str;
01453     else
01454     {
01455         PERR (" value type %d does not match KVP_TYPE_STRING",
01456             value->type);
01457         return NULL;
01458     }
01459 }

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

KvpValue* kvp_value_new_boolean ( gboolean  value  ) 

Since:
0.7.2

Definition at line 1226 of file kvpframe.c.

01227 {
01228     KvpValue * retval = g_new0 (KvpValue, 1);
01229     retval->type = KVP_TYPE_BOOLEAN;
01230     retval->value.gbool = value;
01231     return retval;
01232 }

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 1348 of file kvpframe.c.

01349 {
01350     KvpValue *retval;
01351     if (!value)
01352         return NULL;
01353 
01354     retval = g_new0 (KvpValue, 1);
01355     retval->type = KVP_TYPE_FRAME;
01356     retval->value.frame = value;
01357     return retval;
01358 }

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 1309 of file kvpframe.c.

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

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 1322 of file kvpframe.c.

01323 {
01324     KvpValue *retval;
01325     if (!value)
01326         return NULL;
01327 
01328     retval = g_new0 (KvpValue, 1);
01329     retval->type = KVP_TYPE_GLIST;
01330     retval->value.list = value;
01331     return retval;
01332 }

KvpFrame* kvp_value_replace_frame_nc ( KvpValue value,
KvpFrame newframe 
)

Replace old frame value with new, return old frame

Definition at line 1564 of file kvpframe.c.

01565 {
01566     KvpFrame *oldframe;
01567     if (!value)
01568         return NULL;
01569     if (KVP_TYPE_FRAME != value->type)
01570     {
01571         PERR (" value type %d does not match KVP_TYPE_FRAME",
01572             value->type);
01573         return NULL;
01574     }
01575     oldframe = value->value.frame;
01576     value->value.frame = newframe;
01577     return oldframe;
01578 }

GList* kvp_value_replace_glist_nc ( KvpValue value,
GList *  newlist 
)

Replace old glist value with new, return old glist

Definition at line 1581 of file kvpframe.c.

01582 {
01583     GList *oldlist;
01584     if (!value)
01585         return NULL;
01586     if (KVP_TYPE_GLIST != value->type)
01587     {
01588         PERR (" value type %d does not match KVP_TYPE_GLIST",
01589             value->type);
01590         return NULL;
01591     }
01592 
01593     oldlist = value->value.list;
01594     value->value.list = newlist;
01595     return oldlist;
01596 }

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 1848 of file kvpframe.c.

01849 {
01850     gchar *tmp1;
01851     gchar *tmp2;
01852     const gchar *ctmp;
01853 
01854     g_return_val_if_fail (val, NULL);
01855     tmp1 = g_strdup ("");
01856     switch (kvp_value_get_type (val))
01857     {
01858         case KVP_TYPE_GINT64:
01859         {
01860             return g_strdup_printf ("%" G_GINT64_FORMAT,
01861                 kvp_value_get_gint64 (val));
01862             break;
01863         }
01864         case KVP_TYPE_DOUBLE:
01865         {
01866             return g_strdup_printf ("(%g)", kvp_value_get_double (val));
01867             break;
01868         }
01869         case KVP_TYPE_NUMERIC:
01870         {
01871             tmp1 = qof_numeric_to_string (kvp_value_get_numeric (val));
01872             tmp2 = g_strdup_printf ("%s", tmp1 ? tmp1 : "");
01873             g_free (tmp1);
01874             return tmp2;
01875             break;
01876         }
01877         case KVP_TYPE_STRING:
01878         {
01879             tmp1 = kvp_value_get_string (val);
01880             return g_strdup_printf ("%s", tmp1 ? tmp1 : "");
01881             break;
01882         }
01883         case KVP_TYPE_GUID:
01884         {
01885             ctmp = guid_to_string (kvp_value_get_guid (val));
01886             tmp2 = g_strdup_printf ("%s", ctmp ? ctmp : "");
01887             return tmp2;
01888             break;
01889         }
01890 #ifndef QOF_DISABLE_DEPRECATED
01891         case KVP_TYPE_TIMESPEC:
01892         {
01893             time_t t;
01894             t = timespecToTime_t (kvp_value_get_timespec (val));
01895             qof_date_format_set (QOF_DATE_FORMAT_UTC);
01896             return qof_print_date (t);
01897             break;
01898         }
01899 #endif
01900         case KVP_TYPE_BOOLEAN :
01901             return (kvp_value_get_boolean (val)) ? "TRUE" : "FALSE";
01902         case KVP_TYPE_BINARY:
01903         {
01904             guint64 len;
01905             gpointer data;
01906             data = kvp_value_get_binary (val, &len);
01907             tmp1 = binary_to_string (data, len);
01908             return g_strdup_printf ("%s", tmp1 ? tmp1 : "");
01909             break;
01910         }
01911         case KVP_TYPE_GLIST:
01912         /* borked. kvp_value_glist_to_string is a debug fcn */
01913         {
01914             tmp1 = kvp_value_glist_to_string (kvp_value_get_glist (val));
01915             tmp2 = g_strdup_printf ("%s", tmp1 ? tmp1 : "");
01916             g_free (tmp1);
01917             return tmp2;
01918             break;
01919         }
01920         case KVP_TYPE_FRAME:
01921         {
01922             KvpFrame *frame;
01923 
01924             frame = kvp_value_get_frame (val);
01925             if (frame->hash)
01926             {
01927                 tmp1 = g_strdup ("");
01928                 g_hash_table_foreach (frame->hash,
01929                     kvp_frame_to_bare_string_helper, &tmp1);
01930             }
01931             return tmp1;
01932             break;
01933         }
01934         default:
01935             return g_strdup_printf (" ");
01936             break;
01937     }
01938 }

gchar* kvp_value_to_string ( const KvpValue val  ) 

Debug version.

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

Definition at line 1941 of file kvpframe.c.

01942 {
01943     gchar *tmp1;
01944     gchar *tmp2;
01945     const gchar *ctmp;
01946 
01947     g_return_val_if_fail (val, NULL);
01948 
01949     switch (kvp_value_get_type (val))
01950     {
01951         case KVP_TYPE_GINT64:
01952         {
01953             return g_strdup_printf ("KVP_VALUE_GINT64(%" G_GINT64_FORMAT ")",
01954                 kvp_value_get_gint64 (val));
01955             break;
01956         }
01957         case KVP_TYPE_DOUBLE:
01958         {
01959             return g_strdup_printf ("KVP_VALUE_DOUBLE(%g)",
01960                 kvp_value_get_double (val));
01961             break;
01962         }
01963         case KVP_TYPE_NUMERIC:
01964         {
01965             tmp1 = qof_numeric_to_string (kvp_value_get_numeric (val));
01966             tmp2 = g_strdup_printf ("KVP_VALUE_NUMERIC(%s)", tmp1 ? tmp1 : "");
01967             g_free (tmp1);
01968             return tmp2;
01969             break;
01970         }
01971         case KVP_TYPE_STRING:
01972         {
01973             tmp1 = kvp_value_get_string (val);
01974             return g_strdup_printf ("KVP_VALUE_STRING(%s)", tmp1 ? tmp1 : "");
01975             break;
01976         }
01977         case KVP_TYPE_GUID:
01978         {
01979             /* THREAD-UNSAFE */
01980             ctmp = guid_to_string (kvp_value_get_guid (val));
01981             tmp2 = g_strdup_printf ("KVP_VALUE_GUID(%s)", ctmp ? ctmp : "");
01982             return tmp2;
01983             break;
01984         }
01985 #ifndef QOF_DISABLE_DEPRECATED
01986         case KVP_TYPE_TIMESPEC:
01987         {
01988             tmp1 = g_new0 (gchar, 40);
01989             gnc_timespec_to_iso8601_buff (kvp_value_get_timespec (val), tmp1);
01990             tmp2 = g_strdup_printf ("KVP_VALUE_TIMESPEC(%s)", tmp1);
01991             g_free (tmp1);
01992             return tmp2;
01993             break;
01994         }
01995 #endif
01996         case KVP_TYPE_BINARY:
01997         {
01998             guint64 len;
01999             gpointer data;
02000             data = kvp_value_get_binary (val, &len);
02001             tmp1 = binary_to_string (data, len);
02002             return g_strdup_printf ("KVP_VALUE_BINARY(%s)",
02003                 tmp1 ? tmp1 : "");
02004             break;
02005         }
02006         case KVP_TYPE_GLIST:
02007         {
02008             tmp1 = kvp_value_glist_to_string (kvp_value_get_glist (val));
02009             tmp2 = g_strdup_printf ("KVP_VALUE_GLIST(%s)", tmp1 ? tmp1 : "");
02010             g_free (tmp1);
02011             return tmp2;
02012             break;
02013         }
02014         case KVP_TYPE_FRAME:
02015         {
02016             tmp1 = kvp_frame_to_string (kvp_value_get_frame (val));
02017             tmp2 = g_strdup_printf ("KVP_VALUE_FRAME(%s)", tmp1 ? tmp1 : "");
02018             g_free (tmp1);
02019             return tmp2;
02020             break;
02021         }
02022         default:
02023             return g_strdup_printf (" ");
02024             break;
02025     }
02026 }

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 67 of file kvputil.c.

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

KvpFrame* qof_kvp_bag_find_by_guid ( KvpFrame root,
const gchar *  path,
const gchar *  guid_name,
GUID *  desired_guid 
)

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

Definition at line 89 of file kvputil.c.

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

void qof_kvp_bag_merge ( KvpFrame kvp_into,
const gchar *  intopath,
KvpFrame kvp_from,
const gchar *  frompath 
)

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

Definition at line 186 of file kvputil.c.

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

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.

Definition at line 119 of file kvputil.c.

00120 {
00121     KvpValue *arr;
00122     KvpValueType valtype;
00123     GList *node, *listhead;
00124 
00125     arr = kvp_frame_get_value (root, path);
00126     valtype = kvp_value_get_type (arr);
00127     if (KVP_TYPE_FRAME == valtype)
00128     {
00129         if (fr == kvp_value_get_frame (arr))
00130         {
00131             KvpValue *old_val =
00132                 kvp_frame_replace_value_nc (root, path, NULL);
00133             kvp_value_replace_frame_nc (old_val, NULL);
00134             kvp_value_delete (old_val);
00135         }
00136         return;
00137     }
00138 
00139     /* Its got to be a single isolated frame, or a list of them. */
00140     if (KVP_TYPE_GLIST != valtype)
00141         return;
00142 
00143     listhead = kvp_value_get_glist (arr);
00144     for (node = listhead; node; node = node->next)
00145     {
00146         KvpValue *va = node->data;
00147         if (fr == kvp_value_get_frame (va))
00148         {
00149             listhead = g_list_remove_link (listhead, node);
00150             g_list_free_1 (node);
00151             kvp_value_replace_glist_nc (arr, listhead);
00152             kvp_value_replace_frame_nc (va, NULL);
00153             kvp_value_delete (va);
00154             return;
00155         }
00156     }
00157 }


Generated on Thu Jan 31 22:50:27 2008 for QOF by  doxygen 1.5.4