Version: 9.12.0
CorbaTypeManipulator.hxx
Go to the documentation of this file.
1 // Copyright (C) 2007-2023 CEA, EDF, 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, or (at your option) any later version.
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 
23 // File : CorbaTypeManipulator.hxx
24 // Author : Eric Fayolle (EDF)
25 // Module : KERNEL
26 // Modified by : $LastChangedBy$
27 // Date : $LastChangedDate: 2007-02-07 18:26:44 +0100 (mer, 07 fév 2007) $
28 // Id : $Id$
29 //
30 #ifndef _CORBA_TYPE_MANIPULATION_HXX_
31 #define _CORBA_TYPE_MANIPULATION_HXX_
32 
33 #include "utilities.h"
34 
35 #include <iostream>
36 #include <cstring>
37 #include <omniORB4/CORBA.h>
38 
39 // Classes manipulation
40 // -------------------
41 //
42 // Ces différentes classes permettent d'unifier la manipulation des
43 // différents types de données dans un port datastream
44 // Les données sont maniées par valeur ou par pointeur
45 // pour éviter les recopies de gros volume de données
46 
47 // Les classes présentes quatre méthodes :
48 // - clone
49 // - get_data
50 // - delete_data
51 // - dump
52 // et
53 // trois types :
54 // - Type : Le type CORBA de la donnée manipulée
55 // - InType : Le mapping CORBA pour un paramètre IN du type manipulé// - InnerType : Type interne des valeurs d'un type contenant // Cette classe permet de manipuler des types CORBA // any, struct, union et sequence (utiliser plutôt les seq_manipulator) // Ces types sont manipulés par pointeur. // Les données reçues de CORBA sont systématiquement // dupliquées pour être conservées. // Quelque soit le type de donnée, les données sont considérées // comme une donnée unique (retour de size() == 1) template <typename T > class user_type_manipulation { public: typedef T * Type; // correspond au mapping corba des type any, struct, // union, séquence en paramètre IN typedef const T & CorbaInType; typedef T InnerType; // Operation de recuperation des donnees venant de l'ORB et // creation d'une copie (memoire spécialement allouee) static inline Type get_data(CorbaInType data) { return new T(data); } // Pb si ownerShip == True car appel par l'utilisateur de relPointer ! static inline InnerType * const getPointer(Type data, bool ownerShip = false) { return data; } static inline void relPointer(InnerType * dataPtr) { delete dataPtr; } // Operation de clonage : par defaut, creation d'une copie en memoire allouee pour l'occasion static inline Type clone(Type data) { return new T (* data); } static inline Type clone(CorbaInType data) { return new T (data); } // Operation de création static inline Type create (size_t size=1) { return new T(); } // Operation de destruction d'une donnee static inline void delete_data(Type data) { delete data; } // Renvoie la taille de la donnée static inline size_t size(Type data) { return 1; } // Dump de l'objet pour deboguage: neant car on ne connait pas sa structure static inline void dump (CorbaInType data) {} }; // Gére les types CORBA atomiques ('Int', 'Char', 'Float', ...) // Gére les types enums // Gére les références d'objets CORBA // Ces types sont manipulés par valeur // Les méthodes getPointer ... ne devrait pas être utilisée // pour ce types de données template <typename T> class atom_manipulation { public: typedef T Type; // correspond au mapping corba des types simples en paramètre IN typedef T CorbaInType; typedef T InnerType; // Operation de recuperation des donnees venant de l'ORB : une copie par affectation simple static inline Type get_data(CorbaInType data) { return data; } static inline InnerType * const getPointer(Type & data, bool getOwnerShip = false) { // InnerType * ptr; // if (getOwnerShip) { // ptr =new InnerType[1];*ptr=data; // return ptr; // } else // return &data; return &data; } // static inline void relPointer(InnerType * dataPtr) { // return; // delete[] dataPtr; // } // Je ne sais pas comment l'implémenter sans faire // d'allocation heap //static inline InnerType * allocPointer(size_t size=1) { // return new InnerType[1]; //} // Operation de clonage : une copie par affectation simple static inline Type clone(Type data) { return data; } // Inutile car Type == CorbaInType // static inline Type clone(CorbaInType data) { // return data; // } // Operation de création // static inline Type create(size_t size=1,InnerType * data=NULL, // bool giveOwnerShip=false) { // Type dummy; // if (dataPtr) // return *data; // else // return dummy; // } // Operation de destruction d'une donnee: rien a faire car pas de memoire a liberer static inline void delete_data(Type /*data*/) {} // Renvoie la taille de la donnée static inline size_t size(Type data) { return 1; } // Dump de l'objet pour deboguage : Affiche la donnee static void inline dump (CorbaInType data) { std::cerr << "[atom_manipulation] Data : " << data << std::endl; } }; // Gére un type sequence de taille illimitee (Unbounded) // Ces types sont manipulés par pointeur template <typename seq_T,typename elem_T> class seq_u_manipulation { public: typedef seq_T * Type; // Type de donnée abstrait manipulé par GenericPort::Put,Get,.. typedef const seq_T & CorbaInType; // Mapping corba de la séquence en paramètre IN typedef elem_T InnerType; // Il n'existe pas dans CORBA de seq_T::elem_T // C'est la raison d'être du second paramètre template de seq_u_mani // Operation de recuperation des donnees venant de l'ORB // Remarque : On a un paramètre d'entrée de type const seq_T & // et en sortie un seq_T * static inline Type get_data(CorbaInType data) { CORBA::Long len = data.length(); CORBA::Long max = data.maximum(); // Récupère et devient propriétaire des données reçues dans la séquence. // La séquence reçue (mais pas le buffer) sera désallouée au retour // de la méthode CORBA qui a reçu le type CorbaInType en paramètre // (ex: GenericPort::put) // REM : Le mapping CORBA du type séquence IN est : const seq & // OLD : On ne teste pas si le flag release de la séquence est à true ou false // OLD : ( pour des séquences de chaines ou d'objrefs ) // OLD : -> Si on est collocalisé le port uses doit créer une copie pour éviter la modification // OLD : du contenu de la séquence lorsque l'utilisateur modifie ses données dans son programme (0 copie) // OLD : ATTENTION TESTER p194 si le pointeur est null (release flag==false) // OLD : -> La séquence n'était pas propriétaire des données ! // Le flag release() de la séquence est à false si elle n'est pas propriétaire du buffer // En collocalité release() renvoie false car // l'appelé n'est pas propriétaire de la séquence. On effectue alors // une copie pour éviter de perturber les structures de données de l'appelant. // En non collocalisé on recrée une séquence avec le buffer de la première dont on // a demandé la propriété. if (SALOME::VerbosityActivated()) std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1 ------------------" << std::endl; if ( data.release() ) { InnerType * p_data = const_cast<seq_T &>(data).get_buffer(true); // Crée une nouvelle sequence propriétaire des données du buffer (pas de recopie) // Les données de la nouvelle séquence seront automatiquement désallouées // par appel à la méthode freebuf dans le destructeur de la séquence (cf delete_data). if (SALOME::VerbosityActivated()) std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1(0 copy) bis ------" << p_data << "------------" << std::endl; return new seq_T (max, len, p_data, true); } if (SALOME::VerbosityActivated()) std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1(recopie) bis ------" << &data << "------------" << std::endl; // Crée une nouvelle sequence propriétaire des données du buffer (avec recopie) return new seq_T(data); } static inline size_t size(Type data) { return data->length(); } // Operation de destruction d'une donnee static inline void delete_data(Type data) { //La séquence est détruite par appel à son destructeur //Ce destructeur prend en compte la nécessité de détruire ou non //les données contenues en fonction de son flag interne release() delete data; } // Operation de clonage : par defaut creation d'une copie en memoire allouee pour l'occasion // Utilisation du constructeur du type seq_T static inline Type clone(Type data) { return new seq_T (*data) ; } static inline Type clone(CorbaInType data) { return new seq_T (data); } // Permet d'obtenir un pointeur sur le buffer de la séquence : // Si ownerShip=True, la séquence n'est plus propriétaire du buffer // (son pointeur de buffer interne est aussi réinitialisé) // On détruit également explicitement la séquence (mais pas le buffer !) // Si ownerShip=False, la séquence reste propriétaire du buffer // et l'utilisateur devra appeler delete_data sur la séquence contenante pour // détruire à la fois la séquence et le buffer contenu. static inline InnerType * const getPointer(Type data, bool ownerShip = false) { InnerType * p_data; if (ownerShip) { p_data = data->get_buffer(true); delete_data(data); } else p_data = data->get_buffer(false); return p_data; } // Permet de désallouer le buffer dont on détient le pointeur après appel // à la méthode getPointer avec ownerShip=True static inline void relPointer(InnerType * dataPtr) { seq_T::freebuf(dataPtr); } // Permet d'allouer un buffer compatible avec le type séquence static inline InnerType * allocPointer(size_t size ) { return seq_T::allocbuf(size); } // Opération de création de la séquence CORBA soit // - Vide et de taille size // - Utilisant les données du pointeur *data de taille size // (généralement pas de recopie qlq soit l'ownership ) // data doit avoir été alloué par allocPointer si giveOwnerShip = true static inline Type create(size_t size, InnerType * const data = NULL, bool giveOwnerShip = false ) { Type tmp; if (!data) { tmp = new seq_T(); tmp->length(size); } else { tmp = new seq_T(size,size,data,giveOwnerShip); } return tmp; } // Copie le contenu de la séquence dans le buffer idata de taille isize // pour les types non pointeur template <typename T > static inline void copy( Type data, T * const idata, size_t isize ) { InnerType *dataPtr = getPointer(data,false); for (size_t i = 0; i< isize; ++i) idata[i]=dataPtr[i]; // Le mode de recopie suivant ne permet pas la conversion de type (ex int -> CORBA::Long) //OLD: Type tmp = new seq_T(isize,isize,idata,false); //OLD: // giveOwnerShip == false -> seul le contenu du buffer data est détruit et remplacé //OLD: // par celui de data dans l'affectation suivante : //OLD: // ---> ATTENTION SI LA TAILLE DU BUFFER EST TROP PETITE, QUE FAIT CORBA ! //OLD: // corruption mémoire //OLD: // Cependant ce cas devrait pas arrivé (on s'assure dans les couches supérieures //OLD: // de la taille correcte du buffer de recopie) //OLD: // Si giveOwnerShip était == true -> le buffer et son contenu serait détruit puis une //OLD: // allocation de la taille du buffer de data serait effectué avant la copie des données //OLD: // tmp = data; } // Copie le contenu de la séquence de char* dans le buffer idata de taille isize // La généralisation de la recopie profonde est difficile du fait que CORBA ne renvoie pas // pas des objets de haut niveau de type std::vector<std::string> (avec des interfaces d'accès identiques) // mais un type simple C comme char *Tab[N]. On doit alors utiliser une méthode de recopie spécifique // comme l'appel C strcpy. static inline void copy( Type data, char* * const idata, size_t isize ) { char* *dataPtr = getPointer(data,false); // Si idata[i] n'a pas été alloué suffisament grand, // il y a corruption de la mémoire for (size_t i = 0; i< isize; ++i) strcpy(idata[i],dataPtr[i]); } // Dump de l'objet pour deboguage static void inline dump (CorbaInType data) { // Affiche la longueur des donnees std::cerr << "[seq_u_manipulation] Data length: " << data.length() << std::endl; // Affiche la longueur des donnees std::cerr << "[seq_u_manipulation] Data max: " << data.maximum() << std::endl; } }; // TODO : Vérifier la conformité de l'implémentation par rapport // au type unbounded // Gére un type sequence de taille limitée (bounded) // Ces types sont manipulés par pointeur // Cette classe diffère de la seq_u_manipulation // par la signature du constructeur de la séquence // utilisé dans le methode get_data template <typename seq_T,typename elem_T> class seq_b_manipulation { public: typedef seq_T * Type; typedef const seq_T & CorbaInType; typedef elem_T InnerType; // Operation de recuperation des donnees venant de l'ORB // Sans opération de notre part, ces données seraient perdues // au retour de la méthode put de GenericPort. // Remarque : On a un paramètre d'entrée de type const seq_T & // et en sortie un seq_T * static inline Type get_data(CorbaInType data) { CORBA::Long len = data.length(); // Récupère et devient propriétaire des données reçues dans la séquence // la séquence sera désalloué (mais pas le buffer) // au retour de la méthode put (car mapping de type IN : const seq & ) if ( data.release() ) { InnerType * p_data = const_cast<seq_T &>(data).get_buffer(true); // Crée une nouvelle sequence propriétaire des données du buffer (généralement pas de recopie) // Les données seront automatiquement désallouées par appel interne à la méthode freebuf // lors de la destruction de l'objet par appel à delete_data. if (SALOME::VerbosityActivated()) std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1bis Pas de Duplication -----------" << std::endl; return new seq_T (len, p_data, true); } if (SALOME::VerbosityActivated()) std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1bis Duplication pour en devenir propriétaire -----------" << std::endl; // Crée une nouvelle sequence propriétaire des données du buffer (avec recopie) return new seq_T(data); } static inline size_t size(Type data) { return data->length(); } // Operation de clonage : par defaut creation d'une copie en memoire allouee pour l'occasion // Utilisation du constructeur du type seq_T static inline Type clone(Type data) { return new seq_T (* data); } static inline Type clone(CorbaInType data) { return new seq_T (data); } // Operation de destruction d'une donnee CORBA static inline void delete_data(Type data) { delete data; } // Permet d'obtenir un pointeur sur le buffer de la séquence : // Si ownerShip=True, la séquence n'est plus propriétaire du buffer // (son pointeur de buffer interne est aussi réinitialisé) // On détruit également explicitement la séquence (mais pas le buffer !) // Si ownerShip=False, la séquence reste propriétaire du buffer // et l'utilisateur devra appeler delete_data sur la séquence contenante pour // détruire à la fois la séquence et le buffer contenu. static inline InnerType * const getPointer(Type data, bool getOwnerShip = false) { InnerType * p_data; if (getOwnerShip) { p_data = data->get_buffer(true); delete_data(data); } else p_data = data->get_buffer(false); return p_data; } // Permet de désallouer le buffer dont on détient le pointeur par appel // à la méthode getPointer avec ownerShip=True si la séquence contenante // à été détruite. static inline void relPointer(InnerType * dataPtr) { seq_T::freebuf(dataPtr); } // Permet d'allouer un buffer pour la séquence static inline InnerType * allocPointer(size_t size ) { return seq_T::allocbuf(size); } // Operation de création du type corba soit // - Vide et de taille size // - Utilisant les données du pointeur *data de taille size // (généralement pas de recopie qlq soit l'ownership ) // data doit avoir été alloué par allocPointer si giveOwnerShip = true static inline Type create(size_t size, InnerType * const data = NULL, bool giveOwnerShip = false ) { Type tmp; if (!data) { tmp = new seq_T(); tmp->length(size); } else { tmp = new seq_T(size,data,giveOwnerShip); } return tmp; } // Dump de l'objet pour deboguage static inline void dump (CorbaInType data) { // Affiche la longueur des donnees std::cerr << "[seq_b_manipulation] Data length: " << data.length() << std::endl; } }; #endif
56 // - InnerType : Type interne des valeurs d'un type contenant
57 
58 // Cette classe permet de manipuler des types CORBA
59 // any, struct, union et sequence (utiliser plutôt les seq_manipulator)
60 // Ces types sont manipulés par pointeur.
61 // Les données reçues de CORBA sont systématiquement
62 // dupliquées pour être conservées.
63 // Quelque soit le type de donnée, les données sont considérées
64 // comme une donnée unique (retour de size() == 1)
65 template <typename T >
67 {
68 public:
69  typedef T * Type;
70  // correspond au mapping corba des type any, struct,
71  // union, séquence en paramètre IN
72  typedef const T & CorbaInType;
73  typedef T InnerType;
74 
75  // Operation de recuperation des donnees venant de l'ORB et
76  // creation d'une copie (memoire spécialement allouee)
77  static inline Type get_data(CorbaInType data) {
78  return new T(data);
79  }
80 
81  // Pb si ownerShip == True car appel par l'utilisateur de relPointer !
82  static inline InnerType * const getPointer(Type data, bool ownerShip = false) {
83  return data;
84  }
85 
86  static inline void relPointer(InnerType * dataPtr) {
87  delete dataPtr;
88  }
89 
90  // Operation de clonage : par defaut, creation d'une copie en memoire allouee pour l'occasion
91  static inline Type clone(Type data) {
92  return new T (* data);
93  }
94  static inline Type clone(CorbaInType data) {
95  return new T (data);
96  }
97 
98  // Operation de création
99  static inline Type create (size_t size=1) {
100  return new T();
101  }
102 
103  // Operation de destruction d'une donnee
104  static inline void delete_data(Type data) {
105  delete data;
106  }
107 
108  // Renvoie la taille de la donnée
109  static inline size_t size(Type data) {
110  return 1;
111  }
112 
113  // Dump de l'objet pour deboguage: neant car on ne connait pas sa structure
114  static inline void dump (CorbaInType data) {}
115 };
116 
117 
118 // Gére les types CORBA atomiques ('Int', 'Char', 'Float', ...)
119 // Gére les types enums
120 // Gére les références d'objets CORBA
121 // Ces types sont manipulés par valeur
122 // Les méthodes getPointer ... ne devrait pas être utilisée
123 // pour ce types de données
124 template <typename T>
126 {
127 public:
128  typedef T Type;
129  // correspond au mapping corba des types simples en paramètre IN
130  typedef T CorbaInType;
131  typedef T InnerType;
132 
133 
134  // Operation de recuperation des donnees venant de l'ORB : une copie par affectation simple
135  static inline Type get_data(CorbaInType data) {
136  return data;
137  }
138 
139  static inline InnerType * const getPointer(Type & data, bool getOwnerShip = false) {
140 // InnerType * ptr;
141 // if (getOwnerShip) {
142 // ptr =new InnerType[1];*ptr=data;
143 // return ptr;
144 // } else
145 // return &data;
146  return &data;
147  }
148 
149 // static inline void relPointer(InnerType * dataPtr) {
150 // return;
151 // delete[] dataPtr;
152 // }
153 
154 // Je ne sais pas comment l'implémenter sans faire
155 // d'allocation heap
156 //static inline InnerType * allocPointer(size_t size=1) {
157 // return new InnerType[1];
158  //}
159 
160  // Operation de clonage : une copie par affectation simple
161  static inline Type clone(Type data) {
162  return data;
163  }
164 
165  // Inutile car Type == CorbaInType
166  // static inline Type clone(CorbaInType data) {
167  // return data;
168  // }
169 
170  // Operation de création
171 // static inline Type create(size_t size=1,InnerType * data=NULL,
172 // bool giveOwnerShip=false) {
173 // Type dummy;
174 // if (dataPtr)
175 // return *data;
176 // else
177 // return dummy;
178 // }
179 
180  // Operation de destruction d'une donnee: rien a faire car pas de memoire a liberer
181  static inline void delete_data(Type /*data*/) {}
182  // Renvoie la taille de la donnée
183 
184  static inline size_t size(Type data) {
185  return 1;
186  }
187 
188  // Dump de l'objet pour deboguage : Affiche la donnee
189  static void inline dump (CorbaInType data) {
190  std::cerr << "[atom_manipulation] Data : " << data << std::endl;
191  }
192 };
193 
194 
195 // Gére un type sequence de taille illimitee (Unbounded)
196 // Ces types sont manipulés par pointeur
197 template <typename seq_T,typename elem_T>
199 
200 public:
201  typedef seq_T * Type; // Type de donnée abstrait manipulé par GenericPort::Put,Get,..
202  typedef const seq_T & CorbaInType; // Mapping corba de la séquence en paramètre IN
203  typedef elem_T InnerType; // Il n'existe pas dans CORBA de seq_T::elem_T
204  // C'est la raison d'être du second paramètre template de seq_u_mani
205 
206  // Operation de recuperation des donnees venant de l'ORB
207  // Remarque : On a un paramètre d'entrée de type const seq_T &
208  // et en sortie un seq_T *
209  static inline Type get_data(CorbaInType data) {
210  CORBA::Long len = data.length();
211  CORBA::Long max = data.maximum();
212  // Récupère et devient propriétaire des données reçues dans la séquence.
213  // La séquence reçue (mais pas le buffer) sera désallouée au retour
214  // de la méthode CORBA qui a reçu le type CorbaInType en paramètre
215  // (ex: GenericPort::put)
216  // REM : Le mapping CORBA du type séquence IN est : const seq &
217 
218  // OLD : On ne teste pas si le flag release de la séquence est à true ou false
219  // OLD : ( pour des séquences de chaines ou d'objrefs )
220  // OLD : -> Si on est collocalisé le port uses doit créer une copie pour éviter la modification
221  // OLD : du contenu de la séquence lorsque l'utilisateur modifie ses données dans son programme (0 copie)
222  // OLD : ATTENTION TESTER p194 si le pointeur est null (release flag==false)
223  // OLD : -> La séquence n'était pas propriétaire des données !
224 
225  // Le flag release() de la séquence est à false si elle n'est pas propriétaire du buffer
226  // En collocalité release() renvoie false car
227  // l'appelé n'est pas propriétaire de la séquence. On effectue alors
228  // une copie pour éviter de perturber les structures de données de l'appelant.
229  // En non collocalisé on recrée une séquence avec le buffer de la première dont on
230  // a demandé la propriété.
231 
233  std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1 ------------------" << std::endl;
234 
235  if ( data.release() ) {
236  InnerType * p_data = const_cast<seq_T &>(data).get_buffer(true);
237 
238  // Crée une nouvelle sequence propriétaire des données du buffer (pas de recopie)
239  // Les données de la nouvelle séquence seront automatiquement désallouées
240  // par appel à la méthode freebuf dans le destructeur de la séquence (cf delete_data).
242  std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1(0 copy) bis ------" << p_data << "------------" << std::endl;
243 
244  return new seq_T (max, len, p_data, true);
245  }
246 
248  std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1(recopie) bis ------" << &data << "------------" << std::endl;
249 
250  // Crée une nouvelle sequence propriétaire des données du buffer (avec recopie)
251  return new seq_T(data);
252 
253  }
254 
255  static inline size_t size(Type data) {
256  return data->length();
257  }
258 
259  // Operation de destruction d'une donnee
260  static inline void delete_data(Type data) {
261  //La séquence est détruite par appel à son destructeur
262  //Ce destructeur prend en compte la nécessité de détruire ou non
263  //les données contenues en fonction de son flag interne release()
264  delete data;
265  }
266 
267  // Operation de clonage : par defaut creation d'une copie en memoire allouee pour l'occasion
268  // Utilisation du constructeur du type seq_T
269  static inline Type clone(Type data) {
270  return new seq_T (*data) ;
271  }
272  static inline Type clone(CorbaInType data) {
273  return new seq_T (data);
274  }
275 
276  // Permet d'obtenir un pointeur sur le buffer de la séquence :
277  // Si ownerShip=True, la séquence n'est plus propriétaire du buffer
278  // (son pointeur de buffer interne est aussi réinitialisé)
279  // On détruit également explicitement la séquence (mais pas le buffer !)
280  // Si ownerShip=False, la séquence reste propriétaire du buffer
281  // et l'utilisateur devra appeler delete_data sur la séquence contenante pour
282  // détruire à la fois la séquence et le buffer contenu.
283  static inline InnerType * const getPointer(Type data, bool ownerShip = false) {
284  InnerType * p_data;
285  if (ownerShip) {
286  p_data = data->get_buffer(true);
287  delete_data(data);
288  } else
289  p_data = data->get_buffer(false);
290  return p_data;
291  }
292 
293  // Permet de désallouer le buffer dont on détient le pointeur après appel
294  // à la méthode getPointer avec ownerShip=True
295  static inline void relPointer(InnerType * dataPtr) {
296  seq_T::freebuf(dataPtr);
297  }
298 
299  // Permet d'allouer un buffer compatible avec le type séquence
300  static inline InnerType * allocPointer(size_t size ) {
301  return seq_T::allocbuf(size);
302  }
303 
304  // Opération de création de la séquence CORBA soit
305  // - Vide et de taille size
306  // - Utilisant les données du pointeur *data de taille size
307  // (généralement pas de recopie qlq soit l'ownership )
308  // data doit avoir été alloué par allocPointer si giveOwnerShip = true
309  static inline Type create(size_t size, InnerType * const data = NULL,
310  bool giveOwnerShip = false ) {
311  Type tmp;
312  if (!data) {
313  tmp = new seq_T();
314  tmp->length(size);
315  } else {
316  tmp = new seq_T(size,size,data,giveOwnerShip);
317  }
318  return tmp;
319  }
320 
321  // Copie le contenu de la séquence dans le buffer idata de taille isize
322  // pour les types non pointeur
323  template <typename T >
324  static inline void copy( Type data, T * const idata, size_t isize ) {
325 
326  InnerType *dataPtr = getPointer(data,false);
327 
328  for (size_t i = 0; i< isize; ++i)
329  idata[i]=dataPtr[i];
330 
331  // Le mode de recopie suivant ne permet pas la conversion de type (ex int -> CORBA::Long)
332  //OLD: Type tmp = new seq_T(isize,isize,idata,false);
333  //OLD: // giveOwnerShip == false -> seul le contenu du buffer data est détruit et remplacé //OLD: // par celui de data dans l'affectation suivante : //OLD: // ---> ATTENTION SI LA TAILLE DU BUFFER EST TROP PETITE, QUE FAIT CORBA ! //OLD: // corruption mémoire //OLD: // Cependant ce cas devrait pas arrivé (on s'assure dans les couches supérieures //OLD: // de la taille correcte du buffer de recopie) //OLD: // Si giveOwnerShip était == true -> le buffer et son contenu serait détruit puis une //OLD: // allocation de la taille du buffer de data serait effectué avant la copie des données //OLD: // tmp = data; } // Copie le contenu de la séquence de char* dans le buffer idata de taille isize // La généralisation de la recopie profonde est difficile du fait que CORBA ne renvoie pas // pas des objets de haut niveau de type std::vector<std::string> (avec des interfaces d'accès identiques) // mais un type simple C comme char *Tab[N]. On doit alors utiliser une méthode de recopie spécifique // comme l'appel C strcpy. static inline void copy( Type data, char* * const idata, size_t isize ) { char* *dataPtr = getPointer(data,false); // Si idata[i] n'a pas été alloué suffisament grand, // il y a corruption de la mémoire for (size_t i = 0; i< isize; ++i) strcpy(idata[i],dataPtr[i]); } // Dump de l'objet pour deboguage static void inline dump (CorbaInType data) { // Affiche la longueur des donnees std::cerr << "[seq_u_manipulation] Data length: " << data.length() << std::endl; // Affiche la longueur des donnees std::cerr << "[seq_u_manipulation] Data max: " << data.maximum() << std::endl; } }; // TODO : Vérifier la conformité de l'implémentation par rapport // au type unbounded // Gére un type sequence de taille limitée (bounded) // Ces types sont manipulés par pointeur // Cette classe diffère de la seq_u_manipulation // par la signature du constructeur de la séquence // utilisé dans le methode get_data template <typename seq_T,typename elem_T> class seq_b_manipulation { public: typedef seq_T * Type; typedef const seq_T & CorbaInType; typedef elem_T InnerType; // Operation de recuperation des donnees venant de l'ORB // Sans opération de notre part, ces données seraient perdues // au retour de la méthode put de GenericPort. // Remarque : On a un paramètre d'entrée de type const seq_T & // et en sortie un seq_T * static inline Type get_data(CorbaInType data) { CORBA::Long len = data.length(); // Récupère et devient propriétaire des données reçues dans la séquence // la séquence sera désalloué (mais pas le buffer) // au retour de la méthode put (car mapping de type IN : const seq & ) if ( data.release() ) { InnerType * p_data = const_cast<seq_T &>(data).get_buffer(true); // Crée une nouvelle sequence propriétaire des données du buffer (généralement pas de recopie) // Les données seront automatiquement désallouées par appel interne à la méthode freebuf // lors de la destruction de l'objet par appel à delete_data. if (SALOME::VerbosityActivated()) std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1bis Pas de Duplication -----------" << std::endl; return new seq_T (len, p_data, true); } if (SALOME::VerbosityActivated()) std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1bis Duplication pour en devenir propriétaire -----------" << std::endl; // Crée une nouvelle sequence propriétaire des données du buffer (avec recopie) return new seq_T(data); } static inline size_t size(Type data) { return data->length(); } // Operation de clonage : par defaut creation d'une copie en memoire allouee pour l'occasion // Utilisation du constructeur du type seq_T static inline Type clone(Type data) { return new seq_T (* data); } static inline Type clone(CorbaInType data) { return new seq_T (data); } // Operation de destruction d'une donnee CORBA static inline void delete_data(Type data) { delete data; } // Permet d'obtenir un pointeur sur le buffer de la séquence : // Si ownerShip=True, la séquence n'est plus propriétaire du buffer // (son pointeur de buffer interne est aussi réinitialisé) // On détruit également explicitement la séquence (mais pas le buffer !) // Si ownerShip=False, la séquence reste propriétaire du buffer // et l'utilisateur devra appeler delete_data sur la séquence contenante pour // détruire à la fois la séquence et le buffer contenu. static inline InnerType * const getPointer(Type data, bool getOwnerShip = false) { InnerType * p_data; if (getOwnerShip) { p_data = data->get_buffer(true); delete_data(data); } else p_data = data->get_buffer(false); return p_data; } // Permet de désallouer le buffer dont on détient le pointeur par appel // à la méthode getPointer avec ownerShip=True si la séquence contenante // à été détruite. static inline void relPointer(InnerType * dataPtr) { seq_T::freebuf(dataPtr); } // Permet d'allouer un buffer pour la séquence static inline InnerType * allocPointer(size_t size ) { return seq_T::allocbuf(size); } // Operation de création du type corba soit // - Vide et de taille size // - Utilisant les données du pointeur *data de taille size // (généralement pas de recopie qlq soit l'ownership ) // data doit avoir été alloué par allocPointer si giveOwnerShip = true static inline Type create(size_t size, InnerType * const data = NULL, bool giveOwnerShip = false ) { Type tmp; if (!data) { tmp = new seq_T(); tmp->length(size); } else { tmp = new seq_T(size,data,giveOwnerShip); } return tmp; } // Dump de l'objet pour deboguage static inline void dump (CorbaInType data) { // Affiche la longueur des donnees std::cerr << "[seq_b_manipulation] Data length: " << data.length() << std::endl; } }; #endif
334  //OLD: // par celui de data dans l'affectation suivante :
335  //OLD: // ---> ATTENTION SI LA TAILLE DU BUFFER EST TROP PETITE, QUE FAIT CORBA !
336  //OLD: // corruption mémoire
337  //OLD: // Cependant ce cas devrait pas arrivé (on s'assure dans les couches supérieures
338  //OLD: // de la taille correcte du buffer de recopie)
339  //OLD: // Si giveOwnerShip était == true -> le buffer et son contenu serait détruit puis une
340  //OLD: // allocation de la taille du buffer de data serait effectué avant la copie des données
341  //OLD: // tmp = data;
342  }
343 
344  // Copie le contenu de la séquence de char* dans le buffer idata de taille isize
345  // La généralisation de la recopie profonde est difficile du fait que CORBA ne renvoie pas
346  // pas des objets de haut niveau de type std::vector<std::string> (avec des interfaces d'accès identiques)
347  // mais un type simple C comme char *Tab[N]. On doit alors utiliser une méthode de recopie spécifique
348  // comme l'appel C strcpy.
349  static inline void copy( Type data, char* * const idata, size_t isize ) {
350 
351  char* *dataPtr = getPointer(data,false);
352 
353  // Si idata[i] n'a pas été alloué suffisament grand,
354  // il y a corruption de la mémoire
355  for (size_t i = 0; i< isize; ++i)
356  strcpy(idata[i],dataPtr[i]);
357  }
358 
359  // Dump de l'objet pour deboguage
360  static void inline dump (CorbaInType data) {
361  // Affiche la longueur des donnees
362  std::cerr << "[seq_u_manipulation] Data length: " << data.length() << std::endl;
363  // Affiche la longueur des donnees
364  std::cerr << "[seq_u_manipulation] Data max: " << data.maximum() << std::endl;
365  }
366 };
367 
368 
369 // TODO : Vérifier la conformité de l'implémentation par rapport
370 // au type unbounded
371 
372 // Gére un type sequence de taille limitée (bounded)
373 // Ces types sont manipulés par pointeur
374 // Cette classe diffère de la seq_u_manipulation
375 // par la signature du constructeur de la séquence
376 // utilisé dans le methode get_data
377 template <typename seq_T,typename elem_T>
379 
380 public:
381  typedef seq_T * Type;
382  typedef const seq_T & CorbaInType;
383  typedef elem_T InnerType;
384 
385 
386  // Operation de recuperation des donnees venant de l'ORB
387  // Sans opération de notre part, ces données seraient perdues
388  // au retour de la méthode put de GenericPort.
389  // Remarque : On a un paramètre d'entrée de type const seq_T &
390  // et en sortie un seq_T *
391  static inline Type get_data(CorbaInType data) {
392  CORBA::Long len = data.length();
393  // Récupère et devient propriétaire des données reçues dans la séquence
394  // la séquence sera désalloué (mais pas le buffer)
395  // au retour de la méthode put (car mapping de type IN : const seq & )
396  if ( data.release() ) {
397  InnerType * p_data = const_cast<seq_T &>(data).get_buffer(true);
398 
399  // Crée une nouvelle sequence propriétaire des données du buffer (généralement pas de recopie)
400  // Les données seront automatiquement désallouées par appel interne à la méthode freebuf
401  // lors de la destruction de l'objet par appel à delete_data.
403  std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1bis Pas de Duplication -----------" << std::endl;
404 
405  return new seq_T (len, p_data, true);
406  }
407 
409  std::cout << "----seq_u_manipulation::get_data(..)-- MARK 1bis Duplication pour en devenir propriétaire -----------" << std::endl;
410 
411  // Crée une nouvelle sequence propriétaire des données du buffer (avec recopie)
412  return new seq_T(data);
413  }
414 
415  static inline size_t size(Type data) {
416  return data->length();
417  }
418 
419  // Operation de clonage : par defaut creation d'une copie en memoire allouee pour l'occasion
420  // Utilisation du constructeur du type seq_T
421  static inline Type clone(Type data) {
422  return new seq_T (* data);
423  }
424  static inline Type clone(CorbaInType data) {
425  return new seq_T (data);
426  }
427 
428  // Operation de destruction d'une donnee CORBA
429  static inline void delete_data(Type data) {
430  delete data;
431  }
432 
433  // Permet d'obtenir un pointeur sur le buffer de la séquence :
434  // Si ownerShip=True, la séquence n'est plus propriétaire du buffer
435  // (son pointeur de buffer interne est aussi réinitialisé)
436  // On détruit également explicitement la séquence (mais pas le buffer !)
437  // Si ownerShip=False, la séquence reste propriétaire du buffer
438  // et l'utilisateur devra appeler delete_data sur la séquence contenante pour
439  // détruire à la fois la séquence et le buffer contenu.
440  static inline InnerType * const getPointer(Type data, bool getOwnerShip = false) {
441  InnerType * p_data;
442  if (getOwnerShip) {
443  p_data = data->get_buffer(true);
444  delete_data(data);
445  } else
446  p_data = data->get_buffer(false);
447  return p_data;
448  }
449 
450  // Permet de désallouer le buffer dont on détient le pointeur par appel
451  // à la méthode getPointer avec ownerShip=True si la séquence contenante
452  // à été détruite.
453  static inline void relPointer(InnerType * dataPtr) {
454  seq_T::freebuf(dataPtr);
455  }
456 
457  // Permet d'allouer un buffer pour la séquence
458  static inline InnerType * allocPointer(size_t size ) {
459  return seq_T::allocbuf(size);
460  }
461 
462  // Operation de création du type corba soit
463  // - Vide et de taille size
464  // - Utilisant les données du pointeur *data de taille size
465  // (généralement pas de recopie qlq soit l'ownership )
466  // data doit avoir été alloué par allocPointer si giveOwnerShip = true
467  static inline Type create(size_t size, InnerType * const data = NULL,
468  bool giveOwnerShip = false ) {
469  Type tmp;
470  if (!data) {
471  tmp = new seq_T();
472  tmp->length(size);
473  } else {
474  tmp = new seq_T(size,data,giveOwnerShip);
475  }
476  return tmp;
477  }
478 
479 
480  // Dump de l'objet pour deboguage
481  static inline void dump (CorbaInType data) {
482  // Affiche la longueur des donnees
483  std::cerr << "[seq_b_manipulation] Data length: " << data.length() << std::endl;
484  }
485 };
486 
487 #endif
Definition: CorbaTypeManipulator.hxx:126
static Type clone(Type data)
Definition: CorbaTypeManipulator.hxx:161
static void dump(CorbaInType data)
Definition: CorbaTypeManipulator.hxx:189
static InnerType *const getPointer(Type &data, bool getOwnerShip=false)
Definition: CorbaTypeManipulator.hxx:139
static size_t size(Type data)
Definition: CorbaTypeManipulator.hxx:184
T InnerType
Definition: CorbaTypeManipulator.hxx:131
T Type
Definition: CorbaTypeManipulator.hxx:128
static void delete_data(Type)
Definition: CorbaTypeManipulator.hxx:181
static Type get_data(CorbaInType data)
Definition: CorbaTypeManipulator.hxx:135
T CorbaInType
Definition: CorbaTypeManipulator.hxx:130
Definition: CorbaTypeManipulator.hxx:378
seq_T * Type
Definition: CorbaTypeManipulator.hxx:381
static void relPointer(InnerType *dataPtr)
Definition: CorbaTypeManipulator.hxx:453
const seq_T & CorbaInType
Definition: CorbaTypeManipulator.hxx:382
static Type clone(Type data)
Definition: CorbaTypeManipulator.hxx:421
static void dump(CorbaInType data)
Definition: CorbaTypeManipulator.hxx:481
static InnerType *const getPointer(Type data, bool getOwnerShip=false)
Definition: CorbaTypeManipulator.hxx:440
elem_T InnerType
Definition: CorbaTypeManipulator.hxx:383
static size_t size(Type data)
Definition: CorbaTypeManipulator.hxx:415
static Type get_data(CorbaInType data)
Definition: CorbaTypeManipulator.hxx:391
static InnerType * allocPointer(size_t size)
Definition: CorbaTypeManipulator.hxx:458
static void delete_data(Type data)
Definition: CorbaTypeManipulator.hxx:429
static Type create(size_t size, InnerType *const data=NULL, bool giveOwnerShip=false)
Definition: CorbaTypeManipulator.hxx:467
static Type clone(CorbaInType data)
Definition: CorbaTypeManipulator.hxx:424
Definition: CorbaTypeManipulator.hxx:198
static Type clone(CorbaInType data)
Definition: CorbaTypeManipulator.hxx:272
static Type get_data(CorbaInType data)
Definition: CorbaTypeManipulator.hxx:209
static void dump(CorbaInType data)
Definition: CorbaTypeManipulator.hxx:360
static InnerType *const getPointer(Type data, bool ownerShip=false)
Definition: CorbaTypeManipulator.hxx:283
static InnerType * allocPointer(size_t size)
Definition: CorbaTypeManipulator.hxx:300
seq_T * Type
Definition: CorbaTypeManipulator.hxx:201
static void copy(Type data, char **const idata, size_t isize)
Definition: CorbaTypeManipulator.hxx:349
static void relPointer(InnerType *dataPtr)
Definition: CorbaTypeManipulator.hxx:295
static void copy(Type data, T *const idata, size_t isize)
Definition: CorbaTypeManipulator.hxx:324
const seq_T & CorbaInType
Definition: CorbaTypeManipulator.hxx:202
static Type create(size_t size, InnerType *const data=NULL, bool giveOwnerShip=false)
Definition: CorbaTypeManipulator.hxx:309
static void delete_data(Type data)
Definition: CorbaTypeManipulator.hxx:260
elem_T InnerType
Definition: CorbaTypeManipulator.hxx:203
static Type clone(Type data)
Definition: CorbaTypeManipulator.hxx:269
static size_t size(Type data)
Definition: CorbaTypeManipulator.hxx:255
Definition: CorbaTypeManipulator.hxx:67
static void relPointer(InnerType *dataPtr)
Definition: CorbaTypeManipulator.hxx:86
static Type create(size_t size=1)
Definition: CorbaTypeManipulator.hxx:99
static Type clone(CorbaInType data)
Definition: CorbaTypeManipulator.hxx:94
static void dump(CorbaInType data)
Definition: CorbaTypeManipulator.hxx:114
static size_t size(Type data)
Definition: CorbaTypeManipulator.hxx:109
T InnerType
Definition: CorbaTypeManipulator.hxx:73
static void delete_data(Type data)
Definition: CorbaTypeManipulator.hxx:104
T * Type
Definition: CorbaTypeManipulator.hxx:69
static Type clone(Type data)
Definition: CorbaTypeManipulator.hxx:91
static InnerType *const getPointer(Type data, bool ownerShip=false)
Definition: CorbaTypeManipulator.hxx:82
static Type get_data(CorbaInType data)
Definition: CorbaTypeManipulator.hxx:77
const T & CorbaInType
Definition: CorbaTypeManipulator.hxx:72
bool VerbosityActivated()
Called by any log message macros to decide about log output in Release and Debug mode dynamically rel...
Definition: libSALOMELog.cxx:48
tmp
Definition: TestSalomeSDS1.py:63