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