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" 39 static QofLogModule log_module = GNC_MOD_IO;
87 price_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 GncGUID* c = dom_tree_to_guid (sub_node);
96 gnc_price_set_guid (p, c);
99 else if (g_strcmp0 (
"price:commodity", (
char*)sub_node->name) == 0)
101 gnc_commodity* c = dom_tree_to_commodity_ref (sub_node, book);
102 if (!c)
return FALSE;
103 gnc_price_set_commodity (p, c);
105 else if (g_strcmp0 (
"price:currency", (
char*)sub_node->name) == 0)
107 gnc_commodity* c = dom_tree_to_commodity_ref (sub_node, book);
108 if (!c)
return FALSE;
109 gnc_price_set_currency (p, c);
111 else if (g_strcmp0 (
"price:time", (
char*)sub_node->name) == 0)
113 time64 time = dom_tree_to_time64 (sub_node);
114 if (!dom_tree_valid_time64 (time, sub_node->name)) time = 0;
115 gnc_price_set_time64 (p, time);
117 else if (g_strcmp0 (
"price:source", (
char*)sub_node->name) == 0)
119 char* text = dom_tree_to_text (sub_node);
120 if (!text)
return FALSE;
121 gnc_price_set_source_string (p, text);
124 else if (g_strcmp0 (
"price:type", (
char*)sub_node->name) == 0)
126 char* text = dom_tree_to_text (sub_node);
127 if (!text)
return FALSE;
128 gnc_price_set_typestr (p, text);
131 else if (g_strcmp0 (
"price:value", (
char*)sub_node->name) == 0)
133 gnc_price_set_value (p, dom_tree_to_gnc_numeric (sub_node));
135 gnc_price_commit_edit (p);
140 price_parse_xml_end_handler (gpointer data_for_children,
141 GSList* data_from_children,
142 GSList* sibling_data,
143 gpointer parent_data,
144 gpointer global_data,
149 xmlNodePtr price_xml = (xmlNodePtr) data_for_children;
152 gxpf_data* gdata =
static_cast<decltype (gdata)
> (global_data);
153 QofBook* book =
static_cast<decltype (book)
> (gdata->bookdata);
156 if (parent_data)
return TRUE;
160 if (!price_xml)
return FALSE;
164 goto cleanup_and_exit;
169 goto cleanup_and_exit;
171 if (!price_xml->xmlChildrenNode)
174 goto cleanup_and_exit;
181 goto cleanup_and_exit;
184 for (child = price_xml->xmlChildrenNode; child; child = child->next)
188 case XML_COMMENT_NODE:
191 case XML_ELEMENT_NODE:
192 if (!price_parse_xml_sub_node (p, child, book))
195 goto cleanup_and_exit;
199 PERR (
"Unknown node type (%d) while parsing gnc-price xml.", child->type);
202 goto cleanup_and_exit;
217 xmlFreeNode (price_xml);
222 cleanup_gnc_price (sixtp_child_result* result)
228 gnc_price_parser_new (
void)
230 return sixtp_dom_parser_new (price_parse_xml_end_handler,
253 pricedb_start_handler (GSList* sibling_data,
254 gpointer parent_data,
255 gpointer global_data,
256 gpointer* data_for_children,
261 gxpf_data* gdata =
static_cast<decltype (gdata)
> (global_data);
262 QofBook* book =
static_cast<decltype (book)
> (gdata->bookdata);
264 g_return_val_if_fail (db, FALSE);
271 pricedb_after_child_handler (gpointer data_for_children,
272 GSList* data_from_children,
273 GSList* sibling_data,
274 gpointer parent_data,
275 gpointer global_data,
278 const gchar* child_tag,
279 sixtp_child_result* child_result)
281 gxpf_data* gdata =
static_cast<decltype (gdata)
> (global_data);
282 sixtp_gdv2* gd =
static_cast<decltype (gd)
> (gdata->parsedata);
283 GNCPriceDB* db = (GNCPriceDB*) * result;
285 g_return_val_if_fail (db, FALSE);
288 if (!child_result)
return (FALSE);
289 if (child_result->type != SIXTP_CHILD_RESULT_NODE)
return (FALSE);
291 if (strcmp (child_result->tag,
"price") == 0)
293 GNCPrice* p = (GNCPrice*) child_result->data;
295 g_return_val_if_fail (p, FALSE);
297 gd->counter.prices_loaded++;
298 sixtp_run_callback (gd,
"prices");
303 PERR (
"unexpected tag %s\n", child_result->tag);
310 pricedb_cleanup_result_handler (sixtp_child_result* result)
314 GNCPriceDB* db = (GNCPriceDB*) result->data;
321 pricedb_v2_end_handler (
322 gpointer data_for_children, GSList* data_from_children,
323 GSList* sibling_data, gpointer parent_data, gpointer global_data,
324 gpointer* result,
const gchar* tag)
326 GNCPriceDB* db =
static_cast<decltype (db)
> (*result);
327 gxpf_data* gdata = (gxpf_data*)global_data;
339 gdata->cb (tag, gdata->parsedata, db);
348 gnc_pricedb_parser_new (
void)
354 sixtp_set_any (sixtp_new (), TRUE,
355 SIXTP_START_HANDLER_ID, pricedb_start_handler,
356 SIXTP_AFTER_CHILD_HANDLER_ID, pricedb_after_child_handler,
357 SIXTP_CHARACTERS_HANDLER_ID,
358 allow_and_ignore_only_whitespace,
359 SIXTP_RESULT_FAIL_ID, pricedb_cleanup_result_handler,
360 SIXTP_CLEANUP_RESULT_ID, pricedb_cleanup_result_handler,
361 SIXTP_NO_MORE_HANDLERS);
363 if (!top_level)
return NULL;
365 price_parser = gnc_price_parser_new ();
369 sixtp_destroy (top_level);
373 sixtp_add_sub_parser (top_level,
"price", price_parser);
379 gnc_pricedb_sixtp_parser_create (
void)
382 ret = gnc_pricedb_parser_new ();
383 sixtp_set_end (ret, pricedb_v2_end_handler);
393 add_child_or_kill_parent (xmlNodePtr parent, xmlNodePtr child)
397 xmlFreeNode (parent);
400 xmlAddChild (parent, child);
405 gnc_price_to_dom_tree (
const xmlChar* tag, GNCPrice* price)
407 xmlNodePtr price_xml;
408 const gchar* typestr, *sourcestr;
410 gnc_commodity* commodity;
411 gnc_commodity* currency;
415 if (! (tag && price))
return NULL;
417 price_xml = xmlNewNode (NULL, tag);
418 if (!price_xml)
return NULL;
420 commodity = gnc_price_get_commodity (price);
421 currency = gnc_price_get_currency (price);
423 if (! (commodity && currency))
return NULL;
425 tmpnode = guid_to_dom_tree (
"price:id", gnc_price_get_guid (price));
426 if (!add_child_or_kill_parent (price_xml, tmpnode))
return NULL;
428 tmpnode = commodity_ref_to_dom_tree (
"price:commodity", commodity);
429 if (!add_child_or_kill_parent (price_xml, tmpnode))
return NULL;
431 tmpnode = commodity_ref_to_dom_tree (
"price:currency", currency);
432 if (!add_child_or_kill_parent (price_xml, tmpnode))
return NULL;
434 time = gnc_price_get_time64 (price);
435 tmpnode = time64_to_dom_tree (
"price:time", time);
436 if (!add_child_or_kill_parent (price_xml, tmpnode))
return NULL;
438 sourcestr = gnc_price_get_source_string (price);
439 if (sourcestr && *sourcestr)
441 tmpnode = text_to_dom_tree (
"price:source", sourcestr);
442 if (!add_child_or_kill_parent (price_xml, tmpnode))
return NULL;
445 typestr = gnc_price_get_typestr (price);
446 if (typestr && *typestr)
448 tmpnode = text_to_dom_tree (
"price:type", typestr);
449 if (!add_child_or_kill_parent (price_xml, tmpnode))
return NULL;
452 value = gnc_price_get_value (price);
453 tmpnode = gnc_numeric_to_dom_tree (
"price:value", &value);
454 if (!add_child_or_kill_parent (price_xml, tmpnode))
return NULL;
460 xml_add_gnc_price_adapter (GNCPrice* p, gpointer data)
462 xmlNodePtr xml_node = (xmlNodePtr) data;
466 xmlNodePtr price_xml = gnc_price_to_dom_tree (BAD_CAST
"price", p);
467 if (!price_xml)
return FALSE;
468 xmlAddChild (xml_node, price_xml);
478 gnc_pricedb_to_dom_tree (
const xmlChar* tag, GNCPriceDB* db)
480 xmlNodePtr db_xml = NULL;
482 if (!tag)
return NULL;
484 db_xml = xmlNewNode (NULL, tag);
485 if (!db_xml)
return NULL;
487 xmlSetProp (db_xml, BAD_CAST
"version", BAD_CAST
"1");
491 xmlFreeNode (db_xml);
496 if (!db_xml->xmlChildrenNode)
498 xmlFreeNode (db_xml);
506 gnc_pricedb_dom_tree_create (GNCPriceDB* db)
508 return gnc_pricedb_to_dom_tree (BAD_CAST
"gnc:pricedb", db);
GNCPrice * gnc_price_create(QofBook *book)
gnc_price_create - returns a newly allocated and initialized price with a reference count of 1...
a simple price database for gnucash
void gnc_price_unref(GNCPrice *p)
gnc_price_unref - indicate you're finished with a price (i.e.
gboolean gnc_pricedb_add_price(GNCPriceDB *db, GNCPrice *p)
Add a price to the pricedb.
#define PERR(format, args...)
Log a serious error.
GNCPriceDB * gnc_pricedb_get_db(QofBook *book)
Return the pricedb associated with the book.
api for GnuCash version 2 XML-based file format
void gnc_pricedb_destroy(GNCPriceDB *db)
Destroy the given pricedb and unref all of the prices it contains.
void gnc_pricedb_set_bulk_update(GNCPriceDB *db, gboolean bulk_update)
Set flag to indicate whether duplication checks should be performed.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
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...
The type used to store guids in C.