Salome HOME
Merge from V6_3_BR 06/06/2011
[modules/smesh.git] / src / SMESH / SMESH_File.cxx
1 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // File      : SMESH_File.cxx
21 // Created   : Wed Mar 10 11:23:25 2010
22 // Author    : Edward AGAPOV (eap)
23 //
24 #include "SMESH_File.hxx"
25 #include "utilities.h"
26
27 #include <OSD_File.hxx>
28 #include <OSD_Path.hxx>
29 #include <Standard_ProgramError.hxx>
30 #include <Standard_ErrorHandler.hxx>
31 #include <Standard_Failure.hxx>
32
33 #include <fcntl.h>
34 #include <sys/stat.h>
35
36 #ifdef WIN32
37 #include <io.h>
38 #else
39 #include <sys/mman.h>
40 #endif
41
42 //================================================================================
43 /*!
44  * \brief Creator opening the file for reading by default
45  */
46 //================================================================================
47
48 SMESH_File::SMESH_File(const std::string& name, bool open)
49   :_name(name), _size(-1), _file(0), _map(0), _pos(0), _end(0)
50 {
51   if ( open ) this->open();
52 }
53
54 //================================================================================
55 /*!
56  * \brief Destructor closing the file
57  */
58 //================================================================================
59
60 SMESH_File::~SMESH_File()
61 {
62   close();
63 }
64
65 //================================================================================
66 /*!
67  * \brief Open file for reading. Return true if there is something to read
68  */
69 //================================================================================
70
71 bool SMESH_File::open()
72 {
73   int length = size();
74   if ( !_map && length > 0 )
75   {
76 #ifdef WNT
77     _file = CreateFile(_name.data(), GENERIC_READ, FILE_SHARE_READ,
78                        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
79     bool ok = ( _file != INVALID_HANDLE_VALUE );
80 #else
81     _file = ::open(_name.data(), O_RDONLY );
82     bool ok = ( _file > 0 );
83 #endif
84     if ( ok )
85     {
86 #ifdef WNT
87       _mapObj = CreateFileMapping(_file, NULL, PAGE_READONLY, 0, (DWORD)length, NULL);
88       _map = (void*) MapViewOfFile( _mapObj, FILE_MAP_READ, 0, 0, 0 );
89 #else
90       _map = ::mmap(0,length,PROT_READ,MAP_PRIVATE,_file,0);
91       if ( _map == MAP_FAILED ) _map = NULL;
92 #endif
93       if ( _map != NULL )
94       {
95         _size = length;
96         _pos = (char*) _map;
97         _end = _pos + _size;
98       }
99       else
100       {
101 #ifdef WNT
102         CloseHandle(_mapObj);
103         CloseHandle(_file);
104 #else
105         ::close(_file);
106 #endif
107       }
108     }
109   }
110   return _pos;
111 }
112
113 //================================================================================
114 /*!
115  * \brief Close the file
116  */
117 //================================================================================
118
119 void SMESH_File::close()
120 {
121   if ( _map != NULL )
122   {
123 #ifdef WNT
124     UnmapViewOfFile(_map);
125     CloseHandle(_mapObj);
126     CloseHandle(_file);
127 #else
128     ::munmap(_map, _size);
129     ::close(_file);
130 #endif
131     _map = NULL;
132     _pos = _end = 0;
133     _size = -1;
134   }
135 }
136
137 //================================================================================
138 /*!
139  * \brief Remove the file
140  */
141 //================================================================================
142
143 bool SMESH_File::remove()
144 {
145   close();
146   try {
147     OSD_Path filePath(TCollection_AsciiString((char*)_name.data()));
148     OSD_File(filePath).Remove();
149   }
150   catch ( Standard_ProgramError ) {
151     MESSAGE("Can't remove file: " << _name << " ; file does not exist or permission denied");
152     return false;
153   }
154   return true;
155 }
156
157 //================================================================================
158 /*!
159  * \brief Return file size
160  */
161 //================================================================================
162
163 int SMESH_File::size() const
164 {
165   if ( _size >= 0 ) return _size; // size of open file
166
167   int size = -1;
168   int file = ::open( _name.data(), O_RDONLY );
169   if ( file > 0 )
170   {
171     struct stat status;
172     int err = fstat( file, &status);
173     if ( !err )
174       size = status.st_size;
175     ::close( file );
176   }
177   return size;
178 }
179
180 //================================================================================
181 /*!
182  * \brief Set cursor to the given position
183  */
184 //================================================================================
185
186 void SMESH_File::setPos(const char* pos)
187 {
188   if ( pos > (const char*)_map && pos < _end )
189     _pos = (char*) pos;
190 }
191
192 //================================================================================
193 /*!
194  * \brief Skip till current line end and return the skipped string
195  */
196 //================================================================================
197
198 std::string SMESH_File::getLine()
199 {
200   std::string line;
201   const char* p = _pos;
202   while ( !eof() )
203     if ( *(++_pos) == '\n' )
204       break;
205   line.append( p, _pos );
206   if ( !eof() ) _pos++;
207   return line;
208 }
209
210 //================================================================================
211 /*!
212  * \brief Move cursor to the file beginning
213  */
214 //================================================================================
215
216 void SMESH_File::rewind()
217 {
218   _pos = (char*) _map;
219 }
220
221 //================================================================================
222 /*!
223  * \brief Fill vector by reading out integers from file. Vector size gives number
224  * of integers to read
225  */
226 //================================================================================
227
228 bool SMESH_File::getInts(std::vector<int>& ints)
229 {
230   int i = 0;
231   while ( i < ints.size() )
232   {
233     while ( !isdigit( *_pos ) && !eof()) ++_pos;
234     if ( eof() ) break;
235     if ( _pos[-1] == '-' ) --_pos;
236     ints[ i++ ] = strtol( _pos, (char**)&_pos, 10 );
237   }
238   return ( i == ints.size() );
239 }