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 : CorbaTypeManipulator.hxx
23 // Author : Eric Fayolle (EDF)
25 // Modified by : $LastChangedBy$
26 // Date : $LastChangedDate: 2007-02-07 18:26:44 +0100 (mer, 07 fév 2007) $
29 #ifndef _TYPE_MANIPULATION_HXX_
30 #define _TYPE_MANIPULATION_HXX_
37 // Classes manipulation
38 // -------------------
40 // Ces différentes classes permettent d'unifier la manipulation des
41 // différents types de données dans un port datastream
42 // Les données sont maniées par valeur ou par pointeur
43 // pour éviter les recopies de gros volume de données
45 // Les classes présentes quatre méthodes :
52 // - Type : Le type CORBA de la donnée manipulée
53 // - InType : Le mapping CORBA pour un paramètre IN du type manipulé
56 // Cette classe permet de manipuler des types CORBA
57 // any, struct, union et sequence (utiliser plutôt les seq_manipulator)
58 // Ces types sont manipulés par pointeur.
59 // Les données reçues de CORBA sont systématiquement
60 // dupliquées pour être conservées.
61 // Quelque soit le type de donnée, les données sont considérées
62 // comme une donnée unique (retour de size() == 1)
63 template <typename T >
64 class user_type_manipulation
68 // correspond au mapping corba des type any, struct,
69 // union, séquence en paramètre IN
70 typedef const T & CorbaInType;
73 // Operation de recuperation des donnees venant de l'ORB et
74 // creation d'une copie (memoire spécialement allouee)
75 static inline Type get_data(CorbaInType data) {
79 // Pb si ownerShip == True car appel par l'utilisateur de relPointer !
80 static inline InnerType * const getPointer(Type data, bool ownerShip = false) {
84 static inline void relPointer(InnerType * dataPtr) {
88 // Operation de clonage : par defaut, creation d'une copie en memoire allouee pour l'occasion
89 static inline Type clone(Type data) {
90 return new T (* data);
92 static inline Type clone(CorbaInType data) {
96 // Operation de création
97 static inline Type create (size_t size=1) {
101 // Operation de destruction d'une donnee
102 static inline void delete_data(Type data) {
106 // Renvoie la taille de la donnée
107 static inline size_t size(Type data) {
111 // Dump de l'objet pour deboguage: neant car on ne connait pas sa structure
112 static inline void dump (CorbaInType data) {}
116 // Gére les types CORBA atomiques ('Int', 'Char', 'Float', ...)
117 // Gére les types enums
118 // Gére les références d'objets CORBA
119 // Ces types sont manipulés par valeur
120 // Les méthodes getPointer ... ne devrait pas être utilisée
121 // pour ce types de données
122 template <typename T>
123 class atom_manipulation
127 // correspond au mapping corba des types simples en paramètre IN
128 typedef T CorbaInType;
132 // Operation de recuperation des donnees venant de l'ORB : une copie par affectation simple
133 static inline Type get_data(CorbaInType data) {
137 static inline InnerType * const getPointer(Type & data, bool getOwnerShip = false) {
139 // if (getOwnerShip) {
140 // ptr =new InnerType[1];*ptr=data;
147 // static inline void relPointer(InnerType * dataPtr) {
152 // Je ne sais pas comment l'implémenter sans faire
154 //static inline InnerType * allocPointer(size_t size=1) {
155 // return new InnerType[1];
158 // Operation de clonage : une copie par affectation simple
159 static inline Type clone(Type data) {
163 // Inutile car Type == CorbaInType
164 // static inline Type clone(CorbaInType data) {
168 // Operation de création
169 // static inline Type create(size_t size=1,InnerType * data=NULL,
170 // bool giveOwnerShip=false) {
178 // Operation de destruction d'une donnee: rien a faire car pas de memoire a liberer
179 static inline void delete_data(Type data) {}
180 // Renvoie la taille de la donnée
182 static inline size_t size(Type data) {
186 // Dump de l'objet pour deboguage : Affiche la donnee
187 static void inline dump (CorbaInType data) {
188 cerr << "[atom_manipulation] Data : " << data << endl;
193 // Gére un type sequence de taille illimitee (Unbounded)
194 // Ces types sont manipulés par pointeur
195 template <typename seq_T,typename elem_T>
196 class seq_u_manipulation {
199 typedef seq_T * Type;
200 // correspond au mapping corba de la séquence en paramètre IN
201 typedef const seq_T & CorbaInType;
202 typedef elem_T InnerType;
205 // Operation de recuperation des donnees venant de l'ORB
206 // Remarque : On a un paramètre d'entrée de type const seq_T &
207 // et en sortie un seq_T *
208 static inline Type get_data(CorbaInType data) {
209 CORBA::Long len = data.length();
210 CORBA::Long max = data.maximum();
211 // Récupère et devient propriétaire des données reçues dans la séquence.
212 // La séquence sera désalloué (mais pas le buffer) au retour
213 // de la méthode put (car mapping de type IN : const seq & )
214 // ATTENTION TESTER p184 si le pointeur est null
215 // ATTENTION TESTER Si le flag release si la sequence contient des chaines
216 // ou des object refs
217 std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1 ------------------" << std::endl;
218 InnerType * p_data = const_cast<seq_T &>(data).get_buffer(true);
219 std::cout << "----seq_u_manipulation::get_data(..)-- MARK 2 ------"<< p_data <<"------------" << std::endl;
221 // Crée une nouvelle sequence propriétaire des données du buffer (pas de recopie)
222 // Les données seront automatiquement désallouées par appel interne à la méthode freebuf
223 // lors de la destruction de l'objet par appel à delete_data.
224 return new seq_T (max, len, p_data, true);
227 static inline size_t size(Type data) {
228 return data->length();
231 // Operation de destruction d'une donnee
232 static inline void delete_data(Type data) {
236 // Operation de clonage : par defaut creation d'une copie en memoire allouee pour l'occasion
237 // Utilisation du constructeur du type seq_T
238 static inline Type clone(Type data) {
239 return new seq_T (*data) ;
241 static inline Type clone(CorbaInType data) {
242 return new seq_T (data);
245 // Permet de désallouer le buffer dont on détient le pointeur par appel
246 // à la méthode getPointer avec ownerShip=True si la séquence contenante
248 static inline InnerType * const getPointer(Type data, bool ownerShip = false) {
251 p_data = data->get_buffer(true);
254 p_data = data->get_buffer(false);
258 // Permet de désallouer le buffer dont on détient le pointeur par appel
259 // à la méthode getPointer avec ownerShip=True si la séquence contenante
261 static inline void relPointer(InnerType * dataPtr) {
262 seq_T::freebuf(dataPtr);
265 // Permet d'allouer un buffer pour la séquence
266 static inline InnerType * allocPointer(size_t size ) {
267 return seq_T::allocbuf(size);
270 // Operation de création du type corba soit
271 // - Vide et de taille size
272 // - Utilisant les données du pointeur *data de taille size
273 // (généralement pas de recopie qlq soit l'ownership )
274 // data doit avoir été alloué par allocPointer si giveOwnerShip = true
275 static inline Type create(size_t size, InnerType * const data = NULL,
276 bool giveOwnerShip = false ) {
282 tmp = new seq_T(size,size,data,giveOwnerShip);
287 // Dump de l'objet pour deboguage
288 static void inline dump (CorbaInType data) {
289 // Affiche la longueur des donnees
290 cerr << "[seq_u_manipulation] Data length: " << data.length() << endl;
291 // Affiche la longueur des donnees
292 cerr << "[seq_u_manipulation] Data max: " << data.maximum() << endl;
297 // Gére un type sequence de taille limitée (bounded)
298 // Ces types sont manipulés par pointeur
299 // Cette classe diffère de la seq_u_manipulation
300 // par la signature du constructeur de la séquence
301 // utilisé dans le methode get_data
302 template <typename seq_T,typename elem_T>
303 class seq_b_manipulation {
306 typedef seq_T * Type;
307 typedef const seq_T & CorbaInType;
308 typedef elem_T InnerType;
311 // Operation de recuperation des donnees venant de l'ORB
312 // Sans opération de notre part, ces données seraient perdues
313 // au retour de la méthode put de GenericPort.
314 // Remarque : On a un paramètre d'entrée de type const seq_T &
315 // et en sortie un seq_T *
316 static inline Type get_data(CorbaInType data) {
317 CORBA::Long len = data.length();
318 // Récupère et devient propriétaire des données reçues dans la séquence
319 // la séquence sera désalloué (mais pas le buffer)
320 // au retour de la méthode put (car mapping de type IN : const seq & )
321 InnerType * p_data = const_cast<seq_T &>(data).get_buffer(true);
322 // Crée une nouvelle sequence propriétaire des données du buffer (généralement pas de recopie)
323 // Les données seront automatiquement désallouées par appel interne à la méthode freebuf
324 // lors de la destruction de l'objet par appel à delete_data.
325 return new seq_T (len, p_data, true);
328 static inline size_t size(Type data) {
329 return data->length();
332 // Operation de clonage : par defaut creation d'une copie en memoire allouee pour l'occasion
333 // Utilisation du constructeur du type seq_T
334 static inline Type clone(Type data) {
335 return new seq_T (* data);
337 static inline Type clone(CorbaInType data) {
338 return new seq_T (data);
341 // Operation de destruction d'une donnee CORBA
342 static inline void delete_data(Type data) {
346 // Récupère un pointeur sur les données de type InnerType contenue dans la séquence
347 // si ownership=True, l'utilisateur devra appeler relPointer
348 // si ownership=False, l'utilisateur devra appeler delete_data sur la séquence contenante
349 static inline InnerType * const getPointer(Type data, bool getOwnerShip = false) {
352 p_data = data->get_buffer(true);
355 p_data = data->get_buffer(false);
359 // Permet de désallouer le buffer dont on détient le pointeur par appel
360 // à la méthode getPointer avec ownerShip=True si la séquence contenante
362 static inline void relPointer(InnerType * dataPtr) {
363 seq_T::freebuf(dataPtr);
366 // Permet d'allouer un buffer pour la séquence
367 static inline InnerType * allocPointer(size_t size ) {
368 return seq_T::allocbuf(size);
371 // Operation de création du type corba soit
372 // - Vide et de taille size
373 // - Utilisant les données du pointeur *data de taille size
374 // (généralement pas de recopie qlq soit l'ownership )
375 // data doit avoir été alloué par allocPointer si giveOwnerShip = true
376 static inline Type create(size_t size, InnerType * const data = NULL,
377 bool giveOwnerShip = false ) {
383 tmp = new seq_T(size,data,giveOwnerShip);
389 // Dump de l'objet pour deboguage
390 static inline void dump (CorbaInType data) {
391 // Affiche la longueur des donnees
392 cerr << "[seq_b_manipulation] Data length: " << data.length() << endl;