1 // Copyright (C) 2006-2019 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #include "Runtime.hxx"
22 #include "TypeCode.hxx"
23 #include "InvalidExtractionException.hxx"
25 #include <boost/archive/iterators/base64_from_binary.hpp>
26 #include <boost/archive/iterators/binary_from_base64.hpp>
27 #include <boost/archive/iterators/transform_width.hpp>
28 #include <boost/archive/iterators/insert_linebreaks.hpp>
29 #include <boost/archive/iterators/remove_whitespace.hpp>
35 using namespace YACS::ENGINE;
38 // forbidden value int=-269488145 double=-1.54947e+231 bool=239
39 const char SeqAlloc::DFT_CHAR_VAR=-17;//0xEF
41 std::string YACS::ENGINE::ToBase64(const std::string& bytes)
43 std::string input(bytes);
44 // The input must be in multiples of 3, otherwise the transformation
45 // may overflow the input buffer, so pad with zero.
46 size_t num_pad_chars((3 - input.size() % 3) % 3);
47 input.append(num_pad_chars, 0);
49 // Transform to Base64 with line breaks every 76 characters
50 using namespace boost::archive::iterators;
51 typedef insert_linebreaks<base64_from_binary<transform_width<std::string::const_iterator, 6, 8> >, 76> ItBase64T;
52 std::string output(ItBase64T(input.begin()), ItBase64T(input.end() - num_pad_chars));
54 // Pad blank characters with '='
55 output.append(num_pad_chars, '=');
60 std::string YACS::ENGINE::FromBase64(const std::string& base64Str)
62 std::string input(base64Str);
63 using namespace boost::archive::iterators;
64 typedef transform_width<binary_from_base64<remove_whitespace<std::string::const_iterator> >, 8, 6> ItBinaryT;
68 // If the input isn't a multiple of 4, pad with =
69 size_t num_pad_chars((4 - input.size() % 4) % 4);
70 input.append(num_pad_chars, '=');
72 size_t pad_chars(std::count(input.begin(), input.end(), '='));
73 std::replace(input.begin(), input.end(), '=', 'A');
74 std::string output(ItBinaryT(input.begin()), ItBinaryT(input.end()));
75 output.erase(output.end() - pad_chars, output.end());
78 catch (std::exception const&)
84 StringOnHeap::StringOnHeap(const char *val):_str(strdup(val)),_len(strlen(val)),_dealloc(0)
88 StringOnHeap::StringOnHeap(const char *val, std::size_t len):_dealloc(0),_len(len)
90 _str=(char *)malloc(len+1);
91 std::copy(val,val+len,_str);
95 StringOnHeap::StringOnHeap(const std::string& val):_dealloc(0),_len(val.size()),_str(nullptr)
97 _str=(char *)malloc(val.size()+1);
98 std::copy(val.cbegin(),val.cend(),_str);
99 _str[val.size()]='\0';
103 * \note : no copy is performed if a deallocator is given.
104 * \param val : String in C format that is NOT copied if
106 * \param deAlloc : pointer on function to deallocate val after
109 StringOnHeap::StringOnHeap(char *val, Deallocator deAlloc):_len(0),_dealloc(deAlloc)
117 bool StringOnHeap::operator ==(const StringOnHeap& other) const
119 return strcmp(_str, other._str)==0;
122 StringOnHeap *StringOnHeap::deepCopy() const
125 return new StringOnHeap(_str);
127 return new StringOnHeap(_str,_len);
130 StringOnHeap::~StringOnHeap()
138 Any::Any(TypeCode* type):_type(type)
143 Any::Any(const Any& other):_type(other._type)
153 bool Any::IsNull(char *data)
158 for(std::size_t i=0;i<sizeof(void *) && isNull;i++)
159 isNull=(data[i]==SeqAlloc::DFT_CHAR_VAR);
163 AtomAny::AtomAny(int val):Any(Runtime::_tc_int)
168 AtomAny::AtomAny(bool val):Any(Runtime::_tc_bool)
173 AtomAny::AtomAny(double val):Any(Runtime::_tc_double)
178 AtomAny::AtomAny(const char *val):Any(Runtime::_tc_string)
180 _value._s=new StringOnHeap(val);
183 AtomAny::AtomAny(const std::string& val):Any(Runtime::_tc_string)
185 _value._s=new StringOnHeap(val);
188 AtomAny::AtomAny(const AtomAny& other):Any(other)
190 if(_type->isA(Runtime::_tc_string))
192 StringOnHeap *cpy=(other._value._s)->deepCopy();
193 memcpy(&_value._s,&cpy,_type->getSizeInByteOfAnyReprInSeq());
195 else if(_type->isA(Runtime::_tc_double))
196 memcpy(&_value._d,&other._value._d,_type->getSizeInByteOfAnyReprInSeq());
197 else if(_type->isA(Runtime::_tc_int))
198 memcpy(&_value._i,&other._value._i,_type->getSizeInByteOfAnyReprInSeq());
199 else if(_type->isA(Runtime::_tc_bool))
200 memcpy(&_value._b,&other._value._b,_type->getSizeInByteOfAnyReprInSeq());
203 AtomAny::AtomAny(char *val, Deallocator deAlloc):Any(Runtime::_tc_string)
205 _value._s=new StringOnHeap(val,deAlloc);
208 AtomAny::AtomAny(char *data, TypeCode* type):Any(type)
210 if(type->isA(Runtime::_tc_string))
212 void **tmp=(void **)data;
213 StringOnHeap *cpy=((StringOnHeap *)(*tmp))->deepCopy();
214 memcpy(&_value._s,&cpy,type->getSizeInByteOfAnyReprInSeq());
216 else if(type->isA(Runtime::_tc_double))
217 memcpy(&_value._d,data,type->getSizeInByteOfAnyReprInSeq());
218 else if(type->isA(Runtime::_tc_int))
219 memcpy(&_value._i,data,type->getSizeInByteOfAnyReprInSeq());
220 else if(type->isA(Runtime::_tc_bool))
221 memcpy(&_value._b,data,type->getSizeInByteOfAnyReprInSeq());
224 Any *AtomAny::clone() const
226 return new AtomAny(*this);
229 AtomAny *AtomAny::New(char *val,Deallocator dealloc)
231 return new AtomAny(val,dealloc);
234 AnyPtr AtomAny::operator[](int i) const throw(YACS::Exception)
236 throw InvalidExtractionException(_type->kind(),Sequence);
239 AnyPtr AtomAny::operator[](const char *key) const throw(YACS::Exception)
241 throw Exception("AtomAny::operator[] : try to get a part of a partitionned data whereas atomical.");
244 bool AtomAny::operator ==(const Any& other) const
246 if(!_type->isA(other.getType()))
248 const AtomAny& otherC=(const AtomAny&) other;//cast granted due to previous lines
249 if(_type->isA(Runtime::_tc_double))
250 return _value._d==otherC._value._d;
251 else if(_type->isA(Runtime::_tc_int))
252 return _value._i==otherC._value._i;
253 else if(_type->isA(Runtime::_tc_bool))
254 return _value._b==otherC._value._b;
255 else if(_type->isA(Runtime::_tc_string))
256 return (*_value._s)==*(otherC._value._s);
261 int AtomAny::getIntValue() const throw(YACS::Exception)
263 if(_type->isA(Runtime::_tc_int))
266 throw Exception("Value is not an int");
269 bool AtomAny::getBoolValue() const throw(YACS::Exception)
271 if(_type->isA(Runtime::_tc_bool))
274 throw Exception("Value is not a bool");
277 double AtomAny::getDoubleValue() const throw(YACS::Exception)
279 if(_type->isA(Runtime::_tc_double))
282 throw Exception("Value is not a double");
285 std::string AtomAny::getStringValue() const throw(YACS::Exception)
287 if(_type->isA(Runtime::_tc_string))
289 std::size_t sz(_value._s->size());
291 return string(_value._s->cStr());
293 return string(_value._s->cStr(),sz);
296 throw Exception("Value is not a string");
299 const char *AtomAny::getBytesValue(std::size_t& len) const
301 if(_type->isA(Runtime::_tc_string))
303 len=_value._s->size();
304 return _value._s->cStr();
307 throw Exception("Value is not a string");
311 * \note : This method put in data its zipped recursive content in data.
312 * The ownership of the recursive content is tranfered to data.
313 * So this owns nothing and its counter fall by 1.
314 * For memory space minimal use, not all of '*this' is pushed at data location.
315 * \param data : already allocated memory zone where to put compressed content of 'this'
317 void AtomAny::putMyReprAtPlace(char *data) const
319 if(_type->isA(Runtime::_tc_string))
321 StringOnHeap *tmp=_value._s->deepCopy();
322 memcpy(data,&tmp,_type->getSizeInByteOfAnyReprInSeq());
324 else if(_type->isA(Runtime::_tc_double))
325 memcpy(data,&_value._d,_type->getSizeInByteOfAnyReprInSeq());
326 else if(_type->isA(Runtime::_tc_int))
327 memcpy(data,&_value._i,_type->getSizeInByteOfAnyReprInSeq());
328 else if(_type->isA(Runtime::_tc_bool))
329 memcpy(data,&_value._b,_type->getSizeInByteOfAnyReprInSeq());
333 * \note : This method put in data its zipped recursive content in data.
334 * The ownership of the recursive content is tranfered to data.
335 * So this owns nothing and its counter fall by 1.
336 * For memory space minimal use, not all of '*this' is pushed at data location.
337 * 'deepCpy' param is not used here because by definition of AtomAny deep copy is performed.
338 * \param data : already allocated memory zone where to put compressed content of 'this'
343 void AtomAny::putReprAtPlace(char *data, const char *src, const TypeCode *type, bool deepCpy)
345 if(type->isA(Runtime::_tc_string))
347 void **tmp1=(void **)src;
348 StringOnHeap *tmp=((const StringOnHeap *)(*tmp1))->deepCopy();
349 memcpy(data,&tmp,type->getSizeInByteOfAnyReprInSeq());
351 else if(type->isA(Runtime::_tc_double))
352 memcpy(data,src,type->getSizeInByteOfAnyReprInSeq());
353 else if(type->isA(Runtime::_tc_int))
354 memcpy(data,src,type->getSizeInByteOfAnyReprInSeq());
355 else if(type->isA(Runtime::_tc_bool))
356 memcpy(data,src,type->getSizeInByteOfAnyReprInSeq());
360 * \note : Opposite method of putMyReprAtPlace. But static because due to data compression
363 void AtomAny::destroyReprAtPlace(char *data, const TypeCode *type)
365 DynType typ=type->kind();
368 if(!Any::IsNull(data))
370 void **tmp=(void **)data;
371 delete ((StringOnHeap *)(*tmp));
376 AnyPtr AtomAny::getOrBuildFromData(char *data, const TypeCode *type)
379 ret=new AtomAny(data,(TypeCode *)type);
383 bool AtomAny::takeInChargeStorageOf(TypeCode *type)
385 DynType typ=type->kind();
386 return (typ==Double || typ==Int || typ==Bool || typ==String);
391 if(_type->kind() == String)
395 ComposedAny::ComposedAny(const ComposedAny& other):Any(other)
399 ComposedAny::ComposedAny(TypeCode* type, bool isNew):Any(type)
405 AnyPtr ComposedAny::operator[](const char *key) const throw(YACS::Exception)
407 throw Exception("AtomAny::operator[] : try to get a part of a partitionned data not localizable by a string.");
410 void ComposedAny::checkTypeOf(const Any *elem) const throw(YACS::Exception)
412 if(!elem->getType()->isA(_type->contentType()))
413 throw Exception("ComposedAny::checkTypeOf : invalid type.");
416 int ComposedAny::getIntValue() const throw(YACS::Exception)
418 throw InvalidExtractionException(_type->kind(),Runtime::_tc_int->kind());
421 bool ComposedAny::getBoolValue() const throw(YACS::Exception)
423 throw InvalidExtractionException(_type->kind(),Runtime::_tc_bool->kind());
426 double ComposedAny::getDoubleValue() const throw(YACS::Exception)
428 throw InvalidExtractionException(_type->kind(),Runtime::_tc_double->kind());
431 std::string ComposedAny::getStringValue() const throw(YACS::Exception)
433 throw InvalidExtractionException(_type->kind(),Runtime::_tc_string->kind());
436 SeqAlloc::SeqAlloc(const SeqAlloc& other):_sizeOf1Elm(other._sizeOf1Elm),_notStdDeAlloc(0),
437 _start(0),_finish(0),_endOfStorage(0)
439 _start=allocate(other._finish-other._start);
440 _finish=_start+(other._finish-other._start);
441 _endOfStorage=_finish;
444 SeqAlloc::SeqAlloc(unsigned int sizeOf1Elm):_sizeOf1Elm(sizeOf1Elm),_notStdDeAlloc(0),
445 _start(0),_finish(0),_endOfStorage(0)
449 SeqAlloc::~SeqAlloc()
454 void SeqAlloc::clear()
463 * \note : This method is exclusively reserved for arrays of C++ built-in types because no
464 * constructor is applied atomically.
466 void SeqAlloc::initCoarseMemory(char *mem, unsigned int size, Deallocator dealloc)
468 unsigned sizeInByte=size*_sizeOf1Elm;
471 _notStdDeAlloc=dealloc;
476 _start=allocate(sizeInByte);
478 memcpy(_start,mem,sizeInByte);
481 for(unsigned int i=0;i<sizeInByte;i++) _start[i]=DFT_CHAR_VAR;// see getSetItems
484 _finish=_start+sizeInByte;
485 _endOfStorage=_finish;
488 void SeqAlloc::construct(char *pt, const Any *val)
490 val->putMyReprAtPlace(pt);
494 * \note: This performs the placement new or zip info into pt.
496 * \param val : the source from which the construction will be performed.
498 * \param deepCpy : If true in pt place a deep copy pointed by val will be put.
500 void SeqAlloc::construct(char *pt, const char *val, const TypeCode *tc, bool deepCpy)
502 tc->putReprAtPlace(pt,val,deepCpy);
505 char *SeqAlloc::allocate(unsigned int nbOfByte)
508 return (char *)::operator new(nbOfByte);
513 // pt is not permitted to be a null pointer.
514 void SeqAlloc::deallocate(char *pt)
519 ::operator delete(pt);
528 void SeqAlloc::destroy(char *pt, const TypeCode *tc)
530 tc->destroyZippedAny(pt);
533 unsigned int SeqAlloc::size() const
535 return (_finish-_start)/_sizeOf1Elm;
538 std::vector<unsigned int> SeqAlloc::getSetItems() const
540 std::vector<unsigned int> ret;
541 unsigned int sz(size());
542 for(unsigned int i=0;i<sz;i++)
544 const char *pt(_start+i*_sizeOf1Elm);
545 for(unsigned j=0;j<_sizeOf1Elm && *pt==DFT_CHAR_VAR;j++,pt++); //see initCoarseMemory
546 if(pt!=_start+(i+1)*_sizeOf1Elm)
552 void SequenceAny::clear()
554 for (char *cur=_alloc._start;cur!=_alloc._finish;cur+=_alloc._sizeOf1Elm)
555 _alloc.destroy(cur,_type->contentType());
559 void SequenceAny::popBack()
561 _alloc._finish-=_alloc._sizeOf1Elm;
562 _alloc.destroy(_alloc._finish,_type->contentType());
565 void SequenceAny::pushBack(const Any* elem)
567 if(!elem->_type->isA(_type->contentType()))
568 throw InvalidExtractionException(elem->_type->kind(),_type->contentType()->kind());
569 if(_alloc._finish != _alloc._endOfStorage)
571 _alloc.construct(_alloc._finish, elem);
572 _alloc._finish+=_alloc._sizeOf1Elm;
575 realloc(_alloc._finish, elem);
578 bool SequenceAny::operator ==(const Any& other) const
580 if(!_type->isA(other.getType()))
582 const SequenceAny& otherC=(const SequenceAny&) other;//cast granted due to previous lines
583 if(size()!=otherC.size())
585 for(unsigned i=0;i<size();i++)
586 if(!((*(*this)[i])==(*otherC[i])))
591 void SequenceAny::setEltAtRank(int i, const Any *elem) throw(YACS::Exception)
594 _alloc.destroy(_alloc._start+i*_alloc._sizeOf1Elm,_type->contentType());
595 _alloc.construct(_alloc._start+i*_alloc._sizeOf1Elm,elem);
598 AnyPtr SequenceAny::operator[](int i) const throw(YACS::Exception)
600 return _type->contentType()->getOrBuildAnyFromZippedData(_alloc._start+i*_alloc._sizeOf1Elm);
604 * \note : Contrary to AtomAny 'this' (ref) is put in data NOT a deep copy.
605 * \param data : already allocated memory zone where to put address of 'this'
607 void SequenceAny::putMyReprAtPlace(char *data) const
609 const void *tmp=(const void *)this;
610 memcpy(data,&tmp,_type->getSizeInByteOfAnyReprInSeq());
611 const void **tmp2=(const void **) data;
612 ((SequenceAny *)(*tmp2))->incrRef();
613 //::new((SequenceAny *)data) SequenceAny((SequenceAny&) (*this));
616 void SequenceAny::putReprAtPlace(char *data, const char *src, const TypeCode *type, bool deepCpy)
618 void **tmp2=(void **) src;
621 ((SequenceAny *)(*tmp2))->incrRef();
622 memcpy(data,src,type->getSizeInByteOfAnyReprInSeq());
626 SequenceAny *cpy=new SequenceAny(*((SequenceAny *)(*tmp2)));
627 memcpy(data,&cpy,type->getSizeInByteOfAnyReprInSeq());
629 //::new((SequenceAny *)data) SequenceAny((SequenceAny&) (*this));
632 void SequenceAny::destroyReprAtPlace(char *data, const TypeCode *type)
634 void **tmp=(void **) data;
635 if(!Any::IsNull(data))
636 ((SequenceAny *)(*tmp))->decrRef();
637 //((SequenceAny *)data)->~SequenceAny();
640 AnyPtr SequenceAny::getOrBuildFromData(char *data, const TypeCode *type)
642 void **tmp=(void **) data;
643 ((SequenceAny *) (*tmp))->incrRef();
644 return AnyPtr((SequenceAny *)(*tmp));
647 Any *SequenceAny::clone() const
649 return new SequenceAny(*this);
652 SequenceAny *SequenceAny::removeUnsetItemsFromThis() const
654 std::vector<unsigned int> its(getSetItems());
655 std::size_t sz(its.size());
656 SequenceAny *ret(SequenceAny::New(getType()->contentType(),sz));
657 for(std::size_t i=0;i<sz;i++)
659 AnyPtr obj((*this)[its[i]]);
660 ret->setEltAtRank(i,obj);
665 SequenceAny *SequenceAny::New(const TypeCode *typeOfContent)
667 if(typeOfContent->kind() == Objref)
669 //In case of Objref, use a sequence of string
670 return new SequenceAny(Runtime::_tc_string);
673 return new SequenceAny(typeOfContent);
676 SequenceAny *SequenceAny::New(const TypeCode *typeOfContent, unsigned lgth)
678 if(typeOfContent->kind() == Objref)
680 //In case of Objref, use a sequence of string
681 return new SequenceAny(Runtime::_tc_string,lgth);
684 return new SequenceAny(typeOfContent,lgth);
687 bool SequenceAny::takeInChargeStorageOf(TypeCode *type)
689 DynType typ=type->kind();
690 return (typ==Sequence);
693 SequenceAny::SequenceAny(const SequenceAny& other):ComposedAny(other),_alloc(other._alloc)
695 const char *srcCur=other._alloc._start;
696 for(char *cur=_alloc._start;srcCur != other._alloc._finish; srcCur+=_alloc._sizeOf1Elm, cur+=_alloc._sizeOf1Elm)
697 _alloc.construct(cur, srcCur, _type->contentType(),true);
700 SequenceAny::~SequenceAny()
702 for (char *cur=_alloc._start;cur!=_alloc._finish;cur+=_alloc._sizeOf1Elm)
703 _alloc.destroy(cur,_type->contentType());
707 * \param typeOfContent : typeCode of the type of elements stored in sequence.
709 SequenceAny::SequenceAny(const TypeCode *typeOfContent):ComposedAny(new TypeCodeSeq("","",typeOfContent)),
710 _alloc(typeOfContent->getSizeInByteOfAnyReprInSeq())
714 SequenceAny::SequenceAny(const TypeCode *typeOfContent, unsigned lgth):ComposedAny(new TypeCodeSeq("","",typeOfContent)),
715 _alloc(typeOfContent->getSizeInByteOfAnyReprInSeq())
717 _alloc.initCoarseMemory(0,lgth,0);
720 SequenceAny::SequenceAny(int *val, unsigned int lgth, Deallocator deAlloc):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_int)),
721 _alloc(Runtime::_tc_int->getSizeInByteOfAnyReprInSeq())
723 _alloc.initCoarseMemory((char *)val,lgth,deAlloc);
726 SequenceAny::SequenceAny(bool *val, unsigned int lgth, Deallocator deAlloc):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_bool)),
727 _alloc(Runtime::_tc_bool->getSizeInByteOfAnyReprInSeq())
729 _alloc.initCoarseMemory((char *)val,lgth,deAlloc);
732 SequenceAny::SequenceAny(double *val, unsigned int lgth, Deallocator deAlloc):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_double)),
733 _alloc(Runtime::_tc_double->getSizeInByteOfAnyReprInSeq())
735 _alloc.initCoarseMemory((char *)val,lgth,deAlloc);
738 SequenceAny::SequenceAny(const std::vector<int>& val):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_int)),
739 _alloc(Runtime::_tc_int->getSizeInByteOfAnyReprInSeq())
741 _alloc.initCoarseMemory((char *)&val[0],val.size(),0);
744 SequenceAny::SequenceAny(const std::vector<bool>& val):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_bool)),
745 _alloc(Runtime::_tc_bool->getSizeInByteOfAnyReprInSeq())
747 for(vector<bool>::const_iterator iter=val.begin();iter!=val.end();iter++)
749 AtomAnyPtr tmp=AtomAny::New(*iter);
754 SequenceAny::SequenceAny(const std::vector<double>& val):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_double)),
755 _alloc(Runtime::_tc_double->getSizeInByteOfAnyReprInSeq())
757 _alloc.initCoarseMemory((char *)&val[0],val.size(),0);
760 SequenceAny::SequenceAny(const std::vector<std::string>& val):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_string)),
761 _alloc(Runtime::_tc_string->getSizeInByteOfAnyReprInSeq())
763 for(vector<string>::const_iterator iter=val.begin();iter!=val.end();iter++)
765 AtomAnyPtr tmp=AtomAny::New(*iter);
770 void SequenceAny::realloc(char *endOfCurrentAllocated, const Any *elem)
772 unsigned int oldSize=_alloc._finish-_alloc._start;
773 unsigned int newSize = oldSize != 0 ? 2 * oldSize : _alloc._sizeOf1Elm;
774 char *newStart=_alloc.allocate(newSize);
776 char *newFinish=performCpy(_alloc._start, endOfCurrentAllocated,newStart);
777 _alloc.construct(newFinish, elem);
778 newFinish+=_alloc._sizeOf1Elm;
779 newFinish=performCpy(endOfCurrentAllocated, _alloc._finish, newFinish);
781 for (char *cur=_alloc._start;cur!=_alloc._finish;cur+=_alloc._sizeOf1Elm)
782 _alloc.destroy(cur,_type->contentType());
783 _alloc.deallocate(_alloc._start);
784 _alloc._start = newStart;
785 _alloc._finish = newFinish;
786 _alloc._endOfStorage=newStart+newSize;
789 char *SequenceAny::performCpy(char *srcStart, char *srcFinish, char *destStart)
792 for (;srcStart != srcFinish; srcStart+=_alloc._sizeOf1Elm, cur+=_alloc._sizeOf1Elm)
793 _alloc.construct(cur, srcStart, _type->contentType(),false);
797 ArrayAny::~ArrayAny()
799 const TypeCode *subType=_type->contentType();
800 unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
801 unsigned int size=((TypeCodeArray *)_type)->getStaticLgth();
803 for(unsigned i=0;i<size;i++,tmp+=sizePerContent)
804 subType->destroyZippedAny(tmp);
808 ArrayAny::ArrayAny(const TypeCode *typeOfContent, unsigned int lgth):ComposedAny(new TypeCodeArray("","",typeOfContent,lgth))
810 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
811 for(unsigned int i=0;i<_type->getSizeInByteOfAnyReprInSeq();i++)
812 _data[i]=SeqAlloc::DFT_CHAR_VAR;
815 ArrayAny::ArrayAny(char *data, TypeCodeArray * type):ComposedAny(type,false),_data(0)
817 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
818 const TypeCode *subType=_type->contentType();
819 unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
820 for(unsigned i=0;i<type->getStaticLgth();i++)
821 subType->putReprAtPlace(_data+i*sizePerContent,data+i*sizePerContent,false);
824 ArrayAny::ArrayAny(const ArrayAny& other):ComposedAny(other)
826 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
827 const TypeCode *subType=_type->contentType();
828 unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
829 for(unsigned i=0;i<((TypeCodeArray *)_type)->getStaticLgth();i++)
830 subType->putReprAtPlace(_data+i*sizePerContent,other._data+i*sizePerContent,true);
833 ArrayAny::ArrayAny(const int *val, unsigned int lgth):ComposedAny(new TypeCodeArray("","",Runtime::_tc_int,lgth)),
836 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
837 memcpy(_data,val,_type->getSizeInByteOfAnyReprInSeq());
840 ArrayAny::ArrayAny(const bool *val, unsigned int lgth):ComposedAny(new TypeCodeArray("","",Runtime::_tc_bool,lgth)),
843 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
844 memcpy(_data,val,_type->getSizeInByteOfAnyReprInSeq());
847 ArrayAny::ArrayAny(const double *val, unsigned int lgth):ComposedAny(new TypeCodeArray("","",Runtime::_tc_double,lgth)),
850 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
851 memcpy(_data,val,_type->getSizeInByteOfAnyReprInSeq());
854 ArrayAny::ArrayAny(const std::vector<int>& val):ComposedAny(new TypeCodeArray("","",Runtime::_tc_int,val.size())),
857 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
858 memcpy(_data,&val[0],_type->getSizeInByteOfAnyReprInSeq());
861 ArrayAny::ArrayAny(const std::vector<double>& val):ComposedAny(new TypeCodeArray("","",Runtime::_tc_double,val.size())),
864 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
865 memcpy(_data,&val[0],_type->getSizeInByteOfAnyReprInSeq());
868 ArrayAny::ArrayAny(const std::vector<std::string>& val):ComposedAny(new TypeCodeArray("","",Runtime::_tc_string,val.size())),
871 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
873 const TypeCode *subType=_type->contentType();
874 unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
875 for(vector<std::string>::const_iterator iter=val.begin();iter!=val.end();iter++,i++)
877 StringOnHeap *st=new StringOnHeap(*iter);
878 memcpy(_data+i*sizePerContent,&st,sizePerContent);
882 void ArrayAny::setEltAtRank(int i, const Any *elem) throw(YACS::Exception)
885 const TypeCode *subType=_type->contentType();
886 subType->destroyZippedAny(_data+i*subType->getSizeInByteOfAnyReprInSeq());
887 elem->putMyReprAtPlace(_data+i*subType->getSizeInByteOfAnyReprInSeq());
890 bool ArrayAny::operator ==(const Any& other) const
892 if(!_type->isA(other.getType()))
894 const ArrayAny& otherC=(const ArrayAny&) other;//cast granted due to previous lines
895 for(unsigned i=0;i<((const TypeCodeArray *)_type)->getStaticLgth();i++)
896 if(!((*(*this)[i])==(*otherC[i])))
901 AnyPtr ArrayAny::operator[](int i) const throw(YACS::Exception)
903 const TypeCode *subType=_type->contentType();
904 unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
905 if(i<0 || i>=((TypeCodeArray *)_type)->getStaticLgth())
906 throw Exception("Trying to access to an invalid index in an Any Tuple");
907 return _type->contentType()->getOrBuildAnyFromZippedData(_data+i*sizePerContent);
910 unsigned int ArrayAny::size() const
912 return ((TypeCodeArray *)_type)->getStaticLgth();
915 Any *ArrayAny::clone() const
917 return new ArrayAny(*this);
920 ArrayAny *ArrayAny::New(const TypeCode *typeOfContent, unsigned int lgth)
922 return new ArrayAny(typeOfContent,lgth);
925 void ArrayAny::putMyReprAtPlace(char *data) const
927 const TypeCode *subType=_type->contentType();
928 unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
929 for(unsigned i=0;i<((const TypeCodeArray *)_type)->getStaticLgth();i++)
930 subType->putReprAtPlace(data+i*sizePerContent,_data+i*sizePerContent,false);
933 void ArrayAny::putReprAtPlace(char *data, const char *src, const TypeCodeArray *type, bool deepCpy)
935 const TypeCode *subType=type->contentType();
936 unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
937 for(unsigned i=0;i<type->getStaticLgth();i++)
938 subType->putReprAtPlace(data+i*sizePerContent,src+i*sizePerContent,deepCpy);
941 void ArrayAny::destroyReprAtPlace(char *data, const TypeCodeArray *type)
943 const TypeCode *subType=type->contentType();
944 unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
945 for(unsigned i=0;i<type->getStaticLgth();i++)
946 subType->destroyZippedAny(data+i*sizePerContent);
949 AnyPtr ArrayAny::getOrBuildFromData(char *data, const TypeCodeArray *type)
952 ret=new ArrayAny(data,(TypeCodeArray *)type);
956 bool ArrayAny::takeInChargeStorageOf(TypeCode *type)
958 DynType typ=type->kind();
962 Any *StructAny::clone() const
964 return new StructAny(*this);
967 bool StructAny::operator ==(const Any& other) const
969 if(!_type->isA(other.getType()))
971 const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
972 vector< pair<string,TypeCode*> >::const_iterator iter;
973 for(iter=typeC->_members.begin();iter!=typeC->_members.end();iter++)
974 if(!((*(*this)[(*iter).first.c_str()]==(*other[(*iter).first.c_str()]))))
979 AnyPtr StructAny::operator[](int i) const throw(YACS::Exception)
981 const char what[]="StructAny::operator[](int i) : Struct key are strings not integers.";
982 throw Exception(what);
985 AnyPtr StructAny::operator[](const char *key) const throw(YACS::Exception)
987 const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
988 char *whereToGet=_data;
989 vector< pair<string,TypeCode*> >::const_iterator iter;
990 for(iter=typeC->_members.begin();iter!=typeC->_members.end();iter++)
991 if((*iter).first!=key)
992 whereToGet+=(*iter).second->getSizeInByteOfAnyReprInSeq();
995 if(iter==typeC->_members.end())
997 string what("Unexisting key \""); what+=key; what+="\" for struct extraction.";
998 throw Exception(what);
1000 return (*iter).second->getOrBuildAnyFromZippedData(whereToGet);
1003 void StructAny::setEltAtRank(int i, const Any *elem) throw(YACS::Exception)
1005 const char what[]="Struct key are strings not integers.";
1006 throw Exception(what);
1009 void StructAny::setEltAtRank(const char *key, const Any *elem) throw(YACS::Exception)
1011 const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
1013 const TypeCode *tcOnKey=typeC->getMember(key,offset);
1015 throw Exception("StructAny::setEltAtRank : invalid key given.");
1016 if(!elem->getType()->isA(tcOnKey))
1017 throw Exception("StructAny::setEltAtRank : invalid data type on the specified given key.");
1018 tcOnKey->destroyZippedAny(_data+offset);
1019 elem->putMyReprAtPlace(_data+offset);
1022 void StructAny::putMyReprAtPlace(char *data) const
1024 const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
1026 vector< pair<string,TypeCode*> >::const_iterator iter;
1027 for(iter=typeC->_members.begin();iter!=typeC->_members.end();iter++)
1029 (*iter).second->putReprAtPlace(data+offset,_data+offset,false);
1030 offset+=(*iter).second->getSizeInByteOfAnyReprInSeq();
1034 void StructAny::putReprAtPlace(char *data, const char *src, const TypeCodeStruct *type, bool deepCpy)
1037 vector< pair<string,TypeCode*> >::const_iterator iter;
1038 for(iter=type->_members.begin();iter!=type->_members.end();iter++)
1040 (*iter).second->putReprAtPlace(data+offset,src+offset,deepCpy);
1041 offset+=(*iter).second->getSizeInByteOfAnyReprInSeq();
1045 void StructAny::destroyReprAtPlace(char *data, const TypeCodeStruct *type)
1047 char *whereToGet=data;
1048 vector< pair<string,TypeCode*> >::const_iterator iter;
1049 for(iter=type->_members.begin();iter!=type->_members.end();iter++)
1051 (*iter).second->destroyZippedAny(whereToGet);
1052 whereToGet+=(*iter).second->getSizeInByteOfAnyReprInSeq();
1056 AnyPtr StructAny::getOrBuildFromData(char *data, const TypeCodeStruct *type)
1059 ret=new StructAny(data,(TypeCodeStruct *)type);
1063 StructAny::~StructAny()
1065 const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
1066 vector< pair<string,TypeCode*> >::const_iterator iter;
1067 char *whereToGet=_data;
1068 for(iter=typeC->_members.begin();iter!=typeC->_members.end();iter++)
1070 (*iter).second->destroyZippedAny(whereToGet);
1071 whereToGet+=(*iter).second->getSizeInByteOfAnyReprInSeq();
1076 StructAny::StructAny(TypeCodeStruct *type):ComposedAny(type,false)
1078 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
1079 for(unsigned int i=0;i<_type->getSizeInByteOfAnyReprInSeq();i++)
1080 _data[i]=SeqAlloc::DFT_CHAR_VAR;
1083 StructAny::StructAny(const StructAny& other):ComposedAny(other)
1085 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
1086 const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
1087 vector< pair<string,TypeCode*> >::const_iterator iter;
1089 for(iter=typeC->_members.begin();iter!=typeC->_members.end();iter++)
1091 (*iter).second->putReprAtPlace(_data+offset,other._data+offset,true);
1092 offset+=(*iter).second->getSizeInByteOfAnyReprInSeq();
1096 StructAny::StructAny(char *data, TypeCodeStruct * type):ComposedAny(type,false),_data(0)
1098 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
1099 vector< pair<string,TypeCode*> >::const_iterator iter;
1101 for(iter=type->_members.begin();iter!=type->_members.end();iter++)
1103 (*iter).second->putReprAtPlace(_data+offset,data+offset,false);
1104 offset+=(*iter).second->getSizeInByteOfAnyReprInSeq();
1108 StructAny *StructAny::New(TypeCodeStruct *type)
1110 return new StructAny(type);