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