00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <shogun/lib/config.h>
00012 #ifdef HAVE_XML
00013
00014 #include <shogun/io/SerializableXmlFile.h>
00015 #include <shogun/io/SerializableXmlReader00.h>
00016
00017 #define STR_ROOT_NAME_00 \
00018 "_SHOGUN_SERIALIZABLE_XML_FILE_V_00_"
00019
00020 using namespace shogun;
00021
00022 CSerializableXmlFile::CSerializableXmlFile()
00023 :CSerializableFile() { init(false); }
00024
00025 CSerializableXmlFile::CSerializableXmlFile(const char* fname, char rw,
00026 bool format)
00027 :CSerializableFile()
00028 {
00029 CSerializableFile::init(NULL, rw, fname);
00030 init(format);
00031 }
00032
00033 CSerializableXmlFile::~CSerializableXmlFile()
00034 {
00035 close();
00036 }
00037
00038 CSerializableFile::TSerializableReader*
00039 CSerializableXmlFile::new_reader(char* dest_version, size_t n)
00040 {
00041 xmlChar* name;
00042
00043 if ((name = xmlGetNodePath(m_stack_stream.back())) == NULL)
00044 return NULL;
00045
00046 strncpy(dest_version, (const char*) (name+1), n);
00047 xmlFree(name);
00048
00049 if (strcmp(STR_ROOT_NAME_00, dest_version) == 0)
00050 return new SerializableXmlReader00(this);
00051
00052 return NULL;
00053 }
00054
00055 bool
00056 CSerializableXmlFile::push_node(const xmlChar* name)
00057 {
00058 xmlNode* node
00059 = xmlNewChild(m_stack_stream.back(), NULL, name, NULL);
00060
00061 m_stack_stream.push_back(node);
00062
00063 return node != NULL;
00064 }
00065
00066 bool
00067 CSerializableXmlFile::join_node(const xmlChar* name)
00068 {
00069 for (xmlNode* cur=m_stack_stream.back()->children; cur!=NULL;
00070 cur=cur->next) {
00071 if (cur->type != XML_ELEMENT_NODE
00072 || xmlStrcmp(cur->name, name) != 0) continue;
00073
00074 m_stack_stream.push_back(cur);
00075 return true;
00076 }
00077
00078 return false;
00079 }
00080
00081 bool
00082 CSerializableXmlFile::next_node(const xmlChar* name)
00083 {
00084 for (xmlNode* cur=m_stack_stream.back()->next; cur!=NULL;
00085 cur=cur->next) {
00086 if (cur->type != XML_ELEMENT_NODE
00087 || xmlStrcmp(cur->name, name) != 0) continue;
00088
00089 pop_node();
00090 m_stack_stream.push_back(cur);
00091 return true;
00092 }
00093
00094 return false;
00095 }
00096
00097 void
00098 CSerializableXmlFile::pop_node()
00099 {
00100 m_stack_stream.pop_back();
00101 }
00102
00103 void
00104 CSerializableXmlFile::init(bool format)
00105 {
00106 m_format = format, m_doc = NULL;
00107
00108 LIBXML_TEST_VERSION;
00109
00110 if (m_filename == NULL || *m_filename == '\0') {
00111 SG_WARNING("Filename not given for opening file!\n");
00112 close(); return;
00113 }
00114
00115 SG_DEBUG("Opening '%s'\n", m_filename);
00116
00117 xmlNode* tmp;
00118 switch (m_task) {
00119 case 'r':
00120 if ((m_doc = xmlReadFile(m_filename, NULL, XML_PARSE_HUGE | XML_PARSE_NONET)) == NULL
00121 || (tmp = xmlDocGetRootElement(m_doc)) == NULL)
00122 {
00123 SG_WARNING("Could not open file `%s' for reading!\n", m_filename);
00124 close(); return;
00125 }
00126 m_stack_stream.push_back(tmp);
00127 break;
00128 case 'w':
00129 m_doc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
00130 m_stack_stream.push_back(xmlNewNode(
00131 NULL, BAD_CAST STR_ROOT_NAME_00));
00132 xmlDocSetRootElement(m_doc, m_stack_stream.back());
00133 break;
00134 default:
00135 SG_WARNING("Could not open file `%s', unknown mode!\n",
00136 m_filename);
00137 close(); return;
00138 }
00139 }
00140
00141 void
00142 CSerializableXmlFile::close()
00143 {
00144 while (m_stack_stream.get_num_elements() > 0) pop_node();
00145
00146 if (is_opened()) {
00147 if (m_task == 'w'
00148 && xmlSaveFormatFileEnc(m_filename, m_doc, "UTF-8",
00149 m_format) < 0) {
00150 SG_WARNING("Could not close file `%s' for writing!\n",
00151 m_filename);
00152 }
00153
00154 xmlFreeDoc(m_doc); m_doc = NULL;
00155 xmlCleanupParser();
00156 }
00157 }
00158
00159 bool
00160 CSerializableXmlFile::is_opened()
00161 {
00162 return m_doc != NULL;
00163 }
00164
00165 bool
00166 CSerializableXmlFile::write_scalar_wrapped(
00167 const TSGDataType* type, const void* param)
00168 {
00169 string_t buf;
00170
00171 switch (type->m_ptype) {
00172 case PT_BOOL:
00173 if (snprintf(buf, STRING_LEN, "%s", *(bool*) param? STR_TRUE
00174 : STR_FALSE) <= 0) return false;
00175 break;
00176 case PT_CHAR:
00177 if (snprintf(buf, STRING_LEN, "%c", *(char*) param
00178 ) <= 0) return false;
00179 break;
00180 case PT_INT8:
00181 if (snprintf(buf, STRING_LEN, "%"PRIi8, *(int8_t*) param
00182 ) <= 0) return false;
00183 break;
00184 case PT_UINT8:
00185 if (snprintf(buf, STRING_LEN, "%"PRIu8, *(uint8_t*) param
00186 ) <= 0) return false;
00187 break;
00188 case PT_INT16:
00189 if (snprintf(buf, STRING_LEN, "%"PRIi16, *(int16_t*) param
00190 ) <= 0) return false;
00191 break;
00192 case PT_UINT16:
00193 if (snprintf(buf, STRING_LEN, "%"PRIu16, *(uint16_t*) param
00194 ) <= 0) return false;
00195 break;
00196 case PT_INT32:
00197 if (snprintf(buf, STRING_LEN, "%"PRIi32, *(int32_t*) param
00198 ) <= 0) return false;
00199 break;
00200 case PT_UINT32:
00201 if (snprintf(buf, STRING_LEN, "%"PRIu32, *(uint32_t*) param
00202 ) <= 0) return false;
00203 break;
00204 case PT_INT64:
00205 if (snprintf(buf, STRING_LEN, "%"PRIi64, *(int64_t*) param
00206 ) <= 0) return false;
00207 break;
00208 case PT_UINT64:
00209 if (snprintf(buf, STRING_LEN, "%"PRIu64, *(uint64_t*) param
00210 ) <= 0) return false;
00211 break;
00212 case PT_FLOAT32:
00213 if (snprintf(buf, STRING_LEN, "%.16g", *(float32_t*) param
00214 ) <= 0) return false;
00215 break;
00216 case PT_FLOAT64:
00217 if (snprintf(buf, STRING_LEN, "%.16lg", *(float64_t*) param
00218 ) <= 0) return false;
00219 break;
00220 case PT_FLOATMAX:
00221 if (snprintf(buf, STRING_LEN, "%.16Lg", *(floatmax_t*)
00222 param) <= 0) return false;
00223 break;
00224 case PT_SGOBJECT:
00225 SG_ERROR("write_scalar_wrapped(): Implementation error during"
00226 " writing XmlFile!");
00227 return false;
00228 }
00229
00230 xmlNodeAddContent(m_stack_stream.back(), BAD_CAST buf);
00231 return true;
00232 }
00233
00234 bool
00235 CSerializableXmlFile::write_cont_begin_wrapped(
00236 const TSGDataType* type, index_t len_real_y, index_t len_real_x)
00237 {
00238 return true;
00239 }
00240
00241 bool
00242 CSerializableXmlFile::write_cont_end_wrapped(
00243 const TSGDataType* type, index_t len_real_y, index_t len_real_x)
00244 {
00245 if (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX)
00246 if (len_real_y*len_real_x>0)
00247 pop_node();
00248
00249 return true;
00250 }
00251
00252 bool
00253 CSerializableXmlFile::write_string_begin_wrapped(
00254 const TSGDataType* type, index_t length)
00255 {
00256 return true;
00257 }
00258
00259 bool
00260 CSerializableXmlFile::write_string_end_wrapped(
00261 const TSGDataType* type, index_t length)
00262 {
00263 return true;
00264 }
00265
00266 bool
00267 CSerializableXmlFile::write_stringentry_begin_wrapped(
00268 const TSGDataType* type, index_t y)
00269 {
00270 if (!push_node(BAD_CAST STR_STRING)) return false;
00271
00272 return true;
00273 }
00274
00275 bool
00276 CSerializableXmlFile::write_stringentry_end_wrapped(
00277 const TSGDataType* type, index_t y)
00278 {
00279 pop_node();
00280
00281 return true;
00282 }
00283
00284 bool
00285 CSerializableXmlFile::write_sparse_begin_wrapped(
00286 const TSGDataType* type, index_t vec_index,
00287 index_t length)
00288 {
00289 string_t buf;
00290 snprintf(buf, STRING_LEN, "%"PRIi32, vec_index);
00291 if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_VECINDEX,
00292 BAD_CAST buf) == NULL) return false;
00293
00294 return true;
00295 }
00296
00297 bool
00298 CSerializableXmlFile::write_sparse_end_wrapped(
00299 const TSGDataType* type, index_t vec_index,
00300 index_t length)
00301 {
00302 return true;
00303 }
00304
00305 bool
00306 CSerializableXmlFile::write_sparseentry_begin_wrapped(
00307 const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
00308 index_t feat_index, index_t y)
00309 {
00310 push_node(BAD_CAST STR_SPARSE);
00311
00312 string_t buf;
00313 snprintf(buf, STRING_LEN, "%"PRIi32, feat_index);
00314 if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_FEATINDEX,
00315 BAD_CAST buf) == NULL) return false;
00316 return true;
00317 }
00318
00319 bool
00320 CSerializableXmlFile::write_sparseentry_end_wrapped(
00321 const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
00322 index_t feat_index, index_t y)
00323 {
00324 pop_node();
00325
00326 return true;
00327 }
00328
00329 bool
00330 CSerializableXmlFile::write_item_begin_wrapped(
00331 const TSGDataType* type, index_t y, index_t x)
00332 {
00333 if (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX) {
00334 if (y==0)
00335 {
00336 if (x != 0) pop_node();
00337
00338 string_t buf_x; snprintf(buf_x, STRING_LEN, "x%"PRIi32, x);
00339 if (!push_node(BAD_CAST buf_x)) return false;
00340 }
00341 }
00342
00343 push_node(BAD_CAST STR_ITEM);
00344
00345 return true;
00346 }
00347
00348 bool
00349 CSerializableXmlFile::write_item_end_wrapped(
00350 const TSGDataType* type, index_t y, index_t x)
00351 {
00352 pop_node();
00353
00354 return true;
00355 }
00356
00357 bool
00358 CSerializableXmlFile::write_sgserializable_begin_wrapped(
00359 const TSGDataType* type, const char* sgserializable_name,
00360 EPrimitiveType generic)
00361 {
00362 if (*sgserializable_name == '\0') {
00363 if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_IS_NULL,
00364 BAD_CAST STR_TRUE) == NULL) return false;
00365 return true;
00366 }
00367
00368 if (xmlNewProp(m_stack_stream.back(),
00369 BAD_CAST STR_PROP_INSTANCE_NAME,
00370 BAD_CAST sgserializable_name) == NULL) return false;
00371
00372 if (generic != PT_NOT_GENERIC) {
00373 string_t buf;
00374 TSGDataType::ptype_to_string(buf, generic, STRING_LEN);
00375 if (xmlNewProp(m_stack_stream.back(),
00376 BAD_CAST STR_PROP_GENERIC_NAME, BAD_CAST buf)
00377 == NULL) return false;
00378 }
00379
00380 return true;
00381 }
00382
00383 bool
00384 CSerializableXmlFile::write_sgserializable_end_wrapped(
00385 const TSGDataType* type, const char* sgserializable_name,
00386 EPrimitiveType generic)
00387 {
00388 return true;
00389 }
00390
00391 bool
00392 CSerializableXmlFile::write_type_begin_wrapped(
00393 const TSGDataType* type, const char* name, const char* prefix)
00394 {
00395 if (!push_node(BAD_CAST name)) return false;
00396
00397 SG_SET_LOCALE_C;
00398
00399 string_t buf;
00400 type->to_string(buf, STRING_LEN);
00401 if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_TYPE,
00402 BAD_CAST buf) == NULL) return false;
00403
00404 return true;
00405 }
00406
00407 bool
00408 CSerializableXmlFile::write_type_end_wrapped(
00409 const TSGDataType* type, const char* name, const char* prefix)
00410 {
00411 pop_node();
00412
00413 SG_RESET_LOCALE;
00414
00415 return true;
00416 }
00417
00418 #endif