kvp_frame.h File Reference


Detailed Description

A key-value frame system.

Author:
Copyright (C) 2000 Bill Gribble

Copyright (C) 2003 Linas Vepstas <linas@linas.org>

Definition in file kvp_frame.h.

#include "gnc-date.h"
#include "gnc-numeric.h"
#include "guid.h"

Go to the source code of this file.

KvpFrame Basic Value Storing

#define kvp_frame_set_gnc_numeric   kvp_frame_set_numeric
#define kvp_frame_set_str   kvp_frame_set_string
void kvp_frame_set_gint64 (KvpFrame *frame, const gchar *path, gint64 ival)
void kvp_frame_set_double (KvpFrame *frame, const gchar *path, double dval)
void kvp_frame_set_numeric (KvpFrame *frame, const gchar *path, gnc_numeric nval)
void kvp_frame_set_timespec (KvpFrame *frame, const gchar *path, Timespec ts)
void kvp_frame_set_string (KvpFrame *frame, const gchar *path, const char *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_frame (KvpFrame *frame, const gchar *path, KvpFrame *chld)
void kvp_frame_set_frame_nc (KvpFrame *frame, const gchar *path, KvpFrame *chld)
KvpFramekvp_frame_set_value (KvpFrame *frame, const gchar *path, const KvpValue *value)
KvpFramekvp_frame_set_value_nc (KvpFrame *frame, const gchar *path, KvpValue *value)
KvpValuekvp_frame_replace_value_nc (KvpFrame *frame, const gchar *slot, KvpValue *new_value)

KvpFrame Glist Bag Storing

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

KvpValue Constructors

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

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

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

KvpFrame Constructors

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

KvpFrame URL handling

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

KvpFrame Value Fetching

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

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

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

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

gint64 kvp_frame_get_gint64 (const KvpFrame *frame, const gchar *path)
double kvp_frame_get_double (const KvpFrame *frame, const gchar *path)
gnc_numeric kvp_frame_get_numeric (const KvpFrame *frame, const gchar *path)
gchar * kvp_frame_get_string (const KvpFrame *frame, const gchar *path)
GUIDkvp_frame_get_guid (const KvpFrame *frame, const gchar *path)
void * kvp_frame_get_binary (const KvpFrame *frame, const gchar *path, guint64 *size_return)
Timespec kvp_frame_get_timespec (const KvpFrame *frame, const gchar *path)
KvpValuekvp_frame_get_value (const KvpFrame *frame, const gchar *path)
KvpFramekvp_frame_get_frame (const KvpFrame *frame, const gchar *path)
KvpFramekvp_frame_get_frame_path (KvpFrame *frame, const gchar *,...)
KvpFramekvp_frame_get_frame_gslist (KvpFrame *frame, GSList *key_path)
KvpFramekvp_frame_get_frame_slash (KvpFrame *frame, const gchar *path)

KvpFrame KvpValue low-level storing routines.

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

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

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

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

KvpFrame KvpValue Low-Level Retrieval Routines

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

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

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

KvpValuekvp_frame_get_slot (const KvpFrame *frame, const gchar *key)
KvpValuekvp_frame_get_slot_path (KvpFrame *frame, const gchar *first_key,...)
KvpValuekvp_frame_get_slot_path_gslist (KvpFrame *frame, GSList *key_path)
gint kvp_frame_compare (const KvpFrame *fa, const KvpFrame *fb)
gint double_compare (double v1, double v2)

KvpValue List Convenience Functions

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

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

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

KvpValue Value access

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

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

Iterators

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

Defines

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

Typedefs

typedef _KvpFrame KvpFrame
typedef _KvpValue KvpValue

Enumerations

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

Functions

gchar * kvp_value_to_bare_string (const KvpValue *val)
 General purpose function to convert any KvpValue to a string.
gchar * kvp_value_to_string (const KvpValue *val)
 Debug version of kvp_value_to_string.
gboolean kvp_value_binary_append (KvpValue *v, void *data, guint64 size)
gchar * kvp_frame_to_string (const KvpFrame *frame)
gchar * binary_to_string (const void *data, guint32 size)
gchar * kvp_value_glist_to_string (const GList *list)
GHashTable * kvp_frame_get_hash (const KvpFrame *frame)


Define Documentation

#define kvp_frame_add_gnc_numeric   kvp_frame_add_numeric
 

Deprecated:
Use kvp_frame_add_numeric instead of kvp_frame_add_gnc_numeric

Definition at line 270 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 279 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 154 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_new_gnc_numeric   kvp_value_new_numeric
 

Deprecated:
Use kvp_value_new_numeric instead of kvp_value_new_gnc_numeric

Definition at line 558 of file kvp_frame.h.


Function Documentation

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

void kvp_frame_add_url_encoding KvpFrame frame,
const gchar *  enc
 

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

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

gint kvp_frame_compare const KvpFrame fa,
const KvpFrame fb
 

Similar returns as strcmp.

Definition at line 1561 of file kvp_frame.c.

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

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

00151 {
00152   KvpFrame * retval = kvp_frame_new();
00153 
00154   if (!frame) return retval;
00155 
00156   if(frame->hash) 
00157   {
00158     if(!init_frame_body_if_needed(retval)) return(NULL);
00159     g_hash_table_foreach(frame->hash,
00160                          & kvp_frame_copy_worker, 
00161                          (gpointer)retval);
00162   }
00163   return retval;
00164 }

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

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

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

01470 {
01471   if(!f) return;
01472   if(!proc) return;
01473   if(!(f->hash)) return;
01474 
01475   g_hash_table_foreach(f->hash, (GHFunc) proc, data);
01476 }

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

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

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

01013 {
01014   if (!frame || !key_path) return NULL;
01015 
01016   while (TRUE) 
01017   {
01018     const char *key = key_path->data;
01019     KvpValue *value;
01020 
01021     if (!key) return NULL;
01022 
01023     value = kvp_frame_get_slot (frame, key);
01024     if (!value) return NULL;
01025 
01026     key_path = key_path->next;
01027     if (!key_path) return value;
01028 
01029     frame = kvp_value_get_frame (value);
01030     if (!frame) return NULL;
01031   }
01032 }

gboolean kvp_frame_is_empty KvpFrame frame  ) 
 

Return TRUE if the KvpFrame is empty

Definition at line 133 of file kvp_frame.c.

00134 {
00135   if (!frame) return TRUE;
00136   if (!frame->hash) return TRUE;
00137   return FALSE;
00138 }

KvpFrame* kvp_frame_new void   ) 
 

Return a new empty instance of KvpFrame

Definition at line 98 of file kvp_frame.c.

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

KvpValue* kvp_frame_replace_slot_nc KvpFrame frame,
const gchar *  slot,
KvpValue new_value
 

The kvp_frame_replace_slot_nc() routine places the new value into the indicated frame, for the given key. It returns the old value, if any. It returns NULL if the slot doesn't exist, if there was some other an error, or if there was no old value. Passing in a NULL new_value has the effect of deleting that slot.

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

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

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

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

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

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

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

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

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

The kvp_frame_set_slot() routine copies the value into the frame, associating it with a copy of 'key'. Pointers passed as arguments into kvp_frame_set_slot are the responsibility of the caller; the pointers are *not* taken over or managed. The old value at this location, if any, is destroyed.

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

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

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

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

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

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

Definition at line 724 of file kvp_frame.c.

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

void kvp_frame_set_string KvpFrame frame,
const gchar *  path,
const char *  str
 

Store a copy of the string at the indicated path.

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

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

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

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

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

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

01819 {
01820     gchar *tmp1;
01821 
01822     g_return_val_if_fail (frame != NULL, NULL);
01823 
01824     tmp1 = g_strdup_printf("{\n");
01825 
01826     if (frame->hash)
01827       g_hash_table_foreach(frame->hash, kvp_frame_to_string_helper, &tmp1);
01828 
01829     {
01830         gchar *tmp2;
01831         tmp2 = g_strdup_printf("%s}\n", tmp1);
01832         g_free(tmp1);
01833         tmp1 = tmp2;
01834     }
01835 
01836     return tmp1;
01837 }

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

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

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

01040 {
01041   GList *node;
01042   if(!list) return;
01043   
01044   /* Delete the data in the list */
01045   for (node=list; node; node=node->next)
01046   {
01047     KvpValue *val = node->data;
01048     kvp_value_delete(val);
01049   }
01050   
01051   /* Free the backbone */
01052   g_list_free(list);
01053 }

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

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

KvpValue* kvp_value_copy const KvpValue value  ) 
 

This is a deep value copy.

Definition at line 1427 of file kvp_frame.c.

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

void kvp_value_delete KvpValue value  ) 
 

This is a deep (recursive) delete.

Definition at line 1245 of file kvp_frame.c.

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

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

01356 {
01357   if (!value)
01358   {
01359     if (size_return)
01360       *size_return = 0;
01361     return NULL;
01362   }
01363 
01364   if(value->type == KVP_TYPE_BINARY) {
01365     if (size_return)
01366       *size_return = value->value.binary.datasize;
01367     return value->value.binary.data;
01368   }
01369   else {
01370     if (size_return)
01371       *size_return = 0;
01372     return NULL;
01373   }
01374 }

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

01390 {
01391   if (!value) return NULL;
01392   if(value->type == KVP_TYPE_FRAME) {
01393     return value->value.frame;
01394   }
01395   else {
01396     return NULL;
01397   }
01398 }

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

01285 {
01286   if (!value) return 0;
01287   if(value->type == KVP_TYPE_GINT64) {
01288     return value->value.int64;
01289   }
01290   else {
01291     return 0;
01292   }
01293 }

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

01378 {
01379   if (!value) return NULL;
01380   if(value->type == KVP_TYPE_GLIST) {
01381     return value->value.list;
01382   }
01383   else {
01384     return NULL;
01385   }
01386 }

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

01333 {
01334   if (!value) return NULL;
01335   if(value->type == KVP_TYPE_GUID) {
01336     return value->value.guid;
01337   }
01338   else {
01339     return NULL;
01340   }
01341 }

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

01321 {
01322   if (!value) return NULL;
01323   if(value->type == KVP_TYPE_STRING) {
01324     return value->value.str;
01325   }
01326   else { 
01327     return NULL; 
01328   }
01329 }

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

01185 {
01186   KvpValue * retval;
01187   if (!value) return NULL;
01188 
01189   retval = g_new0(KvpValue, 1);
01190   retval->type = KVP_TYPE_BINARY;
01191   retval->value.binary.data = value;
01192   retval->value.binary.datasize = datasize;
01193   return retval;
01194 }

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

01234 {
01235   KvpValue * retval;
01236   if (!value) return NULL;
01237 
01238   retval  = g_new0(KvpValue, 1);
01239   retval->type        = KVP_TYPE_FRAME;
01240   retval->value.frame = value;
01241   return retval;  
01242 }

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

01198 {
01199   KvpValue * retval;
01200   if (!value) return NULL;
01201 
01202   retval = g_new0(KvpValue, 1);
01203   retval->type       = KVP_TYPE_GLIST;
01204   retval->value.list = kvp_glist_copy(value);
01205   return retval;
01206 }  

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

01210 {
01211   KvpValue * retval;
01212   if (!value) return NULL;
01213 
01214   retval = g_new0(KvpValue, 1);
01215   retval->type       = KVP_TYPE_GLIST;
01216   retval->value.list = value;
01217   return retval;
01218 }  

KvpFrame* kvp_value_replace_frame_nc KvpValue value,
KvpFrame newframe
 

Replace old frame value with new, return old frame

Definition at line 1401 of file kvp_frame.c.

01402 {
01403   KvpFrame *oldframe;
01404   if (!value) return NULL;
01405   if (KVP_TYPE_FRAME != value->type) return NULL;
01406 
01407   oldframe = value->value.frame;
01408   value->value.frame = newframe;
01409   return oldframe;  
01410 }

GList* kvp_value_replace_glist_nc KvpValue value,
GList *  newlist
 

Replace old glist value with new, return old glist

Definition at line 1413 of file kvp_frame.c.

01414 {
01415   GList *oldlist;
01416   if (!value) return NULL;
01417   if (KVP_TYPE_GLIST != value->type) return NULL;
01418 
01419   oldlist = value->value.list;
01420   value->value.list = newlist;
01421   return oldlist;
01422 }

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

01641 {
01642     gchar *tmp1;
01643     gchar *tmp2;
01644     const gchar *ctmp;
01645     
01646     g_return_val_if_fail(val, NULL);
01647     tmp1 = g_strdup("");
01648     switch(kvp_value_get_type(val))
01649     {
01650     case KVP_TYPE_GINT64:
01651         return g_strdup_printf("%" G_GINT64_FORMAT, kvp_value_get_gint64(val));
01652         break;
01653 
01654     case KVP_TYPE_DOUBLE:
01655         return g_strdup_printf("(%g)", kvp_value_get_double(val));
01656         break;
01657 
01658     case KVP_TYPE_NUMERIC:
01659         tmp1 = gnc_numeric_to_string(kvp_value_get_numeric(val));
01660         tmp2 = g_strdup_printf("%s", tmp1 ? tmp1 : "");
01661         g_free(tmp1);
01662         return tmp2;
01663         break;
01664 
01665     case KVP_TYPE_STRING:
01666         tmp1 = kvp_value_get_string (val);
01667         return g_strdup_printf("%s", tmp1 ? tmp1 : "");
01668         break;
01669 
01670     case KVP_TYPE_GUID:
01671         ctmp = guid_to_string(kvp_value_get_guid(val));
01672         tmp2 = g_strdup_printf("%s", ctmp ? ctmp : "");
01673         return tmp2;
01674         break;
01675 
01676     case KVP_TYPE_TIMESPEC:
01677         {
01678                 time_t t;
01679                 t = timespecToTime_t(kvp_value_get_timespec(val));
01680         qof_date_format_set(QOF_DATE_FORMAT_UTC);
01681         return qof_print_date(t);
01682         break;
01683         }
01684     case KVP_TYPE_BINARY:
01685     {
01686         guint64 len;
01687         void *data;
01688         data = kvp_value_get_binary(val, &len);
01689         tmp1 = binary_to_string(data, len);
01690         return g_strdup_printf("%s", tmp1 ? tmp1 : "");
01691     }
01692         break;
01693  
01694     case KVP_TYPE_GLIST:
01695                 /* borked. kvp_value_glist_to_string is a debug fcn */
01696         {
01697         tmp1 = kvp_value_glist_to_string(kvp_value_get_glist(val));
01698         tmp2 = g_strdup_printf("%s", tmp1 ? tmp1 : "");
01699         g_free(tmp1);
01700         return tmp2;
01701         break;
01702         }
01703     case KVP_TYPE_FRAME:
01704         {
01705                 KvpFrame *frame;
01706 
01707                 frame = kvp_value_get_frame(val);
01708                 if (frame->hash) {
01709                         tmp1 = g_strdup("");
01710                         g_hash_table_foreach(frame->hash, kvp_frame_to_bare_string_helper, &tmp1);
01711                 }
01712         return tmp1;
01713         break;
01714         }
01715     default:
01716         return g_strdup_printf(" ");
01717         break;
01718     }
01719 }

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

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


Generated on Fri May 12 17:57:21 2006 for QOF by  doxygen 1.4.4