GnuCash c935c2f+
Loading...
Searching...
No Matches
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
36static QofLogModule log_module = GNC_MOD_IO;
37
38xmlNodePtr
39boolean_to_dom_tree (const char* tag, gboolean val)
40{
41 return text_to_dom_tree (tag, val ? "TRUE" : "FALSE");
42}
43
44xmlNodePtr
45text_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
60xmlNodePtr
61int_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
73xmlNodePtr
74guint_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
87xmlNodePtr
88guid_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
108xmlNodePtr
109commodity_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
133xmlNodePtr
134time64_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
148xmlNodePtr
149gdate_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
168xmlNodePtr
169gnc_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
188gchar*
189double_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
205static void
206add_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
212static void add_kvp_slot (const char* key, KvpValue* value, void* data);
213
214static void
215add_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
314static void
315add_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
327xmlNodePtr
328qof_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}
GnuCash DateTime class.
std::string format_iso8601() const
Format the GncDateTime into a gnucash-style iso8601 string in UTC.
Date and Time handling routines.
const char * gnc_commodity_get_namespace(const gnc_commodity *cm)
Retrieve the namespace for the specified commodity.
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition gnc-date.h:87
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
Definition guid.h:84
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:208
#define PERR(format, args...)
Log a serious error.
Definition qoflog.h:244
gchar * gnc_numeric_to_string(gnc_numeric n)
Convert to string.
The type used to store guids in C.
Definition guid.h:75