EvolvingObjects
|
00001 #ifdef _MSC_VER 00002 #pragma warning(disable:4786) 00003 #endif 00004 00005 #ifdef HAVE_CONFIG_H 00006 #include <config.h> 00007 #endif 00008 00009 #include <algorithm> 00010 #include <fstream> 00011 #include <sstream> 00012 00013 #include "eoState.h" 00014 #include "eoObject.h" 00015 #include "eoPersistent.h" 00016 00017 using namespace std; 00018 00019 00020 00021 void eoState::removeComment(string& str, string comment) 00022 { 00023 string::size_type pos = str.find(comment); 00024 00025 if (pos != string::npos) 00026 { 00027 str.erase(pos, str.size()); 00028 } 00029 } 00030 00031 bool eoState::is_section(const string& str, string& name) 00032 { 00033 string::size_type pos = str.find(_tag_section_so); 00034 00035 if (pos == string::npos) 00036 return false; 00037 //else 00038 00039 string::size_type end = str.find(_tag_section_sc); 00040 00041 if (end == string::npos) 00042 return false; 00043 // else 00044 00045 // affect name, passed by reference 00046 // Note: substr( start, count ) 00047 name = str.substr( pos + _tag_section_so.size(), end - _tag_section_so.size() ); 00048 00049 return true; 00050 } 00051 00052 eoState::~eoState(void) 00053 { 00054 for (unsigned i = 0; i < ownedObjects.size(); ++i) 00055 { 00056 delete ownedObjects[i]; 00057 } 00058 } 00059 00060 void eoState::registerObject(eoPersistent& registrant) 00061 { 00062 string name = createObjectName(dynamic_cast<eoObject*>(®istrant)); 00063 00064 pair<ObjectMap::iterator,bool> res = objectMap.insert(make_pair(name, ®istrant)); 00065 00066 if (res.second == true) 00067 { 00068 creationOrder.push_back(res.first); 00069 } 00070 else 00071 { 00072 throw logic_error("Interval error: object already present in the state"); 00073 } 00074 } 00075 00076 void eoState::load(const string& _filename) 00077 { 00078 ifstream is (_filename.c_str()); 00079 00080 if (!is) 00081 { 00082 string str = "Could not open file " + _filename; 00083 throw runtime_error(str); 00084 } 00085 00086 load(is); 00087 } 00088 00089 //Â FIXME implement parsing and loading of other formats 00090 void eoState::load(std::istream& is) 00091 { 00092 string str; 00093 string name; 00094 00095 getline(is, str); 00096 00097 if (is.fail()) 00098 { 00099 string str = "Error while reading stream"; 00100 throw runtime_error(str); 00101 } 00102 00103 while(! is.eof()) 00104 { // parse section header 00105 if (is_section(str, name)) 00106 { 00107 string fullString; 00108 ObjectMap::iterator it = objectMap.find(name); 00109 00110 if (it == objectMap.end()) 00111 { // ignore 00112 while (getline(is, str)) 00113 { 00114 if (is_section(str, name)) 00115 break; 00116 } 00117 } 00118 else 00119 { 00120 00121 eoPersistent* object = it->second; 00122 00123 // now we have the object, get lines, remove comments etc. 00124 00125 string fullstring; 00126 00127 while (getline(is, str)) 00128 { 00129 if (is.eof()) 00130 throw runtime_error("No section in load file"); 00131 if (is_section(str, name)) 00132 break; 00133 00134 removeComment(str, getCommentString()); 00135 fullstring += str + "\n"; 00136 } 00137 istringstream the_stream(fullstring); 00138 object->readFrom(the_stream); 00139 } 00140 } 00141 else // if (is_section(str, name)) - what if file empty 00142 { 00143 getline(is, str); // try next line! 00144 // if (is.eof()) 00145 // throw runtime_error("No section in load file"); 00146 } 00147 } 00148 00149 } 00150 00151 void eoState::save(const string& filename) const 00152 { // saves in order of insertion 00153 ofstream os(filename.c_str()); 00154 00155 if (!os) 00156 { 00157 string msg = "Could not open file: " + filename + " for writing!"; 00158 throw runtime_error(msg); 00159 } 00160 00161 save(os); 00162 } 00163 00164 //void eoState::save(std::ostream& os) const 00165 //{ // saves in order of insertion 00166 // for (vector<ObjectMap::iterator>::const_iterator it = creationOrder.begin(); it != creationOrder.end(); ++it) 00167 // { 00168 // os << "\\section{" << (*it)->first << "}\n"; 00169 // (*it)->second->printOn(os); 00170 // os << '\n'; 00171 // } 00172 //} 00173 00174 void eoState::saveSection( std::ostream& os, vector<ObjectMap::iterator>::const_iterator it) const 00175 { 00176 os << _tag_section_so << (*it)->first << _tag_section_sc; 00177 00178 os << _tag_content_s; 00179 (*it)->second->printOn(os); 00180 os << _tag_content_e; 00181 00182 os << _tag_section_e; 00183 } 00184 00185 00186 void eoState::save(std::ostream& os) const 00187 { 00188 os << _tag_state_so << _tag_state_name << _tag_state_sc; 00189 00190 // save the first section 00191 assert( creationOrder.size() > 0 ); 00192 // saves in order of insertion 00193 vector<ObjectMap::iterator>::const_iterator it = creationOrder.begin(); 00194 saveSection(os,it); 00195 it++; 00196 00197 while( it != creationOrder.end() ) { 00198 // add a separator only before [1,n] elements 00199 os << _tag_section_sep; 00200 saveSection(os, it); 00201 it++; 00202 } 00203 os << _tag_state_e; 00204 } 00205 00206 00207 string eoState::createObjectName(eoObject* obj) 00208 { 00209 if (obj == 0) 00210 { 00211 ostringstream os; 00212 os << objectMap.size(); 00213 return os.str(); 00214 } 00215 // else 00216 00217 string name = obj->className(); 00218 ObjectMap::const_iterator it = objectMap.find(name); 00219 00220 unsigned count = 1; 00221 while (it != objectMap.end()) 00222 { 00223 ostringstream os; 00224 os << obj->className().c_str() << count++; 00225 name = os.str(); 00226 it = objectMap.find(name); 00227 } 00228 00229 return name; 00230 }