| |
libFAUDES
Sections
Index
|
rtifncts.cppGo to the documentation of this file.00001 /** @file rtifncts.cpp Runtime interface, operations on faudes types */ 00002 00003 /* FAU Discrete Event Systems Library (libfaudes) 00004 00005 Copyright (C) 2009 Ruediger Berndt 00006 Copyright (C) 2009 Thomas Moor 00007 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Lesser General Public 00010 License as published by the Free Software Foundation; either 00011 version 2.1 of the License, or (at your option) any later version. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Lesser General Public License for more details. 00017 00018 You should have received a copy of the GNU Lesser General Public 00019 License along with this library; if not, write to the Free Software 00020 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00021 00022 00023 #include "rtifncts.h" 00024 #include "rtiregistry.h" 00025 00026 00027 namespace faudes{ 00028 00029 /* 00030 ******************************************************************** 00031 ******************************************************************** 00032 ******************************************************************** 00033 00034 Implementation of class Signature 00035 00036 ******************************************************************** 00037 ******************************************************************** 00038 ******************************************************************** 00039 */ 00040 00041 00042 // clear signature 00043 void Signature::Clear(void){ 00044 FD_DRTI("Signature::Clear()"); 00045 mName=""; 00046 mParameters.clear(); 00047 } 00048 00049 // get name 00050 const std::string& Signature::Name(void) const{ 00051 return mName; 00052 } 00053 00054 // set name 00055 void Signature::Name(const std::string& rName){ 00056 mName = rName; 00057 } 00058 00059 // get size 00060 int Signature::Size() const{ 00061 return mParameters.size(); 00062 } 00063 00064 // get parameter 00065 const Parameter& Signature::At(int n) const{ 00066 // check range 00067 if((n < 0) || (n > Size())){ 00068 std::stringstream err; 00069 err << "Index out of range: " << n << std::endl; 00070 throw Exception("Signature::Param()", err.str(), 47); 00071 } 00072 // return const ref 00073 return mParameters.at(n); 00074 } 00075 00076 // append parameter 00077 void Signature::Append(const Parameter& rParam){ 00078 mParameters.push_back(rParam); 00079 } 00080 00081 00082 00083 // token io 00084 void Signature::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const{ 00085 // ignore 00086 (void) rLabel; 00087 (void) pContext; 00088 // write my section 00089 //FD_DRTI("Signature::DoWrite(): file " << rTw.FileName()); 00090 rTw.WriteBegin("Signature"); 00091 // name 00092 rTw.WriteString(mName); 00093 rTw << "\n"; 00094 rTw << "\n"; 00095 // parameter specs 00096 int intOldCols = rTw.Columns(); 00097 rTw.Columns(3); 00098 for(int i=0; i<Size(); i++){ 00099 rTw << mParameters.at(i).mName; 00100 rTw << mParameters.at(i).mTDName; 00101 switch(mParameters.at(i).mAttr){ 00102 case Parameter::In: rTw.WriteOption("In"); break; 00103 case Parameter::Out: rTw.WriteOption("Out"); break; 00104 case Parameter::InOut: rTw.WriteOption("InOut"); break; 00105 default: rTw.WriteOption("UnDef"); break; 00106 } 00107 } 00108 rTw.Columns(intOldCols); 00109 // end section 00110 rTw << "\n"; 00111 rTw.WriteEnd("Signature"); 00112 } 00113 00114 // token io 00115 void Signature::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext){ 00116 // ignore 00117 (void) rLabel; 00118 (void) pContext; 00119 // read my section 00120 FD_DRTI("Signature::DoRead(): file " << rTr.FileName()); 00121 rTr.ReadBegin("Signature"); 00122 mName=rTr.ReadString(); 00123 FD_DRTI("Signature::DoRead(): found " << mName); 00124 // loop parameters 00125 while(!rTr.Eos("Signature")) { 00126 std::string pname=rTr.ReadString(); 00127 std::string ptype=rTr.ReadString(); 00128 Parameter::ParamAttr pattr= Parameter::UnDef; 00129 Token token; 00130 rTr.Peek(token); 00131 if(token.Type()==Token::Option){ 00132 if(token.StringValue()=="In") pattr= Parameter::In; 00133 if(token.StringValue()=="Out") pattr= Parameter::Out; 00134 if(token.StringValue()=="InOut") pattr= Parameter::InOut; 00135 if(token.StringValue()=="OutIn") pattr= Parameter::InOut; 00136 rTr.Get(token); 00137 } 00138 Append(Parameter(pname,ptype,pattr)); 00139 } 00140 // done 00141 rTr.ReadEnd("Signature"); 00142 FD_DRTI("Signature::DoRead(): done"); 00143 } 00144 00145 00146 00147 00148 /* 00149 ******************************************************************** 00150 ******************************************************************** 00151 ******************************************************************** 00152 00153 Implementation of class FunctionDefinition 00154 00155 ******************************************************************** 00156 ******************************************************************** 00157 ******************************************************************** 00158 */ 00159 00160 00161 // clear (all but prototype) 00162 void FunctionDefinition::Clear(){ 00163 FD_DRTI("FunctionDefinition::Clear(): " << Name()); 00164 // call base 00165 Documentation::Clear(); 00166 // clear my variants 00167 mVariants.clear(); 00168 mVariantIndexMap.clear(); 00169 } 00170 00171 // get prototype object 00172 const Function* FunctionDefinition::Prototype(void) const{ 00173 return(mpFunction); 00174 } 00175 00176 // set prototype object 00177 void FunctionDefinition::Prototype(Function* pFunc){ 00178 // delte any existing prototype 00179 if(mpFunction) delete mpFunction; 00180 // record new prototype 00181 mpFunction = pFunc; 00182 // bail out 00183 if(!mpFunction) return; 00184 // ensure that our prototype uses us as function definition 00185 mpFunction->Definition(this); 00186 } 00187 00188 // construct function on head 00189 Function* FunctionDefinition::NewFunction() const{ 00190 FD_DRTI("FunctionDefinition::NewFunction()"); 00191 if(!mpFunction) return NULL; 00192 return(mpFunction->New()); 00193 } 00194 00195 00196 // # of variants 00197 int FunctionDefinition::VariantsSize() const{ 00198 return(mVariants.size()); 00199 } 00200 00201 // existence of variant by name 00202 bool FunctionDefinition::ExistsVariant(const std::string& varname) const { 00203 return mVariantIndexMap.find(varname)!= mVariantIndexMap.end(); 00204 } 00205 00206 // get index by variant name 00207 int FunctionDefinition::VariantIndex(const std::string& rName) const { 00208 std::map<std::string,int>::const_iterator vit= mVariantIndexMap.find(rName); 00209 if(vit==mVariantIndexMap.end()) return -1; 00210 return vit->second; 00211 } 00212 00213 // extend variants 00214 void FunctionDefinition::AppendVariant(const Signature& rVariant){ 00215 FD_DRTI("FunctionDefinition::AppendVariant()"); 00216 // assure that no variant with the same name is yet contained in the list 00217 if(ExistsVariant(rVariant.Name())) { 00218 std::stringstream err; 00219 err << "Attempt to append variant with existing name: " << rVariant.Name() << " in " << Name() << std::endl; 00220 throw Exception("FunctionDefinition::AppendVariant()", err.str(), 47); 00221 } 00222 // do append 00223 mVariantIndexMap[rVariant.Name()]=mVariants.size(); 00224 mVariants.push_back(rVariant); 00225 } 00226 00227 00228 // get signature by variant name 00229 const Signature& FunctionDefinition::Variant(const std::string& rName) const{ 00230 std::map<std::string,int>::const_iterator vit= mVariantIndexMap.find(rName); 00231 if(vit==mVariantIndexMap.end()) { 00232 std::stringstream err; 00233 err << "Access to non existing variant " << rName << " in fnct " << Name() << std::endl; 00234 throw Exception("FunctionDefinition::Variant()", err.str(), 47); 00235 } 00236 return mVariants.at(vit->second); 00237 } 00238 00239 00240 // get signature by variant index 00241 const Signature& FunctionDefinition::Variant(int n) const{ 00242 // check range 00243 if((n < 0) || (n >= VariantsSize())){ 00244 std::stringstream err; 00245 err << "Index out of range: " << n << std::endl; 00246 throw Exception("FunctionDefinition::Variant()", err.str(), 47); 00247 } 00248 return mVariants.at(n); 00249 } 00250 00251 00252 // merge with docu/variants from token io 00253 void FunctionDefinition::MergeDocumentationBody(TokenReader& rTr) { 00254 // peek function ident 00255 Token token; 00256 rTr.Peek(token); 00257 // extract name 00258 std::string name=token.StringValue(); 00259 size_t pos=name.find("::"); 00260 if(pos!=std::string::npos) name=name.substr(pos+2); 00261 // match? 00262 if(mName!=name && mName!="") { 00263 std::stringstream errstr; 00264 errstr << "Documentation mismatch in file \"" << rTr.FileName() << "\""; 00265 throw Exception("FunctionDefinition::MergeDocumentationBody", errstr.str(), 48); 00266 }; 00267 // call base 00268 Documentation::DoRead(rTr); 00269 // do variants 00270 rTr.ReadBegin("VariantSignatures"); 00271 while(!rTr.Eos("VariantSignatures")) { 00272 Signature sig; 00273 sig.Read(rTr); 00274 // no doublets 00275 if(ExistsVariant(sig.Name())) continue; 00276 // std signature? 00277 if(sig.Name().find("##") == std::string::npos) { 00278 AppendVariant(sig); 00279 continue; 00280 } 00281 // automatic parameters (cosmetic) 00282 for(int i=2; i<FD_RTIMAXSIG; i++ ) { 00283 Signature sigi; 00284 sigi.Name(StringSubstitute(sig.Name(),"##",ToStringInteger(i))); 00285 // loop parameters 00286 for(int j=0; j<sig.Size(); j++) { 00287 // std parameter: append 00288 if(sig.At(j).mName.find("##") == std::string::npos) { 00289 sigi.Append(sig.At(j)); 00290 continue; 00291 } 00292 // automatic parameter 00293 Parameter park=sig.At(j); 00294 for(int k=1; k<=i; k++) { 00295 park.mName = StringSubstitute(sig.At(j).mName,"##",ToStringInteger(k)); 00296 sigi.Append(park); 00297 } 00298 } 00299 // append variant signature 00300 AppendVariant(sigi); 00301 } // end: automatic para 00302 } // end: !EOS 00303 rTr.ReadEnd("VariantSignatures"); 00304 } 00305 00306 00307 // token io 00308 void FunctionDefinition::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) { 00309 // ignore 00310 (void) rLabel; 00311 (void) pContext; 00312 // doit 00313 rTr.ReadBegin("FunctionDefinition"); 00314 // peek and set type name 00315 Token token; 00316 rTr.Peek(token); 00317 // extract name 00318 std::string mName=token.StringValue(); 00319 size_t pos=mName.find("::"); 00320 if(pos!=std::string::npos) mName=mName.substr(pos+2); 00321 // do read 00322 MergeDocumentationBody(rTr); 00323 // no extras .. done 00324 rTr.ReadEnd("FunctionDefinition"); 00325 } 00326 00327 00328 // token io 00329 void FunctionDefinition::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 00330 // ignore 00331 (void) rLabel; 00332 (void) pContext; 00333 // my section 00334 rTw.WriteBegin("FunctionDefinition"); 00335 // call base 00336 Documentation::DoWrite(rTw); 00337 rTw << "\n"; 00338 // write signatures 00339 rTw.WriteBegin("VariantSignatures"); 00340 rTw << "\n"; 00341 for(unsigned int i=0; i<mVariants.size(); i++) { 00342 mVariants.at(i).Write(rTw); 00343 rTw << "\n"; 00344 } 00345 rTw.WriteEnd("VariantSignatures"); 00346 rTw << "\n"; 00347 rTw.WriteEnd("FunctionDefitinion"); 00348 } 00349 00350 00351 /* 00352 ******************************************************************** 00353 ******************************************************************** 00354 ******************************************************************** 00355 00356 Implementation of class Function 00357 00358 ******************************************************************** 00359 ******************************************************************** 00360 ******************************************************************** 00361 */ 00362 00363 // Constructor 00364 Function::Function(const FunctionDefinition* fdef) : 00365 pFuncDef(fdef), 00366 mVariantIndex(-1) 00367 { 00368 #ifdef FAUDES_DEBUG_RUNTIMEINTERFACE 00369 if(!pFuncDef) 00370 {FD_DRTI("Function::Function(): prototype object");} 00371 else 00372 {FD_DRTI("Function::Function(): " << pFuncDef->Name());} 00373 #endif 00374 // have default variant 00375 if(pFuncDef) 00376 if(pFuncDef->VariantsSize()>0) 00377 Variant(0); 00378 } 00379 00380 // set function definition 00381 void Function::Definition(const FunctionDefinition* fdef) { 00382 // invalidate variant 00383 mVariantIndex = -1; 00384 mParameterValues.clear(); 00385 // set 00386 pFuncDef=fdef; 00387 // report 00388 #ifdef FAUDES_DEBUG_RUNTIMEINTERFACE 00389 if(!pFuncDef) 00390 {FD_DRTI("Function::Definition(): prototype object");} 00391 else 00392 {FD_DRTI("Function::Definition(): " << pFuncDef->Name());} 00393 #endif 00394 } 00395 00396 // get function definition 00397 const FunctionDefinition* Function::Definition(void) const { 00398 return pFuncDef; 00399 } 00400 00401 00402 // get signature size 00403 int Function::VariantsSize(void) const { 00404 if(!pFuncDef) return 0; 00405 return pFuncDef->VariantsSize(); 00406 } 00407 00408 // set variant signature 00409 void Function::Variant(int n) { 00410 // clear recent variant 00411 mVariantIndex=-1; 00412 mParameterValues.clear(); 00413 // prototype object can not have a variant 00414 if(!pFuncDef) { 00415 std::stringstream err; 00416 err << "No valid function definition available" << std::endl; 00417 throw Exception("Function::Variant(n)", err.str(), 47); 00418 } 00419 // index out of ragne 00420 if(n<0 || n >= VariantsSize()) { 00421 std::stringstream err; 00422 err << "Variant index out of range" << std::endl; 00423 throw Exception("Function::Variant(n)", err.str(), 48); 00424 } 00425 // set variant 00426 mVariantIndex=n; 00427 int nparam = pFuncDef->Variant(mVariantIndex).Size(); 00428 while((int) mParameterValues.size()<nparam) 00429 mParameterValues.push_back(0); 00430 } 00431 00432 // set variant signature 00433 void Function::Variant(const std::string& rVariantName) { 00434 // prototype object can not have a variant 00435 if(!pFuncDef) { 00436 std::stringstream err; 00437 err << "No valid function definition available" << std::endl; 00438 throw Exception("Function::Variant(name)", err.str(), 47); 00439 } 00440 // get index 00441 int varid = pFuncDef->VariantIndex(rVariantName); 00442 // detect invalid name 00443 if(varid<0) { 00444 std::stringstream err; 00445 err << "Unknown varaiant name " << rVariantName << std::endl; 00446 throw Exception("Function::Variant(name)", err.str(), 47); 00447 } 00448 // set by index 00449 Variant(varid); 00450 } 00451 00452 // get signature 00453 const Signature* Function::Variant(void) const { 00454 if(!pFuncDef) return 0; 00455 if(mVariantIndex<0) return 0; 00456 return &pFuncDef->Variant(mVariantIndex); 00457 } 00458 00459 // get signature size 00460 int Function::ParamsSize(void) const { 00461 return mParameterValues.size(); 00462 } 00463 00464 // set parameter value 00465 void Function::ParamValue(int n, Type* pVal){ 00466 if((n < 0) || (n >= ParamsSize())){ 00467 std::stringstream err; 00468 err << "Parameter index out of range: " << n << std::endl; 00469 throw Exception("Function::ParamValue()", err.str(), 47); 00470 } 00471 mParameterValues.at(n) = pVal; 00472 } 00473 00474 // get parameter 00475 Type* Function::ParamValue(int n) const{ 00476 if((n < 0) || (n >= ParamsSize())){ 00477 std::stringstream err; 00478 err << "Parameter index out of range: " << n << std::endl; 00479 throw Exception("Function::ParamValue()", err.str(), 47); 00480 } 00481 return(mParameterValues.at(n)); 00482 } 00483 00484 00485 // allocate parameter value 00486 void Function::AllocateValue(int n) { 00487 FD_DRTI("Function::AllocateValue()"); 00488 if(!Variant()) { 00489 std::stringstream err; 00490 err << "No variant specified"; 00491 throw Exception("Function::AllocateValue()", err.str(), 47); 00492 } 00493 if((n < 0) || (n >= ParamsSize())){ 00494 std::stringstream err; 00495 err << "Parameter index out of range: " << n << std::endl; 00496 throw Exception("Function::AllocateValue()", err.str(), 47); 00497 } 00498 ParamValue(n,TypeRegistry::G()->NewObject(Variant()->At(n).mTDName)); 00499 } 00500 00501 // allocate parameter value 00502 void Function::AllocateValues(void) { 00503 FD_DRTI("Function::AllocateValues()"); 00504 for(int i = 0; i < ParamsSize(); i++) 00505 AllocateValue(i); 00506 } 00507 00508 // allocate parameter value 00509 void Function::FreeValues(void) { 00510 FD_DRTI("Function::FreeValues()"); 00511 for(int i = 0; i < ParamsSize(); i++) { 00512 delete mParameterValues.at(i); 00513 mParameterValues.at(i) =0; 00514 } 00515 } 00516 00517 00518 // type check wrapper 00519 bool Function::TypeCheck(int n) { 00520 FD_DRTI("Function::TypeCheck()"); 00521 if(mVariantIndex<0) { 00522 std::stringstream err; 00523 err << "Variant not set" << std::endl; 00524 throw Exception("Function::TypeCheck(n)", err.str(), 48); 00525 } 00526 if(n<0 || n>= ParamsSize()) { 00527 std::stringstream err; 00528 err << "Parameter out of range" << std::endl; 00529 throw Exception("Function::Typechek(n)", err.str(), 48); 00530 } 00531 bool res=DoTypeCheck(n); 00532 FD_DRTI("Function::TypeCheck() done, ok=" << res); 00533 return res; 00534 } 00535 00536 // type check wrapper 00537 bool Function::TypeCheck(void) { 00538 FD_DRTI("Function::TypeCheck()"); 00539 if(mVariantIndex<0) { 00540 std::stringstream err; 00541 err << "Variant not set" << std::endl; 00542 throw Exception("Function::TypeCheck()", err.str(), 48); 00543 } 00544 for(int i=0; i<ParamsSize(); i++) 00545 if(!DoTypeCheck(i)) return false; 00546 FD_DRTI("Function::TypeCheck() done, ok"); 00547 return true; 00548 } 00549 00550 // exec wrapper 00551 void Function::Execute(void){ 00552 FD_DRTI("Function::Execute()"); 00553 if(!Variant()) { 00554 std::stringstream err; 00555 err << "Variant not set" << std::endl; 00556 throw Exception("Function::Execute()", err.str(), 48); 00557 } 00558 for(int n=0; n<ParamsSize(); n++) { 00559 if(!DoTypeCheck(n)) { 00560 std::stringstream err; 00561 err << "Cannot cast parameter \"" << Variant()->At(n).mName << 00562 "\" to type \"" << Variant()->At(n).mTDName << "\""; 00563 throw Exception("Function::Execute()", err.str(), 48); 00564 } 00565 } 00566 DoExecute(); 00567 FD_DRTI("Function::Execute() done"); 00568 } 00569 00570 00571 // token io (informative/debug) 00572 void Function::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const{ 00573 (void) pContext; 00574 std::string label = rLabel; 00575 if(label == "") label = "Function"; 00576 FD_DRTI("Function::DoWrite(): file " << rTw.FileName() << " section " << label); 00577 rTw.Columns(1); 00578 rTw.WriteBegin(label); 00579 rTw << "\n"; 00580 rTw.WriteBegin("Parameters"); 00581 for(int i = 0; i < ParamsSize(); i++){ 00582 rTw << typeid(ParamValue(i)).name(); 00583 rTw << "\n"; 00584 } 00585 rTw.WriteEnd("Parameters"); 00586 rTw << "\n"; 00587 rTw.WriteEnd(label); 00588 FD_DRTI("Function::DoWrite(): done"); 00589 } 00590 00591 00592 } // namespace 00593 |
libFAUDES 2.14g --- 2009-12-3 --- c++ source docu by doxygen 1.5.6