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