00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "config.h"
00027
00028 #include <glib.h>
00029 #include <stdarg.h>
00030 #include <stdio.h>
00031 #include <string.h>
00032 #include "qof.h"
00033
00034
00035
00036
00037
00038 struct _KvpFrame
00039 {
00040 GHashTable *hash;
00041 };
00042
00043 typedef struct
00044 {
00045 gpointer data;
00046 gint64 datasize;
00047 } KvpValueBinaryData;
00048
00049 struct _KvpValue
00050 {
00051 KvpValueType type;
00052 union
00053 {
00054 gint64 int64;
00055 gdouble dbl;
00056 QofNumeric numeric;
00057 gchar *str;
00058 GUID *guid;
00059 QofTime *qt;
00060 gboolean gbool;
00061 KvpValueBinaryData binary;
00062 GList *list;
00063 KvpFrame *frame;
00064 } value;
00065 };
00066
00067
00068 static QofLogModule log_module = QOF_MOD_KVP;
00069
00070
00071
00072
00073
00074 static guint
00075 kvp_hash_func (gconstpointer v)
00076 {
00077 return g_str_hash (v);
00078 }
00079
00080 static gint
00081 kvp_comp_func (gconstpointer v, gconstpointer v2)
00082 {
00083 return g_str_equal (v, v2);
00084 }
00085
00086 static gboolean
00087 init_frame_body_if_needed (KvpFrame * f)
00088 {
00089 if (!f->hash)
00090 {
00091 f->hash = g_hash_table_new (&kvp_hash_func, &kvp_comp_func);
00092 }
00093 return (f->hash != NULL);
00094 }
00095
00096 KvpFrame *
00097 kvp_frame_new (void)
00098 {
00099 KvpFrame *retval = g_new0 (KvpFrame, 1);
00100
00101
00102 retval->hash = NULL;
00103 return retval;
00104 }
00105
00106 static void
00107 kvp_frame_delete_worker (gpointer key, gpointer value,
00108 gpointer user_data __attribute__ ((unused)))
00109 {
00110 qof_util_string_cache_remove (key);
00111 kvp_value_delete ((KvpValue *) value);
00112 }
00113
00114 void
00115 kvp_frame_delete (KvpFrame * frame)
00116 {
00117 if (!frame)
00118 return;
00119
00120 if (frame->hash)
00121 {
00122
00123 g_hash_table_foreach (frame->hash, &kvp_frame_delete_worker,
00124 (gpointer) frame);
00125
00126
00127 g_hash_table_destroy (frame->hash);
00128 frame->hash = NULL;
00129 }
00130 g_free (frame);
00131 }
00132
00133 gboolean
00134 kvp_frame_is_empty (KvpFrame * frame)
00135 {
00136 if (!frame)
00137 return TRUE;
00138 if (!frame->hash)
00139 return TRUE;
00140 return FALSE;
00141 }
00142
00143 static void
00144 kvp_frame_copy_worker (gpointer key, gpointer value, gpointer user_data)
00145 {
00146 KvpFrame *dest = (KvpFrame *) user_data;
00147 g_hash_table_insert (dest->hash,
00148 qof_util_string_cache_insert (key),
00149 (gpointer) kvp_value_copy (value));
00150 }
00151
00152 KvpFrame *
00153 kvp_frame_copy (const KvpFrame * frame)
00154 {
00155 KvpFrame *retval = kvp_frame_new ();
00156
00157 if (!frame)
00158 return retval;
00159
00160 if (frame->hash)
00161 {
00162 if (!init_frame_body_if_needed (retval))
00163 return (NULL);
00164 g_hash_table_foreach (frame->hash,
00165 &kvp_frame_copy_worker, (gpointer) retval);
00166 }
00167 return retval;
00168 }
00169
00170
00171
00172
00173
00174 KvpValue *
00175 kvp_frame_replace_slot_nc (KvpFrame * frame, const gchar *slot,
00176 KvpValue * new_value)
00177 {
00178 gpointer orig_key;
00179 gpointer orig_value = NULL;
00180 int key_exists;
00181
00182 if (!frame || !slot)
00183 return NULL;
00184 if (!init_frame_body_if_needed (frame))
00185 return NULL;
00186
00187 key_exists = g_hash_table_lookup_extended (frame->hash, slot,
00188 &orig_key, &orig_value);
00189 if (key_exists)
00190 {
00191 g_hash_table_remove (frame->hash, slot);
00192 qof_util_string_cache_remove (orig_key);
00193 }
00194 else
00195 orig_value = NULL;
00196 if (new_value)
00197 g_hash_table_insert (frame->hash,
00198 qof_util_string_cache_insert ((gpointer) slot), new_value);
00199 return (KvpValue *) orig_value;
00200 }
00201
00202
00203
00204
00205 static inline void
00206 kvp_frame_set_slot_destructively (KvpFrame * frame, const gchar *slot,
00207 KvpValue * new_value)
00208 {
00209 KvpValue *old_value;
00210 old_value = kvp_frame_replace_slot_nc (frame, slot, new_value);
00211 kvp_value_delete (old_value);
00212 }
00213
00214
00215
00216
00217
00218
00219 static inline KvpFrame *
00220 get_or_make (KvpFrame * fr, const gchar *key)
00221 {
00222 KvpFrame *next_frame;
00223 KvpValue *value;
00224
00225 value = kvp_frame_get_slot (fr, key);
00226 if (value)
00227 next_frame = kvp_value_get_frame (value);
00228 else
00229 {
00230 next_frame = kvp_frame_new ();
00231 kvp_frame_set_slot_nc (fr, key,
00232 kvp_value_new_frame_nc (next_frame));
00233 }
00234 return next_frame;
00235 }
00236
00237
00238
00239
00240
00241 static KvpFrame *
00242 kvp_frame_get_frame_slash_trash (KvpFrame * frame, gchar *key_path)
00243 {
00244 gchar *key, *next;
00245 if (!frame || !key_path)
00246 return frame;
00247
00248 key = key_path;
00249 key--;
00250
00251 while (key)
00252 {
00253 key++;
00254 while ('/' == *key)
00255 key++;
00256 if (0x0 == *key)
00257 break;
00258 next = strchr (key, '/');
00259 if (next)
00260 *next = 0x0;
00261
00262 frame = get_or_make (frame, key);
00263 if (!frame)
00264 break;
00265
00266 key = next;
00267 }
00268 return frame;
00269 }
00270
00271
00272
00273
00274
00275 static inline const KvpFrame *
00276 kvp_frame_get_frame_or_null_slash_trash (const KvpFrame * frame,
00277 gchar *key_path)
00278 {
00279 KvpValue *value;
00280 gchar *key, *next;
00281 if (!frame || !key_path)
00282 return NULL;
00283
00284 key = key_path;
00285 key--;
00286
00287 while (key)
00288 {
00289 key++;
00290 while ('/' == *key)
00291 key++;
00292 if (0x0 == *key)
00293 break;
00294 next = strchr (key, '/');
00295 if (next)
00296 *next = 0x0;
00297
00298 value = kvp_frame_get_slot (frame, key);
00299 if (!value)
00300 return NULL;
00301 frame = kvp_value_get_frame (value);
00302 if (!frame)
00303 return NULL;
00304
00305 key = next;
00306 }
00307 return frame;
00308 }
00309
00310
00311
00312
00313
00314
00315 static inline KvpFrame *
00316 get_trailer_make (KvpFrame * frame, const gchar *key_path,
00317 gchar **end_key)
00318 {
00319 gchar *last_key;
00320
00321 if (!frame || !key_path || (0 == key_path[0]))
00322 return NULL;
00323
00324 last_key = strrchr (key_path, '/');
00325 if (NULL == last_key)
00326 last_key = (gchar *) key_path;
00327 else if (last_key == key_path)
00328 last_key++;
00329 else if (0 == last_key[1])
00330 return NULL;
00331 else
00332 {
00333 gchar *root, *lkey;
00334 root = g_strdup (key_path);
00335 lkey = strrchr (root, '/');
00336 *lkey = 0;
00337 frame = kvp_frame_get_frame_slash_trash (frame, root);
00338 g_free (root);
00339 last_key++;
00340 }
00341
00342 *end_key = last_key;
00343 return frame;
00344 }
00345
00346
00347
00348
00349
00350
00351
00352 static inline const KvpFrame *
00353 get_trailer_or_null (const KvpFrame * frame, const gchar *key_path,
00354 gchar **end_key)
00355 {
00356 gchar *last_key;
00357
00358 if (!frame || !key_path || (0 == key_path[0]))
00359 return NULL;
00360
00361 last_key = strrchr (key_path, '/');
00362 if (NULL == last_key)
00363 last_key = (gchar *) key_path;
00364 else if (last_key == key_path)
00365 last_key++;
00366 else if (0 == last_key[1])
00367 return NULL;
00368 else
00369 {
00370 gchar *root, *lkey;
00371 root = g_strdup (key_path);
00372 lkey = strrchr (root, '/');
00373 *lkey = 0;
00374 frame = kvp_frame_get_frame_or_null_slash_trash (frame, root);
00375 g_free (root);
00376
00377 last_key++;
00378 }
00379
00380 *end_key = last_key;
00381 return frame;
00382 }
00383
00384
00385
00386 void
00387 kvp_frame_set_gint64 (KvpFrame * frame, const gchar *path, gint64 ival)
00388 {
00389 KvpValue *value;
00390 value = kvp_value_new_gint64 (ival);
00391 frame = kvp_frame_set_value_nc (frame, path, value);
00392 if (!frame)
00393 kvp_value_delete (value);
00394 }
00395
00396 void
00397 kvp_frame_set_double (KvpFrame * frame, const gchar *path, gdouble dval)
00398 {
00399 KvpValue *value;
00400 value = kvp_value_new_double (dval);
00401 frame = kvp_frame_set_value_nc (frame, path, value);
00402 if (!frame)
00403 kvp_value_delete (value);
00404 }
00405
00406 void
00407 kvp_frame_set_time (KvpFrame * frame, const gchar *path, QofTime *qt)
00408 {
00409 KvpValue *value;
00410 value = kvp_value_new_time (qt);
00411 frame = kvp_frame_set_value_nc (frame, path, value);
00412 if (!frame)
00413 kvp_value_delete (value);
00414 }
00415
00416 void
00417 kvp_frame_set_numeric (KvpFrame * frame, const gchar *path,
00418 QofNumeric nval)
00419 {
00420 KvpValue *value;
00421 value = kvp_value_new_numeric (nval);
00422 frame = kvp_frame_set_value_nc (frame, path, value);
00423 if (!frame)
00424 kvp_value_delete (value);
00425 }
00426
00427 void
00428 kvp_frame_set_boolean (KvpFrame * frame, const gchar * path,
00429 gboolean val)
00430 {
00431 KvpValue * value;
00432 value = kvp_value_new_boolean (val);
00433 frame = kvp_frame_set_value_nc (frame, path, value);
00434 if (!frame)
00435 kvp_value_delete (value);
00436 }
00437
00438 void
00439 kvp_frame_set_string (KvpFrame * frame, const gchar *path,
00440 const gchar *str)
00441 {
00442 KvpValue *value;
00443 value = kvp_value_new_string (str);
00444 frame = kvp_frame_set_value_nc (frame, path, value);
00445 if (!frame)
00446 kvp_value_delete (value);
00447 }
00448
00449 void
00450 kvp_frame_set_guid (KvpFrame * frame, const gchar *path,
00451 const GUID * guid)
00452 {
00453 KvpValue *value;
00454 value = kvp_value_new_guid (guid);
00455 frame = kvp_frame_set_value_nc (frame, path, value);
00456 if (!frame)
00457 kvp_value_delete (value);
00458 }
00459
00460 void
00461 kvp_frame_set_frame (KvpFrame * frame, const gchar *path, KvpFrame * fr)
00462 {
00463 KvpValue *value;
00464 value = kvp_value_new_frame (fr);
00465 frame = kvp_frame_set_value_nc (frame, path, value);
00466 if (!frame)
00467 kvp_value_delete (value);
00468 }
00469
00470 void
00471 kvp_frame_set_frame_nc (KvpFrame * frame, const gchar *path, KvpFrame * fr)
00472 {
00473 KvpValue *value;
00474 value = kvp_value_new_frame_nc (fr);
00475 frame = kvp_frame_set_value_nc (frame, path, value);
00476 if (!frame)
00477 kvp_value_delete (value);
00478 }
00479
00480
00481
00482 KvpFrame *
00483 kvp_frame_set_value_nc (KvpFrame * frame, const gchar *key_path,
00484 KvpValue * value)
00485 {
00486 gchar *last_key;
00487
00488 frame = get_trailer_make (frame, key_path, &last_key);
00489 if (!frame)
00490 return NULL;
00491 kvp_frame_set_slot_destructively (frame, last_key, value);
00492 return frame;
00493 }
00494
00495 KvpFrame *
00496 kvp_frame_set_value (KvpFrame * frame, const gchar *key_path,
00497 const KvpValue * value)
00498 {
00499 KvpValue *new_value = NULL;
00500 gchar *last_key;
00501
00502 frame = get_trailer_make (frame, key_path, &last_key);
00503 if (!frame)
00504 return NULL;
00505
00506 if (value)
00507 new_value = kvp_value_copy (value);
00508 kvp_frame_set_slot_destructively (frame, last_key, new_value);
00509 return frame;
00510 }
00511
00512 KvpValue *
00513 kvp_frame_replace_value_nc (KvpFrame * frame, const gchar *key_path,
00514 KvpValue * new_value)
00515 {
00516 KvpValue *old_value;
00517 gchar *last_key;
00518
00519 last_key = NULL;
00520 if (new_value)
00521 frame = get_trailer_make (frame, key_path, &last_key);
00522 else
00523 frame =
00524 (KvpFrame *) get_trailer_or_null (frame, key_path, &last_key);
00525 if (!frame)
00526 return NULL;
00527
00528 old_value = kvp_frame_replace_slot_nc (frame, last_key, new_value);
00529 return old_value;
00530 }
00531
00532
00533
00534 KvpFrame *
00535 kvp_frame_add_value_nc (KvpFrame * frame, const gchar *path,
00536 KvpValue * value)
00537 {
00538 gchar *key = NULL;
00539 KvpValue *oldvalue;
00540
00541 frame = (KvpFrame *) get_trailer_or_null (frame, path, &key);
00542 oldvalue = kvp_frame_get_slot (frame, key);
00543
00544 ENTER ("old frame=%s", kvp_frame_to_string (frame));
00545 if (oldvalue)
00546 {
00547
00548 if (KVP_TYPE_GLIST == oldvalue->type)
00549 {
00550 GList *vlist = oldvalue->value.list;
00551 vlist = g_list_append (vlist, value);
00552 oldvalue->value.list = vlist;
00553 }
00554 else
00555
00556 {
00557 KvpValue *klist;
00558 GList *vlist = NULL;
00559
00560 vlist = g_list_append (vlist, oldvalue);
00561 vlist = g_list_append (vlist, value);
00562 klist = kvp_value_new_glist_nc (vlist);
00563
00564 kvp_frame_replace_slot_nc (frame, key, klist);
00565 }
00566 LEAVE ("new frame=%s", kvp_frame_to_string (frame));
00567 return frame;
00568 }
00569
00570
00571
00572 frame = kvp_frame_set_value_nc (frame, path, value);
00573 LEAVE ("new frame=%s", kvp_frame_to_string (frame));
00574 return frame;
00575 }
00576
00577 KvpFrame *
00578 kvp_frame_add_value (KvpFrame * frame, const gchar *path, KvpValue * value)
00579 {
00580 value = kvp_value_copy (value);
00581 frame = kvp_frame_add_value_nc (frame, path, value);
00582 if (!frame)
00583 kvp_value_delete (value);
00584 return frame;
00585 }
00586
00587 void
00588 kvp_frame_add_gint64 (KvpFrame * frame, const gchar *path, gint64 ival)
00589 {
00590 KvpValue *value;
00591 value = kvp_value_new_gint64 (ival);
00592 frame = kvp_frame_add_value_nc (frame, path, value);
00593 if (!frame)
00594 kvp_value_delete (value);
00595 }
00596
00597 void
00598 kvp_frame_add_double (KvpFrame * frame, const gchar *path, gdouble dval)
00599 {
00600 KvpValue *value;
00601 value = kvp_value_new_double (dval);
00602 frame = kvp_frame_add_value_nc (frame, path, value);
00603 if (!frame)
00604 kvp_value_delete (value);
00605 }
00606
00607 void
00608 kvp_frame_add_numeric (KvpFrame * frame, const gchar *path,
00609 QofNumeric nval)
00610 {
00611 KvpValue *value;
00612 value = kvp_value_new_numeric (nval);
00613 frame = kvp_frame_add_value_nc (frame, path, value);
00614 if (!frame)
00615 kvp_value_delete (value);
00616 }
00617
00618 void
00619 kvp_frame_add_time (KvpFrame * frame, const gchar *path, QofTime *qt)
00620 {
00621 KvpValue *value;
00622 value = kvp_value_new_time (qt);
00623 frame = kvp_frame_add_value_nc (frame, path, value);
00624 if (!frame)
00625 kvp_value_delete (value);
00626 }
00627
00628 void
00629 kvp_frame_add_boolean (KvpFrame * frame, const gchar * path, gboolean val)
00630 {
00631 KvpValue * value;
00632 value = kvp_value_new_boolean (val);
00633 frame = kvp_frame_add_value_nc (frame, path, value);
00634 if (!frame)
00635 kvp_value_delete (value);
00636 }
00637
00638 void
00639 kvp_frame_add_string (KvpFrame * frame, const gchar *path, const gchar *str)
00640 {
00641 KvpValue *value;
00642 value = kvp_value_new_string (str);
00643 frame = kvp_frame_add_value_nc (frame, path, value);
00644 if (!frame)
00645 kvp_value_delete (value);
00646 }
00647
00648 void
00649 kvp_frame_add_guid (KvpFrame * frame, const gchar *path, const GUID * guid)
00650 {
00651 KvpValue *value;
00652 value = kvp_value_new_guid (guid);
00653 frame = kvp_frame_add_value_nc (frame, path, value);
00654 if (!frame)
00655 kvp_value_delete (value);
00656 }
00657
00658 void
00659 kvp_frame_add_frame (KvpFrame * frame, const gchar *path, KvpFrame * fr)
00660 {
00661 KvpValue *value;
00662 value = kvp_value_new_frame (fr);
00663 frame = kvp_frame_add_value_nc (frame, path, value);
00664 if (!frame)
00665 kvp_value_delete (value);
00666 }
00667
00668 void
00669 kvp_frame_add_frame_nc (KvpFrame * frame, const gchar *path, KvpFrame * fr)
00670 {
00671 KvpValue *value;
00672 value = kvp_value_new_frame_nc (fr);
00673 frame = kvp_frame_add_value_nc (frame, path, value);
00674 if (!frame)
00675 kvp_value_delete (value);
00676 }
00677
00678
00679
00680 void
00681 kvp_frame_set_slot (KvpFrame * frame, const gchar *slot,
00682 const KvpValue * value)
00683 {
00684 KvpValue *new_value = NULL;
00685
00686 if (!frame)
00687 return;
00688
00689 g_return_if_fail (slot && *slot != '\0');
00690
00691 if (value)
00692 new_value = kvp_value_copy (value);
00693 kvp_frame_set_slot_destructively (frame, slot, new_value);
00694 }
00695
00696 void
00697 kvp_frame_set_slot_nc (KvpFrame * frame, const gchar *slot,
00698 KvpValue * value)
00699 {
00700 if (!frame)
00701 return;
00702
00703 g_return_if_fail (slot && *slot != '\0');
00704
00705 kvp_frame_set_slot_destructively (frame, slot, value);
00706 }
00707
00708 KvpValue *
00709 kvp_frame_get_slot (const KvpFrame * frame, const gchar *slot)
00710 {
00711 KvpValue *v;
00712 if (!frame)
00713 return NULL;
00714 if (!frame->hash)
00715 return NULL;
00716 v = g_hash_table_lookup (frame->hash, slot);
00717 return v;
00718 }
00719
00720
00721
00722 void
00723 kvp_frame_set_slot_path (KvpFrame * frame,
00724 const KvpValue * new_value, const gchar *first_key, ...)
00725 {
00726 va_list ap;
00727 const gchar *key;
00728
00729 if (!frame)
00730 return;
00731
00732 g_return_if_fail (first_key && *first_key != '\0');
00733
00734 va_start (ap, first_key);
00735
00736 key = first_key;
00737
00738 while (TRUE)
00739 {
00740 KvpValue *value;
00741 const gchar *next_key;
00742
00743 next_key = va_arg (ap, const gchar *);
00744 if (!next_key)
00745 {
00746 kvp_frame_set_slot (frame, key, new_value);
00747 break;
00748 }
00749
00750 g_return_if_fail (*next_key != '\0');
00751
00752 value = kvp_frame_get_slot (frame, key);
00753 if (!value)
00754 {
00755 KvpFrame *new_frame = kvp_frame_new ();
00756 KvpValue *frame_value = kvp_value_new_frame (new_frame);
00757
00758 kvp_frame_set_slot_nc (frame, key, frame_value);
00759
00760 value = kvp_frame_get_slot (frame, key);
00761 if (!value)
00762 break;
00763 }
00764
00765 frame = kvp_value_get_frame (value);
00766 if (!frame)
00767 break;
00768
00769 key = next_key;
00770 }
00771
00772 va_end (ap);
00773 }
00774
00775 void
00776 kvp_frame_set_slot_path_gslist (KvpFrame * frame,
00777 const KvpValue * new_value, GSList * key_path)
00778 {
00779 if (!frame || !key_path)
00780 return;
00781
00782 while (TRUE)
00783 {
00784 const gchar *key = key_path->data;
00785 KvpValue *value;
00786
00787 if (!key)
00788 return;
00789
00790 g_return_if_fail (*key != '\0');
00791
00792 key_path = key_path->next;
00793 if (!key_path)
00794 {
00795 kvp_frame_set_slot (frame, key, new_value);
00796 return;
00797 }
00798
00799 value = kvp_frame_get_slot (frame, key);
00800 if (!value)
00801 {
00802 KvpFrame *new_frame = kvp_frame_new ();
00803 KvpValue *frame_value = kvp_value_new_frame (new_frame);
00804
00805 kvp_frame_set_slot_nc (frame, key, frame_value);
00806
00807 value = kvp_frame_get_slot (frame, key);
00808 if (!value)
00809 return;
00810 }
00811
00812 frame = kvp_value_get_frame (value);
00813 if (!frame)
00814 return;
00815 }
00816 }
00817
00818
00819
00820
00821
00822
00823
00824 static void
00825 decode (gchar *enc)
00826 {
00827 gchar *p, *w;
00828
00829
00830 p = strchr (enc, '+');
00831 while (p)
00832 {
00833 *p = ' ';
00834 p = strchr (p, '+');
00835 }
00836
00837 p = strchr (enc, '%');
00838 w = p;
00839
00840 while (p)
00841 {
00842 gint ch, cl;
00843 p++;
00844 ch = *p - 0x30;
00845 if (9 < ch)
00846 ch -= 0x11 - 10;
00847 if (16 < ch)
00848 ch -= 0x20;
00849
00850 p++;
00851 cl = *p - 0x30;
00852 if (9 < cl)
00853 cl -= 0x11 - 10;
00854 if (16 < cl)
00855 cl -= 0x20;
00856
00857 *w = (gchar) (ch << 4 | cl);
00858
00859 do
00860 {
00861 ++w;
00862 ++p;
00863 *w = *p;
00864 if (0x0 == *p)
00865 {
00866 p = 0;
00867 break;
00868 }
00869 if ('%' == *p)
00870 break;
00871 }
00872 while (*p);
00873 }
00874 }
00875
00876 void
00877 kvp_frame_add_url_encoding (KvpFrame * frame, const gchar *enc)
00878 {
00879 gchar *buff, *p;
00880 if (!frame || !enc)
00881 return;
00882
00883
00884 buff = g_strdup (enc);
00885 p = buff;
00886 while (*p)
00887 {
00888 gchar *n, *v;
00889 n = strchr (p, '&');
00890 if (n)
00891 *n = 0x0;
00892
00893 v = strchr (p, '=');
00894 if (!v)
00895 break;
00896 *v = 0x0;
00897 v++;
00898
00899 decode (p);
00900 decode (v);
00901 kvp_frame_set_slot_nc (frame, p, kvp_value_new_string (v));
00902
00903 if (!n)
00904 break;
00905 p = ++n;
00906 }
00907
00908 g_free (buff);
00909 }
00910
00911
00912
00913
00914 gint64
00915 kvp_frame_get_gint64 (const KvpFrame * frame, const gchar *path)
00916 {
00917 gchar *key = NULL;
00918 frame = get_trailer_or_null (frame, path, &key);
00919 return kvp_value_get_gint64 (kvp_frame_get_slot (frame, key));
00920 }
00921
00922 gdouble
00923 kvp_frame_get_double (const KvpFrame * frame, const gchar *path)
00924 {
00925 gchar *key = NULL;
00926 frame = get_trailer_or_null (frame, path, &key);
00927 return kvp_value_get_double (kvp_frame_get_slot (frame, key));
00928 }
00929
00930 QofNumeric
00931 kvp_frame_get_numeric (const KvpFrame * frame, const gchar *path)
00932 {
00933 gchar *key = NULL;
00934 frame = get_trailer_or_null (frame, path, &key);
00935 return kvp_value_get_numeric (kvp_frame_get_slot (frame, key));
00936 }
00937
00938 gchar *
00939 kvp_frame_get_string (const KvpFrame * frame, const gchar *path)
00940 {
00941 gchar *key = NULL;
00942 frame = get_trailer_or_null (frame, path, &key);
00943 return kvp_value_get_string (kvp_frame_get_slot (frame, key));
00944 }
00945
00946 gboolean
00947 kvp_frame_get_boolean (const KvpFrame * frame, const gchar * path)
00948 {
00949 gchar * key = NULL;
00950 frame = get_trailer_or_null (frame, path, &key);
00951 return kvp_value_get_boolean (kvp_frame_get_slot (frame, key));
00952 }
00953
00954 GUID *
00955 kvp_frame_get_guid (const KvpFrame * frame, const gchar *path)
00956 {
00957 gchar *key = NULL;
00958 frame = get_trailer_or_null (frame, path, &key);
00959 return kvp_value_get_guid (kvp_frame_get_slot (frame, key));
00960 }
00961
00962 void *
00963 kvp_frame_get_binary (const KvpFrame * frame, const gchar *path,
00964 guint64 * size_return)
00965 {
00966 gchar *key = NULL;
00967 frame = get_trailer_or_null (frame, path, &key);
00968 return kvp_value_get_binary (kvp_frame_get_slot (frame, key),
00969 size_return);
00970 }
00971
00972 QofTime *
00973 kvp_frame_get_time (const KvpFrame * frame, const gchar *path)
00974 {
00975 gchar *key = NULL;
00976 frame = get_trailer_or_null (frame, path, &key);
00977 return kvp_value_get_time (kvp_frame_get_slot (frame, key));
00978 }
00979
00980 KvpFrame *
00981 kvp_frame_get_frame (const KvpFrame * frame, const gchar *path)
00982 {
00983 gchar *key = NULL;
00984 frame = get_trailer_or_null (frame, path, &key);
00985 return kvp_value_get_frame (kvp_frame_get_slot (frame, key));
00986 }
00987
00988 KvpValue *
00989 kvp_frame_get_value (const KvpFrame * frame, const gchar *path)
00990 {
00991 gchar *key = NULL;
00992 frame = get_trailer_or_null (frame, path, &key);
00993 return kvp_frame_get_slot (frame, key);
00994 }
00995
00996
00997
00998 KvpFrame *
00999 kvp_frame_get_frame_gslist (KvpFrame * frame, GSList * key_path)
01000 {
01001 if (!frame)
01002 return frame;
01003
01004 while (key_path)
01005 {
01006 const gchar *key = key_path->data;
01007
01008 if (!key)
01009 return frame;
01010
01011 frame = get_or_make (frame, key);
01012 if (!frame)
01013 return frame;
01014
01015 key_path = key_path->next;
01016 }
01017 return frame;
01018 }
01019
01020 KvpFrame *
01021 kvp_frame_get_frame_path (KvpFrame * frame, const gchar *key, ...)
01022 {
01023 va_list ap;
01024 if (!frame || !key)
01025 return frame;
01026
01027 va_start (ap, key);
01028
01029 while (key)
01030 {
01031 frame = get_or_make (frame, key);
01032 if (!frame)
01033 break;
01034 key = va_arg (ap, const char *);
01035 }
01036
01037 va_end (ap);
01038 return frame;
01039 }
01040
01041 KvpFrame *
01042 kvp_frame_get_frame_slash (KvpFrame * frame, const gchar *key_path)
01043 {
01044 gchar *root;
01045 if (!frame || !key_path)
01046 return frame;
01047
01048 root = g_strdup (key_path);
01049 frame = kvp_frame_get_frame_slash_trash (frame, root);
01050 g_free (root);
01051 return frame;
01052 }
01053
01054
01055
01056 KvpValue *
01057 kvp_frame_get_slot_path (KvpFrame * frame, const gchar *first_key, ...)
01058 {
01059 va_list ap;
01060 KvpValue *value;
01061 const gchar *key;
01062
01063 if (!frame || !first_key)
01064 return NULL;
01065
01066 va_start (ap, first_key);
01067
01068 key = first_key;
01069 value = NULL;
01070
01071 while (TRUE)
01072 {
01073 value = kvp_frame_get_slot (frame, key);
01074 if (!value)
01075 break;
01076
01077 key = va_arg (ap, const gchar *);
01078 if (!key)
01079 break;
01080
01081 frame = kvp_value_get_frame (value);
01082 if (!frame)
01083 {
01084 value = NULL;
01085 break;
01086 }
01087 }
01088
01089 va_end (ap);
01090
01091 return value;
01092 }
01093
01094 KvpValue *
01095 kvp_frame_get_slot_path_gslist (KvpFrame * frame, GSList * key_path)
01096 {
01097 if (!frame || !key_path)
01098 return NULL;
01099
01100 while (TRUE)
01101 {
01102 const gchar *key = key_path->data;
01103 KvpValue *value;
01104
01105 if (!key)
01106 return NULL;
01107
01108 value = kvp_frame_get_slot (frame, key);
01109 if (!value)
01110 return NULL;
01111
01112 key_path = key_path->next;
01113 if (!key_path)
01114 return value;
01115
01116 frame = kvp_value_get_frame (value);
01117 if (!frame)
01118 return NULL;
01119 }
01120 }
01121
01122
01123
01124
01125
01126 void
01127 kvp_glist_delete (GList * list)
01128 {
01129 GList *node;
01130 if (!list)
01131 return;
01132
01133
01134 for (node = list; node; node = node->next)
01135 {
01136 KvpValue *val = node->data;
01137 kvp_value_delete (val);
01138 }
01139
01140
01141 g_list_free (list);
01142 }
01143
01144 GList *
01145 kvp_glist_copy (const GList * list)
01146 {
01147 GList *retval = NULL;
01148 GList *lptr;
01149
01150 if (!list)
01151 return retval;
01152
01153
01154
01155 retval = g_list_copy ((GList *) list);
01156
01157
01158 for (lptr = retval; lptr; lptr = lptr->next)
01159 {
01160 lptr->data = kvp_value_copy (lptr->data);
01161 }
01162
01163 return retval;
01164 }
01165
01166 gint
01167 kvp_glist_compare (const GList * list1, const GList * list2)
01168 {
01169 const GList *lp1;
01170 const GList *lp2;
01171
01172 if (list1 == list2)
01173 return 0;
01174
01175
01176 if (!list1 && list2)
01177 return -1;
01178 if (list1 && !list2)
01179 return 1;
01180
01181 lp1 = list1;
01182 lp2 = list2;
01183 while (lp1 && lp2)
01184 {
01185 KvpValue *v1 = (KvpValue *) lp1->data;
01186 KvpValue *v2 = (KvpValue *) lp2->data;
01187 gint vcmp = kvp_value_compare (v1, v2);
01188 if (vcmp != 0)
01189 return vcmp;
01190 lp1 = lp1->next;
01191 lp2 = lp2->next;
01192 }
01193 if (!lp1 && lp2)
01194 return -1;
01195 if (!lp2 && lp1)
01196 return 1;
01197 return 0;
01198 }
01199
01200
01201
01202
01203
01204 KvpValue *
01205 kvp_value_new_gint64 (gint64 value)
01206 {
01207 KvpValue *retval = g_new0 (KvpValue, 1);
01208 retval->type = KVP_TYPE_GINT64;
01209 retval->value.int64 = value;
01210 return retval;
01211 }
01212
01213 KvpValue *
01214 kvp_value_new_double (gdouble value)
01215 {
01216 KvpValue *retval = g_new0 (KvpValue, 1);
01217 retval->type = KVP_TYPE_DOUBLE;
01218 retval->value.dbl = value;
01219 return retval;
01220 }
01221
01222 KvpValue *
01223 kvp_value_new_boolean (gboolean value)
01224 {
01225 KvpValue * retval = g_new0 (KvpValue, 1);
01226 retval->type = KVP_TYPE_BOOLEAN;
01227 retval->value.gbool = value;
01228 return retval;
01229 }
01230
01231 KvpValue *
01232 kvp_value_new_numeric (QofNumeric value)
01233 {
01234 KvpValue *retval = g_new0 (KvpValue, 1);
01235 retval->type = KVP_TYPE_NUMERIC;
01236 retval->value.numeric = value;
01237 return retval;
01238 }
01239
01240 KvpValue *
01241 kvp_value_new_string (const gchar *value)
01242 {
01243 KvpValue *retval;
01244 if (!value)
01245 return NULL;
01246
01247 retval = g_new0 (KvpValue, 1);
01248 retval->type = KVP_TYPE_STRING;
01249 retval->value.str = g_strdup (value);
01250 return retval;
01251 }
01252
01253 KvpValue *
01254 kvp_value_new_guid (const GUID * value)
01255 {
01256 KvpValue *retval;
01257 if (!value)
01258 return NULL;
01259
01260 retval = g_new0 (KvpValue, 1);
01261 retval->type = KVP_TYPE_GUID;
01262 retval->value.guid = g_new0 (GUID, 1);
01263 memcpy (retval->value.guid, value, sizeof (GUID));
01264 return retval;
01265 }
01266
01267 KvpValue *
01268 kvp_value_new_time (QofTime *value)
01269 {
01270 KvpValue *retval = g_new0 (KvpValue, 1);
01271 retval->type = KVP_TYPE_TIME;
01272 retval->value.qt = value;
01273 return retval;
01274 }
01275
01276 KvpValue *
01277 kvp_value_new_binary (gconstpointer value, guint64 datasize)
01278 {
01279 KvpValue *retval;
01280 if (!value)
01281 return NULL;
01282
01283 retval = g_new0 (KvpValue, 1);
01284 retval->type = KVP_TYPE_BINARY;
01285 retval->value.binary.data = g_new0 (gpointer, datasize);
01286 retval->value.binary.datasize = datasize;
01287 memcpy (retval->value.binary.data, value, datasize);
01288 return retval;
01289 }
01290
01291 KvpValue *
01292 kvp_value_new_binary_nc (gpointer value, guint64 datasize)
01293 {
01294 KvpValue *retval;
01295 if (!value)
01296 return NULL;
01297
01298 retval = g_new0 (KvpValue, 1);
01299 retval->type = KVP_TYPE_BINARY;
01300 retval->value.binary.data = value;
01301 retval->value.binary.datasize = datasize;
01302 return retval;
01303 }
01304
01305 KvpValue *
01306 kvp_value_new_glist (const GList * value)
01307 {
01308 KvpValue *retval;
01309 if (!value)
01310 return NULL;
01311
01312 retval = g_new0 (KvpValue, 1);
01313 retval->type = KVP_TYPE_GLIST;
01314 retval->value.list = kvp_glist_copy (value);
01315 return retval;
01316 }
01317
01318 KvpValue *
01319 kvp_value_new_glist_nc (GList * value)
01320 {
01321 KvpValue *retval;
01322 if (!value)
01323 return NULL;
01324
01325 retval = g_new0 (KvpValue, 1);
01326 retval->type = KVP_TYPE_GLIST;
01327 retval->value.list = value;
01328 return retval;
01329 }
01330
01331 KvpValue *
01332 kvp_value_new_frame (const KvpFrame * value)
01333 {
01334 KvpValue *retval;
01335 if (!value)
01336 return NULL;
01337
01338 retval = g_new0 (KvpValue, 1);
01339 retval->type = KVP_TYPE_FRAME;
01340 retval->value.frame = kvp_frame_copy (value);
01341 return retval;
01342 }
01343
01344 KvpValue *
01345 kvp_value_new_frame_nc (KvpFrame * value)
01346 {
01347 KvpValue *retval;
01348 if (!value)
01349 return NULL;
01350
01351 retval = g_new0 (KvpValue, 1);
01352 retval->type = KVP_TYPE_FRAME;
01353 retval->value.frame = value;
01354 return retval;
01355 }
01356
01357 void
01358 kvp_value_delete (KvpValue * value)
01359 {
01360 if (!value)
01361 return;
01362
01363 switch (value->type)
01364 {
01365 case KVP_TYPE_STRING:
01366 g_free (value->value.str);
01367 break;
01368 case KVP_TYPE_GUID:
01369 g_free (value->value.guid);
01370 break;
01371 case KVP_TYPE_BINARY:
01372 g_free (value->value.binary.data);
01373 break;
01374 case KVP_TYPE_GLIST:
01375 kvp_glist_delete (value->value.list);
01376 break;
01377 case KVP_TYPE_FRAME:
01378 kvp_frame_delete (value->value.frame);
01379 break;
01380 case KVP_TYPE_BOOLEAN:
01381 case KVP_TYPE_GINT64:
01382 case KVP_TYPE_DOUBLE:
01383 case KVP_TYPE_NUMERIC:
01384 default:
01385 break;
01386 }
01387 g_free (value);
01388 }
01389
01390 KvpValueType
01391 kvp_value_get_type (const KvpValue * value)
01392 {
01393 if (!value)
01394 return QOF_FATAL;
01395 return value->type;
01396 }
01397
01398 gint64
01399 kvp_value_get_gint64 (const KvpValue * value)
01400 {
01401 if (!value)
01402 return 0;
01403 if (value->type == KVP_TYPE_GINT64)
01404 return value->value.int64;
01405 else
01406 {
01407 PERR (" value type %d does not match KVP_TYPE_GINT64",
01408 value->type);
01409 return 0;
01410 }
01411 }
01412
01413 gdouble
01414 kvp_value_get_double (const KvpValue * value)
01415 {
01416 if (!value)
01417 return 0.0;
01418 if (value->type == KVP_TYPE_DOUBLE)
01419 return value->value.dbl;
01420 else
01421 {
01422 PERR (" value type %d does not match KVP_TYPE_DOUBLE",
01423 value->type);
01424 return 0.0;
01425 }
01426 }
01427
01428 QofNumeric
01429 kvp_value_get_numeric (const KvpValue * value)
01430 {
01431 if (!value)
01432 return qof_numeric_zero ();
01433 if (value->type == KVP_TYPE_NUMERIC)
01434 return value->value.numeric;
01435 else
01436 {
01437 PERR (" value type %d does not match KVP_TYPE_NUMERIC",
01438 value->type);
01439 return qof_numeric_zero ();
01440 }
01441 }
01442
01443 gchar *
01444 kvp_value_get_string (const KvpValue * value)
01445 {
01446 if (!value)
01447 return NULL;
01448 if (value->type == KVP_TYPE_STRING)
01449 return value->value.str;
01450 else
01451 {
01452 PERR (" value type %d does not match KVP_TYPE_STRING",
01453 value->type);
01454 return NULL;
01455 }
01456 }
01457
01458 gboolean
01459 kvp_value_get_boolean (const KvpValue * value)
01460 {
01461 if (!value)
01462 return FALSE;
01463 if (value->type == KVP_TYPE_BOOLEAN)
01464 return value->value.gbool;
01465 else
01466 {
01467 PERR (" value type %d does not match KVP_TYPE_BOOLEAN",
01468 value->type);
01469 return FALSE;
01470 }
01471 }
01472
01473 GUID *
01474 kvp_value_get_guid (const KvpValue * value)
01475 {
01476 if (!value)
01477 return NULL;
01478 if (value->type == KVP_TYPE_GUID)
01479 return value->value.guid;
01480 else
01481 {
01482 PERR (" value type %d does not match KVP_TYPE_GUID",
01483 value->type);
01484 return NULL;
01485 }
01486 }
01487
01488 QofTime*
01489 kvp_value_get_time (const KvpValue * value)
01490 {
01491 if (!value)
01492 return NULL;
01493 if (value->type == KVP_TYPE_TIME)
01494 return value->value.qt;
01495 else
01496 {
01497 PERR (" value type %d does not match KVP_TYPE_TIME",
01498 value->type);
01499 return NULL;
01500 }
01501 }
01502
01503 void *
01504 kvp_value_get_binary (const KvpValue * value, guint64 * size_return)
01505 {
01506 if (!value)
01507 {
01508 if (size_return)
01509 *size_return = 0;
01510 PERR (" no size specified");
01511 return NULL;
01512 }
01513
01514 if (value->type == KVP_TYPE_BINARY)
01515 {
01516 if (size_return)
01517 *size_return = value->value.binary.datasize;
01518 return value->value.binary.data;
01519 }
01520 else
01521 {
01522 if (size_return)
01523 *size_return = 0;
01524 PERR (" value type %d does not match KVP_TYPE_BINARY",
01525 value->type);
01526 return NULL;
01527 }
01528 }
01529
01530 GList *
01531 kvp_value_get_glist (const KvpValue * value)
01532 {
01533 if (!value)
01534 return NULL;
01535 if (value->type == KVP_TYPE_GLIST)
01536 return value->value.list;
01537 else
01538 {
01539 PERR (" value type %d does not match KVP_TYPE_GLIST",
01540 value->type);
01541 return NULL;
01542 }
01543 }
01544
01545 KvpFrame *
01546 kvp_value_get_frame (const KvpValue * value)
01547 {
01548 if (!value)
01549 return NULL;
01550 if (value->type == KVP_TYPE_FRAME)
01551 return value->value.frame;
01552 else
01553 {
01554 PERR (" value type %d does not match KVP_TYPE_FRAME",
01555 value->type);
01556 return NULL;
01557 }
01558 }
01559
01560 KvpFrame *
01561 kvp_value_replace_frame_nc (KvpValue * value, KvpFrame * newframe)
01562 {
01563 KvpFrame *oldframe;
01564 if (!value)
01565 return NULL;
01566 if (KVP_TYPE_FRAME != value->type)
01567 {
01568 PERR (" value type %d does not match KVP_TYPE_FRAME",
01569 value->type);
01570 return NULL;
01571 }
01572 oldframe = value->value.frame;
01573 value->value.frame = newframe;
01574 return oldframe;
01575 }
01576
01577 GList *
01578 kvp_value_replace_glist_nc (KvpValue * value, GList * newlist)
01579 {
01580 GList *oldlist;
01581 if (!value)
01582 return NULL;
01583 if (KVP_TYPE_GLIST != value->type)
01584 {
01585 PERR (" value type %d does not match KVP_TYPE_GLIST",
01586 value->type);
01587 return NULL;
01588 }
01589
01590 oldlist = value->value.list;
01591 value->value.list = newlist;
01592 return oldlist;
01593 }
01594
01595
01596
01597 KvpValue *
01598 kvp_value_copy (const KvpValue * value)
01599 {
01600 if (!value)
01601 return NULL;
01602
01603 switch (value->type)
01604 {
01605 case KVP_TYPE_GINT64:
01606 return kvp_value_new_gint64 (value->value.int64);
01607 break;
01608 case KVP_TYPE_DOUBLE:
01609 return kvp_value_new_double (value->value.dbl);
01610 break;
01611 case KVP_TYPE_NUMERIC:
01612 return kvp_value_new_numeric (value->value.numeric);
01613 break;
01614 case KVP_TYPE_STRING:
01615 return kvp_value_new_string (value->value.str);
01616 break;
01617 case KVP_TYPE_GUID:
01618 return kvp_value_new_guid (value->value.guid);
01619 break;
01620 case KVP_TYPE_BOOLEAN:
01621 return NULL;
01622 return kvp_value_new_boolean (value->value.gbool);
01623 break;
01624 case KVP_TYPE_TIME :
01625 return kvp_value_new_time (value->value.qt);
01626 break;
01627 case KVP_TYPE_BINARY:
01628 return kvp_value_new_binary (value->value.binary.data,
01629 value->value.binary.datasize);
01630 break;
01631 case KVP_TYPE_GLIST:
01632 return kvp_value_new_glist (value->value.list);
01633 break;
01634 case KVP_TYPE_FRAME:
01635 return kvp_value_new_frame (value->value.frame);
01636 break;
01637 }
01638 return NULL;
01639 }
01640
01641 void
01642 kvp_frame_for_each_slot (KvpFrame * f, KvpValueForeachCB proc, gpointer data)
01643 {
01644 if (!f)
01645 return;
01646 if (!proc)
01647 return;
01648 if (!(f->hash))
01649 return;
01650 g_hash_table_foreach (f->hash, (GHFunc) proc, data);
01651 }
01652
01653 gint
01654 kvp_value_compare (const KvpValue * kva, const KvpValue * kvb)
01655 {
01656 if (kva == kvb)
01657 return 0;
01658
01659 if (!kva && kvb)
01660 return -1;
01661 if (kva && !kvb)
01662 return 1;
01663
01664 if (kva->type < kvb->type)
01665 return -1;
01666 if (kva->type > kvb->type)
01667 return 1;
01668
01669 switch (kva->type)
01670 {
01671 case KVP_TYPE_GINT64:
01672 if (kva->value.int64 < kvb->value.int64)
01673 return -1;
01674 if (kva->value.int64 > kvb->value.int64)
01675 return 1;
01676 return 0;
01677 break;
01678 case KVP_TYPE_DOUBLE:
01679 return qof_util_double_compare (kva->value.dbl, kvb->value.dbl);
01680 break;
01681 case KVP_TYPE_NUMERIC:
01682 return qof_numeric_compare (kva->value.numeric,
01683 kvb->value.numeric);
01684 break;
01685 case KVP_TYPE_STRING:
01686 return strcmp (kva->value.str, kvb->value.str);
01687 break;
01688 case KVP_TYPE_GUID:
01689 return guid_compare (kva->value.guid, kvb->value.guid);
01690 break;
01691 case KVP_TYPE_BOOLEAN:
01692 {
01693
01694 if (kva->value.gbool != kvb->value.gbool)
01695 return (kva->value.gbool) ? 1 : -1;
01696 return 0;
01697 break;
01698 }
01699 case KVP_TYPE_TIME :
01700 return qof_time_cmp (kva->value.qt, kvb->value.qt);
01701 break;
01702 case KVP_TYPE_BINARY:
01703 if (kva->value.binary.datasize < kvb->value.binary.datasize)
01704 return -1;
01705 if (kva->value.binary.datasize > kvb->value.binary.datasize)
01706 return 1;
01707 return memcmp (kva->value.binary.data,
01708 kvb->value.binary.data, kva->value.binary.datasize);
01709 break;
01710 case KVP_TYPE_GLIST:
01711 return kvp_glist_compare (kva->value.list, kvb->value.list);
01712 break;
01713 case KVP_TYPE_FRAME:
01714 return kvp_frame_compare (kva->value.frame, kvb->value.frame);
01715 break;
01716 }
01717 return 0;
01718 }
01719
01720 typedef struct
01721 {
01722 gint compare;
01723 KvpFrame *other_frame;
01724 } KvpFrameCompare;
01725
01726 static void
01727 kvp_frame_compare_helper (const gchar *key, KvpValue * val, gpointer data)
01728 {
01729 KvpFrameCompare *status = (KvpFrameCompare *) data;
01730 if (status->compare == 0)
01731 {
01732 KvpFrame *other_frame = status->other_frame;
01733 KvpValue *other_val = kvp_frame_get_slot (other_frame, key);
01734
01735 if (other_val)
01736 status->compare = kvp_value_compare (val, other_val);
01737 else
01738 status->compare = 1;
01739 }
01740 }
01741
01742 gint
01743 kvp_frame_compare (const KvpFrame * fa, const KvpFrame * fb)
01744 {
01745 KvpFrameCompare status;
01746
01747 if (fa == fb)
01748 return 0;
01749
01750 if (!fa && fb)
01751 return -1;
01752 if (fa && !fb)
01753 return 1;
01754
01755
01756 if (!fa->hash && fb->hash)
01757 return -1;
01758 if (fa->hash && !fb->hash)
01759 return 1;
01760
01761 status.compare = 0;
01762 status.other_frame = (KvpFrame *) fb;
01763
01764 kvp_frame_for_each_slot ((KvpFrame *) fa, kvp_frame_compare_helper,
01765 &status);
01766
01767 if (status.compare != 0)
01768 return status.compare;
01769
01770 status.other_frame = (KvpFrame *) fa;
01771
01772 kvp_frame_for_each_slot ((KvpFrame *) fb, kvp_frame_compare_helper,
01773 &status);
01774
01775 return (-status.compare);
01776 }
01777
01778
01779 gchar *
01780 binary_to_string (gconstpointer data, guint32 size)
01781 {
01782 GString *output;
01783 guint32 i;
01784 guchar *data_str = (guchar *) data;
01785
01786 output = g_string_sized_new (size * sizeof (gchar));
01787
01788 for (i = 0; i < size; i++)
01789 {
01790 g_string_append_printf (output, "%02x",
01791 (guint32) (data_str[i]));
01792 }
01793
01794 return output->str;
01795 }
01796
01797 gchar *
01798 kvp_value_glist_to_string (const GList * list)
01799 {
01800 gchar *tmp1;
01801 gchar *tmp2;
01802 const GList *cursor;
01803
01804 tmp1 = g_strdup_printf ("[ ");
01805
01806 for (cursor = list; cursor; cursor = cursor->next)
01807 {
01808 gchar *tmp3;
01809
01810 tmp3 = kvp_value_to_string ((KvpValue *) cursor->data);
01811 tmp2 = g_strdup_printf ("%s %s,", tmp1, tmp3 ? tmp3 : "");
01812 g_free (tmp1);
01813 g_free (tmp3);
01814 tmp1 = tmp2;
01815 }
01816
01817 tmp2 = g_strdup_printf ("%s ]", tmp1);
01818 g_free (tmp1);
01819
01820 return tmp2;
01821 }
01822
01823 static void
01824 kvp_frame_to_bare_string_helper (gpointer key __attribute__ ((unused)),
01825 gpointer value, gpointer data)
01826 {
01827 gchar **str = (gchar **) data;
01828 *str =
01829 g_strdup_printf ("%s",
01830 kvp_value_to_bare_string ((KvpValue *) value));
01831 }
01832
01833 gchar *
01834 kvp_value_to_bare_string (const KvpValue * val)
01835 {
01836 gchar *tmp1;
01837 gchar *tmp2;
01838 const gchar *ctmp;
01839
01840 g_return_val_if_fail (val, NULL);
01841 tmp1 = g_strdup ("");
01842 switch (kvp_value_get_type (val))
01843 {
01844 case KVP_TYPE_GINT64:
01845 {
01846 return g_strdup_printf ("%" G_GINT64_FORMAT,
01847 kvp_value_get_gint64 (val));
01848 break;
01849 }
01850 case KVP_TYPE_DOUBLE:
01851 {
01852 return g_strdup_printf ("(%g)", kvp_value_get_double (val));
01853 break;
01854 }
01855 case KVP_TYPE_NUMERIC:
01856 {
01857 tmp1 = qof_numeric_to_string (kvp_value_get_numeric (val));
01858 tmp2 = g_strdup_printf ("%s", tmp1 ? tmp1 : "");
01859 g_free (tmp1);
01860 return tmp2;
01861 break;
01862 }
01863 case KVP_TYPE_STRING:
01864 {
01865 tmp1 = kvp_value_get_string (val);
01866 return g_strdup_printf ("%s", tmp1 ? tmp1 : "");
01867 break;
01868 }
01869 case KVP_TYPE_GUID:
01870 {
01871 ctmp = guid_to_string (kvp_value_get_guid (val));
01872 tmp2 = g_strdup_printf ("%s", ctmp ? ctmp : "");
01873 return tmp2;
01874 break;
01875 }
01876 case KVP_TYPE_BOOLEAN :
01877 return (kvp_value_get_boolean (val)) ? "TRUE" : "FALSE";
01878 case KVP_TYPE_BINARY:
01879 {
01880 guint64 len;
01881 gpointer data;
01882 data = kvp_value_get_binary (val, &len);
01883 tmp1 = binary_to_string (data, len);
01884 return g_strdup_printf ("%s", tmp1 ? tmp1 : "");
01885 break;
01886 }
01887 case KVP_TYPE_GLIST:
01888
01889 {
01890 tmp1 = kvp_value_glist_to_string (kvp_value_get_glist (val));
01891 tmp2 = g_strdup_printf ("%s", tmp1 ? tmp1 : "");
01892 g_free (tmp1);
01893 return tmp2;
01894 break;
01895 }
01896 case KVP_TYPE_FRAME:
01897 {
01898 KvpFrame *frame;
01899
01900 frame = kvp_value_get_frame (val);
01901 if (frame->hash)
01902 {
01903 tmp1 = g_strdup ("");
01904 g_hash_table_foreach (frame->hash,
01905 kvp_frame_to_bare_string_helper, &tmp1);
01906 }
01907 return tmp1;
01908 break;
01909 }
01910 default:
01911 return g_strdup_printf (" ");
01912 break;
01913 }
01914 }
01915
01916 gchar *
01917 kvp_value_to_string (const KvpValue * val)
01918 {
01919 gchar *tmp1;
01920 gchar *tmp2;
01921 const gchar *ctmp;
01922
01923 g_return_val_if_fail (val, NULL);
01924
01925 switch (kvp_value_get_type (val))
01926 {
01927 case KVP_TYPE_GINT64:
01928 {
01929 return g_strdup_printf ("KVP_VALUE_GINT64(%" G_GINT64_FORMAT ")",
01930 kvp_value_get_gint64 (val));
01931 break;
01932 }
01933 case KVP_TYPE_DOUBLE:
01934 {
01935 return g_strdup_printf ("KVP_VALUE_DOUBLE(%g)",
01936 kvp_value_get_double (val));
01937 break;
01938 }
01939 case KVP_TYPE_NUMERIC:
01940 {
01941 tmp1 = qof_numeric_to_string (kvp_value_get_numeric (val));
01942 tmp2 = g_strdup_printf ("KVP_VALUE_NUMERIC(%s)", tmp1 ? tmp1 : "");
01943 g_free (tmp1);
01944 return tmp2;
01945 break;
01946 }
01947 case KVP_TYPE_STRING:
01948 {
01949 tmp1 = kvp_value_get_string (val);
01950 return g_strdup_printf ("KVP_VALUE_STRING(%s)", tmp1 ? tmp1 : "");
01951 break;
01952 }
01953 case KVP_TYPE_GUID:
01954 {
01955
01956 ctmp = guid_to_string (kvp_value_get_guid (val));
01957 tmp2 = g_strdup_printf ("KVP_VALUE_GUID(%s)", ctmp ? ctmp : "");
01958 return tmp2;
01959 break;
01960 }
01961 case KVP_TYPE_BINARY:
01962 {
01963 guint64 len;
01964 gpointer data;
01965 data = kvp_value_get_binary (val, &len);
01966 tmp1 = binary_to_string (data, len);
01967 return g_strdup_printf ("KVP_VALUE_BINARY(%s)",
01968 tmp1 ? tmp1 : "");
01969 break;
01970 }
01971 case KVP_TYPE_GLIST:
01972 {
01973 tmp1 = kvp_value_glist_to_string (kvp_value_get_glist (val));
01974 tmp2 = g_strdup_printf ("KVP_VALUE_GLIST(%s)", tmp1 ? tmp1 : "");
01975 g_free (tmp1);
01976 return tmp2;
01977 break;
01978 }
01979 case KVP_TYPE_FRAME:
01980 {
01981 tmp1 = kvp_frame_to_string (kvp_value_get_frame (val));
01982 tmp2 = g_strdup_printf ("KVP_VALUE_FRAME(%s)", tmp1 ? tmp1 : "");
01983 g_free (tmp1);
01984 return tmp2;
01985 break;
01986 }
01987 default:
01988 return g_strdup_printf (" ");
01989 break;
01990 }
01991 }
01992
01993 static void
01994 kvp_frame_to_string_helper (gpointer key, gpointer value, gpointer data)
01995 {
01996 gchar *tmp_val;
01997 gchar **str = (gchar **) data;
01998 gchar *old_data = *str;
01999
02000 tmp_val = kvp_value_to_string ((KvpValue *) value);
02001
02002 *str = g_strdup_printf ("%s %s => %s,\n",
02003 *str ? *str : "", key ? (gchar *) key : "", tmp_val ? tmp_val : "");
02004
02005 g_free (old_data);
02006 g_free (tmp_val);
02007 }
02008
02009 gchar *
02010 kvp_frame_to_string (const KvpFrame * frame)
02011 {
02012 gchar *tmp1;
02013
02014 g_return_val_if_fail (frame != NULL, NULL);
02015
02016 tmp1 = g_strdup_printf ("{\n");
02017
02018 if (frame->hash)
02019 g_hash_table_foreach (frame->hash, kvp_frame_to_string_helper,
02020 &tmp1);
02021 {
02022 gchar *tmp2;
02023 tmp2 = g_strdup_printf ("%s}\n", tmp1);
02024 g_free (tmp1);
02025 tmp1 = tmp2;
02026 }
02027
02028 return tmp1;
02029 }
02030
02031 GHashTable *
02032 kvp_frame_get_hash (const KvpFrame * frame)
02033 {
02034 g_return_val_if_fail (frame != NULL, NULL);
02035 return frame->hash;
02036 }
02037
02038