Salome HOME
bos #24400 [CEA] Option in SALOME for not storing in med files the indices (number...
[modules/smesh.git] / src / MEDWrapper / MED_Wrapper.cxx
index 117ab89f6da8532fff99c42bb6aa5e74e437abf7..b0c56200e2a7555f564fe80262f1fc409247dca5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "MED_Wrapper.hxx"
 #include "MED_TStructures.hxx"
 #include "MED_Utilities.hxx"
+#include "MED_TFile.hxx"
 
+#include "MEDFileUtilities.hxx"
 #include <med.h>
 #include <med_err.h>
 #include <med_proto.h>
 
+#ifdef WIN32
+#include <windows.h>
+#endif
+
 #include <boost/version.hpp>
 
 #ifdef _DEBUG_
 static int MYDEBUG = 0;
 static int MYVALUEDEBUG = 0;
 #else
-static int MYDEBUG = 0;
-static int MYVALUEDEBUG = 0;
+// static int MYDEBUG = 0;      // unused in release mode
+// static int MYVALUEDEBUG = 0; // unused in release mode
 #endif
 
 namespace MED
@@ -72,73 +78,78 @@ namespace MED
   }
 
   //---------------------------------------------------------------
-  class TFile
+  const TIdt& MEDIDTHoder::Id() const
   {
-    TFile();
-    TFile(const TFile&);
-
-  public:
-    TFile(const std::string& theFileName, TInt theMinor=-1):
-      myCount(0),
-      myFid(0),
-      myFileName(theFileName),
-      myMinor(theMinor)
-    {
-      if ((myMinor < 0) || (myMinor > MED_MINOR_NUM)) myMinor = MED_MINOR_NUM;
-    }
+    if (myFid < 0)
+      EXCEPTION(std::runtime_error, "TFile - GetFid() < 0");
+    return myFid;
+  }
 
-    ~TFile()
+  void TMemFile::Open(EModeAcces theMode, TErr* theErr)
+  {
+    if (this->myCount++ == 0)
     {
-      Close();
+      std::string dftFileName = MEDCoupling::MEDFileWritableStandAlone::GenerateUniqueDftFileNameInMem();
+      med_access_mode modeTmp(MED_ACC_CREAT);
+      if(memfile.app_image_ptr)
+        modeTmp = med_access_mode(theMode);
+      myFid = MEDmemFileOpen(dftFileName.c_str(),&memfile,MED_FALSE,modeTmp);
     }
+    if (theErr)
+      *theErr = TErr(myFid);
+    else if (myFid < 0)
+      EXCEPTION(std::runtime_error,"TMemFile - MEDmemFileOpen");
+  }
 
-    void
-    Open(EModeAcces theMode,
-         TErr* theErr = NULL)
-    {
-      if (myCount++ == 0) {
-        const char* aFileName = myFileName.c_str();
-        myFid = MEDfileVersionOpen(aFileName,med_access_mode(theMode), MED_MAJOR_NUM, myMinor, MED_RELEASE_NUM);
+  TFile::TFile(const std::string& theFileName, TInt theMajor, TInt theMinor):
+    myFileName(theFileName),
+    myMajor(theMajor),
+    myMinor(theMinor)
+  {
+    if ((myMajor < 0) || (myMajor > MED_MAJOR_NUM)) myMajor = MED_MAJOR_NUM;
+    if ((myMinor < 0) || (myMajor == MED_MAJOR_NUM && myMinor > MED_MINOR_NUM)) myMinor = MED_MINOR_NUM;
+  }
+
+  void TFile::Open(EModeAcces theMode, TErr* theErr)
+  {
+    if (myCount++ == 0) {
+      const char* aFileName = myFileName.c_str();
+#ifdef WIN32
+      if (med_access_mode(theMode) == MED_ACC_RDWR) {
+        // Force removing readonly attribute from a file under Windows, because of a bug in the HDF5
+        std::string aReadOlnyRmCmd = "attrib -r \"" + myFileName + "\"> nul 2>&1";
+#ifdef UNICODE
+        const char* to_decode = aReadOlnyRmCmd.c_str();
+        int size_needed = MultiByteToWideChar(CP_UTF8, 0, to_decode, strlen(to_decode), NULL, 0);
+        wchar_t* awReadOlnyRmCmd = new wchar_t[size_needed + 1];
+        MultiByteToWideChar(CP_UTF8, 0, to_decode, strlen(to_decode), awReadOlnyRmCmd, size_needed);
+        awReadOlnyRmCmd[size_needed] = '\0';
+        _wsystem(awReadOlnyRmCmd);
+        delete[] awReadOlnyRmCmd;
+#else
+        system(aReadOlnyRmCmd.c_str());
+#endif
       }
-      if (theErr)
-        *theErr = TErr(myFid);
-      else if (myFid < 0)
-        EXCEPTION(std::runtime_error,"TFile - MEDfileVersionOpen('"<<myFileName<<"',"<<theMode<<"',"<< MED_MAJOR_NUM<<"',"<< myMinor<<"',"<< MED_RELEASE_NUM<<")");
-    }
-
-    const TIdt&
-    Id() const
-    {
-      if (myFid < 0)
-        EXCEPTION(std::runtime_error, "TFile - GetFid() < 0");
-      return myFid;
-    }
-
-    void
-    Close()
-    {
-      if (--myCount == 0)
-        MEDfileClose(myFid);
+#endif
+      myFid = MEDfileVersionOpen(aFileName,med_access_mode(theMode), myMajor, myMinor, MED_RELEASE_NUM);
     }
-
-  protected:
-    TInt myCount;
-    TIdt myFid;
-    std::string myFileName;
-    TInt myMinor;
-  };
+    if (theErr)
+      *theErr = TErr(myFid);
+    else if (myFid < 0)
+      EXCEPTION(std::runtime_error,"TFile - MEDfileVersionOpen('"<<myFileName<<"',"<<theMode<<"',"<< myMajor <<"',"<< myMinor<<"',"<< MED_RELEASE_NUM<<")");
+  }
 
   //---------------------------------------------------------------
   class TFileWrapper
   {
-    PFile myFile;
+    PFileInternal myFile;
     TInt myMinor;
 
   public:
-    TFileWrapper(const PFile& theFile,
-                 EModeAcces theMode,
-                 TErr* theErr = NULL,
-                 TInt theMinor=-1):
+    TFileWrapper(const PFileInternal& theFile,
+                 EModeAcces           theMode,
+                 TErr*                theErr = NULL,
+                 TInt                 theMinor=-1):
       myFile(theFile),
       myMinor(theMinor)
     {
@@ -187,23 +198,25 @@ namespace MED
 
   //---------------------------------------------------------------
   TWrapper
-  ::TWrapper(const std::string& theFileName, TInt theMinor):
-    myFile(new TFile(theFileName, theMinor)),
+  ::TWrapper(const std::string& theFileName, bool write, TFileInternal *tfileInst, TInt theMajor, TInt theMinor):
+    myMajor(theMajor),
     myMinor(theMinor)
   {
+    if(!tfileInst)
+      myFile.reset(new TFile(theFileName, theMajor, theMinor) );
+    else
+      myFile.reset(new TFileDecorator(tfileInst) );
+    
     TErr aRet;
-    myFile->Open(eLECTURE_ECRITURE, &aRet);
-    // if (aRet < 0)
-    //   myFile->Close();
-    //   myFile->Open(eLECTURE_AJOUT, &aRet);
-    // }
-    if (aRet < 0) {
-      myFile->Close();
-      myFile->Open(eLECTURE, &aRet);
+    if ( write ) {
+      myFile->Open(eLECTURE_ECRITURE, &aRet);
+      if (aRet < 0) {
+        myFile->Close();
+        myFile->Open(eCREATION, &aRet);
+      }
     }
-    if (aRet < 0) {
-      myFile->Close();
-      myFile->Open(eCREATION, &aRet);
+    else {
+      myFile->Open(eLECTURE, &aRet);
     }
   }
 
@@ -229,9 +242,9 @@ namespace MED
   //----------------------------------------------------------------------------
   void
   TWrapper
-  ::GetMeshInfo(TInt theMeshId,
+  ::GetMeshInfo(TInt            theMeshId,
                 MED::TMeshInfo& theInfo,
-                TErr* theErr)
+                TErr*           theErr)
   {
     TFileWrapper aFileWrapper(myFile, eLECTURE, theErr, myMinor);
 
@@ -272,7 +285,7 @@ namespace MED
   void
   TWrapper
   ::SetMeshInfo(const MED::TMeshInfo& theInfo,
-                TErr* theErr)
+                TErr*                 theErr)
   {
     TErr aRet;
     SetMeshInfo(theInfo, eLECTURE_ECRITURE, &aRet);
@@ -291,8 +304,8 @@ namespace MED
   void
   TWrapper
   ::SetMeshInfo(const MED::TMeshInfo& theInfo,
-                EModeAcces theMode,
-                TErr* theErr)
+                EModeAcces            theMode,
+                TErr*                 theErr)
   {
     TFileWrapper aFileWrapper(myFile, theMode, theErr, myMinor);
 
@@ -339,10 +352,10 @@ namespace MED
   //----------------------------------------------------------------------------
   PMeshInfo
   TWrapper
-  ::CrMeshInfo(TInt theDim,
-               TInt theSpaceDim,
+  ::CrMeshInfo(TInt               theDim,
+               TInt               theSpaceDim,
                const std::string& theValue,
-               EMaillage theType,
+               EMaillage          theType,
                const std::string& theDesc)
   {
     return PMeshInfo(new TTMeshInfo
@@ -364,7 +377,7 @@ namespace MED
   //----------------------------------------------------------------------------
   PMeshInfo
   TWrapper
-  ::GetPMeshInfo(TInt theId,
+  ::GetPMeshInfo(TInt  theId,
                  TErr* theErr)
   {
     PMeshInfo anInfo = CrMeshInfo();
@@ -376,7 +389,7 @@ namespace MED
   TInt
   TWrapper
   ::GetNbFamilies(const MED::TMeshInfo& theInfo,
-                  TErr* theErr)
+                  TErr*                 theErr)
   {
     TFileWrapper aFileWrapper(myFile, eLECTURE, theErr, myMinor);
 
@@ -391,9 +404,9 @@ namespace MED
   //----------------------------------------------------------------------------
   TInt
   TWrapper
-  ::GetNbFamAttr(TInt theFamId,
+  ::GetNbFamAttr(TInt                  theFamId,
                  const MED::TMeshInfo& theInfo,
-                 TErr* theErr)
+                 TErr*                 theErr)
   {
     TFileWrapper aFileWrapper(myFile, eLECTURE, theErr, myMinor);
 
@@ -410,9 +423,9 @@ namespace MED
   //----------------------------------------------------------------------------
   TInt
   TWrapper
-  ::GetNbFamGroup(TInt theFamId,
+  ::GetNbFamGroup(TInt                  theFamId,
                   const MED::TMeshInfo& theInfo,
-                  TErr* theErr)
+                  TErr*                 theErr)
   {
     TFileWrapper aFileWrapper(myFile, eLECTURE, theErr, myMinor);
 
@@ -429,9 +442,9 @@ namespace MED
   //----------------------------------------------------------------------------
   void
   TWrapper
-  ::GetFamilyInfo(TInt theFamId,
+  ::GetFamilyInfo(TInt              theFamId,
                   MED::TFamilyInfo& theInfo,
-                  TErr* theErr)
+                  TErr*             theErr)
   {
     TFileWrapper aFileWrapper(myFile, eLECTURE, theErr, myMinor);
 
@@ -472,7 +485,7 @@ namespace MED
   void
   TWrapper
   ::SetFamilyInfo(const MED::TFamilyInfo& theInfo,
-                  TErr* theErr)
+                  TErr*                   theErr)
   {
     TErr aRet;
     SetFamilyInfo(theInfo, eLECTURE_ECRITURE, &aRet);
@@ -488,8 +501,8 @@ namespace MED
   void
   TWrapper
   ::SetFamilyInfo(const MED::TFamilyInfo& theInfo,
-                  EModeAcces theMode,
-                  TErr* theErr)
+                  EModeAcces              theMode,
+                  TErr*                   theErr)
   {
     TFileWrapper aFileWrapper(myFile, theMode, theErr, myMinor);
 
@@ -527,10 +540,10 @@ namespace MED
   //----------------------------------------------------------------------------
   PFamilyInfo
   TWrapper
-  ::CrFamilyInfo(const PMeshInfo& theMeshInfo,
-                 TInt theNbGroup,
-                 TInt theNbAttr,
-                 TInt theId,
+  ::CrFamilyInfo(const PMeshInfo&   theMeshInfo,
+                 TInt               theNbGroup,
+                 TInt               theNbAttr,
+                 TInt               theId,
                  const std::string& theValue)
   {
     return PFamilyInfo(new TTFamilyInfo
@@ -544,13 +557,13 @@ namespace MED
   //----------------------------------------------------------------------------
   PFamilyInfo
   TWrapper
-  ::CrFamilyInfo(const PMeshInfo& theMeshInfo,
-                 const std::string& theValue,
-                 TInt theId,
-                 const MED::TStringSet& theGroupNames,
+  ::CrFamilyInfo(const PMeshInfo&          theMeshInfo,
+                 const std::string&        theValue,
+                 TInt                      theId,
+                 const MED::TStringSet&    theGroupNames,
                  const MED::TStringVector& theAttrDescs,
-                 const MED::TIntVector& theAttrIds,
-                 const MED::TIntVector& theAttrVals)
+                 const MED::TIntVector&    theAttrIds,
+                 const MED::TIntVector&    theAttrVals)
   {
     return PFamilyInfo(new TTFamilyInfo
                        (theMeshInfo,
@@ -565,7 +578,7 @@ namespace MED
   //----------------------------------------------------------------------------
   PFamilyInfo
   TWrapper
-  ::CrFamilyInfo(const PMeshInfo& theMeshInfo,
+  ::CrFamilyInfo(const PMeshInfo&   theMeshInfo,
                  const PFamilyInfo& theInfo)
   {
     return PFamilyInfo(new TTFamilyInfo
@@ -577,8 +590,8 @@ namespace MED
   PFamilyInfo
   TWrapper
   ::GetPFamilyInfo(const PMeshInfo& theMeshInfo,
-                   TInt theId,
-                   TErr* theErr)
+                   TInt             theId,
+                   TErr*            theErr)
   {
     // must be reimplemented in connection with mesh type eSTRUCTURE
     //     if (theMeshInfo->GetType() != eNON_STRUCTURE)
@@ -607,11 +620,11 @@ namespace MED
   //----------------------------------------------------------------------------
   void
   TWrapper
-  ::GetNames(TElemInfo& theInfo,
-             TInt theNb,
-             EEntiteMaillage theEntity,
+  ::GetNames(TElemInfo&        theInfo,
+             TInt            /*theNb*/,
+             EEntiteMaillage   theEntity,
              EGeometrieElement theGeom,
-             TErr* theErr)
+             TErr*             theErr)
   {
     TFileWrapper aFileWrapper(myFile, eLECTURE, theErr, myMinor);
 
@@ -645,10 +658,10 @@ namespace MED
   //----------------------------------------------------------------------------
   void
   TWrapper
-  ::SetNames(const TElemInfo& theInfo,
-             EEntiteMaillage theEntity,
+  ::SetNames(const TElemInfo&  theInfo,
+             EEntiteMaillage   theEntity,
              EGeometrieElement theGeom,
-             TErr* theErr)
+             TErr*             theErr)
   {
     SetNames(theInfo, eLECTURE_ECRITURE, theEntity, theGeom, theErr);
   }
@@ -656,11 +669,11 @@ namespace MED
   //----------------------------------------------------------------------------
   void
   TWrapper
-  ::SetNames(const TElemInfo& theInfo,
-             EModeAcces theMode,
-             EEntiteMaillage theEntity,
+  ::SetNames(const TElemInfo&  theInfo,
+             EModeAcces        theMode,
+             EEntiteMaillage   theEntity,
              EGeometrieElement theGeom,
-             TErr* theErr)
+             TErr*             theErr)
   {
     TFileWrapper aFileWrapper(myFile, theMode, theErr, myMinor);
 
@@ -685,7 +698,7 @@ namespace MED
                                  MED_NO_DT,
                                  MED_NO_IT,
                                  anEntity,
-                                  aGeom,
+                                 aGeom,
                                  (TInt)anInfo.myElemNames->size(),
                                  &anElemNames);
       if (theErr)
@@ -698,11 +711,11 @@ namespace MED
   //----------------------------------------------------------------------------
   void
   TWrapper
-  ::GetNumeration(TElemInfo& theInfo,
-                  TInt theNb,
-                  EEntiteMaillage theEntity,
+  ::GetNumeration(TElemInfo&        theInfo,
+                  TInt            /*theNb*/,
+                  EEntiteMaillage   theEntity,
                   EGeometrieElement theGeom,
-                  TErr* theErr)
+                  TErr*             theErr)
   {
     TFileWrapper aFileWrapper(myFile, eLECTURE, theErr, myMinor);
 
@@ -736,10 +749,10 @@ namespace MED
   //----------------------------------------------------------------------------
   void
   TWrapper
-  ::SetNumeration(const TElemInfo& theInfo,
-                  EEntiteMaillage theEntity,
+  ::SetNumeration(const TElemInfo&  theInfo,
+                  EEntiteMaillage   theEntity,
                   EGeometrieElement theGeom,
-                  TErr* theErr)
+                  TErr*             theErr)
   {
     SetNumeration(theInfo, eLECTURE_ECRITURE, theEntity, theGeom, theErr);
   }
@@ -747,11 +760,11 @@ namespace MED
   //----------------------------------------------------------------------------
   void
   TWrapper
-  ::SetNumeration(const TElemInfo& theInfo,
-                  EModeAcces theMode,
-                  EEntiteMaillage theEntity,
+  ::SetNumeration(const TElemInfo&  theInfo,
+                  EModeAcces        theMode,
+                  EEntiteMaillage   theEntity,
                   EGeometrieElement theGeom,
-                  TErr* theErr)
+                  TErr*             theErr)
   {
     TFileWrapper aFileWrapper(myFile, theMode, theErr, myMinor);
 
@@ -789,11 +802,11 @@ namespace MED
   //----------------------------------------------------------------------------
   void
   TWrapper
-  ::GetFamilies(TElemInfo& theInfo,
-                TInt theNb,
-                EEntiteMaillage theEntity,
+  ::GetFamilies(TElemInfo&        theInfo,
+                TInt            /*theNb*/,
+                EEntiteMaillage   theEntity,
                 EGeometrieElement theGeom,
-                TErr* theErr)
+                TErr*             theErr)
   {
     TFileWrapper aFileWrapper(myFile, eLECTURE, theErr, myMinor);
 
@@ -836,10 +849,10 @@ namespace MED
   //----------------------------------------------------------------------------
   void
   TWrapper
-  ::SetFamilies(const TElemInfo& theInfo,
-                EEntiteMaillage theEntity,
+  ::SetFamilies(const TElemInfo&  theInfo,
+                EEntiteMaillage   theEntity,
                 EGeometrieElement theGeom,
-                TErr* theErr)
+                TErr*             theErr)
   {
     SetFamilies(theInfo, eLECTURE_ECRITURE, theEntity, theGeom, theErr);
   }
@@ -847,11 +860,11 @@ namespace MED
   //----------------------------------------------------------------------------
   void
   TWrapper
-  ::SetFamilies(const TElemInfo& theInfo,
-                EModeAcces theMode,
-                EEntiteMaillage theEntity,
+  ::SetFamilies(const TElemInfo&  theInfo,
+                EModeAcces        theMode,
+                EEntiteMaillage   theEntity,
                 EGeometrieElement theGeom,
-                TErr* theErr)
+                TErr*             theErr)
   {
     TFileWrapper aFileWrapper(myFile, theMode, theErr, myMinor);
 
@@ -888,7 +901,7 @@ namespace MED
   TInt
   TWrapper
   ::GetNbNodes(const MED::TMeshInfo& theMeshInfo,
-               TErr* theErr)
+               TErr*                 theErr)
   {
     return GetNbNodes(theMeshInfo, eCOOR, theErr);
   }
@@ -2061,6 +2074,24 @@ namespace MED
     TValueHolder<EConnectivite, med_connectivity_mode> aConnMode    (theInfo.myConnMode);
 
     TErr aRet;
+    med_bool dummy;
+    aRet = MEDmeshnEntity(myFile->Id(),
+                          &aMeshName,
+                          MED_NO_DT,
+                          MED_NO_IT,
+                          anEntity,
+                          aGeom,
+                          MED_NAME,
+                          aConnMode,
+                          &dummy, &dummy);
+    if ( aRet > 0 )
+    {
+      // names are present in the file, they will be read in spite of theInfo.myIsElemNames
+      theInfo.myIsElemNames = eVRAI;
+      theInfo.myElemNames.reset( new TString( theInfo.myNbElem * GetPNOMLength() + 1 ));
+      anElemNames.myRepresentation = & ((TString&) theInfo.myElemNames )[0];
+    }
+
     aRet = MEDmeshElementRd(myFile->Id(),
                             &aMeshName,
                             MED_NO_DT,
@@ -2083,11 +2114,11 @@ namespace MED
       EXCEPTION(std::runtime_error, "GetCellInfo - MEDmeshElementRd(...)");
 
     if (anIsFamNum == MED_FALSE)
-      {
-        int mySize = (int) theInfo.myFamNum->size();
-        theInfo.myFamNum->clear();
-        theInfo.myFamNum->resize(mySize, 0);
-      }
+    {
+      int mySize = (int) theInfo.myFamNum->size();
+      theInfo.myFamNum->clear();
+      theInfo.myFamNum->resize(mySize, 0);
+    }
 
   }
 
@@ -2177,14 +2208,14 @@ namespace MED
   //----------------------------------------------------------------------------
   PCellInfo
   TWrapper
-  ::CrCellInfo(const PMeshInfo& theMeshInfo,
-               EEntiteMaillage theEntity,
+  ::CrCellInfo(const PMeshInfo&  theMeshInfo,
+               EEntiteMaillage   theEntity,
                EGeometrieElement theGeom,
-               TInt theNbElem,
-               EConnectivite theConnMode,
-               EBooleen theIsElemNum,
-               EBooleen theIsElemNames,
-               EModeSwitch theMode)
+               TInt              theNbElem,
+               EConnectivite     theConnMode,
+               EBooleen          theIsElemNum,
+               EBooleen          theIsElemNames,
+               EModeSwitch       theMode)
   {
     return PCellInfo(new TTCellInfo
                      (theMeshInfo,
@@ -2283,7 +2314,7 @@ namespace MED
   //----------------------------------------------------------------------------
   EGeometrieElement
   TWrapper
-  ::GetBallGeom(const TMeshInfo& theMeshInfo)
+  ::GetBallGeom(const TMeshInfo& /*theMeshInfo*/)
   {
     TErr anError;
     TFileWrapper aFileWrapper(myFile, eLECTURE, &anError, myMinor);
@@ -2424,7 +2455,7 @@ namespace MED
 
     // write node ids
     SetCellInfo(theInfo, theMode, theErr);
-    if (theErr && theErr < 0)
+    if (theErr && *theErr < 0)
       return;
 
     // write diameter
@@ -2723,7 +2754,7 @@ namespace MED
   //----------------------------------------------------------------------------
   void
   TWrapper
-  ::GetGaussInfo(TInt theId,
+  ::GetGaussInfo(TInt /*theId*/,
                  TGaussInfo& theInfo,
                  TErr* theErr)
   {
@@ -3087,7 +3118,7 @@ namespace MED
   //----------------------------------------------------------------------------
   void
   TWrapper
-  ::GetProfileInfo(TInt theId,
+  ::GetProfileInfo(TInt /*theId*/,
                    TProfileInfo& theInfo,
                    TErr* theErr)
   {
@@ -3966,7 +3997,7 @@ namespace MED
   //----------------------------------------------------------------------------
   PGrilleInfo
   TWrapper
-  ::CrGrilleInfo(const PMeshInfo& theMeshInfo)
+  ::CrGrilleInfo(const PMeshInfo& /*theMeshInfo*/)
   {
     return PGrilleInfo(); // not implemented????
   }