Salome HOME
Ajout des properties
[modules/kernel.git] / src / DSC / DSC_User / Datastream / CorbaTypeManipulator.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   : CorbaTypeManipulator.hxx
23 //  Author : Eric Fayolle (EDF)
24 //  Module : KERNEL
25 // Modified by : $LastChangedBy$
26 // Date        : $LastChangedDate: 2007-02-07 18:26:44 +0100 (mer, 07 fév 2007) $
27 // Id          : $Id$
28
29 #ifndef _TYPE_MANIPULATION_HXX_
30 #define _TYPE_MANIPULATION_HXX_
31
32 #include <iostream>
33 #include <CORBA.h>
34
35 using namespace std;
36
37 // Classes manipulation
38 // -------------------
39 //
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 
44
45 // Les classes présentes quatre méthodes :
46 // - clone
47 // - get_data
48 // - delete_data
49 // - dump
50 // et
51 // deux type :
52 // - Type   : Le type CORBA de la donnée manipulée
53 // - InType : Le mapping CORBA pour un paramètre IN du type manipulé
54  
55
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
65 {
66 public:
67   typedef T *       Type;
68   // correspond au mapping corba des type any, struct, 
69   //                  union, séquence en paramètre IN
70   typedef const T & CorbaInType; 
71   typedef T         InnerType;
72
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) {
76     return new T(data);
77   }
78
79   // Pb si ownerShip == True car appel par l'utilisateur de relPointer !
80   static inline InnerType * const getPointer(Type data, bool ownerShip = false) {
81     return data;
82   }
83
84   static inline void relPointer(InnerType * dataPtr) {
85     delete dataPtr;
86   }
87
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);
91   } 
92   static inline Type clone(CorbaInType data) {
93     return new T (data);
94   }
95
96   // Operation de création
97   static inline Type create (size_t size=1) { 
98     return new T();
99   } 
100
101   // Operation de destruction d'une donnee
102   static inline void delete_data(Type data) {
103     delete data;
104   }
105   
106   // Renvoie la taille de la donnée
107   static inline size_t size(Type data) { 
108     return 1;
109   } 
110
111   // Dump de l'objet pour deboguage: neant car on ne connait pas sa structure
112   static inline void dump (CorbaInType data) {}
113 };
114
115
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
124 {
125 public:
126   typedef T Type;
127   // correspond au mapping corba des types simples en paramètre IN
128   typedef T CorbaInType; 
129   typedef T InnerType; 
130
131     
132   // Operation de recuperation des donnees venant de l'ORB : une copie par affectation simple
133   static inline Type get_data(CorbaInType data) {
134     return data;
135   }
136
137  static inline InnerType * const getPointer(Type & data, bool getOwnerShip = false) {
138 //    InnerType * ptr;
139 //     if (getOwnerShip) {
140 //       ptr =new InnerType[1];*ptr=data;
141 //       return ptr;
142 //     } else
143 //      return &data;
144    return &data;
145  }
146
147 //   static inline void relPointer(InnerType * dataPtr) {
148 //     return;
149 //         delete[] dataPtr;
150 //   }
151
152 // Je ne sais pas comment l'implémenter sans faire
153 // d'allocation heap
154 //static inline InnerType * allocPointer(size_t size=1) {
155 //    return  new InnerType[1];
156   //}
157
158   // Operation de clonage : une copie par affectation simple
159   static inline Type clone(Type data) {
160     return data;
161   }
162
163   // Inutile car Type == CorbaInType
164   //   static inline Type clone(CorbaInType data) {
165   //     return data;
166   //   }
167
168   // Operation de création
169 //   static inline Type create(size_t size=1,InnerType * data=NULL,
170 //                          bool giveOwnerShip=false) {
171 //     Type dummy;
172 //     if (dataPtr)
173 //       return *data;
174 //     else
175 //       return dummy;
176 //   } 
177     
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
181
182   static inline size_t size(Type data) { 
183     return 1;
184   } 
185
186   // Dump de l'objet pour deboguage : Affiche la donnee
187   static void inline dump (CorbaInType data) {
188     cerr << "[atom_manipulation] Data : " << data << endl;
189   }
190 };
191
192
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 {
197   
198 public:
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;
203
204  
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;
220
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);
225   }
226
227   static inline size_t size(Type data) { 
228     return data->length();
229   } 
230
231   // Operation de destruction d'une donnee
232   static inline void delete_data(Type data) {
233     delete data;
234   }
235
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) ;
240   }
241   static inline Type clone(CorbaInType data) {
242     return new seq_T (data);
243   }
244
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
247   // à été détruite.
248   static inline InnerType * const getPointer(Type data, bool ownerShip = false) {
249     InnerType * p_data;
250     if (ownerShip) {
251       p_data = data->get_buffer(true);
252       delete_data(data);
253     } else
254       p_data = data->get_buffer(false);
255     return p_data;
256   }
257
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
260   // à été détruite.
261   static inline void relPointer(InnerType * dataPtr) {
262     seq_T::freebuf(dataPtr);
263   }
264
265   // Permet d'allouer un buffer pour la séquence
266   static inline InnerType *  allocPointer(size_t size ) {
267     return seq_T::allocbuf(size);
268   }
269
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 ) { 
277     Type tmp;
278     if (!data) {
279       tmp = new seq_T();
280       tmp->length(size);
281     } else {
282       tmp = new seq_T(size,size,data,giveOwnerShip); 
283     }
284     return tmp;
285   } 
286   
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;
293   }
294 };
295
296
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 {
304   
305 public:
306   typedef seq_T *       Type;
307   typedef const seq_T & CorbaInType;
308   typedef elem_T        InnerType;
309
310
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);
326   }
327
328   static inline size_t size(Type data) { 
329     return data->length();
330   } 
331
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);
336   }
337   static inline Type clone(CorbaInType data) {
338     return new seq_T (data);
339   }
340
341   // Operation de destruction d'une donnee CORBA
342   static inline void delete_data(Type data) {
343     delete data;
344   }
345
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) {
350     InnerType * p_data;
351     if (getOwnerShip) {
352       p_data = data->get_buffer(true);
353       delete_data(data);
354     } else
355       p_data = data->get_buffer(false);
356     return p_data;
357   }
358
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
361   // à été détruite.
362   static inline void relPointer(InnerType * dataPtr) {
363     seq_T::freebuf(dataPtr);
364   }
365
366   // Permet d'allouer un buffer pour la séquence
367   static inline InnerType *  allocPointer(size_t size ) {
368     return seq_T::allocbuf(size);
369   }
370
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 ) { 
378     Type tmp;
379     if (!data) {
380       tmp = new seq_T();
381       tmp->length(size);
382     } else {
383       tmp = new seq_T(size,data,giveOwnerShip); 
384     }
385     return tmp;
386   } 
387
388   
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;
393   }
394 };
395
396 #endif