Back to index

salome-kernel  6.5.0
CalciumCxxInterface.hxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library 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 GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 //  File   : CalciumCxxInterface.hxx
00021 //  Author : Eric Fayolle (EDF)
00022 //  Module : KERNEL
00023 // Modified by : $LastChangedBy$
00024 // Date        : $LastChangedDate: 2007-03-01 13:27:58 +0100 (jeu, 01 mar 2007) $
00025 // Id          : $Id: CalciumCxxInterface.hxx,v 1.3.2.5.14.3.12.1 2012-04-12 14:05:06 vsr Exp $
00026 //
00027 #ifndef _CALCIUM_CXXINTERFACE_HXX_
00028 #define _CALCIUM_CXXINTERFACE_HXX_
00029 
00030 #if defined(__CONST_H) || defined(__CALCIUM_H)
00031 #error "The header CalciumCxxInterface.hxx must be included before calcium.h"
00032 #endif
00033 
00034 #include <string>
00035 #include <vector>
00036 #include <iostream>
00037 #include "Superv_Component_i.hxx"
00038 #include "CalciumException.hxx"
00039 #include "CalciumTypes.hxx"
00040 #include "CalciumGenericUsesPort.hxx"
00041 #include "Copy2UserSpace.hxx"
00042 #include "Copy2CorbaSpace.hxx"
00043 #include "CalciumPortTraits.hxx"
00044 
00045 #include <stdio.h>
00046 
00047 #include <typeinfo>
00048 
00049 template <typename T1, typename T2>
00050 struct IsSameType {
00051   static const bool value = false;
00052 };
00053 template <typename T1>
00054 struct IsSameType<T1,T1> {
00055   static const bool value = true;
00056 };
00057 
00058 extern const char * CPMESSAGE[];
00059 
00060 //#define MYDEBUG
00061 
00062 #include <boost/type_traits/remove_all_extents.hpp>
00063 
00064 namespace CalciumInterface {
00065   
00066   /********************* CONNECTION INTERFACE *****************/
00067 
00068   static inline void
00069   ecp_cd (Superv_Component_i & component, std::string & instanceName)
00070   { 
00071     /* TODO : Trouver le nom de l'instance SALOME*/
00072     CORBA::String_var componentName=component.instanceName();
00073     std::string containerName=component.getContainerName();
00074     if (instanceName.empty()) instanceName=componentName;
00075     Engines_DSC_interface::writeEvent("CP_CD",containerName,componentName,"","","");
00076   }
00077 
00078   static inline void
00079   ecp_fin (Superv_Component_i & component, bool provideLastGivenValue)
00080   { 
00081     CORBA::String_var componentName=component.instanceName();
00082     std::string containerName=component.getContainerName();
00083     Engines_DSC_interface::writeEvent("CP_FIN",containerName,componentName,"","","");
00084 
00085     std::vector<std::string> usesPortNames;
00086     std::vector<std::string>::const_iterator it;
00087     component.get_uses_port_names(usesPortNames);    
00088     
00089     //Récupérer le type de réel du port est un peu difficile
00090     //car l'interface ne donne aucune indication
00091 
00092     //     uses_port *myUsesPort;
00093     calcium_uses_port* myCalciumUsesPort;
00094       
00095     for (it=usesPortNames.begin(); it != usesPortNames.end(); ++it) 
00096       {
00097         try 
00098           {
00099             myCalciumUsesPort= component.Superv_Component_i::get_port< calcium_uses_port >((*it).c_str());
00100 
00101 //         component.Superv_Component_i::get_port(myUsesPort,(*it).c_str());
00102 //         calcium_uses_port* myCalciumUsesPort=
00103 //           dynamic_cast<calcium_uses_port*>(myUsesPort);
00104 
00105 #ifdef MYDEBUG
00106             std::cerr << "-------- CalciumInterface(ecp_fin) MARK 1 -|"<< *it <<"|----"<< 
00107           //          typeid(myUsesPort).name() <<"-------------" <<
00108               typeid(myCalciumUsesPort).name() <<"-------------" << std::endl;
00109 #endif
00110         
00111 //         if ( !myCalciumUsesPort )
00112 //           throw Superv_Component_i::BadCast(LOC(OSS()<<"Impossible de convertir le port "
00113 //                                                 << *it << " en port de type calcium_uses_port." ));
00114 
00115             myCalciumUsesPort->disconnect(provideLastGivenValue);
00116           }
00117         catch ( const Superv_Component_i::BadCast & ex) 
00118           {
00119             Engines_DSC_interface::writeEvent("CP_FIN",containerName,componentName,"",CPMESSAGE[CalciumTypes::CPTPVR],ex.what());
00120             throw (CalciumException(CalciumTypes::CPTPVR,ex));
00121           }
00122         catch ( const DSC_Exception & ex) 
00123           {
00124             Engines_DSC_interface::writeEvent("CP_FIN",containerName,componentName,"",CPMESSAGE[CalciumTypes::CPOK],ex.what());
00125             // Exception venant de SupervComponent :
00126             //   PortNotDefined(CPNMVR), PortNotConnected(CPLIEN)  
00127             // ou du port uses : Dsc_Exception
00128             // On continue à traiter la deconnexion des autres ports uses
00129           }
00130         catch (...) 
00131           {
00132             Engines_DSC_interface::writeEvent("CP_FIN",containerName,componentName,"",CPMESSAGE[CalciumTypes::CPATAL],"Unexpected exception");
00133             throw (CalciumException(CalciumTypes::CPATAL,"Unexpected exception"));
00134             // En fonction du mode de gestion des erreurs throw;
00135           }
00136       }
00137   }
00138 
00139 
00140   /********************* INTERFACES DE DESALLOCATION  *****************/
00141 
00142   // Uniquement appelé par l'utilisateur s'il utilise la 0 copie
00143   //   ( pointeur de données data==NULL à l'appel de ecp_lecture )
00144   // Une désallocation aura lieu uniquement si un buffer intermédiaire
00145   // était necessaire (type utilisateur et corba diffférent)
00146   // La propriété du buffer est rendue à CORBA sinon  
00147   template <typename T1, typename T2> static void
00148   ecp_free ( T1 * dataPtr )
00149   {
00150     typedef typename ProvidesPortTraits<T2>::PortType     PortType;
00151     typedef typename PortType::DataManipulator            DataManipulator;
00152     typedef typename DataManipulator::Type                DataType; // Attention != T1
00153     typedef typename DataManipulator::InnerType           InnerType;
00154 
00155     DeleteTraits<IsSameType<T1,InnerType>::value, DataManipulator >::apply(dataPtr);
00156   }
00157 
00158   template <typename T1> static void
00159   ecp_free ( T1 * dataPtr )
00160   {
00161     ecp_free<T1,T1> ( dataPtr );
00162   }
00163 
00164 
00165   /********************* READING INTERFACE *****************/
00166 
00167 
00168   // T1 est le type de données
00169   // T2 est un <nom> de type Calcium permettant de sélectionner le port CORBA correspondant 
00170   // T1 et T2 sont dissociés pour discriminer par exemple le cas des nombres complexes
00171   //  -> Les données des nombres complexes sont de type float mais
00172   //     le port à utiliser est le port cplx
00173   template <typename T1, typename T2 > static void
00174   ecp_lecture ( Superv_Component_i & component,
00175                int    const  & dependencyType,
00176                double        & ti,
00177                double const  & tf,
00178                long          & i,
00179                const std::string  & nomVar, 
00180                size_t          bufferLength,
00181                size_t        & nRead, 
00182                T1            * &data )
00183   {
00184 
00185     assert(&component);
00186     CORBA::String_var componentName=component.instanceName();
00187     std::string containerName=component.getContainerName();
00188 
00189     typedef typename ProvidesPortTraits<T2>::PortType     PortType;
00190     typedef typename PortType::DataManipulator            DataManipulator;
00191     typedef typename DataManipulator::Type                CorbaDataType; // Attention != T1
00192     typedef typename DataManipulator::InnerType           InnerType;
00193     CalciumTypes::DependencyType _dependencyType=                
00194       static_cast<CalciumTypes::DependencyType>(dependencyType);
00195     
00196     CorbaDataType     corbaData;
00197 
00198 #ifdef MYDEBUG
00199     std::cerr << "-------- CalciumInterface(ecp_lecture) MARK 1 ------------------" << std::endl;
00200 #endif
00201 
00202     if (nomVar.empty())
00203       {
00204         Engines_DSC_interface::writeEvent("BEGIN_READ",containerName,componentName,"",CPMESSAGE[CalciumTypes::CPNMVR],"");
00205         throw CalciumException(CalciumTypes::CPNMVR, LOC("Empty variable name"));
00206       }
00207     PortType * port;
00208 #ifdef MYDEBUG
00209     std::cout << "-------- CalciumInterface(lecture) MARK 2 --"<<typeid(port).name()<<"----------------" << std::endl;
00210     T1 t1;
00211     T2 t2;
00212     std::cout << "-------- CalciumInterface(lecture) MARK 2b1 -----" << typeid(t1).name() << "-------------" << std::endl;
00213     std::cout << "-------- CalciumInterface(lecture) MARK 2b2 -----" << typeid(t2).name() << "-------------" << std::endl;
00214 #endif
00215 
00216     try 
00217       {
00218         port  = component.Superv_Component_i::get_port< PortType > (nomVar.c_str());
00219 #ifdef MYDEBUG
00220         std::cout << "-------- CalciumInterface(ecp_lecture) MARK 3 ------------------" << std::endl;
00221 #endif
00222       }
00223     catch ( const Superv_Component_i::PortNotDefined & ex) 
00224       {
00225         Engines_DSC_interface::writeEvent("BEGIN_READ",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPNMVR],ex.what());
00226         throw (CalciumException(CalciumTypes::CPNMVR,ex));
00227       }
00228     catch ( const Superv_Component_i::PortNotConnected & ex) 
00229       {
00230         Engines_DSC_interface::writeEvent("BEGIN_READ",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPLIEN],ex.what());
00231         throw (CalciumException(CalciumTypes::CPLIEN,ex)); 
00232         // VERIFIER LES CAS DES CODES : CPINARRET, CPSTOPSEQ, CPCTVR, CPLIEN
00233       }
00234     catch ( const Superv_Component_i::BadCast & ex) 
00235       {
00236         Engines_DSC_interface::writeEvent("BEGIN_READ",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPTPVR],ex.what());
00237         throw (CalciumException(CalciumTypes::CPTPVR,ex));
00238       }
00239   
00240     // mode == mode du port 
00241     CalciumTypes::DependencyType portDependencyType = port->getDependencyType();
00242 
00243     if ( portDependencyType == CalciumTypes::UNDEFINED_DEPENDENCY )
00244       {
00245         Engines_DSC_interface::writeEvent("BEGIN_READ",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPIT],"Dependency mode is undefined");
00246         throw CalciumException(CalciumTypes::CPIT, LOC(OSS()<<"Dependency mode of variable " << nomVar << " is undefined."));
00247       }
00248 
00249     if ( ( portDependencyType != _dependencyType ) && ( _dependencyType != CalciumTypes::SEQUENCE_DEPENDENCY ) ) 
00250       {
00251         Engines_DSC_interface::writeEvent("BEGIN_READ",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPIT],
00252                    "Dependency mode is not the same as the required one");
00253         throw CalciumException(CalciumTypes::CPITVR, LOC(OSS()<<"Dependency mode of variable " << nomVar << ": " 
00254                                 << portDependencyType << " is not the same as the required one."));
00255       }
00256 
00257   
00258     std::stringstream msgout,msg;
00259     if ( _dependencyType == CalciumTypes::TIME_DEPENDENCY ) 
00260       {
00261         try
00262           {
00263             double   tt=ti;
00264             msg << "ti=" << ti << ", tf=" << tf ;
00265             Engines_DSC_interface::writeEvent("BEGIN_READ",containerName,componentName,nomVar.c_str(),"",msg.str().c_str());
00266             corbaData = port->get(tt,tf, 0);
00267             msgout << "read t=" << tt ;
00268 #ifdef MYDEBUG
00269             std::cout << "-------- CalciumInterface(ecp_lecture) MARK 5 ------------------" << std::endl;
00270 #endif
00271           }
00272         catch ( const DSC_Exception & ex)
00273           {
00274             Engines_DSC_interface::writeEvent("END_READ",containerName,componentName,nomVar.c_str(),"",ex.what());
00275             throw;
00276           }
00277       } 
00278     else if ( _dependencyType == CalciumTypes::ITERATION_DEPENDENCY ) 
00279       {
00280         try
00281           {
00282             msg << "i=" << i ;
00283             Engines_DSC_interface::writeEvent("BEGIN_READ",containerName,componentName,nomVar.c_str(),"",msg.str().c_str());
00284             corbaData = port->get(0, i);
00285             msgout << "read i=" << i ;
00286 #ifdef MYDEBUG
00287             std::cout << "-------- CalciumInterface(ecp_lecture) MARK 6 ------------------" << std::endl;
00288 #endif
00289           }
00290         catch ( const DSC_Exception & ex)
00291           {
00292             Engines_DSC_interface::writeEvent("END_READ",containerName,componentName,nomVar.c_str(),"",ex.what());
00293             throw;
00294           }
00295       } 
00296     else 
00297       {
00298         // Sequential read
00299         try
00300           {
00301 #ifdef MYDEBUG
00302             std::cout << "-------- CalciumInterface(ecp_lecture) MARK 7 ------------------" << std::endl;
00303 #endif
00304             Engines_DSC_interface::writeEvent("BEGIN_READ",containerName,componentName,nomVar.c_str(),"","Sequential read");
00305             corbaData = port->next(ti,i);
00306             msgout << "read ";
00307             if(i==0)msgout<< "t=" <<ti;
00308             else msgout<< "i=" <<i;
00309           }
00310         catch ( const DSC_Exception & ex)
00311           {
00312             Engines_DSC_interface::writeEvent("END_READ",containerName,componentName,nomVar.c_str(),"",ex.what());
00313             throw;
00314           }
00315       }
00316  
00317 #ifdef MYDEBUG
00318     std::cout << "-------- CalciumInterface(ecp_lecture) MARK 8 ------------------" << std::endl;
00319 #endif
00320     size_t corbaDataSize = DataManipulator::size(corbaData);
00321 #ifdef MYDEBUG
00322     std::cout << "-------- CalciumInterface(ecp_lecture) corbaDataSize : " << corbaDataSize << std::endl;
00323 #endif
00324    
00325     // Vérifie si l'utilisateur demande du 0 copie
00326     if ( data == NULL ) 
00327       {
00328         if ( bufferLength != 0 ) 
00329           {
00330             MESSAGE("bufferLength devrait valoir 0 pour l'utilisation du mode sans copie (data==NULL)");
00331           }
00332         nRead = corbaDataSize;
00333         // Si les types T1 et InnerType sont différents, il faudra effectuer tout de même une recopie
00334         if (!IsSameType<T1,InnerType>::value) data = new T1[nRead];
00335 #ifdef MYDEBUG
00336         std::cout << "-------- CalciumInterface(ecp_lecture) MARK 9 ------------------" << std::endl;
00337 #endif
00338         // On essaye de faire du 0 copy si les types T1 et InnerType sont les mêmes.
00339         // Copy2UserSpace : 
00340         // La raison d'être du foncteur Copy2UserSpace est qu'il n'est pas possible de compiler
00341         // une expression d'affectation sur des types incompatibles ; même 
00342         // si cette expression se trouve dans une branche non exécuté d'un test
00343         // portant sur la compatibilité des types.
00344         // En utilisant le foncteur Copy2UserSpace, seule la spécialisation en adéquation
00345         // avec la compatibilité des types sera compilée 
00346         Copy2UserSpace< IsSameType<T1,InnerType>::value, DataManipulator >::apply(data,corbaData,nRead);
00347 #ifdef MYDEBUG
00348         std::cout << "-------- CalciumInterface(ecp_lecture) MARK 10 ------------------" << std::endl;
00349 #endif
00350         // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non
00351         // la donnée corba associée à un DataId ! Ne pas effectuer la desallocation suivante :
00352         // DataManipulator::delete_data(corbaData); 
00353         // ni DataManipulator::getPointer(corbaData,true); qui détruit la sequence lorsque l'on
00354         // prend la propriété du buffer
00355         //  old : Dans les deux cas la structure CORBA n'est plus utile 
00356         //  old : Si !IsSameType<T1,InnerType>::value l'objet CORBA est détruit avec son contenu
00357         //  old : Dans l'autre cas seul la coquille CORBA est détruite 
00358         //  L'utilisateur devra appeler ecp_free qui déterminera s'il est necessaire
00359         //  de désallouer un buffer intermédiaire ( types différents) ou de rendre la propriété
00360       }
00361     else 
00362       {
00363         nRead = std::min < size_t > (corbaDataSize,bufferLength);
00364 #ifdef MYDEBUG
00365         std::cout << "-------- CalciumInterface(ecp_lecture) MARK 11 ------------------" << std::endl;
00366 #endif
00367         Copy2UserSpace<false, DataManipulator >::apply(data,corbaData,nRead);
00368         //Déjà fait ci-dessus : 
00369         //DataManipulator::copy(corbaData,data,nRead);
00370 #ifdef MYDEBUG
00371         std::cout << "-------- CalciumInterface(ecp_lecture) MARK 12 ------------------" << std::endl;
00372 #endif
00373       }
00374 #ifdef MYDEBUG
00375     std::cout << "-------- CalciumInterface(ecp_lecture), Valeur de data : " << std::endl;
00376     std::copy(data,data+nRead,std::ostream_iterator<T1>(std::cout," "));
00377     std::cout << "Ptr :" << data << std::endl;
00378     std::cout << "-------- CalciumInterface(ecp_lecture) MARK 13 ------------------" << std::endl;
00379 #endif
00380     Engines_DSC_interface::writeEvent("END_READ",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPOK],msgout.str().c_str());
00381     return;
00382   }
00383 
00384   // T1 is the data type
00385   template <typename T1 > static void
00386   ecp_lecture ( Superv_Component_i & component,
00387                int    const      & dependencyType,
00388                double            & ti,
00389                double const      & tf,
00390                long              & i,
00391                const std::string & nomVar, 
00392                size_t              bufferLength,
00393                size_t            & nRead, 
00394                T1                * &data )
00395   {
00396     ecp_lecture<T1,T1> (component,dependencyType,ti,tf,
00397                         i,nomVar,bufferLength,nRead,data);
00398   
00399   }
00400 
00401   /********************* WRITING INTERFACE *****************/
00402 
00403   // T1 : DataType
00404   // T2 : PortType
00405   template <typename T1, typename T2> static void
00406   ecp_ecriture ( Superv_Component_i & component,
00407                  int    const      & dependencyType,
00408                  double const      & t,
00409                  long   const      & i,
00410                  const std::string & nomVar, 
00411                  size_t              bufferLength,
00412                  T1                  const  & data ) 
00413   {
00414     
00415     assert(&component);
00416     CORBA::String_var componentName=component.instanceName();
00417     std::string containerName=component.getContainerName();
00418 
00419     //typedef typename StarTrait<TT>::NonStarType                    T;
00420     typedef typename boost::remove_all_extents< T1 >::type           T1_without_extent;
00421     typedef typename boost::remove_all_extents< T2 >::type           T2_without_extent;
00422     typedef typename UsesPortTraits    <T2_without_extent>::PortType UsesPortType;
00423     typedef typename ProvidesPortTraits<T2_without_extent>::PortType ProvidesPortType;// pour obtenir un manipulateur de données
00424     typedef typename ProvidesPortType::DataManipulator               DataManipulator;
00425     // Verifier que l'on peut définir UsesPortType::DataManipulator
00426     //    typedef typename PortType::DataManipulator            DataManipulator;
00427     typedef typename DataManipulator::Type                           CorbaDataType; // Attention != T1
00428     typedef typename DataManipulator::InnerType                      InnerType;
00429     
00430     T1_without_extent const & _data = data;
00431 
00432     CalciumTypes::DependencyType _dependencyType=                
00433       static_cast<CalciumTypes::DependencyType>(dependencyType);
00434 
00435 #ifdef MYDEBUG
00436     std::cerr << "-------- CalciumInterface(ecriture) MARK 1 ------------------" << std::endl;
00437 #endif
00438     if ( nomVar.empty() )
00439       {
00440         Engines_DSC_interface::writeEvent("WRITE",containerName,componentName,"",CPMESSAGE[CalciumTypes::CPNMVR],"");
00441         throw CalciumException(CalciumTypes::CPNMVR, LOC("Empty variable name"));
00442       }
00443     UsesPortType * port;
00444 #ifdef MYDEBUG
00445     std::cout << "-------- CalciumInterface(ecriture) MARK 2 ---"<<typeid(port).name()<<"---------------" << std::endl;
00446     T1 t1;
00447     T2 t2;
00448     std::cout << "-------- CalciumInterface(ecriture) MARK 2b1 -----" << typeid(t1).name() << "-------------" << std::endl;
00449     std::cout << "-------- CalciumInterface(ecriture) MARK 2b2 -----" << typeid(t2).name() << "-------------" << std::endl;
00450 #endif
00451 
00452     try 
00453       {
00454         port  = component.Superv_Component_i::get_port< UsesPortType > (nomVar.c_str());
00455 #ifdef MYDEBUG
00456         std::cout << "-------- CalciumInterface(ecriture) MARK 3 ------------------" << std::endl;
00457 #endif
00458       }
00459     catch ( const Superv_Component_i::PortNotDefined & ex) 
00460       {
00461         Engines_DSC_interface::writeEvent("WRITE",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPNMVR],ex.what());
00462         throw (CalciumException(CalciumTypes::CPNMVR,ex));
00463       }
00464     catch ( const Superv_Component_i::PortNotConnected & ex) 
00465       {
00466         Engines_DSC_interface::writeEvent("WRITE",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPLIEN],ex.what());
00467         throw (CalciumException(CalciumTypes::CPLIEN,ex)); 
00468         // VERIFIER LES CAS DES CODES : CPINARRET, CPSTOPSEQ, CPCTVR, CPLIEN
00469       }
00470     catch ( const Superv_Component_i::BadCast & ex) 
00471       {
00472         Engines_DSC_interface::writeEvent("WRITE",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPTPVR],ex.what());
00473         throw (CalciumException(CalciumTypes::CPTPVR,ex));
00474       }
00475  
00476     // mode == mode du port 
00477     // On pourrait créer la méthode CORBA dans le mode de Couplage CALCIUM.
00478     // et donc ajouter cette cette méthode uniquement dans l'IDL calcium !
00479 
00480 //     CalciumTypes::DependencyType portDependencyType;
00481 //     try {
00482 //       portDependencyType = port->getDependencyType();
00483 //       std::cout << "-------- CalciumInterface(ecriture) MARK 4 ------------------" << std::endl;
00484 //     } catch ( const DSC_Exception & ex ) {
00485 //       std::cerr << ex.what() << std::endl;;
00486 //       throw (CalciumException(CalciumTypes::CPIT,ex));
00487 //     }
00488 
00489     if ( _dependencyType == CalciumTypes::UNDEFINED_DEPENDENCY )
00490       {
00491         Engines_DSC_interface::writeEvent("WRITE",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPIT],"Dependency mode is undefined");
00492         throw CalciumException(CalciumTypes::CPIT, LOC(OSS()<<"Dependency mode of variable " << nomVar << " is undefined."));
00493       }
00494 
00495     if ( _dependencyType == CalciumTypes::SEQUENCE_DEPENDENCY )
00496       {
00497         Engines_DSC_interface::writeEvent("WRITE",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPIT],
00498                    "SEQUENCE_DEPENDENCY mode is not possible when writing");
00499         throw CalciumException(CalciumTypes::CPIT, LOC(OSS()<<"Dependency mode SEQUENCE_DEPENDENCY for variable " << nomVar 
00500                                << " is not possible when writing."));
00501       }
00502 
00503     // Il faudrait que le port provides génère une exception si le mode donnée n'est pas
00504     // le bon. La seule façon de le faire est d'envoyer -1 en temps si on n'est en itération
00505     // et vice-versa pour informer les provides port du mode dans lequel on est. Sinon il faut
00506     // modifier l'interface IDL pour y ajouter un mode de dépendance !
00507     // ---->
00508 //     if ( portDependencyType != _dependencyType ) 
00509 //       throw CalciumException(CalciumTypes::CPITVR,
00510 //                                 LOC(OSS()<<"Le mode de dépendance de la variable " 
00511 //                                     << nomVar << " ne correspond pas au mode demandé."));
00512 
00513   
00514     if ( bufferLength < 1 )
00515       {
00516         Engines_DSC_interface::writeEvent("WRITE",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPNTNULL],"Buffer to send is empty");
00517         throw CalciumException(CalciumTypes::CPNTNULL, LOC(OSS()<<"Buffer to send is empty"));
00518       }
00519 
00520     CorbaDataType corbaData;
00521 #ifdef MYDEBUG
00522     std::cout << "-------- CalciumInterface(ecriture) MARK 4 ------------------" << std::endl;
00523 #endif
00524     
00525     // Si les types Utilisateurs et CORBA sont différents
00526     // il faut effectuer une recopie sinon on utilise directement le
00527     // buffer data pour constituer la séquence
00528     // TODO : 
00529     // - Attention en mode asynchrone il faudra eventuellement
00530     //   faire une copie des données même si elles sont de même type.
00531     // - OLD : En cas de collocalisation (du port provide et du port uses)
00532     //   OLD : il est necessaire d'effectuer une recopie du buffer car la
00533     //   OLD : séquence est envoyée au port provide par une référence sur 
00534     //   OLD : la séquence locale. Or la méthode put récupère le buffer directement
00535     //   OLD : qui est alors le buffer utilisateur. Il pourrait alors arriver que :
00536     //   OLD :   * Le recepteur efface le buffer emetteur
00537     //   OLD :   * Le port lui-même efface le buffer de l'utilisateur !
00538     //   OLD : Cette copie est effectuée dans GenericPortUses::put 
00539     //   OLD : en fonction de la collocalisation ou non.
00540     // - OLD :En cas de connection multiples d'un port uses distant vers plusieurs port provides
00541     //   OLD : collocalisés les ports provides partagent la même copie de la donnée ! 
00542     //   OLD : Il faut effectuer une copie dans le port provides.
00543     //   OLD : Cette copie est effectuée dans GenericPortUses::put 
00544     //   OLD : en fonction de la collocalisation ou non.
00545 #ifdef MYDEBUG
00546     T1_without_extent t1b;
00547     InnerType         t2b;
00548     std::cout << "-------- CalciumInterface(ecriture) MARK 4b1 -----" << typeid(t1b).name() << "-------------" << std::endl;
00549     std::cout << "-------- CalciumInterface(ecriture) MARK 4b2 -----" << typeid(t2b).name() << "-------------" << std::endl;
00550 #endif
00551 
00552     Copy2CorbaSpace<IsSameType<T1_without_extent,InnerType>::value, DataManipulator >::apply(corbaData,_data,bufferLength);
00553  
00554     //TODO : GERER LES EXCEPTIONS ICI : ex le port n'est pas connecte
00555     if ( _dependencyType == CalciumTypes::TIME_DEPENDENCY ) 
00556       {
00557         try
00558           {
00559             port->put(*corbaData,t, -1); 
00560             std::stringstream msg;
00561             msg << "t=" << t ;
00562             Engines_DSC_interface::writeEvent("WRITE",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPOK],msg.str().c_str());
00563           }
00564         catch ( const DSC_Exception & ex) 
00565           {
00566             Engines_DSC_interface::writeEvent("WRITE",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPATAL],ex.what());
00567             throw (CalciumException(CalciumTypes::CPATAL,ex.what()));
00568           }
00569         //Le -1 peut être traité par le cst DataIdContainer et transformé en 0 
00570         //Etre obligé de mettre une étoile ds (*corbadata) va poser des pb pour les types <> seq
00571 #ifdef MYDEBUG
00572         std::cout << "-------- CalciumInterface(ecriture) MARK 5 ------------------" << std::endl;
00573 #endif
00574       } 
00575     else if ( _dependencyType == CalciumTypes::ITERATION_DEPENDENCY ) 
00576       {
00577         try
00578           {
00579             port->put(*corbaData,-1, i);
00580             std::stringstream msg;
00581             msg << "i=" << i ;
00582             Engines_DSC_interface::writeEvent("WRITE",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPOK],msg.str().c_str());
00583           }
00584         catch ( const DSC_Exception & ex) 
00585           {
00586             Engines_DSC_interface::writeEvent("WRITE",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPATAL],ex.what());
00587             throw (CalciumException(CalciumTypes::CPATAL,ex.what()));
00588           }
00589 #ifdef MYDEBUG
00590         std::cout << "-------- CalciumInterface(ecriture) MARK 6 ------------------" << std::endl;
00591 #endif
00592       } 
00593     
00594 #ifdef MYDEBUG
00595     std::cout << "-------- CalciumInterface(ecriture), Valeur de corbaData : " << std::endl;
00596     for (int i = 0; i < corbaData->length(); ++i)
00597       std::cout << "-------- CalciumInterface(ecriture), corbaData[" << i << "] = " << (*corbaData)[i] << std::endl;
00598 #endif
00599     
00600     //    if ( !IsSameType<T1,InnerType>::value ) delete corbaData;
00601     // Supprime l'objet CORBA avec eventuellement les données qu'il contient (cas de la recopie)
00602     delete corbaData;
00603 
00604 #ifdef MYDEBUG
00605     std::cout << "-------- CalciumInterface(ecriture) MARK 7 ------------------" << std::endl;
00606 #endif
00607    
00608     return;
00609   };
00610   
00611   template <typename T1> static void
00612   ecp_ecriture ( Superv_Component_i & component,
00613                  int    const  & dependencyType,
00614                  double const  & t,
00615                  long   const  & i,
00616                  const std::string  & nomVar, 
00617                  size_t bufferLength,
00618                  T1 const & data ) 
00619   {
00620     ecp_ecriture<T1,T1> (component,dependencyType,t,i,nomVar,bufferLength,data); 
00621   };
00622 
00623   static inline void
00624   ecp_fini(Superv_Component_i & component,const std::string  & nomVar,long const  & i)
00625   {
00626     CORBA::String_var componentName=component.instanceName();
00627     std::string containerName=component.getContainerName();
00628 
00629     if (nomVar.empty())
00630       {
00631         Engines_DSC_interface::writeEvent("CP_FINI",containerName,componentName,"",CPMESSAGE[CalciumTypes::CPNMVR],"");
00632         throw CalciumException(CalciumTypes::CPNMVR, LOC("Empty variable name"));
00633       }
00634 
00635     calcium_provides_port* port;
00636 
00637     try
00638       {
00639         port = component.Superv_Component_i::get_port< calcium_provides_port >(nomVar.c_str());
00640       }
00641     catch ( const Superv_Component_i::PortNotDefined & ex)
00642       {
00643         Engines_DSC_interface::writeEvent("CP_FINI",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPNMVR],ex.what());
00644         throw (CalciumException(CalciumTypes::CPNMVR,ex));
00645       }
00646     catch ( const Superv_Component_i::PortNotConnected & ex)
00647       {
00648         Engines_DSC_interface::writeEvent("CP_FINI",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPLIEN],ex.what());
00649         throw (CalciumException(CalciumTypes::CPLIEN,ex));
00650       }
00651     catch ( const Superv_Component_i::BadCast & ex)
00652       {
00653         Engines_DSC_interface::writeEvent("CP_FINI",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPTPVR],ex.what());
00654         throw (CalciumException(CalciumTypes::CPTPVR,ex));
00655       }
00656 
00657     // get dependency mode
00658     CalciumTypes::DependencyType portDependencyType = port->getDependencyType();
00659 
00660     if ( portDependencyType == CalciumTypes::UNDEFINED_DEPENDENCY )
00661       {
00662         Engines_DSC_interface::writeEvent("CP_FINI",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPIT],"Dependency mode is undefined");
00663         throw CalciumException(CalciumTypes::CPIT, LOC(OSS()<<"Dependency mode of variable " << nomVar << " is undefined."));
00664       }
00665 
00666     if ( portDependencyType != CalciumTypes::ITERATION_DEPENDENCY )
00667       {
00668         Engines_DSC_interface::writeEvent("CP_FINI",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPIT],
00669                    "Dependency mode must be iteration mode");
00670         throw CalciumException(CalciumTypes::CPITVR, LOC(OSS()<<"Dependency mode of variable " << nomVar << ": "
00671                                 << portDependencyType << " must be iteration mode."));
00672       }
00673 
00674     port->calcium_erase(0., i,true);
00675 
00676     std::stringstream msg;
00677     msg << "i<=" << i ;
00678     Engines_DSC_interface::writeEvent("CP_FINI",containerName,componentName,nomVar.c_str(),"",msg.str().c_str());
00679 
00680   };
00681 
00682   static inline void
00683   ecp_fint(Superv_Component_i & component,const std::string  & nomVar,double const  & t)
00684   {
00685     CORBA::String_var componentName=component.instanceName();
00686     std::string containerName=component.getContainerName();
00687 
00688     if (nomVar.empty())
00689       {
00690         Engines_DSC_interface::writeEvent("CP_FINT",containerName,componentName,"",CPMESSAGE[CalciumTypes::CPNMVR],"");
00691         throw CalciumException(CalciumTypes::CPNMVR, LOC("Empty variable name"));
00692       }
00693 
00694     calcium_provides_port* port;
00695 
00696     try
00697       {
00698         port = component.Superv_Component_i::get_port< calcium_provides_port >(nomVar.c_str());
00699       }
00700     catch ( const Superv_Component_i::PortNotDefined & ex)
00701       {
00702         Engines_DSC_interface::writeEvent("CP_FINT",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPNMVR],ex.what());
00703         throw (CalciumException(CalciumTypes::CPNMVR,ex));
00704       }
00705     catch ( const Superv_Component_i::PortNotConnected & ex)
00706       {
00707         Engines_DSC_interface::writeEvent("CP_FINT",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPLIEN],ex.what());
00708         throw (CalciumException(CalciumTypes::CPLIEN,ex));
00709       }
00710     catch ( const Superv_Component_i::BadCast & ex)
00711       {
00712         Engines_DSC_interface::writeEvent("CP_FINT",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPTPVR],ex.what());
00713         throw (CalciumException(CalciumTypes::CPTPVR,ex));
00714       }
00715 
00716     // get dependency mode
00717     CalciumTypes::DependencyType portDependencyType = port->getDependencyType();
00718 
00719     if ( portDependencyType == CalciumTypes::UNDEFINED_DEPENDENCY )
00720       {
00721         Engines_DSC_interface::writeEvent("CP_FINT",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPIT],"Dependency mode is undefined");
00722         throw CalciumException(CalciumTypes::CPIT, LOC(OSS()<<"Dependency mode of variable " << nomVar << " is undefined."));
00723       }
00724 
00725     if ( portDependencyType != CalciumTypes::TIME_DEPENDENCY )
00726       {
00727         Engines_DSC_interface::writeEvent("CP_FINT",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPIT],
00728                    "Dependency mode must be time mode");
00729         throw CalciumException(CalciumTypes::CPITVR, LOC(OSS()<<"Dependency mode of variable " << nomVar << ": "
00730                                 << portDependencyType << " must be time mode."));
00731       }
00732 
00733     port->calcium_erase(t, 0,true);
00734 
00735     std::stringstream msg;
00736     msg << "t<=" << t ;
00737     Engines_DSC_interface::writeEvent("CP_FINT",containerName,componentName,nomVar.c_str(),"",msg.str().c_str());
00738 
00739   };
00740 
00741   static inline void
00742   ecp_effi(Superv_Component_i & component,const std::string  & nomVar,long const  & i)
00743   {
00744     CORBA::String_var componentName=component.instanceName();
00745     std::string containerName=component.getContainerName();
00746 
00747     if (nomVar.empty())
00748       {
00749         Engines_DSC_interface::writeEvent("CP_EFFI",containerName,componentName,"",CPMESSAGE[CalciumTypes::CPNMVR],"");
00750         throw CalciumException(CalciumTypes::CPNMVR, LOC("Empty variable name"));
00751       }
00752 
00753     calcium_provides_port* port;
00754 
00755     try
00756       {
00757         port = component.Superv_Component_i::get_port< calcium_provides_port >(nomVar.c_str());
00758       }
00759     catch ( const Superv_Component_i::PortNotDefined & ex)
00760       {
00761         Engines_DSC_interface::writeEvent("CP_EFFI",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPNMVR],ex.what());
00762         throw (CalciumException(CalciumTypes::CPNMVR,ex));
00763       }
00764     catch ( const Superv_Component_i::PortNotConnected & ex)
00765       {
00766         Engines_DSC_interface::writeEvent("CP_EFFI",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPLIEN],ex.what());
00767         throw (CalciumException(CalciumTypes::CPLIEN,ex));
00768       }
00769     catch ( const Superv_Component_i::BadCast & ex)
00770       {
00771         Engines_DSC_interface::writeEvent("CP_EFFI",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPTPVR],ex.what());
00772         throw (CalciumException(CalciumTypes::CPTPVR,ex));
00773       }
00774 
00775     // get dependency mode
00776     CalciumTypes::DependencyType portDependencyType = port->getDependencyType();
00777 
00778     if ( portDependencyType == CalciumTypes::UNDEFINED_DEPENDENCY )
00779       {
00780         Engines_DSC_interface::writeEvent("CP_EFFI",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPIT],"Dependency mode is undefined");
00781         throw CalciumException(CalciumTypes::CPIT, LOC(OSS()<<"Dependency mode of variable " << nomVar << " is undefined."));
00782       }
00783 
00784     if ( portDependencyType != CalciumTypes::ITERATION_DEPENDENCY )
00785       {
00786         Engines_DSC_interface::writeEvent("CP_EFFI",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPIT],
00787                    "Dependency mode must be iteration mode");
00788         throw CalciumException(CalciumTypes::CPITVR, LOC(OSS()<<"Dependency mode of variable " << nomVar << ": "
00789                                 << portDependencyType << " must be iteration mode."));
00790       }
00791 
00792     port->calcium_erase(0., i,false);
00793 
00794     std::stringstream msg;
00795     msg << "i>=" << i ;
00796     Engines_DSC_interface::writeEvent("CP_EFFI",containerName,componentName,nomVar.c_str(),"",msg.str().c_str());
00797 
00798   };
00799 
00800   static inline void
00801   ecp_efft(Superv_Component_i & component,const std::string  & nomVar,double const  & t)
00802   {
00803     CORBA::String_var componentName=component.instanceName();
00804     std::string containerName=component.getContainerName();
00805 
00806     if (nomVar.empty())
00807       {
00808         Engines_DSC_interface::writeEvent("CP_EFFT",containerName,componentName,"",CPMESSAGE[CalciumTypes::CPNMVR],"");
00809         throw CalciumException(CalciumTypes::CPNMVR, LOC("Empty variable name"));
00810       }
00811 
00812     calcium_provides_port* port;
00813 
00814     try
00815       {
00816         port = component.Superv_Component_i::get_port< calcium_provides_port >(nomVar.c_str());
00817       }
00818     catch ( const Superv_Component_i::PortNotDefined & ex)
00819       {
00820         Engines_DSC_interface::writeEvent("CP_EFFT",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPNMVR],ex.what());
00821         throw (CalciumException(CalciumTypes::CPNMVR,ex));
00822       }
00823     catch ( const Superv_Component_i::PortNotConnected & ex)
00824       {
00825         Engines_DSC_interface::writeEvent("CP_EFFT",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPLIEN],ex.what());
00826         throw (CalciumException(CalciumTypes::CPLIEN,ex));
00827       }
00828     catch ( const Superv_Component_i::BadCast & ex)
00829       {
00830         Engines_DSC_interface::writeEvent("CP_EFFT",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPTPVR],ex.what());
00831         throw (CalciumException(CalciumTypes::CPTPVR,ex));
00832       }
00833 
00834     // get dependency mode
00835     CalciumTypes::DependencyType portDependencyType = port->getDependencyType();
00836 
00837     if ( portDependencyType == CalciumTypes::UNDEFINED_DEPENDENCY )
00838       {
00839         Engines_DSC_interface::writeEvent("CP_EFFT",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPIT],"Dependency mode is undefined");
00840         throw CalciumException(CalciumTypes::CPIT, LOC(OSS()<<"Dependency mode of variable " << nomVar << " is undefined."));
00841       }
00842 
00843     if ( portDependencyType != CalciumTypes::TIME_DEPENDENCY )
00844       {
00845         Engines_DSC_interface::writeEvent("CP_EFFT",containerName,componentName,nomVar.c_str(),CPMESSAGE[CalciumTypes::CPIT],
00846                    "Dependency mode must be time mode");
00847         throw CalciumException(CalciumTypes::CPITVR, LOC(OSS()<<"Dependency mode of variable " << nomVar << ": "
00848                                 << portDependencyType << " must be time mode."));
00849       }
00850 
00851     port->calcium_erase(t, 0,false);
00852 
00853     std::stringstream msg;
00854     msg << "t>=" << t ;
00855     Engines_DSC_interface::writeEvent("CP_EFFT",containerName,componentName,nomVar.c_str(),"",msg.str().c_str());
00856 
00857   };
00858 
00859 };
00860 
00861 #endif