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

SHOGUN Machine Learning Toolbox - Documentation