GnuCash  5.6-150-g038405b370+
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
sixtp-dom-generators.cpp
1 /********************************************************************
2  * sixtp-dom-generators.c *
3  * Copyright 2001 Gnumatic, Inc. *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License*
16  * along with this program; if not, contact: *
17  * *
18  * Free Software Foundation Voice: +1-617-542-5942 *
19  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
20  * Boston, MA 02110-1301, USA gnu@gnu.org *
21  * *
22  ********************************************************************/
23 #include <glib.h>
24 #include <config.h>
25 
26 #include <gnc-date.h>
27 #include <cstdint>
28 
29 #include "gnc-xml-helper.h"
30 #include "sixtp-dom-generators.h"
31 #include "sixtp-utils.h"
32 
33 #include <kvp-frame.hpp>
34 #include <gnc-datetime.hpp>
35 
36 static QofLogModule log_module = GNC_MOD_IO;
37 
38 xmlNodePtr
39 boolean_to_dom_tree (const char* tag, gboolean val)
40 {
41  return text_to_dom_tree (tag, val ? "TRUE" : "FALSE");
42 }
43 
44 xmlNodePtr
45 text_to_dom_tree (const char* tag, const char* str)
46 {
47  g_return_val_if_fail (tag, NULL);
48  g_return_val_if_fail (str, NULL);
49 
50  xmlNodePtr result = xmlNewNode (NULL, BAD_CAST tag);
51  g_return_val_if_fail (result, NULL);
52 
53  gchar* newstr = g_strdup (str);
54  xmlNodeAddContent (result, checked_char_cast (newstr));
55  g_free (newstr);
56 
57  return result;
58 }
59 
60 xmlNodePtr
61 int_to_dom_tree (const char* tag, gint64 val)
62 {
63  gchar* text;
64  xmlNodePtr result;
65 
66  text = g_strdup_printf ("%" G_GINT64_FORMAT, val);
67  g_return_val_if_fail (text, NULL);
68  result = text_to_dom_tree (tag, text);
69  g_free (text);
70  return result;
71 }
72 
73 xmlNodePtr
74 guint_to_dom_tree (const char* tag, guint an_int)
75 {
76  gchar* text;
77  xmlNodePtr result;
78 
79  text = g_strdup_printf ("%u", an_int);
80  g_return_val_if_fail (text, NULL);
81  result = text_to_dom_tree (tag, text);
82  g_free (text);
83  return result;
84 }
85 
86 
87 xmlNodePtr
88 guid_to_dom_tree (const char* tag, const GncGUID* gid)
89 {
90  char guid_str[GUID_ENCODING_LENGTH + 1];
91  xmlNodePtr ret;
92 
93  ret = xmlNewNode (NULL, BAD_CAST tag);
94 
95  xmlSetProp (ret, BAD_CAST "type", BAD_CAST "guid");
96 
97  if (!guid_to_string_buff (gid, guid_str))
98  {
99  PERR ("guid_to_string_buff failed\n");
100  return NULL;
101  }
102 
103  xmlNodeAddContent (ret, BAD_CAST guid_str);
104 
105  return ret;
106 }
107 
108 xmlNodePtr
109 commodity_ref_to_dom_tree (const char* tag, const gnc_commodity* c)
110 {
111  xmlNodePtr ret;
112  gchar* name_space, *mnemonic;
113 
114  g_return_val_if_fail (c, NULL);
115 
116  ret = xmlNewNode (NULL, BAD_CAST tag);
117 
119  {
120  return NULL;
121  }
122  name_space = g_strdup (gnc_commodity_get_namespace (c));
123  mnemonic = g_strdup (gnc_commodity_get_mnemonic (c));
124  xmlNewTextChild (ret, NULL, BAD_CAST "cmdty:space",
125  checked_char_cast (name_space));
126  xmlNewTextChild (ret, NULL, BAD_CAST "cmdty:id",
127  checked_char_cast (mnemonic));
128  g_free (name_space);
129  g_free (mnemonic);
130  return ret;
131 }
132 
133 xmlNodePtr
134 time64_to_dom_tree (const char* tag, const time64 time)
135 {
136  xmlNodePtr ret;
137  g_return_val_if_fail (time != INT64_MAX, NULL);
138  auto date_str = GncDateTime(time).format_iso8601();
139  if (date_str.empty())
140  return NULL;
141  date_str += " +0000"; //Tack on a UTC offset to mollify GnuCash for Android
142  ret = xmlNewNode (NULL, BAD_CAST tag);
143  xmlNewTextChild (ret, NULL, BAD_CAST "ts:date",
144  checked_char_cast (const_cast<char*>(date_str.c_str())));
145  return ret;
146 }
147 
148 xmlNodePtr
149 gdate_to_dom_tree (const char* tag, const GDate* date)
150 {
151  xmlNodePtr ret;
152  gchar* date_str = NULL;
153 
154  g_return_val_if_fail (date, NULL);
155  date_str = g_new (gchar, 512);
156 
157  g_date_strftime (date_str, 512, "%Y-%m-%d", date);
158 
159  ret = xmlNewNode (NULL, BAD_CAST tag);
160 
161  xmlNewTextChild (ret, NULL, BAD_CAST "gdate", checked_char_cast (date_str));
162 
163  g_free (date_str);
164 
165  return ret;
166 }
167 
168 xmlNodePtr
169 gnc_numeric_to_dom_tree (const char* tag, const gnc_numeric* num)
170 {
171  xmlNodePtr ret;
172  gchar* numstr;
173 
174  g_return_val_if_fail (num, NULL);
175 
176  numstr = gnc_numeric_to_string (*num);
177  g_return_val_if_fail (numstr, NULL);
178 
179  ret = xmlNewNode (NULL, BAD_CAST tag);
180 
181  xmlNodeAddContent (ret, checked_char_cast (numstr));
182 
183  g_free (numstr);
184 
185  return ret;
186 }
187 
188 gchar*
189 double_to_string (double value)
190 {
191  gchar* numstr;
192  numstr = g_strdup_printf ("%24.18g", value);
193 
194  if (!numstr)
195  {
196  return NULL;
197 
198  }
199  else
200  {
201  return g_strstrip (numstr);
202  }
203 }
204 
205 static void
206 add_text_to_node (xmlNodePtr node, const gchar* type, gchar* val)
207 {
208  xmlSetProp (node, BAD_CAST "type", BAD_CAST type);
209  xmlNodeSetContent (node, checked_char_cast (val));
210 }
211 
212 static void add_kvp_slot (const char* key, KvpValue* value, void* data);
213 
214 static void
215 add_kvp_value_node (xmlNodePtr node, const gchar* tag, KvpValue* val)
216 {
217  xmlNodePtr val_node;
218 
219  switch (val->get_type ())
220  {
221  case KvpValue::Type::STRING:
222  {
223  auto newstr = g_strdup (val->get<const char*> ());
224  val_node = xmlNewTextChild (node, NULL, BAD_CAST tag,
225  checked_char_cast (newstr));
226  g_free (newstr);
227  break;
228  }
229  case KvpValue::Type::TIME64:
230  val_node = NULL;
231  break;
232  case KvpValue::Type::GDATE:
233  {
234  auto d = val->get<GDate> ();
235  val_node = gdate_to_dom_tree (tag, &d);
236  xmlAddChild (node, val_node);
237  break;
238  }
239  default:
240  val_node = xmlNewTextChild (node, NULL, BAD_CAST tag, NULL);
241  break;
242  }
243 
244  switch (val->get_type ())
245  {
246  case KvpValue::Type::INT64:
247  {
248  char *int_str = g_strdup_printf ("%" G_GINT64_FORMAT, val->get<int64_t> ());
249  add_text_to_node (val_node, "integer", int_str);
250  g_free (int_str);
251  break;
252  }
253  case KvpValue::Type::DOUBLE:
254  {
255  char *dbl_str = double_to_string (val->get<double> ());
256  add_text_to_node (val_node, "double", dbl_str);
257  g_free (dbl_str);
258  break;
259  }
260  case KvpValue::Type::NUMERIC:
261  {
262  char *num_str = gnc_numeric_to_string (val->get<gnc_numeric> ());
263  add_text_to_node (val_node, "numeric", num_str);
264  g_free (num_str);
265  break;
266  }
267  case KvpValue::Type::STRING:
268  xmlSetProp (val_node, BAD_CAST "type", BAD_CAST "string");
269  break;
270  case KvpValue::Type::GUID:
271  {
272  gchar guidstr[GUID_ENCODING_LENGTH + 1];
273  guid_to_string_buff (val->get<GncGUID*> (), guidstr);
274  add_text_to_node (val_node, "guid", guidstr);
275  break;
276  }
277  /* Note: The type attribute must remain 'timespec' to maintain
278  * compatibility.
279  */
280  case KvpValue::Type::TIME64:
281  {
282  auto t = val->get<Time64> ();
283  val_node = time64_to_dom_tree (tag, t.t);
284  xmlSetProp (val_node, BAD_CAST "type", BAD_CAST "timespec");
285  xmlAddChild (node, val_node);
286  break;
287  }
288  case KvpValue::Type::GDATE:
289  xmlSetProp (val_node, BAD_CAST "type", BAD_CAST "gdate");
290  break;
291  case KvpValue::Type::GLIST:
292  xmlSetProp (val_node, BAD_CAST "type", BAD_CAST "list");
293  for (auto cursor = val->get<GList*> (); cursor; cursor = cursor->next)
294  {
295  auto val = static_cast<KvpValue*> (cursor->data);
296  add_kvp_value_node (val_node, "slot:value", val);
297  }
298  break;
299  case KvpValue::Type::FRAME:
300  {
301  xmlSetProp (val_node, BAD_CAST "type", BAD_CAST "frame");
302 
303  auto frame = val->get<KvpFrame*> ();
304  if (!frame)
305  break;
306  frame->for_each_slot_temp (&add_kvp_slot, val_node);
307  break;
308  }
309  default:
310  break;
311  }
312 }
313 
314 static void
315 add_kvp_slot (const char* key, KvpValue* value, void* data)
316 {
317  auto newkey = g_strdup ((gchar*)key);
318  auto node = static_cast<xmlNodePtr> (data);
319  auto slot_node = xmlNewChild (node, NULL, BAD_CAST "slot", NULL);
320 
321  xmlNewTextChild (slot_node, NULL, BAD_CAST "slot:key",
322  checked_char_cast (newkey));
323  g_free (newkey);
324  add_kvp_value_node (slot_node, "slot:value", value);
325 }
326 
327 xmlNodePtr
328 qof_instance_slots_to_dom_tree (const char* tag, const QofInstance* inst)
329 {
330  xmlNodePtr ret;
331  KvpFrame* frame = qof_instance_get_slots (inst);
332  if (!frame || frame->empty())
333  return nullptr;
334 
335  ret = xmlNewNode (nullptr, BAD_CAST tag);
336  frame->for_each_slot_temp (&add_kvp_slot, ret);
337  return ret;
338 }
std::string format_iso8601() const
Format the GncDateTime into a gnucash-style iso8601 string in UTC.
GnuCash DateTime class.
Date and Time handling routines.
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
const char * gnc_commodity_get_namespace(const gnc_commodity *cm)
Retrieve the namespace for the specified commodity.
gchar * guid_to_string_buff(const GncGUID *guid, gchar *str)
The guid_to_string_buff() routine puts a null-terminated string encoding of the id into the memory po...
Definition: guid.cpp:173
gchar * gnc_numeric_to_string(gnc_numeric n)
Convert to string.
#define PERR(format, args...)
Log a serious error.
Definition: qoflog.h:244
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
Definition: guid.h:84
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition: gnc-date.h:87
The type used to store guids in C.
Definition: guid.h:75