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 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 is_section(const string& str, string& name)
00032 {
00033 string::size_type pos = str.find("\\section{");
00034
00035 if (pos == string::npos)
00036 return false;
00037
00038
00039 string::size_type end = str.find("}");
00040
00041 if (end == string::npos)
00042 return false;
00043
00044
00045 name = str.substr(pos + 9, end-9);
00046
00047 return true;
00048 }
00049
00050 eoState::~eoState(void)
00051 {
00052 for (unsigned i = 0; i < ownedObjects.size(); ++i)
00053 {
00054 delete ownedObjects[i];
00055 }
00056 }
00057
00058 void eoState::registerObject(eoPersistent& registrant)
00059 {
00060 string name = createObjectName(dynamic_cast<eoObject*>(®istrant));
00061
00062 pair<ObjectMap::iterator,bool> res = objectMap.insert(make_pair(name, ®istrant));
00063
00064 if (res.second == true)
00065 {
00066 creationOrder.push_back(res.first);
00067 }
00068 else
00069 {
00070 throw logic_error("Interval error: object already present in the state");
00071 }
00072 }
00073
00074 void eoState::load(const string& _filename)
00075 {
00076 ifstream is (_filename.c_str());
00077
00078 if (!is)
00079 {
00080 string str = "Could not open file " + _filename;
00081 throw runtime_error(str);
00082 }
00083
00084 load(is);
00085 }
00086
00087 void eoState::load(std::istream& is)
00088 {
00089 string str;
00090 string name;
00091
00092 getline(is, str);
00093
00094 if (is.fail())
00095 {
00096 string str = "Error while reading stream";
00097 throw runtime_error(str);
00098 }
00099
00100 while(! is.eof())
00101 {
00102 if (is_section(str, name))
00103 {
00104 string fullString;
00105 ObjectMap::iterator it = objectMap.find(name);
00106
00107 if (it == objectMap.end())
00108 {
00109 while (getline(is, str))
00110 {
00111 if (is_section(str, name))
00112 break;
00113 }
00114 }
00115 else
00116 {
00117
00118 eoPersistent* object = it->second;
00119
00120
00121
00122 string fullstring;
00123
00124 while (getline(is, str))
00125 {
00126 if (is.eof())
00127 throw runtime_error("No section in load file");
00128 if (is_section(str, name))
00129 break;
00130
00131 removeComment(str, getCommentString());
00132 fullstring += str + "\n";
00133 }
00134 istringstream the_stream(fullstring);
00135 object->readFrom(the_stream);
00136 }
00137 }
00138 else
00139 {
00140 getline(is, str);
00141
00142
00143 }
00144 }
00145
00146 }
00147
00148 void eoState::save(const string& filename) const
00149 {
00150 ofstream os(filename.c_str());
00151
00152 if (!os)
00153 {
00154 string msg = "Could not open file: " + filename + " for writing!";
00155 throw runtime_error(msg);
00156 }
00157
00158 save(os);
00159 }
00160
00161 void eoState::save(std::ostream& os) const
00162 {
00163 for (vector<ObjectMap::iterator>::const_iterator it = creationOrder.begin(); it != creationOrder.end(); ++it)
00164 {
00165 os << "\\section{" << (*it)->first << "}\n";
00166 (*it)->second->printOn(os);
00167 os << '\n';
00168 }
00169 }
00170
00171 string eoState::createObjectName(eoObject* obj)
00172 {
00173 if (obj == 0)
00174 {
00175 ostringstream os;
00176 os << objectMap.size();
00177 return os.str();
00178 }
00179
00180
00181 string name = obj->className();
00182 ObjectMap::const_iterator it = objectMap.find(name);
00183
00184 unsigned count = 1;
00185 while (it != objectMap.end())
00186 {
00187 ostringstream os;
00188 os << obj->className().c_str() << count++;
00189 name = os.str();
00190 it = objectMap.find(name);
00191 }
00192
00193 return name;
00194 }
00195