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 constexpr unsigned NB_BITS = 6;
43 constexpr unsigned char TAB[64]={46, 61, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122};
45 unsigned char BitAtPosSimple(char val, std::size_t bitPos)
47 return (val >> bitPos) & 0x1;
50 unsigned char BitAtPos(char pt0, char pt1, std::size_t bitPos)
53 return BitAtPosSimple(pt0,bitPos);
55 return BitAtPosSimple(pt1,bitPos-8);
58 unsigned char ChunkInternal(char pt0, char pt1, std::size_t startBitIdInByte)
61 for(unsigned i = 0; i<NB_BITS; ++i)
63 ret |= BitAtPos(pt0,pt1,startBitIdInByte+i);
70 unsigned char ChunkAtPos(const char *pt, std::size_t len, std::size_t posChunk)
72 std::size_t startByte((posChunk*NB_BITS)/8);
73 std::size_t startBitIdInByte((posChunk*NB_BITS)%8);
74 char pt1(startByte!=len-1?pt[startByte+1]:pt[startByte]);
75 return ChunkInternal(pt[startByte],pt1,startBitIdInByte);
78 std::size_t OnOff(std::size_t i)
85 std::string YACS::ENGINE::ToBase64(const std::string& bytes)
87 const char *bytesPt(bytes.c_str());
88 std::size_t input_len(bytes.size());
89 std::size_t input_len_bit(input_len*8);
90 std::size_t nb_chunks( input_len_bit/NB_BITS + OnOff((NB_BITS - input_len_bit%NB_BITS)%NB_BITS) );
91 std::string ret(nb_chunks,'\0');
92 for(std::size_t i=0;i<nb_chunks;++i)
94 unsigned char cp(ChunkAtPos(bytesPt,input_len, i));
100 constexpr unsigned MAX_VAL_TAB2=123;
102 constexpr unsigned NOT_OK_VAL = 128;
104 constexpr unsigned char TAB2[MAX_VAL_TAB2] = { NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, 0, NOT_OK_VAL, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, 1, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, NOT_OK_VAL, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63 };
106 unsigned char BitAtPosSimple2(char val, std::size_t bitPos)
108 return ( val >> (5-bitPos) ) & 0x1;
111 char BitAtPosOnChunk(char pt0, char pt1, std::size_t bitPos)
114 return BitAtPosSimple2(pt0,bitPos);
116 return BitAtPosSimple2(pt1,bitPos-6);
119 unsigned char CheckEntry(char c)
121 if( ((unsigned) c) < MAX_VAL_TAB2 )
123 unsigned char ret(TAB2[(unsigned char)c]);
124 if(ret != NOT_OK_VAL)
126 throw YACS::Exception("Invalid character found !");
128 throw YACS::Exception("Invalid character found !");
131 char ByteInternal(char c0, char c1, std::size_t startBitIdInByte)
133 unsigned char ret(0);
134 char ct0(CheckEntry(c0)),ct1(CheckEntry(c1));
135 for(int i = 7; i>=0; --i)
137 ret |= BitAtPosOnChunk(ct0,ct1,startBitIdInByte+i);
144 char ByteAtPos(const char *chunckPt, std::size_t bytePos)
146 std::size_t startChunk((bytePos*8)/NB_BITS);
147 std::size_t startBitId((bytePos*8)%NB_BITS);
148 return ByteInternal(chunckPt[startChunk],chunckPt[startChunk+1],startBitId);
151 std::string YACS::ENGINE::FromBase64(const std::string& bytes)
153 std::size_t nb_chunks(bytes.size());
154 const char *chunckPt(bytes.c_str());
155 std::size_t nb_bytes_output((nb_chunks*NB_BITS)/8);
156 std::string ret(nb_bytes_output,'\0');
157 for(std::size_t i = 0; i<nb_bytes_output; ++i)
159 ret[i] = ByteAtPos(chunckPt,i);
165 * Method used at load time in case of non base64 bytes in input (a throw during decoding). If so, the input bytes is returned.
167 std::string YACS::ENGINE::FromBase64Safe(const std::string& bytes)
171 return FromBase64(bytes);
173 catch(const YACS::Exception& e)
179 StringOnHeap::StringOnHeap(const char *val):_str(strdup(val)),_len(strlen(val)),_dealloc(0)
183 StringOnHeap::StringOnHeap(const char *val, std::size_t len):_dealloc(0),_len(len)
185 _str=(char *)malloc(len+1);
186 std::copy(val,val+len,_str);
190 StringOnHeap::StringOnHeap(const std::string& val):_dealloc(0),_len(val.size()),_str(nullptr)
192 _str=(char *)malloc(val.size()+1);
193 std::copy(val.cbegin(),val.cend(),_str);
194 _str[val.size()]='\0';
198 * \note : no copy is performed if a deallocator is given.
199 * \param val : String in C format that is NOT copied if
201 * \param deAlloc : pointer on function to deallocate val after
204 StringOnHeap::StringOnHeap(char *val, Deallocator deAlloc):_len(0),_dealloc(deAlloc)
212 bool StringOnHeap::operator ==(const StringOnHeap& other) const
214 return strcmp(_str, other._str)==0;
217 StringOnHeap *StringOnHeap::deepCopy() const
220 return new StringOnHeap(_str);
222 return new StringOnHeap(_str,_len);
225 StringOnHeap::~StringOnHeap()
233 Any::Any(TypeCode* type):_type(type)
238 Any::Any(const Any& other):_type(other._type)
248 bool Any::IsNull(char *data)
253 for(std::size_t i=0;i<sizeof(void *) && isNull;i++)
254 isNull=(data[i]==SeqAlloc::DFT_CHAR_VAR);
258 AtomAny::AtomAny(int val):Any(Runtime::_tc_int)
263 AtomAny::AtomAny(bool val):Any(Runtime::_tc_bool)
268 AtomAny::AtomAny(double val):Any(Runtime::_tc_double)
273 AtomAny::AtomAny(const char *val):Any(Runtime::_tc_string)
275 _value._s=new StringOnHeap(val);
278 AtomAny::AtomAny(const std::string& val):Any(Runtime::_tc_string)
280 _value._s=new StringOnHeap(val);
283 AtomAny::AtomAny(const std::string& val, TypeCode* type):Any(type)
285 _value._s=new StringOnHeap(val);
288 AtomAny::AtomAny(const AtomAny& other):Any(other)
290 if(_type->isA(Runtime::_tc_string) || _type->kind()==YACS::ENGINE::Objref)
292 StringOnHeap *cpy=(other._value._s)->deepCopy();
293 memcpy(&_value._s,&cpy,_type->getSizeInByteOfAnyReprInSeq());
295 else if(_type->isA(Runtime::_tc_double))
296 memcpy(&_value._d,&other._value._d,_type->getSizeInByteOfAnyReprInSeq());
297 else if(_type->isA(Runtime::_tc_int))
298 memcpy(&_value._i,&other._value._i,_type->getSizeInByteOfAnyReprInSeq());
299 else if(_type->isA(Runtime::_tc_bool))
300 memcpy(&_value._b,&other._value._b,_type->getSizeInByteOfAnyReprInSeq());
303 AtomAny::AtomAny(char *val, Deallocator deAlloc):Any(Runtime::_tc_string)
305 _value._s=new StringOnHeap(val,deAlloc);
308 AtomAny::AtomAny(char *data, TypeCode* type):Any(type)
310 if(type->isA(Runtime::_tc_string) || _type->kind()==YACS::ENGINE::Objref)
312 void **tmp=(void **)data;
313 StringOnHeap *cpy=((StringOnHeap *)(*tmp))->deepCopy();
314 memcpy(&_value._s,&cpy,type->getSizeInByteOfAnyReprInSeq());
316 else if(type->isA(Runtime::_tc_double))
317 memcpy(&_value._d,data,type->getSizeInByteOfAnyReprInSeq());
318 else if(type->isA(Runtime::_tc_int))
319 memcpy(&_value._i,data,type->getSizeInByteOfAnyReprInSeq());
320 else if(type->isA(Runtime::_tc_bool))
321 memcpy(&_value._b,data,type->getSizeInByteOfAnyReprInSeq());
324 Any *AtomAny::clone() const
326 return new AtomAny(*this);
329 AtomAny *AtomAny::New(char *val,Deallocator dealloc)
331 return new AtomAny(val,dealloc);
334 AtomAny *AtomAny::New(const std::string& val, TypeCode *type)
336 return new AtomAny(val,type);
339 AnyPtr AtomAny::operator[](int i) const throw(YACS::Exception)
341 throw InvalidExtractionException(_type->kind(),Sequence);
344 AnyPtr AtomAny::operator[](const char *key) const throw(YACS::Exception)
346 throw Exception("AtomAny::operator[] : try to get a part of a partitionned data whereas atomical.");
349 bool AtomAny::operator ==(const Any& other) const
351 if(!_type->isA(other.getType()))
353 const AtomAny& otherC=(const AtomAny&) other;//cast granted due to previous lines
354 if(_type->isA(Runtime::_tc_double))
355 return _value._d==otherC._value._d;
356 else if(_type->isA(Runtime::_tc_int))
357 return _value._i==otherC._value._i;
358 else if(_type->isA(Runtime::_tc_bool))
359 return _value._b==otherC._value._b;
360 else if(_type->isA(Runtime::_tc_string) || _type->kind()==Objref)
361 return (*_value._s)==*(otherC._value._s);
366 int AtomAny::getIntValue() const throw(YACS::Exception)
368 if(_type->isA(Runtime::_tc_int))
371 throw Exception("Value is not an int");
374 bool AtomAny::getBoolValue() const throw(YACS::Exception)
376 if(_type->isA(Runtime::_tc_bool))
379 throw Exception("Value is not a bool");
382 double AtomAny::getDoubleValue() const throw(YACS::Exception)
384 if(_type->isA(Runtime::_tc_double))
387 throw Exception("Value is not a double");
390 std::string AtomAny::getStringValue() const throw(YACS::Exception)
392 if(_type->isA(Runtime::_tc_string) || _type->kind()==YACS::ENGINE::Objref)
394 std::size_t sz(_value._s->size());
396 return string(_value._s->cStr());
398 return string(_value._s->cStr(),sz);
401 throw Exception("Value is not a string");
404 const char *AtomAny::getBytesValue(std::size_t& len) const
406 if(_type->isA(Runtime::_tc_string) || _type->kind()==YACS::ENGINE::Objref)
408 len=_value._s->size();
409 return _value._s->cStr();
412 throw Exception("Value is not a string");
416 * \note : This method put in data its zipped recursive content in data.
417 * The ownership of the recursive content is tranfered to data.
418 * So this owns nothing and its counter fall by 1.
419 * For memory space minimal use, not all of '*this' is pushed at data location.
420 * \param data : already allocated memory zone where to put compressed content of 'this'
422 void AtomAny::putMyReprAtPlace(char *data) const
424 if(_type->isA(Runtime::_tc_string) || _type->kind()==YACS::ENGINE::Objref)
426 StringOnHeap *tmp=_value._s->deepCopy();
427 memcpy(data,&tmp,_type->getSizeInByteOfAnyReprInSeq());
429 else if(_type->isA(Runtime::_tc_double))
430 memcpy(data,&_value._d,_type->getSizeInByteOfAnyReprInSeq());
431 else if(_type->isA(Runtime::_tc_int))
432 memcpy(data,&_value._i,_type->getSizeInByteOfAnyReprInSeq());
433 else if(_type->isA(Runtime::_tc_bool))
434 memcpy(data,&_value._b,_type->getSizeInByteOfAnyReprInSeq());
438 * \note : This method put in data its zipped recursive content in data.
439 * The ownership of the recursive content is tranfered to data.
440 * So this owns nothing and its counter fall by 1.
441 * For memory space minimal use, not all of '*this' is pushed at data location.
442 * 'deepCpy' param is not used here because by definition of AtomAny deep copy is performed.
443 * \param data : already allocated memory zone where to put compressed content of 'this'
448 void AtomAny::putReprAtPlace(char *data, const char *src, const TypeCode *type, bool deepCpy)
450 if(type->isA(Runtime::_tc_string) || type->kind()==YACS::ENGINE::Objref)
452 void **tmp1=(void **)src;
453 StringOnHeap *tmp=((const StringOnHeap *)(*tmp1))->deepCopy();
454 memcpy(data,&tmp,type->getSizeInByteOfAnyReprInSeq());
456 else if(type->isA(Runtime::_tc_double))
457 memcpy(data,src,type->getSizeInByteOfAnyReprInSeq());
458 else if(type->isA(Runtime::_tc_int))
459 memcpy(data,src,type->getSizeInByteOfAnyReprInSeq());
460 else if(type->isA(Runtime::_tc_bool))
461 memcpy(data,src,type->getSizeInByteOfAnyReprInSeq());
465 * \note : Opposite method of putMyReprAtPlace. But static because due to data compression
468 void AtomAny::destroyReprAtPlace(char *data, const TypeCode *type)
470 DynType typ=type->kind();
471 if(typ==String || typ==Objref)
473 if(!Any::IsNull(data))
475 void **tmp=(void **)data;
476 delete ((StringOnHeap *)(*tmp));
481 AnyPtr AtomAny::getOrBuildFromData(char *data, const TypeCode *type)
484 ret=new AtomAny(data,(TypeCode *)type);
488 bool AtomAny::takeInChargeStorageOf(TypeCode *type)
490 DynType typ=type->kind();
491 return (typ==Double || typ==Int || typ==Bool || typ==String);
496 if(_type->kind() == String || _type->kind()==Objref)
500 ComposedAny::ComposedAny(const ComposedAny& other):Any(other)
504 ComposedAny::ComposedAny(TypeCode* type, bool isNew):Any(type)
510 AnyPtr ComposedAny::operator[](const char *key) const throw(YACS::Exception)
512 throw Exception("AtomAny::operator[] : try to get a part of a partitionned data not localizable by a string.");
515 void ComposedAny::checkTypeOf(const Any *elem) const throw(YACS::Exception)
517 if(!elem->getType()->isA(_type->contentType()))
518 throw Exception("ComposedAny::checkTypeOf : invalid type.");
521 int ComposedAny::getIntValue() const throw(YACS::Exception)
523 throw InvalidExtractionException(_type->kind(),Runtime::_tc_int->kind());
526 bool ComposedAny::getBoolValue() const throw(YACS::Exception)
528 throw InvalidExtractionException(_type->kind(),Runtime::_tc_bool->kind());
531 double ComposedAny::getDoubleValue() const throw(YACS::Exception)
533 throw InvalidExtractionException(_type->kind(),Runtime::_tc_double->kind());
536 std::string ComposedAny::getStringValue() const throw(YACS::Exception)
538 throw InvalidExtractionException(_type->kind(),Runtime::_tc_string->kind());
541 SeqAlloc::SeqAlloc(const SeqAlloc& other):_sizeOf1Elm(other._sizeOf1Elm),_notStdDeAlloc(0),
542 _start(0),_finish(0),_endOfStorage(0)
544 _start=allocate(other._finish-other._start);
545 _finish=_start+(other._finish-other._start);
546 _endOfStorage=_finish;
549 SeqAlloc::SeqAlloc(unsigned int sizeOf1Elm):_sizeOf1Elm(sizeOf1Elm),_notStdDeAlloc(0),
550 _start(0),_finish(0),_endOfStorage(0)
554 SeqAlloc::~SeqAlloc()
559 void SeqAlloc::clear()
568 * \note : This method is exclusively reserved for arrays of C++ built-in types because no
569 * constructor is applied atomically.
571 void SeqAlloc::initCoarseMemory(char *mem, unsigned int size, Deallocator dealloc)
573 unsigned sizeInByte=size*_sizeOf1Elm;
576 _notStdDeAlloc=dealloc;
581 _start=allocate(sizeInByte);
583 memcpy(_start,mem,sizeInByte);
586 for(unsigned int i=0;i<sizeInByte;i++) _start[i]=DFT_CHAR_VAR;// see getSetItems
589 _finish=_start+sizeInByte;
590 _endOfStorage=_finish;
593 void SeqAlloc::construct(char *pt, const Any *val)
595 val->putMyReprAtPlace(pt);
599 * \note: This performs the placement new or zip info into pt.
601 * \param val : the source from which the construction will be performed.
603 * \param deepCpy : If true in pt place a deep copy pointed by val will be put.
605 void SeqAlloc::construct(char *pt, const char *val, const TypeCode *tc, bool deepCpy)
607 tc->putReprAtPlace(pt,val,deepCpy);
610 char *SeqAlloc::allocate(unsigned int nbOfByte)
613 return (char *)::operator new(nbOfByte);
618 // pt is not permitted to be a null pointer.
619 void SeqAlloc::deallocate(char *pt)
624 ::operator delete(pt);
633 void SeqAlloc::destroy(char *pt, const TypeCode *tc)
635 tc->destroyZippedAny(pt);
638 unsigned int SeqAlloc::size() const
640 return (_finish-_start)/_sizeOf1Elm;
643 std::vector<unsigned int> SeqAlloc::getSetItems() const
645 std::vector<unsigned int> ret;
646 unsigned int sz(size());
647 for(unsigned int i=0;i<sz;i++)
649 const char *pt(_start+i*_sizeOf1Elm);
650 for(unsigned j=0;j<_sizeOf1Elm && *pt==DFT_CHAR_VAR;j++,pt++); //see initCoarseMemory
651 if(pt!=_start+(i+1)*_sizeOf1Elm)
657 void SequenceAny::clear()
659 for (char *cur=_alloc._start;cur!=_alloc._finish;cur+=_alloc._sizeOf1Elm)
660 _alloc.destroy(cur,_type->contentType());
664 void SequenceAny::popBack()
666 _alloc._finish-=_alloc._sizeOf1Elm;
667 _alloc.destroy(_alloc._finish,_type->contentType());
670 void SequenceAny::pushBack(const Any* elem)
672 if(!elem->_type->isA(_type->contentType()))
673 throw InvalidExtractionException(elem->_type->kind(),_type->contentType()->kind());
674 if(_alloc._finish != _alloc._endOfStorage)
676 _alloc.construct(_alloc._finish, elem);
677 _alloc._finish+=_alloc._sizeOf1Elm;
680 realloc(_alloc._finish, elem);
683 bool SequenceAny::operator ==(const Any& other) const
685 if(!_type->isA(other.getType()))
687 const SequenceAny& otherC=(const SequenceAny&) other;//cast granted due to previous lines
688 if(size()!=otherC.size())
690 for(unsigned i=0;i<size();i++)
691 if(!((*(*this)[i])==(*otherC[i])))
696 void SequenceAny::setEltAtRank(int i, const Any *elem) throw(YACS::Exception)
699 _alloc.destroy(_alloc._start+i*_alloc._sizeOf1Elm,_type->contentType());
700 _alloc.construct(_alloc._start+i*_alloc._sizeOf1Elm,elem);
703 AnyPtr SequenceAny::operator[](int i) const throw(YACS::Exception)
705 return _type->contentType()->getOrBuildAnyFromZippedData(_alloc._start+i*_alloc._sizeOf1Elm);
709 * \note : Contrary to AtomAny 'this' (ref) is put in data NOT a deep copy.
710 * \param data : already allocated memory zone where to put address of 'this'
712 void SequenceAny::putMyReprAtPlace(char *data) const
714 const void *tmp=(const void *)this;
715 memcpy(data,&tmp,_type->getSizeInByteOfAnyReprInSeq());
716 const void **tmp2=(const void **) data;
717 ((SequenceAny *)(*tmp2))->incrRef();
718 //::new((SequenceAny *)data) SequenceAny((SequenceAny&) (*this));
721 void SequenceAny::putReprAtPlace(char *data, const char *src, const TypeCode *type, bool deepCpy)
723 void **tmp2=(void **) src;
726 ((SequenceAny *)(*tmp2))->incrRef();
727 memcpy(data,src,type->getSizeInByteOfAnyReprInSeq());
731 SequenceAny *cpy=new SequenceAny(*((SequenceAny *)(*tmp2)));
732 memcpy(data,&cpy,type->getSizeInByteOfAnyReprInSeq());
734 //::new((SequenceAny *)data) SequenceAny((SequenceAny&) (*this));
737 void SequenceAny::destroyReprAtPlace(char *data, const TypeCode *type)
739 void **tmp=(void **) data;
740 if(!Any::IsNull(data))
741 ((SequenceAny *)(*tmp))->decrRef();
742 //((SequenceAny *)data)->~SequenceAny();
745 AnyPtr SequenceAny::getOrBuildFromData(char *data, const TypeCode *type)
747 void **tmp=(void **) data;
748 ((SequenceAny *) (*tmp))->incrRef();
749 return AnyPtr((SequenceAny *)(*tmp));
752 Any *SequenceAny::clone() const
754 return new SequenceAny(*this);
757 SequenceAny *SequenceAny::removeUnsetItemsFromThis() const
759 std::vector<unsigned int> its(getSetItems());
760 std::size_t sz(its.size());
761 SequenceAny *ret(SequenceAny::New(getType()->contentType(),sz));
762 for(std::size_t i=0;i<sz;i++)
764 AnyPtr obj((*this)[its[i]]);
765 ret->setEltAtRank(i,obj);
770 SequenceAny *SequenceAny::New(const TypeCode *typeOfContent)
772 return new SequenceAny(typeOfContent);
775 SequenceAny *SequenceAny::New(const TypeCode *typeOfContent, unsigned lgth)
777 return new SequenceAny(typeOfContent,lgth);
780 bool SequenceAny::takeInChargeStorageOf(TypeCode *type)
782 DynType typ=type->kind();
783 return (typ==Sequence);
786 SequenceAny::SequenceAny(const SequenceAny& other):ComposedAny(other),_alloc(other._alloc)
788 const char *srcCur=other._alloc._start;
789 for(char *cur=_alloc._start;srcCur != other._alloc._finish; srcCur+=_alloc._sizeOf1Elm, cur+=_alloc._sizeOf1Elm)
790 _alloc.construct(cur, srcCur, _type->contentType(),true);
793 SequenceAny::~SequenceAny()
795 for (char *cur=_alloc._start;cur!=_alloc._finish;cur+=_alloc._sizeOf1Elm)
796 _alloc.destroy(cur,_type->contentType());
800 * \param typeOfContent : typeCode of the type of elements stored in sequence.
802 SequenceAny::SequenceAny(const TypeCode *typeOfContent):ComposedAny(new TypeCodeSeq("","",typeOfContent)),
803 _alloc(typeOfContent->getSizeInByteOfAnyReprInSeq())
807 SequenceAny::SequenceAny(const TypeCode *typeOfContent, unsigned lgth):ComposedAny(new TypeCodeSeq("","",typeOfContent)),
808 _alloc(typeOfContent->getSizeInByteOfAnyReprInSeq())
810 _alloc.initCoarseMemory(0,lgth,0);
813 SequenceAny::SequenceAny(int *val, unsigned int lgth, Deallocator deAlloc):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_int)),
814 _alloc(Runtime::_tc_int->getSizeInByteOfAnyReprInSeq())
816 _alloc.initCoarseMemory((char *)val,lgth,deAlloc);
819 SequenceAny::SequenceAny(bool *val, unsigned int lgth, Deallocator deAlloc):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_bool)),
820 _alloc(Runtime::_tc_bool->getSizeInByteOfAnyReprInSeq())
822 _alloc.initCoarseMemory((char *)val,lgth,deAlloc);
825 SequenceAny::SequenceAny(double *val, unsigned int lgth, Deallocator deAlloc):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_double)),
826 _alloc(Runtime::_tc_double->getSizeInByteOfAnyReprInSeq())
828 _alloc.initCoarseMemory((char *)val,lgth,deAlloc);
831 SequenceAny::SequenceAny(const std::vector<int>& val):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_int)),
832 _alloc(Runtime::_tc_int->getSizeInByteOfAnyReprInSeq())
834 _alloc.initCoarseMemory((char *)&val[0],val.size(),0);
837 SequenceAny::SequenceAny(const std::vector<bool>& val):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_bool)),
838 _alloc(Runtime::_tc_bool->getSizeInByteOfAnyReprInSeq())
840 for(vector<bool>::const_iterator iter=val.begin();iter!=val.end();iter++)
842 AtomAnyPtr tmp=AtomAny::New(*iter);
847 SequenceAny::SequenceAny(const std::vector<double>& val):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_double)),
848 _alloc(Runtime::_tc_double->getSizeInByteOfAnyReprInSeq())
850 _alloc.initCoarseMemory((char *)&val[0],val.size(),0);
853 SequenceAny::SequenceAny(const std::vector<std::string>& val):ComposedAny(new TypeCodeSeq("","",Runtime::_tc_string)),
854 _alloc(Runtime::_tc_string->getSizeInByteOfAnyReprInSeq())
856 for(vector<string>::const_iterator iter=val.begin();iter!=val.end();iter++)
858 AtomAnyPtr tmp=AtomAny::New(*iter);
863 void SequenceAny::realloc(char *endOfCurrentAllocated, const Any *elem)
865 unsigned int oldSize=_alloc._finish-_alloc._start;
866 unsigned int newSize = oldSize != 0 ? 2 * oldSize : _alloc._sizeOf1Elm;
867 char *newStart=_alloc.allocate(newSize);
869 char *newFinish=performCpy(_alloc._start, endOfCurrentAllocated,newStart);
870 _alloc.construct(newFinish, elem);
871 newFinish+=_alloc._sizeOf1Elm;
872 newFinish=performCpy(endOfCurrentAllocated, _alloc._finish, newFinish);
874 for (char *cur=_alloc._start;cur!=_alloc._finish;cur+=_alloc._sizeOf1Elm)
875 _alloc.destroy(cur,_type->contentType());
876 _alloc.deallocate(_alloc._start);
877 _alloc._start = newStart;
878 _alloc._finish = newFinish;
879 _alloc._endOfStorage=newStart+newSize;
882 char *SequenceAny::performCpy(char *srcStart, char *srcFinish, char *destStart)
885 for (;srcStart != srcFinish; srcStart+=_alloc._sizeOf1Elm, cur+=_alloc._sizeOf1Elm)
886 _alloc.construct(cur, srcStart, _type->contentType(),false);
890 ArrayAny::~ArrayAny()
892 const TypeCode *subType=_type->contentType();
893 unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
894 unsigned int size=((TypeCodeArray *)_type)->getStaticLgth();
896 for(unsigned i=0;i<size;i++,tmp+=sizePerContent)
897 subType->destroyZippedAny(tmp);
901 ArrayAny::ArrayAny(const TypeCode *typeOfContent, unsigned int lgth):ComposedAny(new TypeCodeArray("","",typeOfContent,lgth))
903 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
904 for(unsigned int i=0;i<_type->getSizeInByteOfAnyReprInSeq();i++)
905 _data[i]=SeqAlloc::DFT_CHAR_VAR;
908 ArrayAny::ArrayAny(char *data, TypeCodeArray * type):ComposedAny(type,false),_data(0)
910 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
911 const TypeCode *subType=_type->contentType();
912 unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
913 for(unsigned i=0;i<type->getStaticLgth();i++)
914 subType->putReprAtPlace(_data+i*sizePerContent,data+i*sizePerContent,false);
917 ArrayAny::ArrayAny(const ArrayAny& other):ComposedAny(other)
919 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
920 const TypeCode *subType=_type->contentType();
921 unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
922 for(unsigned i=0;i<((TypeCodeArray *)_type)->getStaticLgth();i++)
923 subType->putReprAtPlace(_data+i*sizePerContent,other._data+i*sizePerContent,true);
926 ArrayAny::ArrayAny(const int *val, unsigned int lgth):ComposedAny(new TypeCodeArray("","",Runtime::_tc_int,lgth)),
929 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
930 memcpy(_data,val,_type->getSizeInByteOfAnyReprInSeq());
933 ArrayAny::ArrayAny(const bool *val, unsigned int lgth):ComposedAny(new TypeCodeArray("","",Runtime::_tc_bool,lgth)),
936 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
937 memcpy(_data,val,_type->getSizeInByteOfAnyReprInSeq());
940 ArrayAny::ArrayAny(const double *val, unsigned int lgth):ComposedAny(new TypeCodeArray("","",Runtime::_tc_double,lgth)),
943 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
944 memcpy(_data,val,_type->getSizeInByteOfAnyReprInSeq());
947 ArrayAny::ArrayAny(const std::vector<int>& val):ComposedAny(new TypeCodeArray("","",Runtime::_tc_int,val.size())),
950 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
951 memcpy(_data,&val[0],_type->getSizeInByteOfAnyReprInSeq());
954 ArrayAny::ArrayAny(const std::vector<double>& val):ComposedAny(new TypeCodeArray("","",Runtime::_tc_double,val.size())),
957 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
958 memcpy(_data,&val[0],_type->getSizeInByteOfAnyReprInSeq());
961 ArrayAny::ArrayAny(const std::vector<std::string>& val):ComposedAny(new TypeCodeArray("","",Runtime::_tc_string,val.size())),
964 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
966 const TypeCode *subType=_type->contentType();
967 unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
968 for(vector<std::string>::const_iterator iter=val.begin();iter!=val.end();iter++,i++)
970 StringOnHeap *st=new StringOnHeap(*iter);
971 memcpy(_data+i*sizePerContent,&st,sizePerContent);
975 void ArrayAny::setEltAtRank(int i, const Any *elem) throw(YACS::Exception)
978 const TypeCode *subType=_type->contentType();
979 subType->destroyZippedAny(_data+i*subType->getSizeInByteOfAnyReprInSeq());
980 elem->putMyReprAtPlace(_data+i*subType->getSizeInByteOfAnyReprInSeq());
983 bool ArrayAny::operator ==(const Any& other) const
985 if(!_type->isA(other.getType()))
987 const ArrayAny& otherC=(const ArrayAny&) other;//cast granted due to previous lines
988 for(unsigned i=0;i<((const TypeCodeArray *)_type)->getStaticLgth();i++)
989 if(!((*(*this)[i])==(*otherC[i])))
994 AnyPtr ArrayAny::operator[](int i) const throw(YACS::Exception)
996 const TypeCode *subType=_type->contentType();
997 unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
998 if(i<0 || i>=((TypeCodeArray *)_type)->getStaticLgth())
999 throw Exception("Trying to access to an invalid index in an Any Tuple");
1000 return _type->contentType()->getOrBuildAnyFromZippedData(_data+i*sizePerContent);
1003 unsigned int ArrayAny::size() const
1005 return ((TypeCodeArray *)_type)->getStaticLgth();
1008 Any *ArrayAny::clone() const
1010 return new ArrayAny(*this);
1013 ArrayAny *ArrayAny::New(const TypeCode *typeOfContent, unsigned int lgth)
1015 return new ArrayAny(typeOfContent,lgth);
1018 void ArrayAny::putMyReprAtPlace(char *data) const
1020 const TypeCode *subType=_type->contentType();
1021 unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
1022 for(unsigned i=0;i<((const TypeCodeArray *)_type)->getStaticLgth();i++)
1023 subType->putReprAtPlace(data+i*sizePerContent,_data+i*sizePerContent,false);
1026 void ArrayAny::putReprAtPlace(char *data, const char *src, const TypeCodeArray *type, bool deepCpy)
1028 const TypeCode *subType=type->contentType();
1029 unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
1030 for(unsigned i=0;i<type->getStaticLgth();i++)
1031 subType->putReprAtPlace(data+i*sizePerContent,src+i*sizePerContent,deepCpy);
1034 void ArrayAny::destroyReprAtPlace(char *data, const TypeCodeArray *type)
1036 const TypeCode *subType=type->contentType();
1037 unsigned sizePerContent=subType->getSizeInByteOfAnyReprInSeq();
1038 for(unsigned i=0;i<type->getStaticLgth();i++)
1039 subType->destroyZippedAny(data+i*sizePerContent);
1042 AnyPtr ArrayAny::getOrBuildFromData(char *data, const TypeCodeArray *type)
1045 ret=new ArrayAny(data,(TypeCodeArray *)type);
1049 bool ArrayAny::takeInChargeStorageOf(TypeCode *type)
1051 DynType typ=type->kind();
1052 return (typ==Array);
1055 Any *StructAny::clone() const
1057 return new StructAny(*this);
1060 bool StructAny::operator ==(const Any& other) const
1062 if(!_type->isA(other.getType()))
1064 const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
1065 vector< pair<string,TypeCode*> >::const_iterator iter;
1066 for(iter=typeC->_members.begin();iter!=typeC->_members.end();iter++)
1067 if(!((*(*this)[(*iter).first.c_str()]==(*other[(*iter).first.c_str()]))))
1072 AnyPtr StructAny::operator[](int i) const throw(YACS::Exception)
1074 const char what[]="StructAny::operator[](int i) : Struct key are strings not integers.";
1075 throw Exception(what);
1078 AnyPtr StructAny::operator[](const char *key) const throw(YACS::Exception)
1080 const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
1081 char *whereToGet=_data;
1082 vector< pair<string,TypeCode*> >::const_iterator iter;
1083 for(iter=typeC->_members.begin();iter!=typeC->_members.end();iter++)
1084 if((*iter).first!=key)
1085 whereToGet+=(*iter).second->getSizeInByteOfAnyReprInSeq();
1088 if(iter==typeC->_members.end())
1090 string what("Unexisting key \""); what+=key; what+="\" for struct extraction.";
1091 throw Exception(what);
1093 return (*iter).second->getOrBuildAnyFromZippedData(whereToGet);
1096 void StructAny::setEltAtRank(int i, const Any *elem) throw(YACS::Exception)
1098 const char what[]="Struct key are strings not integers.";
1099 throw Exception(what);
1102 void StructAny::setEltAtRank(const char *key, const Any *elem) throw(YACS::Exception)
1104 const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
1106 const TypeCode *tcOnKey=typeC->getMember(key,offset);
1108 throw Exception("StructAny::setEltAtRank : invalid key given.");
1109 if(!elem->getType()->isA(tcOnKey))
1110 throw Exception("StructAny::setEltAtRank : invalid data type on the specified given key.");
1111 tcOnKey->destroyZippedAny(_data+offset);
1112 elem->putMyReprAtPlace(_data+offset);
1115 void StructAny::putMyReprAtPlace(char *data) const
1117 const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
1119 vector< pair<string,TypeCode*> >::const_iterator iter;
1120 for(iter=typeC->_members.begin();iter!=typeC->_members.end();iter++)
1122 (*iter).second->putReprAtPlace(data+offset,_data+offset,false);
1123 offset+=(*iter).second->getSizeInByteOfAnyReprInSeq();
1127 void StructAny::putReprAtPlace(char *data, const char *src, const TypeCodeStruct *type, bool deepCpy)
1130 vector< pair<string,TypeCode*> >::const_iterator iter;
1131 for(iter=type->_members.begin();iter!=type->_members.end();iter++)
1133 (*iter).second->putReprAtPlace(data+offset,src+offset,deepCpy);
1134 offset+=(*iter).second->getSizeInByteOfAnyReprInSeq();
1138 void StructAny::destroyReprAtPlace(char *data, const TypeCodeStruct *type)
1140 char *whereToGet=data;
1141 vector< pair<string,TypeCode*> >::const_iterator iter;
1142 for(iter=type->_members.begin();iter!=type->_members.end();iter++)
1144 (*iter).second->destroyZippedAny(whereToGet);
1145 whereToGet+=(*iter).second->getSizeInByteOfAnyReprInSeq();
1149 AnyPtr StructAny::getOrBuildFromData(char *data, const TypeCodeStruct *type)
1152 ret=new StructAny(data,(TypeCodeStruct *)type);
1156 StructAny::~StructAny()
1158 const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
1159 vector< pair<string,TypeCode*> >::const_iterator iter;
1160 char *whereToGet=_data;
1161 for(iter=typeC->_members.begin();iter!=typeC->_members.end();iter++)
1163 (*iter).second->destroyZippedAny(whereToGet);
1164 whereToGet+=(*iter).second->getSizeInByteOfAnyReprInSeq();
1169 StructAny::StructAny(TypeCodeStruct *type):ComposedAny(type,false)
1171 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
1172 for(unsigned int i=0;i<_type->getSizeInByteOfAnyReprInSeq();i++)
1173 _data[i]=SeqAlloc::DFT_CHAR_VAR;
1176 StructAny::StructAny(const StructAny& other):ComposedAny(other)
1178 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
1179 const TypeCodeStruct *typeC=(const TypeCodeStruct *)_type;
1180 vector< pair<string,TypeCode*> >::const_iterator iter;
1182 for(iter=typeC->_members.begin();iter!=typeC->_members.end();iter++)
1184 (*iter).second->putReprAtPlace(_data+offset,other._data+offset,true);
1185 offset+=(*iter).second->getSizeInByteOfAnyReprInSeq();
1189 StructAny::StructAny(char *data, TypeCodeStruct * type):ComposedAny(type,false),_data(0)
1191 _data=new char[_type->getSizeInByteOfAnyReprInSeq()];
1192 vector< pair<string,TypeCode*> >::const_iterator iter;
1194 for(iter=type->_members.begin();iter!=type->_members.end();iter++)
1196 (*iter).second->putReprAtPlace(_data+offset,data+offset,false);
1197 offset+=(*iter).second->getSizeInByteOfAnyReprInSeq();
1201 StructAny *StructAny::New(TypeCodeStruct *type)
1203 return new StructAny(type);