SALOME documentation central

src/DSC/DSC_User/Datastream/Calcium/CalciumCxxInterface.hxx

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