From: admin Date: Fri, 7 Mar 2008 07:43:43 +0000 (+0000) Subject: This commit was generated by cvs2git to create branch 'BR_WPdev_For_4_0'. X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=f25507034dccfad32d7cc45f4b0c477ad24e8eea;p=modules%2Fkernel.git This commit was generated by cvs2git to create branch 'BR_WPdev_For_4_0'. Sprout from BR_Dev_For_4_0 2008-02-06 14:07:04 UTC maintenance team 'Changing version to 4.1.1' Cherrypick from master 2008-03-07 07:43:41 UTC jfa 'Join modifications from BR_Dev_For_4_0 tag V4_1_1.': bin/appliskel/getAppliPath.py src/DSC/DSC_User/Datastream/Calcium/CalciumCxxInterface.hxx --- diff --git a/bin/appliskel/getAppliPath.py b/bin/appliskel/getAppliPath.py new file mode 100755 index 000000000..bac311da7 --- /dev/null +++ b/bin/appliskel/getAppliPath.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python + +import os + +def relpath(target, base): + """ Find relative path from base to target + if target== "/local/chris/appli" and base== "/local/chris" the result is appli + if target== /tmp/appli and base /local/chris the result is ../../tmp/appli + """ + target=target.split(os.path.sep) + base=base.split(os.path.sep) + for i in xrange(len(base)): + if base[i] != target[i]: + i=i-1 + #not in base + break + p=['..']*(len(base)-i-1)+target[i+1:] + if p == []: + return '.' + return os.path.join( *p ) + +def set_var(VAR, strpath): + """Set VAR environment variable """ + value = "%r" % strpath + shell = os.getenv('SHELL') + if shell and shell.endswith('csh'): + return "setenv %s %s" % (VAR, value) + else: + return "export %s=%s" % (VAR, value) + + +applipath=relpath(os.path.abspath(os.path.dirname(__file__)),os.path.abspath(os.getenv('HOME'))) + +#print set_var('APPLI', applipath) +print applipath 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