GnuCash  5.6-150-g038405b370+
gnc-recurrence-xml-v2.cpp
1 /*
2  * gnc-recurrence-xml-v2.c -- xml routines for Recurrence
3  *
4  * Copyright (C) 2005 Chris Shoemaker <c.shoemaker@cox.net>
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 #include <glib.h>
24 
25 #include <config.h>
26 #include <string.h>
27 #include "qof.h"
28 #include "Recurrence.h"
29 
30 #include "gnc-xml.h"
31 #include "gnc-xml-helper.h"
32 
33 #include "sixtp.h"
34 #include "sixtp-utils.h"
35 #include "sixtp-parsers.h"
36 #include "sixtp-utils.h"
37 #include "sixtp-dom-parsers.h"
38 #include "sixtp-dom-generators.h"
39 #include "io-gncxml-v2.h"
40 
41 static QofLogModule log_module = GNC_MOD_IO;
42 
43 const gchar* recurrence_version_string = "1.0.0";
44 #define recurrence_root "gnc:recurrence"
45 #define recurrence_mult "recurrence:mult"
46 #define recurrence_period_type "recurrence:period_type"
47 #define recurrence_start "recurrence:start"
48 #define recurrence_weekend_adj "recurrence:weekend_adj"
49 
50 //TODO: I think three of these functions rightly belong in Recurrence.c.
51 
52 static gboolean
53 recurrence_period_type_handler (xmlNodePtr node, gpointer d)
54 {
55  PeriodType pt;
56  char* nodeTxt;
57 
58  nodeTxt = dom_tree_to_text (node);
59  g_return_val_if_fail (nodeTxt, FALSE);
60  pt = recurrencePeriodTypeFromString (nodeTxt);
61  ((Recurrence*) d)->ptype = pt;
62  g_free (nodeTxt);
63  return (pt != -1);
64 }
65 
66 static gboolean
67 recurrence_start_date_handler (xmlNodePtr node, gpointer r)
68 {
69  GDate* d;
70 
71  d = dom_tree_to_gdate (node);
72  g_return_val_if_fail (d, FALSE);
73  g_return_val_if_fail (g_date_valid (d), FALSE);
74  ((Recurrence*) r)->start = *d;
75  g_date_free (d);
76  return TRUE;
77 }
78 
79 static gboolean
80 recurrence_mult_handler (xmlNodePtr node, gpointer r)
81 {
82  return dom_tree_to_guint16 (node, & ((Recurrence*)r)->mult);
83 }
84 
85 static gboolean
86 recurrence_weekend_adj_handler (xmlNodePtr node, gpointer d)
87 {
88  WeekendAdjust wadj;
89  char* nodeTxt;
90 
91  nodeTxt = dom_tree_to_text (node);
92  g_return_val_if_fail (nodeTxt, FALSE);
93  wadj = recurrenceWeekendAdjustFromString (nodeTxt);
94  ((Recurrence*) d)->wadj = wadj;
95  g_free (nodeTxt);
96  return (wadj != -1);
97 }
98 
99 static struct dom_tree_handler recurrence_dom_handlers[] =
100 {
101  { recurrence_mult, recurrence_mult_handler, 1, 0 },
102  { recurrence_period_type, recurrence_period_type_handler, 1, 0 },
103  { recurrence_start, recurrence_start_date_handler, 1, 0 },
104  { recurrence_weekend_adj, recurrence_weekend_adj_handler, 0, 0 },
105  { NULL, NULL, 0, 0 }
106 };
107 
108 Recurrence*
109 dom_tree_to_recurrence (xmlNodePtr node)
110 {
111  gboolean successful;
112  Recurrence* r;
113 
114  r = g_new (Recurrence, 1);
115  /* In case the file doesn't have a weekend adjustment element */
116  r->wadj = WEEKEND_ADJ_NONE;
117  successful = dom_tree_generic_parse (node, recurrence_dom_handlers, r);
118  if (!successful)
119  {
120  PERR ("failed to parse recurrence node");
121  xmlElemDump (stdout, NULL, node);
122  g_free (r);
123  r = NULL;
124  }
125  return r;
126 }
127 
128 xmlNodePtr
129 recurrence_to_dom_tree (const gchar* tag, const Recurrence* r)
130 {
131  xmlNodePtr n;
132  PeriodType pt;
133  GDate d;
134  WeekendAdjust wadj;
135 
136  n = xmlNewNode (NULL, BAD_CAST tag);
137  xmlSetProp (n, BAD_CAST "version", BAD_CAST recurrence_version_string);
138  xmlAddChild (n, guint_to_dom_tree (recurrence_mult,
139  recurrenceGetMultiplier (r)));
140  pt = recurrenceGetPeriodType (r);
141  xmlAddChild (n, text_to_dom_tree (recurrence_period_type,
142  recurrencePeriodTypeToString (pt)));
143  d = recurrenceGetDate (r);
144  xmlAddChild (n, gdate_to_dom_tree (recurrence_start, &d));
145  wadj = recurrenceGetWeekendAdjust (r);
146  if (wadj != WEEKEND_ADJ_NONE)
147  {
148  /* In r17725 and r17751, I introduced this extra XML child
149  element, but this means a gnucash-2.2.x cannot read the SX
150  recurrence of a >=2.3.x file anymore, which is bad. In order
151  to improve this broken backward compatibility for most of the
152  cases, we don't write out this XML element as long as it is
153  only "none". */
154  xmlAddChild (n, text_to_dom_tree (recurrence_weekend_adj,
155  recurrenceWeekendAdjustToString (wadj)));
156  }
157  return n;
158 }
#define PERR(format, args...)
Log a serious error.
Definition: qoflog.h:244
api for GnuCash version 2 XML-based file format