Salome HOME
Merge branch V7_3_1_BR
[modules/yacs.git] / src / engine / Any.cxx
1 // Copyright (C) 2006-2014  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "Any.hxx"
21 #include "Runtime.hxx"
22 #include "TypeCode.hxx"
23 #include "InvalidExtractionException.hxx"
24
25 #include <cstring>
26 #include <cstdlib>
27
28 using namespace YACS::ENGINE;
29 using namespace std;
30
31 StringOnHeap::StringOnHeap(const char *val):_dealloc(0),_str(strdup(val))
32 {
33 }
34
35 StringOnHeap::StringOnHeap(const std::string& val):_dealloc(0),_str(strdup(val.c_str()))
36 {
37 }
38
39 /*! 
40  * \note : no copy is performed if a deallocator is given.
41  * \param val     : String in C format that is NOT copied if
42  *                  deAlloc != 0
43  * \param deAlloc : pointer on function to deallocate val after
44  *                  last use.
45  */
46 StringOnHeap::StringOnHeap(char *val, Deallocator deAlloc):_dealloc(deAlloc)
47 {
48   if(deAlloc)
49     _str=val;
50   else
51     _str=strdup(val);
52 }
53
54 bool StringOnHeap::operator ==(const StringOnHeap& other) const
55 {
56   return strcmp(_str, other._str)==0;
57 }
58
59 StringOnHeap *StringOnHeap::deepCopy() const
60 {
61   return new StringOnHeap(_str);
62 }
63
64 StringOnHeap::~StringOnHeap()
65 {
66   if(_dealloc)
67     _dealloc(_str);
68   else
69     free(_str);
70 }
71
72 Any::Any(TypeCode* type):_type(type)
73 {
74   _type->incrRef();
75 }
76
77 Any::Any(const Any& other):_type(other._type)
78 {
79   _type->incrRef();
80 }
81
82 Any::~Any()
83 {
84   _type->decrRef();
85 }
86
87 AtomAny::AtomAny(int val):Any(Runtime::_tc_int)
88 {
89   _value._i=val;
90 }
91
92 AtomAny::AtomAny(bool val):Any(Runtime::_tc_bool)
93 {
94   _value._b=val;
95 }
96
97 AtomAny::AtomAny(double val):Any(Runtime::_tc_double)
98 {
99   _value._d=val;
100 }
101
102 AtomAny::AtomAny(const char *val):Any(Runtime::_tc_string)
103 {
104   _value._s=new StringOnHeap(val);
105 }
106
107 AtomAny::AtomAny(const std::string& val):Any(Runtime::_tc_string)
108 {
109   _value._s=new StringOnHeap(val);
110 }
111
112 AtomAny::AtomAny(const AtomAny& other):Any(other)
113 {
114   if(_type->isA(Runtime::_tc_string))
115     {
116       StringOnHeap *cpy=(other._value._s)->deepCopy();
117       memcpy(&_value._s,&cpy,_type->getSizeInByteOfAnyReprInSeq());
118     }
119   else if(_type->isA(Runtime::_tc_double))
120     memcpy(&_value._d,&other._value._d,_type->getSizeInByteOfAnyReprInSeq());
121   else if(_type->isA(Runtime::_tc_int))
122     memcpy(&_value._i,&other._value._i,_type->getSizeInByteOfAnyReprInSeq());
123   else if(_type->isA(Runtime::_tc_bool))
124     memcpy(&_value._b,&other._value._b,_type->getSizeInByteOfAnyReprInSeq());
125 }
126
127 AtomAny::AtomAny(char *val, Deallocator deAlloc):Any(Runtime::_tc_string)
128 {
129   _value._s=new StringOnHeap(val,deAlloc);
130 }
131
132 AtomAny::AtomAny(char *data, TypeCode* type):Any(type)
133 {
134   if(type->isA(Runtime::_tc_string))
135     {
136       void **tmp=(void **)data;
137       StringOnHeap *cpy=((StringOnHeap *)(*tmp))->deepCopy();
138       memcpy(&_value._s,&cpy,type->getSizeInByteOfAnyReprInSeq());
139     }
140   else if(type->isA(Runtime::_tc_double))
141     memcpy(&_value._d,data,type->getSizeInByteOfAnyReprInSeq());
142   else if(type->isA(Runtime::_tc_int))
143     memcpy(&_value._i,data,type->getSizeInByteOfAnyReprInSeq());
144   else if(type->isA(Runtime::_tc_bool))
145     memcpy(&_value._b,data,type->getSizeInByteOfAnyReprInSeq());
146 }
147
148 Any *AtomAny::clone() const
149 {
150   return new AtomAny(*this);
151 }
152
153 AtomAny *AtomAny::New(char *val,Deallocator dealloc)
154 {
155   return new AtomAny(val,dealloc);
156 }
157
158 AnyPtr AtomAny::operator[](int i) const throw(YACS::Exception)
159 {
160   throw InvalidExtractionException(_type->kind(),Sequence);
161 }
162
163 AnyPtr AtomAny::operator[](const char *key) const throw(YACS::Exception)
164 {
165   throw Exception("AtomAny::operator[] : try to get a part of a partitionned data whereas atomical.");
166 }
167
168 bool AtomAny::operator ==(const Any& other) const
169 {
170   if(!_type->isA(other.getType()))
171     return false;
172   const AtomAny& otherC=(const AtomAny&) other;//cast granted due to previous lines
173   if(_type->isA(Runtime::_tc_double))
174     return _value._d==otherC._value._d;
175   else if(_type->isA(Runtime::_tc_int))
176     return _value._i==otherC._value._i;
177   else if(_type->isA(Runtime::_tc_bool))
178     return _value._b==otherC._value._b;
179   else if(_type->isA(Runtime::_tc_string))
180     return (*_value._s)==*(otherC._value._s);
181   else
182     return false;
183 }
184
185 int AtomAny::getIntValue() const throw(YACS::Exception)
186 {
187   if(_type->isA(Runtime::_tc_int))
188     return _value._i;
189   else
190     throw Exception("Value is not an int");
191 }
192
193 bool AtomAny::getBoolValue() const throw(YACS::Exception)
194 {
195   if(_type->isA(Runtime::_tc_bool))
196     return _value._b;
197   else
198     throw Exception("Value is not a bool");
199 }
200
201 double AtomAny::getDoubleValue() const throw(YACS::Exception)
202 {
203   if(_type->isA(Runtime::_tc_double))
204     return _value._d;
205   else
206     throw Exception("Value is not a double");
207 }
208
209 std::string AtomAny::getStringValue() const throw(YACS::Exception)
210 {
211   if(_type->isA(Runtime::_tc_string))
212     return string(_value._s->cStr());
213   else
214     throw Exception("Value is not a string");
215 }
216
217 /*!
218  * \note : This method put in data its zipped recursive content in data.
219  *         The ownership of the recursive content is tranfered to data.
220  *         So this owns nothing and its counter fall by 1.
221  *         For memory space minimal use, not all of '*this' is pushed at data location. 
222  * \param data : already allocated memory zone where to put compressed content of 'this'
223  */
224 void AtomAny::putMyReprAtPlace(char *data) const
225 {
226   if(_type->isA(Runtime::_tc_string))
227     {
228       StringOnHeap *tmp=_value._s->deepCopy();
229       memcpy(data,&tmp,_type->getSizeInByteOfAnyReprInSeq());
230     }
231   else if(_type->isA(Runtime::_tc_double))
232     memcpy(data,&_value._d,_type->getSizeInByteOfAnyReprInSeq());
233   else if(_type->isA(Runtime::_tc_int))
234     memcpy(data,&_value._i,_type->getSizeInByteOfAnyReprInSeq());
235   else if(_type->isA(Runtime::_tc_bool))
236     memcpy(data,&_value._b,_type->getSizeInByteOfAnyReprInSeq());
237 }
238
239 /*!
240  * \note : This method put in data its zipped recursive content in data.
241  *         The ownership of the recursive content is tranfered to data.
242  *         So this owns nothing and its counter fall by 1.
243  *         For memory space minimal use, not all of '*this' is pushed at data location.
244  *         'deepCpy' param is not used here because by definition of AtomAny deep copy is performed.
245  * \param data : already allocated memory zone where to put compressed content of 'this'
246  * \param src :
247  * \param type :
248  * \param deepCpy :
249  */
250 void AtomAny::putReprAtPlace(char *data, const char *src, const TypeCode *type, bool deepCpy)
251 {
252   if(type->isA(Runtime::_tc_string))
253     {
254       void **tmp1=(void **)src;
255       StringOnHeap *tmp=((const StringOnHeap *)(*tmp1))->deepCopy();
256       memcpy(data,&tmp,type->getSizeInByteOfAnyReprInSeq());
257     }
258   else if(type->isA(Runtime::_tc_double))
259     memcpy(data,src,type->getSizeInByteOfAnyReprInSeq());
260   else if(type->isA(Runtime::_tc_int))
261     memcpy(data,src,type->getSizeInByteOfAnyReprInSeq());
262   else if(type->isA(Runtime::_tc_bool))
263     memcpy(data,src,type->getSizeInByteOfAnyReprInSeq());
264 }
265
266 /*!
267  * \note : Opposite method of putMyReprAtPlace. But static because due to data compression
268  *         instance is lost.
269  */
270 void AtomAny::destroyReprAtPlace(char *data, const TypeCode *type)
271 {
272   DynType typ=type->kind();
273   if(typ==String)
274     {
275       void **tmp=(void **)data;
276       delete ((StringOnHeap *)(*tmp));
277     }
278 }
279
280 AnyPtr AtomAny::getOrBuildFromData(char *data, const TypeCode *type)
281 {
282   Any *ret;
283   ret=new AtomAny(data,(TypeCode *)type);
284   return AnyPtr(ret);
285 }
286
287 bool AtomAny::takeInChargeStorageOf(TypeCode *type)
288 {
289   DynType typ=type->kind();
290   return (typ==Double || typ==Int || typ==Bool || typ==String);
291 }
292
293 AtomAny::~AtomAny()
294 {
295   if(_type->kind() == String)
296     delete _value._s;
297 }
298
299 ComposedAny::ComposedAny(const ComposedAny& other):Any(other)
300 {
301 }
302
303 ComposedAny::ComposedAny(TypeCode* type, bool isNew):Any(type)
304 {
305   if(isNew)
306     _type->decrRef();
307 }
308
309 AnyPtr ComposedAny::operator[](const char *key) const throw(YACS::Exception)
310 {
311   throw Exception("AtomAny::operator[] : try to get a part of a partitionned data not localizable by a string.");
312 }
313
314 void ComposedAny::checkTypeOf(const Any *elem) const throw(YACS::Exception)
315 {
316   if(!elem->getType()->isA(_type->contentType()))
317     throw Exception("ComposedAny::checkTypeOf : invalid type.");
318 }
319
320 int ComposedAny::getIntValue() const throw(YACS::Exception)
321 {
322  throw InvalidExtractionException(_type->kind(),Runtime::_tc_int->kind());
323 }
324
325 bool ComposedAny::getBoolValue() const throw(YACS::Exception)
326 {
327   throw InvalidExtractionException(_type->kind(),Runtime::_tc_bool->kind());
328 }
329
330 double ComposedAny::getDoubleValue() const throw(YACS::Exception)
331 {
332   throw InvalidExtractionException(_type->kind(),Runtime::_tc_double->kind());
333 }
334
335 std::string ComposedAny::getStringValue() const throw(YACS::Exception)
336 {
337   throw InvalidExtractionException(_type->kind(),Runtime::_tc_string->kind());
338 }
339
340 SeqAlloc::SeqAlloc(const SeqAlloc& other):_sizeOf1Elm(other._sizeOf1Elm),_notStdDeAlloc(0),
341  _start(0),_finish(0),_endOfStorage(0)
342 {
343   _start=allocate(other._finish-other._start);
344   _finish=_start+(other._finish-other._start);
345   _endOfStorage=_finish;
346 }
347
348 SeqAlloc::SeqAlloc(unsigned int sizeOf1Elm):_sizeOf1Elm(sizeOf1Elm),_notStdDeAlloc(0),
349                                             _start(0),_finish(0),_endOfStorage(0)
350 {
351 }
352
353 SeqAlloc::~SeqAlloc()
354 {
355   deallocate(_start);
356 }
357
358 void SeqAlloc::clear()
359 {
360   deallocate(_start);
361   _start=0;
362   _finish=0;
363   _endOfStorage=0;
364 }
365
366 /*!
367  * \note : This method is exclusively reserved for arrays of C++ built-in types because no
368  *         constructor is applied atomically.
369  */
370 void SeqAlloc::initCoarseMemory(char *mem, unsigned int size, Deallocator dealloc)
371 {
372   unsigned sizeInByte=size*_sizeOf1Elm;
373   if(dealloc)
374     {
375       _notStdDeAlloc=dealloc;
376       _start=mem;
377     }
378   else
379     {
380       _start=allocate(sizeInByte);
381       if(mem)
382         memcpy(_start,mem,sizeInByte);
383       else
384         {
385           for(unsigned int i=0;i<sizeInByte;i++) _start[i]=0;
386         }
387     }
388   _finish=_start+sizeInByte;
389   _endOfStorage=_finish;
390 }
391
392 void SeqAlloc::construct(char *pt, const Any *val)
393 {
394   val->putMyReprAtPlace(pt);
395 }
396
397 /*!
398  * \note: This performs the placement new or zip info into pt.
399  * \param pt :
400  * \param val     : the source from which the construction will be performed.
401  * \param tc  :
402  * \param deepCpy : If true in pt place a deep copy pointed by val will be put.
403  */
404 void SeqAlloc::construct(char *pt, const char *val, const TypeCode *tc, bool deepCpy)
405 {
406   tc->putReprAtPlace(pt,val,deepCpy);
407 }
408
409 char *SeqAlloc::allocate(unsigned int nbOfByte)
410
411   if(nbOfByte>0)
412     return (char *)::operator new(nbOfByte);
413   else
414     return 0;
415 }
416
417 // pt is not permitted to be a null pointer.
418 void SeqAlloc::deallocate(char *pt)
419
420   if(pt)
421     {
422       if(!_notStdDeAlloc)
423         ::operator delete(pt); 
424       else
425         {
426           _notStdDeAlloc(pt);
427           _notStdDeAlloc=0;
428         }
429     }
430 }
431
432 void SeqAlloc::destroy(char *pt, const TypeCode *tc) 
433
434   tc->destroyZippedAny(pt);
435 }
436
437 unsigned int SeqAlloc::size() const
438 {
439   return (_finish-_start)/_sizeOf1Elm;
440 }
441
442 void SequenceAny::clear()
443 {
444   for (char *cur=_alloc._start;cur!=_alloc._finish;cur+=_alloc._sizeOf1Elm)
445     _alloc.destroy(cur,_type->contentType());
446   _alloc.clear();
447 }
448
449 void SequenceAny::popBack()
450 {
451   _alloc._finish-=_alloc._sizeOf1Elm;
452   _alloc.destroy(_alloc._finish,_type->contentType());
453 }
454
455 void SequenceAny::pushBack(const Any* elem)
456 {
457   if(!elem->_type->isA(_type->contentType()))
458     throw InvalidExtractionException(elem->_type->kind(),_type->contentType()->kind());
459   if(_alloc._finish != _alloc._endOfStorage)
460     {
461       _alloc.construct(_alloc._finish, elem);
462       _alloc._finish+=_alloc._sizeOf1Elm;
463     }
464   else
465     realloc(_alloc._finish, elem);
466 }
467
468 bool SequenceAny::operator ==(const Any& other) const
469 {
470   if(!_type->isA(other.getType()))
471     return false;
472   const SequenceAny& otherC=(const SequenceAny&) other;//cast granted due to previous lines
473   if(size()!=otherC.size())
474     return false;
475   for(unsigned i=0;i<size();i++)
476     if(!((*(*this)[i])==(*otherC[i])))
477       return false;
478   return true;
479 }
480
481 void SequenceAny::setEltAtRank(int i, const Any *elem) throw(YACS::Exception)
482 {
483   checkTypeOf(elem);
484   _alloc.destroy(_alloc._start+i*_alloc._sizeOf1Elm,_type->contentType());
485   _alloc.construct(_alloc._start+i*_alloc._sizeOf1Elm,elem);
486 }
487
488 AnyPtr SequenceAny::operator[](int i) const throw(YACS::Exception)
489 {
490   return _type->contentType()->getOrBuildAnyFromZippedData(_alloc._start+i*_alloc._sizeOf1Elm);
491 }
492
493 /*!
494  * \note : Contrary to AtomAny 'this' (ref) is put in data NOT a deep copy.
495  * \param data : already allocated memory zone where to put address of 'this'
496  */
497 void SequenceAny::putMyReprAtPlace(char *data) const
498 {
499   const void *tmp=(const void *)this;
500   memcpy(data,&tmp,_type->getSizeInByteOfAnyReprInSeq());
501   const void **tmp2=(const void **) data;
502   ((SequenceAny *)(*tmp2))->incrRef();
503   //::new((SequenceAny *)data) SequenceAny((SequenceAny&) (*this));
504 }
505
506 void SequenceAny::putReprAtPlace(char *data, const char *src, const TypeCode *type, bool deepCpy)
507 {
508   void **tmp2=(void **) src;
509   if(!deepCpy)
510     {
511       ((SequenceAny *)(*tmp2))->incrRef();
512       memcpy(data,src,type->getSizeInByteOfAnyReprInSeq());
513     }
514   else
515     {
516       SequenceAny *cpy=new SequenceAny(*((SequenceAny *)(*tmp2)));
517       memcpy(data,&cpy,type->getSizeInByteOfAnyReprInSeq());
518     }
519   //::new((SequenceAny *)data) SequenceAny((SequenceAny&) (*this));
520 }
521
522 void SequenceAny::destroyReprAtPlace(char *data, const TypeCode *type)
523 {
524   void **tmp=(void **) data;
525   if(*tmp)
526     ((SequenceAny *)(*tmp))->decrRef();
527   //((SequenceAny *)data)->~SequenceAny();
528 }
529
530 AnyPtr SequenceAny::getOrBuildFromData(char *data, const TypeCode *type)
531 {
532   void **tmp=(void **) data;
533   ((SequenceAny *) (*tmp))->incrRef();
534   return AnyPtr((SequenceAny *)(*tmp));
535 }
536
537 Any *SequenceAny::clone() const
538 {
539   return new SequenceAny(*this);
540 }
541
542 SequenceAny *SequenceAny::New(const TypeCode *typeOfContent)
543 {
544   if(typeOfContent->kind() == Objref)
545     {
546       //In case of Objref, use a sequence of string
547       return new SequenceAny(Runtime::_tc_string);
548     }
549   else
550     return new SequenceAny(typeOfContent);
551 }
552
553 SequenceAny *SequenceAny::New(const TypeCode *typeOfContent, unsigned lgth)
554 {
555   if(typeOfContent->kind() == Objref)
556     {
557       //In case of Objref, use a sequence of string
558       return new SequenceAny(Runtime::_tc_string,lgth);
559     }
560   else
561     return new SequenceAny(typeOfContent,lgth);
562 }
563
564 bool SequenceAny::takeInChargeStorageOf(TypeCode *type)
565 {
566   DynType typ=type->kind();
567   return (typ==Sequence);
568 }
569
570 SequenceAny::SequenceAny(const SequenceAny& other):ComposedAny(other),_alloc(other._alloc)
571 {
572   const char *srcCur=other._alloc._start;
573   for(char *cur=_alloc._start;srcCur != other._alloc._finish; srcCur+=_alloc._sizeOf1Elm, cur+=_alloc._sizeOf1Elm)
574     _alloc.construct(cur, srcCur, _type->contentType(),true);
575 }
576
577 SequenceAny::~SequenceAny()
578 {
579   for (char *cur=_alloc._start;cur!=_alloc._finish;cur+=_alloc._sizeOf1Elm)
580     _alloc.destroy(cur,_type->contentType());
581 }
582
583 /*!
584  * \param typeOfContent : typeCode of the type of elements stored in sequence.
585  */
586 SequenceAny::SequenceAny(const TypeCode *typeOfContent):ComposedAny(new TypeCodeSeq("","",typeOfContent)),
587                                                         _alloc(typeOfContent->getSizeInByteOfAnyReprInSeq())
588 {
589 }
590
591 SequenceAny::SequenceAny(const TypeCode *typeOfContent, unsigned lgth):ComposedAny(new TypeCodeSeq("","",typeOfContent)),
592                                                                        _alloc(typeOfContent->getSizeInByteOfAnyReprInSeq())
593 {
594   _alloc.initCoarseMemory(0,lgth,0);
595 }
596
597 SequenceAny::SequenceAny(int *val, unsigned int lgth, Deallocator deAlloc):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_int)),
598                                                                            _alloc(Runtime::_tc_int->getSizeInByteOfAnyReprInSeq())
599 {
600   _alloc.initCoarseMemory((char *)val,lgth,deAlloc);
601 }
602
603 SequenceAny::SequenceAny(bool *val, unsigned int lgth, Deallocator deAlloc):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_bool)),
604                                                                             _alloc(Runtime::_tc_bool->getSizeInByteOfAnyReprInSeq())
605 {
606   _alloc.initCoarseMemory((char *)val,lgth,deAlloc);
607 }
608
609 SequenceAny::SequenceAny(double *val, unsigned int lgth, Deallocator deAlloc):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_double)),
610                                                                               _alloc(Runtime::_tc_double->getSizeInByteOfAnyReprInSeq())
611 {
612   _alloc.initCoarseMemory((char *)val,lgth,deAlloc);
613 }
614
615 SequenceAny::SequenceAny(const std::vector<int>& val):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_int)),
616                                                       _alloc(Runtime::_tc_int->getSizeInByteOfAnyReprInSeq())
617 {
618   _alloc.initCoarseMemory((char *)&val[0],val.size(),0);
619 }
620
621 SequenceAny::SequenceAny(const std::vector<bool>& val):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_bool)),
622                                                        _alloc(Runtime::_tc_bool->getSizeInByteOfAnyReprInSeq())
623 {
624   for(vector<bool>::const_iterator iter=val.begin();iter!=val.end();iter++)
625     {
626       AtomAnyPtr tmp=AtomAny::New(*iter);
627       pushBack(tmp);
628     }
629 }
630
631 SequenceAny::SequenceAny(const std::vector<double>& val):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_double)),
632                                                          _alloc(Runtime::_tc_double->getSizeInByteOfAnyReprInSeq())
633 {
634   _alloc.initCoarseMemory((char *)&val[0],val.size(),0);
635 }
636
637 SequenceAny::SequenceAny(const std::vector<std::string>& val):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_string)),
638                                                               _alloc(Runtime::_tc_string->getSizeInByteOfAnyReprInSeq())
639 {
640   for(vector<string>::const_iterator iter=val.begin();iter!=val.end();iter++)
641     {
642       AtomAnyPtr tmp=AtomAny::New(*iter);
643       pushBack(tmp);
644     }
645 }
646
647 void SequenceAny::realloc(char *endOfCurrentAllocated, const Any *elem)
648 {
649   unsigned int oldSize=_alloc._finish-_alloc._start;
650   unsigned int newSize = oldSize != 0 ? 2 * oldSize : _alloc._sizeOf1Elm;
651   char *newStart=_alloc.allocate(newSize);
652   //
653   char *newFinish=performCpy(_alloc._start, endOfCurrentAllocated,newStart);
654   _alloc.construct(newFinish, elem);
655   newFinish+=_alloc._sizeOf1Elm;
656   newFinish=performCpy(endOfCurrentAllocated, _alloc._finish, newFinish);
657   //
658   for (char *cur=_alloc._start;cur!=_alloc._finish;cur+=_alloc._sizeOf1Elm)
659     _alloc.destroy(cur,_type->contentType());
660   _alloc.deallocate(_alloc._start);
661   _alloc._start = newStart;
662   _alloc._finish = newFinish;
663   _alloc._endOfStorage=newStart+newSize;
664 }
665
666 char *SequenceAny::performCpy(char *srcStart, char *srcFinish, char *destStart)
667 {
668   char *cur=destStart;
669   for (;srcStart != srcFinish; srcStart+=_alloc._sizeOf1Elm, cur+=_alloc._sizeOf1Elm)
670     _alloc.construct(cur, srcStart, _type->contentType(),false);
671   return cur;
672 }
673
674 ArrayAny::~ArrayAny()
675 {
676   const TypeCode *subType=_type->contentType();
677   unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
678   unsigned int size=((TypeCodeArray *)_type)->getStaticLgth();
679   char *tmp=_data;
680   for(unsigned i=0;i<size;i++,tmp+=sizePerContent)
681     subType->destroyZippedAny(tmp);
682   delete [] _data;
683 }
684
685 ArrayAny::ArrayAny(const TypeCode *typeOfContent, unsigned int lgth):ComposedAny(new TypeCodeArray("","",typeOfContent,lgth))
686 {
687   _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
688   for(unsigned int i=0;i<_type->getSizeInByteOfAnyReprInSeq();i++)
689     _data[i]='\0';
690 }
691
692 ArrayAny::ArrayAny(char *data, TypeCodeArray * type):ComposedAny(type,false),_data(0)
693 {
694   _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
695   const TypeCode *subType=_type->contentType();
696   unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
697   for(unsigned i=0;i<type->getStaticLgth();i++)
698     subType->putReprAtPlace(_data+i*sizePerContent,data+i*sizePerContent,false);
699 }
700
701 ArrayAny::ArrayAny(const ArrayAny& other):ComposedAny(other)
702 {
703   _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
704   const TypeCode *subType=_type->contentType();
705   unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
706   for(unsigned i=0;i<((TypeCodeArray *)_type)->getStaticLgth();i++)
707     subType->putReprAtPlace(_data+i*sizePerContent,other._data+i*sizePerContent,true);
708 }
709
710 ArrayAny::ArrayAny(const int *val, unsigned int lgth):ComposedAny(new TypeCodeArray("","",Runtime::_tc_int,lgth)),
711                                                       _data(0)
712 {
713   _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
714   memcpy(_data,val,_type->getSizeInByteOfAnyReprInSeq());
715 }
716
717 ArrayAny::ArrayAny(const bool *val, unsigned int lgth):ComposedAny(new TypeCodeArray("","",Runtime::_tc_bool,lgth)),
718                                                        _data(0)
719 {
720   _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
721   memcpy(_data,val,_type->getSizeInByteOfAnyReprInSeq());
722 }
723
724 ArrayAny::ArrayAny(const double *val, unsigned int lgth):ComposedAny(new TypeCodeArray("","",Runtime::_tc_double,lgth)),
725                                                          _data(0)
726 {
727   _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
728   memcpy(_data,val,_type->getSizeInByteOfAnyReprInSeq());
729 }
730
731 ArrayAny::ArrayAny(const std::vector<int>& val):ComposedAny(new TypeCodeArray("","",Runtime::_tc_int,val.size())),
732                                                 _data(0)
733 {
734   _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
735   memcpy(_data,&val[0],_type->getSizeInByteOfAnyReprInSeq());
736 }
737
738 ArrayAny::ArrayAny(const std::vector<double>& val):ComposedAny(new TypeCodeArray("","",Runtime::_tc_double,val.size())),
739                                                 _data(0)
740 {
741   _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
742   memcpy(_data,&val[0],_type->getSizeInByteOfAnyReprInSeq());
743 }
744
745 ArrayAny::ArrayAny(const std::vector<std::string>& val):ComposedAny(new TypeCodeArray("","",Runtime::_tc_string,val.size())),
746                                                         _data(0)
747 {
748   _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
749   unsigned i=0;
750   const TypeCode *subType=_type->contentType();
751   unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
752   for(vector<std::string>::const_iterator iter=val.begin();iter!=val.end();iter++,i++)
753     {
754       StringOnHeap *st=new StringOnHeap(*iter);
755       memcpy(_data+i*sizePerContent,&st,sizePerContent);
756     }
757 }
758
759 void ArrayAny::setEltAtRank(int i, const Any *elem) throw(YACS::Exception)
760 {
761   checkTypeOf(elem);
762   const TypeCode *subType=_type->contentType();
763   subType->destroyZippedAny(_data+i*subType->getSizeInByteOfAnyReprInSeq());
764   elem->putMyReprAtPlace(_data+i*subType->getSizeInByteOfAnyReprInSeq());
765 }
766
767 bool ArrayAny::operator ==(const Any& other) const
768 {
769   if(!_type->isA(other.getType()))
770     return false;
771   const ArrayAny& otherC=(const ArrayAny&) other;//cast granted due to previous lines
772   for(unsigned i=0;i<((const TypeCodeArray *)_type)->getStaticLgth();i++)
773     if(!((*(*this)[i])==(*otherC[i])))
774       return false;
775   return true;
776 }
777
778 AnyPtr ArrayAny::operator[](int i) const throw(YACS::Exception)
779 {
780   const TypeCode *subType=_type->contentType();
781   unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
782   if(i<0 || i>=((TypeCodeArray *)_type)->getStaticLgth())
783     throw Exception("Trying to access to an invalid index in an Any Tuple");
784   return _type->contentType()->getOrBuildAnyFromZippedData(_data+i*sizePerContent);
785 }
786
787 unsigned int ArrayAny::size() const
788 {
789   return ((TypeCodeArray *)_type)->getStaticLgth();
790 }
791
792 Any *ArrayAny::clone() const
793 {
794   return new ArrayAny(*this);
795 }
796
797 ArrayAny *ArrayAny::New(const TypeCode *typeOfContent, unsigned int lgth)
798 {
799   return new ArrayAny(typeOfContent,lgth);
800 }
801
802 void ArrayAny::putMyReprAtPlace(char *data) const
803 {
804   const TypeCode *subType=_type->contentType();
805   unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
806   for(unsigned i=0;i<((const TypeCodeArray *)_type)->getStaticLgth();i++)
807     subType->putReprAtPlace(data+i*sizePerContent,_data+i*sizePerContent,false);
808 }
809
810 void ArrayAny::putReprAtPlace(char *data, const char *src, const TypeCodeArray *type, bool deepCpy)
811 {
812   const TypeCode *subType=type->contentType();
813   unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
814   for(unsigned i=0;i<type->getStaticLgth();i++)
815     subType->putReprAtPlace(data+i*sizePerContent,src+i*sizePerContent,deepCpy);
816 }
817
818 void ArrayAny::destroyReprAtPlace(char *data, const TypeCodeArray *type)
819 {
820   const TypeCode *subType=type->contentType();
821   unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
822   for(unsigned i=0;i<type->getStaticLgth();i++)
823     subType->destroyZippedAny(data+i*sizePerContent);
824 }
825
826 AnyPtr ArrayAny::getOrBuildFromData(char *data, const TypeCodeArray *type)
827 {
828   Any *ret;
829   ret=new ArrayAny(data,(TypeCodeArray *)type);
830   return AnyPtr(ret);
831 }
832
833 bool ArrayAny::takeInChargeStorageOf(TypeCode *type)
834 {
835   DynType typ=type->kind();
836   return (typ==Array);
837 }
838
839 Any *StructAny::clone() const
840 {
841   return new StructAny(*this);
842 }
843
844 bool StructAny::operator ==(const Any& other) const
845 {
846   if(!_type->isA(other.getType()))
847     return false;
848   const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
849   vector< pair<string,TypeCode*> >::const_iterator iter;
850   for(iter=typeC->_members.begin();iter!=typeC->_members.end();iter++)
851     if(!((*(*this)[(*iter).first.c_str()]==(*other[(*iter).first.c_str()]))))
852       return false;
853   return true;
854 }
855
856 AnyPtr StructAny::operator[](int i) const throw(YACS::Exception)
857 {
858   const char what[]="StructAny::operator[](int i) : Struct key are strings not integers.";
859   throw Exception(what);
860 }
861
862 AnyPtr StructAny::operator[](const char *key) const throw(YACS::Exception)
863 {
864   const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
865   char *whereToGet=_data;
866   vector< pair<string,TypeCode*> >::const_iterator iter;
867   for(iter=typeC->_members.begin();iter!=typeC->_members.end();iter++)
868     if((*iter).first!=key)
869       whereToGet+=(*iter).second->getSizeInByteOfAnyReprInSeq();
870     else
871       break;
872   if(iter==typeC->_members.end())
873     {
874       string what("Unexisting key \""); what+=key; what+="\" for struct extraction.";
875       throw Exception(what);
876     }
877   return (*iter).second->getOrBuildAnyFromZippedData(whereToGet);
878 }
879
880 void StructAny::setEltAtRank(int i, const Any *elem) throw(YACS::Exception)
881 {
882   const char what[]="Struct key are strings not integers.";
883   throw Exception(what);
884 }
885
886 void StructAny::setEltAtRank(const char *key, const Any *elem) throw(YACS::Exception)
887 {
888   const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
889   unsigned offset;
890   const TypeCode *tcOnKey=typeC->getMember(key,offset);
891   if(!tcOnKey)
892     throw Exception("StructAny::setEltAtRank : invalid key given.");
893   if(!elem->getType()->isA(tcOnKey))
894     throw Exception("StructAny::setEltAtRank : invalid data type on the specified given key.");
895   tcOnKey->destroyZippedAny(_data+offset);
896   elem->putMyReprAtPlace(_data+offset);
897 }
898
899 void StructAny::putMyReprAtPlace(char *data) const
900 {
901   const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
902   unsigned offset=0;
903   vector< pair<string,TypeCode*> >::const_iterator iter;
904   for(iter=typeC->_members.begin();iter!=typeC->_members.end();iter++)
905     {
906       (*iter).second->putReprAtPlace(data+offset,_data+offset,false);
907       offset+=(*iter).second->getSizeInByteOfAnyReprInSeq();
908     }
909 }
910
911 void StructAny::putReprAtPlace(char *data, const char *src, const TypeCodeStruct *type, bool deepCpy)
912 {
913   unsigned offset=0;
914   vector< pair<string,TypeCode*> >::const_iterator iter;
915   for(iter=type->_members.begin();iter!=type->_members.end();iter++)
916     {
917       (*iter).second->putReprAtPlace(data+offset,src+offset,deepCpy);
918       offset+=(*iter).second->getSizeInByteOfAnyReprInSeq();
919     }
920 }
921
922 void StructAny::destroyReprAtPlace(char *data, const TypeCodeStruct *type)
923 {
924   char *whereToGet=data;
925   vector< pair<string,TypeCode*> >::const_iterator iter;
926   for(iter=type->_members.begin();iter!=type->_members.end();iter++)
927     {
928       (*iter).second->destroyZippedAny(whereToGet);
929       whereToGet+=(*iter).second->getSizeInByteOfAnyReprInSeq();
930     }
931 }
932
933 AnyPtr StructAny::getOrBuildFromData(char *data, const TypeCodeStruct *type)
934 {
935   Any *ret;
936   ret=new StructAny(data,(TypeCodeStruct *)type);
937   return AnyPtr(ret);
938 }
939
940 StructAny::~StructAny()
941 {
942   const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
943   vector< pair<string,TypeCode*> >::const_iterator iter;
944   char *whereToGet=_data;
945   for(iter=typeC->_members.begin();iter!=typeC->_members.end();iter++)
946     {
947       (*iter).second->destroyZippedAny(whereToGet);
948       whereToGet+=(*iter).second->getSizeInByteOfAnyReprInSeq();
949     }
950   delete [] _data;
951 }
952
953 StructAny::StructAny(TypeCodeStruct *type):ComposedAny(type,false)
954 {
955   _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
956   for(unsigned int i=0;i<_type->getSizeInByteOfAnyReprInSeq();i++)
957     _data[i]='\0';
958 }
959
960 StructAny::StructAny(const StructAny& other):ComposedAny(other)
961 {
962   _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
963   const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
964   vector< pair<string,TypeCode*> >::const_iterator iter;
965   unsigned offset=0;
966   for(iter=typeC->_members.begin();iter!=typeC->_members.end();iter++)
967     {
968      (*iter).second->putReprAtPlace(_data+offset,other._data+offset,true);
969      offset+=(*iter).second->getSizeInByteOfAnyReprInSeq();
970     }
971 }
972
973 StructAny::StructAny(char *data, TypeCodeStruct * type):ComposedAny(type,false),_data(0)
974 {
975   _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
976   vector< pair<string,TypeCode*> >::const_iterator iter;
977   unsigned offset=0;
978   for(iter=type->_members.begin();iter!=type->_members.end();iter++)
979     {
980       (*iter).second->putReprAtPlace(_data+offset,data+offset,false);
981       offset+=(*iter).second->getSizeInByteOfAnyReprInSeq();
982     }
983 }
984
985 StructAny *StructAny::New(TypeCodeStruct *type)
986 {
987   return new StructAny(type);
988 }