SHOGUN  v3.0.0
 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_SGOBJECT:
230  SG_ERROR("write_scalar_wrapped(): Implementation error during"
231  " writing XmlFile!");
232  return false;
233  }
234 
235  xmlNodeAddContent(m_stack_stream.back(), BAD_CAST buf);
236  return true;
237 }
238 
239 bool
240 CSerializableXmlFile::write_cont_begin_wrapped(
241  const TSGDataType* type, index_t len_real_y, index_t len_real_x)
242 {
243  return true;
244 }
245 
246 bool
247 CSerializableXmlFile::write_cont_end_wrapped(
248  const TSGDataType* type, index_t len_real_y, index_t len_real_x)
249 {
250  if (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX)
251  if (len_real_y*len_real_x>0)
252  pop_node();
253 
254  return true;
255 }
256 
257 bool
258 CSerializableXmlFile::write_string_begin_wrapped(
259  const TSGDataType* type, index_t length)
260 {
261  return true;
262 }
263 
264 bool
265 CSerializableXmlFile::write_string_end_wrapped(
266  const TSGDataType* type, index_t length)
267 {
268  return true;
269 }
270 
271 bool
272 CSerializableXmlFile::write_stringentry_begin_wrapped(
273  const TSGDataType* type, index_t y)
274 {
275  if (!push_node(BAD_CAST STR_STRING)) return false;
276 
277  return true;
278 }
279 
280 bool
281 CSerializableXmlFile::write_stringentry_end_wrapped(
282  const TSGDataType* type, index_t y)
283 {
284  pop_node();
285 
286  return true;
287 }
288 
289 bool
290 CSerializableXmlFile::write_sparse_begin_wrapped(
291  const TSGDataType* type, index_t length)
292 {
293  return true;
294 }
295 
296 bool
297 CSerializableXmlFile::write_sparse_end_wrapped(
298  const TSGDataType* type, index_t length)
299 {
300  return true;
301 }
302 
303 bool
304 CSerializableXmlFile::write_sparseentry_begin_wrapped(
305  const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
306  index_t feat_index, index_t y)
307 {
308  push_node(BAD_CAST STR_SPARSE);
309 
310  string_t buf;
311  snprintf(buf, STRING_LEN, "%" PRIi32, feat_index);
312  if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_FEATINDEX,
313  BAD_CAST buf) == NULL) return false;
314  return true;
315 }
316 
317 bool
318 CSerializableXmlFile::write_sparseentry_end_wrapped(
319  const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
320  index_t feat_index, index_t y)
321 {
322  pop_node();
323 
324  return true;
325 }
326 
327 bool
328 CSerializableXmlFile::write_item_begin_wrapped(
329  const TSGDataType* type, index_t y, index_t x)
330 {
331  if (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX) {
332  if (y==0)
333  {
334  if (x != 0) pop_node();
335 
336  string_t buf_x; snprintf(buf_x, STRING_LEN, "x%" PRIi32, x);
337  if (!push_node(BAD_CAST buf_x)) return false;
338  }
339  }
340 
341  push_node(BAD_CAST STR_ITEM);
342 
343  return true;
344 }
345 
346 bool
347 CSerializableXmlFile::write_item_end_wrapped(
348  const TSGDataType* type, index_t y, index_t x)
349 {
350  pop_node();
351 
352  return true;
353 }
354 
355 bool
356 CSerializableXmlFile::write_sgserializable_begin_wrapped(
357  const TSGDataType* type, const char* sgserializable_name,
358  EPrimitiveType generic)
359 {
360  if (*sgserializable_name == '\0') {
361  if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_IS_NULL,
362  BAD_CAST STR_TRUE) == NULL) return false;
363  return true;
364  }
365 
366  if (xmlNewProp(m_stack_stream.back(),
367  BAD_CAST STR_PROP_INSTANCE_NAME,
368  BAD_CAST sgserializable_name) == NULL) return false;
369 
370  if (generic != PT_NOT_GENERIC) {
371  string_t buf;
373  if (xmlNewProp(m_stack_stream.back(),
374  BAD_CAST STR_PROP_GENERIC_NAME, BAD_CAST buf)
375  == NULL) return false;
376  }
377 
378  return true;
379 }
380 
381 bool
382 CSerializableXmlFile::write_sgserializable_end_wrapped(
383  const TSGDataType* type, const char* sgserializable_name,
384  EPrimitiveType generic)
385 {
386  return true;
387 }
388 
389 bool
390 CSerializableXmlFile::write_type_begin_wrapped(
391  const TSGDataType* type, const char* name, const char* prefix)
392 {
393  if (!push_node(BAD_CAST name)) return false;
394 
396 
397  string_t buf;
398  type->to_string(buf, STRING_LEN);
399  if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_TYPE,
400  BAD_CAST buf) == NULL) return false;
401 
402  return true;
403 }
404 
405 bool
406 CSerializableXmlFile::write_type_end_wrapped(
407  const TSGDataType* type, const char* name, const char* prefix)
408 {
409  pop_node();
410 
412 
413  return true;
414 }
415 
416 #endif /* HAVE_XML */

SHOGUN Machine Learning Toolbox - Documentation