diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am index ce85503782..ff749377ae 100644 --- a/src/engine/Makefile.am +++ b/src/engine/Makefile.am @@ -72,6 +72,7 @@ EXTRA_DIST = \ README.gnc-numeric \ design.txt \ extensions.txt \ + io-gncxml-version1.dtd \ kvp_doc.txt CFLAGS = @CFLAGS@ ${GLIB_CFLAGS} ${GNOME_XML_CFLAGS} diff --git a/src/engine/io-gncxml-r.c b/src/engine/io-gncxml-r.c index a10e19f99b..ee9a897a3a 100644 --- a/src/engine/io-gncxml-r.c +++ b/src/engine/io-gncxml-r.c @@ -1206,6 +1206,56 @@ double_kvp_value_parser_new() { return(simple_kvp_value_parser_new(double_kvp_value_end_handler)); } +/* - gnc_numeric kvp_value parser. + + input: NA + returns: numeric kvp_value + + start: NA + chars: generic_accumulate_chars. + end: convert chars to numeric kvp_value* if possible and return. + + cleanup-result: kvp_value_delete. + cleanup-chars: g_free (for chars) + fail: NA + result-fail: kvp_value_delete + chars-fail: g_free (for chars) + + */ + +static gboolean +numeric_kvp_value_end_handler(gpointer data_for_children, + GSList* data_from_children, + GSList* sibling_data, + gpointer parent_data, + gpointer global_data, + gpointer *result, + const gchar *tag) { + gchar *txt = NULL; + gnc_numeric val; + kvp_value *kvpv; + gboolean ok; + + txt = concatenate_child_result_chars(data_from_children); + if(!txt) return(FALSE); + + ok = string_to_gnc_numeric(txt, &val) != NULL; + g_free(txt); + + if(!ok) return(FALSE); + + kvpv = kvp_value_new_numeric(val); + if(!kvpv) return(FALSE); + + *result = kvpv; + return(TRUE); +} + +static sixtp* +numeric_kvp_value_parser_new() { + return(simple_kvp_value_parser_new(numeric_kvp_value_end_handler)); +} + /* - string kvp_value parser. input: NA @@ -1520,6 +1570,10 @@ add_all_kvp_value_parsers_as_sub_nodes(sixtp *p, if(!child_pr) return(FALSE); sixtp_add_sub_parser(p, "double", child_pr); + child_pr = numeric_kvp_value_parser_new(); + if(!child_pr) return(FALSE); + sixtp_add_sub_parser(p, "numeric", child_pr); + child_pr = string_kvp_value_parser_new(); if(!child_pr) return(FALSE); sixtp_add_sub_parser(p, "string", child_pr); diff --git a/src/engine/io-gncxml-w.c b/src/engine/io-gncxml-w.c index 9605a21425..f9980d24e0 100644 --- a/src/engine/io-gncxml-w.c +++ b/src/engine/io-gncxml-w.c @@ -447,6 +447,9 @@ xml_add_kvp_value(xmlNodePtr p, kvp_value *val) { case KVP_TYPE_DOUBLE: return(xml_add_double(p, "double", kvp_value_get_double(val))); break; + case KVP_TYPE_NUMERIC: + return(xml_add_gnc_numeric(p, "numeric", kvp_value_get_numeric(val))); + break; case KVP_TYPE_STRING: return(xml_add_str(p, "string", kvp_value_get_string(val), TRUE)); break; diff --git a/src/engine/kvp_frame.c b/src/engine/kvp_frame.c index 728d834769..8e6ec9946a 100644 --- a/src/engine/kvp_frame.c +++ b/src/engine/kvp_frame.c @@ -21,13 +21,17 @@ * * ********************************************************************/ -#include "kvp_frame.h" -#include "guid.h" -#include "gnc-engine.h" +#include "config.h" -#include -#include #include +#include +#include + +#include "gnc-engine.h" +#include "gnc-numeric.h" +#include "guid.h" +#include "kvp_frame.h" + /* Note that we keep the keys for this hash table in a GCache * (gnc_string_cache), as it is likely we will see the same keys @@ -47,6 +51,7 @@ struct _kvp_value { union { gint64 int64; double dbl; + gnc_numeric numeric; gchar *str; GUID *guid; kvp_value_binary_data binary; @@ -266,7 +271,15 @@ kvp_value_new_double(double value) { retval->type = KVP_TYPE_DOUBLE; retval->value.dbl = value; return retval; -} +} + +kvp_value * +kvp_value_new_numeric(gnc_numeric value) { + kvp_value * retval = g_new0(kvp_value, 1); + retval->type = KVP_TYPE_NUMERIC; + retval->value.numeric = value; + return retval; +} kvp_value * kvp_value_new_string(const char * value) { @@ -351,6 +364,7 @@ kvp_value_delete(kvp_value * value) { case KVP_TYPE_GINT64: case KVP_TYPE_DOUBLE: + case KVP_TYPE_NUMERIC: default: break; } @@ -382,6 +396,16 @@ kvp_value_get_double(const kvp_value * value) { } } +gnc_numeric +kvp_value_get_numeric(const kvp_value * value) { + if(value->type == KVP_TYPE_NUMERIC) { + return value->value.numeric; + } + else { + return gnc_numeric_zero (); + } +} + char * kvp_value_get_string(const kvp_value * value) { if(value->type == KVP_TYPE_STRING) { @@ -467,6 +491,9 @@ kvp_value_copy(const kvp_value * value) { case KVP_TYPE_DOUBLE: return kvp_value_new_double(value->value.dbl); break; + case KVP_TYPE_NUMERIC: + return kvp_value_new_numeric(value->value.numeric); + break; case KVP_TYPE_STRING: return kvp_value_new_string(value->value.str); break; @@ -515,9 +542,12 @@ kvp_value_compare(const kvp_value * kva, const kvp_value * kvb) { case KVP_TYPE_GINT64: case KVP_TYPE_DOUBLE: if(kva->value.int64 < kvb->value.int64) return -1; - if(kva->value.int64 > kvb->value.int64) return -1; + if(kva->value.int64 > kvb->value.int64) return 1; return 0; break; + case KVP_TYPE_NUMERIC: + return gnc_numeric_compare (kva->value.numeric, kvb->value.numeric); + break; case KVP_TYPE_STRING: return strcmp(kva->value.str, kvb->value.str); break; diff --git a/src/engine/kvp_frame.h b/src/engine/kvp_frame.h index 0d3344b847..1569a1bcb2 100644 --- a/src/engine/kvp_frame.h +++ b/src/engine/kvp_frame.h @@ -24,10 +24,12 @@ #ifndef __KVP_FRAME_H__ #define __KVP_FRAME_H__ -#include -#include #include +#include "gnc-numeric.h" +#include "guid.h" + + /* a kvp_frame is a set of associations between character strings * (keys) and kvp_value structures. A kvp_value is a union with * possible types enumerated in the kvp_value_t enum. @@ -42,6 +44,7 @@ typedef enum { KVP_TYPE_GINT64, KVP_TYPE_DOUBLE, + KVP_TYPE_NUMERIC, KVP_TYPE_STRING, KVP_TYPE_GUID, KVP_TYPE_BINARY, @@ -85,6 +88,7 @@ void kvp_glist_delete(GList * list); /* value constructors (copying for pointer args) */ kvp_value * kvp_value_new_gint64(gint64 value); kvp_value * kvp_value_new_double(double value); +kvp_value * kvp_value_new_numeric(gnc_numeric value); kvp_value * kvp_value_new_string(const char * value); kvp_value * kvp_value_new_guid(const GUID * guid); kvp_value * kvp_value_new_binary(const void * data, guint64 datasize); @@ -101,6 +105,7 @@ kvp_value_t kvp_value_get_type(const kvp_value * value); gint64 kvp_value_get_gint64(const kvp_value * value); double kvp_value_get_double(const kvp_value * value); +gnc_numeric kvp_value_get_numeric(const kvp_value * value); char * kvp_value_get_string(const kvp_value * value); GUID * kvp_value_get_guid(const kvp_value * value); void * kvp_value_get_binary(const kvp_value * value,