X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FMEDWrapper%2FMED_Factory.cxx;h=114cb623e5ce7a7c653159414872fac42bb28df5;hp=3e354c131c4e8cdea033cc7b44c1b608773ccab5;hb=0fc0831670e27a5611b941c52dc152fd63964515;hpb=8b8b4241036975c907a537d208bac1ab1c945d77 diff --git a/src/MEDWrapper/MED_Factory.cxx b/src/MEDWrapper/MED_Factory.cxx index 3e354c131..114cb623e 100644 --- a/src/MEDWrapper/MED_Factory.cxx +++ b/src/MEDWrapper/MED_Factory.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2020 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 @@ -24,9 +24,12 @@ #include "MED_Utilities.hxx" #include "MED_Wrapper.hxx" +#include + #include #include #include +#include #include extern "C" @@ -41,6 +44,29 @@ extern "C" #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 { @@ -48,42 +74,71 @@ namespace MED { #ifdef WIN32 #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); + 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(); + cosnt char* path = xmlPath.c_str(); #endif - bool res = (GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES); + bool res = (GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES); #ifdef UNICODE - delete path; + delete path; #endif - return res; + 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); + 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); + MESSAGE(ret << " " << major << "." << minor << "." << release); if (ret >= 0) { bool isReadOnly = !isForAppend; - if ( isReadOnly || ((major == MED_MAJOR_NUM) && (minor == MED_MINOR_NUM))) + 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); @@ -128,13 +183,27 @@ namespace MED 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, wantedMajor, wantedMinor); } }