Salome HOME
Python 3: PoC to correctly manage unicode strings from Python
authorGilles DAVID <gilles-g.david@edf.fr>
Wed, 31 May 2017 16:31:32 +0000 (18:31 +0200)
committerGilles DAVID <gilles-g.david@edf.fr>
Wed, 31 May 2017 16:31:34 +0000 (18:31 +0200)
The following use case does not work because of the caracter 'é':
>>> import salome
>>> salome.salome_study_init('/tmp/étude.hdf')

The solution here is to consider Unicode strings coming from all the
interfaces of SALOME modules, and then to convert them to encoded strings.

To do that:
- all IDL "string" parameters should be changed into "wstring".
- all C++ interfaces should have wchar_t* instead of char*
- wchar_t* inputs should then be encoded to char* using an ENCODE function (to be written)
- wchar_t* outputs should be decoded from char* using a DECODE function (to be written)

bin/salome_utils.py
idl/SALOMEDS.idl
src/HDFPersist/HDFfile.cc
src/KERNEL_PY/salome_study.py
src/SALOMEDS/SALOMEDS_StudyManager.cxx
src/SALOMEDS/SALOMEDS_StudyManager_i.cxx
src/SALOMEDS/SALOMEDS_StudyManager_i.hxx

index 67c352f9902ff905d12bbf78fb38c07083bae56c..f292943c4b0320a60e7afeb2301c42fbe148912a 100644 (file)
@@ -56,10 +56,9 @@ def _try_bool( arg ):
     are supported.
     If <arg> does not represent a boolean, an exception is raised.
     """
-    import types
-    if type( arg ) == bool  :
+    if isinstance(arg, bool)  :
         return arg
-    elif type( arg ) == bytes  :
+    elif isinstance(arg, (str, bytes)):
         v = str( arg ).lower()
         if   v in [ "yes", "y", "true"  ]: return True
         elif v in [ "no",  "n", "false" ]: return False
index 3303ac682861693f56aee55907fe5fc854e94c99..f7fb5d26052690fc710b40249ff92b9a47281040 100644 (file)
@@ -878,7 +878,7 @@ Searches for a definite %SObject with a definite GUID and returns True if it fin
 
 <em>See \ref example1 for an example of this method usage in batchmode of %SALOME application.</em>
 */
-    Study Open (in URL aStudyUrl) raises (SALOME::SALOME_Exception);
+    Study Open (in wstring aStudyUrl) raises (SALOME::SALOME_Exception);
 
 /*! \brief Closing the study
 
index 71b44e1129f2cce3f186d5d1ae171b75c5c0e62a..d372e460c2dc61d0a9872c0125e50684b48f4379 100644 (file)
@@ -58,29 +58,36 @@ void HDFfile::CreateOnDisk()
 
 void HDFfile::OpenOnDisk(hdf_access_mode access_mode)
 {
-  _access_mode = access_mode;
+       _access_mode = access_mode;
+       std::string msgerr;
 
-  switch (_access_mode)
-    {
-    case HDF_RDWR :
-      if (access(_name,F_OK))
+       switch (_access_mode)
        {
-         if ((_id = HDFfileCreate(_name)) < 0) 
-           throw HDFexception("Can't open HDF file");
+       case HDF_RDWR:
+               if (access(_name, F_OK))
+               {
+                       if ((_id = HDFfileCreate(_name)) < 0) {
+                               msgerr = "Can't create HDF in RW mode file" + std::string(_name);
+                               throw HDFexception(msgerr.c_str());
+                       }
+               }
+               else if ((_id = HDFfileOpen(_name, _access_mode)) < 0) {
+                       msgerr = "Can't open HDF in RW mode file " + std::string(_name);
+                       throw HDFexception(msgerr.c_str());
+               }
+               break;
+
+       case HDF_RDONLY:
+               if ((_id = HDFfileOpen(_name, _access_mode)) < 0) {
+                       msgerr = "Can't open HDF in RO mode file " + std::string(_name);
+                       throw HDFexception(msgerr.c_str());
+               }
+               break;
+
+       default:
+               msgerr = "Can't open HDF file " + std::string(_name) + " : bad acces option";
+               throw HDFexception(msgerr.c_str());
        }
-      else
-       if ((_id = HDFfileOpen(_name,_access_mode)) < 0)
-         throw HDFexception("Can't open HDF file");
-      break;
-      
-    case HDF_RDONLY :
-      if ((_id = HDFfileOpen(_name,_access_mode)) < 0)
-       throw HDFexception("Can't open HDF file");
-      break;
-      
-    default :
-      throw HDFexception("Can't open HDF file : bad acces option");
-    }
 }
 
 void HDFfile::CloseOnDisk()
index b31fad8998b1972b0bdf0e909da8e5e9645bf674..503dff8fd95024cb9b1e3d2dddb7ab6e91d2b517 100755 (executable)
@@ -399,8 +399,9 @@ def salome_study_init(theStudyPath=None):
     myStudy = None
     myStudyId = getActiveStudy()
     if myStudyId == None :
-        import types
-        if theStudyPath and (type(theStudyPath) == bytes or type(theStudyPath) == str):
+        if theStudyPath and isinstance(theStudyPath, (str, bytes)):
+            if isinstance(theStudyPath, bytes):
+                theStudyPath = str(theStudyPath, 'UTF8')
             myStudyId = openStudy(theStudyPath)
         else:
             myStudyId = createNewStudy()
index ba0a8f20652fc975c66b5730b227923031f6f978..4dc29e939e34b312a158337cd8cfbbbdcdef8c1b 100644 (file)
@@ -117,7 +117,8 @@ _PTR(Study) SALOMEDS_StudyManager::Open(const std::string& theStudyUrl)
   //SRN: Pure CORBA Open as it does more initialization than the local one
   SALOMEDSClient_Study* aStudy = NULL;
 
-  SALOMEDS::Study_var aStudy_impl = _corba_impl->Open((char*)theStudyUrl.c_str());
+  std::wstring wtheStudyUrl = std::wstring(theStudyUrl.begin(), theStudyUrl.end());
+  SALOMEDS::Study_var aStudy_impl = _corba_impl->Open((wchar_t*)theStudyUrl.c_str());
   if(CORBA::is_nil(aStudy_impl)) return  _PTR(Study)(aStudy);
 
   aStudy = new SALOMEDS_Study(aStudy_impl.in());
index 6113ccc98c9e78c8fd6a75ba0c0c218bc4198b50..3826e4f69056178dba8551a17ff5cac60aac8d7d 100644 (file)
@@ -159,13 +159,22 @@ SALOMEDS::Study_ptr SALOMEDS_StudyManager_i::NewStudy(const char* study_name)
  *  Purpose  : Open a Study from it's persistent reference
  */
 //============================================================================
-SALOMEDS::Study_ptr  SALOMEDS_StudyManager_i::Open(const char* aUrl)
+SALOMEDS::Study_ptr  SALOMEDS_StudyManager_i::Open(const wchar_t* aWUrl)
      throw(SALOME::SALOME_Exception)
 {
   SALOMEDS::Locker lock;
 
   Unexpect aCatch(SalomeException);
-  MESSAGE("Begin of SALOMEDS_StudyManager_i::Open");
+
+  // Converts UTF8 url to encoded version
+  setlocale(LC_ALL, "");
+  char aUrl[256];
+  int ret;
+  memset( aUrl, 0, 256);
+  ret = wcstombs(aUrl, aWUrl, 255);
+  if (ret==256) aUrl[255]='\0';
+  MESSAGE("Begin of SALOMEDS_StudyManager_i::Open " << aUrl);
+
 
   #ifndef ALLOW_MULTI_STUDIES
   std::vector<SALOMEDSImpl_Study*> anOpened = _impl->GetOpenStudies();
@@ -180,8 +189,10 @@ SALOMEDS::Study_ptr  SALOMEDS_StudyManager_i::Open(const char* aUrl)
 
   SALOMEDSImpl_Study* aStudyImpl = _impl->Open(std::string(aUrl));
 
-  if ( !aStudyImpl )
-    THROW_SALOME_CORBA_EXCEPTION("Impossible to Open study from file", SALOME::BAD_PARAM)
+  if ( !aStudyImpl ) {
+      std::string errmsg = "Impossible to Open study from file " + std::string(aUrl);
+    THROW_SALOME_CORBA_EXCEPTION(errmsg.c_str(), SALOME::BAD_PARAM)
+  }
 
   MESSAGE("Open : Creating the CORBA servant holding it... ");
 
index ba1daf0eb3684e7504c16a9ff8ec33bb34455486..51830f941e9c13d13160a2fe74caf366ca2b5314 100644 (file)
@@ -89,7 +89,7 @@ public:
     \param char* arguments, the study URL
     \return Study_ptr arguments
   */
-  virtual SALOMEDS::Study_ptr Open(const char* aStudyUrl) throw (SALOME::SALOME_Exception);
+  virtual SALOMEDS::Study_ptr Open(const wchar_t* aStudyUrl) throw (SALOME::SALOME_Exception);
 
 
   //! method to close a Study