diff --git a/applications/test/IFstream/Make/files b/applications/test/IFstream/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..71a272eb18193ae35ed9bc6604450739b6e03d47 --- /dev/null +++ b/applications/test/IFstream/Make/files @@ -0,0 +1,3 @@ +Test-IFstream.C + +EXE = $(FOAM_USER_APPBIN)/Test-IFstream diff --git a/applications/test/IFstream/Make/options b/applications/test/IFstream/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..18e6fe47afacb902cddccf82632772447704fd88 --- /dev/null +++ b/applications/test/IFstream/Make/options @@ -0,0 +1,2 @@ +/* EXE_INC = */ +/* EXE_LIBS = */ diff --git a/applications/test/IFstream/Test-IFstream.C b/applications/test/IFstream/Test-IFstream.C new file mode 100644 index 0000000000000000000000000000000000000000..c55957109acc336f680b4ce968bc62a94277765b --- /dev/null +++ b/applications/test/IFstream/Test-IFstream.C @@ -0,0 +1,105 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM 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 General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Application + Test-IFstream + +Description + Tests on low-level reading + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "Fstream.H" +#include "etcFiles.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + argList::noBanner(); + argList::noParallel(); + + #include "setRootCase.H" + + // Test with etc/controlDict (mandatory, from distribution) + + { + const fileName inputFile + ( + findEtcFile("controlDict", true, 0007) + ); + + Info<< nl << "Test getLine" << nl << inputFile << nl; + IFstream is(inputFile); + + string buf; + + // Test that buffer resizing works as expected + + Info<< "buf: " << buf.size() << '/' << buf.capacity() << nl; + + bool skipDoc = true; + + while (is.good()) + { + if (skipDoc || is.lineNumber() % 2) + { + is.getLine(buf); + + Info<< is.lineNumber() << ": " + << buf.size() << '/' << buf.capacity() << ' ' + << buf << nl; + + if (buf.starts_with("Documentation")) + { + skipDoc = false; + + Info<< "Found Documentation: skip until closing '}'" + << " line number will now be incorrect" + << nl; + + auto n = is.getLine(nullptr, '}'); + Info<< is.lineNumber() << ": [" << label(n) << "]" << nl; + } + } + else + { + auto n = is.getLine(nullptr); + + Info<< is.lineNumber() << ": [" << label(n) << "]" << nl; + } + } + } + + Info<< "\nEnd\n" << endl; + return 0; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H index 3fb471b1cd4535fff92d82fc779a587ea5bd0764..eaa2a92420d2cbeca29be9f02dc41ea00d1b717d 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H +++ b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H @@ -41,6 +41,7 @@ SourceFiles #include "Istream.H" #include "fileName.H" +#include <limits> #include <iostream> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -148,9 +149,13 @@ public: // end of file is read. inline int peek(); - //- Raw, low-level getline into a string function. + //- Raw, low-level getline (until delimiter) into a string. inline ISstream& getLine(std::string& str, char delim = '\n'); + //- Low-level discard until delimiter + // \return the number of characters extracted + inline std::streamsize getLine(std::nullptr_t, char delim = '\n'); + //- Raw, low-level putback character function. inline ISstream& putback(const char c); diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/ISstreamI.H b/src/OpenFOAM/db/IOstreams/Sstreams/ISstreamI.H index 69c847d2c2ff013c4ff6422c17dd32f7bc0816fb..23817ceb187378c7e43b12eb2e9c8835cefd9f03 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/ISstreamI.H +++ b/src/OpenFOAM/db/IOstreams/Sstreams/ISstreamI.H @@ -87,6 +87,22 @@ inline Foam::ISstream& Foam::ISstream::getLine(std::string& str, char delim) } +inline std::streamsize Foam::ISstream::getLine(std::nullptr_t, char delim) +{ + is_.ignore(std::numeric_limits<std::streamsize>::max(), delim); + setState(is_.rdstate()); + + std::streamsize count = is_.gcount(); + + if (count && delim == '\n') + { + ++lineNumber_; + } + + return count; +} + + inline Foam::ISstream& Foam::ISstream::putback(const char c) { if (c == '\n') diff --git a/src/OpenFOAM/interpolations/interpolationTable/tableReaders/csv/csvTableReader.C b/src/OpenFOAM/interpolations/interpolationTable/tableReaders/csv/csvTableReader.C index 0ee5c6d7663328870aa6bc8d0d8b763432800c81..ea6e419791fa0e893134c192ef19503e4fd930df 100644 --- a/src/OpenFOAM/interpolations/interpolationTable/tableReaders/csv/csvTableReader.C +++ b/src/OpenFOAM/interpolations/interpolationTable/tableReaders/csv/csvTableReader.C @@ -134,12 +134,12 @@ void Foam::csvTableReader<Type>::operator() const label maxEntry = max(refColumn_, componentColumns_[findMax(componentColumns_)]); + string line; label lineNo = 0; // Skip header if (headerLine_) { - string line; is.getLine(line); ++lineNo; } @@ -149,7 +149,6 @@ void Foam::csvTableReader<Type>::operator() while (is.good()) { - string line; is.getLine(line); ++lineNo; diff --git a/src/OpenFOAM/primitives/functions/Function1/CSV/CSV.C b/src/OpenFOAM/primitives/functions/Function1/CSV/CSV.C index 53b7bb796e5ba308757012692368c52bb5a14b7d..495cd5a481e1910ebca660c8eff03389350a946c 100644 --- a/src/OpenFOAM/primitives/functions/Function1/CSV/CSV.C +++ b/src/OpenFOAM/primitives/functions/Function1/CSV/CSV.C @@ -118,12 +118,12 @@ void Foam::Function1Types::CSV<Type>::read() const label maxEntry = max(refColumn_, componentColumns_[findMax(componentColumns_)]); + string line; label lineNo = 0; // Skip header for (label i = 0; i < nHeaderLine_; ++i) { - string line; is.getLine(line); ++lineNo; } @@ -133,7 +133,6 @@ void Foam::Function1Types::CSV<Type>::read() while (is.good()) { - string line; is.getLine(line); ++lineNo; diff --git a/src/OpenFOAM/primitives/strings/lists/SubStrings.H b/src/OpenFOAM/primitives/strings/lists/SubStrings.H index 41835c5e9e199310ae2fd1cc9385cd585e15000f..189865864710563f6c7baa5c26858571031e0e49 100644 --- a/src/OpenFOAM/primitives/strings/lists/SubStrings.H +++ b/src/OpenFOAM/primitives/strings/lists/SubStrings.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017 OpenCFD Ltd. + Copyright (C) 2017-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -35,8 +35,8 @@ Description #ifndef SubStrings_H #define SubStrings_H -#include <string> #include <regex> +#include <string> #include <vector> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -67,13 +67,13 @@ public: // Constructors - //- Construct null + //- Default construct SubStrings() = default; // Member Functions - //- The total length of all sub-elements. + //- The total string length of all sub-elements. // Use size() for the number elements. std::string::size_type length() const { @@ -89,7 +89,11 @@ public: //- Append sub-string defined by begin/end iterators - void append(string_iterator b, string_iterator e) + void append + ( + const typename String::const_iterator& b, + const typename String::const_iterator& e + ) { value_type range; range.first = b; @@ -101,7 +105,7 @@ public: //- Const reference to the first element, - // for consistency with other OpenFOAM containers + //- for consistency with other OpenFOAM containers auto first() const -> decltype(this->front()) { return this->front(); @@ -109,7 +113,7 @@ public: //- Const reference to the last element, - // for consistency with other OpenFOAM containers + //- for consistency with other OpenFOAM containers auto last() const -> decltype(this->back()) { return this->back(); @@ -121,9 +125,9 @@ public: { return (*this)[pos].str(); } - }; + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam diff --git a/src/OpenFOAM/primitives/strings/string/string.C b/src/OpenFOAM/primitives/strings/string/string.C index 34bc400d91ac06572e8ddc2774e051d3f1228bc7..b7076865c53ca8aeb19c2a2ad3184d64e4319faa 100644 --- a/src/OpenFOAM/primitives/strings/string/string.C +++ b/src/OpenFOAM/primitives/strings/string/string.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2016-2019 OpenCFD Ltd. + Copyright (C) 2016-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -190,7 +190,7 @@ bool Foam::string::removeRepeated(const char character) } } - resize(nChar); + erase(nChar); } return changed; @@ -219,7 +219,7 @@ bool Foam::string::removeEnd(const std::string& text) if (txtLen && strLen >= txtLen && !compare(strLen - txtLen, npos, text)) { - resize(strLen - txtLen); + erase(strLen - txtLen); return true; } @@ -244,7 +244,7 @@ bool Foam::string::removeEnd(const char c) const auto n = length(); if (n > 1 && back() == c) { - resize(n-1); + erase(n-1); return true; } diff --git a/src/OpenFOAM/primitives/strings/stringOps/stringOps.C b/src/OpenFOAM/primitives/strings/stringOps/stringOps.C index dc3a12d84b3f5d86bdeb85265e43845dcd2c0925..a6860584b65cab59701132f378236c472eef2db8 100644 --- a/src/OpenFOAM/primitives/strings/stringOps/stringOps.C +++ b/src/OpenFOAM/primitives/strings/stringOps/stringOps.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2017-2019 OpenCFD Ltd. + Copyright (C) 2017-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -29,10 +29,11 @@ License #include "stringOps.H" #include "typeInfo.H" #include "etcFiles.H" -#include "Pstream.H" +#include "UPstream.H" #include "StringStream.H" #include "OSstream.H" #include "OSspecific.H" +#include <algorithm> #include <cctype> // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // @@ -162,7 +163,7 @@ static void expandLeadingTilde(std::string& s) // Single warning (on master) with guard to avoid Pstream::master() // when Pstream has not yet been initialized - if (Pstream::parRun() ? Pstream::master() : true) + if (UPstream::parRun() ? UPstream::master() : true) { std::cerr << nl @@ -696,55 +697,35 @@ static void expandString std::string::size_type Foam::stringOps::count ( - const std::string& str, + const std::string& s, const char c ) { - std::string::size_type n = 0; - - for (auto iter = str.cbegin(); iter != str.cend(); ++iter) - { - if (*iter == c) - { - ++n; - } - } - - return n; + return std::count(s.cbegin(), s.cend(), c); } -std::string::size_type Foam::stringOps::count(const char* str, const char c) +std::string::size_type Foam::stringOps::count(const char* s, const char c) { - if (!str) - { - return 0; - } - - std::string::size_type n = 0; - - for (const char *iter = str; *iter; ++iter) - { - if (*iter == c) - { - ++n; - } - } - - return n; + return + ( + s == nullptr + ? 0 + : std::count(s, (s + std::char_traits<char>::length(s)), c) + ); } Foam::string Foam::stringOps::expand ( - const std::string& str, + const std::string& s, const HashTable<string, word, string::hash>& mapping, const char sigil ) { - string s(str); - inplaceExpand(s, mapping); - return s; + string out(s); + inplaceExpand(out, mapping); + return out; } @@ -862,14 +843,14 @@ void Foam::stringOps::inplaceExpand Foam::string Foam::stringOps::expand ( - const std::string& str, + const std::string& s, const dictionary& dict, const char sigil ) { - string s(str); - inplaceExpand(s, dict, sigil); - return s; + string out(s); + inplaceExpand(out, dict, sigil); + return out; } @@ -902,13 +883,13 @@ void Foam::stringOps::inplaceExpand Foam::string Foam::stringOps::expand ( - const std::string& str, + const std::string& s, const bool allowEmpty ) { - string s(str); - inplaceExpand(s, allowEmpty); - return s; + string out(s); + inplaceExpand(out, allowEmpty); + return out; } @@ -1064,24 +1045,24 @@ Foam::stringOps::findTrim } -Foam::string Foam::stringOps::trim(const std::string& str) +Foam::string Foam::stringOps::trim(const std::string& s) { std::string::size_type pos = 0; - std::string::size_type end = str.length(); + std::string::size_type end = s.length(); // Right - while (pos < end && std::isspace(str[end-1])) + while (pos < end && std::isspace(s[end-1])) { --end; } // Left - while (pos < end && std::isspace(str[pos])) + while (pos < end && std::isspace(s[pos])) { ++pos; } - return str.substr(pos, end-pos); + return s.substr(pos, end-pos); } @@ -1092,11 +1073,17 @@ void Foam::stringOps::inplaceTrim(std::string& s) } -Foam::string Foam::stringOps::removeComments(const std::string& str) +void Foam::stringOps::inplaceRemoveSpace(std::string& s) { - string s(str); - inplaceRemoveComments(s); - return s; + s.erase(std::remove_if(s.begin(), s.end(), ::isspace), s.end()); +} + + +Foam::string Foam::stringOps::removeComments(const std::string& s) +{ + string out(s); + inplaceRemoveComments(out); + return out; } @@ -1196,43 +1183,35 @@ void Foam::stringOps::inplaceRemoveComments(std::string& s) } -Foam::string Foam::stringOps::lower(const std::string& str) +Foam::string Foam::stringOps::lower(const std::string& s) { - string s(str); - inplaceLower(s); - return s; + string out; + out.resize(s.length()); + + std::transform(s.begin(), s.end(), out.begin(), ::tolower); + return out; } void Foam::stringOps::inplaceLower(std::string& s) { - for (auto iter = s.begin(); iter != s.end(); ++iter) - { - *iter = static_cast<std::string::value_type> - ( - std::tolower(static_cast<unsigned char>(*iter)) - ); - } + std::transform(s.begin(), s.end(), s.begin(), ::tolower); } -Foam::string Foam::stringOps::upper(const std::string& str) +Foam::string Foam::stringOps::upper(const std::string& s) { - string s(str); - inplaceUpper(s); - return s; + string out; + out.resize(s.length()); + + std::transform(s.begin(), s.end(), out.begin(), ::toupper); + return out; } void Foam::stringOps::inplaceUpper(std::string& s) { - for (auto iter = s.begin(); iter != s.end(); ++iter) - { - *iter = static_cast<std::string::value_type> - ( - std::toupper(static_cast<unsigned char>(*iter)) - ); - } + std::transform(s.begin(), s.end(), s.begin(), ::toupper); } diff --git a/src/OpenFOAM/primitives/strings/stringOps/stringOps.H b/src/OpenFOAM/primitives/strings/stringOps/stringOps.H index 51d3a4e37d64a5aabb0c4d6ff1af88eae70bae85..b771277c7fed5dc9f3d7e5619c14b0778fcbe1d1 100644 --- a/src/OpenFOAM/primitives/strings/stringOps/stringOps.H +++ b/src/OpenFOAM/primitives/strings/stringOps/stringOps.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2012 OpenFOAM Foundation - Copyright (C) 2016-2019 OpenCFD Ltd. + Copyright (C) 2016-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -55,7 +55,7 @@ SourceFiles namespace Foam { -// Forward declarations +// Forward Declarations class OSstream; /*---------------------------------------------------------------------------*\ @@ -65,11 +65,11 @@ class OSstream; namespace stringOps { //- Count the number of occurrences of the specified character - std::string::size_type count(const std::string& str, const char c); + std::string::size_type count(const std::string& s, const char c); //- Count the number of occurrences of the specified character // Correctly handles nullptr. - std::string::size_type count(const char* str, const char c); + std::string::size_type count(const char* s, const char c); //- Return true if text matches one of the regular expressions. inline bool match(const UList<wordRe>& patterns, const std::string& text) @@ -83,7 +83,7 @@ namespace stringOps // \sa stringOps::inplaceExpand() for details string expand ( - const std::string& str, + const std::string& s, const HashTable<string, word, string::hash>& mapping, const char sigil = '$' ); @@ -213,7 +213,7 @@ namespace stringOps // \sa stringOps::inplaceExpand(std::string&, const dictionary&, char) string expand ( - const std::string& str, + const std::string& s, const dictionary& dict, const char sigil = '$' ); @@ -246,11 +246,7 @@ namespace stringOps // // \sa // stringOps::inplaceExpand(std::string&, bool); - string expand - ( - const std::string& str, - const bool allowEmpty = false - ); + string expand(const std::string& s, const bool allowEmpty = false); //- Expand initial tags, tildes, and all occurrences of environment @@ -268,11 +264,7 @@ namespace stringOps // - allow empty = Given by parameter (default: False) // - subDict = Not applicable // . - void inplaceExpand - ( - std::string& s, - const bool allowEmpty = false - ); + void inplaceExpand(std::string& s, const bool allowEmpty = false); //- Replace environment variable contents with its name. @@ -305,27 +297,30 @@ namespace stringOps void inplaceTrimRight(std::string& s); //- Return string trimmed of leading and trailing whitespace - string trim(const std::string& str); + string trim(const std::string& s); //- Trim leading and trailing whitespace inplace void inplaceTrim(std::string& s); + //- Eliminate whitespace inplace + void inplaceRemoveSpace(std::string& s); + //- Return string with C/C++ comments removed - string removeComments(const std::string& str); + string removeComments(const std::string& s); //- Remove C/C++ comments inplace void inplaceRemoveComments(std::string& s); - //- Return string transformed with std::tolower on each character - string lower(const std::string& str); + //- Return string copy transformed with std::tolower on each character + string lower(const std::string& s); //- Inplace transform string with std::tolower on each character void inplaceLower(std::string& s); - //- Return string transformed with std::toupper on each character - string upper(const std::string& str); + //- Return string copy transformed with std::toupper on each character + string upper(const std::string& s); //- Inplace transform string with std::toupper on each character void inplaceUpper(std::string& s); diff --git a/src/OpenFOAM/primitives/strings/word/word.C b/src/OpenFOAM/primitives/strings/word/word.C index 52c1334f0af51f9f648dd0b1ecc3a479b8a3b269..9cc7dc15c5cf79b5da1e8f38fbc07cf5a64c5860 100644 --- a/src/OpenFOAM/primitives/strings/word/word.C +++ b/src/OpenFOAM/primitives/strings/word/word.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011 OpenFOAM Foundation - Copyright (C) 2017-2019 OpenCFD Ltd. + Copyright (C) 2017-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -68,7 +68,7 @@ Foam::word Foam::word::validate(const std::string& s, const bool prefix) } } - out.resize(len); + out.erase(len); return out; } @@ -102,7 +102,7 @@ Foam::word Foam::word::validate } } - out.resize(len); + out.erase(len); return out; }