Data Structures | |
| struct | GHashTableKVPair |
Files | |
| file | kvp-util-p.h |
| misc odd-job kvp utils engine-private routines | |
| file | kvp-util.h |
| QOF KVP utility functions. | |
| file | kvp_frame.h |
| A key-value frame system. | |
Defines | |
| #define | QOF_MOD_KVP "qof.kvp" |
| #define | kvp_frame KvpFrame |
| #define | kvp_value KvpValue |
| #define | kvp_value_t KvpValueType |
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_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) |
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.
| #define kvp_frame KvpFrame |
Definition at line 105 of file kvp_frame.h.
| #define kvp_frame_add_gnc_numeric kvp_frame_add_numeric |
Use kvp_frame_add_numeric instead of kvp_frame_add_gnc_numeric
Definition at line 271 of file kvp_frame.h.
| #define kvp_frame_add_str kvp_frame_add_string |
Use kvp_frame_add_string instead of kvp_frame_add_str
Definition at line 280 of file kvp_frame.h.
| #define kvp_frame_set_gnc_numeric kvp_frame_set_numeric |
Use kvp_frame_set_numeric instead of kvp_frame_set_gnc_numeric
Definition at line 155 of file kvp_frame.h.
| #define kvp_frame_set_str kvp_frame_set_string |
Use kvp_frame_set_string instead of kvp_frame_set_str
Definition at line 173 of file kvp_frame.h.
| #define kvp_value KvpValue |
| #define kvp_value_new_gnc_numeric kvp_value_new_numeric |
Use kvp_value_new_numeric instead of kvp_value_new_gnc_numeric
Definition at line 560 of file kvp_frame.h.
| #define kvp_value_t KvpValueType |
| typedef struct _KvpFrame KvpFrame |
Opaque frame structure
Definition at line 71 of file kvp_frame.h.
| typedef struct _KvpValue KvpValue |
A KvpValue is a union with possible types enumerated in the KvpValueType enum.
Definition at line 75 of file kvp_frame.h.
| enum KvpValueType |
possible types in the union KvpValue
Definition at line 88 of file kvp_frame.h.
00089 { 00090 KVP_TYPE_GINT64 = 1, 00091 KVP_TYPE_DOUBLE, 00092 KVP_TYPE_NUMERIC, 00093 KVP_TYPE_STRING, 00094 KVP_TYPE_GUID, 00095 KVP_TYPE_TIMESPEC, 00096 KVP_TYPE_BINARY, 00097 KVP_TYPE_GLIST, 00098 KVP_TYPE_FRAME 00099 } KvpValueType;
| GSList* g_hash_table_key_value_pairs | ( | GHashTable * | table | ) |
Returns a GSList* of all the keys and values in a given hash table. Data elements of lists are actual hash elements, so be careful, and deallocation of the GHashTableKVPairs in the result list are the caller's responsibility. A typical sequence might look like this:
GSList *kvps = g_hash_table_key_value_pairs(hash); ... use kvps->data->key and kvps->data->val, etc. here ... g_slist_foreach(kvps, g_hash_table_kv_pair_free_gfunc, NULL); g_slist_free(kvps);
Definition at line 221 of file kvp-util.c.
00222 { 00223 GSList *result_list = NULL; 00224 g_hash_table_foreach(table, kv_pair_helper, &result_list); 00225 return result_list; 00226 }
| KvpFrame* gnc_kvp_bag_add | ( | KvpFrame * | kvp_root, | |
| const char * | path, | |||
| time_t | secs, | |||
| const char * | first_name, | |||
| ... | ||||
| ) |
The gnc_kvp_bag_add() routine is used to maintain a collection of pointers in a kvp tree.
The thing being pointed at is uniquely identified by its GUID. This routine is typically used to create a linked list, and/or a collection of pointers to objects that are 'related' to each other in some way.
The var-args should be pairs of strings (const char *) followed by the corresponding GUID pointer (const GUID *). Terminate the varargs with a NULL as the last string argument.
The actual 'pointer' is stored in a subdirectory in a bag located at the node directory 'path'. A 'bag' is merely a collection of (unamed) values. The name of our bag is 'path'. A bag can contain any kind of values, including frames. This routine will create a frame, and put it in the bag. The frame will contain named data from the subroutine arguments. Thus, for example:
gnc_kvp_array (kvp, "foo", secs, "acct_guid", aguid, "book_guid", bguid, NULL);
will create a frame containing "/acct_guid" and "/book_guid", whose values are aguid and bguid respecitvely. The frame will also contain "/date", whose value will be secs. This frame will be placed into the bag located at "foo".
This routine returns a pointer to the frame that was created, or NULL if an error occured.
Definition at line 74 of file kvp-util.c.
00076 { 00077 KvpFrame *cwd; 00078 va_list ap; 00079 va_start (ap, first_name); 00080 cwd = gnc_kvp_array_va (pwd, path, secs, first_name, ap); 00081 va_end (ap); 00082 return cwd; 00083 }
| KvpFrame* gnc_kvp_bag_find_by_guid | ( | KvpFrame * | root, | |
| const char * | path, | |||
| const char * | guid_name, | |||
| const GUID * | desired_guid | |||
| ) |
The gnc_kvp_bag_find_by_guid() routine examines the bag pointed located at root. It looks for a frame in that bag that has the guid value of "desired_guid" filed under the key name "guid_name". If it finds that matching guid, then it returns a pointer to the KVP frame that contains it. If it is not found, or if there is any other error, NULL is returned.
Definition at line 96 of file kvp-util.c.
00098 { 00099 KvpValue *arr; 00100 KvpValueType valtype; 00101 GList *node; 00102 00103 arr = kvp_frame_get_value (root, path); 00104 valtype = kvp_value_get_type (arr); 00105 if (KVP_TYPE_FRAME == valtype) 00106 { 00107 MATCH_GUID (arr); 00108 return NULL; 00109 } 00110 00111 /* Its gotta be a single isolated frame, or a list of them. */ 00112 if (KVP_TYPE_GLIST != valtype) return NULL; 00113 00114 for (node = kvp_value_get_glist(arr); node; node = node->next) 00115 { 00116 KvpValue *va = node->data; 00117 MATCH_GUID (va); 00118 } 00119 return NULL; 00120 }
| void gnc_kvp_bag_merge | ( | KvpFrame * | kvp_into, | |
| const char * | intopath, | |||
| KvpFrame * | kvp_from, | |||
| const char * | frompath | |||
| ) |
The gnc_kvp_bag_merge() routine will move the bag contents from the 'kvp_from', to the 'into' bag. It will then delete the 'from' bag from the kvp tree.
Definition at line 190 of file kvp-util.c.
00192 { 00193 KvpFrame *fr; 00194 00195 fr = gnc_kvp_bag_get_first (kvp_from, frompath); 00196 while (fr) 00197 { 00198 gnc_kvp_bag_remove_frame (kvp_from, frompath, fr); 00199 kvp_frame_add_frame_nc (kvp_into, intopath, fr); 00200 fr = gnc_kvp_bag_get_first (kvp_from, frompath); 00201 } 00202 }
Remove the given frame from the bag. The frame is removed, however, it is not deleted. Note that the frame pointer must be a pointer to the actual frame (for example, as returned by gnc_kvp_bag_find_by_guid() for by gnc_kvp_bag_add()), and not some copy of the frame.
Definition at line 125 of file kvp-util.c.
00126 { 00127 KvpValue *arr; 00128 KvpValueType valtype; 00129 GList *node, *listhead; 00130 00131 arr = kvp_frame_get_value (root, path); 00132 valtype = kvp_value_get_type (arr); 00133 if (KVP_TYPE_FRAME == valtype) 00134 { 00135 if (fr == kvp_value_get_frame (arr)) 00136 { 00137 KvpValue *old_val = kvp_frame_replace_value_nc (root, path, NULL); 00138 kvp_value_replace_frame_nc (old_val, NULL); 00139 kvp_value_delete (old_val); 00140 } 00141 return; 00142 } 00143 00144 /* Its gotta be a single isolated frame, or a list of them. */ 00145 if (KVP_TYPE_GLIST != valtype) return; 00146 00147 listhead = kvp_value_get_glist(arr); 00148 for (node = listhead; node; node = node->next) 00149 { 00150 KvpValue *va = node->data; 00151 if (fr == kvp_value_get_frame (va)) 00152 { 00153 listhead = g_list_remove_link (listhead, node); 00154 g_list_free_1 (node); 00155 kvp_value_replace_glist_nc (arr, listhead); 00156 kvp_value_replace_frame_nc (va, NULL); 00157 kvp_value_delete (va); 00158 return; 00159 } 00160 } 00161 }
| void kvp_frame_add_gint64 | ( | KvpFrame * | frame, | |
| const 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.
Similar returns as strcmp.
Definition at line 1607 of file kvp_frame.c.
01608 { 01609 kvp_frame_cmp_status status; 01610 01611 if (fa == fb) return 0; 01612 /* nothing is always less than something */ 01613 if (!fa && fb) return -1; 01614 if (fa && !fb) return 1; 01615 01616 /* nothing is always less than something */ 01617 if (!fa->hash && fb->hash) return -1; 01618 if (fa->hash && !fb->hash) return 1; 01619 01620 status.compare = 0; 01621 status.other_frame = (KvpFrame *) fb; 01622 01623 kvp_frame_for_each_slot((KvpFrame *) fa, kvp_frame_compare_helper, &status); 01624 01625 if (status.compare != 0) 01626 return status.compare; 01627 01628 status.other_frame = (KvpFrame *) fa; 01629 01630 kvp_frame_for_each_slot((KvpFrame *) fb, kvp_frame_compare_helper, &status); 01631 01632 return(-status.compare); 01633 }
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 gchar *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.
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.
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 941 of file kvp_frame.c.
00942 { 00943 if (!frame) return frame; 00944 00945 while (key_path) 00946 { 00947 const char *key = key_path->data; 00948 00949 if (!key) return frame; /* an unusual but valid exit for this routine. */ 00950 00951 frame = get_or_make (frame, key); 00952 if (!frame) return frame; /* this should never happen */ 00953 00954 key_path = key_path->next; 00955 } 00956 return frame; /* this is the normal exit for this func */ 00957 }
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()
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).
This routine return the value at the end of the path, or NULL if any portion of the path doesn't exist.
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 1029 of file kvp_frame.c.
01031 { 01032 if (!frame || !key_path) return NULL; 01033 01034 while (TRUE) 01035 { 01036 const char *key = key_path->data; 01037 KvpValue *value; 01038 01039 if (!key) return NULL; 01040 01041 value = kvp_frame_get_slot (frame, key); 01042 if (!value) return NULL; 01043 01044 key_path = key_path->next; 01045 if (!key_path) return value; 01046 01047 frame = kvp_value_get_frame (value); 01048 if (!frame) return NULL; 01049 } 01050 }
| gboolean kvp_frame_is_empty | ( | const 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 }
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.
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.
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.
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.
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 733 of file kvp_frame.c.
00736 { 00737 if (!frame || !key_path) return; 00738 00739 while (TRUE) 00740 { 00741 const char *key = key_path->data; 00742 KvpValue *value; 00743 00744 if (!key) 00745 return; 00746 00747 g_return_if_fail (*key != '\0'); 00748 00749 key_path = key_path->next; 00750 if (!key_path) 00751 { 00752 kvp_frame_set_slot (frame, key, new_value); 00753 return; 00754 } 00755 00756 value = kvp_frame_get_slot (frame, key); 00757 if (!value) 00758 { 00759 KvpFrame *new_frame = kvp_frame_new (); 00760 KvpValue *frame_value = kvp_value_new_frame (new_frame); 00761 00762 kvp_frame_set_slot_nc (frame, key, frame_value); 00763 00764 value = kvp_frame_get_slot (frame, key); 00765 if (!value) 00766 return; 00767 } 00768 00769 frame = kvp_value_get_frame (value); 00770 if (!frame) 00771 return; 00772 } 00773 }
| void kvp_frame_set_string | ( | KvpFrame * | frame, | |
| const gchar * | path, | |||
| const gchar * | str | |||
| ) |
Store a copy of the string at the indicated path.
If not all frame components of the path exist, they are created. If there was another string previously stored at that path, the old copy is deleted.
Similarly, the set_guid and set_frame will make copies and store those. Old copies, if any, are deleted.
The kvp_frame_set_frame_nc() routine works as above, but does *NOT* copy the frame.
store the value of the Timespec at the indicated path. If not all frame components of the path exist, they are created.
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.
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 1865 of file kvp_frame.c.
01866 { 01867 gchar *tmp1; 01868 01869 g_return_val_if_fail (frame != NULL, NULL); 01870 01871 tmp1 = g_strdup_printf("{\n"); 01872 01873 if (frame->hash) 01874 g_hash_table_foreach(frame->hash, kvp_frame_to_string_helper, &tmp1); 01875 01876 { 01877 gchar *tmp2; 01878 tmp2 = g_strdup_printf("%s}\n", tmp1); 01879 g_free(tmp1); 01880 tmp1 = tmp2; 01881 } 01882 01883 return tmp1; 01884 }
| 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 1074 of file kvp_frame.c.
01075 { 01076 GList * retval = NULL; 01077 GList * lptr; 01078 01079 if (!list) return retval; 01080 01081 /* Duplicate the backbone of the list (this duplicates the POINTERS 01082 * to the values; we need to deep-copy the values separately) */ 01083 retval = g_list_copy((GList *) list); 01084 01085 /* This step deep-copies the values */ 01086 for (lptr = retval; lptr; lptr = lptr->next) 01087 { 01088 lptr->data = kvp_value_copy(lptr->data); 01089 } 01090 01091 return retval; 01092 }
| 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 1057 of file kvp_frame.c.
01058 { 01059 GList *node; 01060 if (!list) return; 01061 01062 /* Delete the data in the list */ 01063 for (node = list; node; node = node->next) 01064 { 01065 KvpValue *val = node->data; 01066 kvp_value_delete(val); 01067 } 01068 01069 /* Free the backbone */ 01070 g_list_free(list); 01071 }
| gboolean kvp_value_binary_append | ( | KvpValue * | v, | |
| void * | data, | |||
| guint64 | size | |||
| ) |
Manipulator:
copying - but more efficient than creating a new KvpValue manually.
Similar returns as strcmp.
Definition at line 1528 of file kvp_frame.c.
01529 { 01530 if (kva == kvb) return 0; 01531 /* nothing is always less than something */ 01532 if (!kva && kvb) return -1; 01533 if (kva && !kvb) return 1; 01534 01535 if (kva->type < kvb->type) return -1; 01536 if (kva->type > kvb->type) return 1; 01537 01538 switch (kva->type) 01539 { 01540 case KVP_TYPE_GINT64: 01541 if (kva->value.int64 < kvb->value.int64) return -1; 01542 if (kva->value.int64 > kvb->value.int64) return 1; 01543 return 0; 01544 break; 01545 case KVP_TYPE_DOUBLE: 01546 return double_compare(kva->value.dbl, kvb->value.dbl); 01547 break; 01548 case KVP_TYPE_NUMERIC: 01549 return gnc_numeric_compare (kva->value.numeric, kvb->value.numeric); 01550 break; 01551 case KVP_TYPE_STRING: 01552 return strcmp(kva->value.str, kvb->value.str); 01553 break; 01554 case KVP_TYPE_GUID: 01555 return guid_compare(kva->value.guid, kvb->value.guid); 01556 break; 01557 case KVP_TYPE_TIMESPEC: 01558 return timespec_cmp(&(kva->value.timespec), &(kvb->value.timespec)); 01559 break; 01560 case KVP_TYPE_BINARY: 01561 /* I don't know that this is a good compare. Ab is bigger than Acef. 01562 But I'm not sure that actually matters here. */ 01563 if (kva->value.binary.datasize < kvb->value.binary.datasize) return -1; 01564 if (kva->value.binary.datasize > kvb->value.binary.datasize) return 1; 01565 return memcmp(kva->value.binary.data, 01566 kvb->value.binary.data, 01567 kva->value.binary.datasize); 01568 break; 01569 case KVP_TYPE_GLIST: 01570 return kvp_glist_compare(kva->value.list, kvb->value.list); 01571 break; 01572 case KVP_TYPE_FRAME: 01573 return kvp_frame_compare(kva->value.frame, kvb->value.frame); 01574 break; 01575 } 01576 PERR ("reached unreachable code."); 01577 return FALSE; 01578 }
This is a deep value copy.
Definition at line 1463 of file kvp_frame.c.
01464 { 01465 if (!value) return NULL; 01466 01467 switch (value->type) 01468 { 01469 case KVP_TYPE_GINT64: 01470 return kvp_value_new_gint64(value->value.int64); 01471 break; 01472 case KVP_TYPE_DOUBLE: 01473 return kvp_value_new_double(value->value.dbl); 01474 break; 01475 case KVP_TYPE_NUMERIC: 01476 return kvp_value_new_gnc_numeric(value->value.numeric); 01477 break; 01478 case KVP_TYPE_STRING: 01479 return kvp_value_new_string(value->value.str); 01480 break; 01481 case KVP_TYPE_GUID: 01482 return kvp_value_new_guid(value->value.guid); 01483 break; 01484 case KVP_TYPE_TIMESPEC: 01485 return kvp_value_new_timespec(value->value.timespec); 01486 break; 01487 case KVP_TYPE_BINARY: 01488 return kvp_value_new_binary(value->value.binary.data, 01489 value->value.binary.datasize); 01490 break; 01491 case KVP_TYPE_GLIST: 01492 return kvp_value_new_glist(value->value.list); 01493 break; 01494 case KVP_TYPE_FRAME: 01495 return kvp_value_new_frame(value->value.frame); 01496 break; 01497 } 01498 return NULL; 01499 }
| void kvp_value_delete | ( | KvpValue * | value | ) |
This is a deep (recursive) delete.
Definition at line 1263 of file kvp_frame.c.
01264 { 01265 if (!value) return; 01266 01267 switch (value->type) 01268 { 01269 case KVP_TYPE_STRING: 01270 g_free(value->value.str); 01271 break; 01272 case KVP_TYPE_GUID: 01273 g_free(value->value.guid); 01274 break; 01275 case KVP_TYPE_BINARY: 01276 g_free(value->value.binary.data); 01277 break; 01278 case KVP_TYPE_GLIST: 01279 kvp_glist_delete(value->value.list); 01280 break; 01281 case KVP_TYPE_FRAME: 01282 kvp_frame_delete(value->value.frame); 01283 break; 01284 01285 case KVP_TYPE_GINT64: 01286 case KVP_TYPE_DOUBLE: 01287 case KVP_TYPE_NUMERIC: 01288 default: 01289 break; 01290 } 01291 g_free(value); 01292 }
| 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 1385 of file kvp_frame.c.
01386 { 01387 if (!value) 01388 { 01389 if (size_return) 01390 *size_return = 0; 01391 return NULL; 01392 } 01393 01394 if (value->type == KVP_TYPE_BINARY) 01395 { 01396 if (size_return) 01397 *size_return = value->value.binary.datasize; 01398 return value->value.binary.data; 01399 } 01400 else 01401 { 01402 if (size_return) 01403 *size_return = 0; 01404 return NULL; 01405 } 01406 }
Value accessor. This one is non-copying -- the caller can modify the value directly.
Definition at line 1423 of file kvp_frame.c.
01424 { 01425 if (!value) return NULL; 01426 if (value->type == KVP_TYPE_FRAME) 01427 { 01428 return value->value.frame; 01429 } 01430 else 01431 { 01432 return NULL; 01433 } 01434 }
| 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 1302 of file kvp_frame.c.
01303 { 01304 if (!value) return 0; 01305 if (value->type == KVP_TYPE_GINT64) 01306 { 01307 return value->value.int64; 01308 } 01309 else 01310 { 01311 return 0; 01312 } 01313 }
| 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 1409 of file kvp_frame.c.
01410 { 01411 if (!value) return NULL; 01412 if (value->type == KVP_TYPE_GLIST) 01413 { 01414 return value->value.list; 01415 } 01416 else 01417 { 01418 return NULL; 01419 } 01420 }
| 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 1358 of file kvp_frame.c.
01359 { 01360 if (!value) return NULL; 01361 if (value->type == KVP_TYPE_GUID) 01362 { 01363 return value->value.guid; 01364 } 01365 else 01366 { 01367 return NULL; 01368 } 01369 }
| 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 1344 of file kvp_frame.c.
01345 { 01346 if (!value) return NULL; 01347 if (value->type == KVP_TYPE_STRING) 01348 { 01349 return value->value.str; 01350 } 01351 else 01352 { 01353 return NULL; 01354 } 01355 }
| 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 1202 of file kvp_frame.c.
01203 { 01204 KvpValue * retval; 01205 if (!value) return NULL; 01206 01207 retval = g_new0(KvpValue, 1); 01208 retval->type = KVP_TYPE_BINARY; 01209 retval->value.binary.data = value; 01210 retval->value.binary.datasize = datasize; 01211 return retval; 01212 }
value constructors (non-copying - KvpValue takes pointer ownership) values *must* have been allocated via glib allocators! (gnew, etc.)
Definition at line 1251 of file kvp_frame.c.
01252 { 01253 KvpValue * retval; 01254 if (!value) return NULL; 01255 01256 retval = g_new0(KvpValue, 1); 01257 retval->type = KVP_TYPE_FRAME; 01258 retval->value.frame = value; 01259 return retval; 01260 }
| 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 1215 of file kvp_frame.c.
01216 { 01217 KvpValue * retval; 01218 if (!value) return NULL; 01219 01220 retval = g_new0(KvpValue, 1); 01221 retval->type = KVP_TYPE_GLIST; 01222 retval->value.list = kvp_glist_copy(value); 01223 return retval; 01224 }
| 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 1227 of file kvp_frame.c.
01228 { 01229 KvpValue * retval; 01230 if (!value) return NULL; 01231 01232 retval = g_new0(KvpValue, 1); 01233 retval->type = KVP_TYPE_GLIST; 01234 retval->value.list = value; 01235 return retval; 01236 }
Replace old frame value with new, return old frame
Definition at line 1437 of file kvp_frame.c.
01438 { 01439 KvpFrame *oldframe; 01440 if (!value) return NULL; 01441 if (KVP_TYPE_FRAME != value->type) return NULL; 01442 01443 oldframe = value->value.frame; 01444 value->value.frame = newframe; 01445 return oldframe; 01446 }
| GList* kvp_value_replace_glist_nc | ( | KvpValue * | value, | |
| GList * | newlist | |||
| ) |
Replace old glist value with new, return old glist
Definition at line 1449 of file kvp_frame.c.
01450 { 01451 GList *oldlist; 01452 if (!value) return NULL; 01453 if (KVP_TYPE_GLIST != value->type) return NULL; 01454 01455 oldlist = value->value.list; 01456 value->value.list = newlist; 01457 return oldlist; 01458 }
| 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 1686 of file kvp_frame.c.
01687 { 01688 gchar *tmp1; 01689 gchar *tmp2; 01690 const gchar *ctmp; 01691 01692 g_return_val_if_fail(val, NULL); 01693 tmp1 = g_strdup(""); 01694 switch (kvp_value_get_type(val)) 01695 { 01696 case KVP_TYPE_GINT64: 01697 return g_strdup_printf("%" G_GINT64_FORMAT, kvp_value_get_gint64(val)); 01698 break; 01699 01700 case KVP_TYPE_DOUBLE: 01701 return g_strdup_printf("(%g)", kvp_value_get_double(val)); 01702 break; 01703 01704 case KVP_TYPE_NUMERIC: 01705 tmp1 = gnc_numeric_to_string(kvp_value_get_numeric(val)); 01706 tmp2 = g_strdup_printf("%s", tmp1 ? tmp1 : ""); 01707 g_free(tmp1); 01708 return tmp2; 01709 break; 01710 01711 case KVP_TYPE_STRING: 01712 tmp1 = kvp_value_get_string (val); 01713 return g_strdup_printf("%s", tmp1 ? tmp1 : ""); 01714 break; 01715 01716 case KVP_TYPE_GUID: 01717 ctmp = guid_to_string(kvp_value_get_guid(val)); 01718 tmp2 = g_strdup_printf("%s", ctmp ? ctmp : ""); 01719 return tmp2; 01720 break; 01721 01722 case KVP_TYPE_TIMESPEC: 01723 { 01724 time_t t; 01725 t = timespecToTime_t(kvp_value_get_timespec(val)); 01726 qof_date_format_set(QOF_DATE_FORMAT_UTC); 01727 return qof_print_date(t); 01728 break; 01729 } 01730 case KVP_TYPE_BINARY: 01731 { 01732 guint64 len; 01733 void *data; 01734 data = kvp_value_get_binary(val, &len); 01735 tmp1 = binary_to_string(data, len); 01736 return g_strdup_printf("%s", tmp1 ? tmp1 : ""); 01737 } 01738 break; 01739 01740 case KVP_TYPE_GLIST: 01741 /* borked. kvp_value_glist_to_string is a debug fcn */ 01742 { 01743 tmp1 = kvp_value_glist_to_string(kvp_value_get_glist(val)); 01744 tmp2 = g_strdup_printf("%s", tmp1 ? tmp1 : ""); 01745 g_free(tmp1); 01746 return tmp2; 01747 break; 01748 } 01749 case KVP_TYPE_FRAME: 01750 { 01751 KvpFrame *frame; 01752 01753 frame = kvp_value_get_frame(val); 01754 if (frame->hash) 01755 { 01756 tmp1 = g_strdup(""); 01757 g_hash_table_foreach(frame->hash, kvp_frame_to_bare_string_helper, &tmp1); 01758 } 01759 return tmp1; 01760 break; 01761 } 01762 default: 01763 return g_strdup_printf(" "); 01764 break; 01765 } 01766 }
| 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 1769 of file kvp_frame.c.
01770 { 01771 gchar *tmp1; 01772 gchar *tmp2; 01773 const gchar *ctmp; 01774 01775 g_return_val_if_fail(val, NULL); 01776 01777 switch (kvp_value_get_type(val)) 01778 { 01779 case KVP_TYPE_GINT64: 01780 return g_strdup_printf("KVP_VALUE_GINT64(%" G_GINT64_FORMAT ")", 01781 kvp_value_get_gint64(val)); 01782 break; 01783 01784 case KVP_TYPE_DOUBLE: 01785 return g_strdup_printf("KVP_VALUE_DOUBLE(%g)", 01786 kvp_value_get_double(val)); 01787 break; 01788 01789 case KVP_TYPE_NUMERIC: 01790 tmp1 = gnc_numeric_to_string(kvp_value_get_numeric(val)); 01791 tmp2 = g_strdup_printf("KVP_VALUE_NUMERIC(%s)", tmp1 ? tmp1 : ""); 01792 g_free(tmp1); 01793 return tmp2; 01794 break; 01795 01796 case KVP_TYPE_STRING: 01797 tmp1 = kvp_value_get_string (val); 01798 return g_strdup_printf("KVP_VALUE_STRING(%s)", tmp1 ? tmp1 : ""); 01799 break; 01800 01801 case KVP_TYPE_GUID: 01802 /* THREAD-UNSAFE */ 01803 ctmp = guid_to_string(kvp_value_get_guid(val)); 01804 tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", ctmp ? ctmp : ""); 01805 return tmp2; 01806 break; 01807 01808 case KVP_TYPE_TIMESPEC: 01809 tmp1 = g_new0 (char, 40); 01810 gnc_timespec_to_iso8601_buff (kvp_value_get_timespec (val), tmp1); 01811 tmp2 = g_strdup_printf("KVP_VALUE_TIMESPEC(%s)", tmp1); 01812 g_free(tmp1); 01813 return tmp2; 01814 break; 01815 01816 case KVP_TYPE_BINARY: 01817 { 01818 guint64 len; 01819 void *data; 01820 data = kvp_value_get_binary(val, &len); 01821 tmp1 = binary_to_string(data, len); 01822 return g_strdup_printf("KVP_VALUE_BINARY(%s)", tmp1 ? tmp1 : ""); 01823 } 01824 break; 01825 01826 case KVP_TYPE_GLIST: 01827 tmp1 = kvp_value_glist_to_string(kvp_value_get_glist(val)); 01828 tmp2 = g_strdup_printf("KVP_VALUE_GLIST(%s)", tmp1 ? tmp1 : ""); 01829 g_free(tmp1); 01830 return tmp2; 01831 break; 01832 01833 case KVP_TYPE_FRAME: 01834 tmp1 = kvp_frame_to_string(kvp_value_get_frame(val)); 01835 tmp2 = g_strdup_printf("KVP_VALUE_FRAME(%s)", tmp1 ? tmp1 : ""); 01836 g_free(tmp1); 01837 return tmp2; 01838 break; 01839 01840 default: 01841 return g_strdup_printf(" "); 01842 break; 01843 } 01844 }
1.5.7.1