]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
*** empty log message ***
authorfayolle <fayolle>
Wed, 13 Feb 2008 15:20:57 +0000 (15:20 +0000)
committerfayolle <fayolle>
Wed, 13 Feb 2008 15:20:57 +0000 (15:20 +0000)
13 files changed:
src/DSC/DSC_User/Datastream/Calcium/Calcium.c
src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.hxx
src/DSC/DSC_User/Datastream/Calcium/CalciumCxxInterface.hxx [new file with mode: 0644]
src/DSC/DSC_User/Datastream/Calcium/CalciumInterface.hxx
src/DSC/DSC_User/Datastream/Calcium/CalciumPortTraits.hxx
src/DSC/DSC_User/Datastream/Calcium/Copy2CorbaSpace.hxx
src/DSC/DSC_User/Datastream/Calcium/Copy2UserSpace.hxx
src/DSC/DSC_User/Datastream/Calcium/Makefile.am
src/DSC/DSC_User/Datastream/CorbaTypeManipulator.hxx
src/DSC/DSC_User/Datastream/CouplingPolicy.hxx
src/DSC/DSC_User/Datastream/GenericPort.hxx
src/DSC/DSC_User/Datastream/GenericUsesPort.hxx
src/DSC/DSC_User/Superv_Component_i.hxx

index de497f752af6381047af73857084ba4a057fc16e..12bfcb6b31489c129e1ef2f475761978ac2dc73b 100644 (file)
 typedef int InfoType;
 typedef int bool;
 
-// INTERFACES DE LECTURE
+// INTERFACES DE LECTURE en 0 copie
 
+// Definition des méthodes calcium étendues en 0 copie
+// Le buffer est alloué par le port pas par l'utilisateur
+// Remarquer le type ** de data
+// L'utilisateur devra appeler ecp_..._free pour désallouer le buffer interne
+// Attention en cas de lectures multiples : le buffer retourné est le même
+// Attention si les niveaux sont actifs le buffer peut être supprimé automatiquement par calcium.
 
-// Definition des méthodes calcium étendues 
-// permettant le 0 copy.
-//const char * nomvar
 #define CALCIUM_EXT_LECT_INTERFACE_C_(_name,_timeType,_type,_typeName,_qual) \
   InfoType ecp_##_name (void * component, int mode,                    \
                        _timeType * ti, _timeType * tf, int * i,        \
@@ -70,48 +73,74 @@ typedef int bool;
     ecp_lecture_##_typeName##_free(data);                                      \
   };
 
+#define STAR *
 CALCIUM_EXT_LECT_INTERFACE_C_(len,float,int,int,);
 CALCIUM_EXT_LECT_INTERFACE_C_(lre,float,float,float,);
 CALCIUM_EXT_LECT_INTERFACE_C_(ldb,double,double,double,);
 CALCIUM_EXT_LECT_INTERFACE_C_(llo,float,bool,bool,);
 CALCIUM_EXT_LECT_INTERFACE_C_(lcp,float,float,cplx,);
-#define STAR *
-//  CALCIUM_EXT_LECT_INTERFACE_C_(lch,float,char,STAR[]); 
-// La signature n'est pas la même pour les chaines de caractères il y a aussi 
-// la taille des chaines
+//CALCIUM_EXT_LECT_INTERFACE_C_(lch,float,char,STAR[]); 
+
+
 
-//const char * nomvar
+// INTERFACES DE LECTURE avec recopie
 
-#define CALCIUM_LECT_INTERFACE_C_(_name,_timeType,_type,_typeName,_qual)               \
+#define CALCIUM_LECT_INTERFACE_C_(_name,_timeType,_type,_typeName,_qual) \
   InfoType cp_##_name (void * component, int mode,                     \
                       _timeType * ti, _timeType * tf, int * i,         \
                       char * nomvar, int bufferLength,                 \
                       int * nRead, _type _qual * data ) {              \
     size_t _nRead;                                                     \
     long   _i=*i;                                                      \
-    fflush(stdout);           \
-    fflush(stderr);           \
-    fprintf(stderr,"Beginning of CPLxx: %s %d %f\n",nomvar,*i,*ti); \
+    fflush(stdout);                                                    \
+    fflush(stderr);                                                    \
+    fprintf(stderr,"Beginning of cpl" #_name " : %s %d %f\n",nomvar,*i,*ti); \
                                                                        \
     if ( (data == NULL) || (bufferLength < 1) ) return CPNTNULL;       \
                                                                        \
-    InfoType info =  ecp_lecture_##_typeName (component, mode, ti, tf, &_i,    \
+    InfoType info =  ecp_lecture_##_typeName (component, mode, ti, tf, &_i, \
                                         nomvar, bufferLength, &_nRead, \
-                                        &data );                       \
-    if(mode == CP_SEQUENTIEL)   \
-      *i = _i;                                                 \
+                                             &data );                  \
+    if(mode == CP_SEQUENTIEL)                                          \
+      *i = _i;                                                         \
     *nRead=_nRead;                                                     \
-    fprintf(stderr,"End of CPLxx: %s %d \n",nomvar,*i); \
-    fflush(stdout);           \
-    fflush(stderr);           \
+    fprintf(stderr,"End of cpl" #_name " : %s %d \n",nomvar,*i);               \
+    fflush(stdout);                                                    \
+    fflush(stderr);                                                    \
                                                                        \
     return info;                                                       \
   };                                                                   \
   void cp_##_name##_free ( _type _qual * data) {                       \
-    ecp_lecture_##_typeName##_free(data);                                      \
+    ecp_lecture_##_typeName##_free(data);                              \
   };
 
 
+
+InfoType cp_lch(void * component, int mode, float * ti,        float * tf, int * i,
+               char  * nomvar, int bufferLength, int * nRead,
+               char ** data, int strSize) {
+
+  size_t _nRead;                                                       
+  long   _i=*i;                                                        
+  fflush(stdout);fflush(stderr);                                                       
+  fprintf(stderr,"Beginning of cplch: %s %d %f\n",nomvar,*i,*ti);      
+                                                                       
+  if ( (data == NULL) || (bufferLength < 1) ) return CPNTNULL; 
+  
+  InfoType info =  ecp_lecture_str (component, mode, ti, tf, &_i, 
+                                   nomvar, bufferLength, &_nRead, 
+                                   &data);/*, strSize );*/
+  if(mode == CP_SEQUENTIEL)                                            
+    *i = _i;                                                           
+  *nRead=_nRead;                                                       
+  fprintf(stderr,"End of cplch: %s %d \n",nomvar,*i);                  
+  fflush(stdout);fflush(stderr);                                                       
+                                                                       
+  return info;                                                 
+};                                                                     
+
+
+
 // Definition des méthodes calcium standard 
 
 CALCIUM_LECT_INTERFACE_C_(len,float,int,int,);
@@ -139,6 +168,7 @@ InfoType cp_fin (void * component, int code) {
 }
 
 
+// INTERFACES D'ECRITURE 
 
 #define CALCIUM_ECR_INTERFACE_C_(_name,_timeType,_type,_typeName,_qual)        \
   InfoType cp_##_name (void * component, int mode,                     \
@@ -147,22 +177,42 @@ InfoType cp_fin (void * component, int code) {
                       _type _qual * data ) {                           \
                                                                        \
     /*long   _i=i;*/                                                   \
-    fflush(stdout);           \
-    fflush(stderr);           \
-    fprintf(stderr,"Beginning of CPExx: %s %d %f\n",nomvar,i,t); \
+    fflush(stdout);                                                    \
+    fflush(stderr);                                                    \
+    fprintf(stderr,"Beginning of cpe" #_name " : %s %d %f\n",nomvar,i,t);      \
     if ( (data == NULL) || (nbelem < 1) ) return CPNTNULL;             \
                                                                        \
     InfoType info =  ecp_ecriture_##_typeName (component, mode, &t, i, \
                                               nomvar, nbelem,          \
                                               data );                  \
-    fprintf(stderr,"End of CPExx: %s %d \n",nomvar,i); \
-    fflush(stdout);           \
-    fflush(stderr);           \
+    fprintf(stderr,"End of cpe" #_name " : %s %d \n",nomvar,i);                \
+    fflush(stdout);                                                    \
+    fflush(stderr);                                                    \
                                                                        \
     return info;                                                       \
   };                                                                   \
 
 
+
+InfoType cp_ech(void * component, int mode, float t, int i,
+               char  * nomvar,  int nbelem,
+               char ** data, int strSize) {
+                                                                       
+  /*long   _i=i;*/                                                     
+  fflush(stdout);fflush(stderr);                                                       
+  fprintf(stderr,"Beginning of cpech: %s %d %f\n",nomvar,i,t); 
+  if ( (data == NULL) || (nbelem < 1) ) return CPNTNULL;               
+    
+  InfoType info =  ecp_ecriture_str (component, mode, &t, i,   
+                                    nomvar, nbelem,            
+                                    data);/*, strSize );*/
+  fprintf(stderr,"End of cpech: %s %d \n",nomvar,i);                   
+  fflush(stdout);                                                      
+  fflush(stderr);                                                      
+                                                                       
+  return info;                                                 
+};                                                                     
+
 // Definition des méthodes calcium standard 
 
 CALCIUM_ECR_INTERFACE_C_(een,float,int,int,);
index a6c301ee67596f2e9b385f8f0de1f6df44163ee3..1fe1c0e5b04ee4876376b18c51fa66463cfcc48f 100644 (file)
@@ -34,6 +34,8 @@
 #include "CouplingPolicy.hxx"
 #include "AdjacentFunctor.hxx"
 #include <boost/lambda/lambda.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_arithmetic.hpp>
 #include "CalciumTypes.hxx"
 #include "CalciumException.hxx"
 
@@ -44,7 +46,8 @@ public:
 
   template <typename T_TIME, typename T_TAG >        class InternalDataIdContainer;
   template <typename T_TIME, typename T_TAG > friend class InternalDataIdContainer;
-  template <typename DataManipulator >        friend class BoundedDataIdProcessor;
+  template <typename DataManipulator, 
+    class EnableIf >                  friend class BoundedDataIdProcessor;
   template <typename DataManipulator >        friend class EraseDataIdProcessor;
   template <typename DataManipulator >        friend class DisconnectProcessor;
 
@@ -103,8 +106,9 @@ public:
   inline TimeType getTime(const DataId &dataId) const { return dataId.first;}
   inline TagType  getTag (const DataId &dataId) const { return dataId.second;}
 
-  // TODO : Vérifier l'application pour tous les types de données
-  template <typename DataManipulator>  struct BoundedDataIdProcessor;
+  template <typename DataManipulator, 
+           class EnableIf = void >    struct BoundedDataIdProcessor;
+  //template <typename DataManipulator>  struct BoundedDataIdProcessor;
   template <typename DataManipulator>  struct EraseDataIdProcessor;
   template <typename DataManipulator>  struct DisconnectProcessor;
 
@@ -157,10 +161,24 @@ struct CalciumCouplingPolicy::InternalDataIdContainer : public std::vector< std:
 };
 
 
-// TODO : Vérifier l'application pour tous les types de données
-// DESACTIVER POUR ?BOOL? et CHAR *
-template <typename DataManipulator>
+template <typename DataManipulator, class EnableIf >
 struct CalciumCouplingPolicy::BoundedDataIdProcessor{
+  BoundedDataIdProcessor(const CouplingPolicy & couplingPolicy) {};
+  template < typename Iterator, typename DataId > 
+  void inline apply(typename iterator_t<Iterator>::value_type & data,
+                   const DataId & dataId,
+                   const Iterator  & it1) const {
+    typedef typename iterator_t<Iterator>::value_type value_type;
+    std::cout << "-------- Calcium Generic BoundedDataIdProcessor.apply() called " << std::endl;
+
+  }
+};
+
+
+template <typename DataManipulator >
+struct CalciumCouplingPolicy::BoundedDataIdProcessor<
+  DataManipulator, 
+  typename boost::enable_if< boost::is_float< typename DataManipulator::InnerType> >::type > {
     
   const CalciumCouplingPolicy & _couplingPolicy;
     
@@ -232,8 +250,8 @@ struct CalciumCouplingPolicy::BoundedDataIdProcessor{
 
       boost::lambda::placeholder1_type _1;
       boost::lambda::placeholder2_type _2;
-      // REM : Pour des buffers de type int
-      // le compilo indiquera warning: converting to `long int' from `Double'
+      // OLD: REM : Pour des buffers de type int
+      // OLD: le compilo indiquera warning: converting to `long int' from `Double'
       std::transform(InIt1,InIt1+dataSize,InIt2,OutIt,
                             ( _1 - _2 ) * coeff + _2 );
 //       for(size_t i =0;  i < dataSize3; ++i) {
diff --git a/src/DSC/DSC_User/Datastream/Calcium/CalciumCxxInterface.hxx b/src/DSC/DSC_User/Datastream/Calcium/CalciumCxxInterface.hxx
new file mode 100644 (file)
index 0000000..39565be
--- /dev/null
@@ -0,0 +1,500 @@
+//  Copyright (C) 2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+//  File   : CalciumCxxInterface.hxx
+//  Author : Eric Fayolle (EDF)
+//  Module : KERNEL
+// Modified by : $LastChangedBy$
+// Date        : $LastChangedDate: 2007-03-01 13:27:58 +0100 (jeu, 01 mar 2007) $
+// Id          : $Id$
+
+#ifndef _CALCIUM_CXXINTERFACE_HXX_
+#define _CALCIUM_CXXINTERFACE_HXX_
+
+#include <string>
+#include <vector>
+#include <iostream>
+#include "Superv_Component_i.hxx"
+#include "CalciumException.hxx"
+#include "CalciumTypes.hxx"
+#include "CalciumGenericUsesPort.hxx"
+#include "Copy2UserSpace.hxx"
+#include "Copy2CorbaSpace.hxx"
+#include "CalciumPortTraits.hxx"
+
+#include <stdio.h>
+
+//#define _DEBUG_
+
+template <typename T1, typename T2>
+struct IsSameType {
+  static const bool value = false;
+};
+template <typename T1>
+struct IsSameType<T1,T1> {
+  static const bool value = true;
+};
+
+
+
+namespace CalciumInterface {
+  
+  /********************* INTERFACE DE DECONNEXION *****************/
+
+  static void
+  ecp_fin (Superv_Component_i & component, bool provideLastGivenValue)
+  { 
+    std::vector<std::string> usesPortNames;
+    std::vector<std::string>::const_iterator it;
+    component.get_uses_port_names(usesPortNames);    
+    
+    //récupérer le type de réel du port est un peu difficile
+    //car l'interface nous donne aucune indication
+
+    //     uses_port *myUsesPort;
+    calcium_uses_port* myCalciumUsesPort;
+      
+    for (it=usesPortNames.begin(); it != usesPortNames.end(); ++it) {
+      try {
+
+       myCalciumUsesPort= 
+         component.Superv_Component_i::get_port< calcium_uses_port >((*it).c_str());
+
+//     component.Superv_Component_i::get_port(myUsesPort,(*it).c_str());
+//     calcium_uses_port* myCalciumUsesPort=
+//       dynamic_cast<calcium_uses_port*>(myUsesPort);
+
+#ifdef _DEBUG_
+       std::cerr << "-------- CalciumInterface(ecp_fin) MARK 1 -|"<< *it <<"|----"<< 
+         //      typeid(myUsesPort).name() <<"-------------" <<
+         typeid(myCalciumUsesPort).name() <<"-------------" << std::endl;
+#endif
+       
+//     if ( !myCalciumUsesPort )
+//       throw Superv_Component_i::BadCast(LOC(OSS()<<"Impossible de convertir le port "
+//                                             << *it << " en port de type calcium_uses_port." ));
+
+       myCalciumUsesPort->disconnect(provideLastGivenValue);
+
+      } catch ( const Superv_Component_i::BadCast & ex) {
+#ifdef _DEBUG_
+       std::cerr << ex.what() << std::endl;
+#endif
+       throw (CalciumException(CalciumTypes::CPTPVR,ex));
+      } catch ( const DSC_Exception & ex) {
+#ifdef _DEBUG_
+       std::cerr << ex.what() << std::endl;
+#endif
+       // Exception venant de SupervComponent :
+       //   PortNotDefined(CPNMVR), PortNotConnected(CPLIEN)  
+       // ou du port uses : Dsc_Exception
+       // On continue à traiter la deconnexion des autres ports uses
+      } catch (...) {
+       throw (CalciumException(CalciumTypes::CPATAL,"Exception innatendue"));
+       // En fonction du mode de gestion des erreurs throw;
+      }
+    }
+  }
+
+
+  /********************* INTERFACES DE DESALLOCATION  *****************/
+
+  // Uniquement appelé par l'utilisateur s'il utilise la 0 copie
+  //   ( pointeur de données data==NULL à l'appel de ecp_lecture )
+  // Une désallocation aura lieu uniquement si un buffer intermédiaire
+  // était necessaire (type utilisateur et corba diffférent)
+  // La propriété du buffer est rendue à CORBA sinon  
+  template <typename T1, typename T2> static void
+  ecp_free ( T1 * dataPtr )
+  {
+    typedef typename ProvidesPortTraits<T2>::PortType     PortType;
+    typedef typename PortType::DataManipulator            DataManipulator;
+    typedef typename DataManipulator::Type                DataType; // Attention != T
+    typedef typename DataManipulator::InnerType           InnerType;
+
+    DeleteTraits<IsSameType<T1,InnerType>::value >::apply(dataPtr);
+  }
+
+  template <typename T1> static void
+  ecp_free ( T1 * dataPtr )
+  {
+    ecp_free<T1,T1> ( dataPtr );
+  }
+
+
+  /********************* INTERFACES DE LECTURE *****************/
+
+  // T1 est le type de données
+  template <typename T1 > static void
+  ecp_lecture ( Superv_Component_i & component,
+              CalciumTypes::DependencyType dependencyType,
+              double        & ti,
+              double const  & tf,
+              long          & i,
+              const string  & nomVar, 
+              size_t          bufferLength,
+              size_t        & nRead, 
+              T1            * &data )
+  {
+    ecp_lecture<T1,T1> (component,dependencyType,ti,tf,
+                       i,nomVar,bufferLength,nRead,data);
+  
+  }
+
+  // T1 est le type de données
+  // T2 est un <nom> de type Calcium permettant de sélectionner le port correspondant 
+  // T1 et T2 sont dissociés pour discriminer le cas des nombres complexes
+  //  -> Les données des nombres complexes sont de type float mais
+  //     le port à utiliser est le port cplx
+  template <typename T1, typename T2 > static void
+  ecp_lecture ( Superv_Component_i & component,
+              CalciumTypes::DependencyType dependencyType,
+              double        & ti,
+              double const  & tf,
+              long          & i,
+              const string  & nomVar, 
+              size_t          bufferLength,
+              size_t        & nRead, 
+              T1            * &data )
+  {
+
+    assert(&component);
+
+    typedef typename ProvidesPortTraits<T2>::PortType     PortType;
+    typedef typename PortType::DataManipulator            DataManipulator;
+    typedef typename DataManipulator::Type                CorbaDataType; // Attention != T1
+    typedef typename DataManipulator::InnerType           InnerType;
+
+    CorbaDataType     corbaData;
+
+#ifdef _DEBUG_
+    std::cerr << "-------- CalciumInterface(ecp_lecture) MARK 1 ------------------" << std::endl;
+#endif
+
+    if (nomVar.empty())
+      throw CalciumException(CalciumTypes::CPNMVR,
+                               LOC("Le nom de la variable est <nul>"));
+    PortType * port;
+#ifdef _DEBUG_
+    std::cout << "-------- CalciumInterface(ecp_lecture) MARK 2 ------------------" << std::endl;
+#endif
+
+    try {
+      port  = component.Superv_Component_i::get_port< PortType > (nomVar.c_str());
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 3 ------------------" << std::endl;
+#endif
+    } catch ( const Superv_Component_i::PortNotDefined & ex) {
+#ifdef _DEBUG_
+      std::cerr << ex.what() << std::endl;
+#endif
+      throw (CalciumException(CalciumTypes::CPNMVR,ex));
+    } catch ( const Superv_Component_i::PortNotConnected & ex) {
+#ifdef _DEBUG_
+      std::cerr << ex.what() << std::endl;;
+#endif
+      throw (CalciumException(CalciumTypes::CPLIEN,ex)); 
+      // VERIFIER LES CAS DES CODES : CPINARRET, CPSTOPSEQ, CPCTVR, CPLIEN
+    } catch ( const Superv_Component_i::BadCast & ex) {
+#ifdef _DEBUG_
+      std::cerr << ex.what() << std::endl;
+#endif
+      throw (CalciumException(CalciumTypes::CPTPVR,ex));
+    }
+  
+    // mode == mode du port 
+    CalciumTypes::DependencyType portDependencyType = port->getDependencyType();
+
+    if ( portDependencyType == CalciumTypes::UNDEFINED_DEPENDENCY )
+      throw CalciumException(CalciumTypes::CPIT,
+                            LOC(OSS()<<"Le mode de dépendance de la variable " 
+                                << nomVar << " est indéfini."));
+
+    if ( ( portDependencyType != dependencyType ) && 
+        ( dependencyType != CalciumTypes::SEQUENCE_DEPENDENCY ) ) 
+      throw CalciumException(CalciumTypes::CPITVR,
+                            LOC(OSS()<<"Le mode de dépendance de la variable " 
+                                << nomVar << ": " << portDependencyType 
+                                << " ne correspond pas au mode demandé."));
+
+  
+    if ( dependencyType == CalciumTypes::TIME_DEPENDENCY ) {
+      corbaData = port->get(ti,tf, 0);
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 5 ------------------" << std::endl;
+#endif
+    } 
+    else if ( dependencyType == CalciumTypes::ITERATION_DEPENDENCY ) {
+      corbaData = port->get(0, i);
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 6 ------------------" << std::endl;
+#endif
+    } else {
+      // Lecture en séquence
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 7 ------------------" << std::endl;
+#endif
+      corbaData = port->next(ti,i);
+    }
+#ifdef _DEBUG_
+    std::cout << "-------- CalciumInterface(ecp_lecture) MARK 8 ------------------" << std::endl;
+#endif
+    size_t corbaDataSize = DataManipulator::size(corbaData);
+#ifdef _DEBUG_
+    std::cout << "-------- CalciumInterface(ecp_lecture) corbaDataSize : " << corbaDataSize << std::endl;
+#endif
+   
+    // Vérifie si l'utilisateur demande du 0 copie
+    if ( data == NULL ) {
+      if ( bufferLength != 0 ) {
+       MESSAGE("bufferLength devrait valoir 0 pour l'utilisation du mode sans copie (data==NULL)");
+      }
+      nRead = corbaDataSize;
+      // Si les types T et InnerType sont différents, il faudra effectuer tout de même une recopie
+      if (!IsSameType<T1,InnerType>::value) data = new T1[nRead];
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 9 ------------------" << std::endl;
+#endif
+      // On essaye de faire du 0 copy si les types T1 et InnerType sont les mêmes
+      Copy2UserSpace< IsSameType<T1,InnerType>::value >::apply(data,corbaData,nRead);
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 10 ------------------" << std::endl;
+#endif
+      // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non
+      // la donnée corba associée à un DataId ! Ne pas effectuer la desallocation suivante :
+      // DataManipulator::delete_data(corbaData);
+      //  old : Dans les deux cas la structure CORBA n'est plus utile 
+      //  old : Si !IsSameType<T1,InnerType>::value l'objet CORBA est détruit avec son contenu
+      //  old : Dans l'autre cas seul la coquille CORBA est détruite 
+      //  L'utilisateur devra appeler ecp_free (version modifiée) qui déterminera s'il est necessaire
+      //   de désallouer un buffer intermédiaire ( types différents) ou de rendre la propriété
+   } else {
+      nRead = std::min < size_t > (corbaDataSize,bufferLength);
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 11 ------------------" << std::endl;
+#endif
+      Copy2UserSpace<false>::apply(data,corbaData,nRead);
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 12 ------------------" << std::endl;
+#endif
+      // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non
+      // la donnée corba associée à un DataId ! Ne pas effectuer la desallocation suivante :
+      // DataManipulator::delete_data(corbaData);
+   }
+#ifdef _DEBUG_
+    std::cout << "-------- CalciumInterface(ecp_lecture), Valeur de data : " << std::endl;
+    std::copy(data,data+nRead,std::ostream_iterator<T1>(std::cout," "));
+    std::cout << "Ptr :" << data << std::endl;
+
+    std::cout << "-------- CalciumInterface(ecp_lecture) MARK 13 ------------------" << std::endl;
+#endif
+  
+    return;
+  }
+
+
+  /********************* INTERFACES D'ECRITURE *****************/
+
+  template <typename T1> static void
+  ecp_ecriture ( Superv_Component_i & component,
+                CalciumTypes::DependencyType dependencyType,
+                double const  & t,
+                long   const  & i,
+                const string  & nomVar, 
+                size_t bufferLength,
+                T1  & data ) {
+    ecp_ecriture<T1,T1> (component,dependencyType,t,i,nomVar,bufferLength,data); 
+  }
+
+  template <typename T1, typename T2> static void
+  ecp_ecriture ( Superv_Component_i & component,
+                CalciumTypes::DependencyType dependencyType,
+                double const  & t,
+                long   const  & i,
+                const string  & nomVar, 
+                size_t bufferLength,
+                T1  & data ) 
+  {
+    
+    assert(&component);
+
+    //typedef typename StarTrait<TT>::NonStarType           T;
+    typedef typename UsesPortTraits<T2>::PortType          PortType;
+    typedef typename ProvidesPortTraits<T2>::PortType      ProvidesPortType;
+    typedef typename ProvidesPortType::DataManipulator     DataManipulator;
+    // Verifier que l'on peut définir UsesPortType::DataManipulator
+    //    typedef typename PortType::DataManipulator            DataManipulator;
+    typedef typename DataManipulator::Type                CorbaDataType; // Attention != T1
+    typedef typename DataManipulator::InnerType           InnerType;
+
+#ifdef _DEBUG_
+    std::cerr << "-------- CalciumInterface(ecriture) MARK 1 ------------------" << std::endl;
+#endif
+    if ( nomVar.empty() ) throw CalciumException(CalciumTypes::CPNMVR,
+                                                   LOC("Le nom de la variable est <nul>"));
+    PortType * port;
+#ifdef _DEBUG_
+    std::cout << "-------- CalciumInterface(ecriture) MARK 2 ------------------" << std::endl;
+#endif
+
+    try {
+      port  = component.Superv_Component_i::get_port< PortType > (nomVar.c_str());
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecriture) MARK 3 ------------------" << std::endl;
+#endif
+    } catch ( const Superv_Component_i::PortNotDefined & ex) {
+#ifdef _DEBUG_
+      std::cerr << ex.what() << std::endl;
+#endif
+      throw (CalciumException(CalciumTypes::CPNMVR,ex));
+    } catch ( const Superv_Component_i::PortNotConnected & ex) {
+#ifdef _DEBUG_
+      std::cerr << ex.what() << std::endl;;
+#endif
+      throw (CalciumException(CalciumTypes::CPLIEN,ex)); 
+      // VERIFIER LES CAS DES CODES : CPINARRET, CPSTOPSEQ, CPCTVR, CPLIEN
+    } catch ( const Superv_Component_i::BadCast & ex) {
+#ifdef _DEBUG_
+      std::cerr << ex.what() << std::endl;
+#endif
+      throw (CalciumException(CalciumTypes::CPTPVR,ex));
+    }
+    // mode == mode du port 
+    // On pourrait créer la méthode CORBA dans le mode de Couplage CALCIUM.
+    // et donc ajouter cette cette méthode uniquement dans l'IDL calcium !
+
+//     CalciumTypes::DependencyType portDependencyType;
+//     try {
+//       portDependencyType = port->getDependencyType();
+//       std::cout << "-------- CalciumInterface(ecriture) MARK 4 ------------------" << std::endl;
+//     } catch ( const DSC_Exception & ex ) {
+//       std::cerr << ex.what() << std::endl;;
+//       throw (CalciumException(CalciumTypes::CPIT,ex));
+//     }
+
+    if ( dependencyType == CalciumTypes::UNDEFINED_DEPENDENCY )
+      throw CalciumException(CalciumTypes::CPIT,
+                               LOC(OSS()<<"Le mode de dépendance demandé pour la variable " 
+                                   << nomVar << " est indéfini."));
+
+    if ( dependencyType == CalciumTypes::SEQUENCE_DEPENDENCY )
+      throw CalciumException(CalciumTypes::CPIT,
+                               LOC(OSS()<<"Le mode de dépendance SEQUENCE_DEPENDENCY pour la variable " 
+                                   << nomVar << " est impossible en écriture."));
+
+    // Il faudrait que le port provides génère une exception si le mode donnée n'est pas
+    // le bon. La seule façon de le faire est d'envoyer -1 en temps si on n'est en itération
+    // et vice-versa pour informer les provides port du mode dans lequel on est. Sinon il faut
+    // modifier l'interface IDL pour y ajouter un mode de dépendance !
+    // ---->
+//     if ( portDependencyType != dependencyType ) 
+//       throw CalciumException(CalciumTypes::CPITVR,
+//                             LOC(OSS()<<"Le mode de dépendance de la variable " 
+//                                 << nomVar << " ne correspond pas au mode demandé."));
+
+  
+    if ( bufferLength < 1 )
+      throw CalciumException(CalciumTypes::CPNTNULL,
+                               LOC(OSS()<<"Le buffer a envoyer est de taille nulle "));
+
+
+#ifdef _DEBUG_
+    std::cout << "-------- CalciumInterface(ecriture) MARK 4 ------------------" << std::endl;
+#endif
+    CorbaDataType corbaData;
+
+    
+    // Si les types Utilisateurs et CORBA sont différents
+    // il faut effectuer une recopie sinon on utilise directement le
+    // buffer data pour constituer la séquence
+    // TODO : 
+    // - Attention en mode asynchrone il faudra eventuellement
+    //   faire une copie des données même si elles sont de même type.
+    // - OLD : En cas de collocalisation (du port provide et du port uses)
+    //   OLD : il est necessaire d'effectuer une recopie du buffer car la
+    //   OLD : séquence est envoyée au port provide par une référence sur 
+    //   OLD : la séquence locale. Or la méthode put récupère le buffer directement
+    //   OLD : qui est alors le buffer utilisateur. Il pourrait alors arriver que :
+    //   OLD :   * Le recepteur efface le buffer emetteur
+    //   OLD :   * Le port lui-même efface le buffer de l'ulisateur !
+    //   OLD : Cette copie est effectuée dans GenericPortUses::put 
+    //   OLD : en fonction de la collocalisation ou non.
+    // - OLD :En cas de connection multiples d'un port uses distant vers plusieurs port provides
+    //   OLD : collocalisés les ports provides partagent la même copie de la donnée ! 
+    //   OLD : Il faut effectuer une copie dans le port provides.
+    //   OLD : Cette copie est effectuée dans GenericPortUses::put 
+    //   OLD : en fonction de la collocalisation ou non.
+    Copy2CorbaSpace<IsSameType<T1,InnerType>::value >::apply(corbaData,data,bufferLength);
+    //TODO : GERER LES EXCEPTIONS ICI : ex le port n'est pas connecté
+    if ( dependencyType == CalciumTypes::TIME_DEPENDENCY ) {
+      try
+      {
+        port->put(*corbaData,t, -1); 
+      }
+      catch ( const DSC_Exception & ex) 
+      {
+        throw (CalciumException(CalciumTypes::CPATAL,ex.what()));
+      }
+      //Le -1 peut être traité par le cst DataIdContainer et transformé en 0 
+      //Etre obligé de mettre une étoile ds (*corbadata) va poser des pb pour les types <> seq
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecriture) MARK 5 ------------------" << std::endl;
+#endif
+    } 
+    else if ( dependencyType == CalciumTypes::ITERATION_DEPENDENCY ) {
+      try
+      {
+        port->put(*corbaData,-1, i);
+      }
+      catch ( const DSC_Exception & ex) 
+      {
+        throw (CalciumException(CalciumTypes::CPATAL,ex.what()));
+      }
+#ifdef _DEBUG_
+      std::cout << "-------- CalciumInterface(ecriture) MARK 6 ------------------" << std::endl;
+#endif
+    } 
+
+    
+#ifdef _DEBUG_
+    std::cout << "-------- CalciumInterface(ecriture), Valeur de corbaData : " << std::endl;
+    for (int i = 0; i < corbaData->length(); ++i)
+      cout << "-------- CalciumInterface(ecriture), corbaData[" << i << "] = " << (*corbaData)[i] << endl;
+#endif
+    
+    //    if ( !IsSameType<T1,InnerType>::value ) delete corbaData;
+    // Supprime l'objet CORBA avec eventuellement les données qu'il contient (cas de la recopie)
+    delete corbaData;
+
+#ifdef _DEBUG_
+    std::cout << "-------- CalciumInterface(ecriture) MARK 7 ------------------" << std::endl;
+#endif
+   
+    return;
+  }
+
+};
+
+#endif
index 8e8453c953e101e95a4160ef47678698b97b00f4..504d3b2562d182318e0071fd9bb0af797c796610 100644 (file)
 #ifndef _CALCIUM_INTERFACE_HXX_
 #define _CALCIUM_INTERFACE_HXX_
 
-#include <string>
-#include <vector>
-#include <iostream>
-#include "Superv_Component_i.hxx"
+//Interface C++
+#include "CalciumCxxInterface.hxx"
+
 #include "CalciumException.hxx"
 #include "CalciumTypes.hxx"
-#include "CalciumGenericUsesPort.hxx"
-#include "Copy2UserSpace.hxx"
-#include "Copy2CorbaSpace.hxx"
-#include "CalciumPortTraits.hxx"
 
 #include <stdio.h>
 
 //#define _DEBUG_
 
-// Déplacer cette information dans CorbaTypeManipulator
-// Gérer en même temps la recopie profonde.
-
-template <typename T1, typename T2>
-struct IsSameType {
-  static const bool value = false;
-};
-template <typename T1>
-struct IsSameType<T1,T1> {
-  static const bool value = true;
-};
-
-
-
-
-//class CalciumInterface {
-namespace CalciumInterface {
-//public :
-
-
-  static void
-  ecp_fin (Superv_Component_i & component, bool provideLastGivenValue)
-  { 
-    std::vector<std::string> usesPortNames;
-    std::vector<std::string>::const_iterator it;
-    component.get_uses_port_names(usesPortNames);    
-    
-    //récupérer le type de réel du port est un peu difficile
-    //car l'interface nous donne aucune indication
-
-    //     uses_port *myUsesPort;
-    calcium_uses_port* myCalciumUsesPort;
-      
-    for (it=usesPortNames.begin(); it != usesPortNames.end(); ++it) {
-      try {
-
-       myCalciumUsesPort= 
-         component.Superv_Component_i::get_port< calcium_uses_port >((*it).c_str());
-
-//     component.Superv_Component_i::get_port(myUsesPort,(*it).c_str());
-//     calcium_uses_port* myCalciumUsesPort=
-//       dynamic_cast<calcium_uses_port*>(myUsesPort);
-
-#ifdef _DEBUG_
-       std::cerr << "-------- CalciumInterface(ecp_fin) MARK 1 -|"<< *it <<"|----"<< 
-         //      typeid(myUsesPort).name() <<"-------------" <<
-         typeid(myCalciumUsesPort).name() <<"-------------" << std::endl;
-#endif
-       
-//     if ( !myCalciumUsesPort )
-//       throw Superv_Component_i::BadCast(LOC(OSS()<<"Impossible de convertir le port "
-//                                             << *it << " en port de type calcium_uses_port." ));
-
-       myCalciumUsesPort->disconnect(provideLastGivenValue);
-
-      } catch ( const Superv_Component_i::BadCast & ex) {
-#ifdef _DEBUG_
-       std::cerr << ex.what() << std::endl;
-#endif
-       throw (CalciumException(CalciumTypes::CPTPVR,ex));
-      } catch ( const DSC_Exception & ex) {
-#ifdef _DEBUG_
-       std::cerr << ex.what() << std::endl;
-#endif
-       // Exception venant de SupervComponent :
-       //   PortNotDefined(CPNMVR), PortNotConnected(CPLIEN)  
-       // ou du port uses : Dsc_Exception
-       // On continue à traiter la deconnexion des autres ports uses
-      } catch (...) {
-       throw (CalciumException(CalciumTypes::CPATAL,"Exception innatendue"));
-       // En fonction du mode de gestion des erreurs throw;
-      }
-    }
-  }
-
-
-  // Uniquement appelé par l'utilisateur s'il a passé un pointeur de données NULL
-  // à l'appel de ecp_lecture (demande de 0 copie)
-  template <typename T1, typename T2> static void
-  ecp_free ( T1 * dataPtr )
-  {
-    typedef typename ProvidesPortTraits<T2>::PortType     PortType;
-    typedef typename PortType::DataManipulator            DataManipulator;
-    typedef typename DataManipulator::Type                DataType; // Attention != T
-    typedef typename DataManipulator::InnerType           InnerType;
-
-    DeleteTraits<IsSameType<T1,InnerType>::value >::apply(dataPtr);
-  }
-
-  template <typename T1> static void
-  ecp_free ( T1 * dataPtr )
-  {
-    ecp_free<T1,T1> ( dataPtr );
-  }
-
-  template <typename T1 > static void
-  ecp_lecture ( Superv_Component_i & component,
-              CalciumTypes::DependencyType dependencyType,
-              double        & ti,
-              double const  & tf,
-              long          & i,
-              const string  & nomVar, 
-              size_t bufferLength,
-              size_t & nRead, 
-              T1 * &data )
-  {
-    ecp_lecture<T1,T1> (component,dependencyType,ti,tf,
-                       i,nomVar,bufferLength,nRead,data);
-  
-  }
-
-  template <typename T1, typename T2 > static void
-  ecp_lecture ( Superv_Component_i & component,
-              CalciumTypes::DependencyType dependencyType,
-              double        & ti,
-              double const  & tf,
-              long          & i,
-              const string  & nomVar, 
-              size_t bufferLength,
-              size_t & nRead, 
-              T1 * &data )
-  {
-
-    assert(&component);
-
-    typedef typename ProvidesPortTraits<T2>::PortType     PortType;
-    typedef typename PortType::DataManipulator            DataManipulator;
-    typedef typename DataManipulator::Type                CorbaDataType; // Attention != T
-    typedef typename DataManipulator::InnerType           InnerType;
-
-    CorbaDataType     corbaData;
-    long         ilong;
-
 #ifdef _DEBUG_
-    std::cerr << "-------- CalciumInterface(ecp_lecture) MARK 1 ------------------" << std::endl;
-#endif
-
-    if (nomVar.empty())
-      throw CalciumException(CalciumTypes::CPNMVR,
-                               LOC("Le nom de la variable est <nul>"));
-    PortType * port;
-#ifdef _DEBUG_
-    std::cout << "-------- CalciumInterface(ecp_lecture) MARK 2 ------------------" << std::endl;
-#endif
-
-    try {
-      port  = component.Superv_Component_i::get_port< PortType > (nomVar.c_str());
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 3 ------------------" << std::endl;
-#endif
-    } catch ( const Superv_Component_i::PortNotDefined & ex) {
-#ifdef _DEBUG_
-      std::cerr << ex.what() << std::endl;
-#endif
-      throw (CalciumException(CalciumTypes::CPNMVR,ex));
-    } catch ( const Superv_Component_i::PortNotConnected & ex) {
-#ifdef _DEBUG_
-      std::cerr << ex.what() << std::endl;;
-#endif
-      throw (CalciumException(CalciumTypes::CPLIEN,ex)); 
-      // VERIFIER LES CAS DES CODES : CPINARRET, CPSTOPSEQ, CPCTVR, CPLIEN
-    } catch ( const Superv_Component_i::BadCast & ex) {
-#ifdef _DEBUG_
-      std::cerr << ex.what() << std::endl;
-#endif
-      throw (CalciumException(CalciumTypes::CPTPVR,ex));
-    }
-  
-    // mode == mode du port 
-    CalciumTypes::DependencyType portDependencyType = port->getDependencyType();
-
-    if ( portDependencyType == CalciumTypes::UNDEFINED_DEPENDENCY )
-      throw CalciumException(CalciumTypes::CPIT,
-                            LOC(OSS()<<"Le mode de dépendance de la variable " 
-                                << nomVar << " est indéfini."));
-
-    if ( ( portDependencyType != dependencyType ) && 
-        ( dependencyType != CalciumTypes::SEQUENCE_DEPENDENCY ) ) 
-      throw CalciumException(CalciumTypes::CPITVR,
-                            LOC(OSS()<<"Le mode de dépendance de la variable " 
-                                << nomVar << ": " << portDependencyType << " ne correspond pas au mode demandé: " << dependencyType));
-
-  
-    if ( dependencyType == CalciumTypes::TIME_DEPENDENCY ) {
-      corbaData = port->get(ti,tf, 0);
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 5 ------------------" << std::endl;
-#endif
-    } 
-    else if ( dependencyType == CalciumTypes::ITERATION_DEPENDENCY ) {
-      corbaData = port->get(0, i);
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 6 ------------------" << std::endl;
-#endif
-    } else {
-      // Lecture en séquence
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 7 ------------------" << std::endl;
-#endif
-      corbaData = port->next(ti,i);
-    }
-#ifdef _DEBUG_
-    std::cout << "-------- CalciumInterface(ecp_lecture) MARK 8 ------------------" << std::endl;
-#endif
-    size_t corbaDataSize = DataManipulator::size(corbaData);
-#ifdef _DEBUG_
-    std::cout << "-------- CalciumInterface(ecp_lecture) corbaDataSize : " << corbaDataSize << std::endl;
-#endif
-   
-    // Vérifie si l'utilisateur demande du 0 copie
-    if ( data == NULL ) {
-      if ( bufferLength != 0 ) {
-       MESSAGE("bufferLength devrait valoir 0 pour l'utilisation du mode sans copie (data==NULL)");
-      }
-      nRead = corbaDataSize;
-      // Si les types T et InnerType sont différents, il faudra effectuer tout de même une recopie
-      if (!IsSameType<T1,InnerType>::value) data = new T1[nRead];
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 9 ------------------" << std::endl;
-#endif
-      // On essaye de faire du 0 copy si les types T et InnerType sont les mêmes
-      Copy2UserSpace< IsSameType<T1,InnerType>::value >::apply(data,corbaData,nRead);
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 10 ------------------" << std::endl;
-#endif
-      // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non
-      // la donnée corba associée à un DataId ! Ne pas effectuer la desallocation suivante :
-      //  old : Dans les deux cas la structure CORBA n'est plus utile 
-      //  old : Si !IsSameType<T1,InnerType>::value l'objet CORBA est détruit avec son contenu
-      //  old : Dans l'autre cas seul la coquille CORBA est détruite 
-      //  tjrs correct : Dans les deux cas l'utilisateur devra appeler ecp_free (version modifiée)
-      // DataManipulator::delete_data(corbaData);
-   } else {
-      nRead = std::min < size_t > (corbaDataSize,bufferLength);
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 11 ------------------" << std::endl;
-#endif
-      Copy2UserSpace<false>::apply(data,corbaData,nRead);
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecp_lecture) MARK 12 ------------------" << std::endl;
-#endif
-      // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non
-      // la donnée corba associée à un DataId ! Ne pas effectuer la desallocation suivante :
-      //      DataManipulator::delete_data(corbaData);
-   }
-#ifdef _DEBUG_
-    std::cout << "-------- CalciumInterface(ecp_lecture), Valeur de data : " << std::endl;
-    std::copy(data,data+nRead,std::ostream_iterator<T1>(std::cout," "));
-    std::cout << "Ptr :" << data << std::endl;
-
-    std::cout << "-------- CalciumInterface(ecp_lecture) MARK 13 ------------------" << std::endl;
-#endif
-  
-    return;
-  }
-
-
-  template <typename T1> static void
-  ecp_ecriture ( Superv_Component_i & component,
-                CalciumTypes::DependencyType dependencyType,
-                double const  & t,
-                long   const  & i,
-                const string  & nomVar, 
-                size_t bufferLength,
-                T1  & data ) {
-    ecp_ecriture<T1,T1> (component,dependencyType,t,i,nomVar,bufferLength,data); 
-  }
-
-  template <typename T1, typename T2> static void
-  ecp_ecriture ( Superv_Component_i & component,
-                CalciumTypes::DependencyType dependencyType,
-                double const  & t,
-                long   const  & i,
-                const string  & nomVar, 
-                size_t bufferLength,
-                T1  & data ) 
-  {
-    
-    assert(&component);
-
-    //typedef typename StarTrait<TT>::NonStarType           T;
-    typedef typename UsesPortTraits<T2>::PortType          PortType;
-    typedef typename ProvidesPortTraits<T2>::PortType      ProvidesPortType;
-    typedef typename ProvidesPortType::DataManipulator     DataManipulator;
-    // Verifier que l'on peut définir UsesPortType::DataManipulator
-    //    typedef typename PortType::DataManipulator            DataManipulator;
-    typedef typename DataManipulator::Type                CorbaDataType; // Attention != T1
-    typedef typename DataManipulator::InnerType           InnerType;
-
-#ifdef _DEBUG_
-    std::cerr << "-------- CalciumInterface(ecriture) MARK 1 ------------------" << std::endl;
-#endif
-    if ( nomVar.empty() ) throw CalciumException(CalciumTypes::CPNMVR,
-                                                   LOC("Le nom de la variable est <nul>"));
-    PortType * port;
-#ifdef _DEBUG_
-    std::cout << "-------- CalciumInterface(ecriture) MARK 2 ------------------" << std::endl;
-#endif
-
-    try {
-      port  = component.Superv_Component_i::get_port< PortType > (nomVar.c_str());
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecriture) MARK 3 ------------------" << std::endl;
-#endif
-    } catch ( const Superv_Component_i::PortNotDefined & ex) {
-#ifdef _DEBUG_
-      std::cerr << ex.what() << std::endl;
-#endif
-      throw (CalciumException(CalciumTypes::CPNMVR,ex));
-    } catch ( const Superv_Component_i::PortNotConnected & ex) {
-#ifdef _DEBUG_
-      std::cerr << ex.what() << std::endl;;
-#endif
-      throw (CalciumException(CalciumTypes::CPLIEN,ex)); 
-      // VERIFIER LES CAS DES CODES : CPINARRET, CPSTOPSEQ, CPCTVR, CPLIEN
-    } catch ( const Superv_Component_i::BadCast & ex) {
-#ifdef _DEBUG_
-      std::cerr << ex.what() << std::endl;
-#endif
-      throw (CalciumException(CalciumTypes::CPTPVR,ex));
-    }
-    // mode == mode du port 
-    // On pourrait créer la méthode CORBA dans le mode de Couplage CALCIUM.
-    // et donc ajouter cette cette méthode uniquement dans l'IDL calcium !
-
-//     CalciumTypes::DependencyType portDependencyType;
-//     try {
-//       portDependencyType = port->getDependencyType();
-//       std::cout << "-------- CalciumInterface(ecriture) MARK 4 ------------------" << std::endl;
-//     } catch ( const DSC_Exception & ex ) {
-//       std::cerr << ex.what() << std::endl;;
-//       throw (CalciumException(CalciumTypes::CPIT,ex));
-//     }
-
-    if ( dependencyType == CalciumTypes::UNDEFINED_DEPENDENCY )
-      throw CalciumException(CalciumTypes::CPIT,
-                               LOC(OSS()<<"Le mode de dépendance demandé pour la variable " 
-                                   << nomVar << " est indéfini."));
-
-    if ( dependencyType == CalciumTypes::SEQUENCE_DEPENDENCY )
-      throw CalciumException(CalciumTypes::CPIT,
-                               LOC(OSS()<<"Le mode de dépendance SEQUENCE_DEPENDENCY pour la variable " 
-                                   << nomVar << " est impossible en écriture."));
-
-    // Il faudrait que le port provides génère une exception si le mode donnée n'est pas
-    // le bon. La seule façon de le faire est d'envoyer -1 en temps si on n'est en itération
-    // et vice-versa pour informer les provides port du mode dans lequel on est. Sinon il faut
-    // modifier l'interface IDL pour y ajouter un mode de dépendance !
-    // ---->
-//     if ( portDependencyType != dependencyType ) 
-//       throw CalciumException(CalciumTypes::CPITVR,
-//                             LOC(OSS()<<"Le mode de dépendance de la variable " 
-//                                 << nomVar << " ne correspond pas au mode demandé."));
-
-  
-    if ( bufferLength < 1 )
-      throw CalciumException(CalciumTypes::CPNTNULL,
-                               LOC(OSS()<<"Le buffer a envoyer est de taille nulle "));
-
-
-#ifdef _DEBUG_
-    std::cout << "-------- CalciumInterface(ecriture) MARK 4 ------------------" << std::endl;
-#endif
-    CorbaDataType corbaData;
-
-    
-    // Si les types Utilisateurs et CORBA sont différents
-    // il faut effectuer une recopie sinon on utilise directement le
-    // buffer data pour constituer la séquence
-    // TODO : 
-    // - Attention en mode asynchrone il faudra eventuellement
-    //   faire une copie des données même si elles sont de même type.
-    // - En cas de collocalisation (du port provide et du port uses)
-    //   il est necessaire d'effectuer une recopie du buffer car la
-    //   séquence est envoyée au port provide par une référence sur 
-    //   la séquence locale. Or la méthode put récupère le buffer directement
-    //   qui est alors le buffer utilisateur. Il pourrait alors arrivé que :
-    //     * Le recepteur efface le buffer emetteur
-    //     * Le port lui-même efface le buffer de l'ulisateur !
-    //   Cette copie est effectuée dans GenericPortUses::put 
-    //   en fonction de la collocalisation ou non.
-    // - En cas de connection multiples d'un port uses distant vers plusieurs port provides
-    //   collocalisés les ports provides partagent la même copie de la donnée ! 
-    //   Il faut effectuer une copie dans le port provides.
-    //   Cette copie est effectuée dans GenericPortUses::put 
-    //   en fonction de la collocalisation ou non.
-    Copy2CorbaSpace<IsSameType<T1,InnerType>::value >::apply(corbaData,data,bufferLength);
-    //TODO : GERER LES EXCEPTIONS ICI : ex le port n'est pas connecté
-    if ( dependencyType == CalciumTypes::TIME_DEPENDENCY ) {
-      try
-      {
-        port->put(*corbaData,t, -1); 
-      }
-      catch ( const DSC_Exception & ex) 
-      {
-        throw (CalciumException(CalciumTypes::CPATAL,ex.what()));
-      }
-      //Le -1 peut être traité par le cst DataIdContainer et transformé en 0 
-      //Etre obligé de mettre une étoile ds (*corbadata) va poser des pb pour les types <> seq
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecriture) MARK 5 ------------------" << std::endl;
-#endif
-    } 
-    else if ( dependencyType == CalciumTypes::ITERATION_DEPENDENCY ) {
-      try
-      {
-        port->put(*corbaData,-1, i);
-      }
-      catch ( const DSC_Exception & ex) 
-      {
-        throw (CalciumException(CalciumTypes::CPATAL,ex.what()));
-      }
-#ifdef _DEBUG_
-      std::cout << "-------- CalciumInterface(ecriture) MARK 6 ------------------" << std::endl;
-#endif
-    } 
-
-    
-#ifdef _DEBUG_
-    std::cout << "-------- CalciumInterface(ecriture), Valeur de corbaData : " << std::endl;
-    for (int i = 0; i < corbaData->length(); ++i)
-      cout << "-------- CalciumInterface(ecriture), corbaData[" << i << "] = " << (*corbaData)[i] << endl;
+#define DEBTRACE(msg) {std::cerr<<std::flush<<__FILE__<<" ["<<__LINE__<<"] : "<<msg<<std::endl<<std::flush;}
+#else
+#define DEBTRACE(msg)
 #endif
-    
-    //    if ( !IsSameType<T1,InnerType>::value ) delete corbaData;
-    // Supprime l'objet CORBA avec eventuellement les données qu'il contient (case de la recopie)
-    delete corbaData;
 
-#ifdef _DEBUG_
-    std::cout << "-------- CalciumInterface(ecriture) MARK 7 ------------------" << std::endl;
-#endif
-   
-    return;
-  }
-
-};
 
 // Interface C/C++
 
@@ -498,6 +59,7 @@ template <> struct CalTimeType<double> {
   typedef double TimeType;
 };
 
+// Définition de ecp_fin
 extern "C"  CalciumTypes::InfoType 
 ecp_fin_ (void * component, int code) {
 
@@ -510,21 +72,14 @@ ecp_fin_ (void * component, int code) {
     CalciumInterface::ecp_fin( *_component,                            
                               provideLastGivenValue); 
   } catch ( const CalciumException & ex) { //tester l'arrêt par exception
-#ifdef _DEBUG_
-    std::cerr << ex.what() << std::endl;                               
-#endif
+    DEBTRACE( ex.what() );
     return ex.getInfo();                                               
   }                                                                    
   return CalciumTypes::CPOK;
 };
 
-#ifdef _DEBUG_
-#define DEBTRACE(msg) {std::cerr<<std::flush<<__FILE__<<" ["<<__LINE__<<"] : "<<msg<<std::endl<<std::flush;}
-#else
-#define DEBTRACE(msg)
-#endif
-
 
+// Définition de ecp_lecture_... , ecp_ecriture_..., ecp_free_...
 #define CALCIUM_C2CPP_INTERFACE_(_name,_type,_qual)                    \
   extern "C" CalciumTypes::InfoType ecp_lecture_##_name (void * component, int dependencyType, \
                                                         CalTimeType< _type _qual >::TimeType * ti, \
@@ -548,9 +103,7 @@ ecp_fin_ (void * component, int code) {
                                                     nomvar,            \
                                                     _bufferLength, _nRead, *data); \
     } catch ( const CalciumException & ex) {                           \
-      DEBTRACE( "-------- CalciumInterface(lecture Inter Part) MARK 1b ------------------" ) \
-      DEBTRACE( ex.what() )                            \
-      DEBTRACE( "-------- CalciumInterface(lecture Inter Part) MARK 1ter ------------------" ) \
+      DEBTRACE( ex.what() );                                           \
       return ex.getInfo();                                             \
     }                                                                  \
     if ( IsSameType< _name , cplx >::value ) { *nRead=_nRead/2;                \
@@ -561,16 +114,15 @@ ecp_fin_ (void * component, int code) {
     if (_dependencyType == CalciumTypes::CP_SEQUENTIEL ) \
         *ti=(CalTimeType< _type _qual >::TimeType)(_ti);                       \
     DEBTRACE( "-------- CalciumInterface(lecture Inter Part), Data Ptr :" << *data ) \
-    /* \
-    for (int i=0; i<_nRead;++i)                                                \
-      printf("-------- CalciumInterface(lecture Inter Part), Valeur de data (typage entier) data[%d] : %d \n",i,(*data)[i]); \
-      */ \
-    DEBTRACE( "-------- CalciumInterface(lecture Inter Part), Data Ptr :" << *data ) \
     return CalciumTypes::CPOK;                                         \
   };                                                                   \
+                                                                       \
+                                                                       \
   extern "C" void ecp_lecture_##_name##_free ( _type _qual * data) {   \
     CalciumInterface::ecp_free< _type, _name >(data);                  \
   };                                                                   \
+                                                                       \
+                                                                       \
   extern "C" CalciumTypes::InfoType ecp_ecriture_##_name (void * component, int dependencyType, \
                                                          CalTimeType< _type _qual >::TimeType *t, \
                                                          long  i,      \
@@ -593,23 +145,102 @@ ecp_fin_ (void * component, int code) {
       std::cerr << ex.what() << std::endl;                             \
       return ex.getInfo();                                             \
     }                                                                  \
-    DEBTRACE( "-------- CalciumInterface(ecriture Inter Part), Valeur de data : " ) \
-    DEBTRACE( "-------- CalciumInterface(ecriture Inter Part), Ptr(1) :" << data ) \
-    /* \
-    for (int i=0; i<_bufferLength;++i)                                 \
-      printf("-------- CalciumInterface(ecriture Inter Part), Valeur de data (typage entier) data[%d] : %d \n",i,data[i]); \
-      */ \
-    DEBTRACE( "-------- CalciumInterface(ecriture Inter Part), Ptr(2) :" << data ) \
-    return CalciumTypes::CPOK;                                         \
+    DEBTRACE( "-------- CalciumInterface(ecriture Inter Part), Valeur de data :" << data ) \
+      return CalciumTypes::CPOK;                                       \
   };                                                                   \
 
 
 
 #define STAR *
+// Le premier argument est utilisée :
+//  - comme suffixe dans la définition des noms ecp_lecture_ ecp_ecriture_ ecp_free_
+//  - comme second argument template à l'appel de la méthode C++ correspondante
+//      ( le port correspondant est alors obtenu par un trait)
+// Le second argument est utilisée :
+// - pour typer le paramètre data de la procédure générée 
+// - pour déduire le type des paramètres t, ti tf via un trait
+// - comme premier paramètre template à l'appel de la méthode C++ correspondante
 CALCIUM_C2CPP_INTERFACE_(int,int,);
 CALCIUM_C2CPP_INTERFACE_(float,float, );
 CALCIUM_C2CPP_INTERFACE_(double,double,);
 CALCIUM_C2CPP_INTERFACE_(bool,bool,);
 CALCIUM_C2CPP_INTERFACE_(cplx,float,);
+CALCIUM_C2CPP_INTERFACE_(str,char*,);
+
+// INTERFACE C/CPP pour les chaines de caractères
+// Le paramètre supplémentaire strsize n'étant pas utilisé
+// j'utilise la génération par la macro CALCIUM_C2CPP_INTERFACE_(str,char*,);
+// TODO : vérifier ecp_free pour ce type particulier
+// extern "C" CalciumTypes::InfoType ecp_lecture_str (void * component, int dependencyType, 
+//                                                float * ti, float * tf, long * i, 
+//                                                const char * const nomvar, size_t bufferLength, 
+//                                                size_t * nRead, char ** *data, size_t strsize ) { 
+
+//   Superv_Component_i * _component = static_cast<Superv_Component_i *>(component); 
+//   double         _ti=*ti;                                           
+//   double         _tf=*tf;                                           
+//   size_t         _nRead=0;                                          
+//   size_t         _bufferLength=bufferLength;                                
+//   CalciumTypes::DependencyType _dependencyType=                     
+//     static_cast<CalciumTypes::DependencyType>(dependencyType);      
+  
+//   // - GERER POINTEUR NULL : NOTHING TODO 
+//   // - VERIFIER LA TAILLE DES CHAINES RETOURNEES (ELLES DEVRAIENT ETRES CORRECTES SI L'ECRITURE EST BIEN CODEE.)
+
+//   DEBTRACE( "-------- CalciumInterface(lecture Inter Part) MARK 1 ------------------" ) 
+//     try {                                                           
+//       CalciumInterface::ecp_lecture< char*, char* >( *_component,   
+//                                                  _dependencyType, 
+//                                                  _ti, _tf, *i,      
+//                                                  nomvar,            
+//                                                  _bufferLength, _nRead, *data); 
+//     } catch ( const CalciumException & ex) {                                
+//       DEBTRACE( ex.what() );
+//       return ex.getInfo();                                          
+//     }                                                                       
+    
+//     *nRead = _nRead;                                                
+    
+//     if (_dependencyType == CalciumTypes::CP_SEQUENTIEL ) 
+//       *ti=(float)(_ti);                     
+    
+//     DEBTRACE( "-------- CalciumInterface(lecture Inter Part), Data Ptr :" << *data ) ;
+
+//     return CalciumTypes::CPOK;
+//   };                                                                        
+                                                                       
+
+// extern "C" void ecp_lecture_str_free (char** data) {        
+//   CalciumInterface::ecp_free< char*, char* >(data);                 
+// };                                                                  
+                                                                       
+                                                                       
+// extern "C" CalciumTypes::InfoType ecp_ecriture_str (void * component, int dependencyType, 
+//                                                 float *t, long  i,  
+//                                                 const char * const nomvar, size_t bufferLength, 
+//                                                 char ** data, int strsize ) { 
+
+//     Superv_Component_i * _component = static_cast<Superv_Component_i *>(component); 
+//     /* Je ne sais pas pourquoi, je n'arrive pas à passer t par valeur : corruption de la pile*/ 
+//     double         _t=*t;                                           
+//     size_t         _bufferLength=bufferLength;                              
+
+//     // - VERIFIER LA TAILLE DES CHAINES RETOURNEES (ELLES DEVRAIENT ETRES CORRECTES SI L'ECRITURE EST BIEN CODEE.)
+
+//     DEBTRACE( "-------- CalciumInterface(ecriture Inter Part) MARK 1 ------------------" ) 
+//     try {                                                           
+//       std::string essai(nomvar);                                    
+//       DEBTRACE( "----------->-" << nomvar )         
+//     CalciumInterface::ecp_ecriture< char*, char* >( *_component,    
+//                                                     static_cast<CalciumTypes::DependencyType>(dependencyType), 
+//                                                     _t,i,nomvar,_bufferLength,*data); 
+//     } catch ( const CalciumException & ex) {                                
+//       std::cerr << ex.what() << std::endl;                          
+//       return ex.getInfo();                                          
+//     }                                                                       
+//     DEBTRACE( "-------- CalciumInterface(ecriture Inter Part), Valeur de data :" << data ) 
+//     return CalciumTypes::CPOK;                                              
+//   };                                                                        
+
 
 #endif
index baacd9c77098b333d2c8ab1dfbb27663ac18d2a6..d05cc440df6e41e9689187b95eb0007b5f35a03d 100644 (file)
 
 #include "Superv_Component_i.hxx"
 
-
-struct UnknownPortType {};
+// PROVIDES PORT TRAITS
+struct UnknownProvidesPortType {};
 template <class T> struct ProvidesPortTraits {
-  typedef  UnknownPortType PortType;
+  typedef  UnknownProvidesPortType PortType;
 };
 template <> struct ProvidesPortTraits<int> {
   typedef  calcium_integer_port_provides PortType;
@@ -48,25 +48,33 @@ template <> struct ProvidesPortTraits<float> {
 template <> struct ProvidesPortTraits<double> {
   typedef  calcium_double_port_provides PortType;
 };
-template <> struct ProvidesPortTraits<char *> {
-  typedef  calcium_string_port_provides PortType;
-};
 template <> struct ProvidesPortTraits<bool> {
   typedef  calcium_logical_port_provides PortType;
 };
-
 // Définition du type cplx pour disciminer ce type de port
 // de celui du float 
 struct cplx {};
 template <> struct ProvidesPortTraits<cplx> {
    typedef calcium_complex_port_provides PortType;
 };
+// Défénition du type str pour obtenir le type de port
+// correspondant
+struct str {};
+template <> struct ProvidesPortTraits<str> {
+   typedef calcium_string_port_provides PortType;
+};
+ template <> struct ProvidesPortTraits<char *> {
+   typedef  calcium_string_port_provides PortType;
+ };
 
 template < typename T > struct StarTrait        { typedef  T NonStarType; };
 template < typename T > struct StarTrait< T * > { typedef  T NonStarType; };
 
+
+// USES PORT TRAITS
+struct UnknownUsesPortType {};
 template <class T> struct UsesPortTraits {
-  typedef  UnknownPortType PortType;
+  typedef  UnknownUsesPortType PortType;
 };
 template <> struct UsesPortTraits<int> {
   typedef  calcium_integer_port_uses PortType;
@@ -80,7 +88,7 @@ template <> struct UsesPortTraits<float> {
 template <> struct UsesPortTraits<double> {
   typedef  calcium_double_port_uses PortType;
 };
-template <> struct UsesPortTraits<char *> {
+template <> struct UsesPortTraits<str> {
   typedef  calcium_string_port_uses PortType;
 };
 template <> struct UsesPortTraits<bool> {
index f4ea3d681f23319fc17d0bb630df525f60a68860..21f3384976bfee34204ae89de510ba312653140a 100644 (file)
@@ -76,7 +76,7 @@ Copy2CorbaSpace<false>  {
     std::cerr << "-------- Copy2CorbaSpace<false> MARK 1 --(dataPtr : " <<
       dataPtr<<")----------------" << std::endl;
 #endif
-    
+    // Attention : Pour les chaines ou tout autre object complexe il faut utiliser une recopie profonde !   
     std::copy(&data,&data+nRead,dataPtr);
  
 #ifdef _DEBUG_
index 36d18e37dd569606f69dbc81871a3210fe9d0617..6079179d165cec7a3614ae5883868591996e1a1c 100644 (file)
 #include <iostream>
 #include "CalciumPortTraits.hxx"
 
+#include <cstdio>
+
+//Les demandes de copies vers l'espace utilisateur
+//proviennent d'une procédure de lecture  
+
 //Cas du zero copie
 template <bool zerocopy >
 struct Copy2UserSpace{
@@ -40,66 +45,108 @@ struct Copy2UserSpace{
   template <class T1, class T2>
   static void apply( T1 * & data, T2 & corbaData, size_t nRead ){
 
+    // La ligne suivante appelle à un commentaire
+    // dans le cas de char *, cf CalciumPortTraits.hxx 'char *' vs 'str'
     typedef typename ProvidesPortTraits<T1>::PortType PortType;
     typedef typename PortType::DataManipulator        DataManipulator;
     typedef typename DataManipulator::InnerType       InnerType;
 
     // Devient propriétaire des données contenues dans la structure CORBA
     // (allouées par allocbuff() pour une séquence)
+    // Le client est propriétaire des données.
+    // Il doit cependant être attentif au fait que s'il les modifie,
+    // une nouvelle demande de lecture lui fournira les données modifiées.
+    // TODO : ? Si plusieurs lecteurs demandent la même donnée ? 
+    //        ? qui devient le propriétaire? --> normalement le premier car
+    //        ensuite la séquence n'est plus propriétaire.
+    //      NO: Le port devrait resté propriétaire du contenu de la séquence
+    //      NO: L'utilisateur doit de toute les façons utiliser les données reçues en
+    //      NO: lecture seulement car si une nouvelle demande de lecture est formulée
+    //      NO: pour ces données, les eventuelles modifications seraient visibles !
+    // YES : La solution de donner la propriété à l'utilisateur est convenable car si
+    // le port déréférence ces données (garbage collecteur, niveau) le buffer
+    // reste disponible à l'ulisateur en lecture et écriture
+    // Le problème est que la donnée CORBA stockée par le port est maintenant vide (cf CORBA BOOK)
+    // du coup quid d'une nouvelle demande de lecture : A TESTER 
     InnerType * dataPtr  = DataManipulator::getPointer(corbaData,true);
 
     // Cette ligne poserait uun problème dans la méthode appelante, si elle
     // ne testait pas que les types utilisateurs et CORBA sont identiques :
     // ex :  InnerType == Corba::Long et d'un T == int
+    // C'est l'objet de la procédure suivante
     data = dataPtr; 
 
-    // L'utilisateur a la charge de la desallocation
-    // il devra appeler la méthode ecp_free pour désallouer le contenu de la séquence CORBA
-    // La structure CORBA sera désallouer le cas échéant dans la méthode appelante
+    // En zero copie l'utilisateur doit appeler ecp_free ( cas ou un buffer intermédiaire
+    // a été alloué pour cause de typage différent xor necessité de désalouer le buffer alloué par CORBA)
+    // L'utilisateur doit cependant être attentif au fait qu'après désallocation, si la donnée
+    // est toujours estampillée dans le port une nouvelle lecture pour cette estampille
+    // rendrait un buffer vide.
   }
 };
 
 // Cas où il faut effectuer une recopie
 template <>
-struct Copy2UserSpace<false>{
+struct Copy2UserSpace<false> {
 
-  //Recopie le contenu de la donnée CORBA dans le buffer utilisateur de longueur
-  //nRead
+  //Recopie le contenu de la donnée CORBA dans le buffer utilisateur de longueur nRead
   template <class T1, class T2>
   static void apply( T1 * &data, T2 & corbaData, size_t nRead){
 
+    // La ligne suivante appelle à un commentaire
+    // dans le cas de char *, cf CalciumPortTraits.hxx 'char *' vs 'str'
     typedef typename ProvidesPortTraits<T1>::PortType  PortType;
     typedef typename PortType::DataManipulator         DataManipulator;
     typedef typename DataManipulator::InnerType        InnerType;
-
-    size_t corbaDataSize = DataManipulator::size      (corbaData);
-    // Récupère un pointeur sur les données contenues dans la structure CORBA sans en devenir propriétaire
-    InnerType * dataPtr  = DataManipulator::getPointer(corbaData,false);
-
-    // Attention : Pour les chaines ou tout autre object complexe il faut utiliser une recopie profonde !
-    // Recopie des données dans le buffer allouée par l'utilisateur 
-    // OU 
-    // Recopie des données dans le buffer allouée la méthode appelante
-    // dans le cas d'une demande utilisateur 0 copie mais sur 
-    // des types utilisateurs et CORBA incompatibles.
+    InnerType * dataPtr = NULL;
+    
+  
 #ifdef _DEBUG_
-    std::cerr << "-------- Copy2UserSpace<false> MARK 1 --(dataPtr : " <<dataPtr<<")----------------" << std::endl;
+      // Affiche la valeur du pointeur de la structure corba
+      //  et les pointeurs contenus le cas échéant
+      dataPtr  = DataManipulator::getPointer(corbaData,false);
+      std::cerr << "-------- Copy2UserSpace<false> MARK 1a --dataPtr("<<dataPtr<<")[0.."<<
+       DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
+      std::copy(dataPtr,dataPtr+DataManipulator::size(corbaData),std::ostream_iterator<T1>(std::cerr," "));
+      for (int i=0; i< DataManipulator::size(corbaData); ++i) 
+       fprintf(stderr,"pointer[%d]=%p ",i, dataPtr[i]);
+      std::cerr << std::endl;
+
+      T1 * tmpData = data;
+      std::cerr << "-------- Copy2UserSpace<false> MARK 1b --data("<<tmpData<<")[0.."<<
+       DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
+      std::copy(tmpData,tmpData+DataManipulator::size(corbaData),std::ostream_iterator<T1>(std::cerr," "));
+      for (int i=0; i< DataManipulator::size(corbaData); ++i) 
+       fprintf(stderr,"pointer[%d]=%p ",i, tmpData[i]);
+      std::cerr << std::endl;
 #endif
+
+      // Pour les types pointeurs et ref il faut effectuer une recopie profonde.
+      // On la délègue au manipulateur de données. 
+      
+      // Recopie des données dans le buffer allouée par l'utilisateur 
+      // OU 
+      // Recopie des données dans le buffer allouée par la méthode appelante (ex: lecture)
+      // dans le cas d'une demande utilisateur 0 copie mais que types utilisateurs et CORBA incompatibles.
     
-    std::copy(dataPtr,dataPtr+nRead,data);
+      //std::copy(dataPtr,dataPtr+nRead,data);
+      DataManipulator::copy(corbaData,data,nRead);
+      
 #ifdef _DEBUG_
-    std::cerr << "-------- Copy2UserSpace<false> MARK 2 --(nRead: "<<nRead<<")-------------" << std::endl;
-    std::cerr << "-------- Copy2UserSpace<false> MARK 3  --(data : " <<data<<") :";
-    std::copy(data,data+nRead,std::ostream_iterator<T1>(std::cout," "));
-    std::cout << std::endl;
+      tmpData = data;
+      std::cerr << "-------- Copy2UserSpace<false> MARK 1c --data("<<tmpData<<")[0.."<<
+       DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
+      std::copy(tmpData,tmpData+DataManipulator::size(corbaData),std::ostream_iterator<T1>(std::cerr," "));
+      for (int i=0; i< DataManipulator::size(corbaData); ++i) 
+       fprintf(stderr,"pointer[%d]=%p ",i, tmpData[i]);
+      std::cerr << std::endl;
 #endif
-
- }
+    
+  }
+  
 };
 
 
+// Désallocation des buffers si necessaire
 template <bool rel>
 struct DeleteTraits {
   template <typename T> 
@@ -110,18 +157,25 @@ struct DeleteTraits {
     //typedef typename DataManipulator::Type         DataType; // Attention != T
     
     // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non
-    // la donnée corba associée à un DataId ! Ne pas effectuer la desallocation suivante :
+    // la donnée corba associée à un DataId ! 
+    // Ne pas effectuer la desallocation suivante :
     // DataManipulator::relPointer(dataPtr);
+    // TODO : Il convient cependant de rendre la propriété du buffer à la séquence CORBA
+    // TODO : PB   : On n'a plus de référence sur la séquence. 
+    // TODO : Modifier l'API ecp_free pour indiquer le dataId associé ?
+    // TODO : ??VERIF accès concurrent à la séquence stockée ?? suppression simultanée ?
+
   }
 };
 
-// Cas où une recopie avait été effectuée
+// Désalocation du buffer intermédiaire 
+// dans le cas de types utilisateur/CORBA différents 
 template <>
 struct DeleteTraits<false>{
+
   template <typename T> 
-  static void apply(T * dataPtr) {
-    delete[] dataPtr;
-  }
+  static void apply(T * dataPtr) { delete[] dataPtr; }
+
 };
 
 #endif
index f3d3fffb436727a6a855d461ead1ac78d4776c0c..3bdabe92a62603dd47fcd6234bc5e4ba7cdfe2c7 100644 (file)
@@ -49,6 +49,7 @@ salomeinclude_HEADERS = calcium_port_factory.hxx \
                        CalciumCouplingPolicy.hxx \
                        CalciumException.hxx \
                        CalciumTypes.hxx \
+                       CalciumCxxInterface.hxx \
                        CalciumInterface.hxx \
                        Copy2UserSpace.hxx \
                        Copy2CorbaSpace.hxx \
index a60cf98b3203133dd99a00a3ab0d896da689b44a..c0adc185397e39b60d25301b15c74ebb2c1e4ec6 100644 (file)
 // Date        : $LastChangedDate: 2007-02-07 18:26:44 +0100 (mer, 07 fév 2007) $
 // Id          : $Id$
 
-#ifndef _TYPE_MANIPULATION_HXX_
-#define _TYPE_MANIPULATION_HXX_
+#ifndef _CORBA_TYPE_MANIPULATION_HXX_
+#define _CORBA_TYPE_MANIPULATION_HXX_
 
 #include <iostream>
+#include <cstring>
 #include <CORBA.h>
 
-using namespace std;
 
 // Classes manipulation
 // -------------------
@@ -48,10 +48,10 @@ using namespace std;
 // - delete_data
 // - dump
 // et
-// deux type :
-// - Type   : Le type CORBA de la donnée manipulée
-// - InType : Le mapping CORBA pour un paramètre IN du type manipulé
+// trois types :
+// - Type      : Le type CORBA de la donnée manipulée
+// - InType    : Le mapping CORBA pour un paramètre IN du type manipulé
+// - InnerType : Type interne des valeurs d'un type contenant 
 
 // Cette classe permet de manipuler des types CORBA 
 // any, struct, union et sequence (utiliser plutôt les seq_manipulator)
@@ -185,7 +185,7 @@ public:
 
   // Dump de l'objet pour deboguage : Affiche la donnee
   static void inline dump (CorbaInType data) {
-    cerr << "[atom_manipulation] Data : " << data << endl;
+    std::cerr << "[atom_manipulation] Data : " << data << std::endl;
   }
 };
 
@@ -196,11 +196,10 @@ template <typename seq_T,typename elem_T>
 class seq_u_manipulation {
   
 public:
-  typedef seq_T * Type;
-  // correspond au mapping corba de la séquence en paramètre IN
-  typedef const seq_T & CorbaInType; 
-  typedef elem_T  InnerType;
-
+  typedef seq_T *       Type;        // Type de donnée abstrait manipulé par GenericPort::Put,Get,..
+  typedef const seq_T & CorbaInType; // Mapping corba de la séquence en paramètre IN
+  typedef elem_T        InnerType;   // Il n'existe pas dans CORBA de seq_T::elem_T
+                                     // C'est la raison d'être du second paramètre template de seq_u_mani
  
   // Operation de recuperation des donnees venant de l'ORB
   // Remarque : On a un paramètre d'entrée de type const seq_T &
@@ -209,23 +208,40 @@ public:
     CORBA::Long len = data.length();
     CORBA::Long max = data.maximum();
     // Récupère et devient propriétaire des données reçues dans la séquence. 
-    // La séquence sera désalloué (mais pas le buffer) au retour 
-    // de la méthode put (car mapping de type IN : const seq & )
-    // ATTENTION TESTER p184 si le pointeur est null
-    // ATTENTION TESTER Si le flag release si la sequence contient des chaines
-    // ou des object refs
+    // La séquence (mais pas le buffer) sera désallouée au retour 
+    // de la méthode GenericPort::put (car le mapping CORBA de ce type IN est : const seq & )
+
+    // OLD : On ne teste pas si le flag release de la séquence est à true ou false 
+    // OLD : ( pour des séquences de chaines ou d'objrefs )
+    // OLD :   -> Si on est collocalisé le port uses doit créer une copie pour éviter la modification
+    // OLD : du contenu de la séquence lorsque l'utilisateur modifie ses données dans son programme (0 copie)
+
+    // Le flag release() de la séquence est à false si elle n'est pas propriétaire du buffer
+    // En  collocalité c'est le cas (on évite ici la copie réalisée auparavant dans le port uses).
+
+    // ATTENTION TESTER p194 si le pointeur est null (release flag==false)
+    //    -> La séquence n'était pas propriétaire des données !
 #ifdef _DEBUG_
     std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1 ------------------" << std::endl;
 #endif
-    InnerType * p_data = const_cast<seq_T &>(data).get_buffer(true); 
+    if ( data.release() ) {
+      InnerType * p_data = const_cast<seq_T &>(data).get_buffer(true);
+
+    // Crée une nouvelle sequence propriétaire des données du buffer (pas de recopie)
+    // Les données de la séquence seront automatiquement désallouées par appel à la méthode freebuf
+    // dans le destructeur de la séquence (cf  delete_data).
 #ifdef _DEBUG_
-    std::cout << "----seq_u_manipulation::get_data(..)-- MARK 2 ------"<<  p_data <<"------------" << std::endl;
+      std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1(0 copy) bis ------"<<  p_data <<"------------" << std::endl;
 #endif
+    
+      return  new seq_T (max, len, p_data, true);
+    }
+#ifdef _DEBUG_
+    std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1(recopie) bis ------"<<  &data <<"------------" << std::endl;
+#endif
+    // Crée une nouvelle sequence propriétaire des données du buffer (avec recopie)    
+    return new seq_T(data);
 
-    // Crée une nouvelle sequence propriétaire des données du buffer (pas de recopie)
-    // Les données seront automatiquement désallouées par appel interne à la méthode freebuf
-    // lors de la destruction de l'objet par appel à delete_data.
-    return  new seq_T (max, len, p_data, true);
   }
 
   static inline size_t size(Type data) { 
@@ -234,6 +250,9 @@ public:
 
   // Operation de destruction d'une donnee
   static inline void delete_data(Type data) {
+    //La séquence est détruite par appel à son destructeur
+    //Ce destructeur prend en compte la nécessité de détruire ou non
+    //les données contenues en fonction de son flag interne release()
     delete data;
   }
 
@@ -246,9 +265,9 @@ public:
     return new seq_T (data);
   }
 
-  // Permet de désallouer le buffer dont on détient le pointeur par appel
-  // à la méthode getPointer avec ownerShip=True si la séquence contenante
-  // à été détruite.
+  // Permet d'obtenir un pointeur sur le buffer de la séquence
+  // si ownerShip=True, la séquence n'est plus propriétaire du buffer et est
+  // détruite (mais pas le buffer !)
   static inline InnerType * const getPointer(Type data, bool ownerShip = false) {
     InnerType * p_data;
     if (ownerShip) {
@@ -266,12 +285,12 @@ public:
     seq_T::freebuf(dataPtr);
   }
 
-  // Permet d'allouer un buffer pour la séquence
+  // Permet d'allouer un buffer compatible avec le type séquence
   static inline InnerType *  allocPointer(size_t size ) {
     return seq_T::allocbuf(size);
   }
 
-  // Operation de création du type corba soit
+  // Operation de création de la séquence corba soit
   // - Vide et de taille size
   // - Utilisant les données du pointeur *data de taille size 
   // (généralement pas de recopie qlq soit l'ownership )
@@ -287,17 +306,54 @@ public:
     }
     return tmp;
   } 
+
+  // Copie le contenu de la séquence dans le buffer idata de taille isize
+  // pour les types non pointeur
+  template <typename T >
+  static inline void copy( Type data, T * const idata, size_t isize ) { 
+    
+    InnerType *dataPtr  = getPointer(data,false);
+
+    for (int i = 0; i< isize; ++i) 
+      idata[i]=dataPtr[i];
+
+    // Ce mode de recopie ne permet pas  la conversion de type (ex int -> CORBA::Long
+    //OLD:     Type tmp = new seq_T(isize,isize,idata,false); 
+    //OLD:     // giveOwnerShip == false -> seul le contenu du buffer data est détruit et remplacé
+    //OLD:     // par celui de data dans l'affectation suivante :
+    //OLD:     //       ---> ATTENTION SI LA TAILLE DU BUFFER EST TROP PETITE, QUE FAIT CORBA !
+    //OLD:     //              corruption mémoire
+    //OLD:     // Cependant ce cas devrait pas arrivé (on s'assure dans les couches supérieures
+    //OLD:     //  de la taille correcte du buffer de recopie)
+    //OLD:     // Si giveOwnerShip était == true -> le buffer et son contenu serait détruit puis une 
+    //OLD:     // allocation de la taille du buffer de data serait effectué avant la copie des données  
+    //OLD:     // tmp = data;
+  } 
+
+  // Copie le contenu de la séquence de char* dans le buffer idata de taille isize
+  static inline void copy( Type data, char* * const idata, size_t isize ) { 
+
+    char* *dataPtr  = getPointer(data,false);
+
+    // Si idata[i] n'a pas été alloué suffisament grand,
+    // il y a corruption de la mémoire
+    for (int i = 0; i< isize; ++i) 
+      strcpy(idata[i],dataPtr[i]);
+  }
   
   // Dump de l'objet pour deboguage
   static void inline dump (CorbaInType data) {
     // Affiche la longueur des donnees
-    cerr << "[seq_u_manipulation] Data length: " << data.length() << endl;
+    std::cerr << "[seq_u_manipulation] Data length: " << data.length() << std::endl;
     // Affiche la longueur des donnees
-    cerr << "[seq_u_manipulation] Data max: " << data.maximum() << endl;
+    std::cerr << "[seq_u_manipulation] Data max: " << data.maximum() << std::endl;
   }
 };
 
 
+// TODO : Vérifier la conformité de l'implémentation par rapport
+//        au type unbounded
+
 // Gére un type sequence de taille limitée (bounded)
 // Ces types sont manipulés par pointeur
 // Cette classe diffère de la seq_u_manipulation
@@ -322,11 +378,23 @@ public:
     // Récupère et devient propriétaire des données reçues dans la séquence 
     // la séquence sera désalloué (mais pas le buffer)
     // au retour de la méthode put (car mapping de type IN : const seq & )
-    InnerType * p_data = const_cast<seq_T &>(data).get_buffer(true);
+     if ( data.release() ) {
+       InnerType * p_data = const_cast<seq_T &>(data).get_buffer(true);
+
     // Crée une nouvelle sequence propriétaire des données du buffer (généralement pas de recopie)
     // Les données seront automatiquement désallouées par appel interne à la méthode freebuf
     // lors de la destruction de l'objet par appel à delete_data.
-    return new seq_T (len, p_data, true);
+#ifdef _DEBUG_
+    std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1bis Pas de Duplication  -----------" << std::endl;
+#endif
+       return new seq_T (len, p_data, true);
+     }
+#ifdef _DEBUG_
+    std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1bis Duplication pour en devenir propriétaire -----------" << std::endl;
+#endif
+    // Crée une nouvelle sequence propriétaire des données du buffer (avec recopie)    
+    return new seq_T(data);
+
   }
 
   static inline size_t size(Type data) { 
@@ -393,7 +461,7 @@ public:
   // Dump de l'objet pour deboguage
   static inline void dump (CorbaInType data) {
     // Affiche la longueur des donnees
-    cerr << "[seq_b_manipulation] Data length: " << data.length() << endl;
+    std::cerr << "[seq_b_manipulation] Data length: " << data.length() << std::endl;
   }
 };
 
index 0ef2b6c10734e4d2e66f8afebfc8184cf4e60317..2ed03762cb5a493d0b831366b43dc7a89ffc57a6 100644 (file)
@@ -93,7 +93,7 @@ public:
   // Elle profite à tous les modes de couplages n'implémentant pas
   // de comportement particulier dans la méthode get pour 
   // le cas d'une demande de dataId inexistant mais encadré par deux autres
-  template <typename DataManipulator>
+  template <typename DataManipulator, class EnableIf = void >
   struct BoundedDataIdProcessor{
     BoundedDataIdProcessor(const CouplingPolicy & couplingPolicy) {};
     template < typename Iterator, typename DataId > 
index 6148b8f8f60d75b6794a07035516b9dc11779be4..fbb324341b432ad8e2983d6d6e6b6debcaa68aa4 100644 (file)
@@ -150,7 +150,7 @@ void GenericPort<DataManipulator, COUPLING_POLICY>::put(CorbaInDataType dataPara
   try {
 #ifdef _DEBUG_
     // Affichage des donnees pour DEBUGging
-    cerr << "parametres emis: " << time << ", " << tag << endl;
+    std::cerr << "parametres emis: " << time << ", " << tag << std::endl;
     DataManipulator::dump(dataParam);
 #endif
   
@@ -428,21 +428,22 @@ GenericPort<DataManipulator, COUPLING_POLICY>::get(TimeType time,
        // Cependant  comme les données sont censées être produites
        // par ordre croissant de DataId, de nouvelles données ne devrait pas améliorer
        // l'interpolation.
-       // Les données calciulées sont donc  stockées dans storedDatas. 
-       // La propriété des données N'EST PAS transférée à l'utilisateur en mode CALCIUM.
 #ifdef _DEBUG_
        std::cout << "-------- Get : MARK 8 ------------------" << std::endl;
 #endif
 
-       typename COUPLING_POLICY::template BoundedDataIdProcessor<DataManipulator> processBoundedDataId(*this);
+       typedef typename COUPLING_POLICY::template BoundedDataIdProcessor<DataManipulator> BDI;
+       BDI processBoundedDataId(*this);
+       //      typename COUPLING_POLICY::template BoundedDataIdProcessor<DataManipulator> processBoundedDataId(*this);
        //si static BDIP::apply(dataToTransmit,expectedDataId,wDataIt1);
        //ancienne version template processBoundedDataId<DataManipulator>(dataToTransmit,expectedDataId,wDataIt1);
        //BDIP processBoundedDataId;
        processBoundedDataId.apply(dataToTransmit,expectedDataId,wDataIt1);
   
        // Il ne peut pas y avoir déjà une clé expectedDataId dans storedDatas (utilisation de la notation [] )
+       // La nouvelle donnée produite est stockée, ce n'était pas le cas dans CALCIUM
        // Cette opération n'a peut être pas un caractère générique.
-       // A déplacer en paramètre de la méthode précédente ?
+       // A déplacer en paramètre de la méthode précédente ? ou déléguer ce choix au mode de couplage ?
        storedDatas[expectedDataId]=dataToTransmit;
 
 #ifdef _DEBUG_
index f6f0ce9128cf8bc981aa7d87c4e2cc638c72fbb2..2c01e49af7461502736d9c92483696e4a2d164be 100644 (file)
@@ -85,37 +85,34 @@ template <typename DataManipulator,typename CorbaPortType, char * repositoryName
 template <typename TimeType,typename TagType>
 void
 GenericUsesPort< DataManipulator,CorbaPortType, repositoryName, UsesPort  >::put( CorbaInDataType data, 
-                                                                      TimeType time, 
-                                                                      TagType tag) {
+                                                                                 TimeType time, 
+                                                                                 TagType tag) {
   typedef typename CorbaPortType::_ptr_type CorbaPortTypePtr;
   if (!_my_ports)
     throw DSC_Exception(LOC("There is no connected provides port to communicate with."));
 
-  // PB1 : Cf remarque dans CalciumInterface, si on n'effectue pas de copie
-  //       du buffer ! 
-  // PB2 : Si les ports provides auquels on envoie data sont collocalisés
-  // ils vont partagés le même buffer (à cause de notre optim ds get_data)
-  // il faut alors effectuer une copie ici.
-  // Pour l'instant on résoud PB2 en créant une copie de la donnée en cas
-  // de connexions multiples. Il faudra tester la collocalisation.
-  DataType copyOfData; // = data; PB1
+  // OLD : PB1 : Cf remarque dans CalciumInterface, si on n'effectue pas de copie
+  // OLD :       du buffer ! 
+  // OLD : PB2 : Si les ports provides auquels on envoie data sont collocalisés
+  // OLD : ils vont partagés le même buffer (à cause de notre optim ds get_data)
+  // OLD : il faut alors effectuer une copie ici.
+  // OLD : Pour l'instant on résoud PB2 en créant une copie de la donnée en cas
+  // OLD : de connexions multiples. Il faudra tester la collocalisation.
+  // OLD :  DataType copyOfData; // = data; PB1
   for(int i = 0; i < _my_ports->length(); i++) {
 
     CorbaPortTypePtr port = CorbaPortType::_narrow((*_my_ports)[i]);
     //if (i) { PB1
-    copyOfData = DataManipulator::clone(data);
+    //OLD :   copyOfData = DataManipulator::clone(data);
 #ifdef _DEBUG_
-    std::cout << "-------- GenericUsesPort::put : Copie de data("
-      //<< DataManipulator::getPointer(data)
-             <<") vers copyOfData ("
-             <<DataManipulator::getPointer(copyOfData)
-             <<")------------------" << std::endl;
+    std::cout << "-------- GenericUsesPort::put -------- " << std::endl;
 #endif
     //} PB1
     try {
-      port->put(*copyOfData,time,tag); // catcher les exceptions
-    }   catch(const CORBA::SystemException& ex){
-      DataManipulator::delete_data(copyOfData);
+      port->put(data,time,tag);
+      // OLD : port->put(*copyOfData,time,tag);
+    } catch(const CORBA::SystemException& ex) {
+      //OLD : DataManipulator::delete_data(copyOfData);
       throw DSC_Exception(LOC(OSS() << "Impossible d'invoquer la méthode put sur le port n°"
                              << i << "( i>=  0)"));
 
@@ -124,8 +121,8 @@ GenericUsesPort< DataManipulator,CorbaPortType, repositoryName, UsesPort  >::put
     // La séquence est détruite avec le buffer si on n'est pas collocalisé
     // La séquence est détruite sans son buffer sinon (cf comportement de get_data
     // appelée dans put (port provides)
-    DataManipulator::delete_data(copyOfData);
-    }
+    //OLD : DataManipulator::delete_data(copyOfData);
+  }
 }
 
 
@@ -138,7 +135,7 @@ GenericUsesPort< DataManipulator, CorbaPortType, repositoryName, UsesPort
   if (_my_ports) delete _my_ports;
 
 #ifdef _DEBUG_
-  std::cerr << "GenericUsesPort::uses_port_changed" << endl;
+  std::cerr << "GenericUsesPort::uses_port_changed" << std::endl;
 #endif
   _my_ports = new Engines::DSC::uses_port(*new_uses_port);
 }
index 4bac01fc3f8c942e7e0a639008a70dab7a3c6c72..cf61ce458ca134e64526e93cf250ab736c2d8b76 100644 (file)
@@ -32,7 +32,7 @@
 #include "provides_port.hxx"
 #include "port_factory.hxx"
 
-// default ports factories on the Kernel
+// default ports factories in the Kernel
 #include "basic_port_factory.hxx"
 #include "palm_port_factory.hxx"
 #include "calcium_port_factory.hxx"