GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sixtp-dom-generators.c
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 [email protected] *
21  * *
22  ********************************************************************/
23 
24 #define __EXTENSIONS__
25 
26 #include "config.h"
27 #include <glib.h>
28 
29 #include "gnc-xml-helper.h"
30 #include <gnc-date.h>
31 
32 #include "sixtp-dom-generators.h"
33 #include "sixtp-utils.h"
34 
35 static QofLogModule log_module = GNC_MOD_IO;
36 
37 xmlNodePtr
38 boolean_to_dom_tree(const char* tag, gboolean val)
39 {
40  return text_to_dom_tree(tag, val ? "TRUE" : "FALSE");
41 }
42 
43 xmlNodePtr
44 text_to_dom_tree(const char *tag, const char *str)
45 {
46  xmlNodePtr result;
47  gchar *newstr = g_strdup (str);
48  g_return_val_if_fail(tag, NULL);
49  g_return_val_if_fail(str, NULL);
50  result = xmlNewNode(NULL, BAD_CAST tag);
51  g_return_val_if_fail(result, NULL);
52  xmlNodeAddContent(result, checked_char_cast (newstr));
53  g_free (newstr);
54  return result;
55 }
56 
57 xmlNodePtr
58 int_to_dom_tree(const char *tag, gint64 val)
59 {
60  gchar *text;
61  xmlNodePtr result;
62 
63  text = g_strdup_printf("%" G_GINT64_FORMAT, val);
64  g_return_val_if_fail(text, NULL);
65  result = text_to_dom_tree(tag, text);
66  g_free(text);
67  return result;
68 }
69 
70 xmlNodePtr
71 guint_to_dom_tree(const char *tag, guint an_int)
72 {
73  gchar *text;
74  xmlNodePtr result;
75 
76  text = g_strdup_printf("%u", an_int );
77  g_return_val_if_fail(text, NULL);
78  result = text_to_dom_tree(tag, text);
79  g_free(text);
80  return result;
81 }
82 
83 
84 xmlNodePtr
85 guid_to_dom_tree(const char *tag, const GncGUID* gid)
86 {
87  char guid_str[GUID_ENCODING_LENGTH + 1];
88  xmlNodePtr ret;
89 
90  ret = xmlNewNode(NULL, BAD_CAST tag);
91 
92  xmlSetProp(ret, BAD_CAST "type", BAD_CAST "guid");
93 
94  if (!guid_to_string_buff(gid, guid_str))
95  {
96  PERR("guid_to_string_buff failed\n");
97  return NULL;
98  }
99 
100  xmlNodeAddContent(ret, BAD_CAST guid_str);
101 
102  return ret;
103 }
104 
105 xmlNodePtr
106 commodity_ref_to_dom_tree(const char *tag, const gnc_commodity *c)
107 {
108  xmlNodePtr ret;
109  gchar *name_space, *mnemonic;
110 
111  g_return_val_if_fail(c, NULL);
112 
113  ret = xmlNewNode(NULL, BAD_CAST tag);
114 
116  {
117  return NULL;
118  }
119  name_space = g_strdup (gnc_commodity_get_namespace_compat(c));
120  mnemonic = g_strdup (gnc_commodity_get_mnemonic(c));
121  xmlNewTextChild(ret, NULL, BAD_CAST "cmdty:space",
122  checked_char_cast (name_space));
123  xmlNewTextChild(ret, NULL, BAD_CAST "cmdty:id",
124  checked_char_cast (mnemonic));
125  g_free (name_space);
126  g_free (mnemonic);
127  return ret;
128 }
129 
130 /* gnc_g_date_time_new_from_timespec_local normalizes the timespec,
131  * but we want to serialize it un-normalized, so we make a partial
132  * copy.
133  */
134 gchar *
135 timespec_sec_to_string(const Timespec *ts)
136 {
137  gchar *time_string;
138  GDateTime *gdt;
139  Timespec sts = { ts->tv_sec, 0};
141  g_return_val_if_fail (gdt != NULL, NULL);
142  time_string = g_date_time_format (gdt, "%Y-%m-%d %H:%M:%S %z");
143  g_date_time_unref (gdt);
144  return time_string;
145 }
146 
147 gchar *
148 timespec_nsec_to_string(const Timespec *ts)
149 {
150  return g_strdup_printf("%ld", ts->tv_nsec);
151 }
152 
153 xmlNodePtr
154 timespec_to_dom_tree(const char *tag, const Timespec *spec)
155 {
156  xmlNodePtr ret;
157  gchar *date_str = NULL;
158  gchar *ns_str = NULL;
159 
160  g_return_val_if_fail(spec, NULL);
161 
162  date_str = timespec_sec_to_string(spec);
163 
164  if (!date_str)
165  {
166  return NULL;
167  }
168 
169  ret = xmlNewNode(NULL, BAD_CAST tag);
170 
171  xmlNewTextChild(ret, NULL, BAD_CAST "ts:date",
172  checked_char_cast (date_str));
173 
174  if (spec->tv_nsec > 0)
175  {
176  ns_str = timespec_nsec_to_string(spec);
177  if (ns_str)
178  {
179  xmlNewTextChild(ret, NULL, BAD_CAST "ts:ns",
180  checked_char_cast (ns_str));
181  }
182  }
183 
184  g_free(date_str);
185  if (ns_str)
186  {
187  g_free(ns_str);
188  }
189 
190  return ret;
191 }
192 
193 xmlNodePtr
194 gdate_to_dom_tree(const char *tag, const GDate *date)
195 {
196  xmlNodePtr ret;
197  gchar *date_str = NULL;
198 
199  g_return_val_if_fail(date, NULL);
200  date_str = g_new( gchar, 512 );
201 
202  g_date_strftime( date_str, 512, "%Y-%m-%d", date );
203 
204  ret = xmlNewNode(NULL, BAD_CAST tag);
205 
206  xmlNewTextChild(ret, NULL, BAD_CAST "gdate", checked_char_cast (date_str));
207 
208  g_free(date_str);
209 
210  return ret;
211 }
212 
213 xmlNodePtr
214 gnc_numeric_to_dom_tree(const char *tag, const gnc_numeric *num)
215 {
216  xmlNodePtr ret;
217  gchar *numstr;
218 
219  g_return_val_if_fail(num, NULL);
220 
221  numstr = gnc_numeric_to_string(*num);
222  g_return_val_if_fail(numstr, NULL);
223 
224  ret = xmlNewNode(NULL, BAD_CAST tag);
225 
226  xmlNodeAddContent(ret, checked_char_cast (numstr));
227 
228  g_free(numstr);
229 
230  return ret;
231 }
232 
233 gchar*
234 double_to_string(double value)
235 {
236  gchar *numstr;
237  numstr = g_strdup_printf ("%24.18g", value);
238 
239  if (!numstr)
240  {
241  return NULL;
242 
243  }
244  else
245  {
246  return g_strstrip(numstr);
247  }
248 }
249 
250 static void
251 add_text_to_node(xmlNodePtr node, gchar *type, gchar *val)
252 {
253  gchar *newtype = g_strdup (type);
254  gchar *newval = g_strdup (val);
255  xmlSetProp(node, BAD_CAST "type", checked_char_cast (type));
256  xmlNodeSetContent(node, checked_char_cast (val));
257  g_free (newtype);
258  g_free(newval);
259 }
260 
261 static void
262 add_kvp_slot(const char * key, KvpValue* value, xmlNodePtr node);
263 
264 static void
265 add_kvp_value_node(xmlNodePtr node, gchar *tag, KvpValue* val)
266 {
267  xmlNodePtr val_node;
268  kvp_value_t kvp_type;
269 
270  kvp_type = kvp_value_get_type(val);
271 
272  if (kvp_type == KVP_TYPE_STRING)
273  {
274  gchar *newstr = g_strdup (kvp_value_get_string(val));
275  val_node = xmlNewTextChild(node, NULL, BAD_CAST tag,
276  checked_char_cast (newstr));
277  g_free (newstr);
278  }
279  else if (kvp_type == KVP_TYPE_TIMESPEC)
280  val_node = NULL;
281  else if (kvp_type == KVP_TYPE_GDATE)
282  {
283  GDate d = kvp_value_get_gdate(val);
284  val_node = gdate_to_dom_tree(tag, &d);
285  xmlAddChild (node, val_node);
286  }
287  else
288  val_node = xmlNewTextChild(node, NULL, BAD_CAST tag, NULL);
289 
290  switch (kvp_value_get_type(val))
291  {
292  case KVP_TYPE_GINT64:
293  add_text_to_node(val_node, "integer",
294  g_strdup_printf("%" G_GINT64_FORMAT,
295  kvp_value_get_gint64(val)));
296  break;
297  case KVP_TYPE_DOUBLE:
298  add_text_to_node(val_node, "double",
299  double_to_string(kvp_value_get_double(val)));
300  break;
301  case KVP_TYPE_NUMERIC:
302  add_text_to_node(val_node, "numeric",
303  gnc_numeric_to_string(kvp_value_get_numeric(val)));
304  break;
305  case KVP_TYPE_STRING:
306  xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "string");
307  break;
308  case KVP_TYPE_GUID:
309  {
310  gchar guidstr[GUID_ENCODING_LENGTH+1];
312  add_text_to_node(val_node, "guid", guidstr);
313  break;
314  }
315  case KVP_TYPE_TIMESPEC:
316  {
317  Timespec ts = kvp_value_get_timespec (val);
318 
319  val_node = timespec_to_dom_tree (tag, &ts);
320  xmlSetProp (val_node, BAD_CAST "type", BAD_CAST "timespec");
321  xmlAddChild (node, val_node);
322  }
323  break;
324  case KVP_TYPE_GDATE:
325  xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "gdate");
326  break;
327  case KVP_TYPE_GLIST:
328  {
329  GList *cursor;
330 
331  xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "list");
332  for (cursor = kvp_value_get_glist(val); cursor; cursor = cursor->next)
333  {
334  KvpValue *val = (KvpValue*)cursor->data;
335  add_kvp_value_node(val_node, "slot:value", val);
336  }
337  }
338 
339  break;
340  case KVP_TYPE_FRAME:
341  {
342  KvpFrame *frame;
343  const char ** keys;
344  unsigned int i;
345 
346  xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "frame");
347 
348  frame = kvp_value_get_frame (val);
349  if (!frame)
350  break;
351 
352  keys = kvp_frame_get_keys(frame);
353  for (i = 0; keys[i]; ++i)
354  add_kvp_slot(keys[i], kvp_frame_get_value(frame, keys[i]), val_node);
355  g_free(keys);
356  }
357  break;
358  default:
359  break;
360  }
361 }
362 
363 static void
364 add_kvp_slot(const char * key, KvpValue* value, xmlNodePtr node)
365 {
366  xmlNodePtr slot_node;
367  gchar *newkey = g_strdup ((gchar*)key);
368  slot_node = xmlNewChild(node, NULL, BAD_CAST "slot", NULL);
369 
370  xmlNewTextChild(slot_node, NULL, BAD_CAST "slot:key",
371  checked_char_cast (newkey));
372  g_free (newkey);
373  add_kvp_value_node(slot_node, "slot:value", value);
374 }
375 
376 xmlNodePtr
377 kvp_frame_to_dom_tree(const char *tag, const KvpFrame *frame)
378 {
379  xmlNodePtr ret;
380  const char ** keys;
381  unsigned int i;
382 
383  if (!frame)
384  {
385  return NULL;
386  }
387 
388  ret = xmlNewNode(NULL, BAD_CAST tag);
389 
390  keys = kvp_frame_get_keys(frame);
391  for (i = 0; keys[i]; ++i)
392  add_kvp_slot(keys[i], kvp_frame_get_value(frame, keys[i]), ret);
393  g_free(keys);
394 
395  return ret;
396 }
397 
Date and Time handling routines.
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
const char * gnc_commodity_get_namespace_compat(const gnc_commodity *cm)
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
const char * gnc_commodity_get_namespace(const gnc_commodity *cm)
gchar * guid_to_string_buff(const GncGUID *guid, gchar *buff)
gchar * gnc_numeric_to_string(gnc_numeric n)
#define PERR(format, args...)
Definition: qoflog.h:237
Definition: guid.h:65
gint64 kvp_value_get_gint64(const KvpValue *value)
char * kvp_value_get_string(const KvpValue *value)
#define GUID_ENCODING_LENGTH
Definition: guid.h:74
const char ** kvp_frame_get_keys(const KvpFrame *frame)
GList * kvp_value_get_glist(const KvpValue *value)
#define kvp_value_t
Definition: kvp_frame.h:113
GncGUID * kvp_value_get_guid(const KvpValue *value)
GDateTime * gnc_g_date_time_new_from_timespec_local(Timespec tm)
Create a GDateTime from a Timespec.
struct KvpFrameImpl KvpFrame
Definition: kvp_frame.h:76
GDate kvp_value_get_gdate(const KvpValue *value)
KvpFrame * kvp_value_get_frame(const KvpValue *value)
struct KvpValueImpl KvpValue
Definition: kvp_frame.h:80
const gchar * QofLogModule
Definition: qofid.h:89