Salome HOME
base64 is used to store pickelized objects into XML
authorAnthony Geay <anthony.geay@edf.fr>
Tue, 14 May 2019 11:58:36 +0000 (13:58 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Tue, 14 May 2019 11:58:36 +0000 (13:58 +0200)
src/engine/Any.cxx
src/engine/Any.hxx
src/engine/CMakeLists.txt
src/engine/ForEachLoop.cxx
src/runtime/TypeConversions.cxx
src/yacsloader_swig/Test/testSaveLoadRun.py

index 37e24f11ce73be44ed654778cb6085d209c7db21..70458bddc45d32238b81724068cdd42342abd034 100644 (file)
 #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>
 
@@ -31,6 +38,49 @@ using namespace std;
 // 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)
 {
 }
index 026bd29d8450d9f2fabf36b49f6aed3a4096008b..e09064e9a1fc93105c5708defac493ac6426e630 100644 (file)
@@ -42,6 +42,10 @@ namespace YACS
     class TypeCodeStruct;
     typedef void (*Deallocator)(void *);
 
+
+    YACSLIBENGINE_EXPORT std::string ToBase64(const std::string& bytes);
+    YACSLIBENGINE_EXPORT std::string FromBase64(const std::string& bytes);
+    
     class YACSLIBENGINE_EXPORT StringOnHeap
     {
       friend class Any;
index e884eaa8ae0167a30f0c0b0cc904dac69539f1e0..6307814218d56a4d199eb300c70891eb43ad1801 100644 (file)
@@ -23,6 +23,9 @@ IF(SALOME_BUILD_TESTS)
 ENDIF(SALOME_BUILD_TESTS)
 
 # --- options ---
+ADD_DEFINITIONS(
+  ${BOOST_DEFINITIONS}
+  )
 
 # additional include directories
 INCLUDE_DIRECTORIES(
index 4605bbada0997d757a648b2e705a651adf553a03..b3d87fdfa6d7ab368b5346968d622e9fd22eb995 100644 (file)
@@ -180,7 +180,7 @@ std::string SeqAnyInputPort::dump()
   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;
@@ -195,7 +195,7 @@ std::string SeqAnyInputPort::dump()
           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;
index a3da28270ecb5ca9f49a795bb4fe77622a6cd8b7..3143d4366201fe5fd858f202596ef4330d241fd2 100644 (file)
@@ -1328,7 +1328,10 @@ namespace YACS
                     {
                       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
                 {
@@ -1498,7 +1501,7 @@ namespace YACS
       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
index 12cddf6873f29b8c46233517a7497b5020fee596..5c2e755fe074bfae0b0ada235f911b2f2d2e4f1e 100755 (executable)
@@ -1171,7 +1171,7 @@ for i in i8:
     self.assertEqual(p.getState(),pilot.DONE)
     pass
 
-  def tess14(self):
+  def test14(self):
     """ Non regression EDF11027. Problem after Save/Load of a foreach node with type pyobj with input "SmplsCollection" manually set before. Correction in convertToYacsObjref from XML->Neutral. Objref can hide a string !"""
     xmlFileName="test14.xml"
     SALOMERuntime.RuntimeSALOME_setRuntime()