1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDLoaderBase.hxx"
22 #include "InterpKernelException.hxx"
29 const char MEDLoaderBase::WHITE_SPACES[]=" \n";
31 int MEDLoaderBase::getStatusOfFile(const std::string& fileName)
34 ifs.open(fileName.c_str());
35 if((ifs.rdstate() & std::ifstream::failbit)!=0)
40 std::ofstream ofs(fileName.c_str(),std::ios_base::app);
41 if((ofs.rdstate() & std::ofstream::failbit)!=0)
48 char *MEDLoaderBase::buildEmptyString(int lgth)
50 char *ret=new char[lgth+1];
51 std::fill(ret,ret+lgth,' ');
56 void MEDLoaderBase::getDirAndBaseName(const std::string& fullName, std::string& dirName, std::string& baseName)
58 std::size_t pos=fullName.find_last_of(getPathSep());
59 if(pos!=std::string::npos)
61 dirName=fullName.substr(0,pos);
62 baseName=fullName.substr(pos+1);
71 std::string MEDLoaderBase::joinPath(const std::string& dirName, const std::string& baseName)
74 return dirName+getPathSep()+baseName;
79 std::string MEDLoaderBase::getPathSep()
82 return std::string("/");
84 return std::string("\\");
88 std::string MEDLoaderBase::buildUnionUnit(const char *name, int nameLgth, const char *unit, int unitLgth)
90 std::string ret(buildStringFromFortran(name,nameLgth));
91 std::string unitCpp(buildStringFromFortran(unit,unitLgth));
92 if(unitCpp.empty() || unitCpp[0]=='\0')
100 void MEDLoaderBase::splitIntoNameAndUnit(const std::string& s, std::string& name, std::string& unit)
102 std::string::size_type f1=s.find_first_of('[');
103 std::string::size_type f2=s.find_last_of(']');
104 if(f1!=std::string::npos && f2!=std::string::npos)
109 unit=s.substr(f1+1,f2-f1-1);
119 void MEDLoaderBase::strip(std::string& s)
121 std::string::size_type f1=s.find_first_not_of(' ');
122 if(f1==std::string::npos)
127 std::string::size_type f2=s.find_last_not_of(' ');
128 s=s.substr(f1,f2-f1+1);
132 * This method operates a safe copy from 'src' to 'dest' by checking the size of 'src' before trying to copy.
133 * If size of 'src' string is higher than 'maxLgth' the behaviour is dependant from 'behaviour' parameter.
134 * If 'behaviour' equals 0 an exception is thrown. If 'behaviour' equals 1 an attempt of zipping of string will be done
135 * ( see zipString to have more details).
137 void MEDLoaderBase::safeStrCpy(const char *src, int maxLgth, char *dest, int behaviour)
139 if((int)strlen(src)>maxLgth)
141 if(behaviour==0 || behaviour>1)
143 std::ostringstream oss; oss << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") !";
144 throw INTERP_KERNEL::Exception(oss.str().c_str());
146 else if(behaviour==1)
148 std::string s=zipString(src,maxLgth);
149 std::cerr << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") : ";
150 std::cerr << "zipping to : " << s << "\n";
151 strcpy(dest,s.c_str());
159 * This method is equivalent to MEDLoaderBase::safeStrCpy except that here no '\0' car is put.
160 * This method should be used for multi string in one string.
162 void MEDLoaderBase::safeStrCpy2(const char *src, int maxLgth, char *dest, int behaviour)
164 if((int)strlen(src)>maxLgth)
166 if(behaviour==0 || behaviour>1)
168 std::ostringstream oss; oss << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") !";
169 throw INTERP_KERNEL::Exception(oss.str().c_str());
171 else if(behaviour==1)
173 std::string s=zipString(src,maxLgth);
174 std::cerr << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") : ";
175 std::cerr << "zipping to : " << s << "\n";
176 strcpy(dest,s.c_str());
184 std::string MEDLoaderBase::buildStringFromFortran(const char *expr, int lgth)
186 std::string ret(expr,lgth);
187 std::string whiteSpaces(WHITE_SPACES);
188 std::size_t lgthReal=strlen(ret.c_str());
189 std::string ret2=ret.substr(0,lgthReal);
190 std::size_t found=ret2.find_last_not_of(whiteSpaces);
191 if (found!=std::string::npos)
194 ret2.clear();//ret is all whitespace
199 * This method given the target size to respect 'sizeToRespect' tries to reduce size of 'src' string.
200 * This method uses several soft methods to do its job. But if it fails a simple cut of string will be performed.
202 std::string MEDLoaderBase::zipString(const std::string& src, int sizeToRespect)
206 if((int)s.length()<=sizeToRespect)
209 zipEqualConsChar(s,3);
210 if((int)s.length()<=sizeToRespect)
213 zipEqualConsChar(s,2);
214 if((int)s.length()<=sizeToRespect)
217 return s.substr(0,sizeToRespect);
221 * This method see if there is in 's' more than 'minConsSmChar' consecutive same character.
222 * If yes, the group will be zipped using only one character for this group.
223 * If no such group is found, s remains unchanged.
225 void MEDLoaderBase::zipEqualConsChar(std::string& s, int minConsSmChar)
227 for(std::string::iterator it=s.begin();it!=s.end();it++)
231 for(std::string::iterator it2=it+1;it2!=s.end() && *it2==tmp;it2++)
233 if(sz>=minConsSmChar)