Salome HOME
Porting functionality on Win32 Platform
[modules/kernel.git] / src / Batch / Batch_Versatile.cxx
1 // Copyright (C) 2005  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  * Versatile.cxx : 
22  *
23  * Auteur : Ivan DUTKA-MALEN - EDF R&D
24  * Date   : Septembre 2003
25  * Projet : SALOME 2
26  *
27  */
28
29 #include <iostream>
30 #include <list>
31 #include <string>
32 #include <sstream>
33 #include <assert.h>
34 //#include "MEDMEM_STRING.hxx"
35 #include "Batch_GenericType.hxx"
36 #include "Batch_IntType.hxx"
37 #include "Batch_BoolType.hxx"
38 #include "Batch_CharType.hxx"
39 #include "Batch_LongType.hxx"
40 #include "Batch_StringType.hxx"
41 #include "Batch_Versatile.hxx"
42 #include "Batch_TypeMismatchException.hxx"
43 #include "Batch_ListIsFullException.hxx"
44 using namespace std;
45
46 namespace Batch {
47
48         // Constructeur par recopie
49   Versatile::Versatile(const Versatile & V) : _discriminator(V._discriminator), _maxsize(V._maxsize), _name(V._name) // , _str_value(0)
50   {
51     Versatile::const_iterator it;
52
53                 // On prend un a un les elements de l'objet passe en argument qu'on duplique
54     for(it=V.begin(); it!=V.end(); it++)
55       push_back( (*it)->clone() ); // Attention, la methode clone fait un new implicite
56   }
57
58         // Destructeur
59   Versatile::~Versatile()
60   {
61                 eraseAll();
62   }
63
64         // Operateur d'affectation entre objets
65   Versatile & Versatile::operator = (const Versatile & Vrhs) throw(TypeMismatchException)
66   {
67                 // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit
68     setType(Vrhs._discriminator);
69     setMaxSize(Vrhs._maxsize);
70     _name = Vrhs._name;
71
72     // On efface les donnees precedentes
73     eraseAll();
74
75     // On copie les donnees de Vrhs
76     Versatile::const_iterator it;
77
78     for(it=Vrhs.begin(); it!=Vrhs.end(); it++)
79       push_back( (*it)->clone() ); // Attention, la methode clone fait un new implicite
80
81     return *this;
82   }
83
84         // Operateur d'affectation a partir d'un long
85   Versatile & Versatile::operator = (const long   l) throw(TypeMismatchException)
86   {
87                 // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit
88     setType(LONG);
89
90     // On efface les donnees precedentes
91     eraseAll();
92
93                 // On ajoute un element interne de type long a l'objet  
94     LongType * pL = new LongType(l);
95     assert(pL != 0);
96     push_back(pL);
97     return *this;
98   }
99
100         // Operateur d'affectation a partir d'une string
101   Versatile & Versatile::operator = (const string & ch) throw(TypeMismatchException)
102   {
103                 // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit
104     setType(STRING);
105
106     // On efface les donnees precedentes
107     eraseAll();
108   
109                 // On ajoute un element interne de type string a l'objet  
110     StringType * pS = new StringType(ch);
111     assert(pS != 0);
112     push_back(pS);
113
114     return *this;
115   }
116
117         // Operateur de concatenation a partir d'une string
118   Versatile & Versatile::operator +=(const string & ch) throw(TypeMismatchException,ListIsFullException)
119   {
120                 // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit
121     setType(STRING);
122
123                 // Si la taille maximale est atteinte, on leve une exception ListIsFullException
124     if (_maxsize == 0) push_back(new StringType(ch));
125     else if ((_maxsize > 0) && (size() < _maxsize)) push_back(new StringType(ch));
126     else {
127       //MEDMEM::STRING msg;
128       ostringstream msg;
129       msg << "Taille maximum : " << _maxsize;
130       throw(ListIsFullException(msg.str()));
131     }
132     return *this;
133   }
134
135         // Operateur de concatenation a partir d'une string
136   Versatile & Versatile::operator , (const string & ch) throw(TypeMismatchException,ListIsFullException)
137   {
138     *this += ch;
139     return *this;
140   }
141
142         // Operateur d'affectation a partir d'un Couple
143   Versatile & Versatile::operator = (const Couple & cp) throw(TypeMismatchException)
144   {
145                 // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit
146                 setType(COUPLE);
147
148     // On efface les donnees precedentes
149     eraseAll();
150   
151                 // On ajoute un element interne de type Couple a l'objet  
152     CoupleType * pC = new CoupleType(cp);
153     assert(pC != 0);
154     push_back(pC);
155
156     return *this;
157   }
158
159         // Operateur de concatenation a partir d'un Couple
160   Versatile & Versatile::operator +=(const Couple & cp) throw(TypeMismatchException,ListIsFullException)
161   {
162                 // ATTENTION : le forçage de type leve une exception TypeMismatchException entre cas de conflit
163     setType(COUPLE);
164
165                 // Si la taille maximale est atteinte, on leve une exception ListIsFullException
166     if (_maxsize == 0) push_back(new CoupleType(cp));
167     else if ((_maxsize > 0) && (size() < _maxsize)) push_back(new CoupleType(cp));
168     else {
169       //MEDMEM::STRING msg;
170       ostringstream msg;
171       msg << "Taille maximum : " << _maxsize;
172       throw(ListIsFullException(msg.str()));
173     }
174     return *this;
175   }
176
177         // Operateur de concatenation a partir d'un Couple
178   Versatile & Versatile::operator , (const Couple & cp) throw(TypeMismatchException,ListIsFullException)
179   {
180     *this += cp;
181     return *this;
182   }
183
184   ostream & operator << (ostream & os, const Versatile & V)
185   {
186     Versatile::const_iterator it;
187     const char * sep = "";
188
189     for(it=V.begin(); it!=V.end(); it++, sep=" ") {
190       string s = (*it)->affiche();
191       os << sep << s;
192     }
193     return os;
194   }
195
196         // Positionnement du type de l'element interne
197   void Versatile::setType(DiscriminatorType t) throw(TypeMismatchException)
198   {
199                 // Si le type est deja defini et ne correspond pas au type en argument
200                 // une exception TypeMismatchException est levee
201     if ( (_discriminator == UNDEFINED) || (_discriminator == t) )
202       _discriminator = t;
203     else {
204       //MEDMEM::STRING sst;
205       ostringstream sst;
206       sst << "Trying to change type of Versatile object \""
207                                         << _name << "\"";
208       throw(TypeMismatchException(sst.str()));
209     }
210   }
211         
212         // Positionnement du nombre d'elements internes
213   void Versatile::setMaxSize(int i)
214   {
215     _maxsize = i;
216     if (i <= 0) return;
217                 // Si la nouvelle taille est inferieure au nombre d'elements deja
218                 // presents, les elements en surplus sont effaces (troncature)
219     if (size() > _maxsize)
220       {
221                                 int reste = size() - _maxsize;
222                                 Versatile::iterator it;
223                                 for(it=end(); (it!=begin()) && reste; it--, reste--)
224                                         {
225                                                 delete back();
226                                                 pop_back();
227                                         }
228       }
229   }
230
231
232         // Conversion de type vers un long
233   Versatile::operator long() const throw(TypeMismatchException)
234   {
235                 // Si le type ne correspond pas ou si la liste contient plus d'un element,
236                 // la conversion est impossible et une exception TypeMismatchException 
237                 // est levee
238     if ( (_maxsize != 1) || (_discriminator != LONG) || (size() == 0) ) {
239       //MEDMEM::STRING sst;
240       ostringstream sst;
241       sst << "Cannot cast Versatile object \""
242                                         << _name << "\" to long";
243       throw(TypeMismatchException(sst.str()));
244     }
245                 return *( static_cast<LongType *>(this->front()) );
246   }
247
248         // Conversion de type vers un Couple
249   Versatile::operator Couple() const throw(TypeMismatchException)
250   {
251                 // Si le type ne correspond pas ou si la liste contient plus d'un element,
252                 // la conversion est impossible et une exception TypeMismatchException 
253                 // est levee
254     if ( (_maxsize != 1) || (_discriminator != COUPLE) || (size() == 0) ) {
255       //MEDMEM::STRING sst;
256       ostringstream sst;
257       sst << "Cannot cast Versatile object \""
258                                         << _name << "\" to Couple";
259       throw(TypeMismatchException(sst.str()));
260     }
261                 return *( static_cast<CoupleType *>(this->front()) );
262   }
263
264         // Conversion de type vers une string
265   string Versatile::str() const throw(TypeMismatchException)
266   {
267                 // Si le type ne correspond pas, la conversion est impossible et 
268                 // une exception TypeMismatchException est levee
269     if ( (_discriminator != STRING) || (size() == 0) ) {
270       //MEDMEM::STRING sst;
271       ostringstream sst;
272       sst << "Cannot cast Versatile object \""
273                                         << _name << "\" to string";
274       throw(TypeMismatchException(sst.str()));
275     }
276
277                 // La chaine renvoyee est la concatenation des chaines internes
278     string s;
279     Versatile::const_iterator it;
280     const char * sep = "";
281     for(it=begin(); it!=end(); it++, s+=sep, sep=" ")
282       s += *( static_cast<StringType *>(*it));
283
284     return s;
285   }
286
287         // Conversion de type vers une string
288   Versatile::operator string () const throw(TypeMismatchException)
289   {
290     return str();
291   }
292
293         // Efface tous les elements internes de l'objet
294   void Versatile::eraseAll()
295   {
296     while(!empty()) 
297       {
298                                 delete back();
299                                 pop_back();
300       }
301   }
302
303
304         // Recuperation du type de l'element interne
305   DiscriminatorType Versatile::getType() const
306   {
307     return _discriminator;
308   }
309
310         // Recuperation du nom de l'objet
311   string Versatile::getName() const
312   {
313     return _name;
314   }
315
316         // Positionnement du nom de l'objet
317   void Versatile::setName(const string & name)
318   {
319     _name = name;
320   }
321 }