// Copyright (C) 2007-2021 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 #include #include #include #include #include extern "C" { #ifndef WIN32 #include #endif } #include #ifdef WIN32 #include #endif // ------------------------------------------------------------------------------------------------------------------- // --- MED file compatibility: write using a lower major version implies append on an empty file of the target version // // ******************************************************************************************************************* // ==> This file must be modified when MED version changes: // MED_MAJOR_NUM and MED_MINOR_NUM are defined in an external include from MED prerequisite: med.h // When MED_MAJOR_NUM or MED_MINOR_NUM changes, MED_MAJOR_EXPECTED and MED_MINOR_EXPECTED must be set accordingly // and MED_VERSIONS_APPEND_COMPATIBLE must be updated: The lower compatible versions may change with a new MED version // If the major version of MED change (for instance 4 --> 5) and if MED allows to append meshes in MED-4.x format, // Empty file content for MED-4.x should be provided (EMPTY_FILE_4x) and method CreateEmptyMEDFile should be updated. // ******************************************************************************************************************* #define MED_MAJOR_EXPECTED 4 #define MED_MINOR_EXPECTED 1 #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 (MED_MAJOR_EXPECTED, MED_MINOR_EXPECTED)" #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 above (MED_MAJOR_EXPECTED, MED_MINOR_EXPECTED)" #endif #define MED_VERSIONS_APPEND_COMPATIBLE {41, 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 namespace MED { bool exists(const std::string& fileName) { #ifdef WIN32 #ifdef UNICODE int size_needed = MultiByteToWideChar(CP_UTF8, 0, fileName.c_str(), strlen(fileName.c_str()), NULL, 0); wchar_t* path = new wchar_t[size_needed + 1]; MultiByteToWideChar(CP_UTF8, 0, fileName.c_str(), strlen(fileName.c_str()), path, size_needed); path[size_needed] = '\0'; #else cosnt char* path = xmlPath.c_str(); #endif bool res = (GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES); #ifdef UNICODE delete path; #endif return res; #else return (access(fileName.c_str(), F_OK) == 0); #endif } /*! * 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 GetMEDVersionsAppendCompatible() { int mvok[] = MED_VERSIONS_APPEND_COMPATIBLE; std::vector MEDVersionsOK(mvok, mvok + sizeof(mvok)/sizeof(int)); int curVersion = MED_MAJOR_NUM * 10 + MED_MINOR_NUM; if ( MEDVersionsOK[0] != curVersion ) MEDVersionsOK.insert( MEDVersionsOK.begin(), curVersion ); 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. */ bool CheckCompatibility(const std::string& fileName, bool isForAppend) { bool ok = false; std::vector medVersionsOK = GetMEDVersionsAppendCompatible(); // check that file is accessible if ( exists(fileName) ) { // check HDF5 && MED compatibility med_bool hdfok, medok; med_err r0 = MEDfileCompatibility(fileName.c_str(), &hdfok, &medok); MESSAGE(r0 << " " << hdfok << " " << medok); if ( r0==0 && hdfok && medok ) { 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); MESSAGE(ret << " " << major << "." << minor << "." << release); if (ret >= 0) { bool isReadOnly = !isForAppend; if (isReadOnly) ok = true; else { int medVersion = 10*major + minor; for (size_t ii=0; ii < medVersionsOK.size(); ii++) if (medVersionsOK[ii] == medVersion) { ok =true; break; } } } } 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 '"< versionsOK(GetMEDVersionsAppendCompatible()); bool isVersionRequestedOK(std::find(versionsOK.begin(),versionsOK.end(),theVersion)!=versionsOK.end()); if (isCreated && isVersionRequestedOK) { wantedMajor = theVersion/10; wantedMinor = theVersion%10; } return new MED::TWrapper(fileName, true, tfileInst, wantedMajor, wantedMinor); } }