GnuCash  5.6-150-g038405b370+
gnc-commodity-xml-v2.cpp
1 /********************************************************************\
2  * gnc-commodity-xml-v2.c -- commodity xml i/o implementation *
3  * *
4  * Copyright (C) 2001 James LewisMoss <dres@debian.org> *
5  * *
6  * This program is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU General Public License as *
8  * published by the Free Software Foundation; either version 2 of *
9  * the License, or (at your option) any later version. *
10  * *
11  * This program is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License*
17  * along with this program; if not, contact: *
18  * *
19  * Free Software Foundation Voice: +1-617-542-5942 *
20  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21  * Boston, MA 02110-1301, USA gnu@gnu.org *
22  * *
23 \********************************************************************/
24 #include <glib.h>
25 
26 #include <config.h>
27 #include <string.h>
28 #include "AccountP.hpp"
29 #include "Account.h"
30 
31 #include "gnc-xml-helper.h"
32 #include "sixtp.h"
33 #include "sixtp-utils.h"
34 #include "sixtp-parsers.h"
35 #include "sixtp-utils.h"
36 #include "sixtp-dom-parsers.h"
37 #include "sixtp-dom-generators.h"
38 
39 #include "gnc-xml.h"
40 #include "io-gncxml-gen.h"
41 
42 static QofLogModule log_module = GNC_MOD_IO;
43 
44 const gchar* commodity_version_string = "2.0.0";
45 
46 /* ids */
47 #define gnc_commodity_string "gnc:commodity"
48 #define cmdty_namespace "cmdty:space"
49 #define cmdty_id "cmdty:id"
50 #define cmdty_name "cmdty:name"
51 #define cmdty_xcode "cmdty:xcode"
52 #define cmdty_fraction "cmdty:fraction"
53 #define cmdty_get_quotes "cmdty:get_quotes"
54 #define cmdty_quote_source "cmdty:quote_source"
55 #define cmdty_quote_tz "cmdty:quote_tz"
56 #define cmdty_slots "cmdty:slots"
57 
58 xmlNodePtr
59 gnc_commodity_dom_tree_create (const gnc_commodity* com)
60 {
61  gnc_quote_source* source;
62  const char* string;
63  xmlNodePtr ret;
64  gboolean currency = gnc_commodity_is_iso (com);
65  xmlNodePtr slotsnode =
66  qof_instance_slots_to_dom_tree (cmdty_slots, QOF_INSTANCE (com));
67 
68  if (currency && !gnc_commodity_get_quote_flag (com) && !slotsnode)
69  return NULL;
70 
71  ret = xmlNewNode (NULL, BAD_CAST gnc_commodity_string);
72 
73  xmlSetProp (ret, BAD_CAST "version", BAD_CAST commodity_version_string);
74 
75  xmlAddChild (ret, text_to_dom_tree (cmdty_namespace,
77  xmlAddChild (ret, text_to_dom_tree (cmdty_id,
79 
80  if (!currency)
81  {
83  {
84  xmlAddChild (ret, text_to_dom_tree (cmdty_name,
86  }
87 
88  const char* cusip = gnc_commodity_get_cusip (com);
89  if (cusip && *cusip)
90  {
91  xmlAddChild (ret, text_to_dom_tree (cmdty_xcode, cusip));
92  }
93 
94  xmlAddChild (ret, int_to_dom_tree (cmdty_fraction,
96  }
97 
99  {
100  xmlNewChild (ret, NULL, BAD_CAST cmdty_get_quotes, NULL);
101  source = gnc_commodity_get_quote_source (com);
102  if (source)
103  xmlAddChild (ret, text_to_dom_tree (cmdty_quote_source,
105  string = gnc_commodity_get_quote_tz (com);
106  if (string)
107  xmlAddChild (ret, text_to_dom_tree (cmdty_quote_tz, string));
108  }
109 
110  if (slotsnode)
111  xmlAddChild (ret, slotsnode);
112 
113  return ret;
114 }
115 
116 /***********************************************************************/
117 
119 {
120  const char* tag;
121  void (*func) (gnc_commodity* com, const char* val);
122 };
123 
124 struct com_char_handler com_handlers[] =
125 {
126  { cmdty_namespace, gnc_commodity_set_namespace },
127  { cmdty_id, gnc_commodity_set_mnemonic },
128  { cmdty_name, gnc_commodity_set_fullname },
129  { cmdty_xcode, gnc_commodity_set_cusip },
130  { cmdty_quote_tz, gnc_commodity_set_quote_tz },
131  { 0, 0 }
132 };
133 
134 static void
135 set_commodity_value (xmlNodePtr node, gnc_commodity* com)
136 {
137  if (g_strcmp0 ((char*) node->name, cmdty_fraction) == 0)
138  {
139  gint64 val;
140  char* string;
141 
142  string = (char*) xmlNodeGetContent (node->xmlChildrenNode);
143  if (string_to_gint64 (string, &val))
144  {
145  gnc_commodity_set_fraction (com, val);
146  }
147  xmlFree (string);
148  }
149  else if (g_strcmp0 ((char*)node->name, cmdty_get_quotes) == 0)
150  {
151  gnc_commodity_set_quote_flag (com, TRUE);
152  }
153  else if (g_strcmp0 ((char*)node->name, cmdty_quote_source) == 0)
154  {
155  gnc_quote_source* source;
156  char* string;
157 
158  string = (char*) xmlNodeGetContent (node->xmlChildrenNode);
159  source = gnc_quote_source_lookup_by_internal (string);
160  if (!source)
161  source = gnc_quote_source_add_new (string, FALSE);
162  gnc_commodity_set_quote_source (com, source);
163  xmlFree (string);
164  }
165  else if (g_strcmp0 ((char*)node->name, cmdty_slots) == 0)
166  {
167  /* We ignore the results here */
168  dom_tree_create_instance_slots (node, QOF_INSTANCE (com));
169  }
170  else
171  {
172  struct com_char_handler* mark;
173 
174  for (mark = com_handlers; mark->tag; mark++)
175  {
176  if (g_strcmp0 (mark->tag, (char*)node->name) == 0)
177  {
178  gchar* val = dom_tree_to_text (node);
179  g_strstrip (val);
180  (mark->func) (com, val);
181  g_free (val);
182  break;
183  }
184  }
185  }
186 }
187 
188 static gboolean
189 valid_commodity (gnc_commodity* com)
190 {
191  if (gnc_commodity_get_namespace (com) == NULL)
192  {
193  PWARN ("Invalid commodity: no namespace");
194  return FALSE;
195  }
196  if (gnc_commodity_get_mnemonic (com) == NULL)
197  {
198  PWARN ("Invalid commodity: no mnemonic");
199  return FALSE;
200  }
201  if (gnc_commodity_get_fraction (com) == 0)
202  {
203  PWARN ("Invalid commodity: 0 fraction");
204  return FALSE;
205  }
206  return TRUE;
207 }
208 
209 static gnc_commodity*
210 gnc_commodity_find_currency (QofBook* book, xmlNodePtr tree)
211 {
212  gnc_commodity_table* table;
213  gnc_commodity* currency = NULL;
214  gchar* exchange = NULL, *mnemonic = NULL;
215  xmlNodePtr node;
216 
217  for (node = tree->xmlChildrenNode; node; node = node->next)
218  {
219  if (g_strcmp0 ((char*) node->name, cmdty_namespace) == 0)
220  exchange = (gchar*) xmlNodeGetContent (node->xmlChildrenNode);
221  if (g_strcmp0 ((char*) node->name, cmdty_id) == 0)
222  mnemonic = (gchar*) xmlNodeGetContent (node->xmlChildrenNode);
223  }
224 
225  if (exchange
226  && gnc_commodity_namespace_is_iso (exchange)
227  && mnemonic)
228  {
230  currency = gnc_commodity_table_lookup (table, exchange, mnemonic);
231  }
232 
233  if (exchange)
234  xmlFree (exchange);
235  if (mnemonic)
236  xmlFree (mnemonic);
237 
238  return currency;
239 }
240 
241 static gboolean
242 gnc_commodity_end_handler (gpointer data_for_children,
243  GSList* data_from_children, GSList* sibling_data,
244  gpointer parent_data, gpointer global_data,
245  gpointer* result, const gchar* tag)
246 {
247  gnc_commodity* com, *old_com;
248  xmlNodePtr achild;
249  xmlNodePtr tree = (xmlNodePtr)data_for_children;
250  gxpf_data* gdata = (gxpf_data*)global_data;
251  QofBook* book = static_cast<decltype (book)> (gdata->bookdata);
252 
253  if (parent_data)
254  {
255  return TRUE;
256  }
257 
258  /* OK. For some messed up reason this is getting called again with a
259  NULL tag. So we ignore those cases */
260  if (!tag)
261  {
262  return TRUE;
263  }
264 
265  g_return_val_if_fail (tree, FALSE);
266 
267  com = gnc_commodity_new (book, NULL, NULL, NULL, NULL, 0);
268  old_com = gnc_commodity_find_currency (book, tree);
269  if (old_com)
270  gnc_commodity_copy (com, old_com);
271 
272  for (achild = tree->xmlChildrenNode; achild; achild = achild->next)
273  {
274  set_commodity_value (achild, com);
275  }
276 
277  if (!valid_commodity (com))
278  {
279  PWARN ("Invalid commodity parsed");
280  xmlElemDump (stdout, NULL, tree);
281  printf ("\n");
282  fflush (stdout);
283  gnc_commodity_destroy (com);
284  return FALSE;
285  }
286 
287  gdata->cb (tag, gdata->parsedata, com);
288 
289  xmlFreeNode (tree);
290 
291  return TRUE;
292 }
293 
294 
295 sixtp*
296 gnc_commodity_sixtp_parser_create (void)
297 {
298  return sixtp_dom_parser_new (gnc_commodity_end_handler, NULL, NULL);
299 }
This is the private header for the account structure.
const char * gnc_commodity_get_cusip(const gnc_commodity *cm)
Retrieve the &#39;exchange code&#39; for the specified commodity.
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
Returns the commodity table associated with a book.
Definition: sixtp.h:129
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
gnc_quote_source * gnc_quote_source_add_new(const char *source_name, gboolean supported)
Create a new quote source.
gboolean gnc_commodity_get_quote_flag(const gnc_commodity *cm)
Retrieve the automatic price quote flag for the specified commodity.
void gnc_commodity_set_quote_tz(gnc_commodity *cm, const char *tz)
Set the automatic price quote timezone for the specified commodity.
const char * gnc_commodity_get_quote_tz(const gnc_commodity *cm)
Retrieve the automatic price quote timezone for the specified commodity.
void gnc_commodity_set_fraction(gnc_commodity *cm, int fraction)
Set the fraction for the specified commodity.
const char * gnc_commodity_get_namespace(const gnc_commodity *cm)
Retrieve the namespace for the specified commodity.
void gnc_commodity_set_quote_flag(gnc_commodity *cm, const gboolean flag)
Set the automatic price quote flag for the specified commodity.
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:250
void gnc_commodity_set_quote_source(gnc_commodity *cm, gnc_quote_source *src)
Set the automatic price quote source for the specified commodity.
Account handling public routines.
void gnc_commodity_set_cusip(gnc_commodity *cm, const char *cusip)
Set the &#39;exchange code&#39; for the specified commodity.
gnc_commodity * gnc_commodity_new(QofBook *book, const char *fullname, const char *name_space, const char *mnemonic, const char *cusip, int fraction)
Create a new commodity.
gboolean gnc_commodity_namespace_is_iso(const char *name_space)
Checks to see if the specified commodity namespace is the namespace for ISO 4217 currencies.
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
Retrieve the full name for the specified commodity.
gnc_quote_source * gnc_quote_source_lookup_by_internal(const char *name)
Given the internal (gnucash or F::Q) name of a quote source, find the data structure identified by th...
void gnc_commodity_set_fullname(gnc_commodity *cm, const char *fullname)
Set the full name for the specified commodity.
gnc_quote_source * gnc_commodity_get_quote_source(const gnc_commodity *cm)
Retrieve the automatic price quote source for the specified commodity.
void gnc_commodity_set_mnemonic(gnc_commodity *cm, const char *mnemonic)
Set the mnemonic for the specified commodity.
void gnc_commodity_set_namespace(gnc_commodity *cm, const char *name_space)
Set the namespace for the specified commodity.
const char * gnc_quote_source_get_internal_name(const gnc_quote_source *source)
Given a gnc_quote_source data structure, return the internal name of this quote source.
void gnc_commodity_copy(gnc_commodity *dest, const gnc_commodity *src)
Copy src into dest.
void gnc_commodity_destroy(gnc_commodity *cm)
Destroy a commodity.
gboolean gnc_commodity_is_iso(const gnc_commodity *cm)
Checks to see if the specified commodity is an ISO 4217 recognized currency.