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 length)
00287 {
00288 return true;
00289 }
00290
00291 bool
00292 CSerializableXmlFile::write_sparse_end_wrapped(
00293 const TSGDataType* type, index_t length)
00294 {
00295 return true;
00296 }
00297
00298 bool
00299 CSerializableXmlFile::write_sparseentry_begin_wrapped(
00300 const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
00301 index_t feat_index, index_t y)
00302 {
00303 push_node(BAD_CAST STR_SPARSE);
00304
00305 string_t buf;
00306 snprintf(buf, STRING_LEN, "%"PRIi32, feat_index);
00307 if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_FEATINDEX,
00308 BAD_CAST buf) == NULL) return false;
00309 return true;
00310 }
00311
00312 bool
00313 CSerializableXmlFile::write_sparseentry_end_wrapped(
00314 const TSGDataType* type, const SGSparseVectorEntry<char>* first_entry,
00315 index_t feat_index, index_t y)
00316 {
00317 pop_node();
00318
00319 return true;
00320 }
00321
00322 bool
00323 CSerializableXmlFile::write_item_begin_wrapped(
00324 const TSGDataType* type, index_t y, index_t x)
00325 {
00326 if (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX) {
00327 if (y==0)
00328 {
00329 if (x != 0) pop_node();
00330
00331 string_t buf_x; snprintf(buf_x, STRING_LEN, "x%"PRIi32, x);
00332 if (!push_node(BAD_CAST buf_x)) return false;
00333 }
00334 }
00335
00336 push_node(BAD_CAST STR_ITEM);
00337
00338 return true;
00339 }
00340
00341 bool
00342 CSerializableXmlFile::write_item_end_wrapped(
00343 const TSGDataType* type, index_t y, index_t x)
00344 {
00345 pop_node();
00346
00347 return true;
00348 }
00349
00350 bool
00351 CSerializableXmlFile::write_sgserializable_begin_wrapped(
00352 const TSGDataType* type, const char* sgserializable_name,
00353 EPrimitiveType generic)
00354 {
00355 if (*sgserializable_name == '\0') {
00356 if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_IS_NULL,
00357 BAD_CAST STR_TRUE) == NULL) return false;
00358 return true;
00359 }
00360
00361 if (xmlNewProp(m_stack_stream.back(),
00362 BAD_CAST STR_PROP_INSTANCE_NAME,
00363 BAD_CAST sgserializable_name) == NULL) return false;
00364
00365 if (generic != PT_NOT_GENERIC) {
00366 string_t buf;
00367 TSGDataType::ptype_to_string(buf, generic, STRING_LEN);
00368 if (xmlNewProp(m_stack_stream.back(),
00369 BAD_CAST STR_PROP_GENERIC_NAME, BAD_CAST buf)
00370 == NULL) return false;
00371 }
00372
00373 return true;
00374 }
00375
00376 bool
00377 CSerializableXmlFile::write_sgserializable_end_wrapped(
00378 const TSGDataType* type, const char* sgserializable_name,
00379 EPrimitiveType generic)
00380 {
00381 return true;
00382 }
00383
00384 bool
00385 CSerializableXmlFile::write_type_begin_wrapped(
00386 const TSGDataType* type, const char* name, const char* prefix)
00387 {
00388 if (!push_node(BAD_CAST name)) return false;
00389
00390 SG_SET_LOCALE_C;
00391
00392 string_t buf;
00393 type->to_string(buf, STRING_LEN);
00394 if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_TYPE,
00395 BAD_CAST buf) == NULL) return false;
00396
00397 return true;
00398 }
00399
00400 bool
00401 CSerializableXmlFile::write_type_end_wrapped(
00402 const TSGDataType* type, const char* name, const char* prefix)
00403 {
00404 pop_node();
00405
00406 SG_RESET_LOCALE;
00407
00408 return true;
00409 }
00410
00411 #endif