diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Strings.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Strings.h index 2b00535e3fd961194632dc0edcedffc96ae38542..46a574b16f5ca58b6c24b4b5981cae8090cd07de 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Strings.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Strings.h @@ -13,15 +13,12 @@ namespace Mantid { -namespace Kernel -{ + namespace Kernel + { -/** Holds support functions for strings. + /** Holds support functions for strings. - @author S. Ansell - @date February 2006 - - Copyright & copy; 2007 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + Copyright & copy; 2007-2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory This file is part of Mantid. @@ -37,132 +34,134 @@ namespace Kernel You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. - + File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>. Code Documentation is available at: <http://doxygen.mantidproject.org> -*/ - -namespace Strings -{ - -//------------------------------------------------------------------------------------------------ -/** Join a set or vector of (something that turns into a string) together - * into one string, separated by a string. - * Returns an empty string if the range is null. - * Does not add the separator after the LAST item. - * - * For example, join a vector of strings with commas with: - * out = join(v.begin(), v.end(), ", "); - * - * @param begin :: iterator at the start - * @param end :: iterator at the end - * @param separator :: string to append. - * @return - */ -template<typename ITERATOR_TYPE> -DLLExport std::string join(ITERATOR_TYPE begin, ITERATOR_TYPE end, const std::string separator) -{ - std::ostringstream output; - ITERATOR_TYPE it; - for (it = begin; it != end; ) - { - output << *it; - it++; - if (it != end) - output << separator; - } - return output.str(); -} - -/// Return a string with all matching occurence-strings -MANTID_KERNEL_DLL std::string replace(const std::string &input, const std::string &find_what, const std::string &replace_with); -/// Return a string with all occurrences of the characters in the input replaced by the replace string -MANTID_KERNEL_DLL std::string replaceAll(const std::string & input, const std::string & charStr, const std::string & substitute); - -/// determine if a character group exists in a string -MANTID_KERNEL_DLL int confirmStr(const std::string& S,const std::string& fullPhrase); -/// Get a word from a string -MANTID_KERNEL_DLL int extractWord(std::string& Line,const std::string& Word,const int cnt = 4); -/// Get an int from the end of a word -MANTID_KERNEL_DLL int endsWithInt(const std::string & word); - -/// strip all spaces -MANTID_KERNEL_DLL std::string removeSpace(const std::string& CLine); -/// strip pre/post spaces -MANTID_KERNEL_DLL std::string fullBlock(const std::string& A); -/// strip pre/post spaces -MANTID_KERNEL_DLL std::string strip(const std::string& A); -/// strip trailling comments -MANTID_KERNEL_DLL void stripComment(std::string& A); -/// Determines if a string is only spaces -MANTID_KERNEL_DLL int isEmpty(const std::string& A); -/// Get a line and strip comments -MANTID_KERNEL_DLL std::string getLine(std::istream& fh,const int spc = 256); -/// get a part of a long line -MANTID_KERNEL_DLL int getPartLine(std::istream& fh,std::string& Out,std::string& Excess,const int spc = 256); - -template<typename T> int convPartNum(const std::string& A,T& out); - -/// Convert a string into a number -template<typename T> int convert(const std::string& A,T& out); -/// Convert a char* into a number -template<typename T> int convert(const char* A,T& out); - -/// Convert a number to a string -template<typename T> std::string toString(const T value); - -/// Convert a vector to a string -template<typename T> std::string toString(const std::vector<T> &value); - -/// Convert a set to a string -template<typename T> std::string toString(const std::set<T> &value); - -template<typename T> -int setValues(const std::string& Line,const std::vector<int>& Index,std::vector<T>& Out); - -/// Convert and cut a string -template<typename T> int sectPartNum(std::string& A,T& out); - -/// Convert and cut a string -template<typename T> int section(std::string& A,T& out); -/// Convert and cut a char* -template<typename T> int section(char* cA,T& out); - -/// Convert and cut a string for MCNPX -template<typename T> int sectionMCNPX(std::string& A,T& out); - -/// Write file in standard MCNPX input form -MANTID_KERNEL_DLL void writeMCNPX(const std::string& Line,std::ostream& OX); - -/// Split tring into spc deliminated components -MANTID_KERNEL_DLL std::vector<std::string> StrParts(std::string Ln); - -/// Write a set of containers to a file -template<template<typename T,typename A> class V,typename T,typename A> -int writeFile(const std::string& Fname,const T & step,const V<T,A>& Y); -template<template<typename T,typename A> class V,typename T,typename A> -int writeFile(const std::string& Fname,const V<T,A>& X,const V<T,A>& Y); -template<template<typename T,typename A> class V,typename T,typename A> -int writeFile(const std::string& Fname,const V<T,A>& X,const V<T,A>& Y,const V<T,A>& Err); - -/// Convert a VAX number to x86 little eindien -float getVAXnum(const float A); - -MANTID_KERNEL_DLL void readToEndOfLine( std::ifstream& in , bool ConsumeEOL ); - -MANTID_KERNEL_DLL std::string getWord( std::ifstream &in , bool consumeEOL ); -/// function parses a path, found in input string "path" and returns vector of the folders contributed into the path */ -MANTID_KERNEL_DLL size_t split_path(const std::string &path, std::vector<std::string> &path_components); - -/// Loads the entire contents of a text file into a string -MANTID_KERNEL_DLL std::string loadFile(const std::string & filename); - -/// checks if the candidate is the member of the group -MANTID_KERNEL_DLL int isMember(const std::vector<std::string> &group, const std::string &candidate); - -} // NAMESPACE Strings - -} // NAMESPACE Kernel + */ + + namespace Strings + { + + //------------------------------------------------------------------------------------------------ + /** Join a set or vector of (something that turns into a string) together + * into one string, separated by a string. + * Returns an empty string if the range is null. + * Does not add the separator after the LAST item. + * + * For example, join a vector of strings with commas with: + * out = join(v.begin(), v.end(), ", "); + * + * @param begin :: iterator at the start + * @param end :: iterator at the end + * @param separator :: string to append. + * @return + */ + template<typename ITERATOR_TYPE> + DLLExport std::string join(ITERATOR_TYPE begin, ITERATOR_TYPE end, const std::string separator) + { + std::ostringstream output; + ITERATOR_TYPE it; + for (it = begin; it != end; ) + { + output << *it; + it++; + if (it != end) + output << separator; + } + return output.str(); + } + + /// Return a string with all matching occurence-strings + MANTID_KERNEL_DLL std::string replace(const std::string &input, const std::string &find_what, const std::string &replace_with); + /// Return a string with all occurrences of the characters in the input replaced by the replace string + MANTID_KERNEL_DLL std::string replaceAll(const std::string & input, const std::string & charStr, const std::string & substitute); + + /// determine if a character group exists in a string + MANTID_KERNEL_DLL int confirmStr(const std::string& S,const std::string& fullPhrase); + /// Get a word from a string + MANTID_KERNEL_DLL int extractWord(std::string& Line,const std::string& Word,const int cnt = 4); + /// Get an int from the end of a word + MANTID_KERNEL_DLL int endsWithInt(const std::string & word); + + /// strip all spaces + MANTID_KERNEL_DLL std::string removeSpace(const std::string& CLine); + /// strip pre/post spaces + MANTID_KERNEL_DLL std::string fullBlock(const std::string& A); + /// strip pre/post spaces + MANTID_KERNEL_DLL std::string strip(const std::string& A); + /// strip trailling comments + MANTID_KERNEL_DLL void stripComment(std::string& A); + /// Determines if a string is only spaces + MANTID_KERNEL_DLL int isEmpty(const std::string& A); + /// Get a line and strip comments + MANTID_KERNEL_DLL std::string getLine(std::istream& fh,const int spc = 256); + /// get a part of a long line + MANTID_KERNEL_DLL int getPartLine(std::istream& fh,std::string& Out,std::string& Excess,const int spc = 256); + + /// Takes a character string and evaluates the first [typename T] object + template<typename T> int convPartNum(const std::string& A,T& out); + + /// Convert a string into a number + template<typename T> int convert(const std::string& A,T& out); + /// Convert a char* into a number + template<typename T> int convert(const char* A,T& out); + + /// Convert a number to a string + template<typename T> std::string toString(const T value); + + /// Convert a vector to a string + template<typename T> std::string toString(const std::vector<T> &value); + + /// Convert a set to a string + template<typename T> std::string toString(const std::set<T> &value); + + template<typename T> + int setValues(const std::string& Line,const std::vector<int>& Index,std::vector<T>& Out); + + /// Convert and cut a string + template<typename T> int sectPartNum(std::string& A,T& out); + + /// Convert and cut a string + template<typename T> int section(std::string& A,T& out); + /// Convert and cut a char* + template<typename T> int section(char* cA,T& out); + + /// Convert and cut a string for MCNPX + template<typename T> int sectionMCNPX(std::string& A,T& out); + + /// Write file in standard MCNPX input form + MANTID_KERNEL_DLL void writeMCNPX(const std::string& Line,std::ostream& OX); + + /// Split tring into spc deliminated components + MANTID_KERNEL_DLL std::vector<std::string> StrParts(std::string Ln); + + /// Write a set of containers to a file + template<template<typename T,typename A> class V,typename T,typename A> + int writeFile(const std::string& Fname,const T & step,const V<T,A>& Y); + template<template<typename T,typename A> class V,typename T,typename A> + int writeFile(const std::string& Fname,const V<T,A>& X,const V<T,A>& Y); + template<template<typename T,typename A> class V,typename T,typename A> + int writeFile(const std::string& Fname,const V<T,A>& X,const V<T,A>& Y,const V<T,A>& Err); + + /// Convert a VAX number to x86 little eindien + float getVAXnum(const float A); + + /// Eat everything from the stream until the next EOL + MANTID_KERNEL_DLL void readToEndOfLine( std::ifstream& in , bool ConsumeEOL ); + /// Returns the next word in the stream + MANTID_KERNEL_DLL std::string getWord( std::ifstream &in , bool consumeEOL ); + /// function parses a path, found in input string "path" and returns vector of the folders contributed into the path */ + MANTID_KERNEL_DLL size_t split_path(const std::string &path, std::vector<std::string> &path_components); + + /// Loads the entire contents of a text file into a string + MANTID_KERNEL_DLL std::string loadFile(const std::string & filename); + + /// checks if the candidate is the member of the group + MANTID_KERNEL_DLL int isMember(const std::vector<std::string> &group, const std::string &candidate); + + } // NAMESPACE Strings + + } // NAMESPACE Kernel } // NAMESPACE Mantid diff --git a/Code/Mantid/Framework/Kernel/src/Strings.cpp b/Code/Mantid/Framework/Kernel/src/Strings.cpp index d8332d14093075b4d18c4dfcae879759700f08be..56b507f8b572eab3592c1ca70b34343088299e58 100644 --- a/Code/Mantid/Framework/Kernel/src/Strings.cpp +++ b/Code/Mantid/Framework/Kernel/src/Strings.cpp @@ -15,1067 +15,1066 @@ using std::size_t; namespace Mantid { -namespace Kernel -{ -namespace Strings -{ - -//------------------------------------------------------------------------------------------------ -/** Loads the entire contents of a text file into a string - * - * @param filename :: full path to file - * @return string contents of text file - */ -std::string loadFile(const std::string & filename) -{ - std::string retVal; - std::string str; - std::ifstream in; - in.open(filename.c_str()); - getline(in,str); - while ( in ) { - retVal += str + "\n"; - getline(in,str); - } - in.close(); - return retVal; -} - - -//------------------------------------------------------------------------------------------------ -/** Return a string with all matching occurence-strings - * - * @param input :: input string - * @param find_what :: will search for all occurences of this string - * @param replace_with :: ... and replace them with this. - * @return the modified string. - */ -std::string replace(const std::string &input, const std::string &find_what, const std::string &replace_with) -{ - std::string output = input; - std::string::size_type pos=0; - while((pos=output.find(find_what, pos))!=std::string::npos) - { - output.erase(pos, find_what.length()); - output.insert(pos, replace_with); - pos+=replace_with.length(); - } - return output; -} - -/** - * Return a string with all occurrences of the characters in the input replaced by the replace string - * @param input :: The input string to perform the replacement on - * @param charStr :: Each occurrence of ANY character in this string within the input string will be replaced by substitute - * @param substitute :: A substitute string - * @return A new string with the characters replaced - */ -MANTID_KERNEL_DLL std::string replaceAll(const std::string & input, const std::string & charStr, const std::string & substitute) -{ - std::string replaced; - replaced.reserve(input.size()); - std::string::const_iterator iend = input.end(); - for( std::string::const_iterator itr = input.begin(); itr != iend; ++itr ) + namespace Kernel { - char inputChar = (*itr); - if( charStr.find_first_of(inputChar) == std::string::npos ) // Input string char is not one of those to be replaced + namespace Strings { - replaced.push_back(inputChar); - } - else - { - replaced.append(substitute); - } - } - return replaced; -} + //------------------------------------------------------------------------------------------------ + /** Loads the entire contents of a text file into a string + * + * @param filename :: full path to file + * @return string contents of text file + */ + std::string loadFile(const std::string & filename) + { + std::string retVal; + std::string str; + std::ifstream in; + in.open(filename.c_str()); + getline(in,str); + while ( in ) { + retVal += str + "\n"; + getline(in,str); + } + in.close(); + return retVal; + } -//------------------------------------------------------------------------------------------------ -/** - Function to convert a number into hex - output (and leave the stream un-changed) - @param OFS :: Output stream - @param n :: Integer to convert - \todo Change this to a stream operator -*/ -void printHex(std::ostream& OFS,const int n) -{ - std::ios_base::fmtflags PrevFlags=OFS.flags(); - OFS<<"Ox"; - OFS.width(8); - OFS.fill('0'); - hex(OFS); - OFS << n; - OFS.flags(PrevFlags); - return; -} - -//------------------------------------------------------------------------------------------------ -/** - Removes the multiple spaces in the line - @param Line :: Line to process - @return String with single space components -*/ -std::string stripMultSpc(const std::string& Line) -{ - std::string Out; - int spc(1); - int lastReal(-1); - for(unsigned int i=0;i<Line.length();i++) - { - if (Line[i]!=' ' && Line[i]!='\t' && - Line[i]!='\r' && Line[i]!='\n') + //------------------------------------------------------------------------------------------------ + /** Return a string with all matching occurence-strings + * + * @param input :: input string + * @param find_what :: will search for all occurences of this string + * @param replace_with :: ... and replace them with this. + * @return the modified string. + */ + std::string replace(const std::string &input, const std::string &find_what, const std::string &replace_with) + { + std::string output = input; + std::string::size_type pos=0; + while((pos=output.find(find_what, pos))!=std::string::npos) { - lastReal=i; - spc=0; - Out+=Line[i]; - } - else if (!spc) + output.erase(pos, find_what.length()); + output.insert(pos, replace_with); + pos+=replace_with.length(); + } + return output; + } + + /** + * Return a string with all occurrences of the characters in the input replaced by the replace string + * @param input :: The input string to perform the replacement on + * @param charStr :: Each occurrence of ANY character in this string within the input string will be replaced by substitute + * @param substitute :: A substitute string + * @return A new string with the characters replaced + */ + MANTID_KERNEL_DLL std::string replaceAll(const std::string & input, const std::string & charStr, const std::string & substitute) + { + std::string replaced; + replaced.reserve(input.size()); + std::string::const_iterator iend = input.end(); + for( std::string::const_iterator itr = input.begin(); itr != iend; ++itr ) { - spc=1; - Out+=' '; - } - } - lastReal++; - if (lastReal<static_cast<int>(Out.length())) - Out.erase(lastReal); - return Out; -} - -//------------------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------------------ -/** - Checks that as least cnt letters of - works is part of the string. It is currently - case sensitive. It removes the Word if found - @param Line :: Line to process - @param Word :: Word to use - @param cnt :: Length of Word for significants [default =4] - @retval 1 on success (and changed Line) - @retval 0 on failure -*/ -int extractWord(std::string& Line,const std::string& Word,const int cnt) -{ - if (Word.empty()) - return 0; - - size_t minSize(cnt>static_cast<int>(Word.size()) ? Word.size() : cnt); - std::string::size_type pos=Line.find(Word.substr(0,minSize)); - if (pos==std::string::npos) - return 0; - // Pos == Start of find - size_t LinePt=minSize+pos; - for(;minSize<Word.size() && LinePt<Line.size() - && Word[minSize]==Line[LinePt];LinePt++,minSize++) - { - } - - Line.erase(pos,LinePt-(pos-1)); - return 1; -} - -//------------------------------------------------------------------------------------------------ -/** If a word ends with a number representing a positive integer, return - * the value of that int. - * - * @param word :: string possibly ending in a number - * @return the number, or -1 if it does not end in a number - */ -int endsWithInt(const std::string & word) -{ - if (word.empty()) - return -1; - int out = -1; - // Find the index of the first number in the string (if any) - int firstNumber = int(word.size()); - for (int i=int(word.size())-1; i>=0; i--) - { - char c = word[i]; - if ((c > '9') || (c < '0')) - break; - firstNumber = i; - } - // Convert the string of decimals to an int - if (firstNumber < int(word.size())) - { - std::string part = word.substr(firstNumber, word.size()-firstNumber); - if (!convert(part, out)) - return -1; - } - return out; -} - -//------------------------------------------------------------------------------------------------ -/** - Check to see if S is the same as the - first part of a phrase. (case insensitive) - @param S :: string to check - @param fullPhrase :: complete phrase - @return 1 on success -*/ -int confirmStr(const std::string& S,const std::string& fullPhrase) -{ - const size_t nS(S.length()); - const size_t nC(fullPhrase.length()); - if (nS>nC || nS==0) - return 0; - for(size_t i=0;i<nS;i++) - if (S[i]!=fullPhrase[i]) - return 0; - return 1; -} - -//------------------------------------------------------------------------------------------------ -/** - Gets a line and determine if there is addition component to add - in the case of a very long line. - @param fh :: input stream to get line - @param Out :: string up to last 'tab' or ' ' - @param Excess :: string after 'tab or ' ' - @param spc :: number of char to try to read - @retval 1 :: more line to be found - @retval -1 :: Error with file - @retval 0 :: line finished. -*/ -int getPartLine(std::istream& fh,std::string& Out,std::string& Excess,const int spc) -{ - //std::string Line; - if (fh.good()) - { - char* ss=new char[spc+1]; - const int clen = static_cast<int>(spc-Out.length()); - fh.getline(ss,clen,'\n'); - ss[clen+1]=0; // incase line failed to read completely - Out+=static_cast<std::string>(ss); - delete [] ss; - // remove trailing comments - std::string::size_type pos = Out.find_first_of("#!"); - if (pos!=std::string::npos) + char inputChar = (*itr); + if( charStr.find_first_of(inputChar) == std::string::npos ) // Input string char is not one of those to be replaced + { + replaced.push_back(inputChar); + } + else + { + replaced.append(substitute); + } + } + return replaced; + } + + + + //------------------------------------------------------------------------------------------------ + /** + * Function to convert a number into hex + * output (and leave the stream un-changed) + * @param OFS :: Output stream + * @param n :: Integer to convert + * \todo Change this to a stream operator + */ + void printHex(std::ostream& OFS,const int n) + { + std::ios_base::fmtflags PrevFlags=OFS.flags(); + OFS<<"Ox"; + OFS.width(8); + OFS.fill('0'); + hex(OFS); + OFS << n; + OFS.flags(PrevFlags); + return; + } + + //------------------------------------------------------------------------------------------------ + /** + * Removes the multiple spaces in the line + * @param Line :: Line to process + * @return String with single space components + */ + std::string stripMultSpc(const std::string& Line) + { + std::string Out; + int spc(1); + int lastReal(-1); + for(unsigned int i=0;i<Line.length();i++) { - Out.erase(pos); - return 0; - } - if (fh.gcount()==clen-1) // cont line + if (Line[i]!=' ' && Line[i]!='\t' && + Line[i]!='\r' && Line[i]!='\n') + { + lastReal=i; + spc=0; + Out+=Line[i]; + } + else if (!spc) + { + spc=1; + Out+=' '; + } + } + lastReal++; + if (lastReal<static_cast<int>(Out.length())) + Out.erase(lastReal); + return Out; + } + + //------------------------------------------------------------------------------------------------ + //------------------------------------------------------------------------------------------------ + /** + * Checks that as least cnt letters of + * works is part of the string. It is currently + * case sensitive. It removes the Word if found + * @param Line :: Line to process + * @param Word :: Word to use + * @param cnt :: Length of Word for significants [default =4] + * @retval 1 on success (and changed Line) + * @retval 0 on failure + */ + int extractWord(std::string& Line,const std::string& Word,const int cnt) + { + if (Word.empty()) + return 0; + + size_t minSize(cnt>static_cast<int>(Word.size()) ? Word.size() : cnt); + std::string::size_type pos=Line.find(Word.substr(0,minSize)); + if (pos==std::string::npos) + return 0; + // Pos == Start of find + size_t LinePt=minSize+pos; + for(;minSize<Word.size() && LinePt<Line.size() + && Word[minSize]==Line[LinePt];LinePt++,minSize++) { - pos=Out.find_last_of("\t "); - if (pos!=std::string::npos) + } + + Line.erase(pos,LinePt-(pos-1)); + return 1; + } + + //------------------------------------------------------------------------------------------------ + /** If a word ends with a number representing a positive integer, return + * the value of that int. + * + * @param word :: string possibly ending in a number + * @return the number, or -1 if it does not end in a number + */ + int endsWithInt(const std::string & word) + { + if (word.empty()) + return -1; + int out = -1; + // Find the index of the first number in the string (if any) + int firstNumber = int(word.size()); + for (int i=int(word.size())-1; i>=0; i--) { - Excess=Out.substr(pos,std::string::npos); - Out.erase(pos); + char c = word[i]; + if ((c > '9') || (c < '0')) + break; + firstNumber = i; } - else - Excess.erase(0,std::string::npos); - fh.clear(); - return 1; - } - return 0; - } - return -1; -} - -//------------------------------------------------------------------------------------------------ -/** - Removes all spaces from a string - except those with in the form '\ ' - @param CLine :: Line to strip - @return String without space -*/ -std::string removeSpace(const std::string& CLine) -{ - std::string Out; - char prev='x'; - for(unsigned int i=0;i<CLine.length();i++) - { - if (!isspace(CLine[i]) || prev=='\\') + // Convert the string of decimals to an int + if (firstNumber < int(word.size())) { - Out+=CLine[i]; - prev=CLine[i]; - } - } - return Out; -} - -//------------------------------------------------------------------------------------------------ -/** - Reads a line from the stream of max length spc. - Trailing comments are removed. (with # or ! character) - @param fh :: already open file handle - @param spc :: max number of characters to read - @return String read. -*/ -std::string getLine(std::istream& fh,const int spc) -{ - char* ss=new char[spc+1]; - std::string Line; - if (fh.good()) - { - fh.getline(ss,spc,'\n'); - ss[spc]=0; // incase line failed to read completely - Line=ss; - // remove trailing comments - std::string::size_type pos = Line.find_first_of("#!"); - if (pos!=std::string::npos) - Line.erase(pos); - } - delete [] ss; - return Line; -} - -//------------------------------------------------------------------------------------------------ -/** - Determines if a string is only spaces - @param A :: string to check - @return 1 on an empty string , 0 on failure -*/ -int isEmpty(const std::string& A) -{ - std::string::size_type pos= - A.find_first_not_of(" \t"); - return (pos!=std::string::npos) ? 0 : 1; -} - -//------------------------------------------------------------------------------------------------ -/** - removes the string after the comment type of - '$ ' or '!' or '# ' - @param A :: String to process -*/ -void stripComment(std::string& A) -{ - std::string::size_type posA=A.find("$ "); - std::string::size_type posB=A.find("# "); - std::string::size_type posC=A.find("!"); - if (posA>posB) - posA=posB; - if (posA>posC) - posA=posC; - if (posA!=std::string::npos) - A.erase(posA,std::string::npos); - return; -} - -//------------------------------------------------------------------------------------------------ -/** - Returns the string from the first non-space to the - last non-space - @param A :: string to process - @return shortened string -*/ -std::string fullBlock(const std::string& A) -{ - return strip(A); -} - -//------------------------------------------------------------------------------------------------ -/** Returns the string from the first non-space to the - last non-space - @param A :: string to process - @return shortened string -*/ -std::string strip(const std::string& A) -{ - std::string::size_type posA=A.find_first_not_of(" "); - std::string::size_type posB=A.find_last_not_of(" "); - if (posA==std::string::npos) - return ""; - return A.substr(posA,1+posB-posA); -} - - -//------------------------------------------------------------------------------------------------ -/** - Write out the line in the limited form for MCNPX - ie initial line from 0->72 after that 8 to 72 - (split on a space or comma) - @param Line :: full MCNPX line - @param OX :: ostream to write to -*/ -void writeMCNPX(const std::string& Line,std::ostream& OX) -{ - const int MaxLine(72); - std::string::size_type pos(0); - std::string X=Line.substr(0,MaxLine); - std::string::size_type posB=X.find_last_of(" ,"); - int spc(0); - while (posB!=std::string::npos && - static_cast<int>(X.length())>=MaxLine-spc) - { - pos+=posB+1; - if (!isspace(X[posB])) - posB++; - const std::string Out=X.substr(0,posB); - if (!isEmpty(Out)) + std::string part = word.substr(firstNumber, word.size()-firstNumber); + if (!convert(part, out)) + return -1; + } + return out; + } + + //------------------------------------------------------------------------------------------------ + /** + * Check to see if S is the same as the + * first part of a phrase. (case insensitive) + * @param S :: string to check + * @param fullPhrase :: complete phrase + * @return 1 on success + */ + int confirmStr(const std::string& S,const std::string& fullPhrase) + { + const size_t nS(S.length()); + const size_t nC(fullPhrase.length()); + if (nS>nC || nS==0) + return 0; + for(size_t i=0;i<nS;i++) + if (S[i]!=fullPhrase[i]) + return 0; + return 1; + } + + //------------------------------------------------------------------------------------------------ + /** + * Gets a line and determine if there is addition component to add + * in the case of a very long line. + * @param fh :: input stream to get line + * @param Out :: string up to last 'tab' or ' ' + * @param Excess :: string after 'tab or ' ' + * @param spc :: number of char to try to read + * @retval 1 :: more line to be found + * @retval -1 :: Error with file + * @retval 0 :: line finished. + */ + int getPartLine(std::istream& fh,std::string& Out,std::string& Excess,const int spc) + { + //std::string Line; + if (fh.good()) { - if (spc) - OX<<std::string(spc,' '); - OX<<X.substr(0,posB)<<std::endl; - } - spc=8; - X=Line.substr(pos,MaxLine-spc); - posB=X.find_last_of(" ,"); - } - if (!isEmpty(X)) - { - if (spc) - OX<<std::string(spc,' '); - OX<<X<<std::endl; - } - return; -} - -//------------------------------------------------------------------------------------------------ -/** - Splits the sting into parts that are space delminated. - @param Ln :: line component to strip - @return vector of components -*/ -std::vector<std::string> StrParts(std::string Ln) -{ - std::vector<std::string> Out; - std::string Part; - while(section(Ln,Part)) - Out.push_back(Part); - return Out; -} - -//------------------------------------------------------------------------------------------------ -/** - Converts a vax number into a standard unix number - @param A :: float number as read from a VAX file - @return float A in IEEE little eindian format -*/ -float getVAXnum(const float A) -{ - union - { - //char a[4]; - float f; - int ival; - } Bd; - - int sign,expt,fmask; - float frac; - double onum; - - Bd.f=A; - sign = (Bd.ival & 0x8000) ? -1 : 1; - expt = ((Bd.ival & 0x7f80) >> 7); //reveresed ? - if (!expt) - return 0.0; - - fmask = ((Bd.ival & 0x7f) << 16) | ((Bd.ival & 0xffff0000) >> 16); - expt-=128; - fmask |= 0x800000; - frac = (float) fmask / 0x1000000; - onum = frac * static_cast<float>(sign) * pow(2.0,expt); - return (float) onum; -} - - -//------------------------------------------------------------------------------------------------ -/** - Takes a character string and evaluates - the first [typename T] object. The string is then - erase upt to the end of number. - The diffierence between this and section is that - it allows trailing characters after the number. - @param out :: place for output - @param A :: string to process - @return 1 on success 0 on failure - */ -template<typename T> -int sectPartNum(std::string& A,T& out) -{ - if (A.empty()) - return 0; - - std::istringstream cx; - T retval; - cx.str(A); - cx.clear(); - cx>>retval; - const std::streamoff xpt = cx.tellg(); - if (xpt < 0) - return 0; - A.erase(0,static_cast<unsigned int>(xpt)); - out=retval; - return 1; -} - -//------------------------------------------------------------------------------------------------ -/** - Takes a character string and evaluates - the first [typename T] object. The string is then filled with - spaces upto the end of the [typename T] object - @param out :: place for output - @param cA :: char array for input and output. - @return 1 on success 0 on failure - */ -template<typename T> -int section(char* cA,T& out) -{ - if (!cA) return 0; - std::string sA(cA); - const int item(section(sA,out)); - if (item) + char* ss=new char[spc+1]; + const int clen = static_cast<int>(spc-Out.length()); + fh.getline(ss,clen,'\n'); + ss[clen+1]=0; // incase line failed to read completely + Out+=static_cast<std::string>(ss); + delete [] ss; + // remove trailing comments + std::string::size_type pos = Out.find_first_of("#!"); + if (pos!=std::string::npos) + { + Out.erase(pos); + return 0; + } + if (fh.gcount()==clen-1) // cont line + { + pos=Out.find_last_of("\t "); + if (pos!=std::string::npos) + { + Excess=Out.substr(pos,std::string::npos); + Out.erase(pos); + } + else + Excess.erase(0,std::string::npos); + fh.clear(); + return 1; + } + return 0; + } + return -1; + } + + //------------------------------------------------------------------------------------------------ + /** + * Removes all spaces from a string + * except those with in the form '\ ' + * @param CLine :: Line to strip + * @return String without space + */ + std::string removeSpace(const std::string& CLine) + { + std::string Out; + char prev='x'; + for(unsigned int i=0;i<CLine.length();i++) + { + if (!isspace(CLine[i]) || prev=='\\') + { + Out+=CLine[i]; + prev=CLine[i]; + } + } + return Out; + } + + //------------------------------------------------------------------------------------------------ + /** + * Reads a line from the stream of max length spc. + * Trailing comments are removed. (with # or ! character) + * @param fh :: already open file handle + * @param spc :: max number of characters to read + * @return String read. + */ + std::string getLine(std::istream& fh,const int spc) + { + char* ss=new char[spc+1]; + std::string Line; + if (fh.good()) + { + fh.getline(ss,spc,'\n'); + ss[spc]=0; // incase line failed to read completely + Line=ss; + // remove trailing comments + std::string::size_type pos = Line.find_first_of("#!"); + if (pos!=std::string::npos) + Line.erase(pos); + } + delete [] ss; + return Line; + } + + //------------------------------------------------------------------------------------------------ + /** + * Determines if a string is only spaces + * @param A :: string to check + * @return 1 on an empty string , 0 on failure + */ + int isEmpty(const std::string& A) + { + std::string::size_type pos= + A.find_first_not_of(" \t"); + return (pos!=std::string::npos) ? 0 : 1; + } + + //------------------------------------------------------------------------------------------------ + /** + * removes the string after the comment type of + * '$ ' or '!' or '# ' + * @param A :: String to process + */ + void stripComment(std::string& A) + { + std::string::size_type posA=A.find("$ "); + std::string::size_type posB=A.find("# "); + std::string::size_type posC=A.find("!"); + if (posA>posB) + posA=posB; + if (posA>posC) + posA=posC; + if (posA!=std::string::npos) + A.erase(posA,std::string::npos); + return; + } + + //------------------------------------------------------------------------------------------------ + /** + * Returns the string from the first non-space to the + * last non-space + * @param A :: string to process + * @return shortened string + */ + std::string fullBlock(const std::string& A) + { + return strip(A); + } + + //------------------------------------------------------------------------------------------------ + /** Returns the string from the first non-space to the + * last non-space + * @param A :: string to process + * @return shortened string + */ + std::string strip(const std::string& A) + { + std::string::size_type posA=A.find_first_not_of(" "); + std::string::size_type posB=A.find_last_not_of(" "); + if (posA==std::string::npos) + return ""; + return A.substr(posA,1+posB-posA); + } + + + //------------------------------------------------------------------------------------------------ + /** + * Write out the line in the limited form for MCNPX + * ie initial line from 0->72 after that 8 to 72 + * (split on a space or comma) + * @param Line :: full MCNPX line + * @param OX :: ostream to write to + */ + void writeMCNPX(const std::string& Line,std::ostream& OX) + { + const int MaxLine(72); + std::string::size_type pos(0); + std::string X=Line.substr(0,MaxLine); + std::string::size_type posB=X.find_last_of(" ,"); + int spc(0); + while (posB!=std::string::npos && + static_cast<int>(X.length())>=MaxLine-spc) + { + pos+=posB+1; + if (!isspace(X[posB])) + posB++; + const std::string Out=X.substr(0,posB); + if (!isEmpty(Out)) + { + if (spc) + OX<<std::string(spc,' '); + OX<<X.substr(0,posB)<<std::endl; + } + spc=8; + X=Line.substr(pos,MaxLine-spc); + posB=X.find_last_of(" ,"); + } + if (!isEmpty(X)) + { + if (spc) + OX<<std::string(spc,' '); + OX<<X<<std::endl; + } + return; + } + + //------------------------------------------------------------------------------------------------ + /** + * Splits the sting into parts that are space delminated. + * @param Ln :: line component to strip + * @return vector of components + */ + std::vector<std::string> StrParts(std::string Ln) { - strcpy(cA,sA.c_str()); - return 1; + std::vector<std::string> Out; + std::string Part; + while(section(Ln,Part)) + Out.push_back(Part); + return Out; } - return 0; -} - -/* - takes a character string and evaluates - the first <T> object. The string is then filled with - spaces upto the end of the <T> object - @param out :: place for output - @param A :: string for input and output. - @return 1 on success 0 on failure -*/ -template<typename T> -int section(std::string& A,T& out) -{ - if (A.empty()) return 0; - std::istringstream cx; - T retval; - cx.str(A); - cx.clear(); - cx>>retval; - if (cx.fail()) - return 0; - const std::streamoff xpt = cx.tellg(); - const char xc = static_cast<char>(cx.get()); - if (!cx.fail() && !isspace(xc)) - return 0; - A.erase(0, static_cast<unsigned int>(xpt)); - out=retval; - return 1; -} - -/* - Takes a character string and evaluates - the first [T] object. The string is then filled with - spaces upto the end of the [T] object. - This version deals with MCNPX numbers. Those - are numbers that are crushed together like - - 5.4938e+04-3.32923e-6 - @param out :: place for output - @param A :: string for input and output. - @return 1 on success 0 on failure -*/ -template<typename T> -int sectionMCNPX(std::string& A,T& out) -{ - if (A.empty()) return 0; - std::istringstream cx; - T retval; - cx.str(A); - cx.clear(); - cx>>retval; - if (!cx.fail()) - { - const std::streamoff xpt = cx.tellg(); - if( xpt < 0 ) + + + //------------------------------------------------------------------------------------------------ + /** + * Converts a vax number into a standard unix number + * @param A :: float number as read from a VAX file + * @return float A in IEEE little eindian format + */ + float getVAXnum(const float A) { + union + { + //char a[4]; + float f; + int ival; + } Bd; + + int sign,expt,fmask; + float frac; + double onum; + + Bd.f=A; + sign = (Bd.ival & 0x8000) ? -1 : 1; + expt = ((Bd.ival & 0x7f80) >> 7); //reveresed ? + if (!expt) + return 0.0; + + fmask = ((Bd.ival & 0x7f) << 16) | ((Bd.ival & 0xffff0000) >> 16); + expt-=128; + fmask |= 0x800000; + frac = (float) fmask / 0x1000000; + onum = frac * static_cast<float>(sign) * pow(2.0,expt); + return (float) onum; + } + + + //------------------------------------------------------------------------------------------------ + /** + * Takes a character string and evaluates + * the first [typename T] object. The string is then + * erase upt to the end of number. + * The diffierence between this and section is that + * it allows trailing characters after the number. + * @param out :: place for output + * @param A :: string to process + * @return 1 on success 0 on failure + */ + template<typename T> + int sectPartNum(std::string& A,T& out) + { + if (A.empty()) + return 0; + + std::istringstream cx; + T retval; + cx.str(A); + cx.clear(); + cx>>retval; + const std::streamoff xpt = cx.tellg(); + if (xpt < 0) + return 0; + A.erase(0,static_cast<unsigned int>(xpt)); + out=retval; + return 1; + } + + //------------------------------------------------------------------------------------------------ + /** + * Takes a character string and evaluates + * the first [typename T] object. The string is then filled with + * spaces upto the end of the [typename T] object + * @param out :: place for output + * @param cA :: char array for input and output. + * @return 1 on success 0 on failure + */ + template<typename T> + int section(char* cA,T& out) + { + if (!cA) return 0; + std::string sA(cA); + const int item(section(sA,out)); + if (item) + { + strcpy(cA,sA.c_str()); + return 1; + } return 0; } - const char xc=static_cast<char>(cx.get()); - if (!cx.fail() && !isspace(xc) && (xc!='-' || xpt<5)) + + /** + * takes a character string and evaluates + * the first <T> object. The string is then filled with + * spaces upto the end of the <T> object + * @param out :: place for output + * @param A :: string for input and output. + * @return 1 on success 0 on failure + */ + template<typename T> + int section(std::string& A,T& out) { + if (A.empty()) return 0; + std::istringstream cx; + T retval; + cx.str(A); + cx.clear(); + cx>>retval; + if (cx.fail()) + return 0; + const std::streamoff xpt = cx.tellg(); + const char xc = static_cast<char>(cx.get()); + if (!cx.fail() && !isspace(xc)) + return 0; + A.erase(0, static_cast<unsigned int>(xpt)); + out=retval; + return 1; + } + + /** + * Takes a character string and evaluates + * the first [T] object. The string is then filled with + * spaces upto the end of the [T] object. + * This version deals with MCNPX numbers. Those + * are numbers that are crushed together like + * - 5.4938e+04-3.32923e-6 + * @param out :: place for output + * @param A :: string for input and output. + * @return 1 on success 0 on failure + */ + template<typename T> + int sectionMCNPX(std::string& A,T& out) + { + if (A.empty()) return 0; + std::istringstream cx; + T retval; + cx.str(A); + cx.clear(); + cx>>retval; + if (!cx.fail()) + { + const std::streamoff xpt = cx.tellg(); + if( xpt < 0 ) + { + return 0; + } + const char xc=static_cast<char>(cx.get()); + if (!cx.fail() && !isspace(xc) && (xc!='-' || xpt<5)) + { + return 0; + } + A.erase(0, static_cast<unsigned int>(xpt)); + out=retval; + return 1; + } return 0; } - A.erase(0, static_cast<unsigned int>(xpt)); - out=retval; - return 1; - } - return 0; -} - -//------------------------------------------------------------------------------------------------ -/** - Takes a character string and evaluates - the first [typename T] object. The string is then - erase upto the end of number. - The diffierence between this and convert is that - it allows trailing characters after the number. - @param out :: place for output - @param A :: string to process - @retval number of char read on success - @retval 0 on failure - */ -template<typename T> -int convPartNum(const std::string& A,T& out) -{ - if (A.empty()) return 0; - std::istringstream cx; - T retval; - cx.str(A); - cx.clear(); - cx>>retval; - // If we have reached the end of the stream, then we need to clear the error as - // it will cause the tellg() call to return -1. Not pretty but works for now. - cx.clear(); - const std::streamoff xpt = cx.tellg(); - if (xpt<0) - return 0; - out=retval; - return static_cast<int>(xpt); -} - -//------------------------------------------------------------------------------------------------ -/** - Convert a string into a value - @param A :: string to pass - @param out :: value if found - @return 0 on failure 1 on success -*/ -template<typename T> -int convert(const std::string& A,T& out) -{ - if (A.empty()) return 0; - std::istringstream cx; - T retval; - cx.str(A); - cx.clear(); - cx>>retval; - if (cx.fail()) - return 0; - const char clast = static_cast<char>(cx.get()); - if (!cx.fail() && !isspace(clast)) - return 0; - out=retval; - return 1; -} - -//------------------------------------------------------------------------------------------------ -/** - Convert a string into a value - @param A :: string to pass - @param out :: value if found - @return 0 on failure 1 on success -*/ -template<typename T> -int convert(const char* A,T& out) -{ - // No string, no conversion - if (!A) return 0; - std::string Cx=A; - return convert(Cx,out); -} - - -//------------------------------------------------------------------------------------------------ -/** Convert a number or other value to a string - * - * @param value :: templated value (e.g. a double) to convert - * @return a string - */ -template<typename T> -std::string toString(const T value) -{ - std::ostringstream mess; - mess << value; - return mess.str(); -} - -/** - * This assumes that the vector is sorted. - * - * @param value :: templated value (only works for integer types) to convert. - * @return A reduced string representation. - */ -template<typename T> -std::string toString(const std::vector<T> &value) -{ - std::ostringstream mess; - auto it = value.begin(); - auto last = value.end(); - T start; - T stop; - for (; it != last; ++it) - { - start = *(it); - stop = start; - for ( ; it != last; ++it) - { - if ( (stop + static_cast<T>(1)) == *(it+1) ) - stop = *(it+1); - else - break; - } - mess << start; - if (start != stop) - mess << "-" << stop; - if (it+1 != last) - mess << ","; - } - return mess.str(); -} - -template<typename T> -std::string toString(const std::set<T> &value) -{ - return toString(std::vector<T>(value.begin(), value.end())); -} - -//------------------------------------------------------------------------------------------------ -/** - Write out the three vectors into a file of type dc 9 - @param step :: parameter to control x-step (starts from zero) - @param Y :: Y column - @param Fname :: Name of the file - @return 0 on success and -ve on failure -*/ -template<template<typename T,typename A> class V,typename T,typename A> -int writeFile(const std::string& Fname,const T &step, const V<T,A>& Y) -{ - V<T,A> Ex; // Empty vector - V<T,A> X; // Empty vector - for(unsigned int i=0;i<Y.size();i++) - X.push_back(i*step); - - return writeFile(Fname,X,Y,Ex); -} - -//------------------------------------------------------------------------------------------------ -/** - Write out the three vectors into a file of type dc 9 - @param X :: X column - @param Y :: Y column - @param Fname :: Name of the file - @return 0 on success and -ve on failure -*/ -template<template<typename T,typename A> class V,typename T,typename A> -int writeFile(const std::string& Fname,const V<T,A>& X,const V<T,A>& Y) -{ - V<T,A> Ex; // Empty vector/list - return writeFile(Fname,X,Y,Ex); // don't need to specific ?? -} - -//------------------------------------------------------------------------------------------------ -/** - Write out the three container into a file with - column free-formated data in the form : - - X Y Err - If Err does not exist (or is short) 0.0 is substituted. - @param X :: X column - @param Y :: Y column - @param Err :: Err column - @param Fname :: Name of the file - @return 0 on success and -ve on failure -*/ -template<template<typename T,typename A> class V,typename T,typename A> -int writeFile(const std::string& Fname,const V<T,A>& X,const V<T,A>& Y,const V<T,A>& Err) -{ - const size_t Npts(X.size()>Y.size() ? Y.size() : X.size()); - const size_t Epts(Npts > Err.size() ? Err.size() : Npts); - std::ofstream FX; + //------------------------------------------------------------------------------------------------ + /** + * Takes a character string and evaluates + * the first [typename T] object. The string is then + * erase upto the end of number. + * The diffierence between this and convert is that + * it allows trailing characters after the number. + * @param out :: place for output + * @param A :: string to process + * @retval number of char read on success + * @retval 0 on failure + */ + template<typename T> + int convPartNum(const std::string& A,T& out) + { + if (A.empty()) return 0; + std::istringstream cx; + T retval; + cx.str(A); + cx.clear(); + cx>>retval; + // If we have reached the end of the stream, then we need to clear the error as + // it will cause the tellg() call to return -1. Not pretty but works for now. + cx.clear(); + const std::streamoff xpt = cx.tellg(); + if (xpt<0) + return 0; + out=retval; + return static_cast<int>(xpt); + } - FX.open(Fname.c_str()); - if (!FX.good()) - return -1; + //------------------------------------------------------------------------------------------------ + /** + * Convert a string into a value + * @param A :: string to pass + * @param out :: value if found + * @return 0 on failure 1 on success + */ + template<typename T> + int convert(const std::string& A,T& out) + { + if (A.empty()) return 0; + std::istringstream cx; + T retval; + cx.str(A); + cx.clear(); + cx>>retval; + if (cx.fail()) + return 0; + const char clast = static_cast<char>(cx.get()); + if (!cx.fail() && !isspace(clast)) + return 0; + out=retval; + return 1; + } - FX<<"# "<<Npts<<" "<<Epts<<std::endl; - FX.precision(10); - FX.setf(std::ios::scientific,std::ios::floatfield); - typename V<T,A>::const_iterator xPt=X.begin(); - typename V<T,A>::const_iterator yPt=Y.begin(); - typename V<T,A>::const_iterator ePt=(Epts ? Err.begin() : Y.begin()); + //------------------------------------------------------------------------------------------------ + /** + * Convert a string into a value + * @param A :: string to pass + * @param out :: value if found + * @return 0 on failure 1 on success + */ + template<typename T> + int convert(const char* A,T& out) + { + // No string, no conversion + if (!A) return 0; + std::string Cx=A; + return convert(Cx,out); + } - // Double loop to include/exclude a short error stack - size_t eCount=0; - for(;eCount<Epts;eCount++) - { - FX<<(*xPt)<<" "<<(*yPt)<<" "<<(*ePt)<<std::endl; - ++xPt; - ++yPt; - ++ePt; - } - for(;eCount<Npts;eCount++) - { - FX<<(*xPt)<<" "<<(*yPt)<<" 0.0"<<std::endl; - ++xPt; - ++yPt; - } - FX.close(); - return 0; -} - -//------------------------------------------------------------------------------------------------ -/** - Call to read in various values in position x1,x2,x3 from the - line. Note to avoid the dependency on crossSort this needs - to be call IN ORDER - @param Line :: string to read - @param Index :: Indexes to read - @param Out :: OutValues [unchanged if not read] - @retval 0 :: success - @retval -ve on failure. -*/ -template<typename T> -int setValues(const std::string& Line,const std::vector<int>& Index,std::vector<T>& Out) -{ - if (Index.empty()) - return 0; - - if(Out.size()!=Index.size()) - return -1; -// throw ColErr::MisMatch<int>(Index.size(),Out.size(), -// "Mantid::Kernel::Strings::setValues"); - - std::string modLine=Line; - std::vector<int> sIndex(Index); // Copy for sorting - std::vector<int> OPt(Index.size()); - for(unsigned int i=0;i<Index.size();i++) - OPt[i]=i; - - - // mathFunc::crossSort(sIndex,OPt); - - typedef std::vector<int>::const_iterator iVecIter; - std::vector<int>::const_iterator sc=sIndex.begin(); - std::vector<int>::const_iterator oc=OPt.begin(); - int cnt(0); - T value; - std::string dump; - while(sc!=sIndex.end() && *sc<0) - { - sc++; - oc++; - } - while(sc!=sIndex.end()) - { - if (*sc==cnt) - { - if (!section(modLine,value)) - return static_cast<int>(-1-distance(static_cast<iVecIter>(sIndex.begin()),sc)); - // this loop handles repeat units - do + //------------------------------------------------------------------------------------------------ + /** Convert a number or other value to a string + * + * @param value :: templated value (e.g. a double) to convert + * @return a string + */ + template<typename T> + std::string toString(const T value) + { + std::ostringstream mess; + mess << value; + return mess.str(); + } + + /** + * This assumes that the vector is sorted. + * + * @param value :: templated value (only works for integer types) to convert. + * @return A reduced string representation. + */ + template<typename T> + std::string toString(const std::vector<T> &value) { - Out[*oc]=value; - sc++; - oc++; - } while (sc!=sIndex.end() && *sc==cnt); - } - else + std::ostringstream mess; + auto it = value.begin(); + auto last = value.end(); + T start; + T stop; + for (; it != last; ++it) { - if (!section(modLine,dump)) - return static_cast<int>(-1-distance(static_cast<iVecIter>(sIndex.begin()),sc)); - } - cnt++; // Add only to cnt [sc/oc in while loop] - } - // Success since loop only gets here if sc is exhaused. - return 0; -} + start = *(it); + stop = start; + for ( ; it != last; ++it) + { + if ( (stop + static_cast<T>(1)) == *(it+1) ) + stop = *(it+1); + else + break; + } + mess << start; + if (start != stop) + mess << "-" << stop; + if (it+1 != last) + mess << ","; + } + return mess.str(); + } + template<typename T> + std::string toString(const std::set<T> &value) + { + return toString(std::vector<T>(value.begin(), value.end())); + } + //------------------------------------------------------------------------------------------------ + /** + * Write out the three vectors into a file of type dc 9 + * @param step :: parameter to control x-step (starts from zero) + * @param Y :: Y column + * @param Fname :: Name of the file + * @return 0 on success and -ve on failure + */ + template<template<typename T,typename A> class V,typename T,typename A> + int writeFile(const std::string& Fname,const T &step, const V<T,A>& Y) + { + V<T,A> Ex; // Empty vector + V<T,A> X; // Empty vector + for(unsigned int i=0;i<Y.size();i++) + X.push_back(i*step); + return writeFile(Fname,X,Y,Ex); + } + //------------------------------------------------------------------------------------------------ + /** + * Write out the three vectors into a file of type dc 9 + * @param X :: X column + * @param Y :: Y column + * @param Fname :: Name of the file + * @return 0 on success and -ve on failure + */ + template<template<typename T,typename A> class V,typename T,typename A> + int writeFile(const std::string& Fname,const V<T,A>& X,const V<T,A>& Y) + { + V<T,A> Ex; // Empty vector/list + return writeFile(Fname,X,Y,Ex); // don't need to specific ?? + } -//----------------------------------------------------------------------------------------------- -/** Get a word from a line and strips spaces - * - * @param in :: stream input - * @param consumeEOL :: set to true to remove the new lines at the end of the line - * @return a string with the word read in - */ -std::string getWord( std::ifstream &in , bool consumeEOL ) -{ - std::string s; - char c = 0; - if( in.good() ) - for( c = static_cast<char>(in.get()) ; c == ' ' && in.good() ; c = static_cast<char>(in.get()) ) - {} - else - return std::string(); - - if( c == '\n' ) - { - if( !consumeEOL ) - in.putback( c ); + //------------------------------------------------------------------------------------------------ + /** + * Write out the three container into a file with + * column free-formated data in the form : + * - X Y Err + * If Err does not exist (or is short) 0.0 is substituted. + * @param X :: X column + * @param Y :: Y column + * @param Err :: Err column + * @param Fname :: Name of the file + * @return 0 on success and -ve on failure + */ + template<template<typename T,typename A> class V,typename T,typename A> + int writeFile(const std::string& Fname,const V<T,A>& X,const V<T,A>& Y,const V<T,A>& Err) + { + const size_t Npts(X.size()>Y.size() ? Y.size() : X.size()); + const size_t Epts(Npts > Err.size() ? Err.size() : Npts); - return std::string(); - } + std::ofstream FX; - s.push_back( c ); + FX.open(Fname.c_str()); + if (!FX.good()) + return -1; - if( in.good() ) - for( c = static_cast<char>(in.get()) ; in.good()&&c != ' ' && c != '\n' && c != '\r' ; c = static_cast<char>(in.get()) ) - s.push_back( c ); + FX<<"# "<<Npts<<" "<<Epts<<std::endl; + FX.precision(10); + FX.setf(std::ios::scientific,std::ios::floatfield); + typename V<T,A>::const_iterator xPt=X.begin(); + typename V<T,A>::const_iterator yPt=Y.begin(); + typename V<T,A>::const_iterator ePt=(Epts ? Err.begin() : Y.begin()); - if( ((c == '\n') || (c == '\r')) && !consumeEOL ) - in.putback( c ); + // Double loop to include/exclude a short error stack + size_t eCount=0; + for(;eCount<Epts;eCount++) + { + FX<<(*xPt)<<" "<<(*yPt)<<" "<<(*ePt)<<std::endl; + ++xPt; + ++yPt; + ++ePt; + } + for(;eCount<Npts;eCount++) + { + FX<<(*xPt)<<" "<<(*yPt)<<" 0.0"<<std::endl; + ++xPt; + ++yPt; + } + FX.close(); + return 0; + } - return s; -} + //------------------------------------------------------------------------------------------------ + /** + * Call to read in various values in position x1,x2,x3 from the + * line. Note to avoid the dependency on crossSort this needs + * to be call IN ORDER + * @param Line :: string to read + * @param Index :: Indexes to read + * @param Out :: OutValues [unchanged if not read] + * @retval 0 :: success + * @retval -ve on failure. + */ + template<typename T> + int setValues(const std::string& Line,const std::vector<int>& Index,std::vector<T>& Out) + { + if (Index.empty()) + return 0; + + if(Out.size()!=Index.size()) + return -1; + // throw ColErr::MisMatch<int>(Index.size(),Out.size(), + // "Mantid::Kernel::Strings::setValues"); + + std::string modLine=Line; + std::vector<int> sIndex(Index); // Copy for sorting + std::vector<int> OPt(Index.size()); + for(unsigned int i=0;i<Index.size();i++) + OPt[i]=i; + + + // mathFunc::crossSort(sIndex,OPt); + + typedef std::vector<int>::const_iterator iVecIter; + std::vector<int>::const_iterator sc=sIndex.begin(); + std::vector<int>::const_iterator oc=OPt.begin(); + int cnt(0); + T value; + std::string dump; + while(sc!=sIndex.end() && *sc<0) + { + sc++; + oc++; + } -//----------------------------------------------------------------------------------------------- -/** Read up to the eol - * - * @param in :: stream input - * @param ConsumeEOL :: set to true to remove the new lines at the end of the line - */ -void readToEndOfLine( std::ifstream& in , bool ConsumeEOL ) -{ - while( in.good() && getWord( in , false ).length() > 0 ) - getWord( in , false ); - if( !ConsumeEOL ) - return ; - getWord( in , true ); -} -/** function parses a path, placed into input string "path" and returns vector of the folders contributed into the path -* @param path :: the string containing input path, - found in path string, if they are separated by \ or / symbols. - Treats special symbols, if defined in the input string as path-es - returns 0 for empty input string - @param path_components :: holder for the individual folders in the path - - used to generate path in hdf file, so the resulting path has to obey hdf constrains; -*/ -size_t split_path(const std::string &path, std::vector<std::string> &path_components) -{ - if(path.empty()){ - path_components.resize(0); + while(sc!=sIndex.end()) + { + if (*sc==cnt) + { + if (!section(modLine,value)) + return static_cast<int>(-1-distance(static_cast<iVecIter>(sIndex.begin()),sc)); + // this loop handles repeat units + do + { + Out[*oc]=value; + sc++; + oc++; + } while (sc!=sIndex.end() && *sc==cnt); + } + else + { + if (!section(modLine,dump)) + return static_cast<int>(-1-distance(static_cast<iVecIter>(sIndex.begin()),sc)); + } + cnt++; // Add only to cnt [sc/oc in while loop] + } + // Success since loop only gets here if sc is exhaused. return 0; - } - // convert Windows path into the unix one - std::string working_path(path); - for(size_t i=0;i<path.size();i++){ - if(working_path[i]<0x20||working_path[i]>0x7E)working_path[i]='_'; - if(working_path[i]=='\\')working_path[i]='/'; - if(working_path[i]==' ')working_path[i]='_'; - } - - - // path start with relative character, and we need to convert it into full path - if(path[0]=='.'){ - // get absolute path using working directory as base; - Poco::Path absol; - absol = absol.absolute(); - working_path = absol.toString(Poco::Path::PATH_UNIX)+working_path; - } - // as poco splt using regular expressions is doing some rubbish, we need to do split manually - // code below implements perl split(/\\//,string) commamd. (\\ has been converted to / above) - std::list<int64_t> split_pos; - split_pos.push_back(-1); - size_t path_size = working_path.size(); - for(size_t i=0;i<path_size;i++){ - if(working_path[i]=='/'){ + } + + + + + + //----------------------------------------------------------------------------------------------- + /** Get a word from a line and strips spaces + * + * @param in :: stream input + * @param consumeEOL :: set to true to remove the new lines at the end of the line + * @return a string with the word read in + */ + std::string getWord( std::ifstream &in , bool consumeEOL ) + { + std::string s; + char c = 0; + if( in.good() ) + for( c = static_cast<char>(in.get()) ; c == ' ' && in.good() ; c = static_cast<char>(in.get()) ) + {} + else + return std::string(); + + if( c == '\n' ) + { + if( !consumeEOL ) + in.putback( c ); + + return std::string(); + } + + s.push_back( c ); + + if( in.good() ) + for( c = static_cast<char>(in.get()) ; in.good()&&c != ' ' && c != '\n' && c != '\r' ; c = static_cast<char>(in.get()) ) + s.push_back( c ); + + if( ((c == '\n') || (c == '\r')) && !consumeEOL ) + in.putback( c ); + + return s; + } + + //----------------------------------------------------------------------------------------------- + /** Read up to the eol + * + * @param in :: stream input + * @param ConsumeEOL :: set to true to remove the new lines at the end of the line + */ + void readToEndOfLine( std::ifstream& in , bool ConsumeEOL ) + { + while( in.good() && getWord( in , false ).length() > 0 ) + getWord( in , false ); + if( !ConsumeEOL ) + return ; + getWord( in , true ); + } + + /** + * Function parses a path, placed into input string "path" and returns vector of the folders contributed into the path + * @param path :: the string containing input path, found in path string, if they are separated by \ or / symbols. + * Treats special symbols, if defined in the input string as path-es + * returns 0 for empty input string + * @param path_components :: holder for the individual folders in the path + * used to generate path in hdf file, so the resulting path has to obey hdf constrains; + */ + size_t split_path(const std::string &path, std::vector<std::string> &path_components) + { + if(path.empty()){ + path_components.resize(0); + return 0; + } + // convert Windows path into the unix one + std::string working_path(path); + for(size_t i=0;i<path.size();i++){ + if(working_path[i]<0x20||working_path[i]>0x7E)working_path[i]='_'; + if(working_path[i]=='\\')working_path[i]='/'; + if(working_path[i]==' ')working_path[i]='_'; + } + + + // path start with relative character, and we need to convert it into full path + if(path[0]=='.'){ + // get absolute path using working directory as base; + Poco::Path absol; + absol = absol.absolute(); + working_path = absol.toString(Poco::Path::PATH_UNIX)+working_path; + } + // as poco splt using regular expressions is doing some rubbish, we need to do split manually + // code below implements perl split(/\\//,string) commamd. (\\ has been converted to / above) + std::list<int64_t> split_pos; + split_pos.push_back(-1); + size_t path_size = working_path.size(); + for(size_t i=0;i<path_size;i++){ + if(working_path[i]=='/'){ split_pos.push_back(i); + } } - } - split_pos.push_back(path_size); - // allocate target vector to keep folder structure and fill it in - size_t n_folders = split_pos.size()-1; - path_components.resize(n_folders); - std::list<int64_t>::iterator it1 = split_pos.begin(); - std::list<int64_t>::iterator it2 = it1; - ++it2; - - int64_t ic(0); - for(; it2!=split_pos.end();++it2){ - std::string folder = working_path.substr(*it1+1,*it2-*it1-1); - if(folder.empty()||(folder.size()==1&&folder==".")){ // skip self-references and double slashes; + split_pos.push_back(path_size); + // allocate target vector to keep folder structure and fill it in + size_t n_folders = split_pos.size()-1; + path_components.resize(n_folders); + std::list<int64_t>::iterator it1 = split_pos.begin(); + std::list<int64_t>::iterator it2 = it1; + ++it2; + + int64_t ic(0); + for(; it2!=split_pos.end();++it2){ + std::string folder = working_path.substr(*it1+1,*it2-*it1-1); + if(folder.empty()||(folder.size()==1&&folder==".")){ // skip self-references and double slashes; it1=it2; continue; - } - // reprocess up-references; - if(folder==".."){ + } + // reprocess up-references; + if(folder==".."){ if(folder.size()!=2)throw(std::invalid_argument("path contains wrong path group")); ic--; if(ic<0)throw(std::invalid_argument("path contains relative references to a folder outside of the seach tree")); it1=it2; continue; + } + path_components[ic]=folder; + ic++; + it1=it2; } - path_components[ic]=folder; - ic++; - it1=it2; - } - n_folders=size_t(ic); - path_components.resize(n_folders); - return n_folders; -} -/** function checks if the candidate is the member of the group - * @param group -- vector of string to check - * @param candidate -- the string which has to be checked against the group - - * @returns -- number of the candidate in the input vector of strings if the candidate belongs to the group - or -1 if it does not. - Returns the number of the first maching entry in the group if there are duplicated entries in the group -*/ -int isMember(const std::vector<std::string> &group, const std::string &candidate) -{ - int num(-1); - for(size_t i=0;i<group.size();i++){ - if(candidate.compare(group[i])==0){ + n_folders=size_t(ic); + path_components.resize(n_folders); + return n_folders; + } + + /** + * Function checks if the candidate is the member of the group + * @param group :: vector of string to check + * @param candidate :: the string which has to be checked against the group + * @returns :: number of the candidate in the input vector of strings if the candidate belongs to the group + or -1 if it does not. + Returns the number of the first maching entry in the group if there are duplicated entries in the group + */ + int isMember(const std::vector<std::string> &group, const std::string &candidate) + { + int num(-1); + for(size_t i=0;i<group.size();i++){ + if(candidate.compare(group[i])==0){ num = int(i); return num; + } } - } - return num; -} - -/// \cond TEMPLATE - -template MANTID_KERNEL_DLL int section(std::string&,double&); -template MANTID_KERNEL_DLL int section(std::string&,float&); -template MANTID_KERNEL_DLL int section(std::string&,int&); -template MANTID_KERNEL_DLL int section(std::string&,std::string&); -//template MANTID_KERNEL_DLL int section(std::string&, Mantid::Geometry::V3D&); - -template MANTID_KERNEL_DLL int sectPartNum(std::string&,double&); -template MANTID_KERNEL_DLL int sectPartNum(std::string&,int&); -template MANTID_KERNEL_DLL int sectionMCNPX(std::string&,double&); - -template MANTID_KERNEL_DLL int convert(const std::string&,double&); -template MANTID_KERNEL_DLL int convert(const std::string&,float&); -template MANTID_KERNEL_DLL int convert(const std::string&,std::string&); -template MANTID_KERNEL_DLL int convert(const std::string&,int&); -template MANTID_KERNEL_DLL int convert(const std::string&,std::size_t&); -template MANTID_KERNEL_DLL int convert(const char*,std::string&); -template MANTID_KERNEL_DLL int convert(const char*,double&); -template MANTID_KERNEL_DLL int convert(const char*,int&); -template MANTID_KERNEL_DLL int convert(const char*,std::size_t&); - -template MANTID_KERNEL_DLL std::string toString(const double value); -template MANTID_KERNEL_DLL std::string toString(const float value); -template MANTID_KERNEL_DLL std::string toString(const int value); -template MANTID_KERNEL_DLL std::string toString(const uint16_t value); -template MANTID_KERNEL_DLL std::string toString(const size_t value); // Matches uint64_t on Linux 64 & Win 64 + return num; + } + + /// \cond TEMPLATE + template MANTID_KERNEL_DLL int section(std::string&,double&); + template MANTID_KERNEL_DLL int section(std::string&,float&); + template MANTID_KERNEL_DLL int section(std::string&,int&); + template MANTID_KERNEL_DLL int section(std::string&,std::string&); + + template MANTID_KERNEL_DLL int sectPartNum(std::string&,double&); + template MANTID_KERNEL_DLL int sectPartNum(std::string&,int&); + template MANTID_KERNEL_DLL int sectionMCNPX(std::string&,double&); + + template MANTID_KERNEL_DLL int convert(const std::string&,double&); + template MANTID_KERNEL_DLL int convert(const std::string&,float&); + template MANTID_KERNEL_DLL int convert(const std::string&,std::string&); + template MANTID_KERNEL_DLL int convert(const std::string&,int&); + template MANTID_KERNEL_DLL int convert(const std::string&,std::size_t&); + template MANTID_KERNEL_DLL int convert(const char*,std::string&); + template MANTID_KERNEL_DLL int convert(const char*,double&); + template MANTID_KERNEL_DLL int convert(const char*,int&); + template MANTID_KERNEL_DLL int convert(const char*,std::size_t&); + + template MANTID_KERNEL_DLL std::string toString(const double value); + template MANTID_KERNEL_DLL std::string toString(const float value); + template MANTID_KERNEL_DLL std::string toString(const int value); + template MANTID_KERNEL_DLL std::string toString(const uint16_t value); + template MANTID_KERNEL_DLL std::string toString(const size_t value); // Matches uint64_t on Linux 64 & Win 64 #if defined(__APPLE__) || ( defined(_WIN32) && !defined(_WIN64)) || (defined(__GNUC__) && !defined(__LP64__)) // Mac or 32-bit compiler - template MANTID_KERNEL_DLL std::string toString(const uint64_t value); + template MANTID_KERNEL_DLL std::string toString(const uint64_t value); #endif -template MANTID_KERNEL_DLL std::string toString(const std::string value); + template MANTID_KERNEL_DLL std::string toString(const std::string value); -// this block should generate the vector ones as well -template MANTID_KERNEL_DLL std::string toString(const std::set<int> &value); -template MANTID_KERNEL_DLL std::string toString(const std::set<int16_t> &value); -template MANTID_KERNEL_DLL std::string toString(const std::set<size_t> &value); // Matches uint64_t on Linux 64 & Win 64 + // this block should generate the vector ones as well + template MANTID_KERNEL_DLL std::string toString(const std::set<int> &value); + template MANTID_KERNEL_DLL std::string toString(const std::set<int16_t> &value); + template MANTID_KERNEL_DLL std::string toString(const std::set<size_t> &value); // Matches uint64_t on Linux 64 & Win 64 #if defined(__APPLE__) || ( defined(_WIN32) && !defined(_WIN64)) || (defined(__GNUC__) && !defined(__LP64__)) // Mac or 32-bit compiler - template MANTID_KERNEL_DLL std::string toString(const std::set<uint64_t> &value); + template MANTID_KERNEL_DLL std::string toString(const std::set<uint64_t> &value); #endif -template MANTID_KERNEL_DLL int convPartNum(const std::string&,double&); -template MANTID_KERNEL_DLL int convPartNum(const std::string&,int&); - -template MANTID_KERNEL_DLL int setValues(const std::string&,const std::vector<int>&,std::vector<double>&); + template MANTID_KERNEL_DLL int convPartNum(const std::string&,double&); + template MANTID_KERNEL_DLL int convPartNum(const std::string&,int&); -template MANTID_KERNEL_DLL int writeFile(const std::string&,const double&,const std::vector<double>&); -template MANTID_KERNEL_DLL int writeFile(const std::string&,const std::vector<double>&,const std::vector<double>&,const std::vector<double>&); -template MANTID_KERNEL_DLL int writeFile(const std::string&,const std::vector<double>&,const std::vector<double>&); -template MANTID_KERNEL_DLL int writeFile(const std::string&,const std::vector<float>&,const std::vector<float>&); -template MANTID_KERNEL_DLL int writeFile(const std::string&,const std::vector<float>&,const std::vector<float>&,const std::vector<float>&); + template MANTID_KERNEL_DLL int setValues(const std::string&,const std::vector<int>&,std::vector<double>&); -/// \endcond TEMPLATE + template MANTID_KERNEL_DLL int writeFile(const std::string&,const double&,const std::vector<double>&); + template MANTID_KERNEL_DLL int writeFile(const std::string&,const std::vector<double>&,const std::vector<double>&,const std::vector<double>&); + template MANTID_KERNEL_DLL int writeFile(const std::string&,const std::vector<double>&,const std::vector<double>&); + template MANTID_KERNEL_DLL int writeFile(const std::string&,const std::vector<float>&,const std::vector<float>&); + template MANTID_KERNEL_DLL int writeFile(const std::string&,const std::vector<float>&,const std::vector<float>&,const std::vector<float>&); + /// \endcond TEMPLATE -} // NAMESPACE Strings + } // NAMESPACE Strings -} // NAMESPACE Kernel + } // NAMESPACE Kernel } // NAMESPACE Mantid