QOF: kvpframe.c Source File

QOF 0.7.5

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

kvpframe.c
1 /********************************************************************
2 * kvpframe.c -- Implements a key-value frame system *
3 * Copyright (C) 2000 Bill Gribble *
4 * Copyright (C) 2001,2003 Linas Vepstas <linas@linas.org> *
5 * Copyright (c) 2006 Neil Williams <linux@codehelp.co.uk> *
6 * *
7 * This program is free software; you can redistribute it and/or *
8 * modify it under the terms of the GNU General Public License as *
9 * published by the Free Software Foundation; either version 2 of *
10 * the License, or (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License*
18 * along with this program; if not, contact: *
19 * *
20 * Free Software Foundation Voice: +1-617-542-5942 *
21 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
22 * Boston, MA 02110-1301, USA gnu@gnu.org *
23 * *
24 ********************************************************************/
25
26 #include "config.h"
27
28 #include <glib.h>
29 #include <stdarg.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include "qof.h"
33
34 /* Note that we keep the keys for this hash table in a GCache
35 * (qof_util_string_cache), as it is very likely we will see the
36 * same keys over and over again */
37
38 struct _KvpFrame
39 {
40 GHashTable *hash;
41 };
42
43 typedef struct
44 {
45 gpointer data;
46 gint64 datasize;
47 } KvpValueBinaryData;
48
49 struct _KvpValue
50 {
51 KvpValueType type;
52 union
53 {
54 gint64 int64;
55 gdouble dbl;
56 QofNumeric numeric;
57 gchar *str;
58 GUID *guid;
59 QofTime *qt;
60 gboolean gbool; /* since 0.7.2 */
61 #ifndef QOF_DISABLE_DEPRECATED
62 Timespec timespec;
63 #endif
64 KvpValueBinaryData binary;
65 GList *list;
66 KvpFrame *frame;
67 } value;
68 };
69
70 /* This static indicates the debugging module that this .o belongs to. */
71 static QofLogModule log_module = QOF_MOD_KVP;
72
73 /* *******************************************************************
74 * KvpFrame functions
75 ********************************************************************/
76
77 static guint
78 kvp_hash_func (gconstpointer v)
79 {
80 return g_str_hash (v);
81 }
82
83 static gint
84 kvp_comp_func (gconstpointer v, gconstpointer v2)
85 {
86 return g_str_equal (v, v2);
87 }
88
89 static gboolean
90 init_frame_body_if_needed (KvpFrame * f)
91 {
92 if (!f->hash)
93 {
94 f->hash = g_hash_table_new (&kvp_hash_func, &kvp_comp_func);
95 }
96 return (f->hash != NULL);
97 }
98
99 KvpFrame *
100 kvp_frame_new (void)
101 {
102 KvpFrame *retval = g_new0 (KvpFrame, 1);
103
104 /* Save space until the frame is actually used */
105 retval->hash = NULL;
106 return retval;
107 }
108
109 static void
110 kvp_frame_delete_worker (gpointer key, gpointer value,
111 gpointer user_data __attribute__ ((unused)))
112 {
113 qof_util_string_cache_remove (key);
114 kvp_value_delete ((KvpValue *) value);
115 }
116
117 void
118 kvp_frame_delete (KvpFrame * frame)
119 {
120 if (!frame)
121 return;
122
123 if (frame->hash)
124 {
125 /* free any allocated resource for frame or its children */
126 g_hash_table_foreach (frame->hash, &kvp_frame_delete_worker,
127 (gpointer) frame);
128
129 /* delete the hash table */
130 g_hash_table_destroy (frame->hash);
131 frame->hash = NULL;
132 }
133 g_free (frame);
134 }
135
136 gboolean
137 kvp_frame_is_empty (KvpFrame * frame)
138 {
139 if (!frame)
140 return TRUE;
141 if (!frame->hash)
142 return TRUE;
143 return FALSE;
144 }
145
146 static void
147 kvp_frame_copy_worker (gpointer key, gpointer value, gpointer user_data)
148 {
149 KvpFrame *dest = (KvpFrame *) user_data;
150 g_hash_table_insert (dest->hash,
151 qof_util_string_cache_insert (key),
152 (gpointer) kvp_value_copy (value));
153 }
154
155 KvpFrame *
156 kvp_frame_copy (const KvpFrame * frame)
157 {
158 KvpFrame *retval = kvp_frame_new ();
159
160 if (!frame)
161 return retval;
162
163 if (frame->hash)
164 {
165 if (!init_frame_body_if_needed (retval))
166 return (NULL);
167 g_hash_table_foreach (frame->hash,
168 &kvp_frame_copy_worker, (gpointer) retval);
169 }
170 return retval;
171 }
172
173 /* Replace the old value with the new value. Return the old value.
174 * Passing in a null value into this routine has the effect of
175 * removing the key from the KVP tree.
176 */
177 KvpValue *
178 kvp_frame_replace_slot_nc (KvpFrame * frame, const gchar *slot,
179 KvpValue * new_value)
180 {
181 gpointer orig_key;
182 gpointer orig_value = NULL;
183 int key_exists;
184
185 if (!frame || !slot)
186 return NULL;
187 if (!init_frame_body_if_needed (frame))
188 return NULL; /* Error ... */
189
190 key_exists = g_hash_table_lookup_extended (frame->hash, slot,
191 &orig_key, &orig_value);
192 if (key_exists)
193 {
194 g_hash_table_remove (frame->hash, slot);
195 qof_util_string_cache_remove (orig_key);
196 }
197 else
198 orig_value = NULL;
199 if (new_value)
200 g_hash_table_insert (frame->hash,
201 qof_util_string_cache_insert ((gpointer) slot), new_value);
202 return (KvpValue *) orig_value;
203 }
204
205 /* Passing in a null value into this routine has the effect
206 * of deleting the old value stored at this slot.
207 */
208 static inline void
209 kvp_frame_set_slot_destructively (KvpFrame * frame, const gchar *slot,
210 KvpValue * new_value)
211 {
212 KvpValue *old_value;
213 old_value = kvp_frame_replace_slot_nc (frame, slot, new_value);
214 kvp_value_delete (old_value);
215 }
216
217 /* ============================================================ */
218 /* Get the named frame, or create it if it doesn't exist.
219 * gcc -O3 should inline it. It performs no error checks,
220 * the caller is responsible of passing good keys and frames.
221 */
222 static inline KvpFrame *
223 get_or_make (KvpFrame * fr, const gchar *key)
224 {
225 KvpFrame *next_frame;
226 KvpValue *value;
227
228 value = kvp_frame_get_slot (fr, key);
229 if (value)
230 next_frame = kvp_value_get_frame (value);
231 else
232 {
233 next_frame = kvp_frame_new ();
234 kvp_frame_set_slot_nc (fr, key,
235 kvp_value_new_frame_nc (next_frame));
236 }
237 return next_frame;
238 }
239
240 /* Get pointer to last frame in path. If the path doesn't exist,
241 * it is created. The string stored in keypath will be hopelessly
242 * mangled .
243 */
244 static inline KvpFrame *
245 kvp_frame_get_frame_slash_trash (KvpFrame * frame, gchar *key_path)
246 {
247 gchar *key, *next;
248 if (!frame || !key_path)
249 return frame;
250
251 key = key_path;
252 key--;
253
254 while (key)
255 {
256 key++;
257 while ('/' == *key)
258 key++;
259 if (0x0 == *key)
260 break; /* trailing slash */
261 next = strchr (key, '/');
262 if (next)
263 *next = 0x0;
264
265 frame = get_or_make (frame, key);
266 if (!frame)
267 break; /* error - should never happen */
268
269 key = next;
270 }
271 return frame;
272 }
273
274 /* ============================================================ */
275 /* Get pointer to last frame in path, or NULL if the path doesn't
276 * exist. The string stored in keypath will be hopelessly mangled .
277 */
278 static inline const KvpFrame *
279 kvp_frame_get_frame_or_null_slash_trash (const KvpFrame * frame,
280 gchar *key_path)
281 {
282 KvpValue *value;
283 gchar *key, *next;
284 if (!frame || !key_path)
285 return NULL;
286
287 key = key_path;
288 key--;
289
290 while (key)
291 {
292 key++;
293 while ('/' == *key)
294 key++;
295 if (0x0 == *key)
296 break; /* trailing slash */
297 next = strchr (key, '/');
298 if (next)
299 *next = 0x0;
300
301 value = kvp_frame_get_slot (frame, key);
302 if (!value)
303 return NULL;
304 frame = kvp_value_get_frame (value);
305 if (!frame)
306 return NULL;
307
308 key = next;
309 }
310 return frame;
311 }
312
313 /* Return pointer to last frame in path, and also store the
314 * last dangling part of path in 'end_key'. If path doesn't
315 * exist, it is created.
316 */
317
318 static inline KvpFrame *
319 get_trailer_make (KvpFrame * frame, const gchar *key_path,
320 gchar **end_key)
321 {
322 gchar *last_key;
323
324 if (!frame || !key_path || (0 == key_path[0]))
325 return NULL;
326
327 last_key = strrchr (key_path, '/');
328 if (NULL == last_key)
329 last_key = (gchar *) key_path;
330 else if (last_key == key_path)
331 last_key++;
332 else if (0 == last_key[1])
333 return NULL;
334 else
335 {
336 gchar *root, *lkey;
337 root = g_strdup (key_path);
338 lkey = strrchr (root, '/');
339 *lkey = 0;
340 frame = kvp_frame_get_frame_slash_trash (frame, root);
341 g_free (root);
342 last_key++;
343 }
344
345 *end_key = last_key;
346 return frame;
347 }
348
349
350 /* Return pointer to last frame in path, or NULL if the path
351 * doesn't exist. Also store the last dangling part of path
352 * in 'end_key'.
353 */
354
355 static inline const KvpFrame *
356 get_trailer_or_null (const KvpFrame * frame, const gchar *key_path,
357 gchar **end_key)
358 {
359 gchar *last_key;
360
361 if (!frame || !key_path || (0 == key_path[0]))
362 return NULL;
363
364 last_key = strrchr (key_path, '/');
365 if (NULL == last_key)
366 last_key = (gchar *) key_path;
367 else if (last_key == key_path)
368 last_key++;
369 else if (0 == last_key[1])
370 return NULL;
371 else
372 {
373 gchar *root, *lkey;
374 root = g_strdup (key_path);
375 lkey = strrchr (root, '/');
376 *lkey = 0;
377 frame = kvp_frame_get_frame_or_null_slash_trash (frame, root);
378 g_free (root);
379
380 last_key++;
381 }
382
383 *end_key = last_key;
384 return frame;
385 }
386
387 /* ============================================================ */
388
389 void
390 kvp_frame_set_gint64 (KvpFrame * frame, const gchar *path, gint64 ival)
391 {
392 KvpValue *value;
393 value = kvp_value_new_gint64 (ival);
394 frame = kvp_frame_set_value_nc (frame, path, value);
395 if (!frame)
396 kvp_value_delete (value);
397 }
398
399 void
400 kvp_frame_set_double (KvpFrame * frame, const gchar *path, gdouble dval)
401 {
402 KvpValue *value;
403 value = kvp_value_new_double (dval);
404 frame = kvp_frame_set_value_nc (frame, path, value);
405 if (!frame)
406 kvp_value_delete (value);
407 }
408
409 void
410 kvp_frame_set_time (KvpFrame * frame, const gchar *path, QofTime *qt)
411 {
412 KvpValue *value;
413 value = kvp_value_new_time (qt);
414 frame = kvp_frame_set_value_nc (frame, path, value);
415 if (!frame)
416 kvp_value_delete (value);
417 }
418
419 void
420 kvp_frame_set_numeric (KvpFrame * frame, const gchar *path,
421 QofNumeric nval)
422 {
423 KvpValue *value;
424 value = kvp_value_new_numeric (nval);
425 frame = kvp_frame_set_value_nc (frame, path, value);
426 if (!frame)
427 kvp_value_delete (value);
428 }
429
430 void
431 kvp_frame_set_boolean (KvpFrame * frame, const gchar * path,
432 gboolean val)
433 {
434 KvpValue * value;
435 value = kvp_value_new_boolean (val);
436 frame = kvp_frame_set_value_nc (frame, path, value);
437 if (!frame)
438 kvp_value_delete (value);
439 }
440
441 void
442 kvp_frame_set_string (KvpFrame * frame, const gchar *path,
443 const gchar *str)
444 {
445 KvpValue *value;
446 value = kvp_value_new_string (str);
447 frame = kvp_frame_set_value_nc (frame, path, value);
448 if (!frame)
449 kvp_value_delete (value);
450 }
451
452 void
453 kvp_frame_set_guid (KvpFrame * frame, const gchar *path,
454 const GUID * guid)
455 {
456 KvpValue *value;
457 value = kvp_value_new_guid (guid);
458 frame = kvp_frame_set_value_nc (frame, path, value);
459 if (!frame)
460 kvp_value_delete (value);
461 }
462
463 void
464 kvp_frame_set_frame (KvpFrame * frame, const gchar *path, KvpFrame * fr)
465 {
466 KvpValue *value;
467 value = kvp_value_new_frame (fr);
468 frame = kvp_frame_set_value_nc (frame, path, value);
469 if (!frame)
470 kvp_value_delete (value);
471 }
472
473 void
474 kvp_frame_set_frame_nc (KvpFrame * frame, const gchar *path, KvpFrame * fr)
475 {
476 KvpValue *value;
477 value = kvp_value_new_frame_nc (fr);
478 frame = kvp_frame_set_value_nc (frame, path, value);
479 if (!frame)
480 kvp_value_delete (value);
481 }
482
483 /* ============================================================ */
484
485 KvpFrame *
486 kvp_frame_set_value_nc (KvpFrame * frame, const gchar *key_path,
487 KvpValue * value)
488 {
489 gchar *last_key;
490
491 frame = get_trailer_make (frame, key_path, &last_key);
492 if (!frame)
493 return NULL;
494 kvp_frame_set_slot_destructively (frame, last_key, value);
495 return frame;
496 }
497
498 KvpFrame *
499 kvp_frame_set_value (KvpFrame * frame, const gchar *key_path,
500 const KvpValue * value)
501 {
502 KvpValue *new_value = NULL;
503 gchar *last_key;
504
505 frame = get_trailer_make (frame, key_path, &last_key);
506 if (!frame)
507 return NULL;
508
509 if (value)
510 new_value = kvp_value_copy (value);
511 kvp_frame_set_slot_destructively (frame, last_key, new_value);
512 return frame;
513 }
514
515 KvpValue *
516 kvp_frame_replace_value_nc (KvpFrame * frame, const gchar *key_path,
517 KvpValue * new_value)
518 {
519 KvpValue *old_value;
520 gchar *last_key;
521
522 last_key = NULL;
523 if (new_value)
524 frame = get_trailer_make (frame, key_path, &last_key);
525 else
526 frame =
527 (KvpFrame *) get_trailer_or_null (frame, key_path, &last_key);
528 if (!frame)
529 return NULL;
530
531 old_value = kvp_frame_replace_slot_nc (frame, last_key, new_value);
532 return old_value;
533 }
534
535 /* ============================================================ */
536
537 KvpFrame *
538 kvp_frame_add_value_nc (KvpFrame * frame, const gchar *path,
539 KvpValue * value)
540 {
541 gchar *key = NULL;
542 KvpValue *oldvalue;
543
544 frame = (KvpFrame *) get_trailer_or_null (frame, path, &key);
545 oldvalue = kvp_frame_get_slot (frame, key);
546
547 ENTER ("old frame=%s", kvp_frame_to_string (frame));
548 if (oldvalue)
549 {
550 /* If already a glist here, just append */
551 if (KVP_TYPE_GLIST == oldvalue->type)
552 {
553 GList *vlist = oldvalue->value.list;
554 vlist = g_list_append (vlist, value);
555 oldvalue->value.list = vlist;
556 }
557 else
558 /* If some other value, convert it to a glist */
559 {
560 KvpValue *klist;
561 GList *vlist = NULL;
562
563 vlist = g_list_append (vlist, oldvalue);
564 vlist = g_list_append (vlist, value);
565 klist = kvp_value_new_glist_nc (vlist);
566
567 kvp_frame_replace_slot_nc (frame, key, klist);
568 }
569 LEAVE ("new frame=%s", kvp_frame_to_string (frame));
570 return frame;
571 }
572
573 /* Hmm, if we are here, the path doesn't exist. We need to
574 * create the path, add the value to it. */
575 frame = kvp_frame_set_value_nc (frame, path, value);
576 LEAVE ("new frame=%s", kvp_frame_to_string (frame));
577 return frame;
578 }
579
580 KvpFrame *
581 kvp_frame_add_value (KvpFrame * frame, const gchar *path, KvpValue * value)
582 {
583 value = kvp_value_copy (value);
584 frame = kvp_frame_add_value_nc (frame, path, value);
585 if (!frame)
586 kvp_value_delete (value);
587 return frame;
588 }
589
590 void
591 kvp_frame_add_gint64 (KvpFrame * frame, const gchar *path, gint64 ival)
592 {
593 KvpValue *value;
594 value = kvp_value_new_gint64 (ival);
595 frame = kvp_frame_add_value_nc (frame, path, value);
596 if (!frame)
597 kvp_value_delete (value);
598 }
599
600 void
601 kvp_frame_add_double (KvpFrame * frame, const gchar *path, gdouble dval)
602 {
603 KvpValue *value;
604 value = kvp_value_new_double (dval);
605 frame = kvp_frame_add_value_nc (frame, path, value);
606 if (!frame)
607 kvp_value_delete (value);
608 }
609
610 void
611 kvp_frame_add_numeric (KvpFrame * frame, const gchar *path,
612 QofNumeric nval)
613 {
614 KvpValue *value;
615 value = kvp_value_new_numeric (nval);
616 frame = kvp_frame_add_value_nc (frame, path, value);
617 if (!frame)
618 kvp_value_delete (value);
619 }
620
621 void
622 kvp_frame_add_time (KvpFrame * frame, const gchar *path, QofTime *qt)
623 {
624 KvpValue *value;
625 value = kvp_value_new_time (qt);
626 frame = kvp_frame_add_value_nc (frame, path, value);
627 if (!frame)
628 kvp_value_delete (value);
629 }
630
631 void
632 kvp_frame_add_boolean (KvpFrame * frame, const gchar * path, gboolean val)
633 {
634 KvpValue * value;
635 value = kvp_value_new_boolean (val);
636 frame = kvp_frame_add_value_nc (frame, path, value);
637 if (!frame)
638 kvp_value_delete (value);
639 }
640
641 void
642 kvp_frame_add_string (KvpFrame * frame, const gchar *path, const gchar *str)
643 {
644 KvpValue *value;
645 value = kvp_value_new_string (str);
646 frame = kvp_frame_add_value_nc (frame, path, value);
647 if (!frame)
648 kvp_value_delete (value);
649 }
650
651 void
652 kvp_frame_add_guid (KvpFrame * frame, const gchar *path, const GUID * guid)
653 {
654 KvpValue *value;
655 value = kvp_value_new_guid (guid);
656 frame = kvp_frame_add_value_nc (frame, path, value);
657 if (!frame)
658 kvp_value_delete (value);
659 }
660
661 void
662 kvp_frame_add_frame (KvpFrame * frame, const gchar *path, KvpFrame * fr)
663 {
664 KvpValue *value;
665 value = kvp_value_new_frame (fr);
666 frame = kvp_frame_add_value_nc (frame, path, value);
667 if (!frame)
668 kvp_value_delete (value);
669 }
670
671 void
672 kvp_frame_add_frame_nc (KvpFrame * frame, const gchar *path, KvpFrame * fr)
673 {
674 KvpValue *value;
675 value = kvp_value_new_frame_nc (fr);
676 frame = kvp_frame_add_value_nc (frame, path, value);
677 if (!frame)
678 kvp_value_delete (value);
679 }
680
681 /* ============================================================ */
682
683 void
684 kvp_frame_set_slot (KvpFrame * frame, const gchar *slot,
685 const KvpValue * value)
686 {
687 KvpValue *new_value = NULL;
688
689 if (!frame)
690 return;
691
692 g_return_if_fail (slot && *slot != '\0');
693
694 if (value)
695 new_value = kvp_value_copy (value);
696 kvp_frame_set_slot_destructively (frame, slot, new_value);
697 }
698
699 void
700 kvp_frame_set_slot_nc (KvpFrame * frame, const gchar *slot,
701 KvpValue * value)
702 {
703 if (!frame)
704 return;
705
706 g_return_if_fail (slot && *slot != '\0');
707
708 kvp_frame_set_slot_destructively (frame, slot, value);
709 }
710
711 KvpValue *
712 kvp_frame_get_slot (const KvpFrame * frame, const gchar *slot)
713 {
714 KvpValue *v;
715 if (!frame)
716 return NULL;
717 if (!frame->hash)
718 return NULL; /* Error ... */
719 v = g_hash_table_lookup (frame->hash, slot);
720 return v;
721 }
722
723 /* ============================================================ */
724
725 void
726 kvp_frame_set_slot_path (KvpFrame * frame,
727 const KvpValue * new_value, const gchar *first_key, ...)
728 {
729 va_list ap;
730 const gchar *key;
731
732 if (!frame)
733 return;
734
735 g_return_if_fail (first_key && *first_key != '\0');
736
737 va_start (ap, first_key);
738
739 key = first_key;
740
741 while (TRUE)
742 {
743 KvpValue *value;
744 const gchar *next_key;
745
746 next_key = va_arg (ap, const gchar *);
747 if (!next_key)
748 {
749 kvp_frame_set_slot (frame, key, new_value);
750 break;
751 }
752
753 g_return_if_fail (*next_key != '\0');
754
755 value = kvp_frame_get_slot (frame, key);
756 if (!value)
757 {
758 KvpFrame *new_frame = kvp_frame_new ();
759 KvpValue *frame_value = kvp_value_new_frame (new_frame);
760
761 kvp_frame_set_slot_nc (frame, key, frame_value);
762
763 value = kvp_frame_get_slot (frame, key);
764 if (!value)
765 break;
766 }
767
768 frame = kvp_value_get_frame (value);
769 if (!frame)
770 break;
771
772 key = next_key;
773 }
774
775 va_end (ap);
776 }
777
778 void
779 kvp_frame_set_slot_path_gslist (KvpFrame * frame,
780 const KvpValue * new_value, GSList * key_path)
781 {
782 if (!frame || !key_path)
783 return;
784
785 while (TRUE)
786 {
787 const gchar *key = key_path->data;
788 KvpValue *value;
789
790 if (!key)
791 return;
792
793 g_return_if_fail (*key != '\0');
794
795 key_path = key_path->next;
796 if (!key_path)
797 {
798 kvp_frame_set_slot (frame, key, new_value);
799 return;
800 }
801
802 value = kvp_frame_get_slot (frame, key);
803 if (!value)
804 {
805 KvpFrame *new_frame = kvp_frame_new ();
806 KvpValue *frame_value = kvp_value_new_frame (new_frame);
807
808 kvp_frame_set_slot_nc (frame, key, frame_value);
809
810 value = kvp_frame_get_slot (frame, key);
811 if (!value)
812 return;
813 }
814
815 frame = kvp_value_get_frame (value);
816 if (!frame)
817 return;
818 }
819 }
820
821 /* ============================================================ */
822 /* decode url-encoded string, do it in place
823 * + == space
824 * %xx == asci char where xx is hexadecimal ascii value
825 */
826
827 static void
828 decode (gchar *enc)
829 {
830 gchar *p, *w;
831
832 /* Loop, convert +'s to blanks */
833 p = strchr (enc, '+');
834 while (p)
835 {
836 *p = ' ';
837 p = strchr (p, '+');
838 }
839
840 p = strchr (enc, '%');
841 w = p;
842
843 while (p)
844 {
845 gint ch, cl;
846 p++;
847 ch = *p - 0x30; /* ascii 0 = 0x30 */
848 if (9 < ch)
849 ch -= 0x11 - 10; /* uppercase A = 0x41 */
850 if (16 < ch)
851 ch -= 0x20; /* lowercase a = 0x61 */
852
853 p++;
854 cl = *p - 0x30; /* ascii 0 = 0x30 */
855 if (9 < cl)
856 cl -= 0x11 - 10; /* uppercase A = 0x41 */
857 if (16 < cl)
858 cl -= 0x20; /* lowercase a = 0x61 */
859
860 *w = (gchar) (ch << 4 | cl);
861
862 do
863 {
864 ++w;
865 ++p;
866 *w = *p;
867 if (0x0 == *p)
868 {
869 p = 0;
870 break;
871 }
872 if ('%' == *p)
873 break;
874 }
875 while (*p);
876 }
877 }
878
879 void
880 kvp_frame_add_url_encoding (KvpFrame * frame, const gchar *enc)
881 {
882 gchar *buff, *p;
883 if (!frame || !enc)
884 return;
885
886 /* Loop over all key-value pairs in the encoded string */
887 buff = g_strdup (enc);
888 p = buff;
889 while (*p)
890 {
891 gchar *n, *v;
892 n = strchr (p, '&'); /* n = next key-value */
893 if (n)
894 *n = 0x0;
895
896 v = strchr (p, '='); /* v = pointer to value */
897 if (!v)
898 break;
899 *v = 0x0;
900 v++;
901
902 decode (p);
903 decode (v);
904 kvp_frame_set_slot_nc (frame, p, kvp_value_new_string (v));
905
906 if (!n)
907 break; /* no next key, we are done */
908 p = ++n;
909 }
910
911 g_free (buff);
912 }
913
914 /* ============================================================ */
915
916
917 gint64
918 kvp_frame_get_gint64 (const KvpFrame * frame, const gchar *path)
919 {
920 gchar *key = NULL;
921 frame = get_trailer_or_null (frame, path, &key);
922 return kvp_value_get_gint64 (kvp_frame_get_slot (frame, key));
923 }
924
925 gdouble
926 kvp_frame_get_double (const KvpFrame * frame, const gchar *path)
927 {
928 gchar *key = NULL;
929 frame = get_trailer_or_null (frame, path, &key);
930 return kvp_value_get_double (kvp_frame_get_slot (frame, key));
931 }
932
933 QofNumeric
934 kvp_frame_get_numeric (const KvpFrame * frame, const gchar *path)
935 {
936 gchar *key = NULL;
937 frame = get_trailer_or_null (frame, path, &key);
938 return kvp_value_get_numeric (kvp_frame_get_slot (frame, key));
939 }
940
941 gchar *
942 kvp_frame_get_string (const KvpFrame * frame, const gchar *path)
943 {
944 gchar *key = NULL;
945 frame = get_trailer_or_null (frame, path, &key);
946 return kvp_value_get_string (kvp_frame_get_slot (frame, key));
947 }
948
949 gboolean
950 kvp_frame_get_boolean (const KvpFrame * frame, const gchar * path)
951 {
952 gchar * key = NULL;
953 frame = get_trailer_or_null (frame, path, &key);
954 return kvp_value_get_boolean (kvp_frame_get_slot (frame, key));
955 }
956
957 GUID *
958 kvp_frame_get_guid (const KvpFrame * frame, const gchar *path)
959 {
960 gchar *key = NULL;
961 frame = get_trailer_or_null (frame, path, &key);
962 return kvp_value_get_guid (kvp_frame_get_slot (frame, key));
963 }
964
965 void *
966 kvp_frame_get_binary (const KvpFrame * frame, const gchar *path,
967 guint64 * size_return)
968 {
969 gchar *key = NULL;
970 frame = get_trailer_or_null (frame, path, &key);
971 return kvp_value_get_binary (kvp_frame_get_slot (frame, key),
972 size_return);
973 }
974
975 QofTime *
976 kvp_frame_get_time (const KvpFrame * frame, const gchar *path)
977 {
978 gchar *key = NULL;
979 frame = get_trailer_or_null (frame, path, &key);
980 return kvp_value_get_time (kvp_frame_get_slot (frame, key));
981 }
982
983 KvpFrame *
984 kvp_frame_get_frame (const KvpFrame * frame, const gchar *path)
985 {
986 gchar *key = NULL;
987 frame = get_trailer_or_null (frame, path, &key);
988 return kvp_value_get_frame (kvp_frame_get_slot (frame, key));
989 }
990
991 KvpValue *
992 kvp_frame_get_value (const KvpFrame * frame, const gchar *path)
993 {
994 gchar *key = NULL;
995 frame = get_trailer_or_null (frame, path, &key);
996 return kvp_frame_get_slot (frame, key);
997 }
998
999 /* ============================================================ */
1000
1001 KvpFrame *
1002 kvp_frame_get_frame_gslist (KvpFrame * frame, GSList * key_path)
1003 {
1004 if (!frame)
1005 return frame;
1006
1007 while (key_path)
1008 {
1009 const gchar *key = key_path->data;
1010
1011 if (!key)
1012 return frame; /* an unusual but valid exit for this routine. */
1013
1014 frame = get_or_make (frame, key);
1015 if (!frame)
1016 return frame; /* this should never happen */
1017
1018 key_path = key_path->next;
1019 }
1020 return frame; /* this is the normal exit for this func */
1021 }
1022
1023 KvpFrame *
1024 kvp_frame_get_frame_path (KvpFrame * frame, const gchar *key, ...)
1025 {
1026 va_list ap;
1027 if (!frame || !key)
1028 return frame;
1029
1030 va_start (ap, key);
1031
1032 while (key)
1033 {
1034 frame = get_or_make (frame, key);
1035 if (!frame)
1036 break; /* error, should never occur */
1037 key = va_arg (ap, const char *);
1038 }
1039
1040 va_end (ap);
1041 return frame;
1042 }
1043
1044 KvpFrame *
1045 kvp_frame_get_frame_slash (KvpFrame * frame, const gchar *key_path)
1046 {
1047 gchar *root;
1048 if (!frame || !key_path)
1049 return frame;
1050
1051 root = g_strdup (key_path);
1052 frame = kvp_frame_get_frame_slash_trash (frame, root);
1053 g_free (root);
1054 return frame;
1055 }
1056
1057 /* ============================================================ */
1058
1059 KvpValue *
1060 kvp_frame_get_slot_path (KvpFrame * frame, const gchar *first_key, ...)
1061 {
1062 va_list ap;
1063 KvpValue *value;
1064 const gchar *key;
1065
1066 if (!frame || !first_key)
1067 return NULL;
1068
1069 va_start (ap, first_key);
1070
1071 key = first_key;
1072 value = NULL;
1073
1074 while (TRUE)
1075 {
1076 value = kvp_frame_get_slot (frame, key);
1077 if (!value)
1078 break;
1079
1080 key = va_arg (ap, const gchar *);
1081 if (!key)
1082 break;
1083
1084 frame = kvp_value_get_frame (value);
1085 if (!frame)
1086 {
1087 value = NULL;
1088 break;
1089 }
1090 }
1091
1092 va_end (ap);
1093
1094 return value;
1095 }
1096
1097 KvpValue *
1098 kvp_frame_get_slot_path_gslist (KvpFrame * frame, GSList * key_path)
1099 {
1100 if (!frame || !key_path)
1101 return NULL;
1102
1103 while (TRUE)
1104 {
1105 const gchar *key = key_path->data;
1106 KvpValue *value;
1107
1108 if (!key)
1109 return NULL;
1110
1111 value = kvp_frame_get_slot (frame, key);
1112 if (!value)
1113 return NULL;
1114
1115 key_path = key_path->next;
1116 if (!key_path)
1117 return value;
1118
1119 frame = kvp_value_get_frame (value);
1120 if (!frame)
1121 return NULL;
1122 }
1123 }
1124
1125 /* *******************************************************************
1126 * kvp glist functions
1127 ********************************************************************/
1128
1129 void
1130 kvp_glist_delete (GList * list)
1131 {
1132 GList *node;
1133 if (!list)
1134 return;
1135
1136 /* Delete the data in the list */
1137 for (node = list; node; node = node->next)
1138 {
1139 KvpValue *val = node->data;
1140 kvp_value_delete (val);
1141 }
1142
1143 /* Free the backbone */
1144 g_list_free (list);
1145 }
1146
1147 GList *
1148 kvp_glist_copy (const GList * list)
1149 {
1150 GList *retval = NULL;
1151 GList *lptr;
1152
1153 if (!list)
1154 return retval;
1155
1156 /* Duplicate the backbone of the list (this duplicates the POINTERS
1157 * to the values; we need to deep-copy the values separately) */
1158 retval = g_list_copy ((GList *) list);
1159
1160 /* This step deep-copies the values */
1161 for (lptr = retval; lptr; lptr = lptr->next)
1162 {
1163 lptr->data = kvp_value_copy (lptr->data);
1164 }
1165
1166 return retval;
1167 }
1168
1169 gint
1170 kvp_glist_compare (const GList * list1, const GList * list2)
1171 {
1172 const GList *lp1;
1173 const GList *lp2;
1174
1175 if (list1 == list2)
1176 return 0;
1177
1178 /* Nothing is always less than something */
1179 if (!list1 && list2)
1180 return -1;
1181 if (list1 && !list2)
1182 return 1;
1183
1184 lp1 = list1;
1185 lp2 = list2;
1186 while (lp1 && lp2)
1187 {
1188 KvpValue *v1 = (KvpValue *) lp1->data;
1189 KvpValue *v2 = (KvpValue *) lp2->data;
1190 gint vcmp = kvp_value_compare (v1, v2);
1191 if (vcmp != 0)
1192 return vcmp;
1193 lp1 = lp1->next;
1194 lp2 = lp2->next;
1195 }
1196 if (!lp1 && lp2)
1197 return -1;
1198 if (!lp2 && lp1)
1199 return 1;
1200 return 0;
1201 }
1202
1203 /* *******************************************************************
1204 * KvpValue functions
1205 ********************************************************************/
1206
1207 KvpValue *
1208 kvp_value_new_gint64 (gint64 value)
1209 {
1210 KvpValue *retval = g_new0 (KvpValue, 1);
1211 retval->type = KVP_TYPE_GINT64;
1212 retval->value.int64 = value;
1213 return retval;
1214 }
1215
1216 KvpValue *
1217 kvp_value_new_double (gdouble value)
1218 {
1219 KvpValue *retval = g_new0 (KvpValue, 1);
1220 retval->type = KVP_TYPE_DOUBLE;
1221 retval->value.dbl = value;
1222 return retval;
1223 }
1224
1225 KvpValue *
1226 kvp_value_new_boolean (gboolean value)
1227 {
1228 KvpValue * retval = g_new0 (KvpValue, 1);
1229 retval->type = KVP_TYPE_BOOLEAN;
1230 retval->value.gbool = value;
1231 return retval;
1232 }
1233
1234 KvpValue *
1235 kvp_value_new_numeric (QofNumeric value)
1236 {
1237 KvpValue *retval = g_new0 (KvpValue, 1);
1238 retval->type = KVP_TYPE_NUMERIC;
1239 retval->value.numeric = value;
1240 return retval;
1241 }
1242
1243 KvpValue *
1244 kvp_value_new_string (const gchar *value)
1245 {
1246 KvpValue *retval;
1247 if (!value)
1248 return NULL;
1249
1250 retval = g_new0 (KvpValue, 1);
1251 retval->type = KVP_TYPE_STRING;
1252 retval->value.str = g_strdup (value);
1253 return retval;
1254 }
1255
1256 KvpValue *
1257 kvp_value_new_guid (const GUID * value)
1258 {
1259 KvpValue *retval;
1260 if (!value)
1261 return NULL;
1262
1263 retval = g_new0 (KvpValue, 1);
1264 retval->type = KVP_TYPE_GUID;
1265 retval->value.guid = g_new0 (GUID, 1);
1266 memcpy (retval->value.guid, value, sizeof (GUID));
1267 return retval;
1268 }
1269
1270 KvpValue *
1271 kvp_value_new_time (QofTime *value)
1272 {
1273 KvpValue *retval = g_new0 (KvpValue, 1);
1274 retval->type = KVP_TYPE_TIME;
1275 retval->value.qt = value;
1276 return retval;
1277 }
1278
1279 KvpValue *
1280 kvp_value_new_binary (gconstpointer value, guint64 datasize)
1281 {
1282 KvpValue *retval;
1283 if (!value)
1284 return NULL;
1285
1286 retval = g_new0 (KvpValue, 1);
1287 retval->type = KVP_TYPE_BINARY;
1288 retval->value.binary.data = g_new0 (gpointer, datasize);
1289 retval->value.binary.datasize = datasize;
1290 memcpy (retval->value.binary.data, value, datasize);
1291 return retval;
1292 }
1293
1294 KvpValue *
1295 kvp_value_new_binary_nc (gpointer value, guint64 datasize)
1296 {
1297 KvpValue *retval;
1298 if (!value)
1299 return NULL;
1300
1301 retval = g_new0 (KvpValue, 1);
1302 retval->type = KVP_TYPE_BINARY;
1303 retval->value.binary.data = value;
1304 retval->value.binary.datasize = datasize;
1305 return retval;
1306 }
1307
1308 KvpValue *
1309 kvp_value_new_glist (const GList * value)
1310 {
1311 KvpValue *retval;
1312 if (!value)
1313 return NULL;
1314
1315 retval = g_new0 (KvpValue, 1);
1316 retval->type = KVP_TYPE_GLIST;
1317 retval->value.list = kvp_glist_copy (value);
1318 return retval;
1319 }
1320
1321 KvpValue *
1322 kvp_value_new_glist_nc (GList * value)
1323 {
1324 KvpValue *retval;
1325 if (!value)
1326 return NULL;
1327
1328 retval = g_new0 (KvpValue, 1);
1329 retval->type = KVP_TYPE_GLIST;
1330 retval->value.list = value;
1331 return retval;
1332 }
1333
1334 KvpValue *
1335 kvp_value_new_frame (const KvpFrame * value)
1336 {
1337 KvpValue *retval;
1338 if (!value)
1339 return NULL;
1340
1341 retval = g_new0 (KvpValue, 1);
1342 retval->type = KVP_TYPE_FRAME;
1343 retval->value.frame = kvp_frame_copy (value);
1344 return retval;
1345 }
1346
1347 KvpValue *
1348 kvp_value_new_frame_nc (KvpFrame * value)
1349 {
1350 KvpValue *retval;
1351 if (!value)
1352 return NULL;
1353
1354 retval = g_new0 (KvpValue, 1);
1355 retval->type = KVP_TYPE_FRAME;
1356 retval->value.frame = value;
1357 return retval;
1358 }
1359
1360 void
1361 kvp_value_delete (KvpValue * value)
1362 {
1363 if (!value)
1364 return;
1365
1366 switch (value->type)
1367 {
1368 case KVP_TYPE_STRING:
1369 g_free (value->value.str);
1370 break;
1371 case KVP_TYPE_GUID:
1372 g_free (value->value.guid);
1373 break;
1374 case KVP_TYPE_BINARY:
1375 g_free (value->value.binary.data);
1376 break;
1377 case KVP_TYPE_GLIST:
1378 kvp_glist_delete (value->value.list);
1379 break;
1380 case KVP_TYPE_FRAME:
1381 kvp_frame_delete (value->value.frame);
1382 break;
1383 case KVP_TYPE_BOOLEAN:
1384 case KVP_TYPE_GINT64:
1385 case KVP_TYPE_DOUBLE:
1386 case KVP_TYPE_NUMERIC:
1387 default:
1388 break;
1389 }
1390 g_free (value);
1391 }
1392
1393 KvpValueType
1394 kvp_value_get_type (const KvpValue * value)
1395 {
1396 if (!value)
1397 return QOF_FATAL;
1398 return value->type;
1399 }
1400
1401 gint64
1402 kvp_value_get_gint64 (const KvpValue * value)
1403 {
1404 if (!value)
1405 return 0;
1406 if (value->type == KVP_TYPE_GINT64)
1407 return value->value.int64;
1408 else
1409 {
1410 PERR (" value type %d does not match KVP_TYPE_GINT64",
1411 value->type);
1412 return 0;
1413 }
1414 }
1415
1416 gdouble
1417 kvp_value_get_double (const KvpValue * value)
1418 {
1419 if (!value)
1420 return 0.0;
1421 if (value->type == KVP_TYPE_DOUBLE)
1422 return value->value.dbl;
1423 else
1424 {
1425 PERR (" value type %d does not match KVP_TYPE_DOUBLE",
1426 value->type);
1427 return 0.0;
1428 }
1429 }
1430
1431 QofNumeric
1432 kvp_value_get_numeric (const KvpValue * value)
1433 {
1434 if (!value)
1435 return qof_numeric_zero ();
1436 if (value->type == KVP_TYPE_NUMERIC)
1437 return value->value.numeric;
1438 else
1439 {
1440 PERR (" value type %d does not match KVP_TYPE_NUMERIC",
1441 value->type);
1442 return qof_numeric_zero ();
1443 }
1444 }
1445
1446 gchar *
1447 kvp_value_get_string (const KvpValue * value)
1448 {
1449 if (!value)
1450 return NULL;
1451 if (value->type == KVP_TYPE_STRING)
1452 return value->value.str;
1453 else
1454 {
1455 PERR (" value type %d does not match KVP_TYPE_STRING",
1456 value->type);
1457 return NULL;
1458 }
1459 }
1460
1461 gboolean
1462 kvp_value_get_boolean (const KvpValue * value)
1463 {
1464 if (!value)
1465 return FALSE;
1466 if (value->type == KVP_TYPE_BOOLEAN)
1467 return value->value.gbool;
1468 else
1469 {
1470 PERR (" value type %d does not match KVP_TYPE_BOOLEAN",
1471 value->type);
1472 return FALSE;
1473 }
1474 }
1475
1476 GUID *
1477 kvp_value_get_guid (const KvpValue * value)
1478 {
1479 if (!value)
1480 return NULL;
1481 if (value->type == KVP_TYPE_GUID)
1482 return value->value.guid;
1483 else
1484 {
1485 PERR (" value type %d does not match KVP_TYPE_GUID",
1486 value->type);
1487 return NULL;
1488 }
1489 }
1490
1491 QofTime*
1492 kvp_value_get_time (const KvpValue * value)
1493 {
1494 if (!value)
1495 return NULL;
1496 if (value->type == KVP_TYPE_TIME)
1497 return value->value.qt;
1498 else
1499 {
1500 PERR (" value type %d does not match KVP_TYPE_TIME",
1501 value->type);
1502 return NULL;
1503 }
1504 }
1505
1506 void *
1507 kvp_value_get_binary (const KvpValue * value, guint64 * size_return)
1508 {
1509 if (!value)
1510 {
1511 if (size_return)
1512 *size_return = 0;
1513 PERR (" no size specified");
1514 return NULL;
1515 }
1516
1517 if (value->type == KVP_TYPE_BINARY)
1518 {
1519 if (size_return)
1520 *size_return = value->value.binary.datasize;
1521 return value->value.binary.data;
1522 }
1523 else
1524 {
1525 if (size_return)
1526 *size_return = 0;
1527 PERR (" value type %d does not match KVP_TYPE_BINARY",
1528 value->type);
1529 return NULL;
1530 }
1531 }
1532
1533 GList *
1534 kvp_value_get_glist (const KvpValue * value)
1535 {
1536 if (!value)
1537 return NULL;
1538 if (value->type == KVP_TYPE_GLIST)
1539 return value->value.list;
1540 else
1541 {
1542 PERR (" value type %d does not match KVP_TYPE_GLIST",
1543 value->type);
1544 return NULL;
1545 }
1546 }
1547
1548 KvpFrame *
1549 kvp_value_get_frame (const KvpValue * value)
1550 {
1551 if (!value)
1552 return NULL;
1553 if (value->type == KVP_TYPE_FRAME)
1554 return value->value.frame;
1555 else
1556 {
1557 PERR (" value type %d does not match KVP_TYPE_FRAME",
1558 value->type);
1559 return NULL;
1560 }
1561 }
1562
1563 KvpFrame *
1564 kvp_value_replace_frame_nc (KvpValue * value, KvpFrame * newframe)
1565 {
1566 KvpFrame *oldframe;
1567 if (!value)
1568 return NULL;
1569 if (KVP_TYPE_FRAME != value->type)
1570 {
1571 PERR (" value type %d does not match KVP_TYPE_FRAME",
1572 value->type);
1573 return NULL;
1574 }
1575 oldframe = value->value.frame;
1576 value->value.frame = newframe;
1577 return oldframe;
1578 }
1579
1580 GList *
1581 kvp_value_replace_glist_nc (KvpValue * value, GList * newlist)
1582 {
1583 GList *oldlist;
1584 if (!value)
1585 return NULL;
1586 if (KVP_TYPE_GLIST != value->type)
1587 {
1588 PERR (" value type %d does not match KVP_TYPE_GLIST",
1589 value->type);
1590 return NULL;
1591 }
1592
1593 oldlist = value->value.list;
1594 value->value.list = newlist;
1595 return oldlist;
1596 }
1597
1598 /* manipulators */
1599
1600 KvpValue *
1601 kvp_value_copy (const KvpValue * value)
1602 {
1603 if (!value)
1604 return NULL;
1605
1606 switch (value->type)
1607 {
1608 case KVP_TYPE_GINT64:
1609 return kvp_value_new_gint64 (value->value.int64);
1610 break;
1611 case KVP_TYPE_DOUBLE:
1612 return kvp_value_new_double (value->value.dbl);
1613 break;
1614 case KVP_TYPE_NUMERIC:
1615 return kvp_value_new_numeric (value->value.numeric);
1616 break;
1617 case KVP_TYPE_STRING:
1618 return kvp_value_new_string (value->value.str);
1619 break;
1620 case KVP_TYPE_GUID:
1621 return kvp_value_new_guid (value->value.guid);
1622 break;
1623 case KVP_TYPE_BOOLEAN:
1624 return NULL;
1625 return kvp_value_new_boolean (value->value.gbool);
1626 break;
1627 case KVP_TYPE_TIME :
1628 return kvp_value_new_time (value->value.qt);
1629 break;
1630 #ifndef QOF_DISABLE_DEPRECATED
1631 case KVP_TYPE_TIMESPEC:
1632 return kvp_value_new_timespec (value->value.timespec);
1633 break;
1634 #endif
1635 case KVP_TYPE_BINARY:
1636 return kvp_value_new_binary (value->value.binary.data,
1637 value->value.binary.datasize);
1638 break;
1639 case KVP_TYPE_GLIST:
1640 return kvp_value_new_glist (value->value.list);
1641 break;
1642 case KVP_TYPE_FRAME:
1643 return kvp_value_new_frame (value->value.frame);
1644 break;
1645 }
1646 return NULL;
1647 }
1648
1649 void
1650 kvp_frame_for_each_slot (KvpFrame * f, KvpValueForeachCB proc, gpointer data)
1651 {
1652 if (!f)
1653 return;
1654 if (!proc)
1655 return;
1656 if (!(f->hash))
1657 return;
1658 g_hash_table_foreach (f->hash, (GHFunc) proc, data);
1659 }
1660
1661 gint
1662 kvp_value_compare (const KvpValue * kva, const KvpValue * kvb)
1663 {
1664 if (kva == kvb)
1665 return 0;
1666 /* nothing is always less than something */
1667 if (!kva && kvb)
1668 return -1;
1669 if (kva && !kvb)
1670 return 1;
1671
1672 if (kva->type < kvb->type)
1673 return -1;
1674 if (kva->type > kvb->type)
1675 return 1;
1676
1677 switch (kva->type)
1678 {
1679 case KVP_TYPE_GINT64:
1680 if (kva->value.int64 < kvb->value.int64)
1681 return -1;
1682 if (kva->value.int64 > kvb->value.int64)
1683 return 1;
1684 return 0;
1685 break;
1686 case KVP_TYPE_DOUBLE:
1687 return qof_util_double_compare (kva->value.dbl, kvb->value.dbl);
1688 break;
1689 case KVP_TYPE_NUMERIC:
1690 return qof_numeric_compare (kva->value.numeric,
1691 kvb->value.numeric);
1692 break;
1693 case KVP_TYPE_STRING:
1694 return strcmp (kva->value.str, kvb->value.str);
1695 break;
1696 case KVP_TYPE_GUID:
1697 return guid_compare (kva->value.guid, kvb->value.guid);
1698 break;
1699 case KVP_TYPE_BOOLEAN:
1700 {
1701 /* true > false */
1702 if (kva->value.gbool != kvb->value.gbool)
1703 return (kva->value.gbool) ? 1 : -1;
1704 return 0;
1705 break;
1706 }
1707 case KVP_TYPE_TIME :
1708 return qof_time_cmp (kva->value.qt, kvb->value.qt);
1709 break;
1710 #ifndef QOF_DISABLE_DEPRECATED
1711 case KVP_TYPE_TIMESPEC:
1712 return timespec_cmp (&(kva->value.timespec),
1713 &(kvb->value.timespec));
1714 break;
1715 #endif
1716 case KVP_TYPE_BINARY:
1717 if (kva->value.binary.datasize < kvb->value.binary.datasize)
1718 return -1;
1719 if (kva->value.binary.datasize > kvb->value.binary.datasize)
1720 return 1;
1721 return memcmp (kva->value.binary.data,
1722 kvb->value.binary.data, kva->value.binary.datasize);
1723 break;
1724 case KVP_TYPE_GLIST:
1725 return kvp_glist_compare (kva->value.list, kvb->value.list);
1726 break;
1727 case KVP_TYPE_FRAME:
1728 return kvp_frame_compare (kva->value.frame, kvb->value.frame);
1729 break;
1730 }
1731 return 0;
1732 }
1733
1734 typedef struct
1735 {
1736 gint compare;
1737 KvpFrame *other_frame;
1738 } KvpFrameCompare;
1739
1740 static void
1741 kvp_frame_compare_helper (const gchar *key, KvpValue * val, gpointer data)
1742 {
1743 KvpFrameCompare *status = (KvpFrameCompare *) data;
1744 if (status->compare == 0)
1745 {
1746 KvpFrame *other_frame = status->other_frame;
1747 KvpValue *other_val = kvp_frame_get_slot (other_frame, key);
1748
1749 if (other_val)
1750 status->compare = kvp_value_compare (val, other_val);
1751 else
1752 status->compare = 1;
1753 }
1754 }
1755
1756 gint
1757 kvp_frame_compare (const KvpFrame * fa, const KvpFrame * fb)
1758 {
1759 KvpFrameCompare status;
1760
1761 if (fa == fb)
1762 return 0;
1763 /* nothing is always less than something */
1764 if (!fa && fb)
1765 return -1;
1766 if (fa && !fb)
1767 return 1;
1768
1769 /* nothing is always less than something */
1770 if (!fa->hash && fb->hash)
1771 return -1;
1772 if (fa->hash && !fb->hash)
1773 return 1;
1774
1775 status.compare = 0;
1776 status.other_frame = (KvpFrame *) fb;
1777
1778 kvp_frame_for_each_slot ((KvpFrame *) fa, kvp_frame_compare_helper,
1779 &status);
1780
1781 if (status.compare != 0)
1782 return status.compare;
1783
1784 status.other_frame = (KvpFrame *) fa;
1785
1786 kvp_frame_for_each_slot ((KvpFrame *) fb, kvp_frame_compare_helper,
1787 &status);
1788
1789 return (-status.compare);
1790 }
1791
1792 /* FIXME: genuine binary content cannot be made a string reliably. */
1793 gchar *
1794 binary_to_string (gconstpointer data, guint32 size)
1795 {
1796 GString *output;
1797 guint32 i;
1798 guchar *data_str = (guchar *) data;
1799
1800 output = g_string_sized_new (size * sizeof (gchar));
1801
1802 for (i = 0; i < size; i++)
1803 {
1804 g_string_append_printf (output, "%02x",
1805 (guint32) (data_str[i]));
1806 }
1807
1808 return output->str;
1809 }
1810
1811 gchar *
1812 kvp_value_glist_to_string (const GList * list)
1813 {
1814 gchar *tmp1;
1815 gchar *tmp2;
1816 const GList *cursor;
1817
1818 tmp1 = g_strdup_printf ("[ ");
1819
1820 for (cursor = list; cursor; cursor = cursor->next)
1821 {
1822 gchar *tmp3;
1823
1824 tmp3 = kvp_value_to_string ((KvpValue *) cursor->data);
1825 tmp2 = g_strdup_printf ("%s %s,", tmp1, tmp3 ? tmp3 : "");
1826 g_free (tmp1);
1827 g_free (tmp3);
1828 tmp1 = tmp2;
1829 }
1830
1831 tmp2 = g_strdup_printf ("%s ]", tmp1);
1832 g_free (tmp1);
1833
1834 return tmp2;
1835 }
1836
1837 static void
1838 kvp_frame_to_bare_string_helper (gpointer key __attribute__ ((unused)),
1839 gpointer value, gpointer data)
1840 {
1841 gchar **str = (gchar **) data;
1842 *str =
1843 g_strdup_printf ("%s",
1844 kvp_value_to_bare_string ((KvpValue *) value));
1845 }
1846
1847 gchar *
1848 kvp_value_to_bare_string (const KvpValue * val)
1849 {
1850 gchar *tmp1;
1851 gchar *tmp2;
1852 const gchar *ctmp;
1853
1854 g_return_val_if_fail (val, NULL);
1855 tmp1 = g_strdup ("");
1856 switch (kvp_value_get_type (val))
1857 {
1858 case KVP_TYPE_GINT64:
1859 {
1860 return g_strdup_printf ("%" G_GINT64_FORMAT,
1861 kvp_value_get_gint64 (val));
1862 break;
1863 }
1864 case KVP_TYPE_DOUBLE:
1865 {
1866 return g_strdup_printf ("(%g)", kvp_value_get_double (val));
1867 break;
1868 }
1869 case KVP_TYPE_NUMERIC:
1870 {
1871 tmp1 = qof_numeric_to_string (kvp_value_get_numeric (val));
1872 tmp2 = g_strdup_printf ("%s", tmp1 ? tmp1 : "");
1873 g_free (tmp1);
1874 return tmp2;
1875 break;
1876 }
1877 case KVP_TYPE_STRING:
1878 {
1879 tmp1 = kvp_value_get_string (val);
1880 return g_strdup_printf ("%s", tmp1 ? tmp1 : "");
1881 break;
1882 }
1883 case KVP_TYPE_GUID:
1884 {
1885 ctmp = guid_to_string (kvp_value_get_guid (val));
1886 tmp2 = g_strdup_printf ("%s", ctmp ? ctmp : "");
1887 return tmp2;
1888 break;
1889 }
1890 #ifndef QOF_DISABLE_DEPRECATED
1891 case KVP_TYPE_TIMESPEC:
1892 {
1893 time_t t;
1894 t = timespecToTime_t (kvp_value_get_timespec (val));
1895 qof_date_format_set (QOF_DATE_FORMAT_UTC);
1896 return qof_print_date (t);
1897 break;
1898 }
1899 #endif
1900 case KVP_TYPE_BOOLEAN :
1901 return (kvp_value_get_boolean (val)) ? "TRUE" : "FALSE";
1902 case KVP_TYPE_BINARY:
1903 {
1904 guint64 len;
1905 gpointer data;
1906 data = kvp_value_get_binary (val, &len);
1907 tmp1 = binary_to_string (data, len);
1908 return g_strdup_printf ("%s", tmp1 ? tmp1 : "");
1909 break;
1910 }
1911 case KVP_TYPE_GLIST:
1912 /* borked. kvp_value_glist_to_string is a debug fcn */
1913 {
1914 tmp1 = kvp_value_glist_to_string (kvp_value_get_glist (val));
1915 tmp2 = g_strdup_printf ("%s", tmp1 ? tmp1 : "");
1916 g_free (tmp1);
1917 return tmp2;
1918 break;
1919 }
1920 case KVP_TYPE_FRAME:
1921 {
1922 KvpFrame *frame;
1923
1924 frame = kvp_value_get_frame (val);
1925 if (frame->hash)
1926 {
1927 tmp1 = g_strdup ("");
1928 g_hash_table_foreach (frame->hash,
1929 kvp_frame_to_bare_string_helper, &tmp1);
1930 }
1931 return tmp1;
1932 break;
1933 }
1934 default:
1935 return g_strdup_printf (" ");
1936 break;
1937 }
1938 }
1939
1940 gchar *
1941 kvp_value_to_string (const KvpValue * val)
1942 {
1943 gchar *tmp1;
1944 gchar *tmp2;
1945 const gchar *ctmp;
1946
1947 g_return_val_if_fail (val, NULL);
1948
1949 switch (kvp_value_get_type (val))
1950 {
1951 case KVP_TYPE_GINT64:
1952 {
1953 return g_strdup_printf ("KVP_VALUE_GINT64(%" G_GINT64_FORMAT ")",
1954 kvp_value_get_gint64 (val));
1955 break;
1956 }
1957 case KVP_TYPE_DOUBLE:
1958 {
1959 return g_strdup_printf ("KVP_VALUE_DOUBLE(%g)",
1960 kvp_value_get_double (val));
1961 break;
1962 }
1963 case KVP_TYPE_NUMERIC:
1964 {
1965 tmp1 = qof_numeric_to_string (kvp_value_get_numeric (val));
1966 tmp2 = g_strdup_printf ("KVP_VALUE_NUMERIC(%s)", tmp1 ? tmp1 : "");
1967 g_free (tmp1);
1968 return tmp2;
1969 break;
1970 }
1971 case KVP_TYPE_STRING:
1972 {
1973 tmp1 = kvp_value_get_string (val);
1974 return g_strdup_printf ("KVP_VALUE_STRING(%s)", tmp1 ? tmp1 : "");
1975 break;
1976 }
1977 case KVP_TYPE_GUID:
1978 {
1979 /* THREAD-UNSAFE */
1980 ctmp = guid_to_string (kvp_value_get_guid (val));
1981 tmp2 = g_strdup_printf ("KVP_VALUE_GUID(%s)", ctmp ? ctmp : "");
1982 return tmp2;
1983 break;
1984 }
1985 #ifndef QOF_DISABLE_DEPRECATED
1986 case KVP_TYPE_TIMESPEC:
1987 {
1988 tmp1 = g_new0 (gchar, 40);
1989 gnc_timespec_to_iso8601_buff (kvp_value_get_timespec (val), tmp1);
1990 tmp2 = g_strdup_printf ("KVP_VALUE_TIMESPEC(%s)", tmp1);
1991 g_free (tmp1);
1992 return tmp2;
1993 break;
1994 }
1995 #endif
1996 case KVP_TYPE_BINARY:
1997 {
1998 guint64 len;
1999 gpointer data;
2000 data = kvp_value_get_binary (val, &len);
2001 tmp1 = binary_to_string (data, len);
2002 return g_strdup_printf ("KVP_VALUE_BINARY(%s)",
2003 tmp1 ? tmp1 : "");
2004 break;
2005 }
2006 case KVP_TYPE_GLIST:
2007 {
2008 tmp1 = kvp_value_glist_to_string (kvp_value_get_glist (val));
2009 tmp2 = g_strdup_printf ("KVP_VALUE_GLIST(%s)", tmp1 ? tmp1 : "");
2010 g_free (tmp1);
2011 return tmp2;
2012 break;
2013 }
2014 case KVP_TYPE_FRAME:
2015 {
2016 tmp1 = kvp_frame_to_string (kvp_value_get_frame (val));
2017 tmp2 = g_strdup_printf ("KVP_VALUE_FRAME(%s)", tmp1 ? tmp1 : "");
2018 g_free (tmp1);
2019 return tmp2;
2020 break;
2021 }
2022 default:
2023 return g_strdup_printf (" ");
2024 break;
2025 }
2026 }
2027
2028 static void
2029 kvp_frame_to_string_helper (gpointer key, gpointer value, gpointer data)
2030 {
2031 gchar *tmp_val;
2032 gchar **str = (gchar **) data;
2033 gchar *old_data = *str;
2034
2035 tmp_val = kvp_value_to_string ((KvpValue *) value);
2036
2037 *str = g_strdup_printf ("%s %s => %s,\n",
2038 *str ? *str : "", key ? (gchar *) key : "", tmp_val ? tmp_val : "");
2039
2040 g_free (old_data);
2041 g_free (tmp_val);
2042 }
2043
2044 gchar *
2045 kvp_frame_to_string (const KvpFrame * frame)
2046 {
2047 gchar *tmp1;
2048
2049 g_return_val_if_fail (frame != NULL, NULL);
2050
2051 tmp1 = g_strdup_printf ("{\n");
2052
2053 if (frame->hash)
2054 g_hash_table_foreach (frame->hash, kvp_frame_to_string_helper,
2055 &tmp1);
2056 {
2057 gchar *tmp2;
2058 tmp2 = g_strdup_printf ("%s}\n", tmp1);
2059 g_free (tmp1);
2060 tmp1 = tmp2;
2061 }
2062
2063 return tmp1;
2064 }
2065
2066 GHashTable *
2067 kvp_frame_get_hash (const KvpFrame * frame)
2068 {
2069 g_return_val_if_fail (frame != NULL, NULL);
2070 return frame->hash;
2071 }
2072
2073 /* ========================== END OF FILE ======================= */
kvp_value_get_guid
GUID * kvp_value_get_guid(const KvpValue *value)
Definition: kvpframe.c:1477
KVP_TYPE_TIMESPEC
Definition: kvpframe.h:121
kvp_frame_get_frame_path
KvpFrame * kvp_frame_get_frame_path(KvpFrame *frame, const gchar *key,...)
Definition: kvpframe.c:1024
QOF_DATE_FORMAT_UTC
#define QOF_DATE_FORMAT_UTC
QOF UTC format, xsd:date compatible. QOF_UTC_DATE_FORMAT "%Y-%m-%dT%H:%M:%SZ".
Definition: qofdate.h:277
kvp_value_get_timespec
Timespec kvp_value_get_timespec(const KvpValue *value)
Definition: deprecated.c:1493
PERR
#define PERR(format, args...)
Definition: qoflog.h:183
kvp_frame_add_time
void kvp_frame_add_time(KvpFrame *frame, const gchar *path, QofTime *qt)
Add the value of the QofTime to the glist bag.
Definition: kvpframe.c:622
qof_numeric_compare
gint qof_numeric_compare(QofNumeric a, QofNumeric b)
Definition: qofnumeric.c:174
kvp_value_replace_glist_nc
GList * kvp_value_replace_glist_nc(KvpValue *value, GList *newlist)
Definition: kvpframe.c:1581
kvp_glist_copy
GList * kvp_glist_copy(const GList *list)
Definition: kvpframe.c:1148
kvp_frame_set_guid
void kvp_frame_set_guid(KvpFrame *frame, const gchar *path, const GUID *guid)
Store a copy of the GUID at the indicated path.
Definition: kvpframe.c:453
KvpValueType
KvpValueType
possible types in the union KvpValue
Definition: kvpframe.h:87
kvp_frame_set_numeric
void kvp_frame_set_numeric(KvpFrame *frame, const gchar *path, QofNumeric nval)
store the value of the QofNumeric at the indicated path.
Definition: kvpframe.c:420
KVP_TYPE_GUID
Unique identifier.
Definition: kvpframe.h:118
kvp_frame_set_frame_nc
void kvp_frame_set_frame_nc(KvpFrame *frame, const gchar *path, KvpFrame *fr)
Store a KvpFrame at the indicated path without copying.
Definition: kvpframe.c:474
kvp_frame_set_time
void kvp_frame_set_time(KvpFrame *frame, const gchar *path, QofTime *qt)
Store a copy of the QofTime at the indicated path.
Definition: kvpframe.c:410
kvp_frame_add_value
KvpFrame * kvp_frame_add_value(KvpFrame *frame, const gchar *path, KvpValue *value)
Add a copy of the value to the glist bag.
Definition: kvpframe.c:581
kvp_frame_add_frame_nc
void kvp_frame_add_frame_nc(KvpFrame *frame, const gchar *path, KvpFrame *fr)
Add the frame to the glist bag without copying.
Definition: kvpframe.c:672
kvp_frame_compare
gint kvp_frame_compare(const KvpFrame *fa, const KvpFrame *fb)
Definition: kvpframe.c:1757
kvp_frame_get_frame_slash
KvpFrame * kvp_frame_get_frame_slash(KvpFrame *frame, const gchar *key_path)
Definition: kvpframe.c:1045
kvp_frame_copy
KvpFrame * kvp_frame_copy(const KvpFrame *frame)
Definition: kvpframe.c:156
KvpFrame
struct _KvpFrame KvpFrame
Definition: kvpframe.h:74
timespec64
Definition: qoftime.h:97
kvp_frame_set_slot_path
void kvp_frame_set_slot_path(KvpFrame *frame, const KvpValue *new_value, const gchar *first_key,...)
Definition: kvpframe.c:726
kvp_glist_compare
gint kvp_glist_compare(const GList *list1, const GList *list2)
Definition: kvpframe.c:1170
kvp_frame_set_gint64
void kvp_frame_set_gint64(KvpFrame *frame, const gchar *path, gint64 ival)
store the value of the gint64 at the indicated path.
Definition: kvpframe.c:390
kvp_value_new_boolean
KvpValue * kvp_value_new_boolean(gboolean value)
Definition: kvpframe.c:1226
KVP_TYPE_GLIST
Definition: kvpframe.h:132
KVP_TYPE_FRAME
Definition: kvpframe.h:134
kvp_frame_is_empty
gboolean kvp_frame_is_empty(KvpFrame *frame)
Definition: kvpframe.c:137
LEAVE
#define LEAVE(format, args...)
Definition: qoflog.h:227
kvp_value_new_frame_nc
KvpValue * kvp_value_new_frame_nc(KvpFrame *value)
Definition: kvpframe.c:1348
kvp_frame_set_slot_path_gslist
void kvp_frame_set_slot_path_gslist(KvpFrame *frame, const KvpValue *new_value, GSList *key_path)
Definition: kvpframe.c:779
kvp_frame_get_frame_gslist
KvpFrame * kvp_frame_get_frame_gslist(KvpFrame *frame, GSList *key_path)
Definition: kvpframe.c:1002
kvp_frame_set_value
KvpFrame * kvp_frame_set_value(KvpFrame *frame, const gchar *key_path, const KvpValue *value)
Copy the KvpValue into the frame.
Definition: kvpframe.c:499
kvp_value_get_binary
void * kvp_value_get_binary(const KvpValue *value, guint64 *size_return)
Definition: kvpframe.c:1507
KVP_TYPE_NUMERIC
128bit denominator/numerator maths.
Definition: kvpframe.h:106
kvp_frame_add_url_encoding
void kvp_frame_add_url_encoding(KvpFrame *frame, const gchar *enc)
Definition: kvpframe.c:880
kvp_frame_delete
void kvp_frame_delete(KvpFrame *frame)
Definition: kvpframe.c:118
kvp_value_get_gint64
gint64 kvp_value_get_gint64(const KvpValue *value)
Definition: kvpframe.c:1402
kvp_frame_replace_value_nc
KvpValue * kvp_frame_replace_value_nc(KvpFrame *frame, const gchar *key_path, KvpValue *new_value)
Definition: kvpframe.c:516
kvp_frame_set_frame
void kvp_frame_set_frame(KvpFrame *frame, const gchar *path, KvpFrame *fr)
Store a copy of the KvpFrame at the indicated path.
Definition: kvpframe.c:464
KvpValueForeachCB
void(* KvpValueForeachCB)(const gchar *key, KvpValue *value, gpointer data)
Definition: kvpframe.h:770
KvpValue
struct _KvpValue KvpValue
Definition: kvpframe.h:78
kvp_frame_replace_slot_nc
KvpValue * kvp_frame_replace_slot_nc(KvpFrame *frame, const gchar *slot, KvpValue *new_value)
Definition: kvpframe.c:178
kvp_value_new_timespec
KvpValue * kvp_value_new_timespec(Timespec timespec)
Definition: deprecated.c:1482
qof_util_string_cache_insert
gpointer qof_util_string_cache_insert(gconstpointer key)
Definition: qofutil.c:439
kvp_frame_set_slot
void kvp_frame_set_slot(KvpFrame *frame, const gchar *slot, const KvpValue *value)
Definition: kvpframe.c:684
qof_util_string_cache_remove
void qof_util_string_cache_remove(gconstpointer key)
Definition: qofutil.c:432
kvp_value_copy
KvpValue * kvp_value_copy(const KvpValue *value)
Definition: kvpframe.c:1601
guid_to_string
const char * guid_to_string(const GUID *guid)
Definition: guid.c:611
qof_time_cmp
gint qof_time_cmp(const QofTime *ta, const QofTime *tb)
Definition: qoftime.c:165
kvp_value_new_binary_nc
KvpValue * kvp_value_new_binary_nc(void *data, guint64 datasize)
KVP_TYPE_GINT64
64bit integer
Definition: kvpframe.h:94
_QofNumeric
Definition: qofnumeric.h:52
kvp_frame_add_double
void kvp_frame_add_double(KvpFrame *frame, const gchar *path, gdouble dval)
Add the value of the double to the glist bag.
Definition: kvpframe.c:601
kvp_frame_set_slot_nc
void kvp_frame_set_slot_nc(KvpFrame *frame, const gchar *slot, KvpValue *value)
Definition: kvpframe.c:700
kvp_frame_set_boolean
void kvp_frame_set_boolean(KvpFrame *frame, const gchar *path, gboolean val)
Store the value of the boolean at the indicated path.
Definition: kvpframe.c:431
kvp_value_get_glist
GList * kvp_value_get_glist(const KvpValue *value)
Definition: kvpframe.c:1534
timespec_cmp
gint timespec_cmp(const Timespec *ta, const Timespec *tb)
Definition: deprecated.c:290
kvp_value_to_bare_string
gchar * kvp_value_to_bare_string(const KvpValue *val)
General purpose function to convert any KvpValue to a string.
Definition: kvpframe.c:1848
kvp_value_replace_frame_nc
KvpFrame * kvp_value_replace_frame_nc(KvpValue *value, KvpFrame *newframe)
Definition: kvpframe.c:1564
kvp_glist_delete
void kvp_glist_delete(GList *list)
Definition: kvpframe.c:1130
kvp_value_get_string
gchar * kvp_value_get_string(const KvpValue *value)
Definition: kvpframe.c:1447
kvp_frame_add_frame
void kvp_frame_add_frame(KvpFrame *frame, const gchar *path, KvpFrame *fr)
Copy the frame to the glist bag at the indicated path.
Definition: kvpframe.c:662
kvp_frame_add_string
void kvp_frame_add_string(KvpFrame *frame, const gchar *path, const gchar *str)
Copy the string to the glist bag at the indicated path.
Definition: kvpframe.c:642
kvp_frame_get_slot_path
KvpValue * kvp_frame_get_slot_path(KvpFrame *frame, const gchar *first_key,...)
Definition: kvpframe.c:1060
kvp_frame_set_value_nc
KvpFrame * kvp_frame_set_value_nc(KvpFrame *frame, const gchar *key_path, KvpValue *value)
Store the KvpValue in the frame without copying.
Definition: kvpframe.c:486
kvp_frame_for_each_slot
void kvp_frame_for_each_slot(KvpFrame *f, KvpValueForeachCB proc, gpointer data)
Definition: kvpframe.c:1650
_GUID
Definition: guid.h:53
qof_numeric_to_string
gchar * qof_numeric_to_string(QofNumeric n)
Definition: qofnumeric.c:1089
kvp_value_new_glist
KvpValue * kvp_value_new_glist(const GList *value)
Definition: kvpframe.c:1309
kvp_value_new_glist_nc
KvpValue * kvp_value_new_glist_nc(GList *value)
Definition: kvpframe.c:1322
QofTime
struct QofTime64 QofTime
Use a 64-bit signed int QofTime.
Definition: qoftime.h:120
KVP_TYPE_BOOLEAN
Simple boolean type.
Definition: kvpframe.h:140
kvp_frame_add_gint64
void kvp_frame_add_gint64(KvpFrame *frame, const gchar *path, gint64 ival)
add the value of the gint64 to the glist bag
Definition: kvpframe.c:591
KVP_TYPE_BINARY
Definition: kvpframe.h:130
qof_util_double_compare
gint qof_util_double_compare(gdouble d1, gdouble d2)
Compare two gdouble values.
Definition: qofutil.c:179
timespecToTime_t
time_t timespecToTime_t(Timespec ts)
Definition: deprecated.c:315
qof_date_format_set
void qof_date_format_set(QofDateFormat df)
Definition: deprecated.c:1427
KVP_TYPE_STRING
standard C string
Definition: kvpframe.h:112
QOF_FATAL
#define QOF_FATAL
general error value
Definition: qoferror.h:131
qof_numeric_zero
static QofNumeric qof_numeric_zero(void)
Definition: qofnumeric.h:253
kvp_frame_set_double
void kvp_frame_set_double(KvpFrame *frame, const gchar *path, gdouble dval)
store the value of the double at the indicated path.
Definition: kvpframe.c:400
kvp_frame_new
KvpFrame * kvp_frame_new(void)
Definition: kvpframe.c:100
kvp_value_get_frame
KvpFrame * kvp_value_get_frame(const KvpValue *value)
Definition: kvpframe.c:1549
KVP_TYPE_DOUBLE
standard C double type
Definition: kvpframe.h:100
kvp_frame_get_frame
KvpFrame * kvp_frame_get_frame(const KvpFrame *frame, const gchar *path)
Definition: kvpframe.c:984
kvp_value_delete
void kvp_value_delete(KvpValue *value)
Definition: kvpframe.c:1361
kvp_frame_get_slot_path_gslist
KvpValue * kvp_frame_get_slot_path_gslist(KvpFrame *frame, GSList *key_path)
Definition: kvpframe.c:1098
kvp_value_compare
gint kvp_value_compare(const KvpValue *kva, const KvpValue *kvb)
Definition: kvpframe.c:1662
ENTER
#define ENTER(format, args...)
Definition: qoflog.h:217
kvp_value_to_string
gchar * kvp_value_to_string(const KvpValue *val)
Debug version.
Definition: kvpframe.c:1941
gnc_timespec_to_iso8601_buff
gchar * gnc_timespec_to_iso8601_buff(Timespec ts, gchar *buff)
Definition: deprecated.c:1197
QofLogModule
const gchar * QofLogModule
Definition: qofid.h:85
kvp_frame_set_string
void kvp_frame_set_string(KvpFrame *frame, const gchar *path, const gchar *str)
Store a copy of the string at the indicated path.
Definition: kvpframe.c:442
kvp_frame_add_numeric
void kvp_frame_add_numeric(KvpFrame *frame, const gchar *path, QofNumeric nval)
Add the value of the QofNumeric to the glist bag.
Definition: kvpframe.c:611
KVP_TYPE_TIME
64bit time/date handling.
Definition: kvpframe.h:128
qof_print_date
char * qof_print_date(time_t secs)
Definition: deprecated.c:767
kvp_frame_add_guid
void kvp_frame_add_guid(KvpFrame *frame, const gchar *path, const GUID *guid)
Copy the GUID to the glist bag at the indicated path.
Definition: kvpframe.c:652