GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-commodity-xml-v2.c
1 /********************************************************************\
2  * gnc-commodity-xml-v2.c -- commodity xml i/o implementation *
3  * *
4  * Copyright (C) 2001 James LewisMoss <[email protected]> *
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 [email protected] *
22  * *
23 \********************************************************************/
24 
25 #include "config.h"
26 
27 #include <glib.h>
28 #include <string.h>
29 
30 #include "gnc-xml-helper.h"
31 
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 #include "sixtp-dom-parsers.h"
43 #include "AccountP.h"
44 #include "Account.h"
45 
46 static QofLogModule log_module = GNC_MOD_IO;
47 
48 const gchar *commodity_version_string = "2.0.0";
49 
50 /* ids */
51 #define gnc_commodity_string "gnc:commodity"
52 #define cmdty_namespace "cmdty:space"
53 #define cmdty_id "cmdty:id"
54 #define cmdty_name "cmdty:name"
55 #define cmdty_xcode "cmdty:xcode"
56 #define cmdty_fraction "cmdty:fraction"
57 #define cmdty_get_quotes "cmdty:get_quotes"
58 #define cmdty_quote_source "cmdty:quote_source"
59 #define cmdty_quote_tz "cmdty:quote_tz"
60 #define cmdty_slots "cmdty:slots"
61 
62 xmlNodePtr
63 gnc_commodity_dom_tree_create(const gnc_commodity *com)
64 {
65  gnc_quote_source *source;
66  const char *string;
67  xmlNodePtr ret;
68  gboolean currency = gnc_commodity_is_iso(com);
69  xmlNodePtr kvpnode =
70  kvp_frame_to_dom_tree(cmdty_slots,
71  qof_instance_get_slots(QOF_INSTANCE(com)));
72 
73  if (currency && !gnc_commodity_get_quote_flag(com) && !kvpnode)
74  return NULL;
75 
76  ret = xmlNewNode(NULL, BAD_CAST gnc_commodity_string);
77 
78  xmlSetProp(ret, BAD_CAST "version", BAD_CAST commodity_version_string);
79 
80  xmlAddChild(ret, text_to_dom_tree(cmdty_namespace,
82  xmlAddChild(ret, text_to_dom_tree(cmdty_id,
84 
85  if (!currency)
86  {
88  {
89  xmlAddChild(ret, text_to_dom_tree(cmdty_name,
91  }
92 
93  if (gnc_commodity_get_cusip(com) &&
94  strlen(gnc_commodity_get_cusip(com)) > 0)
95  {
96  xmlAddChild(ret, text_to_dom_tree(
97  cmdty_xcode,
99  }
100 
101  xmlAddChild(ret, int_to_dom_tree(cmdty_fraction,
103  }
104 
106  {
107  xmlNewChild(ret, NULL, BAD_CAST cmdty_get_quotes, NULL);
108  source = gnc_commodity_get_quote_source(com);
109  if (source)
110  xmlAddChild(ret, text_to_dom_tree(cmdty_quote_source,
112  string = gnc_commodity_get_quote_tz(com);
113  if (string)
114  xmlAddChild(ret, text_to_dom_tree(cmdty_quote_tz, string));
115  }
116 
117  if (kvpnode)
118  xmlAddChild(ret, kvpnode);
119 
120  return ret;
121 }
122 
123 /***********************************************************************/
124 
126 {
127  gchar *tag;
128  void(*func)(gnc_commodity *com, const char*val);
129 };
130 
131 struct com_char_handler com_handlers[] =
132 {
133  { cmdty_namespace, gnc_commodity_set_namespace },
134  { cmdty_id, gnc_commodity_set_mnemonic },
135  { cmdty_name, gnc_commodity_set_fullname },
136  { cmdty_xcode, gnc_commodity_set_cusip },
137  { cmdty_quote_tz, gnc_commodity_set_quote_tz },
138  { 0, 0 }
139 };
140 
141 static void
142 set_commodity_value(xmlNodePtr node, gnc_commodity* com)
143 {
144  if (g_strcmp0((char*) node->name, cmdty_fraction) == 0)
145  {
146  gint64 val;
147  char *string;
148 
149  string = (char*) xmlNodeGetContent (node->xmlChildrenNode);
150  if (string_to_gint64(string, &val))
151  {
152  gnc_commodity_set_fraction(com, val);
153  }
154  xmlFree (string);
155  }
156  else if (g_strcmp0((char*)node->name, cmdty_get_quotes) == 0)
157  {
158  gnc_commodity_set_quote_flag(com, TRUE);
159  }
160  else if (g_strcmp0((char*)node->name, cmdty_quote_source) == 0)
161  {
162  gnc_quote_source *source;
163  char *string;
164 
165  string = (char*) xmlNodeGetContent (node->xmlChildrenNode);
166  source = gnc_quote_source_lookup_by_internal(string);
167  if (!source)
168  source = gnc_quote_source_add_new(string, FALSE);
169  gnc_commodity_set_quote_source(com, source);
170  xmlFree (string);
171  }
172  else if (g_strcmp0((char*)node->name, cmdty_slots) == 0)
173  {
174  /* We ignore the results here */
175  dom_tree_to_kvp_frame_given(node,
176  qof_instance_get_slots(QOF_INSTANCE(com)));
177  }
178  else
179  {
180  struct com_char_handler *mark;
181 
182  for (mark = com_handlers; mark->tag; mark++)
183  {
184  if (g_strcmp0(mark->tag, (char*)node->name) == 0)
185  {
186  gchar* val = dom_tree_to_text(node);
187  g_strstrip(val);
188  (mark->func)(com, val);
189  g_free(val);
190  break;
191  }
192  }
193  }
194 }
195 
196 static gboolean
197 valid_commodity(gnc_commodity *com)
198 {
199  if (gnc_commodity_get_namespace(com) == NULL)
200  {
201  PWARN("Invalid commodity: no namespace");
202  return FALSE;
203  }
204  if (gnc_commodity_get_mnemonic(com) == NULL)
205  {
206  PWARN("Invalid commodity: no mnemonic");
207  return FALSE;
208  }
209  if (gnc_commodity_get_fraction(com) == 0)
210  {
211  PWARN("Invalid commodity: 0 fraction");
212  return FALSE;
213  }
214  return TRUE;
215 }
216 
217 static gnc_commodity *
218 gnc_commodity_find_currency (QofBook *book, xmlNodePtr tree)
219 {
221  gnc_commodity *currency = NULL;
222  gchar *exchange = NULL, *mnemonic = NULL;
223  xmlNodePtr node;
224 
225  for (node = tree->xmlChildrenNode; node; node = node->next)
226  {
227  if (g_strcmp0((char*) node->name, cmdty_namespace) == 0)
228  exchange = (gchar*) xmlNodeGetContent (node->xmlChildrenNode);
229  if (g_strcmp0((char*) node->name, cmdty_id) == 0)
230  mnemonic = (gchar*) xmlNodeGetContent (node->xmlChildrenNode);
231  }
232 
233  if (exchange
234  && gnc_commodity_namespace_is_iso(exchange)
235  && mnemonic)
236  {
237  table = gnc_commodity_table_get_table(book);
238  currency = gnc_commodity_table_lookup(table, exchange, mnemonic);
239  }
240 
241  if (exchange)
242  xmlFree(exchange);
243  if (mnemonic)
244  xmlFree(mnemonic);
245 
246  return currency;
247 }
248 
249 static gboolean
250 gnc_commodity_end_handler(gpointer data_for_children,
251  GSList* data_from_children, GSList* sibling_data,
252  gpointer parent_data, gpointer global_data,
253  gpointer *result, const gchar *tag)
254 {
255  gnc_commodity *com, *old_com;
256  xmlNodePtr achild;
257  xmlNodePtr tree = (xmlNodePtr)data_for_children;
258  gxpf_data *gdata = (gxpf_data*)global_data;
259  QofBook *book = gdata->bookdata;
260 
261  if (parent_data)
262  {
263  return TRUE;
264  }
265 
266  /* OK. For some messed up reason this is getting called again with a
267  NULL tag. So we ignore those cases */
268  if (!tag)
269  {
270  return TRUE;
271  }
272 
273  g_return_val_if_fail(tree, FALSE);
274 
275  com = gnc_commodity_new(book, NULL, NULL, NULL, NULL, 0);
276  old_com = gnc_commodity_find_currency(book, tree);
277  if (old_com)
278  gnc_commodity_copy(com, old_com);
279 
280  for (achild = tree->xmlChildrenNode; achild; achild = achild->next)
281  {
282  set_commodity_value(achild, com);
283  }
284 
285  if (!valid_commodity(com))
286  {
287  PWARN("Invalid commodity parsed");
288  xmlElemDump(stdout, NULL, tree);
289  printf("\n");
290  fflush(stdout);
292  return FALSE;
293  }
294 
295  gdata->cb(tag, gdata->parsedata, com);
296 
297  xmlFreeNode(tree);
298 
299  return TRUE;
300 }
301 
302 
303 sixtp*
304 gnc_commodity_sixtp_parser_create(void)
305 {
306  return sixtp_dom_parser_new(gnc_commodity_end_handler, NULL, NULL);
307 }
const char * gnc_commodity_get_cusip(const gnc_commodity *cm)
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
Definition: sixtp.h:93
int gnc_commodity_get_fraction(const gnc_commodity *cm)
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
gnc_quote_source * gnc_quote_source_add_new(const char *source_name, gboolean supported)
gboolean gnc_commodity_get_quote_flag(const gnc_commodity *cm)
const char * gnc_commodity_get_namespace_compat(const gnc_commodity *cm)
void gnc_commodity_set_quote_tz(gnc_commodity *cm, const char *tz)
const char * gnc_commodity_get_quote_tz(const gnc_commodity *cm)
void gnc_commodity_set_fraction(gnc_commodity *cm, int fraction)
const char * gnc_commodity_get_namespace(const gnc_commodity *cm)
void gnc_commodity_set_quote_flag(gnc_commodity *cm, const gboolean flag)
#define PWARN(format, args...)
Definition: qoflog.h:243
void gnc_commodity_set_quote_source(gnc_commodity *cm, gnc_quote_source *src)
Account handling public routines.
void gnc_commodity_set_cusip(gnc_commodity *cm, const char *cusip)
gnc_commodity * gnc_commodity_new(QofBook *book, const char *fullname, const char *name_space, const char *mnemonic, const char *cusip, int fraction)
gboolean gnc_commodity_namespace_is_iso(const char *name_space)
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
gnc_quote_source * gnc_quote_source_lookup_by_internal(const char *name)
void gnc_commodity_set_fullname(gnc_commodity *cm, const char *fullname)
gnc_quote_source * gnc_commodity_get_quote_source(const gnc_commodity *cm)
void gnc_commodity_set_mnemonic(gnc_commodity *cm, const char *mnemonic)
void gnc_commodity_set_namespace(gnc_commodity *cm, const char *name_space)
const char * gnc_quote_source_get_internal_name(const gnc_quote_source *source)
void gnc_commodity_copy(gnc_commodity *dest, const gnc_commodity *src)
void gnc_commodity_destroy(gnc_commodity *cm)
gboolean gnc_commodity_is_iso(const gnc_commodity *cm)
const gchar * QofLogModule
Definition: qofid.h:89