00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
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
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
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)
00206 {
00207
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))
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
00248
00249 for(int i = 0; i < width * height; i++)
00250 {
00251 switch (lexer->yylex())
00252 {
00253 case NUMBER:
00254 {
00255 if (atoi(lexer->YYText()) > 1)
00256 {
00257
00258 delete rule;
00259 return false;
00260 }
00261 else
00262 {
00263 if (atoi(lexer->YYText()))
00264 {
00265
00266 rule->cellChanged(i - width * (i/width), i/width, nENABLED, nINITIAL);
00267 }
00268 else
00269 {
00270
00271 rule->cellChanged(i - width * (i/width), i/width, nDISABLED, nINITIAL);
00272 }
00273 }
00274 break;
00275 }
00276 case POINT:
00277 {
00278
00279 rule->cellChanged(i - width * (i/width), i/width, nDONTCARE, nINITIAL);
00280 break;
00281 }
00282 default:
00283 {
00284
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:
00296 {
00297 if (atoi(lexer->YYText()) > 1)
00298 {
00299
00300 return false;
00301 }
00302 else
00303 {
00304 if (atoi(lexer->YYText()))
00305 {
00306
00307 rule->cellChanged(i - width * (i/width), i/width, nENABLED, nFINAL);
00308 }
00309 else
00310 {
00311
00312 rule->cellChanged(i - width * (i/width), i/width, nDISABLED, nFINAL);
00313 }
00314 }
00315 break;
00316 }
00317 case POINT:
00318 {
00319
00320
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:
00326 {
00327
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 }