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

SHOGUN Machine Learning Toolbox - Documentation