# eoState.cpp

    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     //else
    00038
    00039     string::size_type end = str.find("}");
    00040
    00041     if (end == string::npos)
    00042         return false;
    00043     // else
    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*>(&registrant));
    00061
    00062     pair<ObjectMap::iterator,bool> res = objectMap.insert(make_pair(name, &registrant));
    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     { // parse section header
    00102         if (is_section(str, name))
    00103         {
    00104             string fullString;
    00105             ObjectMap::iterator it = objectMap.find(name);
    00106
    00107             if (it == objectMap.end())
    00108             { // ignore
    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                 // now we have the object, get lines, remove comments etc.
    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 // if (is_section(str, name)) - what if file empty
    00139           {
    00140             getline(is, str);   // try next line!
    00141             //      if (is.eof())
    00142             //        throw runtime_error("No section in load file");
    00143           }
    00144     }
    00145
    00146 }
    00147
    00148 void eoState::save(const string& filename) const
    00149 { // saves in order of insertion
    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 { // saves in order of insertion
    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     // else
    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