// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // File : SMESH_File.cxx // Created : Wed Mar 10 11:23:25 2010 // Author : Edward AGAPOV (eap) // #include "SMESH_File.hxx" #include "utilities.h" #include #include #include #include #include #include #include #ifdef WIN32 #include #else #include #include #endif //================================================================================ /*! * \brief Creator opening the file for reading by default */ //================================================================================ SMESH_File::SMESH_File(const std::string& name, bool open) :_name(name), _size(-1), _file(0), _map(0), _pos(0), _end(0) { if ( open ) this->open(); } //================================================================================ /*! * \brief Destructor closing the file */ //================================================================================ SMESH_File::~SMESH_File() { close(); } //================================================================================ /*! * \brief Open file for reading. Return true if there is something to read */ //================================================================================ bool SMESH_File::open() { int length = size(); if ( !_map && length > 0 ) { #ifdef WIN32 _file = CreateFile(_name.data(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); bool ok = ( _file != INVALID_HANDLE_VALUE ); #else _file = ::open(_name.data(), O_RDONLY ); bool ok = ( _file > 0 ); #endif if ( ok ) { #ifdef WIN32 _mapObj = CreateFileMapping(_file, NULL, PAGE_READONLY, 0, (DWORD)length, NULL); _map = (void*) MapViewOfFile( _mapObj, FILE_MAP_READ, 0, 0, 0 ); #else _map = ::mmap(0,length,PROT_READ,MAP_PRIVATE,_file,0); if ( _map == MAP_FAILED ) _map = NULL; #endif if ( _map != NULL ) { _size = length; _pos = (char*) _map; _end = _pos + _size; } else { #ifdef WIN32 CloseHandle(_mapObj); CloseHandle(_file); #else ::close(_file); #endif } } } return _pos; } //================================================================================ /*! * \brief Close the file */ //================================================================================ void SMESH_File::close() { if ( _map != NULL ) { #ifdef WIN32 UnmapViewOfFile(_map); CloseHandle(_mapObj); CloseHandle(_file); #else ::munmap(_map, _size); ::close(_file); #endif _map = NULL; _pos = _end = 0; _size = -1; } } //================================================================================ /*! * \brief Remove the file */ //================================================================================ 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; } //================================================================================ /*! * \brief Return file size */ //================================================================================ int SMESH_File::size() const { if ( _size >= 0 ) return _size; // size of 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; } //================================================================================ /*! * \brief Set cursor to the given position */ //================================================================================ void SMESH_File::setPos(const char* pos) { if ( pos > (const char*)_map && pos < _end ) _pos = (char*) pos; } //================================================================================ /*! * \brief Skip till current line end and return the skipped string */ //================================================================================ std::string SMESH_File::getLine() { std::string line; const char* p = _pos; while ( !eof() ) if ( *(++_pos) == '\n' ) break; line.append( p, _pos ); if ( !eof() ) _pos++; return line; } //================================================================================ /*! * \brief Move cursor to the file beginning */ //================================================================================ void SMESH_File::rewind() { _pos = (char*) _map; } //================================================================================ /*! * \brief Fill vector by reading out integers from file. Vector size gives number * of integers to read */ //================================================================================ bool SMESH_File::getInts(std::vector& ints) { int i = 0; while ( i < ints.size() ) { while ( !isdigit( *_pos ) && !eof()) ++_pos; if ( eof() ) break; if ( _pos[-1] == '-' ) --_pos; ints[ i++ ] = strtol( _pos, (char**)&_pos, 10 ); } return ( i == ints.size() ); }