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, \
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,);
}
+// INTERFACES D'ECRITURE
#define CALCIUM_ECR_INTERFACE_C_(_name,_timeType,_type,_typeName,_qual) \
InfoType cp_##_name (void * component, int mode, \
_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,);
#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"
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;
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;
};
-// 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;
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) {
--- /dev/null
+// 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
#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++
typedef double TimeType;
};
+// Définition de ecp_fin
extern "C" CalciumTypes::InfoType
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, \
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; \
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, \
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
#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;
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;
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> {
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_
#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{
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>
//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
CalciumCouplingPolicy.hxx \
CalciumException.hxx \
CalciumTypes.hxx \
+ CalciumCxxInterface.hxx \
CalciumInterface.hxx \
Copy2UserSpace.hxx \
Copy2CorbaSpace.hxx \
// 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
// -------------------
// - 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)
// 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;
}
};
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 &
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) {
// 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;
}
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) {
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 )
}
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
// 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) {
// 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;
}
};
// 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 >
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
// 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_
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)"));
// 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);
+ }
}
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);
}
#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"