1 // Copyright (C) 2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : Copy2UserSpace.hxx
23 // Author : Eric Fayolle (EDF)
25 // Modified by : $LastChangedBy$
26 // Date : $LastChangedDate: 2007-02-13 11:09:09 +0100 (mar, 13 fév 2007) $
29 #ifndef _COPY_TO_USER_SPACE_HXX_
30 #define _COPY_TO_USER_SPACE_HXX_
34 #include "CalciumPortTraits.hxx"
38 //Les demandes de copies vers l'espace utilisateur
39 //proviennent d'une procédure de lecture
42 template <bool zerocopy >
43 struct Copy2UserSpace{
45 template <class T1, class T2>
46 static void apply( T1 * & data, T2 & corbaData, size_t nRead ){
48 // La ligne suivante appelle à un commentaire
49 // dans le cas de char *, cf CalciumPortTraits.hxx 'char *' vs 'str'
50 typedef typename ProvidesPortTraits<T1>::PortType PortType;
51 typedef typename PortType::DataManipulator DataManipulator;
52 typedef typename DataManipulator::InnerType InnerType;
54 // Devient propriétaire des données contenues dans la structure CORBA
55 // (allouées par allocbuff() pour une séquence)
56 // Le client est propriétaire des données.
57 // Il doit cependant être attentif au fait que s'il les modifie,
58 // une nouvelle demande de lecture lui fournira les données modifiées.
59 // TODO : ? Si plusieurs lecteurs demandent la même donnée ?
60 // ? qui devient le propriétaire? --> normalement le premier car
61 // ensuite la séquence n'est plus propriétaire.
62 // NO: Le port devrait resté propriétaire du contenu de la séquence
63 // NO: L'utilisateur doit de toute les façons utiliser les données reçues en
64 // NO: lecture seulement car si une nouvelle demande de lecture est formulée
65 // NO: pour ces données, les eventuelles modifications seraient visibles !
66 // YES : La solution de donner la propriété à l'utilisateur est convenable car si
67 // le port déréférence ces données (garbage collecteur, niveau) le buffer
68 // reste disponible à l'ulisateur en lecture et écriture
69 // Le problème est que la donnée CORBA stockée par le port est maintenant vide (cf CORBA BOOK)
70 // du coup quid d'une nouvelle demande de lecture : A TESTER
71 InnerType * dataPtr = DataManipulator::getPointer(corbaData,true);
73 // Cette ligne poserait uun problème dans la méthode appelante, si elle
74 // ne testait pas que les types utilisateurs et CORBA sont identiques :
75 // ex : InnerType == Corba::Long et d'un T == int
76 // C'est l'objet de la procédure suivante
79 // En zero copie l'utilisateur doit appeler ecp_free ( cas ou un buffer intermédiaire
80 // a été alloué pour cause de typage différent xor necessité de désalouer le buffer alloué par CORBA)
81 // L'utilisateur doit cependant être attentif au fait qu'après désallocation, si la donnée
82 // est toujours estampillée dans le port une nouvelle lecture pour cette estampille
83 // rendrait un buffer vide.
87 // Cas où il faut effectuer une recopie
89 struct Copy2UserSpace<false> {
91 //Recopie le contenu de la donnée CORBA dans le buffer utilisateur de longueur nRead
92 template <class T1, class T2>
93 static void apply( T1 * &data, T2 & corbaData, size_t nRead){
95 // La ligne suivante appelle à un commentaire
96 // dans le cas de char *, cf CalciumPortTraits.hxx 'char *' vs 'str'
97 typedef typename ProvidesPortTraits<T1>::PortType PortType;
98 typedef typename PortType::DataManipulator DataManipulator;
99 typedef typename DataManipulator::InnerType InnerType;
103 InnerType * dataPtr = NULL;
104 // Affiche la valeur du pointeur de la structure corba
105 // et les pointeurs contenus le cas échéant
106 dataPtr = DataManipulator::getPointer(corbaData,false);
107 std::cerr << "-------- Copy2UserSpace<false> MARK 1a --dataPtr("<<dataPtr<<")[0.."<<
108 DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
109 std::copy(dataPtr,dataPtr+DataManipulator::size(corbaData),std::ostream_iterator<T1>(std::cerr," "));
110 for (int i=0; i< DataManipulator::size(corbaData); ++i)
111 fprintf(stderr,"pointer[%d]=%p ",i, dataPtr[i]);
112 std::cerr << std::endl;
115 std::cerr << "-------- Copy2UserSpace<false> MARK 1b --data("<<tmpData<<")[0.."<<
116 DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
117 std::copy(tmpData,tmpData+DataManipulator::size(corbaData),std::ostream_iterator<T1>(std::cerr," "));
118 for (int i=0; i< DataManipulator::size(corbaData); ++i)
119 fprintf(stderr,"pointer[%d]=%p ",i, tmpData[i]);
120 std::cerr << std::endl;
123 // Pour les types pointeurs et ref il faut effectuer une recopie profonde.
124 // On la délègue au manipulateur de données.
126 // Recopie des données dans le buffer allouée par l'utilisateur
128 // Recopie des données dans le buffer allouée par la méthode appelante (ex: lecture)
129 // dans le cas d'une demande utilisateur 0 copie mais que types utilisateurs et CORBA incompatibles.
131 //std::copy(dataPtr,dataPtr+nRead,data);
132 DataManipulator::copy(corbaData,data,nRead);
136 std::cerr << "-------- Copy2UserSpace<false> MARK 1c --data("<<tmpData<<")[0.."<<
137 DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
138 std::copy(tmpData,tmpData+DataManipulator::size(corbaData),std::ostream_iterator<T1>(std::cerr," "));
139 for (int i=0; i< DataManipulator::size(corbaData); ++i)
140 fprintf(stderr,"pointer[%d]=%p ",i, tmpData[i]);
141 std::cerr << std::endl;
149 // Désallocation des buffers si necessaire
151 struct DeleteTraits {
152 template <typename T>
153 static void apply(T * dataPtr) {
155 typedef typename ProvidesPortTraits<T>::PortType PortType;
156 typedef typename PortType::DataManipulator DataManipulator;
157 //typedef typename DataManipulator::Type DataType; // Attention != T
159 // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non
160 // la donnée corba associée à un DataId !
161 // Ne pas effectuer la desallocation suivante :
162 // DataManipulator::relPointer(dataPtr);
163 // TODO : Il convient cependant de rendre la propriété du buffer à la séquence CORBA
164 // TODO : PB : On n'a plus de référence sur la séquence.
165 // TODO : Modifier l'API ecp_free pour indiquer le dataId associé ?
166 // TODO : ??VERIF accès concurrent à la séquence stockée ?? suppression simultanée ?
171 // Désalocation du buffer intermédiaire
172 // dans le cas de types utilisateur/CORBA différents
174 struct DeleteTraits<false>{
176 template <typename T>
177 static void apply(T * dataPtr) { delete[] dataPtr; }