2016-04-06 17:24:26 +03:00
// Copyright (C) 2007-2016 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
//
// 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
//
# include "MED_Factory.hxx"
# include "MED_Utilities.hxx"
# include "MED_Wrapper.hxx"
# include <stdio.h>
# include <errno.h>
# include <sstream>
# include <med.h>
extern " C "
{
# ifndef WIN32
# include <unistd.h>
# endif
}
2018-07-18 15:51:37 +02:00
# include <utilities.h>
2016-04-06 17:24:26 +03:00
2018-08-29 14:47:50 +03:00
# ifdef WIN32
# include <windows.h>
# endif
2018-10-03 15:08:45 +02:00
# define MED_MAJOR_EXPECTED 4
# define MED_MINOR_EXPECTED 0
# if MED_MAJOR_NUM != MED_MAJOR_EXPECTED
# error "MED major version does not correspond to the expected version, fix the minor and major compatibility values in CheckCompatibility method (MED_VERSIONS_APPEND_COMPATIBLE) and set the correct expected version"
# endif
# if MED_MINOR_NUM != MED_MINOR_EXPECTED
# error "MED minor version does not correspond to the expected version, fix the minor and major compatibility values in CheckCompatibility method (MED_VERSIONS_APPEND_COMPATIBLE) and set the correct expected version"
# endif
# define MED_VERSIONS_APPEND_COMPATIBLE {40, 32, 33} // --- 10*major + minor (the 3rd digit, release, is not used here,
// med uses always the latest available)
// --- The first in the list should be the default: current version
2018-08-29 14:47:50 +03:00
2016-04-06 17:24:26 +03:00
namespace MED
{
bool exists ( const std : : string & fileName )
{
# ifdef WIN32
2018-08-29 14:47:50 +03:00
# ifdef UNICODE
size_t length = strlen ( fileName . c_str ( ) ) + sizeof ( char ) ;
wchar_t * path = new wchar_t [ length ] ;
memset ( path , ' \0 ' , length ) ;
mbstowcs ( path , fileName . c_str ( ) , length ) ;
# else
cosnt char * path = xmlPath . c_str ( ) ;
# endif
return ( GetFileAttributes ( path ) ! = INVALID_FILE_ATTRIBUTES ) ;
2016-04-06 17:24:26 +03:00
# else
return ( access ( fileName . c_str ( ) , F_OK ) = = 0 ) ;
# endif
}
2018-10-03 15:08:45 +02:00
/*!
* Return the list of med versions compatibles for write / append ,
* encoded in 10 * major + minor ( for instance , code for med 3.2 .1 is 32 )
*/
std : : vector < int > GetMEDVersionsAppendCompatible ( )
{
int mvok [ ] = MED_VERSIONS_APPEND_COMPATIBLE ;
std : : vector < int > MEDVersionsOK ( mvok , mvok + sizeof ( mvok ) / sizeof ( int ) ) ;
return MEDVersionsOK ;
}
/*!
* \ brief : Check read or write ( append ) Compatibility of a med file
* \ param [ in ] : fileName - the file to read or to append to
* \ param [ in ] : isforAppend - when true , check if the med file version is OK to append a mesh ,
* when false , check if the med file is readable .
*/
2018-07-18 15:51:37 +02:00
bool CheckCompatibility ( const std : : string & fileName , bool isForAppend )
2016-04-06 17:24:26 +03:00
{
bool ok = false ;
2018-10-03 15:08:45 +02:00
int medVersionsOK [ ] = MED_VERSIONS_APPEND_COMPATIBLE ;
2016-04-06 17:24:26 +03:00
// check that file is accessible
if ( exists ( fileName ) ) {
// check HDF5 && MED compatibility
med_bool hdfok , medok ;
2018-07-18 15:51:37 +02:00
med_err r0 = MEDfileCompatibility ( fileName . c_str ( ) , & hdfok , & medok ) ;
2018-10-03 15:08:45 +02:00
MESSAGE ( r0 < < " " < < hdfok < < " " < < medok ) ;
2018-07-18 15:51:37 +02:00
if ( r0 = = 0 & & hdfok & & medok ) {
2016-04-06 17:24:26 +03:00
med_idt aFid = MEDfileOpen ( fileName . c_str ( ) , MED_ACC_RDONLY ) ;
if ( aFid > = 0 ) {
med_int major , minor , release ;
med_err ret = MEDfileNumVersionRd ( aFid , & major , & minor , & release ) ;
2018-10-03 15:08:45 +02:00
MESSAGE ( ret < < " " < < major < < " . " < < minor < < " . " < < release ) ;
2016-04-06 17:24:26 +03:00
if ( ret > = 0 ) {
2018-07-18 15:51:37 +02:00
bool isReadOnly = ! isForAppend ;
2018-10-03 15:08:45 +02:00
if ( isReadOnly )
2016-04-06 17:24:26 +03:00
ok = true ;
2018-10-03 15:08:45 +02:00
else {
int medVersion = 10 * major + minor ;
for ( int ii = 0 ; ii < sizeof ( medVersionsOK ) / sizeof ( int ) ; ii + + )
if ( medVersionsOK [ ii ] = = medVersion ) {
ok = true ;
break ;
}
}
2016-04-06 17:24:26 +03:00
}
}
MEDfileClose ( aFid ) ;
}
}
return ok ;
}
bool GetMEDVersion ( const std : : string & fileName , int & major , int & minor , int & release )
{
bool ok = false ;
major = minor = release = 0 ;
med_idt aFid = MEDfileOpen ( fileName . c_str ( ) , MED_ACC_RDONLY ) ;
if ( aFid > = 0 ) {
med_int _major , _minor , _release ;
med_err ret = MEDfileNumVersionRd ( aFid , & _major , & _minor , & _release ) ;
if ( ret = = 0 ) {
major = _major ;
minor = _minor ;
release = _release ;
ok = true ;
}
MEDfileClose ( aFid ) ;
}
return ok ;
}
std : : string GetMEDVersion ( const std : : string & fileName )
{
std : : string version ;
int major , minor , release ;
if ( GetMEDVersion ( fileName , major , minor , release ) ) {
std : : ostringstream os ;
os < < major < < " . " < < minor < < " . " < < release ;
version = os . str ( ) ;
}
return version ;
}
PWrapper CrWrapperR ( const std : : string & fileName )
{
if ( ! CheckCompatibility ( fileName ) ) {
EXCEPTION ( std : : runtime_error , " Cannot open file ' " < < fileName < < " '. " ) ;
}
return new MED : : TWrapper ( fileName ) ;
}
2018-10-09 15:06:17 +02:00
PWrapper CrWrapperW ( const std : : string & fileName , int theVersion )
2016-04-06 17:24:26 +03:00
{
2018-10-09 15:06:17 +02:00
bool isCreated = false ;
2018-07-18 15:51:37 +02:00
if ( ! CheckCompatibility ( fileName , true ) )
2018-10-09 15:06:17 +02:00
{
remove ( fileName . c_str ( ) ) ;
isCreated = true ;
}
int minor = - 1 ;
if ( isCreated )
{
med_int wantedMajor = MED_MAJOR_NUM ;
med_int wantedMinor = MED_MINOR_NUM ;
if ( theVersion > 0 )
{
wantedMajor = theVersion / 10 ;
wantedMinor = theVersion % 10 ;
}
if ( wantedMajor = = MED_MAJOR_NUM ) // the med file will be actually created
{
if ( wantedMinor < MED_MINOR_NUM )
minor = wantedMinor ;
}
else // an empty existing med file of the right version will be used for append
{
int medVersionsOK [ ] = MED_VERSIONS_APPEND_COMPATIBLE ;
bool isVersionOK = false ;
for ( int ii = 0 ; ii < sizeof ( medVersionsOK ) / sizeof ( int ) ; ii + + )
if ( medVersionsOK [ ii ] = = theVersion )
{
isVersionOK = true ;
break ;
}
if ( isVersionOK ) // copy an empty existing med file of the right version, for append
{
MESSAGE ( " copy an empty existing med file of the right version, for append " < < theVersion ) ;
}
}
}
return new MED : : TWrapper ( fileName , minor ) ;
2016-04-06 17:24:26 +03:00
}
}