libFAUDES

Sections

Index

rtifncts.cpp

Go 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