From 2c94e68ab60532ed8592f4f786b57ddead8ddefb Mon Sep 17 00:00:00 2001 From: fayolle Date: Wed, 13 Feb 2008 15:20:57 +0000 Subject: [PATCH] *** empty log message *** --- src/DSC/DSC_User/Datastream/Calcium/Calcium.c | 104 +++- .../Calcium/CalciumCouplingPolicy.hxx | 34 +- .../Calcium/CalciumCxxInterface.hxx | 500 +++++++++++++++ .../Datastream/Calcium/CalciumInterface.hxx | 571 ++++-------------- .../Datastream/Calcium/CalciumPortTraits.hxx | 26 +- .../Datastream/Calcium/Copy2CorbaSpace.hxx | 2 +- .../Datastream/Calcium/Copy2UserSpace.hxx | 118 +++- .../DSC_User/Datastream/Calcium/Makefile.am | 1 + .../Datastream/CorbaTypeManipulator.hxx | 136 +++-- .../DSC_User/Datastream/CouplingPolicy.hxx | 2 +- src/DSC/DSC_User/Datastream/GenericPort.hxx | 11 +- .../DSC_User/Datastream/GenericUsesPort.hxx | 41 +- src/DSC/DSC_User/Superv_Component_i.hxx | 2 +- 13 files changed, 938 insertions(+), 610 deletions(-) create mode 100644 src/DSC/DSC_User/Datastream/Calcium/CalciumCxxInterface.hxx diff --git a/src/DSC/DSC_User/Datastream/Calcium/Calcium.c b/src/DSC/DSC_User/Datastream/Calcium/Calcium.c index de497f752..12bfcb6b3 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/Calcium.c +++ b/src/DSC/DSC_User/Datastream/Calcium/Calcium.c @@ -34,12 +34,15 @@ 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,); diff --git a/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.hxx b/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.hxx index a6c301ee6..1fe1c0e5b 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/CalciumCouplingPolicy.hxx @@ -34,6 +34,8 @@ #include "CouplingPolicy.hxx" #include "AdjacentFunctor.hxx" #include +#include +#include #include "CalciumTypes.hxx" #include "CalciumException.hxx" @@ -44,7 +46,8 @@ public: template class InternalDataIdContainer; template friend class InternalDataIdContainer; - template friend class BoundedDataIdProcessor; + template friend class BoundedDataIdProcessor; template friend class EraseDataIdProcessor; template 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 struct BoundedDataIdProcessor; + template struct BoundedDataIdProcessor; + //template struct BoundedDataIdProcessor; template struct EraseDataIdProcessor; template 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 +template struct CalciumCouplingPolicy::BoundedDataIdProcessor{ + BoundedDataIdProcessor(const CouplingPolicy & couplingPolicy) {}; + template < typename Iterator, typename DataId > + void inline apply(typename iterator_t::value_type & data, + const DataId & dataId, + const Iterator & it1) const { + typedef typename iterator_t::value_type value_type; + std::cout << "-------- Calcium Generic BoundedDataIdProcessor.apply() called " << std::endl; + + } +}; + + +template +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 index 000000000..39565be08 --- /dev/null +++ b/src/DSC/DSC_User/Datastream/Calcium/CalciumCxxInterface.hxx @@ -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 +#include +#include +#include "Superv_Component_i.hxx" +#include "CalciumException.hxx" +#include "CalciumTypes.hxx" +#include "CalciumGenericUsesPort.hxx" +#include "Copy2UserSpace.hxx" +#include "Copy2CorbaSpace.hxx" +#include "CalciumPortTraits.hxx" + +#include + +//#define _DEBUG_ + +template +struct IsSameType { + static const bool value = false; +}; +template +struct IsSameType { + static const bool value = true; +}; + + + +namespace CalciumInterface { + + /********************* INTERFACE DE DECONNEXION *****************/ + + static void + ecp_fin (Superv_Component_i & component, bool provideLastGivenValue) + { + std::vector usesPortNames; + std::vector::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(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 static void + ecp_free ( T1 * dataPtr ) + { + typedef typename ProvidesPortTraits::PortType PortType; + typedef typename PortType::DataManipulator DataManipulator; + typedef typename DataManipulator::Type DataType; // Attention != T + typedef typename DataManipulator::InnerType InnerType; + + DeleteTraits::value >::apply(dataPtr); + } + + template static void + ecp_free ( T1 * dataPtr ) + { + ecp_free ( dataPtr ); + } + + + /********************* INTERFACES DE LECTURE *****************/ + + // T1 est le type de données + template 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 (component,dependencyType,ti,tf, + i,nomVar,bufferLength,nRead,data); + + } + + // T1 est le type de données + // T2 est un 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 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::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 ")); + 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::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::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::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::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(std::cout," ")); + std::cout << "Ptr :" << data << std::endl; + + std::cout << "-------- CalciumInterface(ecp_lecture) MARK 13 ------------------" << std::endl; +#endif + + + return; + } + + + /********************* INTERFACES D'ECRITURE *****************/ + + template 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 (component,dependencyType,t,i,nomVar,bufferLength,data); + } + + template 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::NonStarType T; + typedef typename UsesPortTraits::PortType PortType; + typedef typename ProvidesPortTraits::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 ")); + 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::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::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 diff --git a/src/DSC/DSC_User/Datastream/Calcium/CalciumInterface.hxx b/src/DSC/DSC_User/Datastream/Calcium/CalciumInterface.hxx index 8e8453c95..504d3b256 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/CalciumInterface.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/CalciumInterface.hxx @@ -29,461 +29,22 @@ #ifndef _CALCIUM_INTERFACE_HXX_ #define _CALCIUM_INTERFACE_HXX_ -#include -#include -#include -#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 //#define _DEBUG_ -// Déplacer cette information dans CorbaTypeManipulator -// Gérer en même temps la recopie profonde. - -template -struct IsSameType { - static const bool value = false; -}; -template -struct IsSameType { - static const bool value = true; -}; - - - - -//class CalciumInterface { -namespace CalciumInterface { -//public : - - - static void - ecp_fin (Superv_Component_i & component, bool provideLastGivenValue) - { - std::vector usesPortNames; - std::vector::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(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 static void - ecp_free ( T1 * dataPtr ) - { - typedef typename ProvidesPortTraits::PortType PortType; - typedef typename PortType::DataManipulator DataManipulator; - typedef typename DataManipulator::Type DataType; // Attention != T - typedef typename DataManipulator::InnerType InnerType; - - DeleteTraits::value >::apply(dataPtr); - } - - template static void - ecp_free ( T1 * dataPtr ) - { - ecp_free ( dataPtr ); - } - - template 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 (component,dependencyType,ti,tf, - i,nomVar,bufferLength,nRead,data); - - } - - template 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::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 ")); - 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::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::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::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::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(std::cout," ")); - std::cout << "Ptr :" << data << std::endl; - - std::cout << "-------- CalciumInterface(ecp_lecture) MARK 13 ------------------" << std::endl; -#endif - - - return; - } - - - template 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 (component,dependencyType,t,i,nomVar,bufferLength,data); - } - - template 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::NonStarType T; - typedef typename UsesPortTraits::PortType PortType; - typedef typename ProvidesPortTraits::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 ")); - 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::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<::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 { 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<::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(component); +// double _ti=*ti; +// double _tf=*tf; +// size_t _nRead=0; +// size_t _bufferLength=bufferLength; +// CalciumTypes::DependencyType _dependencyType= +// static_cast(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(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(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 diff --git a/src/DSC/DSC_User/Datastream/Calcium/CalciumPortTraits.hxx b/src/DSC/DSC_User/Datastream/Calcium/CalciumPortTraits.hxx index baacd9c77..d05cc440d 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/CalciumPortTraits.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/CalciumPortTraits.hxx @@ -31,10 +31,10 @@ #include "Superv_Component_i.hxx" - -struct UnknownPortType {}; +// PROVIDES PORT TRAITS +struct UnknownProvidesPortType {}; template struct ProvidesPortTraits { - typedef UnknownPortType PortType; + typedef UnknownProvidesPortType PortType; }; template <> struct ProvidesPortTraits { typedef calcium_integer_port_provides PortType; @@ -48,25 +48,33 @@ template <> struct ProvidesPortTraits { template <> struct ProvidesPortTraits { typedef calcium_double_port_provides PortType; }; -template <> struct ProvidesPortTraits { - typedef calcium_string_port_provides PortType; -}; template <> struct ProvidesPortTraits { 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 { typedef calcium_complex_port_provides PortType; }; +// Défénition du type str pour obtenir le type de port +// correspondant +struct str {}; +template <> struct ProvidesPortTraits { + typedef calcium_string_port_provides PortType; +}; + template <> struct ProvidesPortTraits { + 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 struct UsesPortTraits { - typedef UnknownPortType PortType; + typedef UnknownUsesPortType PortType; }; template <> struct UsesPortTraits { typedef calcium_integer_port_uses PortType; @@ -80,7 +88,7 @@ template <> struct UsesPortTraits { template <> struct UsesPortTraits { typedef calcium_double_port_uses PortType; }; -template <> struct UsesPortTraits { +template <> struct UsesPortTraits { typedef calcium_string_port_uses PortType; }; template <> struct UsesPortTraits { diff --git a/src/DSC/DSC_User/Datastream/Calcium/Copy2CorbaSpace.hxx b/src/DSC/DSC_User/Datastream/Calcium/Copy2CorbaSpace.hxx index f4ea3d681..21f338497 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/Copy2CorbaSpace.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/Copy2CorbaSpace.hxx @@ -76,7 +76,7 @@ Copy2CorbaSpace { std::cerr << "-------- Copy2CorbaSpace 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_ diff --git a/src/DSC/DSC_User/Datastream/Calcium/Copy2UserSpace.hxx b/src/DSC/DSC_User/Datastream/Calcium/Copy2UserSpace.hxx index 36d18e37d..6079179d1 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/Copy2UserSpace.hxx +++ b/src/DSC/DSC_User/Datastream/Calcium/Copy2UserSpace.hxx @@ -33,6 +33,11 @@ #include #include "CalciumPortTraits.hxx" +#include + +//Les demandes de copies vers l'espace utilisateur +//proviennent d'une procédure de lecture + //Cas du zero copie template struct Copy2UserSpace{ @@ -40,66 +45,108 @@ struct Copy2UserSpace{ template 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::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{ +struct Copy2UserSpace { - //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 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::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 MARK 1 --(dataPtr : " < MARK 1a --dataPtr("<(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 MARK 1b --data("<(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 MARK 2 --(nRead: "< MARK 3 --(data : " <(std::cout," ")); - std::cout << std::endl; + tmpData = data; + std::cerr << "-------- Copy2UserSpace MARK 1c --data("<(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 struct DeleteTraits { template @@ -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{ + template - static void apply(T * dataPtr) { - delete[] dataPtr; - } + static void apply(T * dataPtr) { delete[] dataPtr; } + }; #endif diff --git a/src/DSC/DSC_User/Datastream/Calcium/Makefile.am b/src/DSC/DSC_User/Datastream/Calcium/Makefile.am index f3d3fffb4..3bdabe92a 100644 --- a/src/DSC/DSC_User/Datastream/Calcium/Makefile.am +++ b/src/DSC/DSC_User/Datastream/Calcium/Makefile.am @@ -49,6 +49,7 @@ salomeinclude_HEADERS = calcium_port_factory.hxx \ CalciumCouplingPolicy.hxx \ CalciumException.hxx \ CalciumTypes.hxx \ + CalciumCxxInterface.hxx \ CalciumInterface.hxx \ Copy2UserSpace.hxx \ Copy2CorbaSpace.hxx \ diff --git a/src/DSC/DSC_User/Datastream/CorbaTypeManipulator.hxx b/src/DSC/DSC_User/Datastream/CorbaTypeManipulator.hxx index a60cf98b3..c0adc1853 100644 --- a/src/DSC/DSC_User/Datastream/CorbaTypeManipulator.hxx +++ b/src/DSC/DSC_User/Datastream/CorbaTypeManipulator.hxx @@ -26,13 +26,13 @@ // 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 +#include #include -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 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(data).get_buffer(true); + if ( data.release() ) { + InnerType * p_data = const_cast(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 + 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(data).get_buffer(true); + if ( data.release() ) { + InnerType * p_data = const_cast(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; } }; diff --git a/src/DSC/DSC_User/Datastream/CouplingPolicy.hxx b/src/DSC/DSC_User/Datastream/CouplingPolicy.hxx index 0ef2b6c10..2ed03762c 100644 --- a/src/DSC/DSC_User/Datastream/CouplingPolicy.hxx +++ b/src/DSC/DSC_User/Datastream/CouplingPolicy.hxx @@ -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 + template struct BoundedDataIdProcessor{ BoundedDataIdProcessor(const CouplingPolicy & couplingPolicy) {}; template < typename Iterator, typename DataId > diff --git a/src/DSC/DSC_User/Datastream/GenericPort.hxx b/src/DSC/DSC_User/Datastream/GenericPort.hxx index 6148b8f8f..fbb324341 100644 --- a/src/DSC/DSC_User/Datastream/GenericPort.hxx +++ b/src/DSC/DSC_User/Datastream/GenericPort.hxx @@ -150,7 +150,7 @@ void GenericPort::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::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 processBoundedDataId(*this); + typedef typename COUPLING_POLICY::template BoundedDataIdProcessor BDI; + BDI processBoundedDataId(*this); + // typename COUPLING_POLICY::template BoundedDataIdProcessor processBoundedDataId(*this); //si static BDIP::apply(dataToTransmit,expectedDataId,wDataIt1); //ancienne version template processBoundedDataId(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_ diff --git a/src/DSC/DSC_User/Datastream/GenericUsesPort.hxx b/src/DSC/DSC_User/Datastream/GenericUsesPort.hxx index f6f0ce912..2c01e49af 100644 --- a/src/DSC/DSC_User/Datastream/GenericUsesPort.hxx +++ b/src/DSC/DSC_User/Datastream/GenericUsesPort.hxx @@ -85,37 +85,34 @@ template 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 (" - <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); } diff --git a/src/DSC/DSC_User/Superv_Component_i.hxx b/src/DSC/DSC_User/Superv_Component_i.hxx index 4bac01fc3..cf61ce458 100644 --- a/src/DSC/DSC_User/Superv_Component_i.hxx +++ b/src/DSC/DSC_User/Superv_Component_i.hxx @@ -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" -- 2.39.2