#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>
// forbidden value int=-269488145 double=-1.54947e+231 bool=239
const char SeqAlloc::DFT_CHAR_VAR=-17;//0xEF
+std::string YACS::ENGINE::ToBase64(const std::string& bytes)
+{
+ std::string input(bytes);
+ // The input must be in multiples of 3, otherwise the transformation
+ // may overflow the input buffer, so pad with zero.
+ size_t num_pad_chars((3 - input.size() % 3) % 3);
+ input.append(num_pad_chars, 0);
+
+ // Transform to Base64 with line breaks every 76 characters
+ using namespace boost::archive::iterators;
+ typedef insert_linebreaks<base64_from_binary<transform_width<std::string::const_iterator, 6, 8> >, 76> ItBase64T;
+ std::string output(ItBase64T(input.begin()), ItBase64T(input.end() - num_pad_chars));
+
+ // Pad blank characters with '='
+ output.append(num_pad_chars, '=');
+
+ return output;
+}
+
+std::string YACS::ENGINE::FromBase64(const std::string& base64Str)
+{
+ std::string input(base64Str);
+ using namespace boost::archive::iterators;
+ typedef transform_width<binary_from_base64<remove_whitespace<std::string::const_iterator> >, 8, 6> ItBinaryT;
+
+ try
+ {
+ // If the input isn't a multiple of 4, pad with =
+ size_t num_pad_chars((4 - input.size() % 4) % 4);
+ input.append(num_pad_chars, '=');
+
+ size_t pad_chars(std::count(input.begin(), input.end(), '='));
+ std::replace(input.begin(), input.end(), '=', 'A');
+ std::string output(ItBinaryT(input.begin()), ItBinaryT(input.end()));
+ output.erase(output.end() - pad_chars, output.end());
+ return output;
+ }
+ catch (std::exception const&)
+ {
+ return std::string();
+ }
+}
+
StringOnHeap::StringOnHeap(const char *val):_str(strdup(val)),_len(strlen(val)),_dealloc(0)
{
}
for (int i = 0; i < nbElem; i++)
{
Any *val = getValueAtRank(i);
- switch (val->getType()->kind())
+ switch (((YACS::ENGINE::TypeCodeSeq *)edGetType())->contentType()->kind())
{
case Double:
xmldump << "<value><double>" << setprecision(16) << val->getDoubleValue() << "</double></value>" << endl;
xmldump << "<value><string>" << val->getStringValue() << "</string></value>" << endl;
break;
case Objref:
- xmldump << "<value><objref>" << val->getStringValue() << "</objref></value>" << endl;
+ xmldump << "<value><objref>" << ToBase64(val->getStringValue()) << "</objref></value>" << endl;
break;
default:
xmldump << "<value><error> NO_SERIALISATION_AVAILABLE </error></value>" << endl;
{
DEBTRACE("############### workaround to improve...");
}
- return mystr;
+ if(strncmp(t->id(),"python",6)==0 )
+ return FromBase64(mystr);
+ else
+ return mystr;
}
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"string")))// <- here case where pyobj value has been stored in XML. pyobj has kind==ObjRef. And the stored format is String ! EDF11027
{
static inline std::string convert(const TypeCode *t,std::string& o)
{
if(strncmp(t->id(),"python",6)==0 )
- return "<value><objref><![CDATA[" + o + "]]></objref></value>\n";
+ return "<value><objref><![CDATA[" + ToBase64(o) + "]]></objref></value>\n";
else if(strncmp(t->id(),"json",4)==0)
return "<value><objref><![CDATA[" + o + "]]></objref></value>\n";
else