Salome HOME
On the fly
authorAnthony Geay <anthony.geay@edf.fr>
Wed, 5 Jun 2019 14:44:11 +0000 (16:44 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Wed, 5 Jun 2019 14:44:11 +0000 (16:44 +0200)
src/engine/Any.cxx
src/engine/Any.hxx
src/engine_swig/pilot.i

index 70458bddc45d32238b81724068cdd42342abd034..a3c5cfa6b12f69c33b3e05e4ba660bd61fb68e01 100644 (file)
@@ -38,47 +38,113 @@ 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)
+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)
 {
-  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);
+  return (val >> bitPos) & 0x1;
+}
 
-  // 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));
+unsigned char BitAtPos(char pt0, char pt1, std::size_t bitPos)
+{
+  if(bitPos<8)
+    return BitAtPosSimple(pt0,bitPos);
+  else
+    return BitAtPosSimple(pt1,bitPos-8);
+}
 
-  // Pad blank characters with '='
-  output.append(num_pad_chars, '=');
+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;
+}
 
-  return output;
+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::string YACS::ENGINE::FromBase64(const std::string& base64Str)
+std::size_t OnOff(std::size_t i)
 {
-  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(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)
     {
-      // 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;
+      unsigned char cp(ChunkAtPos(bytesPt,input_len, i));
+      ret[i] = TAB[cp];
     }
-  catch (std::exception const&)
+  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)
     {
-      return std::string();
+      ret |= BitAtPosOnChunk(ct0,ct1,startBitIdInByte+i);
+      if(i!=0)
+        ret <<= 1;
     }
+  return ret;
+}
+
+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)
index e09064e9a1fc93105c5708defac493ac6426e630..489cefa96e4afc6e1ce5ee7b15d5a6f7629962c0 100644 (file)
@@ -42,9 +42,10 @@ namespace YACS
     class TypeCodeStruct;
     typedef void (*Deallocator)(void *);
 
-
+#ifndef SWIG
     YACSLIBENGINE_EXPORT std::string ToBase64(const std::string& bytes);
     YACSLIBENGINE_EXPORT std::string FromBase64(const std::string& bytes);
+#endif
     
     class YACSLIBENGINE_EXPORT StringOnHeap
     {
index f7ad4f1c6fb95ecb1a0481f916055274194f860b..94b114efdad4c15dac3b0298613b3efac79a3f52 100644 (file)
@@ -694,4 +694,24 @@ namespace YACS
   {
     YACS::ENGINE::UnLoadObserversPluginIfAny();
   }
+
+  PyObject *ToBase64Swig(PyObject *bytes)
+  {
+    char *pt = nullptr;
+    Py_ssize_t length=0;
+    PyBytes_AsStringAndSize(bytes,&pt,&length);
+    std::string input(pt,length);
+    std::string ret(YACS::ENGINE::ToBase64(input));
+    return PyBytes_FromStringAndSize(ret.c_str(),ret.size());
+  }
+
+  PyObject *FromBase64Swig(PyObject *base64Str)
+  {
+    char *pt = nullptr;
+    Py_ssize_t length=0;
+    PyBytes_AsStringAndSize(base64Str,&pt,&length);
+    std::string input(pt,length);
+    std::string ret(YACS::ENGINE::FromBase64(input));
+    return PyBytes_FromStringAndSize(ret.c_str(),ret.size());
+  }
 }