00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "lib/config.h"
00012 #ifdef HAVE_XML
00013
00014 #include "lib/SerializableXmlFile.h"
00015 #include "lib/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(void)
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(void)
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(void)
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(void)
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 && len_real_y *len_real_x > 0)
00246 pop_node();
00247
00248 return true;
00249 }
00250
00251 bool
00252 CSerializableXmlFile::write_string_begin_wrapped(
00253 const TSGDataType* type, index_t length)
00254 {
00255 return true;
00256 }
00257
00258 bool
00259 CSerializableXmlFile::write_string_end_wrapped(
00260 const TSGDataType* type, index_t length)
00261 {
00262 return true;
00263 }
00264
00265 bool
00266 CSerializableXmlFile::write_stringentry_begin_wrapped(
00267 const TSGDataType* type, index_t y)
00268 {
00269 if (!push_node(BAD_CAST STR_STRING)) return false;
00270
00271 return true;
00272 }
00273
00274 bool
00275 CSerializableXmlFile::write_stringentry_end_wrapped(
00276 const TSGDataType* type, index_t y)
00277 {
00278 pop_node();
00279
00280 return true;
00281 }
00282
00283 bool
00284 CSerializableXmlFile::write_sparse_begin_wrapped(
00285 const TSGDataType* type, index_t vec_index,
00286 index_t length)
00287 {
00288 string_t buf;
00289 snprintf(buf, STRING_LEN, "%"PRIi32, vec_index);
00290 if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_VECINDEX,
00291 BAD_CAST buf) == NULL) return false;
00292
00293 return true;
00294 }
00295
00296 bool
00297 CSerializableXmlFile::write_sparse_end_wrapped(
00298 const TSGDataType* type, index_t vec_index,
00299 index_t length)
00300 {
00301 return true;
00302 }
00303
00304 bool
00305 CSerializableXmlFile::write_sparseentry_begin_wrapped(
00306 const TSGDataType* type, const TSparseEntry<char>* first_entry,
00307 index_t feat_index, index_t y)
00308 {
00309 push_node(BAD_CAST STR_SPARSE);
00310
00311 string_t buf;
00312 snprintf(buf, STRING_LEN, "%"PRIi32, feat_index);
00313 if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_FEATINDEX,
00314 BAD_CAST buf) == NULL) return false;
00315 return true;
00316 }
00317
00318 bool
00319 CSerializableXmlFile::write_sparseentry_end_wrapped(
00320 const TSGDataType* type, const TSparseEntry<char>* first_entry,
00321 index_t feat_index, index_t y)
00322 {
00323 pop_node();
00324
00325 return true;
00326 }
00327
00328 bool
00329 CSerializableXmlFile::write_item_begin_wrapped(
00330 const TSGDataType* type, index_t y, index_t x)
00331 {
00332 if (type->m_ctype == CT_MATRIX && y == 0) {
00333 if (x != 0) pop_node();
00334
00335 string_t buf_x; snprintf(buf_x, STRING_LEN, "x%"PRIi32, x);
00336 if (!push_node(BAD_CAST buf_x)) return false;
00337 }
00338
00339 push_node(BAD_CAST STR_ITEM);
00340
00341 return true;
00342 }
00343
00344 bool
00345 CSerializableXmlFile::write_item_end_wrapped(
00346 const TSGDataType* type, index_t y, index_t x)
00347 {
00348 pop_node();
00349
00350 return true;
00351 }
00352
00353 bool
00354 CSerializableXmlFile::write_sgserializable_begin_wrapped(
00355 const TSGDataType* type, const char* sgserializable_name,
00356 EPrimitiveType generic)
00357 {
00358 if (*sgserializable_name == '\0') {
00359 if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_IS_NULL,
00360 BAD_CAST STR_TRUE) == NULL) return false;
00361 return true;
00362 }
00363
00364 if (xmlNewProp(m_stack_stream.back(),
00365 BAD_CAST STR_PROP_INSTANCE_NAME,
00366 BAD_CAST sgserializable_name) == NULL) return false;
00367
00368 if (generic != PT_NOT_GENERIC) {
00369 string_t buf;
00370 TSGDataType::ptype_to_string(buf, generic, STRING_LEN);
00371 if (xmlNewProp(m_stack_stream.back(),
00372 BAD_CAST STR_PROP_GENERIC_NAME, BAD_CAST buf)
00373 == NULL) return false;
00374 }
00375
00376 return true;
00377 }
00378
00379 bool
00380 CSerializableXmlFile::write_sgserializable_end_wrapped(
00381 const TSGDataType* type, const char* sgserializable_name,
00382 EPrimitiveType generic)
00383 {
00384 return true;
00385 }
00386
00387 bool
00388 CSerializableXmlFile::write_type_begin_wrapped(
00389 const TSGDataType* type, const char* name, const char* prefix)
00390 {
00391 if (!push_node(BAD_CAST name)) return false;
00392
00393 SG_SET_LOCALE_C;
00394
00395 string_t buf;
00396 type->to_string(buf, STRING_LEN);
00397 if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_TYPE,
00398 BAD_CAST buf) == NULL) return false;
00399
00400 return true;
00401 }
00402
00403 bool
00404 CSerializableXmlFile::write_type_end_wrapped(
00405 const TSGDataType* type, const char* name, const char* prefix)
00406 {
00407 pop_node();
00408
00409 SG_RESET_LOCALE;
00410
00411 return true;
00412 }
00413
00414 #endif