Salome HOME
22308: EDF 2572 SMESH: Can't import a file with a non ascii character in the path
authoreap <eap@opencascade.com>
Fri, 21 Mar 2014 10:53:47 +0000 (14:53 +0400)
committereap <eap@opencascade.com>
Fri, 21 Mar 2014 10:53:47 +0000 (14:53 +0400)
 Replace OSD_Path, which does not support non-ascii coding, by SMESH_File

src/DriverSTL/DriverSTL_R_SMDS_Mesh.cxx
src/DriverSTL/DriverSTL_R_SMDS_Mesh.h
src/DriverSTL/DriverSTL_W_SMDS_Mesh.cxx
src/SMESHUtils/SMESH_File.cxx
src/SMESHUtils/SMESH_File.hxx
src/SMESH_I/SMESH_Mesh_i.cxx

index 0f01bff..ee4da4a 100644 (file)
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-#include <stdio.h>
-#include <gp_Pnt.hxx>
-#include <Basics_Utils.hxx>
-
-//=======================================================================
-//function : HashCode
-//purpose  : 
-//=======================================================================
-inline Standard_Integer HashCode
-  (const gp_Pnt& point,  Standard_Integer Upper)
-{
-  union 
-    {
-    Standard_Real R[3];
-    Standard_Integer I[6];
-    } U;
-
-  point.Coord(U.R[0],U.R[1],U.R[2]);  
-
-  return ::HashCode(U.I[0]/23+U.I[1]/19+U.I[2]/17+U.I[3]/13+U.I[4]/11+U.I[5]/7,Upper);
-}
-static Standard_Real tab1[3];
-static Standard_Real tab2[3];
-//=======================================================================
-//function : IsEqual
-//purpose  : 
-//=======================================================================
-inline Standard_Boolean IsEqual
-  (const gp_Pnt& point1, const gp_Pnt& point2)
-{
-  point1.Coord(tab1[0],tab1[1],tab1[2]);  
-  point2.Coord(tab2[0],tab2[1],tab2[2]);  
-  return (memcmp(tab1,tab2,sizeof(tab1)) == 0);
-}
 #include "DriverSTL_R_SMDS_Mesh.h"
 
 #include "SMDS_Mesh.hxx"
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "SMESH_File.hxx"
 
-#include <OSD_Path.hxx>
-#include <OSD_File.hxx>
-#include <OSD_FromWhere.hxx>
-#include <OSD_Protection.hxx>
-#include <OSD_SingleProtection.hxx>
-#include <Standard_NoMoreObject.hxx>
-
-#include "utilities.h"
+#include <gp_Pnt.hxx>
+#include <Basics_Utils.hxx>
 
-static const int HEADER_SIZE           =  84;
-static const int SIZEOF_STL_FACET      =  50;
-//static const int STL_MIN_FILE_SIZE     = 284;
-static const int ASCII_LINES_PER_FACET =   7;
+#include <NCollection_DataMap.hxx>
+#include <Standard_NoMoreObject.hxx>
 
+namespace
+{
+  struct Hasher
+  {
+    //=======================================================================
+    //function : HashCode
+    //purpose  :
+    //=======================================================================
+    inline static Standard_Integer HashCode
+    (const gp_Pnt& point,  Standard_Integer Upper)
+    {
+      union
+      {
+        Standard_Real    R[3];
+        Standard_Integer I[6];
+      } U;
 
-//typedef NCollection_BaseCollection<SMDS_MeshNodePtr> DriverSTL_ColOfNodePtr;
+      point.Coord( U.R[0], U.R[1], U.R[2] );
 
+      return ::HashCode(U.I[0]/23+U.I[1]/19+U.I[2]/17+U.I[3]/13+U.I[4]/11+U.I[5]/7,Upper);
+    }
+    //=======================================================================
+    //function : IsEqual
+    //purpose  :
+    //=======================================================================
+    inline static Standard_Boolean IsEqual
+    (const gp_Pnt& point1, const gp_Pnt& point2)
+    {
+      static Standard_Real tab1[3], tab2[3];
+      point1.Coord(tab1[0],tab1[1],tab1[2]);
+      point2.Coord(tab2[0],tab2[1],tab2[2]);
+      return (memcmp(tab1,tab2,sizeof(tab1)) == 0);
+    }
+  };
+  typedef NCollection_DataMap<gp_Pnt,SMDS_MeshNode*,Hasher> TDataMapOfPntNodePtr;
+
+  const int HEADER_SIZE           = 84;
+  const int SIZEOF_STL_FACET      = 50;
+  const int ASCII_LINES_PER_FACET = 7;
+  const int SIZE_OF_FLOAT         = 4;
+  // const int STL_MIN_FILE_SIZE     = 284;
+}
 
-#include <NCollection_DataMap.hxx>
-typedef NCollection_DataMap<gp_Pnt,SMDS_MeshNode*> DriverSTL_DataMapOfPntNodePtr;
 //=======================================================================
 //function : DriverSTL_R_SMDS_Mesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 DriverSTL_R_SMDS_Mesh::DriverSTL_R_SMDS_Mesh()
@@ -110,42 +106,29 @@ Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::Perform()
 
   Status aResult = DRS_OK;
 
-  TCollection_AsciiString aFileName( (char *)myFile.c_str() );
-  if ( aFileName.IsEmpty() ) {
+  if ( myFile.empty() ) {
     fprintf(stderr, ">> ERREOR : invalid file name \n");
     return DRS_FAIL;
   }
 
-  filebuf fic;
-  Standard_IStream is(&fic);
-  if (!fic.open(aFileName.ToCString(),ios::in)) {
-    fprintf(stderr, ">> ERROR : cannot open file %s \n", aFileName.ToCString());
+  SMESH_File file( myFile, /*open=*/false );
+  if ( !file.open() ) {
+    fprintf(stderr, ">> ERROR : cannot open file %s \n", myFile.c_str());
     return DRS_FAIL;
   }
 
-
-  OSD_Path aPath( aFileName );
-  OSD_File file = OSD_File( aPath );
-  file.Open(OSD_ReadOnly,OSD_Protection(OSD_RWD,OSD_RWD,OSD_RWD,OSD_RWD));
-  unsigned char str[128];
-  Standard_Integer lread,i;
-  Standard_Address ach;
-  ach = (Standard_Address)str;
   // we skip the header which is in Ascii for both modes
-  file.Read(ach,HEADER_SIZE,lread);
+  const char* data = file;
+  data += HEADER_SIZE;
 
-  // we read 128 characters to detect if we have a non-ascii char
-  file.Read(ach,sizeof(str),lread);
-  
+  // we check 128 characters to detect if we have a non-ascii char
   myIsAscii = Standard_True;
-  for (i = 0; i < lread; ++i) {
-    if (str[i] > '~') {
+  for (int i = 0; i < 128; ++i, ++data) {
+    if ( !isascii( *data ) && data < file.end() ) {
       myIsAscii = Standard_False;
       break;
     }
   }
-      
-  file.Close();
 
   if ( !myMesh ) {
     fprintf(stderr, ">> ERREOR : cannot create mesh \n");
@@ -153,37 +136,34 @@ Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::Perform()
   }
 
   if ( myIsAscii )
-    aResult = readAscii();
+    aResult = readAscii( file );
   else
-    aResult = readBinary();
+    aResult = readBinary( file );
 
   return aResult;
 }
 
 // static methods
 
-static Standard_Real readFloat(OSD_File& theFile)
+static Standard_Real readFloat(SMESH_File& theFile)
 {
   union {
-    Standard_Boolean i; 
+    Standard_Boolean i;
     Standard_ShortReal f;
-  }u;
+  } u;
 
-  char c[4];
-  Standard_Address adr;
-  adr = (Standard_Address)c;
-  Standard_Integer lread;
-  theFile.Read(adr,4,lread);
+  const char* c = theFile;
   u.i  =  c[0] & 0xFF;
   u.i |= (c[1] & 0xFF) << 0x08;
   u.i |= (c[2] & 0xFF) << 0x10;
   u.i |= (c[3] & 0xFF) << 0x18;
+  theFile += SIZE_OF_FLOAT;
 
   return u.f;
 }
 
 static SMDS_MeshNode* addNode(const gp_Pnt& P,
-                              DriverSTL_DataMapOfPntNodePtr& uniqnodes,
+                              TDataMapOfPntNodePtr& uniqnodes,
                               SMDS_Mesh* theMesh)
 {
   SMDS_MeshNode* node = 0;
@@ -198,7 +178,7 @@ static SMDS_MeshNode* addNode(const gp_Pnt& P,
 }                                
 
 static SMDS_MeshNode* readNode(FILE* file,
-                               DriverSTL_DataMapOfPntNodePtr& uniqnodes,
+                               TDataMapOfPntNodePtr& uniqnodes,
                                SMDS_Mesh* theMesh)
 {
   Standard_ShortReal coord[3];
@@ -209,17 +189,16 @@ static SMDS_MeshNode* readNode(FILE* file,
   return addNode( P, uniqnodes, theMesh );
 }
 
-static SMDS_MeshNode* readNode(OSD_File& theFile,
-                               DriverSTL_DataMapOfPntNodePtr& uniqnodes,
+static SMDS_MeshNode* readNode(SMESH_File& theFile,
+                               TDataMapOfPntNodePtr& uniqnodes,
                                SMDS_Mesh* theMesh)
 {
-  Standard_ShortReal coord[3];
-  coord[0] = readFloat(theFile);
-  coord[1] = readFloat(theFile);
-  coord[2] = readFloat(theFile);
+  gp_Pnt coord;
+  coord.SetX( readFloat(theFile));
+  coord.SetY( readFloat(theFile));
+  coord.SetZ( readFloat(theFile));
 
-  gp_Pnt P(coord[0],coord[1],coord[2]);
-  return addNode( P, uniqnodes, theMesh );
+  return addNode( coord, uniqnodes, theMesh );
 }
 
 //=======================================================================
@@ -227,35 +206,30 @@ static SMDS_MeshNode* readNode(OSD_File& theFile,
 //purpose  : 
 //=======================================================================
 
-Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::readAscii() const
+Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::readAscii(SMESH_File& theFile) const
 {
   Status aResult = DRS_OK;
-  long ipos;
-  Standard_Integer nbLines = 0;
 
-  // Open the file 
-  TCollection_AsciiString aFileName( (char *)myFile.c_str() );
-  FILE* file = fopen(aFileName.ToCString(),"r");
-  fseek(file,0L,SEEK_END);
   // get the file size
-  long filesize = ftell(file);
-  fclose(file);
-  file = fopen(aFileName.ToCString(),"r");
-  
+  long filesize = theFile.size();
+  theFile.close();
+
+  // Open the file 
+  FILE* file = fopen( myFile.c_str(),"r");
+
   // count the number of lines
-  for (ipos = 0; ipos < filesize; ++ipos) {
+  Standard_Integer nbLines = 0;
+  for (long ipos = 0; ipos < filesize; ++ipos) {
     if (getc(file) == '\n')
       nbLines++;
   }
 
   // go back to the beginning of the file
-//  fclose(file);
-//  file = fopen(aFileName.ToCString(),"r");
   rewind(file);
   
   Standard_Integer nbTri = (nbLines / ASCII_LINES_PER_FACET);
 
-  DriverSTL_DataMapOfPntNodePtr uniqnodes;
+  TDataMapOfPntNodePtr uniqnodes;
   // skip header
   while (getc(file) != '\n');
 
@@ -293,23 +267,14 @@ Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::readAscii() const
 //purpose  : 
 //=======================================================================
 
-Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::readBinary() const
+Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::readBinary(SMESH_File& file) const
 {
   Status aResult = DRS_OK;
 
-  char buftest[5];
-  Standard_Address adr;
-  adr = (Standard_Address)buftest;
-
-  TCollection_AsciiString aFileName( (char *)myFile.c_str() );
-  OSD_File aFile = OSD_File(OSD_Path( aFileName ));
-  aFile.Open(OSD_ReadOnly,OSD_Protection(OSD_RWD,OSD_RWD,OSD_RWD,OSD_RWD));
-
   // the size of the file (minus the header size)
   // must be a multiple of SIZEOF_STL_FACET
 
-  // compute file size
-  Standard_Integer filesize = aFile.Size();
+  long filesize = file.size();
 
   if ( (filesize - HEADER_SIZE) % SIZEOF_STL_FACET !=0 
       // Commented to allow reading small files (ex: 1 face)
@@ -322,29 +287,25 @@ Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::readBinary() const
   Standard_Integer nbTri = ((filesize - HEADER_SIZE) / SIZEOF_STL_FACET);
 
   // skip the header
-  aFile.Seek(HEADER_SIZE,OSD_FromBeginning);
+  file += HEADER_SIZE;
 
-  DriverSTL_DataMapOfPntNodePtr uniqnodes;
-  Standard_Integer lread;
+  TDataMapOfPntNodePtr uniqnodes;
   
   for (Standard_Integer iTri = 0; iTri < nbTri; ++iTri) {
 
     // ignore normals
-    readFloat(aFile);
-    readFloat(aFile);
-    readFloat(aFile);
+    file += 3 * SIZE_OF_FLOAT;
 
     // read vertices
-    SMDS_MeshNode* node1 = readNode( aFile, uniqnodes, myMesh );
-    SMDS_MeshNode* node2 = readNode( aFile, uniqnodes, myMesh );
-    SMDS_MeshNode* node3 = readNode( aFile, uniqnodes, myMesh );
+    SMDS_MeshNode* node1 = readNode( file, uniqnodes, myMesh );
+    SMDS_MeshNode* node2 = readNode( file, uniqnodes, myMesh );
+    SMDS_MeshNode* node3 = readNode( file, uniqnodes, myMesh );
 
     if (myIsCreateFaces)
       myMesh->AddFace(node1,node2,node3);
 
     // skip extra bytes
-    aFile.Read(adr,2,lread);
+    file += 2;
   }
-  aFile.Close();
   return aResult;
 }
index b1f924b..75df49c 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "Driver_SMDS_Mesh.h"
 
-#include <Standard_TypeDef.hxx>
+class SMESH_File;
 
 class MESHDRIVERSTL_EXPORT DriverSTL_R_SMDS_Mesh: public Driver_SMDS_Mesh
 {
@@ -38,8 +38,8 @@ class MESHDRIVERSTL_EXPORT DriverSTL_R_SMDS_Mesh: public Driver_SMDS_Mesh
   
  private:
   // PRIVATE METHODS
-  Status           readAscii() const;
-  Status           readBinary() const;
+  Status           readAscii (SMESH_File& file) const;
+  Status           readBinary(SMESH_File& file) const;
   
  private:
   // PRIVATE FIELDS
index 6d572ca..5499183 100644 (file)
@@ -20,9 +20,6 @@
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-#include <stdio.h>
-#include <limits>
-
 #include "DriverSTL_W_SMDS_Mesh.h"
 
 #include "SMDS_FaceOfNodes.hxx"
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_SetIterator.hxx"
 #include "SMDS_VolumeTool.hxx"
+#include "SMESH_File.hxx"
 #include "SMESH_TypeDefs.hxx"
 
-#include <OSD_File.hxx>
-#include <OSD_Path.hxx>
-#include <OSD_Protection.hxx>
-#include <TCollection_AsciiString.hxx>
-#include <gp_XYZ.hxx>
 #include <Basics_Utils.hxx>
 
-#include "utilities.h"
+//#include "utilities.h"
+
+#include <limits>
+
 
 // definition des constantes 
 static const int LABEL_SIZE = 80;
@@ -147,7 +143,7 @@ SMDS_ElemIteratorPtr DriverSTL_W_SMDS_Mesh::getFaces() const
 
 // static methods
 
-static void writeInteger( const Standard_Integer& theVal, OSD_File& ofile )
+static void writeInteger( const Standard_Integer& theVal, SMESH_File& ofile )
 {
   union {
     Standard_Integer i;
@@ -162,16 +158,15 @@ static void writeInteger( const Standard_Integer& theVal, OSD_File& ofile )
   entier |= (u.c[2] & 0xFF) << 0x10;
   entier |= (u.c[3] & 0xFF) << 0x18;
 
-  ofile.Write((char *)&entier,sizeof(u.c));
+  ofile.write( entier );
 }
 
-static void writeFloat  ( const Standard_ShortReal& theVal,
-                         OSD_File& ofile)
+static void writeFloat( const Standard_ShortReal& theVal, SMESH_File& ofile)
 {
   union {
     Standard_ShortReal f;
     char c[4]; 
-  }u;
+  } u;
 
   u.f = theVal;
 
@@ -182,7 +177,7 @@ static void writeFloat  ( const Standard_ShortReal& theVal,
   entier |= (u.c[2] & 0xFF) << 0x10;
   entier |= (u.c[3] & 0xFF) << 0x18;
 
-  ofile.Write((char *)&entier,sizeof(u.c));
+  ofile.write( entier );
 }
 
 static gp_XYZ getNormale( const SMDS_MeshNode* n1,
@@ -287,19 +282,18 @@ static int getTriangles( const SMDS_MeshElement* face,
 Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeAscii() const
 {
   Status aResult = DRS_OK;
-  TCollection_AsciiString aFileName( (char *)myFile.c_str() );
-  if ( aFileName.IsEmpty() ) {
+  if ( myFile.empty() ) {
     fprintf(stderr, ">> ERREOR : invalid file name \n");
     return DRS_FAIL;
   }
 
-  OSD_File aFile = OSD_File(OSD_Path(aFileName));
-  aFile.Build(OSD_WriteOnly,OSD_Protection());
+  SMESH_File aFile( myFile, /*openForReading=*/false );
+  aFile.openForWriting();
 
-  char sval[16];
-  TCollection_AsciiString buf = TCollection_AsciiString ("solid\n");
-  aFile.Write (buf,buf.Length());buf.Clear();
+  std::string buf("solid\n");
+  aFile.writeRaw( buf.c_str(), buf.size() );
 
+  char sval[128];
   const SMDS_MeshNode* triaNodes[2048];
 
   SMDS_ElemIteratorPtr itFaces = getFaces();
@@ -313,45 +307,25 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeAscii() const
       gp_XYZ normale = getNormale( triaNodes[iN],
                                    triaNodes[iN+1],
                                    triaNodes[iN+2] );
+      sprintf (sval,
+               " facet normal % 12e % 12e % 12e\n"
+               "   outer loop\n" ,
+               normale.X(), normale.Y(), normale.Z());
+      aFile.writeRaw ( sval, 70 );
 
-      buf += " facet normal "; 
-      sprintf (sval,"% 12e",normale.X());
-      buf += sval;
-      buf += " "; 
-      sprintf (sval,"% 12e",normale.Y());
-      buf += sval;
-      buf += " "; 
-      sprintf (sval,"% 12e",normale.Z());
-      buf += sval;
-      buf += '\n';
-      aFile.Write (buf,buf.Length());buf.Clear();
-      buf += "   outer loop\n"; 
-      aFile.Write (buf,buf.Length());buf.Clear();
-      
-      for ( int jN = 0; jN < 3; ++jN, ++iN ) {
-        const SMDS_MeshNode* node = triaNodes[iN];
-        buf += "     vertex "; 
-        sprintf (sval,"% 12e",node->X());
-        buf += sval;
-        buf += " "; 
-        sprintf (sval,"% 12e",node->Y());
-        buf += sval;
-        buf += " "; 
-        sprintf (sval,"% 12e",node->Z());
-        buf += sval;
-        buf += '\n';
-        aFile.Write (buf,buf.Length());buf.Clear();
+      for ( int jN = 0; jN < 3; ++jN, ++iN )
+      {
+        SMESH_TNodeXYZ node = triaNodes[iN];
+        sprintf (sval,
+                 "     vertex % 12e % 12e % 12e\n",
+                 node.X(), node.Y(), node.Z() );
+        aFile.writeRaw ( sval, 54 );
       }
-      buf += "   endloop\n"; 
-      aFile.Write (buf,buf.Length());buf.Clear();
-      buf += " endfacet\n"; 
-      aFile.Write (buf,buf.Length());buf.Clear();
+      aFile.writeRaw ("   endloop\n"
+                      " endfacet\n", 21 );
     } 
   }
-  buf += "endsolid\n";
-  aFile.Write (buf,buf.Length());buf.Clear();
-  
-  aFile.Close ();
+  aFile.writeRaw ("endsolid\n" , 9 );
 
   return aResult;
 }
@@ -366,14 +340,14 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeAscii() const
 Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeBinary() const
 {
   Status aResult = DRS_OK;
-  TCollection_AsciiString aFileName( (char *)myFile.c_str() );
-  if ( aFileName.IsEmpty() ) {
+
+  if ( myFile.empty() ) {
     fprintf(stderr, ">> ERREOR : invalid filename \n");
     return DRS_FAIL;
   }
 
-  OSD_File aFile = OSD_File(OSD_Path(aFileName));
-  aFile.Build(OSD_WriteOnly,OSD_Protection());
+  SMESH_File aFile( myFile );
+  aFile.openForWriting();
 
   // we first count the number of triangles
   int nbTri = myVolumeTrias.size();
@@ -384,12 +358,11 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeBinary() const
       nbTri += getNbTriangles( aFace );
     }
   }
-  // char sval[80]; -- avoid writing not initialized memory
-  TCollection_AsciiString sval(LABEL_SIZE-1,' ');
-  aFile.Write((Standard_Address)sval.ToCString(),LABEL_SIZE);
+  std::string sval( LABEL_SIZE, ' ' );
+  aFile.write( sval.c_str(), LABEL_SIZE );
 
   // write number of triangles
-  writeInteger(nbTri,aFile);  
+  writeInteger( nbTri, aFile );  
 
   // Loop writing nodes
 
@@ -419,10 +392,9 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeBinary() const
         writeFloat(node->Y(),aFile);
         writeFloat(node->Z(),aFile);
       }
-      aFile.Write (&dum,2);
-    } 
+      aFile.writeRaw ( &dum, 2 );
+    }
   }
-  aFile.Close ();
 
   return aResult;
 }
index b2549e7..ae5f9bb 100644 (file)
 #include "SMESH_File.hxx"
 #include "utilities.h"
 
-#include <OSD_File.hxx>
-#include <OSD_Path.hxx>
-#include <Standard_ProgramError.hxx>
-#include <Standard_ErrorHandler.hxx>
-#include <Standard_Failure.hxx>
-
 #include <fcntl.h>
 #include <sys/stat.h>
 
 #include <sys/mman.h>
 #endif
 
+#include <boost/filesystem.hpp>
+
+namespace boofs = boost::filesystem;
+
 //================================================================================
 /*!
  * \brief Creator opening the file for reading by default
@@ -133,6 +131,16 @@ void SMESH_File::close()
     _pos = _end = 0;
     _size = -1;
   }
+  else if ( _file >= 0 )
+  {
+#ifdef WIN32
+    CloseHandle(_file);
+    _file = INVALID_HANDLE_VALUE;
+#else
+    ::close(_file);
+    _file = -1;
+#endif
+  }
 }
 
 //================================================================================
@@ -144,15 +152,12 @@ void SMESH_File::close()
 bool SMESH_File::remove()
 {
   close();
-  try {
-    OSD_Path filePath(TCollection_AsciiString((char*)_name.data()));
-    OSD_File(filePath).Remove();
-  }
-  catch ( Standard_ProgramError ) {
-    MESSAGE("Can't remove file: " << _name << " ; file does not exist or permission denied");
-    return false;
-  }
-  return true;
+
+  boost::system::error_code err;
+  boofs::remove( _name, err );
+  _error = err.message();
+
+  return !err;
 }
 
 //================================================================================
@@ -161,21 +166,45 @@ bool SMESH_File::remove()
  */
 //================================================================================
 
-int SMESH_File::size() const
+long SMESH_File::size()
 {
-  if ( _size >= 0 ) return _size; // size of open file
+  if ( _size >= 0 ) return _size; // size of an open file
 
-  int size = -1;
-  int file = ::open( _name.data(), O_RDONLY );
-  if ( file > 0 )
-  {
-    struct stat status;
-    int err = fstat( file, &status);
-    if ( !err )
-      size = status.st_size;
-    ::close( file );
-  }
-  return size;
+  boost::system::error_code err;
+  uintmax_t size = boofs::file_size( _name, err );
+  _error = err.message();
+
+  return err ? -1 : (long) size;
+}
+
+//================================================================================
+/*!
+ * \brief Check existence
+ */
+//================================================================================
+
+bool SMESH_File::exists()
+{
+  boost::system::error_code err;
+  bool res = boofs::exists( _name, err );
+  _error = err.message();
+
+  return err ? false : res;
+}
+
+//================================================================================
+/*!
+ * \brief Check existence
+ */
+//================================================================================
+
+bool SMESH_File::isDirectory()
+{
+  boost::system::error_code err;
+  bool res = boofs::is_directory( _name, err );
+  _error = err.message();
+
+  return err ? false : res;
 }
 
 //================================================================================
@@ -238,3 +267,56 @@ bool SMESH_File::getInts(std::vector<int>& ints)
   }
   return ( i == ints.size() );
 }
+
+//================================================================================
+/*!
+ * \brief Open for binary writing only.
+ */
+//================================================================================
+
+bool SMESH_File::openForWriting()
+{
+#ifdef WIN32
+
+  _file = CreateFile( _name.c_str(),          // name of the write
+                      GENERIC_WRITE,          // open for writing
+                      0,                      // do not share
+                      NULL,                   // default security
+                      OPEN_ALWAYS,            // CREATE NEW or OPEN EXISTING
+                      FILE_ATTRIBUTE_NORMAL,  // normal file
+                      NULL);                  // no attr. template
+  return ( _file != INVALID_HANDLE_VALUE );
+
+#else
+
+  _file = ::open( _name.c_str(),
+                  O_WRONLY | O_CREAT,
+                  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ); // rw-r--r--
+  return _file >= 0;
+
+#endif
+}
+
+//================================================================================
+/*!
+ * \brief Write binary data
+ */
+//================================================================================
+
+bool SMESH_File::writeRaw(const void* data, size_t size)
+{
+#ifdef WIN32
+
+  DWORD nbWritten = 0;
+  BOOL err = WriteFile( _file, data, size, & nbWritten, NULL);
+
+  return (( err == FALSE ) &&
+          ( nbWritten == (DWORD) size ));
+
+#else
+
+  ssize_t nbWritten = ::write( _file, data, size );
+  return ( nbWritten == size );
+
+#endif
+}
index 5232fec..0e7ccca 100644 (file)
@@ -42,24 +42,30 @@ class SMESHUtils_EXPORT SMESH_File
 {
 public:
 
-  SMESH_File(const std::string& name, bool open=true);
+  SMESH_File(const std::string& name, bool openForReading=true);
 
   ~SMESH_File();
 
   std::string getName() const { return _name; }
 
-  bool open();
+  const std::string& error() const { return _error; }
 
   void close();
 
   bool remove();
 
-  int size() const;
+  long size();
+
+  bool exists();
+
+  bool isDirectory();
 
   // ------------------------
   // Access to file contents
   // ------------------------
 
+  bool open(); // for reading
+
   operator const char*() const { return _pos; }
 
   bool operator++() { return ++_pos < _end; }
@@ -68,6 +74,8 @@ public:
 
   bool eof() const { return _pos >= _end; }
 
+  const char* end() const { return _end; }
+
   const char* getPos() const { return _pos; }
 
   void setPos(const char* pos);
@@ -78,10 +86,31 @@ public:
 
   bool getInts(std::vector<int>& ids);
 
+  // ------------------------
+  // Writting a binary file
+  // ------------------------
+
+  bool openForWriting(); // binary writing only
+
+  template <typename T>
+    bool write( const T* values, size_t nbTValues )
+  {
+    return writeRaw((const void*) values, nbTValues * sizeof(T));
+  }
+
+  template <typename T>
+    bool write( const T& value )
+  {
+    return writeRaw((const void*) & value, sizeof(T));
+  }
+
+  bool writeRaw(const void* data, size_t size);
+
 private:
 
   std::string _name; //!< file name
   int         _size; //!< file size
+  std::string _error;
 #ifdef WIN32
   HANDLE      _file, _mapObj;
 #else
index 2b230a5..b0c453b 100644 (file)
 #include "SMESHDS_Group.hxx"
 #include "SMESHDS_GroupOnGeom.hxx"
 #include "SMESH_Controls.hxx"
+#include "SMESH_File.hxx"
 #include "SMESH_Filter_i.hxx"
 #include "SMESH_Gen_i.hxx"
 #include "SMESH_Group.hxx"
 #include "SMESH_Group_i.hxx"
+#include "SMESH_Mesh.hxx"
 #include "SMESH_MeshAlgos.hxx"
 #include "SMESH_MeshEditor.hxx"
 #include "SMESH_MeshEditor_i.hxx"
 #include "SMESH_PythonDump.hxx"
 #include "SMESH_subMesh_i.hxx"
 
-#include <OpUtil.hxx>
 #include <SALOMEDS_Attributes_wrap.hxx>
 #include <SALOMEDS_wrap.hxx>
-#include <SALOME_NamingService.hxx>
 #include <Utils_ExceptHandlers.hxx>
-#include <Utils_SINGLETON.hxx>
 #include <utilities.h>
 
 #include <GEOMImpl_Types.hxx>
 
 // OCCT Includes
 #include <BRep_Builder.hxx>
-#include <OSD_Directory.hxx>
-#include <OSD_File.hxx>
-#include <OSD_Path.hxx>
-#include <OSD_Protection.hxx>
-#include <Standard_OutOfMemory.hxx>
-#include <TColStd_MapIteratorOfMapOfInteger.hxx>
+#include <Standard_ErrorHandler.hxx>
 #include <TColStd_MapOfInteger.hxx>
-#include <TColStd_SequenceOfInteger.hxx>
-#include <TCollection_AsciiString.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_MapIteratorOfMapOfShape.hxx>
 
 // STL Includes
 #include <algorithm>
-#include <string>
 #include <iostream>
 #include <sstream>
 
-#include <sys/stat.h>
-
 // to pass CORBA exception through SMESH_TRY
 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
 
@@ -404,14 +393,7 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
   _medFileInfo->major    = major;
   _medFileInfo->minor    = minor;
   _medFileInfo->release  = release;
-#ifdef WIN32
-  struct _stati64 d;
-  if ( ::_stati64( theFileName, &d ) != -1 )
-#else
-  struct stat64 d;
-  if ( ::stat64( theFileName, &d ) != -1 )
-#endif
-    _medFileInfo->fileSize = d.st_size;
+  _medFileInfo->fileSize = SMESH_File( theFileName ).size();
 
   return ConvertDriverMEDReadStatus(status);
 }
@@ -2773,44 +2755,36 @@ CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
 
 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
 {
-  TCollection_AsciiString aFullName ((char*)file);
-  OSD_Path aPath (aFullName);
-  OSD_File aFile (aPath);
-  if (aFile.Exists()) {
+  SMESH_File aFile( file );
+  SMESH_Comment msg;
+  if (aFile.exists()) {
     // existing filesystem node
-    if (aFile.KindOfFile() == OSD_FILE) {
-      if (aFile.IsWriteable()) {
-        if (overwrite) {
-          aFile.Reset();
-          aFile.Remove();
-        }
-        if (aFile.Failed()) {
-          TCollection_AsciiString msg ("File ");
-          msg += aFullName + " cannot be replaced.";
-          THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
+    if ( !aFile.isDirectory() ) {
+      if ( aFile.openForWriting() ) {
+        if ( overwrite && ! aFile.remove()) {
+          msg << "Can't replace " << aFile.getName();
         }
       } else {
-        TCollection_AsciiString msg ("File ");
-        msg += aFullName + " cannot be overwritten.";
-        THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
+        msg << "Can't write into " << aFile.getName();
       }
     } else {
-      TCollection_AsciiString msg ("Location ");
-      msg += aFullName + " is not a file.";
-      THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
+      msg << "Location " << aFile.getName() << " is not a file";
     }
-  } else {
+  }
+  else {
     // nonexisting file; check if it can be created
-    aFile.Reset();
-    aFile.Build(OSD_WriteOnly, OSD_Protection());
-    if (aFile.Failed()) {
-      TCollection_AsciiString msg ("You cannot create the file ");
-      msg += aFullName + ". Check the directory existance and access rights.";
-      THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
-    } else {
-      aFile.Close();
-      aFile.Remove();
+    if ( !aFile.openForWriting() ) {
+      msg << "You cannot create the file "
+          << aFile.getName()
+          << ". Check the directory existance and access rights";
     }
+    aFile.remove();
+  }
+
+  if ( !msg.empty() )
+  {
+    msg << ".";
+    THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
   }
 }
 
@@ -4164,17 +4138,11 @@ SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
 
   // find inverse elements
   SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
-  TColStd_SequenceOfInteger IDs;
-  while(eIt->more()) {
+  aResult->length( aNode->NbInverseElements() );  
+  for( int i = 0; eIt->more(); ++i )
+  {
     const SMDS_MeshElement* elem = eIt->next();
-    IDs.Append(elem->GetID());
-  }
-  if(IDs.Length()>0) {
-    aResult->length(IDs.Length());
-    int i = 1;
-    for(; i<=IDs.Length(); i++) {
-      aResult[i-1] = IDs.Value(i);
-    }
+    aResult[ i ] = elem->GetID();
   }
   return aResult._retn();
 }