]> SALOME platform Git repositories - modules/kernel.git/blob - src/DSC/DSC_User/Datastream/Calcium/Copy2UserSpace.hxx
Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/kernel.git] / src / DSC / DSC_User / Datastream / Calcium / Copy2UserSpace.hxx
1 //  Copyright (C) 2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
3 // 
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. 
8 // 
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. 
13 // 
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 
17 // 
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 //
21 //
22 //  File   : Copy2UserSpace.hxx
23 //  Author : Eric Fayolle (EDF)
24 //  Module : KERNEL
25 // Modified by : $LastChangedBy$
26 // Date        : $LastChangedDate: 2007-02-13 11:09:09 +0100 (mar, 13 fév 2007) $
27 // Id          : $Id$
28
29 #ifndef _COPY_TO_USER_SPACE_HXX_
30 #define _COPY_TO_USER_SPACE_HXX_
31
32 #include <string>
33 #include <iostream>
34 #include "CalciumPortTraits.hxx"
35
36 #include <cstdio>
37
38 //Les demandes de copies vers l'espace utilisateur
39 //proviennent d'une procédure de lecture  
40
41 //Cas du zero copie
42 template <bool zerocopy >
43 struct Copy2UserSpace{
44   
45   template <class T1, class T2>
46   static void apply( T1 * & data, T2 & corbaData, size_t nRead ){
47
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;
53
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);
72
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
77     data = dataPtr; 
78
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.
84   }
85 };
86
87 // Cas où il faut effectuer une recopie
88 template <>
89 struct Copy2UserSpace<false> {
90
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){
94
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;
100     
101   
102 #ifdef _DEBUG_
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;
113
114       T1 * tmpData = data;
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;
121 #endif
122
123       // Pour les types pointeurs et ref il faut effectuer une recopie profonde.
124       // On la délègue au manipulateur de données. 
125       
126       // Recopie des données dans le buffer allouée par l'utilisateur 
127       // OU 
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.
130     
131       //std::copy(dataPtr,dataPtr+nRead,data);
132       DataManipulator::copy(corbaData,data,nRead);
133       
134 #ifdef _DEBUG_
135       tmpData = data;
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;
142 #endif
143     
144   }
145   
146 };
147
148
149 // Désallocation des buffers si necessaire
150 template <bool rel>
151 struct DeleteTraits {
152   template <typename T> 
153   static void apply(T * dataPtr) {
154
155     typedef typename ProvidesPortTraits<T>::PortType     PortType;
156     typedef typename PortType::DataManipulator          DataManipulator;
157     //typedef typename DataManipulator::Type         DataType; // Attention != T
158     
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 ?
167
168   }
169 };
170
171 // Désalocation du buffer intermédiaire 
172 // dans le cas de types utilisateur/CORBA différents 
173 template <>
174 struct DeleteTraits<false>{
175
176   template <typename T> 
177   static void apply(T * dataPtr) { delete[] dataPtr; }
178
179 };
180
181 #endif