Salome HOME
a86092b429acc918c9569a4e749258412a697459
[modules/smesh.git] / src / SMESH / SMESH_File.cxx
1 // File      : SMESH_File.cxx
2 // Created   : Wed Mar 10 11:23:25 2010
3 // Author    : Edward AGAPOV (eap)
4
5
6 #include "SMESH_File.hxx"
7 #include "utilities.h"
8
9 #include <OSD_File.hxx>
10 #include <OSD_Path.hxx>
11 #include <Standard_ProgramError.hxx>
12 #include <Standard_ErrorHandler.hxx>
13 #include <Standard_Failure.hxx>
14
15 #include <fcntl.h>
16 #include <sys/stat.h>
17
18 #ifdef WIN32
19 #include <io.h>
20 #else
21 #include <sys/mman.h>
22 #endif
23
24 //================================================================================
25 /*!
26  * \brief Creator opening the file for reading by default
27  */
28 //================================================================================
29
30 SMESH_File::SMESH_File(const std::string& name, bool open)
31   :_name(name), _size(-1), _file(0), _map(0), _pos(0), _end(0)
32 {
33   if ( open ) this->open();
34 }
35
36 //================================================================================
37 /*!
38  * \brief Destructor closing the file
39  */
40 //================================================================================
41
42 SMESH_File::~SMESH_File()
43 {
44   close();
45 }
46
47 //================================================================================
48 /*!
49  * \brief Open file for reading. Return true if there is something to read
50  */
51 //================================================================================
52
53 bool SMESH_File::open()
54 {
55   int length = size();
56   if ( !_map && length > 0 )
57   {
58 #ifdef WNT
59     _file = CreateFile(_name.data(), GENERIC_READ, FILE_SHARE_READ,
60                        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
61     bool ok = ( _file != INVALID_HANDLE_VALUE );
62 #else
63     _file = ::open(_name.data(), O_RDONLY );
64     bool ok = ( _file > 0 );
65 #endif
66     if ( ok )
67     {
68 #ifdef WNT
69       _mapObj = CreateFileMapping(_file, NULL, PAGE_READONLY, 0, (DWORD)length, NULL);
70       _map = (void*) MapViewOfFile( _mapObj, FILE_MAP_READ, 0, 0, 0 );
71 #else
72       _map = ::mmap(0,length,PROT_READ,MAP_PRIVATE,_file,0);
73       if ( _map == MAP_FAILED ) _map = NULL;
74 #endif
75       if ( _map != NULL )
76       {
77         _size = length;
78         _pos = (char*) _map;
79         _end = _pos + _size;
80       }
81       else
82       {
83 #ifdef WNT
84         CloseHandle(_mapObj);
85         CloseHandle(_file);
86 #else
87         ::close(_file);
88 #endif
89       }
90     }
91   }
92   return _pos;
93 }
94
95 //================================================================================
96 /*!
97  * \brief Close the file
98  */
99 //================================================================================
100
101 void SMESH_File::close()
102 {
103   if ( _map != NULL )
104   {
105 #ifdef WNT
106     UnmapViewOfFile(_map);
107     CloseHandle(_mapObj);
108     CloseHandle(_file);
109 #else
110     ::munmap(_map, _size);
111     ::close(_file);
112 #endif
113     _map = NULL;
114     _pos = _end = 0;
115     _size = -1;
116   }
117 }
118
119 //================================================================================
120 /*!
121  * \brief Remove the file
122  */
123 //================================================================================
124
125 bool SMESH_File::remove()
126 {
127   close();
128   try {
129     OSD_Path filePath(TCollection_AsciiString((char*)_name.data()));
130     OSD_File(filePath).Remove();
131   }
132   catch ( Standard_ProgramError ) {
133     MESSAGE("Can't remove file: " << _name << " ; file does not exist or permission denied");
134     return false;
135   }
136   return true;
137 }
138
139 //================================================================================
140 /*!
141  * \brief Return file size
142  */
143 //================================================================================
144
145 int SMESH_File::size() const
146 {
147   if ( _size >= 0 ) return _size; // size of open file
148
149   int size = -1;
150   int file = ::open( _name.data(), O_RDONLY );
151   if ( file > 0 )
152   {
153     struct stat status;
154     int err = fstat( file, &status);
155     if ( !err )
156       size = status.st_size;
157     ::close( file );
158   }
159   return size;
160 }
161
162 //================================================================================
163 /*!
164  * \brief Set cursor to the given position
165  */
166 //================================================================================
167
168 void SMESH_File::setPos(const char* pos)
169 {
170   if ( pos > (const char*)_map && pos < _end )
171     _pos = (char*) pos;
172 }
173
174 //================================================================================
175 /*!
176  * \brief Skip till current line end and return the skipped string
177  */
178 //================================================================================
179
180 std::string SMESH_File::getLine()
181 {
182   std::string line;
183   const char* p = _pos;
184   while ( !eof() )
185     if ( *(++_pos) == '\n' )
186       break;
187   line.append( p, _pos );
188   if ( !eof() ) _pos++;
189   return line;
190 }
191
192 //================================================================================
193 /*!
194  * \brief Move cursor to the file beginning
195  */
196 //================================================================================
197
198 void SMESH_File::rewind()
199 {
200   _pos = (char*) _map;
201 }
202
203 //================================================================================
204 /*!
205  * \brief Fill vector by reading out integers from file. Vector size gives number
206  * of integers to read
207  */
208 //================================================================================
209
210 bool SMESH_File::getInts(std::vector<int>& ints)
211 {
212   int i = 0;
213   while ( i < ints.size() )
214   {
215     while ( !isdigit( *_pos ) && !eof()) ++_pos;
216     if ( eof() ) break;
217     if ( _pos[-1] == '-' ) --_pos;
218     ints[ i++ ] = strtol( _pos, (char**)&_pos, 10 );
219   }
220   return ( i == ints.size() );
221 }