/home/enzo/treballs/fib/pfc/nanocomp/src/ruleDiskManager.cpp

Go to the documentation of this file.
00001 /*
00002  *                                                                         *
00003  *   This program is free software; you can redistribute it and/or modify  *
00004  *   it under the terms of the GNU General Public License as published by  *
00005  *   the Free Software Foundation; either version 2 of the License, or     *
00006  *   (at your option) any later version.                                   *
00007  *                                                                         *
00008  *   This program is distributed in the hope that it will be useful,       *
00009  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00010  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00011  *   GNU General Public License for more details.                          *
00012  *                                                                         *
00013  *   You should have received a copy of the GNU General Public License     *
00014  *   along with this program; if not, write to the                         *
00015  *   Free Software Foundation, Inc.,                                       *
00016  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00017                                                                           */
00018 
00019 // $Revision: 1.16 $
00020 
00021 #include <list>
00022 #include <fstream>
00023 #include "flexDefines.hpp"
00024 #include "ruleDiskManager.hpp"
00025 
00026 using namespace std;
00027 
00029 
00032 RuleDiskManager::RuleDiskManager(RuleManager *controller)
00033 {
00034     this->controller = controller;
00035 }
00036 
00037 
00039 RuleDiskManager::~RuleDiskManager()
00040 {
00041 }
00042 
00043 
00045 
00050 bool RuleDiskManager::saveRules(list<Rule*> rules, wxString fileName)
00051 {
00052     if (wxFile::Exists(fileName))
00053     {
00054         file.Open(fileName);
00055     }
00056     else
00057     {
00058         file.Create(fileName);   
00059     }
00060     file.Clear();
00061     if (!saveRuleList(rules))
00062     {
00063         file.Close();
00064         return false;
00065     }
00066     if (!file.Write(wxTextFileType_Unix))
00067     {
00068         file.Close();
00069         return false;
00070     }
00071     return (file.Close());
00072 }
00073 
00074 
00076 
00080 bool RuleDiskManager::saveRuleList(list<Rule*> rules)
00081 {
00082     bool result = true;
00083     int ruleId = 1;
00084     file.AddLine(_("#Rule file created by Nanocomp."));
00085     file.AddLine(_("#Do not edit this file if you don't know what are you doing."));
00086     file.AddLine(wxEmptyString);
00087     for(list<Rule*>::iterator i = rules.begin(); i != rules.end(); i++)
00088     {
00089         file.AddLine(wxString::Format(_("#Rule %d"), ruleId));
00090         result = result && saveRule((*i));
00091         ruleId++;
00092     }
00093     file.AddLine(_("#End of file"));
00094     return result;
00095 }
00096 
00097 
00099 
00103 bool RuleDiskManager::saveRule(Rule *rule)
00104 {
00105     file.AddLine(wxString::Format(_("%d %d"), rule->getWidth(), rule->getHeight()));
00106     file.AddLine(wxEmptyString);
00107     saveGrid(rule->getInitialGrid());
00108     file.AddLine(wxEmptyString);
00109     saveGrid(rule->getFinalGrid());
00110     file.AddLine(wxEmptyString);
00111     return true;    
00112 }
00113 
00114 
00116 
00120 bool RuleDiskManager::saveGrid(Grid grid)
00121 {
00122     wxString space = wxEmptyString;
00123     for(int i = 0; i < grid.getHeight(); i++)
00124     {
00125         wxString line = space;
00126         for(int j = 0; j < grid.getWidth(); j++)
00127         {
00128             switch (grid(j, i))
00129             {
00130                 case nENABLED:
00131                 {
00132                     line = line + _("1");
00133                     break;
00134                 }
00135                 case nDISABLED:
00136                 {
00137                     line = line + _("0");
00138                     break;
00139                 }
00140                 case nDONTCARE:
00141                 {
00142                     line = line + _(".");
00143                     break;
00144                 }
00145                 default:
00146                 {
00147                 }
00148             }
00149             
00150             //Add the space between cells (except if last)
00151             if(j != grid.getWidth() - 1)
00152             {
00153                 for (int l = 0; l < CELL_SPACE; l++)
00154                 {
00155                     line += _(" ");
00156                 }
00157             }
00158         }
00159         file.AddLine(line);
00160         //Add the line tabulation for each line
00161         for (int k = 0; k < LINE_SPACE; k++)
00162         {
00163             space += _(" ");
00164         }
00165     }
00166     return true;
00167 }
00168 
00169 
00171 
00175 bool RuleDiskManager::openRules(wxString fileName)
00176 {
00177     list<Rule *> *ruleList = new list<Rule *>();
00178     filebuf fb;
00179     if (!fb.open (fileName.mb_str(), ios::in))
00180     {
00181         //cout << "Error opening the file" << endl;
00182         return false;
00183     }
00184     istream *is = new istream(&fb);
00185     int result;
00186     int width;
00187     int height;
00188     FlexLexer* lexer = new yyFlexLexer();
00189     lexer->switch_streams(is, NULL);
00190     result = lexer->yylex();
00191     while (result != 0)
00192     {
00193         if (result != NUMBER)
00194         {
00195             //cout << "Number expected, file format error" << endl;
00196             delete ruleList;
00197             delete is;
00198             delete lexer;
00199             fb.close();
00200             return false;
00201         }
00202         else
00203         {
00204             width = atoi(lexer->YYText());
00205             if (lexer->yylex() != NUMBER) //Not another number
00206             {
00207                 //cout << "Number expected, file format error" << endl;
00208                 delete ruleList;
00209                 delete is;
00210                 delete lexer;
00211                 fb.close();
00212                 return false;
00213             }
00214             else
00215             {
00216                 height = atoi(lexer->YYText());
00217                 if (!readRule(width, height, ruleList, lexer))//Wrong rule format
00218                 {
00219                     delete ruleList;
00220                     delete is;
00221                     delete lexer;
00222                     fb.close();
00223                     return false;
00224                 }
00225             }
00226             result = lexer->yylex();
00227         }
00228     }
00229     fb.close();
00230     returnRules(ruleList);
00231     delete ruleList;
00232     return true;
00233 }
00234 
00235 
00237 
00244 bool RuleDiskManager::readRule(int width, int height, list<Rule *> *ruleList, FlexLexer *lexer)
00245 {
00246     Rule *rule = new Rule(width, height);
00247     //Now we have to process width * height * 2 cells
00248     //First rule
00249                 for(int i = 0; i < width * height; i++)
00250                 {
00251                     switch (lexer->yylex())
00252                     {
00253                         case NUMBER: //Number, so must be 1 or 0, else error
00254                             {
00255                                 if (atoi(lexer->YYText()) > 1)
00256                                 {
00257                                     //cout << "-, 1 or 0 expected, file format error" << endl;
00258                                     delete rule;
00259                                     return false;
00260                                 }
00261                                 else
00262                                 {
00263                                     if (atoi(lexer->YYText()))
00264                                     {
00265                                         //cout << "Cell at position " << i/width << ", " << i - width * (i/width) << endl;
00266                                         rule->cellChanged(i - width * (i/width), i/width, nENABLED, nINITIAL);
00267                                     }
00268                                     else
00269                                     {
00270                                         //cout << "No Cell at position " << i/width << ", " << i - width * (i/width) << endl;
00271                                         rule->cellChanged(i - width * (i/width), i/width, nDISABLED, nINITIAL);
00272                                     }
00273                                 }
00274                                 break;
00275                             }
00276                         case POINT: 
00277                             {
00278                                 //cout << "Don't care at position " << i/width << ", " << i - width * (i/width) << endl;
00279                                 rule->cellChanged(i - width * (i/width), i/width, nDONTCARE, nINITIAL);
00280                                 break;
00281                             }
00282                         default: //Error
00283                             {
00284                                 //cout << "-, 1 or 0 expected, file format error" << endl;
00285                                 delete rule;
00286                                 return false;
00287                             }
00288                     }
00289                 }
00290 
00291                 for(int i = 0; i < width * height; i++)
00292                 {
00293                     switch (lexer->yylex())
00294                     {
00295                         case NUMBER: //Number, so must be 1 or 0, else error
00296                             {
00297                                 if (atoi(lexer->YYText()) > 1)
00298                                 {
00299                                     //cout << "-, 1 or 0 expected, file format error" << endl;
00300                                     return false;
00301                                 }
00302                                 else
00303                                 {
00304                                     if (atoi(lexer->YYText()))
00305                                     {
00306                                         //cout << "Cell at position " << i/width << ", " << i - width * (i/width) << endl;
00307                                         rule->cellChanged(i - width * (i/width), i/width, nENABLED, nFINAL);
00308                                     }
00309                                     else
00310                                     {
00311                                         //cout << "No Cell at position " << i/width << ", " << i - width * (i/width) << endl;
00312                                         rule->cellChanged(i - width * (i/width), i/width, nDISABLED, nFINAL);
00313                                     }
00314                                 }
00315                                 break;
00316                             }
00317                         case POINT:
00318                             {
00319                                 //cout << "Don't care at position " << i/width << ", " << i - width * (i/width) << endl;
00320                                 //Same as the initial grid
00321                                 int initialStatus = rule->getInitialGrid()(i - width * (i/width), i/width);
00322                                 rule->cellChanged(i - width * (i/width), i/width, initialStatus, nFINAL);
00323                                 break;
00324                             }
00325                         default: //Error
00326                             {
00327                                 //cout << "-, 1 or 0 expected, file format error" << endl;
00328                                 return false;
00329                             }
00330                     }
00331                 }
00332                 ruleList->push_back(rule);
00333                 return true;
00334 }
00335 
00336 
00338 
00341 void RuleDiskManager::returnRules(list<Rule *> *ruleList)
00342 {
00343     for(list<Rule *>::iterator i = ruleList->begin(); i != ruleList->end(); i++)
00344     {
00345         controller->newRule((*i));
00346     }   
00347 }

Generated on Fri Sep 1 23:55:14 2006 for NanoComp by  doxygen 1.4.6