27#include "gnc-pricedb-p.h"
31#include "sixtp-utils.h"
32#include "sixtp-parsers.h"
33#include "sixtp-dom-parsers.h"
34#include "sixtp-dom-generators.h"
35#include "io-gncxml-gen.h"
39static QofLogModule log_module = GNC_MOD_IO;
87price_parse_xml_sub_node (GNCPrice* p, xmlNodePtr sub_node,
QofBook* book)
89 if (!p || !sub_node)
return FALSE;
91 gnc_price_begin_edit (p);
92 if (g_strcmp0 (
"price:id", (
char*)sub_node->name) == 0)
94 auto c = dom_tree_to_guid (sub_node);
96 gnc_price_set_guid (p, &*c);
98 else if (g_strcmp0 (
"price:commodity", (
char*)sub_node->name) == 0)
100 gnc_commodity* c = dom_tree_to_commodity_ref (sub_node, book);
101 if (!c)
return FALSE;
102 gnc_price_set_commodity (p, c);
104 else if (g_strcmp0 (
"price:currency", (
char*)sub_node->name) == 0)
106 gnc_commodity* c = dom_tree_to_commodity_ref (sub_node, book);
107 if (!c)
return FALSE;
108 gnc_price_set_currency (p, c);
110 else if (g_strcmp0 (
"price:time", (
char*)sub_node->name) == 0)
112 time64 time = dom_tree_to_time64 (sub_node);
113 if (!dom_tree_valid_time64 (time, sub_node->name)) time = 0;
114 gnc_price_set_time64 (p, time);
116 else if (g_strcmp0 (
"price:source", (
char*)sub_node->name) == 0)
118 if (!apply_xmlnode_text (gnc_price_set_source_string, p, sub_node))
121 else if (g_strcmp0 (
"price:type", (
char*)sub_node->name) == 0)
123 if (!apply_xmlnode_text (gnc_price_set_typestr, p, sub_node))
126 else if (g_strcmp0 (
"price:value", (
char*)sub_node->name) == 0)
128 gnc_price_set_value (p, dom_tree_to_gnc_numeric (sub_node));
130 gnc_price_commit_edit (p);
135price_parse_xml_end_handler (gpointer data_for_children,
136 GSList* data_from_children,
137 GSList* sibling_data,
138 gpointer parent_data,
139 gpointer global_data,
144 xmlNodePtr price_xml = (xmlNodePtr) data_for_children;
147 gxpf_data* gdata =
static_cast<decltype (gdata)
> (global_data);
148 QofBook* book =
static_cast<decltype (book)
> (gdata->bookdata);
151 if (parent_data)
return TRUE;
155 if (!price_xml)
return FALSE;
159 goto cleanup_and_exit;
164 goto cleanup_and_exit;
166 if (!price_xml->xmlChildrenNode)
169 goto cleanup_and_exit;
176 goto cleanup_and_exit;
179 for (child = price_xml->xmlChildrenNode; child; child = child->next)
183 case XML_COMMENT_NODE:
186 case XML_ELEMENT_NODE:
187 if (!price_parse_xml_sub_node (p, child, book))
190 goto cleanup_and_exit;
194 PERR (
"Unknown node type (%d) while parsing gnc-price xml.", child->type);
197 goto cleanup_and_exit;
212 xmlFreeNode (price_xml);
217cleanup_gnc_price (sixtp_child_result* result)
223gnc_price_parser_new (
void)
225 return sixtp_dom_parser_new (price_parse_xml_end_handler,
248pricedb_start_handler (GSList* sibling_data,
249 gpointer parent_data,
250 gpointer global_data,
251 gpointer* data_for_children,
256 gxpf_data* gdata =
static_cast<decltype (gdata)
> (global_data);
257 QofBook* book =
static_cast<decltype (book)
> (gdata->bookdata);
259 g_return_val_if_fail (db, FALSE);
266pricedb_after_child_handler (gpointer data_for_children,
267 GSList* data_from_children,
268 GSList* sibling_data,
269 gpointer parent_data,
270 gpointer global_data,
273 const gchar* child_tag,
274 sixtp_child_result* child_result)
276 gxpf_data* gdata =
static_cast<decltype (gdata)
> (global_data);
277 sixtp_gdv2* gd =
static_cast<decltype (gd)
> (gdata->parsedata);
278 GNCPriceDB* db = (GNCPriceDB*) * result;
280 g_return_val_if_fail (db, FALSE);
283 if (!child_result)
return (FALSE);
284 if (child_result->type != SIXTP_CHILD_RESULT_NODE)
return (FALSE);
286 if (strcmp (child_result->tag,
"price") == 0)
288 GNCPrice* p = (GNCPrice*) child_result->data;
290 g_return_val_if_fail (p, FALSE);
292 gd->counter.prices_loaded++;
293 sixtp_run_callback (gd,
"prices");
298 PERR (
"unexpected tag %s\n", child_result->tag);
305pricedb_cleanup_result_handler (sixtp_child_result* result)
309 GNCPriceDB* db = (GNCPriceDB*) result->data;
316pricedb_v2_end_handler (
317 gpointer data_for_children, GSList* data_from_children,
318 GSList* sibling_data, gpointer parent_data, gpointer global_data,
319 gpointer* result,
const gchar* tag)
321 GNCPriceDB* db =
static_cast<decltype (db)
> (*result);
322 gxpf_data* gdata = (gxpf_data*)global_data;
334 gdata->cb (tag, gdata->parsedata, db);
343gnc_pricedb_parser_new (
void)
349 sixtp_set_any (sixtp_new (), TRUE,
350 SIXTP_START_HANDLER_ID, pricedb_start_handler,
351 SIXTP_AFTER_CHILD_HANDLER_ID, pricedb_after_child_handler,
352 SIXTP_CHARACTERS_HANDLER_ID,
353 allow_and_ignore_only_whitespace,
354 SIXTP_RESULT_FAIL_ID, pricedb_cleanup_result_handler,
355 SIXTP_CLEANUP_RESULT_ID, pricedb_cleanup_result_handler,
356 SIXTP_NO_MORE_HANDLERS);
358 if (!top_level)
return NULL;
360 price_parser = gnc_price_parser_new ();
364 sixtp_destroy (top_level);
368 sixtp_add_sub_parser (top_level,
"price", price_parser);
374gnc_pricedb_sixtp_parser_create (
void)
377 ret = gnc_pricedb_parser_new ();
378 sixtp_set_end (ret, pricedb_v2_end_handler);
388add_child_or_kill_parent (xmlNodePtr parent, xmlNodePtr child)
392 xmlFreeNode (parent);
395 xmlAddChild (parent, child);
400gnc_price_to_dom_tree (
const xmlChar* tag, GNCPrice* price)
402 xmlNodePtr price_xml;
403 const gchar* typestr, *sourcestr;
405 gnc_commodity* commodity;
406 gnc_commodity* currency;
410 if (! (tag && price))
return NULL;
412 price_xml = xmlNewNode (NULL, tag);
413 if (!price_xml)
return NULL;
415 commodity = gnc_price_get_commodity (price);
416 currency = gnc_price_get_currency (price);
418 if (! (commodity && currency))
return NULL;
420 tmpnode = guid_to_dom_tree (
"price:id", gnc_price_get_guid (price));
421 if (!add_child_or_kill_parent (price_xml, tmpnode))
return NULL;
423 tmpnode = commodity_ref_to_dom_tree (
"price:commodity", commodity);
424 if (!add_child_or_kill_parent (price_xml, tmpnode))
return NULL;
426 tmpnode = commodity_ref_to_dom_tree (
"price:currency", currency);
427 if (!add_child_or_kill_parent (price_xml, tmpnode))
return NULL;
429 time = gnc_price_get_time64 (price);
430 tmpnode = time64_to_dom_tree (
"price:time", time);
431 if (!add_child_or_kill_parent (price_xml, tmpnode))
return NULL;
433 sourcestr = gnc_price_get_source_string (price);
434 if (sourcestr && *sourcestr)
436 tmpnode = text_to_dom_tree (
"price:source", sourcestr);
437 if (!add_child_or_kill_parent (price_xml, tmpnode))
return NULL;
440 typestr = gnc_price_get_typestr (price);
441 if (typestr && *typestr)
443 tmpnode = text_to_dom_tree (
"price:type", typestr);
444 if (!add_child_or_kill_parent (price_xml, tmpnode))
return NULL;
447 value = gnc_price_get_value (price);
448 tmpnode = gnc_numeric_to_dom_tree (
"price:value", &value);
449 if (!add_child_or_kill_parent (price_xml, tmpnode))
return NULL;
455xml_add_gnc_price_adapter (GNCPrice* p, gpointer data)
457 xmlNodePtr xml_node = (xmlNodePtr) data;
461 xmlNodePtr price_xml = gnc_price_to_dom_tree (BAD_CAST
"price", p);
462 if (!price_xml)
return FALSE;
463 xmlAddChild (xml_node, price_xml);
473gnc_pricedb_to_dom_tree (
const xmlChar* tag, GNCPriceDB* db)
475 xmlNodePtr db_xml = NULL;
477 if (!tag)
return NULL;
479 db_xml = xmlNewNode (NULL, tag);
480 if (!db_xml)
return NULL;
482 xmlSetProp (db_xml, BAD_CAST
"version", BAD_CAST
"1");
486 xmlFreeNode (db_xml);
491 if (!db_xml->xmlChildrenNode)
493 xmlFreeNode (db_xml);
501gnc_pricedb_dom_tree_create (GNCPriceDB* db)
503 return gnc_pricedb_to_dom_tree (BAD_CAST
"gnc:pricedb", db);
a simple price database for gnucash
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
#define PERR(format, args...)
Log a serious error.
void gnc_pricedb_set_bulk_update(GNCPriceDB *db, gboolean bulk_update)
Set flag to indicate whether duplication checks should be performed.
gboolean gnc_pricedb_foreach_price(GNCPriceDB *db, GncPriceForeachFunc f, gpointer user_data, gboolean stable_order)
Call a GncPriceForeachFunction once for each price in db, until the function returns FALSE.
GNCPriceDB * gnc_pricedb_get_db(QofBook *book)
Return the pricedb associated with the book.
void gnc_pricedb_destroy(GNCPriceDB *db)
Destroy the given pricedb and unref all of the prices it contains.
gboolean gnc_pricedb_add_price(GNCPriceDB *db, GNCPrice *p)
Add a price to the pricedb.
GNCPrice * gnc_price_create(QofBook *book)
gnc_price_create - returns a newly allocated and initialized price with a reference count of 1.
void gnc_price_unref(GNCPrice *p)
gnc_price_unref - indicate you're finished with a price (i.e.
api for GnuCash version 2 XML-based file format