presage
0.8.7
|
00001 00002 /****************************************************** 00003 * Presage, an extensible predictive text entry system 00004 * --------------------------------------------------- 00005 * 00006 * Copyright (C) 2008 Matteo Vescovi <matteo.vescovi@yahoo.co.uk> 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 2 of the License, or 00011 (at your option) any later version. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License along 00019 with this program; if not, write to the Free Software Foundation, Inc., 00020 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00021 * 00022 **********(*)*/ 00023 00024 00025 #include "core/profile.h" 00026 00027 #include <iostream> 00028 #include <sstream> 00029 00030 Profile::Profile(const std::string& profile_file) 00031 { 00032 xmlProfileDoc = new TiXmlDocument(); 00033 assert( xmlProfileDoc ); 00034 00035 xml_filename = profile_file; 00036 00037 xml_profile_read_ok = xmlProfileDoc->LoadFile (xml_filename.c_str()); 00038 } 00039 00040 Profile::~Profile() 00041 { 00042 delete xmlProfileDoc; 00043 } 00044 00045 bool Profile::file_read_ok () const 00046 { 00047 return xml_profile_read_ok; 00048 } 00049 00050 void Profile::read_into_configuration(Configuration* config) 00051 { 00052 init_configuration(config, xmlProfileDoc); 00053 } 00054 00055 void Profile::init_configuration(Configuration* config, TiXmlDocument* root) 00056 { 00057 std::vector<std::string> variable; 00058 00059 visit_node(config, root, variable); 00060 } 00061 00062 void Profile::visit_node(Configuration* configuration, 00063 TiXmlNode* node, 00064 std::vector<std::string> variable) 00065 { 00066 if (node) { 00067 // visit the node only if it is one 00068 00069 // first visit our siblings 00070 visit_node(configuration, node->NextSibling(), variable); 00071 00072 // then check this element contains a 00073 // configuration variable 00074 TiXmlElement* element = node->ToElement(); 00075 if (element) { 00076 // append element name to variable to 00077 // build fully qualified variable name 00078 // before visit children 00079 variable.push_back(element->Value()); 00080 00081 // if element contains text, we have a value for our 00082 // config variable, so add it to our configuration 00083 const char* text = element->GetText(); 00084 if (text) { 00085 configuration->insert (Variable::vector_to_string(variable), text); 00086 00087 //std::cerr << "[Profile] Inserted variable: " << Variable::vector_to_string(variable) << " = " << text << std::endl; 00088 } 00089 } 00090 00091 // then descend down the tree 00092 visit_node(configuration, node->FirstChild(), variable); 00093 } 00094 } 00095 00096 bool Profile::write_to_file () const 00097 { 00098 //std::cerr << "Saving profile to file: " << xml_filename << std::endl; 00099 return xmlProfileDoc->SaveFile(xml_filename.c_str()); 00100 } 00101 00102 void Profile::read_from_configuration (Configuration* configuration) 00103 { 00104 TiXmlNode* node = 0; 00105 00106 // insert initial mandatory declaration if not present 00107 TiXmlNode* decl = 0; 00108 for (TiXmlNode* child = xmlProfileDoc->FirstChild(); 00109 child && !decl; child = child->NextSibling() ) { 00110 decl = child->ToDeclaration (); 00111 } 00112 if (! decl) { 00113 node = xmlProfileDoc->InsertEndChild( TiXmlDeclaration( "1.0", "UTF-8", "no" ) ); 00114 assert (node); 00115 } 00116 00117 // for each configuration variable in configuration 00118 for (std::map<std::string, Variable*>::const_iterator conf_it = configuration->begin(); 00119 conf_it != configuration->end(); 00120 conf_it ++) { 00121 00122 // start from root of DOM 00123 node = xmlProfileDoc; 00124 00125 // get the variable name and break it up in its component vector 00126 std::string variable_name = conf_it->second->get_name (); 00127 std::vector<std::string> variable_name_vector = Variable::string_to_vector (variable_name); 00128 00129 // for each component in variable name vector 00130 for (size_t i = 0; i < variable_name_vector.size(); i++) { 00131 00132 // check if component element exists 00133 TiXmlElement* existing = node->FirstChildElement (variable_name_vector[i].c_str()); 00134 if (existing) { 00135 // carry on with existing component 00136 node = existing; 00137 00138 } else { 00139 // create missing component element and carry on with new component 00140 node = node->InsertEndChild (TiXmlElement (variable_name_vector[i].c_str())); 00141 assert (node); 00142 } 00143 } 00144 00145 // check if a text node for element exists 00146 TiXmlText* text = 0; 00147 for(TiXmlNode* child = node->FirstChild(); child && !text; child = child->NextSibling() ) { 00148 text = child->ToText (); 00149 } 00150 if (text) { 00151 // text child already exists, so remove it to set new value 00152 node->RemoveChild (text); 00153 } 00154 node = node->InsertEndChild (TiXmlText (conf_it->second->get_value ().c_str ())); 00155 assert (node); 00156 00157 } 00158 }