mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
James LewisMoss's big big patch.
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3678 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
eff510bd09
commit
5b7f9b4631
73
ChangeLog
73
ChangeLog
@ -1,3 +1,76 @@
|
||||
2001-02-22 James LewisMoss <jimdres@mindspring.com>
|
||||
|
||||
* src/test/test-dom-parser1.c: Move generic funcs to test-stuff.c
|
||||
|
||||
* src/test/test-dom-converters1.c: Move generic funcs to
|
||||
test-stuff.c
|
||||
|
||||
* src/test/test-date-converting.c: move generic funcs to
|
||||
test-stuff.c
|
||||
|
||||
* src/engine/sixtp-to-dom-parser.c (dom_start_handler): cast arg
|
||||
to xmlNewChild to xmlNodePtr
|
||||
(dom_chars_handler): Remove is_whitespace func and use isspace_str
|
||||
from other file.
|
||||
|
||||
* src/engine/sixtp-dom-parsers.c: Add all the dom_tree_to funcs.
|
||||
|
||||
* src/engine/sixtp-dom-generators.c (guid_to_dom_tree): Make GUID
|
||||
arg const.
|
||||
(commodity_ref_to_dom_tree): check nulls.
|
||||
(add_kvp_value_node): Add all the kvp code.
|
||||
|
||||
* src/engine/kvp_frame.c: Use string cache func.
|
||||
(charstar_va_list_to_gslist): new func.
|
||||
(kvp_frame_get_frame): More refactoring.
|
||||
|
||||
* src/engine/gnc-engine.h: Add func def as below.
|
||||
|
||||
* src/engine/gnc-engine.c: Move string cache creation to function
|
||||
to get so that you don't have to gnc_engine_init to use the global
|
||||
string cache.
|
||||
(gnc_engine_get_string_cache): Add func as above.
|
||||
|
||||
* src/engine/gnc-book.h: Add func as below.
|
||||
|
||||
* src/engine/gnc-book.c (gnc_book_get_commodity_table): Add
|
||||
function.
|
||||
|
||||
* src/engine/gnc-account-xml-v2.c (gnc_account_dom_tree_create):
|
||||
Complete func.
|
||||
(gnc_account_end_handler): Fix up. Finish work.
|
||||
|
||||
* src/engine/Transaction.c (xaccInitSplit): Use func to get string
|
||||
cache rather than accessing the var directly.
|
||||
|
||||
* src/engine/Account.h: same as Account.c. Add comment on
|
||||
xaccAccountSet{Currency,Security} that they take control of the
|
||||
gnc_commodity args.
|
||||
|
||||
* src/engine/Account.c: Rename xaccAccountSetSlots to *_nc so we
|
||||
use the kvp_frame provided rather than copy.
|
||||
|
||||
* src/doc/xml/types.dtd: Fix up kvp type list. clean up timestamp
|
||||
tuff. Simplify a bit.
|
||||
|
||||
* src/doc/xml/account-v2.dtd: add code and description.
|
||||
|
||||
2001-02-19 James LewisMoss <jimdres@mindspring.com>
|
||||
|
||||
* src/engine/kvp_frame.c: Fix < to be > in binary datasize
|
||||
argument (bug fix). Add comment about appropriateness of
|
||||
comparing data sizes first.
|
||||
Fix double compare. was using just gint64 compare. Extracted out
|
||||
double compare into double_compare function.
|
||||
Fix return value of kvp_value_compare from gboolean -> gint.
|
||||
Fix bug in kvp_glist_compare where it should have read (!lp2 &&
|
||||
lp1) and it read (!lp2) so glists never compared equal.
|
||||
(kvp_frame_get_hash): Add func.
|
||||
(kvp_frame_to_string): Add func.
|
||||
(kvp_value_to_string): Add func.
|
||||
(kvp_value_glist_to_string): Add func.
|
||||
(binary_to_string): Add func.
|
||||
|
||||
2001-02-15 Bill Gribble <grib@billgribble.com>
|
||||
|
||||
* src/scm/qif-import/qif-guess-map.scm: add stock hash
|
||||
|
@ -2,6 +2,7 @@
|
||||
%types;
|
||||
|
||||
<!ELEMENT gnc:account (act:name, act:id, act:type, act:currency,
|
||||
act:code?, act:description?,
|
||||
act:security?, act:slots?, act:parent?)>
|
||||
<!ATTLIST gnc:account version CDATA #REQUIRED>
|
||||
|
||||
|
@ -7,20 +7,23 @@
|
||||
|
||||
<!ENTITY % commodity-type "(cmdty:space, cmdty:id)">
|
||||
|
||||
<!-- need to replace the etc here -->
|
||||
<!ENTITY % slot-types "(string | integer | double | etc)">
|
||||
|
||||
<!ELEMENT slot (key, value)>
|
||||
|
||||
<!ELEMENT slot:key (#PCDATA)>
|
||||
|
||||
<!ELEMENT slot:value (#PCDATA)>
|
||||
|
||||
<!ATTLIST slot:value type %slot-types; "string">
|
||||
|
||||
<!ENTITY % slot-type "(slot+)">
|
||||
<!ENTITY % slot-types "(integer | double | numeric | string | guid | binary | glist | frame)">
|
||||
|
||||
<!ELEMENT ts:date (#PCDATA)>
|
||||
<!ELEMENT ts:ns (#PCDATA)>
|
||||
|
||||
<!ENTITY % date-type "(ts:date, ts:ns?)">
|
||||
|
||||
<!-- this stuff isn't quite right -->
|
||||
<!ELEMENT slot (slot:key, slot:value)>
|
||||
|
||||
<!ELEMENT slot:key (#PCDATA)>
|
||||
|
||||
<!ENTITY % slot-val-type "(slot+?, slot:value+?, #PCDATA?)">
|
||||
|
||||
<!ELEMENT slot:value %slot-val-type;>
|
||||
|
||||
<!ATTLIST slot:value type %slot-types; "string">
|
||||
|
||||
<!ENTITY % slot-type "(slot+)">
|
||||
|
||||
|
@ -460,7 +460,7 @@ xaccAccountGetSlots(Account * account) {
|
||||
}
|
||||
|
||||
void
|
||||
xaccAccountSetSlots(Account *account, kvp_frame *frame)
|
||||
xaccAccountSetSlots_nc(Account *account, kvp_frame *frame)
|
||||
{
|
||||
if (!account) return;
|
||||
if (frame == account->kvp_data) return;
|
||||
|
@ -134,7 +134,7 @@ void xaccAccountCommitEdit (Account *account);
|
||||
void xaccAccountDestroy (Account *account);
|
||||
|
||||
kvp_frame * xaccAccountGetSlots (Account *account);
|
||||
void xaccAccountSetSlots(Account *account, kvp_frame *frame);
|
||||
void xaccAccountSetSlots_nc(Account *account, kvp_frame *frame);
|
||||
|
||||
/*
|
||||
* The xaccAccountGetGUID() subroutine will return the
|
||||
@ -218,6 +218,7 @@ void xaccAccountSetCommodity (Account *account, const gnc_commodity *comm);
|
||||
* The future API will associate only one thing with an account:
|
||||
* the 'commodity'. Use xaccAccountGetCommodity() to fetch it.
|
||||
*/
|
||||
/* these two funcs take control of thier gnc_commodity args. Don't free */
|
||||
void xaccAccountSetCurrency (Account *account, const gnc_commodity *currency);
|
||||
void xaccAccountSetSecurity (Account *account, const gnc_commodity *security);
|
||||
void xaccAccountSetCurrencySCU (Account *account, int frac);
|
||||
|
@ -21,6 +21,7 @@ libgncengine_la_SOURCES = \
|
||||
date.c \
|
||||
GNCId.c \
|
||||
gnc-account-xml-v2.c \
|
||||
gnc-commodity-xml-v2.c \
|
||||
guid.c \
|
||||
io-gncbin-r.c \
|
||||
io-gncxml-r.c \
|
||||
@ -83,6 +84,7 @@ noinst_HEADERS = \
|
||||
gnc-event-p.h \
|
||||
gnc-numeric.h \
|
||||
gnc-xml-helper.h \
|
||||
gnc-xml.h \
|
||||
sixtp-dom-generators.h \
|
||||
sixtp-dom-parsers.h \
|
||||
sixtp-parsers.h \
|
||||
|
@ -94,8 +94,8 @@ xaccInitSplit(Split * split)
|
||||
split->acc = NULL;
|
||||
split->parent = NULL;
|
||||
|
||||
split->action = g_cache_insert(gnc_string_cache, "");
|
||||
split->memo = g_cache_insert(gnc_string_cache, "");
|
||||
split->action = g_cache_insert(gnc_engine_get_string_cache(), "");
|
||||
split->memo = g_cache_insert(gnc_engine_get_string_cache(), "");
|
||||
split->reconciled = NREC;
|
||||
split->damount = gnc_numeric_zero();
|
||||
split->value = gnc_numeric_zero();
|
||||
@ -147,8 +147,8 @@ xaccCloneSplit (Split *s)
|
||||
split->acc = s->acc;
|
||||
split->parent = s->parent;
|
||||
|
||||
split->memo = g_cache_insert (gnc_string_cache, s->memo);
|
||||
split->action = g_cache_insert (gnc_string_cache, s->action);
|
||||
split->memo = g_cache_insert (gnc_engine_get_string_cache(), s->memo);
|
||||
split->action = g_cache_insert (gnc_engine_get_string_cache(), s->action);
|
||||
|
||||
split->kvp_data = kvp_frame_copy (s->kvp_data);
|
||||
|
||||
@ -180,8 +180,8 @@ xaccFreeSplit (Split *split)
|
||||
|
||||
kvp_frame_delete (split->kvp_data);
|
||||
|
||||
g_cache_remove(gnc_string_cache, split->memo);
|
||||
g_cache_remove(gnc_string_cache, split->action);
|
||||
g_cache_remove(gnc_engine_get_string_cache(), split->memo);
|
||||
g_cache_remove(gnc_engine_get_string_cache(), split->action);
|
||||
|
||||
/* just in case someone looks up freed memory ... */
|
||||
split->memo = NULL;
|
||||
@ -571,8 +571,8 @@ static void
|
||||
xaccInitTransaction (Transaction * trans)
|
||||
{
|
||||
/* Fill in some sane defaults */
|
||||
trans->num = g_cache_insert(gnc_string_cache, "");
|
||||
trans->description = g_cache_insert(gnc_string_cache, "");
|
||||
trans->num = g_cache_insert(gnc_engine_get_string_cache(), "");
|
||||
trans->description = g_cache_insert(gnc_engine_get_string_cache(), "");
|
||||
|
||||
trans->common_currency = NULL;
|
||||
trans->splits = NULL;
|
||||
@ -626,8 +626,8 @@ xaccCloneTransaction (Transaction *t)
|
||||
|
||||
trans = g_new0 (Transaction, 1);
|
||||
|
||||
trans->num = g_cache_insert (gnc_string_cache, t->num);
|
||||
trans->description = g_cache_insert (gnc_string_cache, t->description);
|
||||
trans->num = g_cache_insert (gnc_engine_get_string_cache(), t->num);
|
||||
trans->description = g_cache_insert (gnc_engine_get_string_cache(), t->description);
|
||||
|
||||
trans->kvp_data = kvp_frame_copy (t->kvp_data);
|
||||
|
||||
@ -673,8 +673,8 @@ xaccFreeTransaction (Transaction *trans)
|
||||
trans->splits = NULL;
|
||||
|
||||
/* free up transaction strings */
|
||||
g_cache_remove(gnc_string_cache, trans->num);
|
||||
g_cache_remove(gnc_string_cache, trans->description);
|
||||
g_cache_remove(gnc_engine_get_string_cache(), trans->num);
|
||||
g_cache_remove(gnc_engine_get_string_cache(), trans->description);
|
||||
|
||||
kvp_frame_delete (trans->kvp_data);
|
||||
|
||||
@ -1411,13 +1411,13 @@ xaccTransRollbackEdit (Transaction *trans)
|
||||
* the guid would have been unlisted. Restore that */
|
||||
xaccStoreEntity(trans, &trans->guid, GNC_ID_TRANS);
|
||||
|
||||
g_cache_remove (gnc_string_cache, trans->num);
|
||||
g_cache_remove (gnc_engine_get_string_cache(), trans->num);
|
||||
trans->num = orig->num;
|
||||
orig->num = g_cache_insert(gnc_string_cache, "");
|
||||
orig->num = g_cache_insert(gnc_engine_get_string_cache(), "");
|
||||
|
||||
g_cache_remove (gnc_string_cache, trans->description);
|
||||
g_cache_remove (gnc_engine_get_string_cache(), trans->description);
|
||||
trans->description = orig->description;
|
||||
orig->description = g_cache_insert(gnc_string_cache, "");
|
||||
orig->description = g_cache_insert(gnc_engine_get_string_cache(), "");
|
||||
|
||||
kvp_frame_delete (trans->kvp_data);
|
||||
trans->kvp_data = orig->kvp_data;
|
||||
@ -1466,13 +1466,13 @@ xaccTransRollbackEdit (Transaction *trans)
|
||||
break;
|
||||
}
|
||||
|
||||
g_cache_remove (gnc_string_cache, s->action);
|
||||
g_cache_remove (gnc_engine_get_string_cache(), s->action);
|
||||
s->action = so->action;
|
||||
so->action = g_cache_insert(gnc_string_cache, "");
|
||||
so->action = g_cache_insert(gnc_engine_get_string_cache(), "");
|
||||
|
||||
g_cache_remove (gnc_string_cache, s->memo);
|
||||
g_cache_remove (gnc_engine_get_string_cache(), s->memo);
|
||||
s->memo = so->memo;
|
||||
so->memo = g_cache_insert(gnc_string_cache, "");
|
||||
so->memo = g_cache_insert(gnc_engine_get_string_cache(), "");
|
||||
|
||||
kvp_frame_delete (s->kvp_data);
|
||||
s->kvp_data = so->kvp_data;
|
||||
@ -1907,8 +1907,8 @@ xaccTransSetNum (Transaction *trans, const char *xnum)
|
||||
if (!trans || !xnum) return;
|
||||
check_open (trans);
|
||||
|
||||
tmp = g_cache_insert(gnc_string_cache, (gpointer) xnum);
|
||||
g_cache_remove(gnc_string_cache, trans->num);
|
||||
tmp = g_cache_insert(gnc_engine_get_string_cache(), (gpointer) xnum);
|
||||
g_cache_remove(gnc_engine_get_string_cache(), trans->num);
|
||||
trans->num = tmp;
|
||||
mark_trans (trans);
|
||||
}
|
||||
@ -1920,8 +1920,8 @@ xaccTransSetDescription (Transaction *trans, const char *desc)
|
||||
if (!trans || !desc) return;
|
||||
check_open (trans);
|
||||
|
||||
tmp = g_cache_insert(gnc_string_cache, (gpointer) desc);
|
||||
g_cache_remove(gnc_string_cache, trans->description);
|
||||
tmp = g_cache_insert(gnc_engine_get_string_cache(), (gpointer) desc);
|
||||
g_cache_remove(gnc_engine_get_string_cache(), trans->description);
|
||||
trans->description = tmp;
|
||||
mark_trans (trans);
|
||||
}
|
||||
@ -2048,8 +2048,8 @@ xaccSplitSetMemo (Split *split, const char *memo)
|
||||
if (!split || !memo) return;
|
||||
check_open (split->parent);
|
||||
|
||||
tmp = g_cache_insert(gnc_string_cache, (gpointer) memo);
|
||||
g_cache_remove(gnc_string_cache, split->memo);
|
||||
tmp = g_cache_insert(gnc_engine_get_string_cache(), (gpointer) memo);
|
||||
g_cache_remove(gnc_engine_get_string_cache(), split->memo);
|
||||
split->memo = tmp;
|
||||
mark_split (split);
|
||||
}
|
||||
@ -2061,8 +2061,8 @@ xaccSplitSetAction (Split *split, const char *actn)
|
||||
if (!split || !actn) return;
|
||||
check_open (split->parent);
|
||||
|
||||
tmp = g_cache_insert(gnc_string_cache, (gpointer) actn);
|
||||
g_cache_remove(gnc_string_cache, split->action);
|
||||
tmp = g_cache_insert(gnc_engine_get_string_cache(), (gpointer) actn);
|
||||
g_cache_remove(gnc_engine_get_string_cache(), split->action);
|
||||
split->action = tmp;
|
||||
mark_split (split);
|
||||
}
|
||||
|
@ -9,16 +9,67 @@
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-parsers.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-dom-parsers.h"
|
||||
#include "sixtp-dom-generators.h"
|
||||
|
||||
#include "gnc-xml.h"
|
||||
|
||||
#include "sixtp-dom-parsers.h"
|
||||
#include "AccountP.h"
|
||||
#include "Account.h"
|
||||
#include "Group.h"
|
||||
|
||||
const gchar *account_version_string = "2.0.0";
|
||||
|
||||
xmlNodePtr
|
||||
gnc_account_dom_tree_create(Account *act)
|
||||
{
|
||||
return NULL;
|
||||
xmlNodePtr ret;
|
||||
|
||||
ret = xmlNewNode(NULL, "gnc:account");
|
||||
xmlSetProp(ret, "version", account_version_string);
|
||||
|
||||
xmlNewChild(ret, NULL, "act:name", xaccAccountGetName(act));
|
||||
|
||||
xmlAddChild(ret, guid_to_dom_tree("act:id", xaccAccountGetGUID(act)));
|
||||
|
||||
xmlNewChild(ret, NULL, "act:type",
|
||||
xaccAccountTypeEnumAsString(xaccAccountGetType(act)));
|
||||
|
||||
xmlAddChild(ret, commodity_ref_to_dom_tree("act:currency",
|
||||
xaccAccountGetCurrency(act)));
|
||||
|
||||
if(xaccAccountGetCode(act))
|
||||
{
|
||||
xmlNewChild(ret, NULL, "act:code", xaccAccountGetCode(act));
|
||||
}
|
||||
|
||||
if(xaccAccountGetDescription(act))
|
||||
{
|
||||
xmlNewChild(ret, NULL, "act:description",
|
||||
xaccAccountGetDescription(act));
|
||||
}
|
||||
|
||||
if(xaccAccountGetSecurity(act))
|
||||
{
|
||||
xmlAddChild(ret, commodity_ref_to_dom_tree("act:security",
|
||||
xaccAccountGetSecurity(act)));
|
||||
}
|
||||
|
||||
if(xaccAccountGetSlots(act))
|
||||
{
|
||||
xmlAddChild(ret, kvp_frame_to_dom_tree("act:slots",
|
||||
xaccAccountGetSlots(act)));
|
||||
}
|
||||
|
||||
if(xaccAccountGetParentAccount(act))
|
||||
{
|
||||
xmlAddChild(ret, guid_to_dom_tree(
|
||||
"act:parent",
|
||||
xaccAccountGetGUID(xaccAccountGetParentAccount(act))));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
@ -80,6 +131,7 @@ static gboolean
|
||||
account_slots_handler (xmlNodePtr node, Account* act)
|
||||
{
|
||||
/* return dom_tree_handle_kvp(act->kvp_data, node); */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -178,16 +230,19 @@ gnc_account_end_handler(gpointer data_for_children,
|
||||
xmlNodePtr tree = (xmlNodePtr)data_for_children;
|
||||
|
||||
successful = TRUE;
|
||||
|
||||
if(parent_data)
|
||||
{
|
||||
return successful;
|
||||
}
|
||||
|
||||
acc = xaccMallocAccount();
|
||||
g_return_val_if_fail(acc, FALSE);
|
||||
xaccAccountBeginEdit(acc);
|
||||
|
||||
achild = tree->xmlChildrenNode;
|
||||
|
||||
set_handlers(account_handlers_v2);
|
||||
|
||||
while(!achild)
|
||||
for(achild = tree->xmlChildrenNode; achild; achild = achild->next)
|
||||
{
|
||||
if(!gnc_xml_set_account_data(achild->name, achild, acc,
|
||||
account_handlers_v2))
|
||||
@ -195,7 +250,6 @@ gnc_account_end_handler(gpointer data_for_children,
|
||||
successful = FALSE;
|
||||
break;
|
||||
}
|
||||
achild = achild->next;
|
||||
}
|
||||
|
||||
xaccAccountCommitEdit(acc);
|
||||
@ -214,17 +268,17 @@ gnc_account_end_handler(gpointer data_for_children,
|
||||
if(!xaccAccountGetParent(acc))
|
||||
{
|
||||
/* FIXME: something like this */
|
||||
/* xaccGroupInsertAccount(global_data->accountgroup, acc); */
|
||||
/* xaccGroupInsertAccount(global_data, acc); */
|
||||
}
|
||||
}
|
||||
|
||||
xmlFreeNode(data_for_children);
|
||||
xmlFreeNode(result);
|
||||
|
||||
return successful;
|
||||
}
|
||||
|
||||
sixtp*
|
||||
gnc_account_sixtp_parser_create()
|
||||
gnc_account_sixtp_parser_create(void)
|
||||
{
|
||||
return sixtp_dom_parser_new(gnc_account_end_handler);
|
||||
}
|
||||
|
@ -146,6 +146,12 @@ gnc_book_new (void)
|
||||
|
||||
/* ============================================================== */
|
||||
|
||||
gnc_commodity_table*
|
||||
gnc_book_get_commodity_table(GNCBook *book)
|
||||
{
|
||||
return gnc_engine_commodities();
|
||||
}
|
||||
|
||||
AccountGroup *
|
||||
gnc_book_get_group (GNCBook *book)
|
||||
{
|
||||
|
@ -124,6 +124,14 @@ GNCBackendError gnc_book_pop_error (GNCBook *book);
|
||||
AccountGroup * gnc_book_get_group (GNCBook *book);
|
||||
void gnc_book_set_group (GNCBook *book, AccountGroup *topgroup);
|
||||
|
||||
|
||||
/*
|
||||
* gnc_book_get_commodity_table returns the commodity table associated with
|
||||
* the BOOK. At the moment this just returns the global commodity table,
|
||||
* but if we get everything using this we can make it a non-global table :)
|
||||
*/
|
||||
gnc_commodity_table* gnc_book_get_commodity_table(GNCBook *book);
|
||||
|
||||
/* The gnc_book_get_file_path() routine returns the fully-qualified file
|
||||
* path for the book. That is, if a relative or partial filename
|
||||
* was for the book, then it had to have been fully resolved to
|
||||
|
142
src/engine/gnc-commodity-xml-v2.c
Normal file
142
src/engine/gnc-commodity-xml-v2.c
Normal file
@ -0,0 +1,142 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gnc-xml-helper.h"
|
||||
|
||||
#include "sixtp.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-parsers.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-dom-parsers.h"
|
||||
#include "sixtp-dom-generators.h"
|
||||
|
||||
#include "gnc-xml.h"
|
||||
|
||||
#include "sixtp-dom-parsers.h"
|
||||
#include "AccountP.h"
|
||||
#include "Account.h"
|
||||
#include "Group.h"
|
||||
|
||||
const gchar *commodity_version_string = "2.0.0";
|
||||
|
||||
xmlNodePtr
|
||||
gnc_commodity_dom_tree_create(const gnc_commodity *com)
|
||||
{
|
||||
xmlNodePtr ret;
|
||||
|
||||
ret = xmlNewNode(NULL, "gnc:commodity");
|
||||
|
||||
xmlSetProp(ret, "version", commodity_version_string);
|
||||
|
||||
xmlNewChild(ret, NULL, "cmdty:space", gnc_commodity_get_namespace(com));
|
||||
xmlNewChild(ret, NULL, "cmdty:id", gnc_commodity_get_mnemonic(com));
|
||||
|
||||
if(gnc_commodity_get_fullname(com))
|
||||
{
|
||||
xmlNewChild(ret, NULL, "cmdty:name", gnc_commodity_get_fullname(com));
|
||||
}
|
||||
|
||||
if(gnc_commodity_get_exchange_code(com))
|
||||
{
|
||||
xmlNewChild(ret, NULL, "cmdty:xcode",
|
||||
gnc_commodity_get_exchange_code(com));
|
||||
}
|
||||
|
||||
{
|
||||
gchar *text;
|
||||
text = g_strdup_printf("%d", gnc_commodity_get_fraction(com));
|
||||
xmlNewChild(ret, NULL, "cmdty:fraction", text);
|
||||
g_free(text);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
struct com_char_handler
|
||||
{
|
||||
gchar *tag;
|
||||
void(*func)(gnc_commodity *com, const char*val);
|
||||
};
|
||||
|
||||
struct com_char_handlers com_handlers[] = {
|
||||
{ "cmdty:space", gnc_commodity_set_namespace },
|
||||
{ "cmdty:id", gnc_commodity_set_mnemonic },
|
||||
{ "cmdty:name", gnc_commodity_set_fullname },
|
||||
{ "cmdty:xcode", gnc_commodity_set_exchange_code },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static void
|
||||
set_commodity_value(xmlNodePtr node, gnc_commodity* com)
|
||||
{
|
||||
if(safe_strcmp(node->name, "cmdty:fraction"))
|
||||
{
|
||||
gint64 val;
|
||||
if(string_to_integer(node, &val))
|
||||
{
|
||||
gnc_commodity_set_fraction(com, val);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
struct com_char_handlers *mark;
|
||||
|
||||
for(mark = com_handlers; mark->tag; mark++)
|
||||
{
|
||||
if(safe_strcmp(mark->tag, node->name))
|
||||
{
|
||||
gchar* val = dom_tree_to_text(node->xmlChildrenNode);
|
||||
(mark->func)(com, val);
|
||||
g_free(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
valid_commodity(gnc_commodity *com)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gnc_commodity_end_handler(gpointer data_for_children,
|
||||
GSList* data_from_children, GSList* sibling_data,
|
||||
gpointer parent_data, gpointer global_data,
|
||||
gpointer *result, const gchar *tag)
|
||||
{
|
||||
gnc_commodity *com;
|
||||
xmlNodePtr achild;
|
||||
xmlNodePtr tree = (xmlNodePtr)data_for_children;
|
||||
|
||||
if(parent_data)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
com = gnc_commodity_new(NULL, NULL, NULL, NULL, 0);
|
||||
|
||||
for(achild = tree->xmlChildrenNode; achild; achild = achild->next)
|
||||
{
|
||||
set_commodity_value(achild, com);
|
||||
}
|
||||
|
||||
if(!valid_commodity(com))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE
|
||||
}
|
||||
|
||||
|
||||
sixtp*
|
||||
gnc_commodity_sixtp_parser_create(void)
|
||||
{
|
||||
return sixtp_dom_parser_new(gnc_commodity_end_handler);
|
||||
}
|
@ -47,10 +47,8 @@ gnc_engine_init(int argc, char ** argv) {
|
||||
engine_is_initialized = 1;
|
||||
|
||||
/* initialize the string cache */
|
||||
gnc_string_cache = g_cache_new( (GCacheNewFunc) g_strdup,
|
||||
g_free, (GCacheDupFunc) g_strdup, g_free, g_str_hash,
|
||||
g_str_hash, g_str_equal);
|
||||
|
||||
gnc_engine_get_string_cache();
|
||||
|
||||
xaccGUIDInit ();
|
||||
|
||||
/* initialize the commodity table (it starts empty) */
|
||||
@ -65,6 +63,19 @@ gnc_engine_init(int argc, char ** argv) {
|
||||
}
|
||||
}
|
||||
|
||||
GCache*
|
||||
gnc_engine_get_string_cache(void)
|
||||
{
|
||||
if(!gnc_string_cache)
|
||||
{
|
||||
gnc_string_cache = g_cache_new(
|
||||
(GCacheNewFunc) g_strdup, g_free,
|
||||
(GCacheDupFunc) g_strdup, g_free, g_str_hash,
|
||||
g_str_hash, g_str_equal);
|
||||
}
|
||||
return gnc_string_cache;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* gnc_engine_shutdown
|
||||
* shutdown backend, destroy any global data, etc.
|
||||
|
@ -61,7 +61,9 @@ gnc_commodity_table * gnc_engine_commodities(void);
|
||||
* Note that all the work is done when inserting or removing. Once
|
||||
* cached the strings are just plain C strings.
|
||||
*/
|
||||
extern GCache *gnc_string_cache;
|
||||
|
||||
/* get the gnc_string_cache. Create it if it doesn't exist already */
|
||||
GCache* gnc_engine_get_string_cache(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
75
src/engine/gnc-transaction-xml-v2.c
Normal file
75
src/engine/gnc-transaction-xml-v2.c
Normal file
@ -0,0 +1,75 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gnc-xml-helper.h"
|
||||
|
||||
#include "sixtp.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-parsers.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-dom-parsers.h"
|
||||
#include "sixtp-dom-generators.h"
|
||||
|
||||
#include "gnc-xml.h"
|
||||
|
||||
#include "sixtp-dom-parsers.h"
|
||||
#include "AccountP.h"
|
||||
#include "Account.h"
|
||||
#include "Group.h"
|
||||
|
||||
const gchar *transaction_version_string = "2.0.0";
|
||||
|
||||
xmlNodePtr
|
||||
gnc_transaction_dom_tree_create(const Transaction *com)
|
||||
{
|
||||
xmlNodePtr ret;
|
||||
|
||||
ret = xmlNewNode(NULL, "gnc:transaction");
|
||||
|
||||
xmlSetProp(ret, "version", transaction_version_string);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
|
||||
static gboolean
|
||||
valid_transaction(const Transaction *com)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gnc_transaction_end_handler(gpointer data_for_children,
|
||||
GSList* data_from_children, GSList* sibling_data,
|
||||
gpointer parent_data, gpointer global_data,
|
||||
gpointer *result, const gchar *tag)
|
||||
{
|
||||
Transaction *com;
|
||||
xmlNodePtr achild;
|
||||
xmlNodePtr tree = (xmlNodePtr)data_for_children;
|
||||
|
||||
if(parent_data)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
if(!valid_transaction(com))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE
|
||||
}
|
||||
|
||||
|
||||
sixtp*
|
||||
gnc_transaction_sixtp_parser_create(void)
|
||||
{
|
||||
return sixtp_dom_parser_new(gnc_transaction_end_handler);
|
||||
}
|
25
src/engine/gnc-xml.h
Normal file
25
src/engine/gnc-xml.h
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
#ifndef __GNC_XML_H__
|
||||
#define __GNC_XML_H__
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gnc-xml-helper.h"
|
||||
|
||||
#include "Account.h"
|
||||
#include "gnc-commodity.h"
|
||||
|
||||
#include "sixtp.h"
|
||||
|
||||
|
||||
xmlNodePtr gnc_account_dom_tree_create(Account *act);
|
||||
sixtp* gnc_account_sixtp_parser_create(void);
|
||||
|
||||
xmlNodePtr gnc_commodity_dom_tree_create(const gnc_commodity *act);
|
||||
sixtp* gnc_commodity_sixtp_parser_create(void);
|
||||
|
||||
xmlNodePtr gnc_transaction_dom_tree_create(const Transaction *com);
|
||||
sixtp* gnc_transaction_sixtp_parser_create(void);
|
||||
|
||||
|
||||
#endif /* __GNC_XML_H__ */
|
@ -27,6 +27,7 @@
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "gnc-engine.h"
|
||||
#include "gnc-numeric.h"
|
||||
@ -94,7 +95,7 @@ kvp_frame_new(void) {
|
||||
|
||||
static void
|
||||
kvp_frame_delete_worker(gpointer key, gpointer value, gpointer user_data) {
|
||||
g_cache_remove(gnc_string_cache, key);
|
||||
g_cache_remove(gnc_engine_get_string_cache(), key);
|
||||
kvp_value_delete((kvp_value *)value);
|
||||
}
|
||||
|
||||
@ -120,7 +121,7 @@ kvp_frame_copy_worker(gpointer key, gpointer value, gpointer user_data) {
|
||||
kvp_frame * dest = (kvp_frame *)user_data;
|
||||
g_hash_table_freeze(dest->hash);
|
||||
g_hash_table_insert(dest->hash,
|
||||
(gpointer)g_cache_insert(gnc_string_cache, key),
|
||||
(gpointer)g_cache_insert(gnc_engine_get_string_cache(), key),
|
||||
(gpointer)kvp_value_copy(value));
|
||||
g_hash_table_thaw(dest->hash);
|
||||
}
|
||||
@ -159,13 +160,14 @@ kvp_frame_set_slot_destructively(kvp_frame * frame, const char * slot,
|
||||
& orig_key, & orig_value);
|
||||
if(key_exists) {
|
||||
g_hash_table_remove(frame->hash, slot);
|
||||
g_cache_remove(gnc_string_cache, orig_key);
|
||||
g_cache_remove(gnc_engine_get_string_cache(), orig_key);
|
||||
kvp_value_delete(orig_value);
|
||||
}
|
||||
|
||||
if(new_value) {
|
||||
g_hash_table_insert(frame->hash,
|
||||
g_cache_insert(gnc_string_cache, (gpointer) slot),
|
||||
g_cache_insert(gnc_engine_get_string_cache(),
|
||||
(gpointer) slot),
|
||||
new_value);
|
||||
}
|
||||
|
||||
@ -331,34 +333,45 @@ kvp_frame_get_frame_gslist (kvp_frame *frame, GSList *key_path)
|
||||
}
|
||||
}
|
||||
|
||||
static GSList*
|
||||
charstar_va_list_to_gslist(va_list lst)
|
||||
{
|
||||
const char *val;
|
||||
GSList *ret = NULL;
|
||||
|
||||
while(TRUE)
|
||||
{
|
||||
val = va_arg(lst, const char*);
|
||||
|
||||
if(!val)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ret = g_slist_append(ret, (gpointer)val);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
kvp_frame *
|
||||
kvp_frame_get_frame (kvp_frame *frame, const char *first_key, ...)
|
||||
kvp_frame_get_frame (kvp_frame *frame, ...)
|
||||
{
|
||||
va_list ap;
|
||||
const char *key;
|
||||
GSList *lst;
|
||||
kvp_frame *ret;
|
||||
|
||||
if (!frame || !first_key)
|
||||
return frame;
|
||||
if (!frame)
|
||||
return NULL;
|
||||
|
||||
va_start (ap, first_key);
|
||||
va_start (ap, frame);
|
||||
|
||||
key = first_key;
|
||||
lst = charstar_va_list_to_gslist(ap);
|
||||
|
||||
ret = kvp_frame_get_frame_gslist(frame, lst);
|
||||
|
||||
lst = NULL;
|
||||
|
||||
while (TRUE) {
|
||||
lst = g_slist_append(lst, (gpointer) key);
|
||||
|
||||
key = va_arg (ap, const char *);
|
||||
if (!key) {
|
||||
break; /* the normal exit to this routine. */
|
||||
}
|
||||
}
|
||||
va_end (ap);
|
||||
|
||||
ret = kvp_frame_get_frame_gslist(frame, lst);
|
||||
g_slist_free(lst);
|
||||
|
||||
return ret;
|
||||
@ -548,7 +561,7 @@ kvp_glist_compare(const GList * list1, const GList * list2) {
|
||||
lp2 = lp2->next;
|
||||
}
|
||||
if(!lp1 && lp2) return -1;
|
||||
if(!lp2) return 1;
|
||||
if(!lp2 && lp1) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -759,25 +772,6 @@ kvp_value_get_frame(const kvp_value * value) {
|
||||
|
||||
/* manipulators */
|
||||
|
||||
#if 0
|
||||
/* untested - didn't end up needing it... */
|
||||
|
||||
gboolean
|
||||
kvp_value_binary_append(kvp_value *kv, void *data, guint64 size) {
|
||||
void *new_data;
|
||||
guint64 new_size;
|
||||
|
||||
if(kv->type != KVP_TYPE_BINARY) return(FALSE);
|
||||
new_size = kv->value.binary.datasize + size;
|
||||
new_data = g_realloc(kv->value.binary.data, new_size);
|
||||
if(!new_data) return(FALSE);
|
||||
memcpy(kv->value.binary.data + kv->value.binary.datasize, data, size);
|
||||
kv->value.binary.datasize = new_size;
|
||||
return(TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
kvp_value *
|
||||
kvp_value_copy(const kvp_value * value) {
|
||||
|
||||
@ -827,7 +821,18 @@ kvp_frame_for_each_slot(kvp_frame *f,
|
||||
g_hash_table_foreach(f->hash, (GHFunc) proc, data);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gint
|
||||
double_compare(double d1, double d2)
|
||||
{
|
||||
if(isnan(d1) && isnan(d2)) return 0;
|
||||
if((isinf(d1) == 1) && (isinf(d2) == 1)) return 0;
|
||||
if((isinf(d1) == -1) && (isinf(d2) == -1)) return 0;
|
||||
if(d1 < d2) return -1;
|
||||
if(d1 > d2) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
gint
|
||||
kvp_value_compare(const kvp_value * kva, const kvp_value * kvb) {
|
||||
if(kva == kvb) return 0;
|
||||
/* nothing is always less than something */
|
||||
@ -839,11 +844,13 @@ kvp_value_compare(const kvp_value * kva, const kvp_value * kvb) {
|
||||
|
||||
switch(kva->type) {
|
||||
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;
|
||||
return 0;
|
||||
break;
|
||||
case KVP_TYPE_DOUBLE:
|
||||
return double_compare(kva->value.dbl, kvb->value.dbl);
|
||||
break;
|
||||
case KVP_TYPE_NUMERIC:
|
||||
return gnc_numeric_compare (kva->value.numeric, kvb->value.numeric);
|
||||
break;
|
||||
@ -854,8 +861,10 @@ kvp_value_compare(const kvp_value * kva, const kvp_value * kvb) {
|
||||
return guid_compare(kva->value.guid, kvb->value.guid);
|
||||
break;
|
||||
case KVP_TYPE_BINARY:
|
||||
/* I don't know that this is a good compare. Ab is bigger than Acef.
|
||||
But I'm not sure that actually matters here. */
|
||||
if(kva->value.binary.datasize < kvb->value.binary.datasize) return -1;
|
||||
if(kva->value.binary.datasize < kvb->value.binary.datasize) return 1;
|
||||
if(kva->value.binary.datasize > kvb->value.binary.datasize) return 1;
|
||||
return memcmp(kva->value.binary.data,
|
||||
kvb->value.binary.data,
|
||||
kva->value.binary.datasize);
|
||||
@ -911,3 +920,155 @@ kvp_frame_compare(const kvp_frame *fa, const kvp_frame *fb) {
|
||||
|
||||
return(status.compare);
|
||||
}
|
||||
|
||||
gchar*
|
||||
binary_to_string(const void *data, guint32 size)
|
||||
{
|
||||
GString *output;
|
||||
guint32 i;
|
||||
guchar *data_str = (guchar*)data;
|
||||
|
||||
output = g_string_sized_new(size * sizeof(char));
|
||||
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
g_string_sprintfa(output, "%02x", (unsigned int) (data_str[i]));
|
||||
}
|
||||
|
||||
return output->str;
|
||||
}
|
||||
|
||||
gchar*
|
||||
kvp_value_glist_to_string(const GList *list)
|
||||
{
|
||||
gchar *tmp1;
|
||||
gchar *tmp2;
|
||||
const GList *cursor;
|
||||
|
||||
tmp1 = g_strdup_printf("[ ");
|
||||
|
||||
for(cursor = list; cursor; cursor = cursor->next)
|
||||
{
|
||||
gchar *tmp3;
|
||||
|
||||
tmp3 = kvp_value_to_string((kvp_value*)cursor->data);
|
||||
tmp2 = g_strdup_printf("%s %s,", tmp1, tmp3);
|
||||
g_free(tmp1);
|
||||
g_free(tmp3);
|
||||
tmp1 = tmp2;
|
||||
}
|
||||
|
||||
tmp2 = g_strdup_printf("%s ]", tmp1);
|
||||
g_free(tmp1);
|
||||
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
gchar*
|
||||
kvp_value_to_string(const kvp_value *val)
|
||||
{
|
||||
gchar *tmp1;
|
||||
gchar *tmp2;
|
||||
|
||||
g_return_val_if_fail(val, NULL);
|
||||
|
||||
switch(kvp_value_get_type(val))
|
||||
{
|
||||
case KVP_TYPE_GINT64:
|
||||
return g_strdup_printf("KVP_VALUE_GINT64(%lld)",
|
||||
kvp_value_get_gint64(val));
|
||||
break;
|
||||
|
||||
case KVP_TYPE_DOUBLE:
|
||||
return g_strdup_printf("KVP_VALUE_DOUBLE(%g)",
|
||||
kvp_value_get_double(val));
|
||||
break;
|
||||
|
||||
case KVP_TYPE_NUMERIC:
|
||||
tmp1 = gnc_numeric_to_string(kvp_value_get_numeric(val));
|
||||
tmp2 = g_strdup_printf("KVP_VALUE_NUMERIC(%s)", tmp1);
|
||||
g_free(tmp1);
|
||||
return tmp2;
|
||||
break;
|
||||
|
||||
case KVP_TYPE_STRING:
|
||||
return g_strdup_printf("KVP_VALUE_STRING(%s)",
|
||||
kvp_value_get_string(val));
|
||||
break;
|
||||
|
||||
case KVP_TYPE_GUID:
|
||||
tmp1 = guid_to_string(kvp_value_get_guid(val));
|
||||
tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", tmp1);
|
||||
g_free(tmp1);
|
||||
return tmp2;
|
||||
break;
|
||||
|
||||
case KVP_TYPE_BINARY:
|
||||
{
|
||||
guint64 len;
|
||||
void *data;
|
||||
data = kvp_value_get_binary(val, &len);
|
||||
tmp1 = binary_to_string(data, len);
|
||||
return g_strdup_printf("KVP_VALUE_BINARY(%s)", tmp1);
|
||||
}
|
||||
break;
|
||||
|
||||
case KVP_TYPE_GLIST:
|
||||
tmp1 = kvp_value_glist_to_string(kvp_value_get_glist(val));
|
||||
tmp2 = g_strdup_printf("KVP_VALUE_GLIST(%s)", tmp1);
|
||||
g_free(tmp1);
|
||||
return tmp2;
|
||||
break;
|
||||
|
||||
case KVP_TYPE_FRAME:
|
||||
tmp1 = kvp_frame_to_string(kvp_value_get_frame(val));
|
||||
tmp2 = g_strdup_printf("KVP_VALUE_FRAME(%s)", tmp1);
|
||||
g_free(tmp1);
|
||||
return tmp2;
|
||||
break;
|
||||
|
||||
default:
|
||||
return g_strdup_printf(" ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
kvp_frame_to_string_helper(gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
gchar *tmp_val;
|
||||
gchar **str = (gchar**)data;
|
||||
gchar *old_data = *str;
|
||||
|
||||
tmp_val = kvp_value_to_string((kvp_value*)value);
|
||||
|
||||
*str = g_strdup_printf("%s %s => %s,\n", *str, (gchar*)key, tmp_val);
|
||||
|
||||
g_free(old_data);
|
||||
g_free(tmp_val);
|
||||
}
|
||||
|
||||
gchar*
|
||||
kvp_frame_to_string(const kvp_frame *frame)
|
||||
{
|
||||
gchar *tmp1;
|
||||
|
||||
tmp1 = g_strdup_printf("{\n");
|
||||
|
||||
g_hash_table_foreach(frame->hash, kvp_frame_to_string_helper, &tmp1);
|
||||
|
||||
{
|
||||
gchar *tmp2;
|
||||
tmp2 = g_strdup_printf("%s}\n", tmp1);
|
||||
g_free(tmp1);
|
||||
tmp1 = tmp2;
|
||||
}
|
||||
|
||||
return tmp1;
|
||||
}
|
||||
|
||||
GHashTable*
|
||||
kvp_frame_get_hash(const kvp_frame *frame)
|
||||
{
|
||||
return frame->hash;
|
||||
}
|
||||
|
@ -62,11 +62,20 @@ kvp_frame * kvp_frame_new(void);
|
||||
void kvp_frame_delete(kvp_frame * frame);
|
||||
kvp_frame * kvp_frame_copy(const kvp_frame * frame);
|
||||
|
||||
gchar* kvp_frame_to_string(const kvp_frame *frame);
|
||||
gchar* binary_to_string(const void *data, guint32 size);
|
||||
gchar* kvp_value_glist_to_string(const GList *list);
|
||||
|
||||
GHashTable* kvp_frame_get_hash(const kvp_frame *frame);
|
||||
|
||||
/* The kvp_frame_set_slot() routine copies the value into the frame,
|
||||
* associating it with 'key'.
|
||||
* The kvp_frame_set_slot_nc() routine puts the value (without copying
|
||||
* it) into the frame, associating it with 'key'. This routine is
|
||||
* handy for avoiding excess memory allocations & frees.
|
||||
* Pointers passed as arguments into set_slot and get_slot are the
|
||||
* responsibility of the caller. Pointers returned by get_slot are
|
||||
* owned by the kvp_frame. Make copies as needed.
|
||||
*/
|
||||
void kvp_frame_set_slot(kvp_frame * frame,
|
||||
const char * key, const kvp_value * value);
|
||||
@ -99,8 +108,7 @@ void kvp_frame_set_slot_path_gslist (kvp_frame *frame,
|
||||
*
|
||||
*
|
||||
*/
|
||||
kvp_frame * kvp_frame_get_frame (kvp_frame *frame,
|
||||
const char *first_key, ...);
|
||||
kvp_frame * kvp_frame_get_frame (kvp_frame *frame, ...);
|
||||
|
||||
kvp_frame * kvp_frame_get_frame_gslist (kvp_frame *frame,
|
||||
GSList *key_path);
|
||||
@ -118,6 +126,7 @@ kvp_value * kvp_frame_get_slot_path_gslist (kvp_frame *frame,
|
||||
GSList *key_path);
|
||||
|
||||
gint kvp_frame_compare(const kvp_frame *fa, const kvp_frame *fb);
|
||||
gint double_compare(double v1, double v2);
|
||||
|
||||
void kvp_value_delete(kvp_value * value);
|
||||
kvp_value * kvp_value_copy(const kvp_value * value);
|
||||
@ -161,6 +170,8 @@ void * kvp_value_get_binary(const kvp_value * value,
|
||||
GList * kvp_value_get_glist(const kvp_value * value);
|
||||
kvp_frame * kvp_value_get_frame(const kvp_value * value);
|
||||
|
||||
gchar* kvp_value_to_string(const kvp_value *val);
|
||||
|
||||
/* manipulators */
|
||||
|
||||
gboolean kvp_value_binary_append(kvp_value *v, void *data, guint64 size);
|
||||
@ -178,4 +189,5 @@ void kvp_frame_for_each_slot(kvp_frame *f,
|
||||
gpointer data),
|
||||
gpointer data);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "kvp_frame.h"
|
||||
|
||||
xmlNodePtr
|
||||
guid_to_dom_tree(const char *tag, GUID* gid)
|
||||
guid_to_dom_tree(const char *tag, const GUID* gid)
|
||||
{
|
||||
char *guid_str;
|
||||
xmlNodePtr ret;
|
||||
@ -43,6 +43,11 @@ commodity_ref_to_dom_tree(const char *tag, const gnc_commodity *c)
|
||||
|
||||
ret = xmlNewNode(NULL, tag);
|
||||
|
||||
if(!gnc_commodity_get_namespace(c) || !gnc_commodity_get_mnemonic(c))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xmlNewTextChild(ret, NULL, "cmdty:space", gnc_commodity_get_namespace(c));
|
||||
xmlNewTextChild(ret, NULL, "cmdty:id", gnc_commodity_get_mnemonic(c));
|
||||
|
||||
@ -144,7 +149,135 @@ gnc_numeric_to_dom_tree(const char *tag, const gnc_numeric *num)
|
||||
return ret;
|
||||
}
|
||||
|
||||
gchar*
|
||||
double_to_string(double value)
|
||||
{
|
||||
gchar *numstr;
|
||||
#ifdef USE_GUILE_FOR_DOUBLE_CONVERSION
|
||||
numstr = gh_scm2newstr(gh_call1(gh_eval_str("number->string"),
|
||||
gh_double2scm(value)),
|
||||
NULL);
|
||||
|
||||
#else /* don't USE_GUILE_FOR_DOUBLE_CONVERSION */
|
||||
/*
|
||||
* we're just going to use plain-old libc for the double conversion.
|
||||
* There was some question as to whether libc is accurate enough
|
||||
* in its printf function for doubles, but I don't understand
|
||||
* how it couldn't be ...
|
||||
*/
|
||||
numstr = g_strdup_printf ("%24.18g", value);
|
||||
|
||||
#endif /* USE_GUILE_FOR_DOUBLE_CONVERSION */
|
||||
if(!numstr)
|
||||
{
|
||||
return NULL;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return g_strstrip(numstr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_text_to_node(xmlNodePtr node, gchar *type, gchar *val)
|
||||
{
|
||||
xmlSetProp(node, "type", type);
|
||||
xmlNodeSetContent(node, val);
|
||||
g_free(val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
add_kvp_slot(gpointer key, gpointer value, gpointer data);
|
||||
|
||||
static void
|
||||
add_kvp_value_node(xmlNodePtr node, gchar *tag, kvp_value* val)
|
||||
{
|
||||
xmlNodePtr val_node;
|
||||
gchar *tmp_str1;
|
||||
|
||||
val_node = xmlNewChild(node, NULL, tag, NULL);
|
||||
|
||||
switch(kvp_value_get_type(val))
|
||||
{
|
||||
case KVP_TYPE_GINT64:
|
||||
add_text_to_node(val_node, "integer",
|
||||
g_strdup_printf("%lld", kvp_value_get_gint64(val)));
|
||||
break;
|
||||
case KVP_TYPE_DOUBLE:
|
||||
add_text_to_node(val_node,"double",
|
||||
double_to_string(kvp_value_get_double(val)));
|
||||
break;
|
||||
case KVP_TYPE_NUMERIC:
|
||||
add_text_to_node(val_node,"numeric",
|
||||
gnc_numeric_to_string(kvp_value_get_numeric(val)));
|
||||
break;
|
||||
case KVP_TYPE_STRING:
|
||||
xmlSetProp(val_node, "type", "string");
|
||||
xmlNodeSetContent(val_node, kvp_value_get_string(val));
|
||||
break;
|
||||
case KVP_TYPE_GUID:
|
||||
add_text_to_node(val_node,"guid",
|
||||
guid_to_string(kvp_value_get_guid(val)));
|
||||
break;
|
||||
case KVP_TYPE_BINARY:
|
||||
{
|
||||
guint64 size;
|
||||
void *binary_data = kvp_value_get_binary(val, &size);
|
||||
xmlSetProp(val_node, "type", "binary");
|
||||
g_return_if_fail(binary_data);
|
||||
tmp_str1 = binary_to_string(binary_data, size);
|
||||
xmlNodeSetContent(val_node, tmp_str1);
|
||||
g_free(tmp_str1);
|
||||
}
|
||||
break;
|
||||
case KVP_TYPE_GLIST:
|
||||
{
|
||||
GList *cursor;
|
||||
|
||||
xmlSetProp(val_node, "type", "list");
|
||||
for(cursor = kvp_value_get_glist(val); cursor; cursor = cursor->next)
|
||||
{
|
||||
kvp_value *val = (kvp_value*)cursor->data;
|
||||
add_kvp_value_node(val_node, "slot:value", val);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case KVP_TYPE_FRAME:
|
||||
xmlSetProp(val_node, "type", "frame");
|
||||
g_hash_table_foreach(kvp_frame_get_hash(kvp_value_get_frame(val)),
|
||||
add_kvp_slot, val_node);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_kvp_slot(gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
xmlNodePtr slot_node;
|
||||
xmlNodePtr node = (xmlNodePtr)data;
|
||||
|
||||
slot_node = xmlNewChild(node, NULL, "slot", NULL);
|
||||
|
||||
xmlNewTextChild(slot_node, NULL, "slot:key", (gchar*)key);
|
||||
|
||||
add_kvp_value_node(slot_node, "slot:value", (kvp_value*)value);
|
||||
}
|
||||
|
||||
xmlNodePtr
|
||||
kvp_frame_to_dom_tree(const char *tag, const kvp_frame *frame)
|
||||
{
|
||||
xmlNodePtr ret;
|
||||
|
||||
ret = xmlNewNode(NULL, tag);
|
||||
|
||||
g_hash_table_foreach(kvp_frame_get_hash(frame), add_kvp_slot, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -12,12 +12,16 @@
|
||||
#include "gnc-commodity.h"
|
||||
#include "date.h"
|
||||
#include "gnc-numeric.h"
|
||||
#include "kvp_frame.h"
|
||||
|
||||
xmlNodePtr guid_to_dom_tree(const char *tag, GUID* gid);
|
||||
xmlNodePtr guid_to_dom_tree(const char *tag, const GUID* gid);
|
||||
xmlNodePtr commodity_ref_to_dom_tree(const char *tag, const gnc_commodity *c);
|
||||
xmlNodePtr timespec_to_dom_tree(const char *tag, const Timespec *spec);
|
||||
gchar * timespec_nsec_to_string(const Timespec *ts);
|
||||
gchar * timespec_sec_to_string(const Timespec *ts);
|
||||
xmlNodePtr gnc_numeric_to_dom_tree(const char *tag, const gnc_numeric *num);
|
||||
xmlNodePtr kvp_frame_to_dom_tree(const char *tag, const kvp_frame *frame);
|
||||
|
||||
gchar* double_to_string(double value);
|
||||
|
||||
#endif /* _SIXTP_DOM_GENERATORS_H_ */
|
||||
|
@ -51,11 +51,317 @@ dom_tree_to_guid(xmlNodePtr node)
|
||||
}
|
||||
}
|
||||
|
||||
kvp_frame*
|
||||
dom_tree_handle_kvp(xmlNodePtr node)
|
||||
kvp_value*
|
||||
dom_tree_to_integer_kvp_value(xmlNodePtr node)
|
||||
{
|
||||
gchar *text;
|
||||
gint64 daint;
|
||||
kvp_value* ret = NULL;
|
||||
|
||||
text = dom_tree_to_text(node->xmlChildrenNode);
|
||||
|
||||
return FALSE;
|
||||
if(string_to_gint64(text, &daint))
|
||||
{
|
||||
ret = kvp_value_new_gint64(daint);
|
||||
}
|
||||
g_free(text);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
dom_tree_to_integer(xmlNodePtr node, gint64 *daint)
|
||||
{
|
||||
gchar *text;
|
||||
|
||||
text = dom_tree_to_text(node->xmlChildrenNode);
|
||||
|
||||
if(string_to_gint64(text, daint))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
kvp_value*
|
||||
dom_tree_to_double_kvp_value(xmlNodePtr node)
|
||||
{
|
||||
gchar *text;
|
||||
double dadoub;
|
||||
kvp_value *ret = NULL;
|
||||
|
||||
text = dom_tree_to_text(node->xmlChildrenNode);
|
||||
|
||||
if(string_to_double(text, &dadoub))
|
||||
{
|
||||
ret = kvp_value_new_double(dadoub);
|
||||
}
|
||||
|
||||
g_free(text);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
kvp_value*
|
||||
dom_tree_to_numeric_kvp_value(xmlNodePtr node)
|
||||
{
|
||||
gnc_numeric *danum;
|
||||
kvp_value *ret = NULL;
|
||||
|
||||
danum = dom_tree_to_gnc_numeric(node);
|
||||
|
||||
if(danum)
|
||||
{
|
||||
ret = kvp_value_new_gnc_numeric(*danum);
|
||||
}
|
||||
|
||||
g_free(danum);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
kvp_value*
|
||||
dom_tree_to_string_kvp_value(xmlNodePtr node)
|
||||
{
|
||||
gchar *datext;
|
||||
kvp_value *ret = NULL;
|
||||
|
||||
datext = dom_tree_to_text(node->xmlChildrenNode);
|
||||
if(datext)
|
||||
{
|
||||
ret = kvp_value_new_string(datext);
|
||||
}
|
||||
|
||||
g_free(datext);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
kvp_value*
|
||||
dom_tree_to_guid_kvp_value(xmlNodePtr node)
|
||||
{
|
||||
GUID *daguid;
|
||||
kvp_value *ret = NULL;
|
||||
|
||||
daguid = dom_tree_to_guid(node);
|
||||
if(daguid)
|
||||
{
|
||||
ret = kvp_value_new_guid(daguid);
|
||||
}
|
||||
|
||||
g_free(daguid);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
string_to_binary(const gchar *str, void **v, guint64 *data_len)
|
||||
{
|
||||
guint64 str_len;
|
||||
guchar *data;
|
||||
int i, j;
|
||||
|
||||
str_len = strlen(str);
|
||||
|
||||
/* Since no whitespace is allowed and hex encoding is 2 text chars
|
||||
per binary char, the result must be half the input size and the
|
||||
input size must be even. */
|
||||
if((str_len % 2) != 0)
|
||||
return(FALSE);
|
||||
*data_len = str_len / 2;
|
||||
data = g_new0(guchar, *data_len);
|
||||
|
||||
g_return_val_if_fail(*v, FALSE);
|
||||
|
||||
for(j = 0, i = 0; i < str_len; i += 2, j++)
|
||||
{
|
||||
gchar tmpstr[3];
|
||||
long int converted;
|
||||
|
||||
tmpstr[0] = str[i];
|
||||
tmpstr[1] = str[i + 1];
|
||||
tmpstr[2] = '\0';
|
||||
|
||||
converted = strtol(tmpstr, NULL, 16);
|
||||
|
||||
data[j] = (unsigned char)converted;
|
||||
}
|
||||
|
||||
*v = data;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
kvp_value*
|
||||
dom_tree_to_binary_kvp_value(xmlNodePtr node)
|
||||
{
|
||||
gchar *text;
|
||||
void *val;
|
||||
guint64 len;
|
||||
kvp_value *ret = NULL;
|
||||
|
||||
text = dom_tree_to_text(node->xmlChildrenNode);
|
||||
|
||||
if(string_to_binary(text, &val, &len))
|
||||
{
|
||||
ret = kvp_value_new_binary_nc(val, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning("string_to_binary returned false");
|
||||
}
|
||||
|
||||
g_free(text);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
kvp_value*
|
||||
dom_tree_to_list_kvp_value(xmlNodePtr node)
|
||||
{
|
||||
GList *list = NULL;
|
||||
xmlNodePtr mark;
|
||||
kvp_value *ret = NULL;
|
||||
|
||||
for(mark = node->xmlChildrenNode; mark; mark = mark->next)
|
||||
{
|
||||
kvp_value *new_val;
|
||||
new_val = dom_tree_to_kvp_value(mark);
|
||||
if(new_val)
|
||||
{
|
||||
list = g_list_append(list, (gpointer)new_val);
|
||||
}
|
||||
}
|
||||
|
||||
if(list)
|
||||
{
|
||||
ret = kvp_value_new_glist_nc(list);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
kvp_value*
|
||||
dom_tree_to_frame_kvp_value(xmlNodePtr node)
|
||||
{
|
||||
kvp_frame *frame;
|
||||
kvp_value *ret = NULL;
|
||||
|
||||
frame = dom_tree_to_kvp_frame(node);
|
||||
|
||||
if(frame)
|
||||
{
|
||||
ret = kvp_value_new_frame(frame);
|
||||
}
|
||||
|
||||
kvp_frame_delete(frame);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
struct kvp_val_converter
|
||||
{
|
||||
gchar *tag;
|
||||
kvp_value* (*converter)(xmlNodePtr node);
|
||||
};
|
||||
|
||||
struct kvp_val_converter val_converters[] = {
|
||||
{ "integer", dom_tree_to_integer_kvp_value },
|
||||
{ "double", dom_tree_to_double_kvp_value },
|
||||
{ "numeric", dom_tree_to_numeric_kvp_value },
|
||||
{ "string", dom_tree_to_string_kvp_value },
|
||||
{ "guid", dom_tree_to_guid_kvp_value },
|
||||
{ "binary", dom_tree_to_binary_kvp_value },
|
||||
{ "list", dom_tree_to_list_kvp_value },
|
||||
{ "frame", dom_tree_to_frame_kvp_value },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
kvp_value*
|
||||
dom_tree_to_kvp_value(xmlNodePtr node)
|
||||
{
|
||||
gchar *type;
|
||||
struct kvp_val_converter *mark;
|
||||
kvp_value *ret = NULL;
|
||||
|
||||
type = xmlGetProp(node, "type");
|
||||
if(!type)
|
||||
{
|
||||
type = g_strdup_printf("string");
|
||||
}
|
||||
|
||||
for(mark = val_converters; mark->tag; mark++)
|
||||
{
|
||||
if(safe_strcmp(type, mark->tag) == 0)
|
||||
{
|
||||
ret = (mark->converter)(node);
|
||||
}
|
||||
}
|
||||
|
||||
if(!mark->tag)
|
||||
{
|
||||
/* FIXME: deal with unknown type tag here */
|
||||
}
|
||||
|
||||
g_free(type);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
kvp_frame*
|
||||
dom_tree_to_kvp_frame(xmlNodePtr node)
|
||||
{
|
||||
kvp_frame *ret;
|
||||
xmlNodePtr mark;
|
||||
|
||||
g_return_val_if_fail(node, NULL);
|
||||
|
||||
ret = kvp_frame_new();
|
||||
|
||||
for(mark = node->xmlChildrenNode; mark; mark = mark->next)
|
||||
{
|
||||
if(safe_strcmp(mark->name, "slot") == 0)
|
||||
{
|
||||
xmlNodePtr mark2;
|
||||
gchar *key = NULL;
|
||||
kvp_value *val = NULL;
|
||||
|
||||
for(mark2 = mark->xmlChildrenNode; mark2; mark2 = mark2->next)
|
||||
{
|
||||
if(safe_strcmp(mark2->name, "slot:key") == 0)
|
||||
{
|
||||
key = dom_tree_to_text(mark2->xmlChildrenNode);
|
||||
}
|
||||
else if(safe_strcmp(mark2->name, "slot:value") == 0)
|
||||
{
|
||||
val = dom_tree_to_kvp_value(mark2);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: should put some error here */
|
||||
}
|
||||
}
|
||||
|
||||
if(key)
|
||||
{
|
||||
if(val)
|
||||
{
|
||||
kvp_frame_set_slot_nc(ret, key, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: should put some error here */
|
||||
}
|
||||
g_free(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -302,5 +608,5 @@ associate_commodity_ref_with_engine_commodity(gnc_commodity *com)
|
||||
{
|
||||
return gnc_commodity_table_lookup(gnc_engine_commodities(),
|
||||
gnc_commodity_get_namespace(com),
|
||||
gnc_commodity_get_exchange_code(com));
|
||||
gnc_commodity_get_mnemonic(com));
|
||||
}
|
||||
|
@ -24,7 +24,20 @@ gnc_commodity *dom_tree_to_commodity_ref_no_engine(xmlNodePtr node);
|
||||
Timespec* dom_tree_to_timespec(xmlNodePtr node);
|
||||
gnc_numeric* dom_tree_to_gnc_numeric(xmlNodePtr node);
|
||||
gchar * dom_tree_to_text(xmlNodePtr tree);
|
||||
gboolean string_to_binary(const gchar *str, void **v, guint64 *data_len);
|
||||
|
||||
kvp_frame* dom_tree_to_kvp_frame(xmlNodePtr node);
|
||||
kvp_value* dom_tree_to_kvp_value(xmlNodePtr node);
|
||||
kvp_value* dom_tree_to_integer_kvp_value(xmlNodePtr node);
|
||||
kvp_value* dom_tree_to_double_kvp_value(xmlNodePtr node);
|
||||
kvp_value* dom_tree_to_numeric_kvp_value(xmlNodePtr node);
|
||||
kvp_value* dom_tree_to_string_kvp_value(xmlNodePtr node);
|
||||
kvp_value* dom_tree_to_guid_kvp_value(xmlNodePtr node);
|
||||
kvp_value* dom_tree_to_binary_kvp_value(xmlNodePtr node);
|
||||
kvp_value* dom_tree_to_list_kvp_value(xmlNodePtr node);
|
||||
kvp_value* dom_tree_to_frame_kvp_value(xmlNodePtr node);
|
||||
|
||||
gboolean dom_tree_to_integer(xmlNodePtr node, gint64 *daint);
|
||||
|
||||
kvp_frame* dom_tree_handle_kvp(xmlNodePtr node);
|
||||
|
||||
#endif /* _SIXTP_DOM_PARSERS_H_ */
|
||||
|
@ -6,8 +6,10 @@
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp.h"
|
||||
|
||||
static xmlNsPtr global_namespace;
|
||||
static xmlNsPtr global_namespace = NULL;
|
||||
|
||||
/* Don't pass anything in the data_for_children value to this
|
||||
function. It'll cause a segfault */
|
||||
static gboolean dom_start_handler(
|
||||
GSList* sibling_data, gpointer parent_data, gpointer global_data,
|
||||
gpointer *data_for_children, gpointer *result, const gchar *tag,
|
||||
@ -22,7 +24,8 @@ static gboolean dom_start_handler(
|
||||
}
|
||||
else
|
||||
{
|
||||
thing = xmlNewChild(parent_data, global_namespace, tag, NULL);
|
||||
thing = xmlNewChild((xmlNodePtr)parent_data, global_namespace,
|
||||
tag, NULL);
|
||||
}
|
||||
|
||||
if(attrs != NULL)
|
||||
@ -40,26 +43,12 @@ static gboolean dom_start_handler(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean is_whitespace(const char *text, int len)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
if(!isspace(text[i]))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean dom_chars_handler(
|
||||
GSList *sibling_data, gpointer parent_data, gpointer global_data,
|
||||
gpointer *result, const char *text, int length)
|
||||
{
|
||||
if(length > 0 && !is_whitespace(text, length))
|
||||
if(length > 0 && !isspace_str(text, length))
|
||||
{
|
||||
/* gchar *stuff = g_strndup(text, length); */
|
||||
xmlNodeSetContentLen((xmlNodePtr)parent_data, text, length);
|
||||
}
|
||||
return TRUE;
|
||||
|
@ -86,7 +86,7 @@ gnc_quickfill_new (void)
|
||||
|
||||
/* For now, use the engine cache. */
|
||||
if (qf_string_cache == NULL)
|
||||
qf_string_cache = gnc_string_cache;
|
||||
qf_string_cache = gnc_engine_get_string_cache ();
|
||||
|
||||
qf = g_new (QuickFill, 1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user