]> SALOME platform Git repositories - modules/kernel.git/blob - src/DSC/DSC_User/Datastream/Calcium/Copy2UserSpace.hxx
Salome HOME
merge from branch BR_V5_DEV
[modules/kernel.git] / src / DSC / DSC_User / Datastream / Calcium / Copy2UserSpace.hxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
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
42 //Cas du zero copie
43 template <bool zerocopy, typename DataManipulator >
44 struct Copy2UserSpace{
45   
46   template <class T1, class T2>
47   static void apply( T1 * & data, T2 & corbaData, size_t nRead ){
48
49      typedef typename DataManipulator::InnerType       InnerType;
50
51     // OLD:Devient propriétaire des données contenues dans la structure CORBA
52     // OLD:(allouées par allocbuff() pour une séquence)
53     // OLD:Le client est propriétaire des données.
54     // OLD:Il doit cependant être attentif au fait que s'il les modifie,
55     // OLD:une nouvelle demande de lecture lui fournira les données modifiées.
56     // OLD:TODO : Si plusieurs lecteurs demandent la même donnée, 
57     // OLD:       ? qui devient le propriétaire? --> Forcément le premier car
58     // OLD:       ensuite la séquence n'est plus propriétaire et rendra un pointeur NULL.
59     // OLD:     NO: Le port devrait resté propriétaire du contenu de la séquence
60     // OLD:     NO: L'utilisateur doit de toute les façons utiliser les données reçues en
61     // OLD:     NO: lecture seulement car si une nouvelle demande de lecture est formulée
62     // OLD:     NO: pour ces données, les eventuelles modifications seraient visibles !
63     // OLD:YES : La solution de donner la propriété à l'utilisateur est convenable car si
64     // OLD:le port déréférence ces données (garbage collecteur, niveau) le buffer
65     // OLD:reste disponible à l'ulisateur en lecture et écriture
66     // OLD:Le problème est que la donnée CORBA stockée par le port est maintenant vide (cf CORBA BOOK)
67     // OLD:du coup quid d'une nouvelle demande de lecture : A TESTER 
68
69      // Le PORT doit être capable de répondre aux demandes de lecture
70      // multiples d'une donnée pour une même estampille et doit donc garder un pointeur valide
71      // sur le buffer. Il se pose cependant un problème s'il décide
72      // de supprimer la donnée alors que des client utilise le buffer (historique) !
73      // La seule façon de gérer proprement cette situation est d'utiliser un shared_pointer (TODO).
74      // Pour l'instant l'utilisateur du mode zero copie doit s'assurer que le niveau d'historique
75      // utilisé par le port est compatible avec son utilisation des buffers. Il doit
76      // être également conscient que s'il modifie le buffer, il est modifier pour tous les
77      // utilisateurs actuels et futurs.
78     
79      //REF:    InnerType * dataPtr  = DataManipulator::getPointer(corbaData,true);
80      // Laisse la propriété des données à la structure CORBA
81      // (buffer allouée par allocbuff() pour une séquence)
82      InnerType * dataPtr  = DataManipulator::getPointer(corbaData,false);
83
84     // Cette ligne poserait uun problème dans la méthode appelante, si elle
85     // ne testait pas que les types utilisateurs et CORBA sont identiques :
86     // ex :  InnerType == Corba::Long et d'un T == int
87     // C'est l'objet de la procédure suivante
88     data = dataPtr; 
89
90     // En zero copie l'utilisateur doit appeler ecp_free ( cas ou un buffer intermédiaire
91     // a été alloué pour cause de typage différent xor necessité de désalouer le buffer alloué par CORBA)
92     // L'utilisateur doit cependant être attentif au fait qu'après désallocation, si la donnée
93     // est toujours estampillée dans le port une nouvelle lecture pour cette estampille
94     // rendrait un buffer vide.
95   }
96 };
97
98 // Cas où il faut effectuer une recopie
99 template <typename DataManipulator>
100 struct Copy2UserSpace<false, DataManipulator> {
101
102   //Recopie le contenu de la donnée CORBA dans le buffer utilisateur de longueur nRead
103   template <class T1, class T2>
104   static void apply( T1 * &data, T2 & corbaData, size_t nRead){
105
106     typedef typename DataManipulator::InnerType        InnerType;
107     
108   
109 #ifdef _DEBUG_
110     InnerType * dataPtr = NULL;
111     // Affiche la valeur du pointeur de la structure corba
112     //  et les pointeurs contenus le cas échéant
113     dataPtr  = DataManipulator::getPointer(corbaData,false);
114     std::cerr << "-------- Copy2UserSpace<false> MARK 1a --dataPtr("<<dataPtr<<")[0.."<<
115       DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
116     std::copy(dataPtr,dataPtr+DataManipulator::size(corbaData),std::ostream_iterator<T1>(std::cerr," "));
117     for (int i=0; i< DataManipulator::size(corbaData); ++i) 
118       fprintf(stderr,"pointer[%d]=%p ",i, dataPtr[i]);
119     std::cerr << std::endl;
120
121     T1 * tmpData = data;
122     //Cette affichage peut provoquer la détection d'écriture d'un espace non initailisé.
123     std::cerr << "-------- Copy2UserSpace<false> MARK 1b --data("<<tmpData<<")[0.."<<
124       DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
125     std::copy(tmpData,tmpData+DataManipulator::size(corbaData),std::ostream_iterator<T1>(std::cerr," "));
126     for (int i=0; i< DataManipulator::size(corbaData); ++i) 
127       fprintf(stderr,"pointer[%d]=%p ",i, tmpData[i]);
128     std::cerr << std::endl;
129 #endif
130
131     // Pour les types pointeurs et ref il faut effectuer une recopie profonde.
132     // On la délègue au manipulateur de données. 
133       
134     // Recopie des données dans le buffer allouée par l'utilisateur 
135     // OU 
136     // Recopie des données dans le buffer allouée par la méthode appelante (ex: lecture)
137     // dans le cas d'une demande utilisateur 0 copie mais que types utilisateurs et CORBA incompatibles.
138     
139     //std::copy(dataPtr,dataPtr+nRead,data);
140     DataManipulator::copy(corbaData,data,nRead);
141       
142 #ifdef _DEBUG_
143     tmpData = data;
144     std::cerr << "-------- Copy2UserSpace<false> MARK 1c --data("<<tmpData<<")[0.."<<
145       DataManipulator::size(corbaData) <<"] : ----------------" << std::endl;
146     std::copy(tmpData,tmpData+DataManipulator::size(corbaData),std::ostream_iterator<T1>(std::cerr," "));
147     for (int i=0; i< DataManipulator::size(corbaData); ++i) 
148       fprintf(stderr,"pointer[%d]=%p ",i, tmpData[i]);
149     std::cerr << std::endl;
150 #endif
151     
152   }
153   
154 };
155
156
157 // Désallocation des buffers si necessaire
158 template <bool rel, typename DataManipulator >
159 struct DeleteTraits {
160   template <typename T> 
161   static void apply(T * dataPtr) {
162
163     typedef typename DataManipulator::Type         DataType; // Attention != T
164     
165     // Attention : Seul CalciumCouplingPolicy via eraseDataId doit décider de supprimer ou non
166     // la donnée corba associée à un DataId ! 
167     // Ne pas effectuer la desallocation suivante :
168     // DataManipulator::relPointer(dataPtr);
169   }
170 };
171
172 // Désalocation du buffer intermédiaire 
173 // dans le cas d'un type Utilisateur différent du type CORBA 
174 template <typename DataManipulator>
175 struct DeleteTraits< false, DataManipulator > {
176
177   template <typename T> 
178   static void apply(T * dataPtr) { delete[] dataPtr; }
179
180 };
181
182 #endif