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