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_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 /* HAVE_XML  */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation