GnuCash  5.6-150-g038405b370+
gnc-book-xml-v2.cpp
1 /********************************************************************\
2  * gnc-book-xml-v2.c -- book xml i/o implementation *
3  * *
4  * Copyright (C) 2001 James LewisMoss <dres@debian.org> *
5  * Copyright (C) 2001 Linas Vepstas <linas@linas.org> *
6  * *
7  * This program is free software; you can redistribute it and/or *
8  * modify it under the terms of the GNU General Public License as *
9  * published by the Free Software Foundation; either version 2 of *
10  * the License, or (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License*
18  * along with this program; if not, contact: *
19  * *
20  * Free Software Foundation Voice: +1-617-542-5942 *
21  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
22  * Boston, MA 02110-1301, USA gnu@gnu.org *
23  * *
24 \********************************************************************/
25 #include <glib.h>
26 
27 #include <config.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include "qof.h"
31 
32 #include "gnc-xml-helper.h"
33 
34 #include "sixtp.h"
35 #include "sixtp-utils.h"
36 #include "sixtp-parsers.h"
37 #include "sixtp-utils.h"
38 #include "sixtp-dom-parsers.h"
39 #include "sixtp-dom-generators.h"
40 
41 #include "gnc-xml.h"
42 #include "io-gncxml-gen.h"
43 #include "io-gncxml-v2.h"
44 #include "io-utils.h"
45 
46 #include "sixtp-dom-parsers.h"
47 
48 /* non-static because it's used in io-gncxml-v2.c */
49 const gchar* gnc_v2_book_version_string = "2.0.0";
50 
51 /* ids */
52 #define gnc_book_string "gnc:book"
53 #define book_id_string "book:id"
54 #define book_slots_string "book:slots"
55 
56 static QofLogModule log_module = GNC_MOD_IO;
57 
58 /* ================================================================ */
59 
60 xmlNodePtr
61 gnc_book_dom_tree_create (QofBook* book)
62 {
63  xmlNodePtr ret;
64  G_GNUC_UNUSED gboolean allow_incompat = TRUE;
65 
66  ret = xmlNewNode (NULL, BAD_CAST gnc_book_string);
67  xmlSetProp (ret, BAD_CAST "version", BAD_CAST gnc_v2_book_version_string);
68 
69  xmlAddChild (ret, guid_to_dom_tree (book_id_string,
70  qof_book_get_guid (book)));
71 
72  /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */
73  xmlAddChild (ret, qof_instance_slots_to_dom_tree (book_slots_string,
74  QOF_INSTANCE (book)));
75 
76  return ret;
77 }
78 
79 /* ================================================================ */
80 /* same as above, but we write out directly. Only handle the guid
81  * and slots, everything else is handled elsewhere */
82 
83 gboolean
84 write_book_parts (FILE* out, QofBook* book)
85 {
86  xmlNodePtr domnode, slotsnode;
87 
88  domnode = guid_to_dom_tree (book_id_string, qof_book_get_guid (book));
89  xmlElemDump (out, NULL, domnode);
90  xmlFreeNode (domnode);
91 
92  if (ferror (out) || fprintf (out, "\n") < 0)
93  return FALSE;
94 
95 
96  slotsnode = qof_instance_slots_to_dom_tree (book_slots_string,
97  QOF_INSTANCE (book));
98  if (slotsnode)
99  {
100  xmlElemDump (out, NULL, slotsnode);
101  xmlFreeNode (slotsnode);
102 
103  if (ferror (out) || fprintf (out, "\n") < 0)
104  return FALSE;
105  }
106 
107  return TRUE;
108 }
109 
110 
111 /* ================================================================ */
112 
113 static gboolean
114 book_id_handler (xmlNodePtr node, gpointer book_pdata)
115 {
116  QofBook* book = static_cast<decltype (book)> (book_pdata);
117  GncGUID* guid;
118 
119  guid = dom_tree_to_guid (node);
120  qof_instance_set_guid (QOF_INSTANCE (book), guid);
121  guid_free (guid);
122 
123  return TRUE;
124 }
125 
126 static gboolean
127 book_slots_handler (xmlNodePtr node, gpointer book_pdata)
128 {
129  QofBook* book = static_cast<decltype (book)> (book_pdata);
130  gboolean success;
131 
132  /* the below works only because the get is guaranteed to return
133  * a frame, even if its empty */
134  success = dom_tree_create_instance_slots (node, QOF_INSTANCE (book));
135 
136  g_return_val_if_fail (success, FALSE);
137 
138  return TRUE;
139 }
140 
141 
142 static struct dom_tree_handler book_handlers_v2[] =
143 {
144  { book_id_string, book_id_handler, 1, 0 },
145  { book_slots_string, book_slots_handler, 0, 0 },
146  { NULL, 0, 0, 0 }
147 };
148 
149 static gboolean
150 gnc_book_end_handler (gpointer data_for_children,
151  GSList* data_from_children, GSList* sibling_data,
152  gpointer parent_data, gpointer global_data,
153  gpointer* result, const gchar* tag)
154 {
155  xmlNodePtr tree = (xmlNodePtr)data_for_children;
156  gxpf_data* gdata = (gxpf_data*)global_data;
157  QofBook* book = static_cast<decltype (book)> (gdata->bookdata);
158 
159 
160  if (parent_data) return TRUE;
161 
162  /* OK. For some messed up reason this is getting called again with a
163  NULL tag. So we ignore those cases */
164  if (!tag) return TRUE;
165 
166  g_return_val_if_fail (tree, FALSE);
167 
168  book = dom_tree_to_book (tree, book);
169  if (!book)
170  gdata->cb (tag, gdata->parsedata, book);
171 
172  xmlFreeNode (tree);
173 
174  return book != NULL;
175 }
176 
177 static gboolean
178 gnc_book_id_end_handler (gpointer data_for_children,
179  GSList* data_from_children, GSList* sibling_data,
180  gpointer parent_data, gpointer global_data,
181  gpointer* result, const gchar* tag)
182 {
183  gboolean successful;
184  xmlNodePtr tree = (xmlNodePtr)data_for_children;
185  gxpf_data* gdata = (gxpf_data*)global_data;
186  QofBook* book = static_cast<decltype (book)> (gdata->bookdata);
187 
188  if (parent_data) return TRUE;
189  if (!tag) return TRUE;
190 
191  g_return_val_if_fail (tree, FALSE);
192 
193  successful = book_id_handler (tree, book);
194  xmlFreeNode (tree);
195 
196  return successful;
197 }
198 
199 static gboolean
200 gnc_book_slots_end_handler (gpointer data_for_children,
201  GSList* data_from_children, GSList* sibling_data,
202  gpointer parent_data, gpointer global_data,
203  gpointer* result, const gchar* tag)
204 {
205  gboolean successful;
206  xmlNodePtr tree = (xmlNodePtr)data_for_children;
207  gxpf_data* gdata = (gxpf_data*)global_data;
208  QofBook* book = static_cast<decltype (book)> (gdata->bookdata);
209 
210  if (parent_data) return TRUE;
211  if (!tag) return TRUE;
212 
213  g_return_val_if_fail (tree, FALSE);
214 
215  successful = book_slots_handler (tree, book);
216  xmlFreeNode (tree);
217 
218  return successful;
219 }
220 
221 QofBook*
222 dom_tree_to_book (xmlNodePtr node, QofBook* book)
223 {
224  gboolean successful;
225 
226  successful = dom_tree_generic_parse (node, book_handlers_v2,
227  book);
228  if (!successful)
229  {
230  PERR ("failed to parse book");
231  book = NULL;
232  }
233 
234  return book;
235 }
236 
237 sixtp*
238 gnc_book_sixtp_parser_create (void)
239 {
240  return sixtp_dom_parser_new (gnc_book_end_handler, NULL, NULL);
241 }
242 
243 sixtp*
244 gnc_book_id_sixtp_parser_create (void)
245 {
246  return sixtp_dom_parser_new (gnc_book_id_end_handler, NULL, NULL);
247 }
248 
249 sixtp*
250 gnc_book_slots_sixtp_parser_create (void)
251 {
252  return sixtp_dom_parser_new (gnc_book_slots_end_handler, NULL, NULL);
253 }
Definition: sixtp.h:129
#define PERR(format, args...)
Log a serious error.
Definition: qoflog.h:244
api for GnuCash version 2 XML-based file format
#define qof_book_get_guid(X)
deprecated
Definition: qofbook.h:441
The type used to store guids in C.
Definition: guid.h:75