Branch data Line data Source code
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 : 932 : gnc_commodity_dom_tree_create (const gnc_commodity* com)
60 : : {
61 : : gnc_quote_source* source;
62 : : const char* string;
63 : : xmlNodePtr ret;
64 : 932 : gboolean currency = gnc_commodity_is_iso (com);
65 : : xmlNodePtr slotsnode =
66 : 932 : qof_instance_slots_to_dom_tree (cmdty_slots, QOF_INSTANCE (com));
67 : :
68 : 932 : if (currency && !gnc_commodity_get_quote_flag (com) && !slotsnode)
69 : 904 : return NULL;
70 : :
71 : 28 : ret = xmlNewNode (NULL, BAD_CAST gnc_commodity_string);
72 : :
73 : 28 : xmlSetProp (ret, BAD_CAST "version", BAD_CAST commodity_version_string);
74 : :
75 : 28 : xmlAddChild (ret, text_to_dom_tree (cmdty_namespace,
76 : : gnc_commodity_get_namespace (com)));
77 : 28 : xmlAddChild (ret, text_to_dom_tree (cmdty_id,
78 : : gnc_commodity_get_mnemonic (com)));
79 : :
80 : 28 : if (!currency)
81 : : {
82 : 24 : if (gnc_commodity_get_fullname (com))
83 : : {
84 : 24 : xmlAddChild (ret, text_to_dom_tree (cmdty_name,
85 : : gnc_commodity_get_fullname (com)));
86 : : }
87 : :
88 : 24 : const char* cusip = gnc_commodity_get_cusip (com);
89 : 24 : if (cusip && *cusip)
90 : : {
91 : 24 : xmlAddChild (ret, text_to_dom_tree (cmdty_xcode, cusip));
92 : : }
93 : :
94 : 24 : xmlAddChild (ret, int_to_dom_tree (cmdty_fraction,
95 : 24 : gnc_commodity_get_fraction (com)));
96 : : }
97 : :
98 : 28 : if (gnc_commodity_get_quote_flag (com))
99 : : {
100 : 4 : xmlNewChild (ret, NULL, BAD_CAST cmdty_get_quotes, NULL);
101 : 4 : source = gnc_commodity_get_quote_source (com);
102 : 4 : if (source)
103 : 4 : xmlAddChild (ret, text_to_dom_tree (cmdty_quote_source,
104 : : gnc_quote_source_get_internal_name (source)));
105 : 4 : string = gnc_commodity_get_quote_tz (com);
106 : 4 : if (string)
107 : 4 : xmlAddChild (ret, text_to_dom_tree (cmdty_quote_tz, string));
108 : : }
109 : :
110 : 28 : if (slotsnode)
111 : 0 : xmlAddChild (ret, slotsnode);
112 : :
113 : 28 : return ret;
114 : : }
115 : :
116 : : /***********************************************************************/
117 : :
118 : : struct com_char_handler
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 : 1212 : set_commodity_value (xmlNodePtr node, gnc_commodity* com)
136 : : {
137 : 1212 : if (g_strcmp0 ((char*) node->name, cmdty_fraction) == 0)
138 : : {
139 : : gint64 val;
140 : : char* string;
141 : :
142 : 102 : string = (char*) xmlNodeGetContent (node->xmlChildrenNode);
143 : 102 : if (string_to_gint64 (string, &val))
144 : : {
145 : 102 : gnc_commodity_set_fraction (com, val);
146 : : }
147 : 102 : xmlFree (string);
148 : : }
149 : 1110 : else if (g_strcmp0 ((char*)node->name, cmdty_get_quotes) == 0)
150 : : {
151 : 19 : gnc_commodity_set_quote_flag (com, TRUE);
152 : : }
153 : 1091 : else if (g_strcmp0 ((char*)node->name, cmdty_quote_source) == 0)
154 : : {
155 : : gnc_quote_source* source;
156 : : char* string;
157 : :
158 : 19 : string = (char*) xmlNodeGetContent (node->xmlChildrenNode);
159 : 19 : source = gnc_quote_source_lookup_by_internal (string);
160 : 19 : if (!source)
161 : 0 : source = gnc_quote_source_add_new (string, FALSE);
162 : 19 : gnc_commodity_set_quote_source (com, source);
163 : 19 : xmlFree (string);
164 : : }
165 : 1072 : else if (g_strcmp0 ((char*)node->name, cmdty_slots) == 0)
166 : : {
167 : : /* We ignore the results here */
168 : 1 : dom_tree_create_instance_slots (node, QOF_INSTANCE (com));
169 : : }
170 : : else
171 : : {
172 : : struct com_char_handler* mark;
173 : :
174 : 4932 : for (mark = com_handlers; mark->tag; mark++)
175 : : {
176 : 4266 : if (g_strcmp0 (mark->tag, (char*)node->name) == 0)
177 : : {
178 : 405 : gchar* val = dom_tree_to_text (node);
179 : 405 : g_strstrip (val);
180 : 405 : (mark->func) (com, val);
181 : 405 : g_free (val);
182 : 405 : break;
183 : : }
184 : : }
185 : : }
186 : 1212 : }
187 : :
188 : : static gboolean
189 : 120 : valid_commodity (gnc_commodity* com)
190 : : {
191 : 120 : if (gnc_commodity_get_namespace (com) == NULL)
192 : : {
193 : 0 : PWARN ("Invalid commodity: no namespace");
194 : 0 : return FALSE;
195 : : }
196 : 120 : if (gnc_commodity_get_mnemonic (com) == NULL)
197 : : {
198 : 0 : PWARN ("Invalid commodity: no mnemonic");
199 : 0 : return FALSE;
200 : : }
201 : 120 : if (gnc_commodity_get_fraction (com) == 0)
202 : : {
203 : 0 : PWARN ("Invalid commodity: 0 fraction");
204 : 0 : return FALSE;
205 : : }
206 : 120 : return TRUE;
207 : : }
208 : :
209 : : static gnc_commodity*
210 : 120 : gnc_commodity_find_currency (QofBook* book, xmlNodePtr tree)
211 : : {
212 : : gnc_commodity_table* table;
213 : 120 : gnc_commodity* currency = NULL;
214 : 120 : gchar* exchange = NULL, *mnemonic = NULL;
215 : : xmlNodePtr node;
216 : :
217 : 1332 : for (node = tree->xmlChildrenNode; node; node = node->next)
218 : : {
219 : 1212 : if (g_strcmp0 ((char*) node->name, cmdty_namespace) == 0)
220 : 120 : exchange = (gchar*) xmlNodeGetContent (node->xmlChildrenNode);
221 : 1212 : if (g_strcmp0 ((char*) node->name, cmdty_id) == 0)
222 : 120 : mnemonic = (gchar*) xmlNodeGetContent (node->xmlChildrenNode);
223 : : }
224 : :
225 : 120 : if (exchange
226 : 120 : && gnc_commodity_namespace_is_iso (exchange)
227 : 240 : && mnemonic)
228 : : {
229 : 18 : table = gnc_commodity_table_get_table (book);
230 : 18 : currency = gnc_commodity_table_lookup (table, exchange, mnemonic);
231 : : }
232 : :
233 : 120 : if (exchange)
234 : 120 : xmlFree (exchange);
235 : 120 : if (mnemonic)
236 : 111 : xmlFree (mnemonic);
237 : :
238 : 120 : return currency;
239 : : }
240 : :
241 : : static gboolean
242 : 689 : 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 : 689 : xmlNodePtr tree = (xmlNodePtr)data_for_children;
250 : 689 : gxpf_data* gdata = (gxpf_data*)global_data;
251 : 689 : QofBook* book = static_cast<decltype (book)> (gdata->bookdata);
252 : :
253 : 689 : if (parent_data)
254 : : {
255 : 549 : 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 : 140 : if (!tag)
261 : : {
262 : 20 : return TRUE;
263 : : }
264 : :
265 : 120 : g_return_val_if_fail (tree, FALSE);
266 : :
267 : 120 : com = gnc_commodity_new (book, NULL, NULL, NULL, NULL, 0);
268 : 120 : old_com = gnc_commodity_find_currency (book, tree);
269 : 120 : if (old_com)
270 : 18 : gnc_commodity_copy (com, old_com);
271 : :
272 : 1332 : for (achild = tree->xmlChildrenNode; achild; achild = achild->next)
273 : : {
274 : 1212 : set_commodity_value (achild, com);
275 : : }
276 : :
277 : 120 : if (!valid_commodity (com))
278 : : {
279 : 0 : PWARN ("Invalid commodity parsed");
280 : 0 : xmlElemDump (stdout, NULL, tree);
281 : 0 : printf ("\n");
282 : 0 : fflush (stdout);
283 : 0 : gnc_commodity_destroy (com);
284 : 0 : return FALSE;
285 : : }
286 : :
287 : 120 : gdata->cb (tag, gdata->parsedata, com);
288 : :
289 : 120 : xmlFreeNode (tree);
290 : :
291 : 120 : return TRUE;
292 : : }
293 : :
294 : :
295 : : sixtp*
296 : 62 : gnc_commodity_sixtp_parser_create (void)
297 : : {
298 : 62 : return sixtp_dom_parser_new (gnc_commodity_end_handler, NULL, NULL);
299 : : }
|