-// Copyright (C) 2006-2014 CEA/DEN, EDF R&D
+// Copyright (C) 2006-2019 CEA/DEN, EDF R&D
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
#include "TypeCode.hxx"
#include "InvalidExtractionException.hxx"
+#include <boost/archive/iterators/base64_from_binary.hpp>
+#include <boost/archive/iterators/binary_from_base64.hpp>
+#include <boost/archive/iterators/transform_width.hpp>
+#include <boost/archive/iterators/insert_linebreaks.hpp>
+#include <boost/archive/iterators/remove_whitespace.hpp>
+
+#include <algorithm>
#include <cstring>
#include <cstdlib>
using namespace YACS::ENGINE;
using namespace std;
-StringOnHeap::StringOnHeap(const char *val):_dealloc(0),_str(strdup(val))
+// forbidden value int=-269488145 double=-1.54947e+231 bool=239
+const char SeqAlloc::DFT_CHAR_VAR=-17;//0xEF
+
+constexpr unsigned NB_BITS = 6;
+
+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};
+
+unsigned char BitAtPosSimple(char val, std::size_t bitPos)
+{
+ return (val >> bitPos) & 0x1;
+}
+
+unsigned char BitAtPos(char pt0, char pt1, std::size_t bitPos)
+{
+ if(bitPos<8)
+ return BitAtPosSimple(pt0,bitPos);
+ else
+ return BitAtPosSimple(pt1,bitPos-8);
+}
+
+unsigned char ChunkInternal(char pt0, char pt1, std::size_t startBitIdInByte)
+{
+ unsigned char ret(0);
+ for(unsigned i = 0; i<NB_BITS; ++i)
+ {
+ ret |= BitAtPos(pt0,pt1,startBitIdInByte+i);
+ ret <<= 1;
+ }
+ ret >>= 1;
+ return ret;
+}
+
+unsigned char ChunkAtPos(const char *pt, std::size_t len, std::size_t posChunk)
+{
+ std::size_t startByte((posChunk*NB_BITS)/8);
+ std::size_t startBitIdInByte((posChunk*NB_BITS)%8);
+ char pt1(startByte!=len-1?pt[startByte+1]:pt[startByte]);
+ return ChunkInternal(pt[startByte],pt1,startBitIdInByte);
+}
+
+std::size_t OnOff(std::size_t i)
+{
+ if(i!=0)
+ return 1;
+ return 0;
+}
+
+std::string YACS::ENGINE::ToBase64(const std::string& bytes)
+{//64 == 2**6
+ const char *bytesPt(bytes.c_str());
+ std::size_t input_len(bytes.size());
+ std::size_t input_len_bit(input_len*8);
+ std::size_t nb_chunks( input_len_bit/NB_BITS + OnOff((NB_BITS - input_len_bit%NB_BITS)%NB_BITS) );
+ std::string ret(nb_chunks,'\0');
+ for(std::size_t i=0;i<nb_chunks;++i)
+ {
+ unsigned char cp(ChunkAtPos(bytesPt,input_len, i));
+ ret[i] = TAB[cp];
+ }
+ return ret;
+}
+
+constexpr unsigned MAX_VAL_TAB2=123;
+
+constexpr unsigned char TAB2[MAX_VAL_TAB2] = { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 128, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 128, 128, 128, 1, 128, 128, 128, 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, 128, 128, 128, 128, 128, 128, 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 };
+
+unsigned char BitAtPosSimple2(char val, std::size_t bitPos)
+{
+ return (val >> 5-bitPos) & 0x1;
+}
+
+char BitAtPosOnChunk(char pt0, char pt1, std::size_t bitPos)
+{
+ if(bitPos<6)
+ return BitAtPosSimple2(pt0,bitPos);
+ else
+ return BitAtPosSimple2(pt1,bitPos-6);
+}
+
+char ByteInternal(char c0, char c1, std::size_t startBitIdInByte)
{
+ unsigned char ret(0);
+ char ct0(TAB2[(unsigned char)c0]),ct1(TAB2[(unsigned char)c1]);
+ for(int i = 7; i>=0; --i)
+ {
+ ret |= BitAtPosOnChunk(ct0,ct1,startBitIdInByte+i);
+ if(i!=0)
+ ret <<= 1;
+ }
+ return ret;
}
-StringOnHeap::StringOnHeap(const std::string& val):_dealloc(0),_str(strdup(val.c_str()))
+char ByteAtPos(const char *chunckPt, std::size_t bytePos)
{
+ std::size_t startChunk((bytePos*8)/NB_BITS);
+ std::size_t startBitId((bytePos*8)%NB_BITS);
+ return ByteInternal(chunckPt[startChunk],chunckPt[startChunk+1],startBitId);
+}
+
+std::string YACS::ENGINE::FromBase64(const std::string& bytes)
+{
+ std::size_t nb_chunks(bytes.size());
+ const char *chunckPt(bytes.c_str());
+ std::size_t nb_bytes_output((nb_chunks*NB_BITS)/8);
+ std::string ret(nb_bytes_output,'\0');
+ for(std::size_t i = 0; i<nb_bytes_output; ++i)
+ {
+ ret[i] = ByteAtPos(chunckPt,i);
+ }
+ return ret;
+}
+
+StringOnHeap::StringOnHeap(const char *val):_str(strdup(val)),_len(strlen(val)),_dealloc(0)
+{
+}
+
+StringOnHeap::StringOnHeap(const char *val, std::size_t len):_dealloc(0),_len(len)
+{
+ _str=(char *)malloc(len+1);
+ std::copy(val,val+len,_str);
+ _str[len]='\0';
+}
+
+StringOnHeap::StringOnHeap(const std::string& val):_dealloc(0),_len(val.size()),_str(nullptr)
+{
+ _str=(char *)malloc(val.size()+1);
+ std::copy(val.cbegin(),val.cend(),_str);
+ _str[val.size()]='\0';
}
/*!
* \param deAlloc : pointer on function to deallocate val after
* last use.
*/
-StringOnHeap::StringOnHeap(char *val, Deallocator deAlloc):_dealloc(deAlloc)
+StringOnHeap::StringOnHeap(char *val, Deallocator deAlloc):_len(0),_dealloc(deAlloc)
{
if(deAlloc)
_str=val;
StringOnHeap *StringOnHeap::deepCopy() const
{
- return new StringOnHeap(_str);
+ if(_len==0)
+ return new StringOnHeap(_str);
+ else
+ return new StringOnHeap(_str,_len);
}
StringOnHeap::~StringOnHeap()
_type->decrRef();
}
+bool Any::IsNull(char *data)
+{
+ if(!data)
+ return true;
+ bool isNull(true);
+ for(std::size_t i=0;i<sizeof(void *) && isNull;i++)
+ isNull=(data[i]==SeqAlloc::DFT_CHAR_VAR);
+ return isNull;
+}
+
AtomAny::AtomAny(int val):Any(Runtime::_tc_int)
{
_value._i=val;
std::string AtomAny::getStringValue() const throw(YACS::Exception)
{
if(_type->isA(Runtime::_tc_string))
- return string(_value._s->cStr());
+ {
+ std::size_t sz(_value._s->size());
+ if(sz==0)
+ return string(_value._s->cStr());
+ else
+ return string(_value._s->cStr(),sz);
+ }
+ else
+ throw Exception("Value is not a string");
+}
+
+const char *AtomAny::getBytesValue(std::size_t& len) const
+{
+ if(_type->isA(Runtime::_tc_string))
+ {
+ len=_value._s->size();
+ return _value._s->cStr();
+ }
else
throw Exception("Value is not a string");
}
DynType typ=type->kind();
if(typ==String)
{
- void **tmp=(void **)data;
- delete ((StringOnHeap *)(*tmp));
+ if(!Any::IsNull(data))
+ {
+ void **tmp=(void **)data;
+ delete ((StringOnHeap *)(*tmp));
+ }
}
}
memcpy(_start,mem,sizeInByte);
else
{
- for(unsigned int i=0;i<sizeInByte;i++) _start[i]=0;
+ for(unsigned int i=0;i<sizeInByte;i++) _start[i]=DFT_CHAR_VAR;// see getSetItems
}
}
_finish=_start+sizeInByte;
return (_finish-_start)/_sizeOf1Elm;
}
+std::vector<unsigned int> SeqAlloc::getSetItems() const
+{
+ std::vector<unsigned int> ret;
+ unsigned int sz(size());
+ for(unsigned int i=0;i<sz;i++)
+ {
+ const char *pt(_start+i*_sizeOf1Elm);
+ for(unsigned j=0;j<_sizeOf1Elm && *pt==DFT_CHAR_VAR;j++,pt++); //see initCoarseMemory
+ if(pt!=_start+(i+1)*_sizeOf1Elm)
+ ret.push_back(i);
+ }
+ return ret;
+}
+
void SequenceAny::clear()
{
for (char *cur=_alloc._start;cur!=_alloc._finish;cur+=_alloc._sizeOf1Elm)
void SequenceAny::destroyReprAtPlace(char *data, const TypeCode *type)
{
void **tmp=(void **) data;
- if(*tmp)
+ if(!Any::IsNull(data))
((SequenceAny *)(*tmp))->decrRef();
//((SequenceAny *)data)->~SequenceAny();
}
return new SequenceAny(*this);
}
+SequenceAny *SequenceAny::removeUnsetItemsFromThis() const
+{
+ std::vector<unsigned int> its(getSetItems());
+ std::size_t sz(its.size());
+ SequenceAny *ret(SequenceAny::New(getType()->contentType(),sz));
+ for(std::size_t i=0;i<sz;i++)
+ {
+ AnyPtr obj((*this)[its[i]]);
+ ret->setEltAtRank(i,obj);
+ }
+ return ret;
+}
+
SequenceAny *SequenceAny::New(const TypeCode *typeOfContent)
{
if(typeOfContent->kind() == Objref)
{
_data=new char[_type->getSizeInByteOfAnyReprInSeq()];
for(unsigned int i=0;i<_type->getSizeInByteOfAnyReprInSeq();i++)
- _data[i]='\0';
+ _data[i]=SeqAlloc::DFT_CHAR_VAR;
}
ArrayAny::ArrayAny(char *data, TypeCodeArray * type):ComposedAny(type,false),_data(0)
{
_data=new char[_type->getSizeInByteOfAnyReprInSeq()];
for(unsigned int i=0;i<_type->getSizeInByteOfAnyReprInSeq();i++)
- _data[i]='\0';
+ _data[i]=SeqAlloc::DFT_CHAR_VAR;
}
StructAny::StructAny(const StructAny& other):ComposedAny(other)