SHOGUN  v3.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SerializableXmlFile.cpp
Go to the documentation of this file.
00001 /*
00002  * This program is free software; you can redistribute it and/or modify
00003  * it under the terms of the GNU General Public License as published by
00004  * the Free Software Foundation; either version 3 of the License, or
00005  * (at your option) any later version.
00006  *
00007  * Written (W) 2010 Soeren Sonnenburg
00008  * Copyright (C) 2010 Berlin Institute of Technology
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_COMPLEX128:
00225         if (snprintf(buf, STRING_LEN, "(%.16lg,%.16lg)",
00226                 ((complex128_t*) param)->real(),((complex128_t*) param)->imag()
00227                 ) <= 0) return false;
00228         break;
00229     case PT_UNDEFINED:
00230     case PT_SGOBJECT:
00231         SG_ERROR("write_scalar_wrapped(): Implementation error during"
00232                  " writing XmlFile!");
00233         return false;
00234     }
00235 
00236     xmlNodeAddContent(m_stack_stream.back(), BAD_CAST buf);
00237     return true;
00238 }
00239 
00240 bool
00241 CSerializableXmlFile::write_cont_begin_wrapped(
00242     const TSGDataType* type, index_t len_real_y, index_t len_real_x)
00243 {
00244     return true;
00245 }
00246 
00247 bool
00248 CSerializableXmlFile::write_cont_end_wrapped(
00249     const TSGDataType* type, index_t len_real_y, index_t len_real_x)
00250 {
00251     if (type->m_ctype==CT_MATRIX || type->m_ctype==CT_SGMATRIX)
00252         if (len_real_y*len_real_x>0)
00253             pop_node();
00254 
00255     return true;
00256 }
00257 
00258 bool
00259 CSerializableXmlFile::write_string_begin_wrapped(
00260     const TSGDataType* type, index_t length)
00261 {
00262     return true;
00263 }
00264 
00265 bool
00266 CSerializableXmlFile::write_string_end_wrapped(
00267     const TSGDataType* type, index_t length)
00268 {
00269     return true;
00270 }
00271 
00272 bool
00273 CSerializableXmlFile::write_stringentry_begin_wrapped(
00274     const TSGDataType* type, index_t y)
00275 {
00276     if (!push_node(BAD_CAST STR_STRING)) return false;
00277 
00278     return true;
00279 }
00280 
00281 bool
00282 CSerializableXmlFile::write_stringentry_end_wrapped(
00283     const TSGDataType* type, index_t y)
00284 {
00285     pop_node();
00286 
00287     return true;
00288 }
00289 
00290 bool
00291 CSerializableXmlFile::write_sparse_begin_wrapped(
00292     const TSGDataType* type, index_t length)
00293 {
00294     return true;
00295 }
00296 
00297 bool
00298 CSerializableXmlFile::write_sparse_end_wrapped(
00299     const TSGDataType* type, index_t length)
00300 {
00301     return true;
00302 }
00303 
00304 bool
00305 CSerializableXmlFile::write_sparseentry_begin_wrapped(
00306     const TSGDataType* type, const SGSparseVectorEntry<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 SGSparseVectorEntry<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 || type->m_ctype==CT_SGMATRIX) {
00333         if (y==0)
00334         {
00335             if (x != 0) pop_node();
00336 
00337             string_t buf_x; snprintf(buf_x, STRING_LEN, "x%" PRIi32, x);
00338             if (!push_node(BAD_CAST buf_x)) return false;
00339         }
00340     }
00341 
00342     push_node(BAD_CAST STR_ITEM);
00343 
00344     return true;
00345 }
00346 
00347 bool
00348 CSerializableXmlFile::write_item_end_wrapped(
00349     const TSGDataType* type, index_t y, index_t x)
00350 {
00351     pop_node();
00352 
00353     return true;
00354 }
00355 
00356 bool
00357 CSerializableXmlFile::write_sgserializable_begin_wrapped(
00358     const TSGDataType* type, const char* sgserializable_name,
00359     EPrimitiveType generic)
00360 {
00361     if (*sgserializable_name == '\0') {
00362         if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_IS_NULL,
00363                        BAD_CAST STR_TRUE) == NULL) return false;
00364         return true;
00365     }
00366 
00367     if (xmlNewProp(m_stack_stream.back(),
00368                    BAD_CAST STR_PROP_INSTANCE_NAME,
00369                    BAD_CAST sgserializable_name) == NULL) return false;
00370 
00371     if (generic != PT_NOT_GENERIC) {
00372         string_t buf;
00373         TSGDataType::ptype_to_string(buf, generic, STRING_LEN);
00374         if (xmlNewProp(m_stack_stream.back(),
00375                        BAD_CAST STR_PROP_GENERIC_NAME, BAD_CAST buf)
00376             == NULL) return false;
00377     }
00378 
00379     return true;
00380 }
00381 
00382 bool
00383 CSerializableXmlFile::write_sgserializable_end_wrapped(
00384     const TSGDataType* type, const char* sgserializable_name,
00385     EPrimitiveType generic)
00386 {
00387     return true;
00388 }
00389 
00390 bool
00391 CSerializableXmlFile::write_type_begin_wrapped(
00392     const TSGDataType* type, const char* name, const char* prefix)
00393 {
00394     if (!push_node(BAD_CAST name)) return false;
00395 
00396     SG_SET_LOCALE_C;
00397 
00398     string_t buf;
00399     type->to_string(buf, STRING_LEN);
00400     if (xmlNewProp(m_stack_stream.back(), BAD_CAST STR_PROP_TYPE,
00401                    BAD_CAST buf) == NULL) return false;
00402 
00403     return true;
00404 }
00405 
00406 bool
00407 CSerializableXmlFile::write_type_end_wrapped(
00408     const TSGDataType* type, const char* name, const char* prefix)
00409 {
00410     pop_node();
00411 
00412     SG_RESET_LOCALE;
00413 
00414     return true;
00415 }
00416 
00417 #endif /* HAVE_XML  */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation