EvolvingObjects
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 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*>(&registrant));
00063 
00064     pair<ObjectMap::iterator,bool> res = objectMap.insert(make_pair(name, &registrant));
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 }
 All Classes Namespaces Files Functions Variables Typedefs Friends