SHOGUN  3.2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SerializableXmlFile.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2010 Soeren Sonnenburg
8  * Copyright (C) 2010 Berlin Institute of Technology
9  */
10 
11 #include <shogun/lib/config.h>
12 #ifdef HAVE_XML
13 
16 
17 #define STR_ROOT_NAME_00 \
18  "_SHOGUN_SERIALIZABLE_XML_FILE_V_00_"
19 
20 using namespace shogun;
21 
22 CSerializableXmlFile::CSerializableXmlFile()
23  :CSerializableFile() { init(false); }
24 
25 CSerializableXmlFile::CSerializableXmlFile(const char* fname, char rw,
26  bool format)
28 {
29  CSerializableFile::init(NULL, rw, fname);
30  init(format);
31 }
32 
33 CSerializableXmlFile::~CSerializableXmlFile()
34 {
35  close();
36 }
37 
39 CSerializableXmlFile::new_reader(char* dest_version, size_t n)
40 {
41  xmlChar* name;
42 
43  if ((name = xmlGetNodePath(m_stack_stream.back())) == NULL)
44  return NULL;
45 
46  strncpy(dest_version, (const char*) (name+1), n);
47  xmlFree(name);
48 
49  if (strcmp(STR_ROOT_NAME_00, dest_version) == 0)
50  return new SerializableXmlReader00(this);
51 
52  return NULL;
53 }
54 
55 bool
56 CSerializableXmlFile::push_node(const xmlChar* name)
57 {
58  xmlNode* node
59  = xmlNewChild(m_stack_stream.back(), NULL, name, NULL);
60 
61  m_stack_stream.push_back(node);
62 
63  return node != NULL;
64 }
65 
66 bool
67 CSerializableXmlFile::join_node(const xmlChar* name)
68 {
69  for (xmlNode* cur=m_stack_stream.back()->children; cur!=NULL;
70  cur=cur->next) {
71  if (cur->type != XML_ELEMENT_NODE
72  || xmlStrcmp(cur->name, name) != 0) continue;
73 
74  m_stack_stream.push_back(cur);
75  return true;
76  }
77 
78  return false;
79 }
80 
81 bool
82 CSerializableXmlFile::next_node(const xmlChar* name)
83 {
84  for (xmlNode* cur=m_stack_stream.back()->next; cur!=NULL;
85  cur=cur->next) {
86  if (cur->type != XML_ELEMENT_NODE
87  || xmlStrcmp(cur->name, name) != 0) continue;
88 
89  pop_node();
90  m_stack_stream.push_back(cur);
91  return true;
92  }
93 
94  return false;
95 }
96 
97 void
98 CSerializableXmlFile::pop_node()
99 {
100  m_stack_stream.pop_back();
101 }
102 
103 void
104 CSerializableXmlFile::init(bool format)
105 {
106  m_format = format, m_doc = NULL;
107 
108  LIBXML_TEST_VERSION;
109 
110  if (m_filename == NULL || *m_filename == '\0') {
111  SG_WARNING("Filename not given for opening file!\n")
112  close(); return;
113  }
114 
115  SG_DEBUG("Opening '%s'\n", m_filename)
116 
117  xmlNode* tmp;
118  switch (m_task) {
119  case 'r':
120  if ((m_doc = xmlReadFile(m_filename, NULL, XML_PARSE_HUGE | XML_PARSE_NONET)) == NULL
121  || (tmp = xmlDocGetRootElement(m_doc)) == NULL)
122  {
123  SG_WARNING("Could not open file `%s' for reading!\n", m_filename)
124  close(); return;
125  }
126  m_stack_stream.push_back(tmp);
127  break;
128  case 'w':
129  m_doc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
130  m_stack_stream.push_back(xmlNewNode(
131  NULL, BAD_CAST STR_ROOT_NAME_00));
132  xmlDocSetRootElement(m_doc, m_stack_stream.back());
133  break;
134  default:
135  SG_WARNING("Could not open file `%s', unknown mode!\n",
136  m_filename);
137  close(); return;
138  }
139 }
140 
141 void
142 CSerializableXmlFile::close()
143 {
144  while (m_stack_stream.get_num_elements() > 0) pop_node();
145 
146  if (is_opened()) {
147  if (m_task == 'w'
148  && xmlSaveFormatFileEnc(m_filename, m_doc, "UTF-8",
149  m_format) < 0) {
150  SG_WARNING("Could not close file `%s' for writing!\n",
151  m_filename);
152  }
153 
154  xmlFreeDoc(m_doc); m_doc = NULL;
155  xmlCleanupParser();
156  }
157 }
158 
159 bool
160 CSerializableXmlFile::is_opened()
161 {
162  return m_doc != NULL;
163 }
164 
165 bool
166 CSerializableXmlFile::write_scalar_wrapped(
167  const TSGDataType* type, const void* param)
168 {
169  string_t buf;
170 
171  switch (type->m_ptype) {
172  case PT_BOOL:
173  if (snprintf(buf, STRING_LEN, "%s", *(bool*) param? STR_TRUE
174  : STR_FALSE) <= 0) return false;
175  break;
176  case PT_CHAR:
177  if (snprintf(buf, STRING_LEN, "%c", *(char*) param
178  ) <= 0) return false;
179  break;
180  case PT_INT8:
181  if (snprintf(buf, STRING_LEN, "%" PRIi8, *(int8_t*) param
182  ) <= 0) return false;
183  break;
184  case PT_UINT8:
185  if (snprintf(buf, STRING_LEN, "%" PRIu8, *(uint8_t*) param
186  ) <= 0) return false;
187  break;
188  case PT_INT16:
189  if (snprintf(buf, STRING_LEN, "%" PRIi16, *(int16_t*) param
190  ) <= 0) return false;
191  break;
192  case PT_UINT16:
193  if (snprintf(buf, STRING_LEN, "%" PRIu16, *(uint16_t*) param
194  ) <= 0) return false;
195  break;
196  case PT_INT32:
197  if (snprintf(buf, STRING_LEN, "%" PRIi32, *(int32_t*) param
198  ) <= 0) return false;
199  break;
200  case PT_UINT32:
201  if (snprintf(buf, STRING_LEN, "%" PRIu32, *(uint32_t*) param
202  ) <= 0) return false;
203  break;
204  case PT_INT64:
205  if (snprintf(buf, STRING_LEN, "%" PRIi64, *(int64_t*) param
206  ) <= 0) return false;
207  break;
208  case PT_UINT64:
209  if (snprintf(buf, STRING_LEN, "%" PRIu64, *(uint64_t*) param
210  ) <= 0) return false;
211  break;
212  case PT_FLOAT32:
213  if (snprintf(buf, STRING_LEN, "%.16g", *(float32_t*) param
214  ) <= 0) return false;
215  break;
216  case PT_FLOAT64:
217  if (snprintf(buf, STRING_LEN, "%.16lg", *(float64_t*) param
218  ) <= 0) return false;
219  break;
220  case PT_FLOATMAX:
221  if (snprintf(buf, STRING_LEN, "%.16Lg", *(floatmax_t*)
222  param) <= 0) return false;
223  break;
224  case PT_COMPLEX128:
225  if (snprintf(buf, STRING_LEN, "(%.16lg,%.16lg)",
226  ((complex128_t*) param)->real(),((complex128_t*) param)->imag()
227  ) <= 0) return false;
228  break;
229  case PT_UNDEFINED:
230  case PT_SGOBJECT:
231  SG_ERROR("write_scalar_wrapped(): Implementation error during"
232  " writing XmlFile!");
233  return false;
234  }
235 
236  xmlNodeAddContent(m_stack_stream.back(), BAD_CAST buf);
237  return true;
238 }
239 
240 bool
241 CSerializableXmlFile::write_cont_begin_wrapped(
242  const TSGDataType* type, index_t len_real_y, index_t len_real_x)
243 {
244  return true;
245 }
246 
247 bool
248 CSerializableXmlFile::write_cont_end_wrapped(
249  const TSGDataType* type, index_t len_real_y, index_t len_real_x)
250 {
251  if (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX)
252  if (len_real_y*len_real_x>0)
253  pop_node();
254 
255  return true;
256 }
257 
258 bool
259 CSerializableXmlFile::write_string_begin_wrapped(
260  const TSGDataType* type, index_t length)
261 {
262  return true;
263 }
264 
265 bool
266 CSerializableXmlFile::write_string_end_wrapped(
267  const TSGDataType* type, index_t length)
268 {
269  return true;
270 }
271 
272 bool
273 CSerializableXmlFile::write_stringentry_begin_wrapped(
274  const TSGDataType* type, index_t y)
275 {
276  if (!push_node(BAD_CAST STR_STRING)) return false;
277 
278  return true;
279 }
280 
281 bool
282 CSerializableXmlFile::write_stringentry_end_wrapped(
283  const TSGDataType* type, index_t y)
284 {
285  pop_node();
286 
287  return true;
288 }
289 
290 bool
291 CSerializableXmlFile::write_sparse_begin_wrapped(
292  const TSGDataType* type, index_t length)
293 {
294  return true;
295 }
296 
297 bool
298 CSerializableXmlFile::write_sparse_end_wrapped(
299  const TSGDataType* type, index_t length)
300 {
301  return true;
302 }
303 
304 bool
305 CSerializableXmlFile::write_sparseentry_begin_wrapped(
306  const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
307  index_t feat_index, index_t y)
308 {
309  push_node(BAD_CAST STR_SPARSE);
310 
311  string_t buf;
312  snprintf(buf, STRING_LEN, "%" PRIi32, feat_index);
313  if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_FEATINDEX,
314  BAD_CAST buf) == NULL) return false;
315  return true;
316 }
317 
318 bool
319 CSerializableXmlFile::write_sparseentry_end_wrapped(
320  const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
321  index_t feat_index, index_t y)
322 {
323  pop_node();
324 
325  return true;
326 }
327 
328 bool
329 CSerializableXmlFile::write_item_begin_wrapped(
330  const TSGDataType* type, index_t y, index_t x)
331 {
332  if (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX) {
333  if (y==0)
334  {
335  if (x != 0) pop_node();
336 
337  string_t buf_x; snprintf(buf_x, STRING_LEN, "x%" PRIi32, x);
338  if (!push_node(BAD_CAST buf_x)) return false;
339  }
340  }
341 
342  push_node(BAD_CAST STR_ITEM);
343 
344  return true;
345 }
346 
347 bool
348 CSerializableXmlFile::write_item_end_wrapped(
349  const TSGDataType* type, index_t y, index_t x)
350 {
351  pop_node();
352 
353  return true;
354 }
355 
356 bool
357 CSerializableXmlFile::write_sgserializable_begin_wrapped(
358  const TSGDataType* type, const char* sgserializable_name,
359  EPrimitiveType generic)
360 {
361  if (*sgserializable_name == '\0') {
362  if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_IS_NULL,
363  BAD_CAST STR_TRUE) == NULL) return false;
364  return true;
365  }
366 
367  if (xmlNewProp(m_stack_stream.back(),
368  BAD_CAST STR_PROP_INSTANCE_NAME,
369  BAD_CAST sgserializable_name) == NULL) return false;
370 
371  if (generic != PT_NOT_GENERIC) {
372  string_t buf;
374  if (xmlNewProp(m_stack_stream.back(),
375  BAD_CAST STR_PROP_GENERIC_NAME, BAD_CAST buf)
376  == NULL) return false;
377  }
378 
379  return true;
380 }
381 
382 bool
383 CSerializableXmlFile::write_sgserializable_end_wrapped(
384  const TSGDataType* type, const char* sgserializable_name,
385  EPrimitiveType generic)
386 {
387  return true;
388 }
389 
390 bool
391 CSerializableXmlFile::write_type_begin_wrapped(
392  const TSGDataType* type, const char* name, const char* prefix)
393 {
394  if (!push_node(BAD_CAST name)) return false;
395 
397 
398  string_t buf;
399  type->to_string(buf, STRING_LEN);
400  if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_TYPE,
401  BAD_CAST buf) == NULL) return false;
402 
403  return true;
404 }
405 
406 bool
407 CSerializableXmlFile::write_type_end_wrapped(
408  const TSGDataType* type, const char* name, const char* prefix)
409 {
410  pop_node();
411 
413 
414  return true;
415 }
416 
417 #endif /* HAVE_XML */

SHOGUN Machine Learning Toolbox - Documentation