diff --git a/src/phasicFlow/fileSystem/fileSystem.C b/src/phasicFlow/fileSystem/fileSystem.C new file mode 100644 index 00000000..689dc1a0 --- /dev/null +++ b/src/phasicFlow/fileSystem/fileSystem.C @@ -0,0 +1,355 @@ +/*------------------------------- phasicFlow --------------------------------- + O C enter of + O O E ngineering and + O O M ultiscale modeling of + OOOOOOO F luid flow +------------------------------------------------------------------------------ + Copyright (C): www.cemf.ir + email: hamid.r.norouzi AT gmail.com +------------------------------------------------------------------------------ +Licence: + This file is part of phasicFlow code. It is a free software for simulating + granular and multiphase flows. You can redistribute it and/or modify it under + the terms of GNU General Public License v3 or any other later versions. + + phasicFlow is distributed to help others in their research in the field of + granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +-----------------------------------------------------------------------------*/ + + +#include "fileSystem.H" +#include "error.H" +#include "iOstream.H" + + +bool pFlow::fileSystem::checkFileName(const word& name) +{ + + if(!validFileName(name)) + { + fatalErrorInFunction << + "Invalid file name supplied " << name << + "the following characters are not allowd: " << + notPermittedCharsFile << endl; + fatalExit; + return false; + } + + return true; +} + + + +pFlow::fileSystem::fileSystem( const word& dir, const word& file) +{ + isDir_ = file.empty(); + + if( !isDir_) + { + checkFileName(file); + } + + try + { + path_ = pathType(dir)/file; + } + catch (std::filesystem::filesystem_error & ec) + { + fatalErrorInFunction<< + "Invalid fileSystem input:" << + ec.what()< +#include "bTypes.H" +#include "List.H" + + +namespace pFlow +{ + + +class iOstream; +class ostream; +class fileSystem; + +iOstream& operator << +( + iOstream& os, + fileSystem fs +); + +std::ostream& operator << +( + std::ostream& os, + fileSystem fs +); + + +fileSystem operator / +( + const fileSystem& fs1, + const fileSystem& fs2 + ); + +fileSystem operator + +( + const fileSystem& fs1, + const word fName +); + +// a class to manage file/directory names +class fileSystem +{ +protected: + + std::filesystem::path path_; + bool isDir_; + + + // protected static variables + inline static word notPermittedCharsFile = word(" ") + word("\t\n\0;:?*/<>\"?\'"); + + // protected methods + + bool static validFileName(const word& name) + { + return name.find_first_of(notPermittedCharsFile); + } + + bool static checkFileName(const word& name); + +public: + + inline static fileSystem CWD() + { + return fileSystem(std::filesystem::current_path().c_str()); + } + +public: + + + typedef std::filesystem::path pathType; + + + fileSystem(): + path_(), + isDir_(true) + {} + // Constructors + fileSystem( const word& dir, const word& file = ""); + fileSystem( const char* dir, const char* file = ""); + fileSystem( const pathType& path ); + + fileSystem(const fileSystem&) = default; + + fileSystem(fileSystem&&) = default; + + fileSystem& operator = (const fileSystem&) = default; + + fileSystem& operator = (fileSystem&&) = default; + + ~fileSystem() = default; + + // Methods + bool isDir() const + { + return isDir_; + } + + const pathType& path()const + { + return path_; + } + + word wordPath()const + { + return word(path_.c_str()); + } + + // dir path of this + fileSystem dirPath() const; + + // file name of this (if any) + word fileName() const; + + // absolute path of this + fileSystem absolute()const; + + + //fileSystem relative()const; + + // canonical path of this (it should exist) + fileSystem canonical()const; + + // only operate on dir path + // check if the dir path exists + bool dirExist()const; + + // check if the path exists + bool exist()const; + + // operate on dir path only + // create dir based on the path and returns the canonical path + fileSystem createDirs()const; + + + // if this is dir path, add the filename to dir path + // if it is file path, replace the file name + void operator += (const word& fileName); + + // it operates on dir path only + // it adds the dir path of fs to this + void operator /=(const fileSystem& fs ); + + // Create a dir path from dir path of fs1 and fas2 in the + // form of fs1/fs2 + friend fileSystem operator /(const fileSystem& fs1, const fileSystem& fs2 ); + + + // return the dir path of this + fileSystem operator()(bool retDir = true) const; + + + friend iOstream& operator << (iOstream& os, fileSystem fs); + + friend std::ostream& operator << (std::ostream& os, fileSystem fs); + +}; + + +using fileSystemList = List; + + + +inline fileSystem CWD() +{ + return fileSystem::CWD(); +} + +bool isDirectory(const fileSystem& path); + +bool isRegularFile(const fileSystem& path); + +fileSystemList subDirectories(const fileSystem& path); + +fileSystemList containingFiles(const fileSystem& path); + +} // pFlow + +#endif diff --git a/src/phasicFlow/streams/Fstream/fileStream.C b/src/phasicFlow/streams/Fstream/fileStream.C new file mode 100755 index 00000000..530bee0f --- /dev/null +++ b/src/phasicFlow/streams/Fstream/fileStream.C @@ -0,0 +1,123 @@ +/*------------------------------- phasicFlow --------------------------------- + O C enter of + O O E ngineering and + O O M ultiscale modeling of + OOOOOOO F luid flow +------------------------------------------------------------------------------ + Copyright (C): www.cemf.ir + email: hamid.r.norouzi AT gmail.com +------------------------------------------------------------------------------ +Licence: + This file is part of phasicFlow code. It is a free software for simulating + granular and multiphase flows. You can redistribute it and/or modify it under + the terms of GNU General Public License v3 or any other later versions. + + phasicFlow is distributed to help others in their research in the field of + granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +-----------------------------------------------------------------------------*/ +// based on OpenFOAM stream, with some modifications/simplifications +// to be tailored to our needs + + +#include "fileStream.H" +#include "error.H" + + + +void pFlow::fileStream::openInFile +( + const fileSystem& path +) +{ + + if( !path.exist() ) + { + fatalErrorInFunction << + "File " << path << " does not exist for opening. \n"; + fatalExit; + } + + inStream_ = makeUnique( path.wordPath(), std::ios_base::in); + + if( !inStream_->is_open()) + { + + fatalErrorInFunction << + "File " << path << " cannot be opened. \n"; + fatalExit; + + } +} + + +void pFlow::fileStream::openOutFile +( + const fileSystem& path +) +{ + + // - check if the Dir exists + auto dir = path.dirPath(); + + if(!dir.exist()) + { + dir.createDirs(); + } + + outStream_ = makeUnique< std::ofstream>(path.wordPath(), std::ios_base::out); + + if(!outStream_->is_open()) + { + fatalErrorInFunction << + "File " << path << " cannot be opened. \n"; + fatalExit; + } +} + +void pFlow::fileStream::close() +{ + if(inStream_) + { + inStream_.reset(nullptr); + } + + if(outStream_) + { + outStream_.reset(nullptr); + } +} + +pFlow::fileStream::fileStream +( + const fileSystem& path, + bool outStream +) +: + inStream_(nullptr), + outStream_(nullptr) +{ + + if(outStream) + { + openOutFile(path); + }else + { + openInFile(path); + } + +} + +std::ifstream& pFlow::fileStream::inStream() +{ + return inStream_(); +} + +std::ofstream& pFlow::fileStream::outStream() +{ + return outStream_(); +} + + + diff --git a/src/phasicFlow/streams/Fstream/fileStream.H b/src/phasicFlow/streams/Fstream/fileStream.H new file mode 100755 index 00000000..6e7cdd61 --- /dev/null +++ b/src/phasicFlow/streams/Fstream/fileStream.H @@ -0,0 +1,81 @@ +/*------------------------------- phasicFlow --------------------------------- + O C enter of + O O E ngineering and + O O M ultiscale modeling of + OOOOOOO F luid flow +------------------------------------------------------------------------------ + Copyright (C): www.cemf.ir + email: hamid.r.norouzi AT gmail.com +------------------------------------------------------------------------------ +Licence: + This file is part of phasicFlow code. It is a free software for simulating + granular and multiphase flows. You can redistribute it and/or modify it under + the terms of GNU General Public License v3 or any other later versions. + + phasicFlow is distributed to help others in their research in the field of + granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +-----------------------------------------------------------------------------*/ +// based on OpenFOAM stream, with some modifications/simplifications +// to be tailored to our needs + + +#ifndef __fileStream_H__ +#define __fileStream_H__ + + +#include + +#include "fileSystem.H" +#include "uniquePtr.H" + +namespace pFlow +{ + +class fileStream +{ +protected: + + // - in file stream + uniquePtr inStream_; + + // - out file stream + uniquePtr outStream_; + + // - open input file + void openInFile(const fileSystem& path); + + // - open output file + void openOutFile(const fileSystem& path); + + // - close streams + void close(); + +public: + + // - Constructors + + fileStream( const fileSystem& path, bool outStream = false); + + fileStream(const fileStream&)= delete; + + fileStream& operator=(const fileStream&)=delete; + + virtual ~fileStream() + { + close(); + } + + + // - access + + std::ifstream& inStream(); + + std::ofstream& outStream(); + +}; + +} + +#endif diff --git a/src/phasicFlow/streams/Fstream/iFstream.C b/src/phasicFlow/streams/Fstream/iFstream.C new file mode 100755 index 00000000..30ee47cb --- /dev/null +++ b/src/phasicFlow/streams/Fstream/iFstream.C @@ -0,0 +1,32 @@ +/*------------------------------- phasicFlow --------------------------------- + O C enter of + O O E ngineering and + O O M ultiscale modeling of + OOOOOOO F luid flow +------------------------------------------------------------------------------ + Copyright (C): www.cemf.ir + email: hamid.r.norouzi AT gmail.com +------------------------------------------------------------------------------ +Licence: + This file is part of phasicFlow code. It is a free software for simulating + granular and multiphase flows. You can redistribute it and/or modify it under + the terms of GNU General Public License v3 or any other later versions. + + phasicFlow is distributed to help others in their research in the field of + granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +-----------------------------------------------------------------------------*/ +// based on OpenFOAM stream, with some modifications/simplifications +// to be tailored to our needs + + +#include "iFstream.H" + + +pFlow::iFstream::iFstream (const fileSystem& path) +: + fileStream(path), + Istream( fileStream::inStream(), path.wordPath()) +{ +} \ No newline at end of file diff --git a/src/phasicFlow/streams/Fstream/iFstream.H b/src/phasicFlow/streams/Fstream/iFstream.H new file mode 100755 index 00000000..6db2e664 --- /dev/null +++ b/src/phasicFlow/streams/Fstream/iFstream.H @@ -0,0 +1,59 @@ +/*------------------------------- phasicFlow --------------------------------- + O C enter of + O O E ngineering and + O O M ultiscale modeling of + OOOOOOO F luid flow +------------------------------------------------------------------------------ + Copyright (C): www.cemf.ir + email: hamid.r.norouzi AT gmail.com +------------------------------------------------------------------------------ +Licence: + This file is part of phasicFlow code. It is a free software for simulating + granular and multiphase flows. You can redistribute it and/or modify it under + the terms of GNU General Public License v3 or any other later versions. + + phasicFlow is distributed to help others in their research in the field of + granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +-----------------------------------------------------------------------------*/ +// based on OpenFOAM stream, with some modifications/simplifications +// to be tailored to our needs + +#ifndef __iFstream_H__ +#define __iFstream_H__ + + +#include "fileSystem.H" +#include "fileStream.H" +#include "Istream.H" + +namespace pFlow +{ + + +class iFstream +: + public fileStream, + public Istream +{ +public: + + // - Constructor + iFstream (const fileSystem& path); + + // no copy constructor + iFstream( const iFstream& src) = delete; + + // no assignment + iFstream& operator = (const iFstream& rhs) = delete; + + // - Destructor + virtual ~iFstream() = default; + +}; + +} + + +#endif diff --git a/src/phasicFlow/streams/Fstream/oFstream.C b/src/phasicFlow/streams/Fstream/oFstream.C new file mode 100755 index 00000000..a26ed597 --- /dev/null +++ b/src/phasicFlow/streams/Fstream/oFstream.C @@ -0,0 +1,34 @@ +/*------------------------------- phasicFlow --------------------------------- + O C enter of + O O E ngineering and + O O M ultiscale modeling of + OOOOOOO F luid flow +------------------------------------------------------------------------------ + Copyright (C): www.cemf.ir + email: hamid.r.norouzi AT gmail.com +------------------------------------------------------------------------------ +Licence: + This file is part of phasicFlow code. It is a free software for simulating + granular and multiphase flows. You can redistribute it and/or modify it under + the terms of GNU General Public License v3 or any other later versions. + + phasicFlow is distributed to help others in their research in the field of + granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +-----------------------------------------------------------------------------*/ +// based on OpenFOAM stream, with some modifications/simplifications +// to be tailored to our needs + + +#include "oFstream.H" + + +pFlow::oFstream::oFstream (const fileSystem& path) +: + fileStream(path, true), + Ostream( fileStream::outStream(), path.wordPath()) +{ + + +} \ No newline at end of file diff --git a/src/phasicFlow/streams/Fstream/oFstream.H b/src/phasicFlow/streams/Fstream/oFstream.H new file mode 100755 index 00000000..516dd093 --- /dev/null +++ b/src/phasicFlow/streams/Fstream/oFstream.H @@ -0,0 +1,60 @@ +/*------------------------------- phasicFlow --------------------------------- + O C enter of + O O E ngineering and + O O M ultiscale modeling of + OOOOOOO F luid flow +------------------------------------------------------------------------------ + Copyright (C): www.cemf.ir + email: hamid.r.norouzi AT gmail.com +------------------------------------------------------------------------------ +Licence: + This file is part of phasicFlow code. It is a free software for simulating + granular and multiphase flows. You can redistribute it and/or modify it under + the terms of GNU General Public License v3 or any other later versions. + + phasicFlow is distributed to help others in their research in the field of + granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +-----------------------------------------------------------------------------*/ +// based on OpenFOAM stream, with some modifications/simplifications +// to be tailored to our needs + + +#ifndef __oFstream_H__ +#define __oFstream_H__ + + +#include "fileSystem.H" +#include "fileStream.H" +#include "Ostream.H" + +namespace pFlow +{ + + +class oFstream +: + public fileStream, + public Ostream +{ +public: + + // Constructor + oFstream (const fileSystem& path); + + // no copy constructor + oFstream( const oFstream& src) = delete; + + // no assignment + oFstream& operator = (const oFstream& rhs) = delete; + + // Destructor + virtual ~oFstream() = default; + +}; + +} + + +#endif diff --git a/src/phasicFlow/streams/Stream/Istream.C b/src/phasicFlow/streams/Stream/Istream.C new file mode 100755 index 00000000..3500ee6f --- /dev/null +++ b/src/phasicFlow/streams/Stream/Istream.C @@ -0,0 +1,876 @@ +/*------------------------------- phasicFlow --------------------------------- + O C enter of + O O E ngineering and + O O M ultiscale modeling of + OOOOOOO F luid flow +------------------------------------------------------------------------------ + Copyright (C): www.cemf.ir + email: hamid.r.norouzi AT gmail.com +------------------------------------------------------------------------------ +Licence: + This file is part of phasicFlow code. It is a free software for simulating + granular and multiphase flows. You can redistribute it and/or modify it under + the terms of GNU General Public License v3 or any other later versions. + + phasicFlow is distributed to help others in their research in the field of + granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +-----------------------------------------------------------------------------*/ +// based on OpenFOAM stream, with some modifications/simplifications +// to be tailored to our needs + + +#include "Istream.H" +#include "token.H" +#include "error.H" + + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +// Truncate error message for readability +static constexpr const unsigned errLen = 80; + + +namespace +{ + +// Convert a single character to a word with length 1 +inline static pFlow::word charToWord(char c) +{ + return pFlow::word(std::string(1, c), false); +} + +// Permit slash-scoping of entries +static inline bool validVariableChar(char c) +{ + return (pFlow::validWord(c) || c == '/'); +} + +} // End anonymous namespace + + +char pFlow::Istream::nextValid() +{ + char c = 0; + + while (true) + { + // Get next non-whitespace character + while (get(c) && isspace(c)) + {} + + // Return if stream is bad - ie, previous get() failed + if (bad() || isspace(c)) + { + return 0; + } + + // Is this the start of a C/C++ comment? + if (c == '/') + { + if (!get(c)) + { + // Cannot get another character - return this one + return '/'; + } + + if (c == '/') + { + // C++ style single-line comment - skip through past end-of-line + while (get(c) && c != '\n') + {} + } + else if (c == '*') + { + // Within a C-style comment + while (true) + { + // Search for end of C-style comment - '*/' + if (get(c) && c == '*') + { + if (get(c)) + { + if (c == '/') + { + // matched '*/' + break; + } + else if (c == '*') + { + // check again + putback(c); + } + } + } + + if (!good()) + { + return 0; + } + } + } + else + { + // The '/' did not start a C/C++ comment - return it + putback(c); + return '/'; + } + } + else + { + // A valid character - return it + return c; + } + } + + return 0; +} + + +void pFlow::Istream::readWordToken(token& t) +{ + word val; + if (read(val).bad()) + { + t.setBad(); + } + else + { + t = std::move(val); // Move contents to token + } +} + + +pFlow::Istream& pFlow::Istream::readVariable(word& str) +{ + constexpr const unsigned maxLen = 1024; + static char buf[maxLen]; + + unsigned nChar = 0; + unsigned depth = 0; // Track depth of (..) or {..} nesting + char c; + + // First character must be '$' + if (!get(c) || c != token::DOLLAR) + { + ioErrorInFile( name(), lineNumber()) + << "Invalid first character found : " << c << nl; + fatalExit; + } + buf[nChar++] = c; + + // Next character should also exist. + // This should never fail, since it was checked before calling. + if (!get(c)) + { + str.assign(buf, nChar); + warningInFunction + << "Truncated variable name : " << str << nl; + + return *this; + } + buf[nChar++] = c; + + str.clear(); + if (c == token::BEGIN_BLOCK) + { + // Processing ${...} style. + ++depth; + + // Could check that the next char is good and not one of '{}' + // since this would indicate "${}", "${{..." or truncated "${" + + while (get(c)) + { + buf[nChar++] = c; + if (nChar == maxLen) + { + str.append(buf, nChar); + nChar = 0; + } + if (c == token::BEGIN_BLOCK) + { + ++depth; + } + else if (c == token::END_BLOCK) + { + --depth; + if (!depth) + { + // Found closing '}' character + str.append(buf, nChar); + return *this; + } + } + } + + // Should never reach here on normal input + + str.append(buf, nChar); // Finalize pending buffer input + + nChar = str.length(); + if (str.length() > errLen) + { + str.erase(errLen); + } + + ioErrorInFile(name(), lineNumber()) + << "stream terminated while reading variable '" + << str.c_str() << "...' [" << static_cast(nChar) << "]\n"; + fatalExit; + + return *this; + } + else if (validVariableChar(c)) + { + // Processing $var style + + while + ( + (nChar < maxLen) && get(c) + && (validVariableChar(c)) + ) + { + if (c == token::BEGIN_LIST) + { + ++depth; + } + else if (c == token::END_LIST) + { + if (!depth) + { + break; // Closed ')' without an opening '(' ? ... stop + } + --depth; + } + + buf[nChar++] = c; + } + } + else + { + // Invalid character. Terminate string (for message) without + // including the invalid character in the count. + + buf[nChar--] = '\0'; + + warningInFunction + << "Bad variable name: " << buf << nl << endl; + } + + if (nChar >= maxLen) + { + buf[errLen] = '\0'; + + ioErrorInFile(name(), lineNumber()) + << "variable '" << buf << "...'\n" + << " is too long (max. " << static_cast(maxLen) << " characters)"; + fatalExit; + + return *this; + } + + buf[nChar] = '\0'; // Terminate string + + if (bad()) + { + // Could probably skip this check + buf[errLen] = '\0'; + + ioErrorInFile(name(), lineNumber()) + << "Problem while reading variable '" << buf << "...' after " + << static_cast(nChar) << " characters\n"; + fatalExit; + + ioErrorInFile(name(), lineNumber()); + + return *this; + } + + if (depth) + { + warningInFunction + << "Missing " << static_cast(depth) + << " closing ')' while parsing" << nl << nl + << buf << nl << endl; + } + + // Finalize + str.assign(buf, nChar); + putback(c); + + return *this; +} + + +pFlow::Istream::Istream +( + std::istream& is, + const word& streamName +) +: + iIstream(), + name_(streamName), + is_(is) +{ + if (is_.good()) + { + setOpened(); + setGood(); + } + else + { + setState(is_.rdstate()); + } +} + +pFlow::Istream& pFlow::Istream::get(char& c) +{ + is_.get(c); + setState(is_.rdstate()); + + if (good() && c == '\n') + { + ++lineNumber_; + } + + return *this; +} + + +int pFlow::Istream::peek() +{ + return is_.peek(); +} + + +pFlow::Istream& pFlow::Istream::getLine(std::string& str, char delim) +{ + std::getline(is_, str, delim); + setState(is_.rdstate()); + + if (delim == '\n') + { + ++lineNumber_; + } + + return *this; +} + + +std::streamsize pFlow::Istream::getLine(std::nullptr_t, char delim) +{ + is_.ignore(std::numeric_limits::max(), delim); + setState(is_.rdstate()); + + std::streamsize count = is_.gcount(); + + if (count && delim == '\n') + { + ++lineNumber_; + } + + return count; +} + + +pFlow::Istream& pFlow::Istream::putback(const char c) +{ + if (c == '\n') + { + --lineNumber_; + } + + if (!is_.putback(c)) + { + setBad(); + } + + setState(is_.rdstate()); + + return *this; +} + +pFlow::iIstream& pFlow::Istream::read(token& t) +{ + constexpr const unsigned maxLen = 128; // Max length for units/scalars + static char buf[maxLen]; + + // Return the put back token if it exists + if (Istream::getBack(t)) + { + return *this; + } + + // Assume that the streams supplied are in working order. + // Lines are counted by '\n' + + // Get next 'valid character': i.e. proceed through any whitespace + // and/or comments until a semantically valid character is found + + char c = nextValid(); + + // Set the line number of this token to the current stream line number + t.lineNumber() = lineNumber(); + + // Return on error + if (!c) + { + t.setBad(); + return *this; + } + + // Analyse input starting with this character. + switch (c) + { + // Check for punctuation first - same as token::isseparator() + + case token::END_STATEMENT : + case token::BEGIN_LIST : + case token::END_LIST : + case token::BEGIN_SQR : + case token::END_SQR : + case token::BEGIN_BLOCK : + case token::END_BLOCK : + case token::COLON : + case token::COMMA : + case token::DIVIDE : + { + t = token::punctuationToken(c); + return *this; + } + + // String: enclosed by double quotes. + case token::BEGIN_STRING : + { + putback(c); + + word val; + if (read(val).bad()) + { + t.setBad(); + } + else + { + t = std::move(val); // Move contents to token + } + + return *this; + } + // Dictionary variable (as rvalue) + case token::DOLLAR : + { + char nextC; + if (read(nextC).bad()) + { + // Return lone '$' as word + t = charToWord(c); + } + else + { + // Put back both so that '$...' is included in the variable + putback(nextC); + putback(c); + + word val; + if (readVariable(val).bad()) + { + t.setBad(); + } + else + { + t = std::move(val); // Move contents to token + t.setType(token::tokenType::VARIABLE); + } + } + + return *this; + } + + // Number: integer or floating point + // + // ideally match the equivalent of this regular expression + // + // /[-+]?([0-9]+\.?[0-9]*|\.[0-9]+)([Ee][-+]?[0-9]+)?/ + // + case '-' : + case '.' : + case '0' : case '1' : case '2' : case '3' : case '4' : + case '5' : case '6' : case '7' : case '8' : case '9' : + { + int64 int64Val = (c != '.'); // used as bool here + + unsigned nChar = 0; + buf[nChar++] = c; + + // get everything that could resemble a number and let + // readScalar determine the validity + while + ( + is_.get(c) + && ( + isdigit(c) + || c == '+' + || c == '-' + || c == '.' + || c == 'E' + || c == 'e' + ) + ) + { + if (int64Val) + { + int64Val = isdigit(c); + } + + buf[nChar++] = c; + if (nChar == maxLen) + { + // Runaway argument - avoid buffer overflow + buf[maxLen-1] = '\0'; + + ioErrorInFile( name(), lineNumber()) + << "number '" << buf << "...'\n" + << " is too long (max. " << + static_cast(maxLen) << " characters)"; + fatalExit; + + t.setBad(); + return *this; + } + } + buf[nChar] = '\0'; // Terminate string + + setState(is_.rdstate()); + if (is_.bad()) + { + t.setBad(); + } + else + { + is_.putback(c); + + if (nChar == 1 && buf[0] == '-') + { + // A single '-' is punctuation + t = token::punctuationToken(token::SUBTRACT); + } + else if (int64Val && readInt64(buf, int64Val)) + { + t = int64Val; + } + else + { + real realVal; + + if (readReal(buf, realVal)) + { + // A scalar or too big to fit as a unit + t = realVal; + } + else + { + t.setBad(); + } + } + } + + return *this; + } + + // Should be a word (which can also be a single character) + default: + { + putback(c); + readWordToken(t); + + return *this; + } + } +} + + +pFlow::iIstream& pFlow::Istream::read(char& c) +{ + c = nextValid(); + return *this; +} + + +pFlow::iIstream& pFlow::Istream::read(word& str) +{ + + constexpr const unsigned maxLen = 1024; + static char buf[maxLen]; + + unsigned nChar = 0; + unsigned depth = 0; // Track depth of (..) nesting + char c; + + while + ( + (nChar < maxLen) + && get(c) + && validWord(c) + ) + { + if (c == token::BEGIN_LIST) + { + ++depth; + } + else if (c == token::END_LIST) + { + if (!depth) + { + break; // Closed ')' without an opening '(' ? ... stop + } + --depth; + } + + buf[nChar++] = c; + } + + if (nChar >= maxLen) + { + buf[errLen] = '\0'; + ioErrorInFile(name(), lineNumber()) + << "word '" << buf << "...'\n" + << " is too long (max. " << + static_cast(maxLen) << " characters)"; + fatalExit; + + return *this; + } + + buf[nChar] = '\0'; // Terminate string + + if (bad()) + { + // Could probably skip this check + buf[errLen] = '\0'; + + ioErrorInFile(name(), lineNumber()) + << "Problem while reading word '" << buf << "...' after " + << static_cast(nChar) << " characters\n"; + fatalExit; + + return *this; + } + + if (nChar == 0) + { + ioErrorInFile(name(), lineNumber()) + << "Invalid first character found : " << c; + fatalExit; + } + else if (depth) + { + warningInFunction + << "Missing " << static_cast(depth) + << " closing ')' while parsing" << nl << nl + << buf << nl << endl; + } + + // Finalize: content already validated, assign without additional checks. + str.assign(buf, nChar); + putback(c); + + return *this; +} + + +pFlow::iIstream& pFlow::Istream::readString(word& str) +{ + constexpr const unsigned maxLen = 1024; + static char buf[maxLen]; + + char c; + + if (!get(c)) + { + ioErrorInFile(name(), lineNumber()) + << "cannot read start of string"; + fatalExit; + + return *this; + } + + // Note, we could also handle single-quoted strings here (if desired) + if (c != token::BEGIN_STRING) + { + ioErrorInFile(name(), lineNumber()) + << "Incorrect start of string character found : " << c; + fatalExit; + + return *this; + } + + unsigned nChar = 0; + bool escaped = false; + + while + ( + (nChar < maxLen) + && get(c) + ) + { + if (c == token::END_STRING) + { + if (escaped) + { + escaped = false; + --nChar; // Overwrite backslash + } + else + { + // Done reading + str.assign(buf, nChar); + return *this; + } + } + else if (c == token::NL) + { + if (escaped) + { + escaped = false; + --nChar; // Overwrite backslash + } + else + { + buf[errLen] = buf[nChar] = '\0'; + + ioErrorInFile(name(), lineNumber()) + << "found '\\n' while reading string \"" + << buf << "...\""; + fatalExit; + + return *this; + } + } + else if (c == '\\') + { + escaped = !escaped; // toggle state (retains backslashes) + } + else + { + escaped = false; + } + + buf[nChar++] = c; + } + + if (nChar >= maxLen) + { + buf[errLen] = '\0'; + + ioErrorInFile(name(), lineNumber()) + << "string \"" << buf << "...\"\n" + << " is too long (max. " << static_cast(maxLen) << " characters)"; + fatalExit; + + return *this; + } + + // Don't worry about a dangling backslash if string terminated prematurely + buf[errLen] = buf[nChar] = '\0'; + + ioErrorInFile(name(), lineNumber()) + << "Problem while reading string \"" << buf << "...\""; + fatalExit; + + return *this; +} + +pFlow::iIstream& pFlow::Istream::read(int64& val) +{ + is_ >> val; + setState(is_.rdstate()); + return *this; +} + +pFlow::iIstream& pFlow::Istream::read(int32& val) +{ + is_ >> val; + setState(is_.rdstate()); + return *this; +} + +pFlow::iIstream& pFlow::Istream::read(int16& val) +{ + is_ >> val; + setState(is_.rdstate()); + return *this; +} + +pFlow::iIstream& pFlow::Istream::read(int8& val) +{ + is_ >> val; + setState(is_.rdstate()); + return *this; +} + +pFlow::iIstream& pFlow::Istream::read(label& val) +{ + is_ >> val; + setState(is_.rdstate()); + return *this; +} + +pFlow::iIstream& pFlow::Istream::read(uint32& val) +{ + is_ >> val; + setState(is_.rdstate()); + return *this; +} + +pFlow::iIstream& pFlow::Istream::read(uint16& val) +{ + is_ >> val; + setState(is_.rdstate()); + return *this; +} + +pFlow::iIstream& pFlow::Istream::read(float& val) +{ + is_ >> val; + setState(is_.rdstate()); + return *this; +} + + +pFlow::iIstream& pFlow::Istream::read(double& val) +{ + is_ >> val; + setState(is_.rdstate()); + return *this; +} + + +void pFlow::Istream::rewind() +{ + lineNumber_ = 1; // Reset line number + + stdStream().clear(); // Clear the iostate error state flags + setGood(); // Sync local copy of iostate + + // pubseekpos() rather than seekg() so that it works with gzstream + stdStream().rdbuf()->pubseekpos(0, std::ios_base::in); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +std::ios_base::fmtflags pFlow::Istream::flags() const +{ + return is_.flags(); +} + + +std::ios_base::fmtflags pFlow::Istream::flags(const ios_base::fmtflags f) +{ + return is_.flags(f); +} + + +// ************************************************************************* // diff --git a/src/phasicFlow/streams/Stream/Istream.H b/src/phasicFlow/streams/Stream/Istream.H new file mode 100755 index 00000000..b8941518 --- /dev/null +++ b/src/phasicFlow/streams/Stream/Istream.H @@ -0,0 +1,183 @@ +/*------------------------------- phasicFlow --------------------------------- + O C enter of + O O E ngineering and + O O M ultiscale modeling of + OOOOOOO F luid flow +------------------------------------------------------------------------------ + Copyright (C): www.cemf.ir + email: hamid.r.norouzi AT gmail.com +------------------------------------------------------------------------------ +Licence: + This file is part of phasicFlow code. It is a free software for simulating + granular and multiphase flows. You can redistribute it and/or modify it under + the terms of GNU General Public License v3 or any other later versions. + + phasicFlow is distributed to help others in their research in the field of + granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +-----------------------------------------------------------------------------*/ +// based on OpenFOAM stream, with some modifications/simplifications +// to be tailored to our needs + + +#ifndef __Istream_H__ +#define __Istream_H__ + +#include +#include + +#include "iIstream.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace pFlow +{ + + +class Istream +: + public iIstream +{ + // Private Data + + word name_; + + std::istream& is_; + + + //- Get the next valid character + char nextValid(); + + //- Read a word token + void readWordToken(token& t); + + + //- Read a variable name starting with '$'. + // Handles "$var" and "${var}" forms, permits '/' scoping character. + Istream& readVariable(word& str); + + //- No copy assignment + void operator=(const Istream&) = delete; + + +public: + + + //- Construct wrapper around std::istream, set stream status + Istream( std::istream& is, const word& streamName); + + + //- Destructor + virtual ~Istream() = default; + + + //// - Methods + + //- Return the name of the stream + virtual const word& name() const + { + return name_; + } + + //- Return non-const access to the name of the stream + virtual word& name() + { + return name_; + } + + //- Return flags of output stream + virtual ios_base::fmtflags flags() const; + + + //// Read Functions + + //- Raw, low-level get character function. + Istream& get(char& c); + + //- Raw, low-level peek function. + // Does not remove the character from the stream. + // Returns the next character in the stream or EOF if the + // end of file is read. + int peek(); + + //- Raw, low-level getline (until delimiter) into a string. + Istream& getLine(word& str, char delim = '\n'); + + //- Low-level discard until delimiter + // return the number of characters extracted + std::streamsize getLine(std::nullptr_t, char delim = '\n'); + + //- Raw, low-level putback character function. + Istream& putback(const char c); + + //- Return next token from stream + virtual iIstream& read(token& t) override; + + //- Read a character + virtual iIstream& read(char& c) override; + + //- Read a word + virtual iIstream& read(word& str) override; + + //- Read a string + virtual iIstream& readString(word& str) override; + + //- Read a int64 + virtual iIstream& read(int64&) override; + + //- Read a int32 + virtual iIstream& read(int32&) override; + + //- Read a int16 + virtual iIstream& read(int16&) override; + + //- Read a int8 + virtual iIstream& read(int8&) override; + + //- Read a label + virtual iIstream& read(label&) override; + + //- Read a uint32 + virtual iIstream& read(uint32&) override; + + //- Read a uint16 + virtual iIstream& read(uint16&) override; + + //- Read a float + virtual iIstream& read(float& val) override; + + //- Read a double + virtual iIstream& read(double& val) override; + + + //- Rewind the stream so that it may be read again + virtual void rewind(); + + + //- Set stream flags + virtual ios_base::fmtflags flags(const ios_base::fmtflags flags); + + + + //- Access to underlying std::istream + virtual std::istream& stdStream() + { + return is_; + } + + //- Const access to underlying std::istream + virtual const std::istream& stdStream() const + { + return is_; + } + + +}; + + +} + + +#endif + diff --git a/src/phasicFlow/streams/Stream/Ostream.C b/src/phasicFlow/streams/Stream/Ostream.C new file mode 100755 index 00000000..48edcf91 --- /dev/null +++ b/src/phasicFlow/streams/Stream/Ostream.C @@ -0,0 +1,307 @@ +/*------------------------------- phasicFlow --------------------------------- + O C enter of + O O E ngineering and + O O M ultiscale modeling of + OOOOOOO F luid flow +------------------------------------------------------------------------------ + Copyright (C): www.cemf.ir + email: hamid.r.norouzi AT gmail.com +------------------------------------------------------------------------------ +Licence: + This file is part of phasicFlow code. It is a free software for simulating + granular and multiphase flows. You can redistribute it and/or modify it under + the terms of GNU General Public License v3 or any other later versions. + + phasicFlow is distributed to help others in their research in the field of + granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +-----------------------------------------------------------------------------*/ +// based on OpenFOAM stream, with some modifications/simplifications +// to be tailored to our needs + +#include "error.H" +#include "token.H" +#include "Ostream.H" + + +pFlow::Ostream::Ostream +( + std::ostream& os, + const word& streamName +) +: + iOstream(), + name_(streamName), + os_(os) +{ + if (os_.good()) + { + setOpened(); + setGood(); + os_.precision(precision_); + } + else + { + setState(os_.rdstate()); + } +} + + + +bool pFlow::Ostream::write(const token& tok) +{ + // Direct token handling only for some types + + switch (tok.type()) + { + case token::tokenType::FLAG : + { + // silently consume the flag + return true; + } + + case token::tokenType::VARIABLE : + { + writeQuoted(tok.wordToken(), false); + + return true; + } + + default: + break; + } + + return false; +} + + +pFlow::iOstream& pFlow::Ostream::write(const char c) +{ + os_ << c; + if (c == token::NL) + { + ++lineNumber_; + } + setState(os_.rdstate()); + return *this; +} + + +pFlow::iOstream& pFlow::Ostream::write(const char* str) +{ + lineNumber_ += countChar(str, token::NL); + os_ << str; + setState(os_.rdstate()); + return *this; +} + + +pFlow::iOstream& pFlow::Ostream::write(const word& str) +{ + os_ << str; + setState(os_.rdstate()); + return *this; +} + + +pFlow::iOstream& pFlow::Ostream::writeQuoted +( + const word& str, + const bool quoted +) +{ + if (!quoted) + { + // Output unquoted, only advance line number on newline + lineNumber_ += countChar(str, token::NL); + os_ << str; + + setState(os_.rdstate()); + return *this; + } + + + // Output with surrounding quotes and backslash escaping + os_ << token::BEGIN_STRING; + + unsigned backslash = 0; + for (auto iter = str.cbegin(); iter != str.cend(); ++iter) + { + const char c = *iter; + + if (c == '\\') + { + ++backslash; + continue; // only output after escaped character is known + } + else if (c == token::NL) + { + ++lineNumber_; + ++backslash; // backslash escape for newline + } + else if (c == token::END_STRING) + { + ++backslash; // backslash escape for quote + } + + // output all pending backslashes + while (backslash) + { + os_ << '\\'; + --backslash; + } + + os_ << c; + } + + // silently drop any trailing backslashes + // they would otherwise appear like an escaped end-quote + os_ << token::END_STRING; + + setState(os_.rdstate()); + return *this; +} + + + +pFlow::iOstream& pFlow::Ostream::write(const int64 val) +{ + os_ << val; + setState(os_.rdstate()); + return *this; +} + + +pFlow::iOstream& pFlow::Ostream::write(const int32 val) +{ + os_ << val; + setState(os_.rdstate()); + return *this; +} + +/*pFlow::iOstream& pFlow::Ostream::write(const int16 val) +{ + os_ << val; + setState(os_.rdstate()); + return *this; +} + +pFlow::iOstream& pFlow::Ostream::write(const int8 val) +{ + os_ << val; + setState(os_.rdstate()); + return *this; +}*/ + +pFlow::iOstream& pFlow::Ostream::write(const label val) +{ + os_ << val; + setState(os_.rdstate()); + return *this; +} + +pFlow::iOstream& pFlow::Ostream::write(const uint32 val) +{ + os_ << val; + setState(os_.rdstate()); + return *this; +} + +pFlow::iOstream& pFlow::Ostream::write(const uint16 val) +{ + os_ << val; + setState(os_.rdstate()); + return *this; +} + +pFlow::iOstream& pFlow::Ostream::write(const float val) +{ + os_ << val; + setState(os_.rdstate()); + return *this; +} + + +pFlow::iOstream& pFlow::Ostream::write(const double val) +{ + os_ << val; + setState(os_.rdstate()); + return *this; +} + + + +void pFlow::Ostream::indent() +{ + for (unsigned short i = 0; i < indentLevel_*indentSize_; ++i) + { + os_ << ' '; + } +} + + +void pFlow::Ostream::flush() +{ + os_.flush(); +} + + +void pFlow::Ostream::endl() +{ + write('\n'); + os_.flush(); +} + + +std::ios_base::fmtflags pFlow::Ostream::flags() const +{ + return os_.flags(); +} + + +std::ios_base::fmtflags pFlow::Ostream::flags(const ios_base::fmtflags f) +{ + return os_.flags(f); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +char pFlow::Ostream::fill() const +{ + return os_.fill(); +} + + +char pFlow::Ostream::fill(const char fillch) +{ + return os_.fill(fillch); +} + + +int pFlow::Ostream::width() const +{ + return os_.width(); +} + + +int pFlow::Ostream::width(const int w) +{ + return os_.width(w); +} + + +int pFlow::Ostream::precision() const +{ + return os_.precision(); +} + + +int pFlow::Ostream::precision(const int p) +{ + return os_.precision(p); +} + + +// ************************************************************************* // diff --git a/src/phasicFlow/streams/Stream/Ostream.H b/src/phasicFlow/streams/Stream/Ostream.H new file mode 100755 index 00000000..c1cdf6b0 --- /dev/null +++ b/src/phasicFlow/streams/Stream/Ostream.H @@ -0,0 +1,170 @@ +/*------------------------------- phasicFlow --------------------------------- + O C enter of + O O E ngineering and + O O M ultiscale modeling of + OOOOOOO F luid flow +------------------------------------------------------------------------------ + Copyright (C): www.cemf.ir + email: hamid.r.norouzi AT gmail.com +------------------------------------------------------------------------------ +Licence: + This file is part of phasicFlow code. It is a free software for simulating + granular and multiphase flows. You can redistribute it and/or modify it under + the terms of GNU General Public License v3 or any other later versions. + + phasicFlow is distributed to help others in their research in the field of + granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +-----------------------------------------------------------------------------*/ +// based on OpenFOAM stream, with some modifications/simplifications +// to be tailored to our needs + +#ifndef __Ostream_H__ +#define __Ostream_H__ + +#include "iOstream.H" +#include + + +namespace dFlow +{ + + + +class Ostream +: + public iOstream +{ + + word name_; + + std::ostream& os_; + + +public: + + // Constructors + + Ostream ( std::ostream& os, const word& streamName); + + //- no copy construct + Ostream(const Ostream&) = delete; + + //- No copy assignment + void operator=(const Ostream&) = delete; + + + //// - Methods + + //- Return the name of the stream + virtual const word& name() const + { + return name_; + } + + //- Return non-const access to the name of the stream + virtual word& name() + { + return name_; + } + + //- Return flags of output stream + virtual ios_base::fmtflags flags() const; + + + //- Write token to stream or otherwise handle it. + // return false if the token type was not handled by this method + virtual bool write(const token& tok)override; + + //- Write character + virtual iOstream& write(const char c)override; + + //- Write character string + virtual iOstream& write(const char* str)override; + + //- Write word + virtual iOstream& write(const word& str)override; + + //- Write std::string surrounded by quotes. + // Optional write without quotes. + virtual iOstream& writeQuoted ( const word& str, const bool quoted=true )override; + + //- Write int64 + virtual iOstream& write(const int64 val) override; + + //- Write int32 + virtual iOstream& write(const int32 val) override; + + + //- Write label + virtual iOstream& write(const label val) override; + + //- Write uint32 + virtual iOstream& write(const uint32 val) override; + + //- Write uint16 + virtual iOstream& write(const uint16 val) override; + + //- Write float + virtual iOstream& write(const float val) override; + + //- Write double + virtual iOstream& write(const double val) override; + + //- Add indentation characters + virtual void indent(); + + + //- Set stream flags + virtual ios_base::fmtflags flags(const ios_base::fmtflags f); + + //- Flush stream + virtual void flush(); + + //- Add newline and flush stream + virtual void endl(); + + //- Get the current padding character + virtual char fill() const; + + //- Set padding character for formatted field up to field width + // \return previous padding character + virtual char fill(const char fillch); + + //- Get width of output field + virtual int width() const; + + //- Set width of output field + // \return previous width + virtual int width(const int w); + + //- Get precision of output field + virtual int precision() const; + + //- Set precision of output field + // return old precision + virtual int precision(const int p); + + //- Access to underlying std::ostream + virtual std::ostream& stdStream() + { + return os_; + } + + //- Const access to underlying std::ostream + virtual const std::ostream& stdStream() const + { + return os_; + } + +}; + + + +} // dFlow + + +#endif + + diff --git a/src/phasicFlow/streams/TStream/helperTstream.H b/src/phasicFlow/streams/TStream/helperTstream.H new file mode 100755 index 00000000..22571f60 --- /dev/null +++ b/src/phasicFlow/streams/TStream/helperTstream.H @@ -0,0 +1,35 @@ +#ifndef __helperTstream_H__ +#define __helperTstream_H__ + + + +inline bool validTokenForStream(const token tok) +{ + if( tok.good() && !tok.isPunctuation() )return true; + if( tok == token::SPACE) return false; + if( tok == token::TAB) return false; + if( tok == token::NL) return false; + if( tok == token::NULL_TOKEN )return false; + + return true; +} + +inline bool isBeginToken(const token& tok) +{ + if( tok.good() && !tok.isPunctuation() )return false; + if( tok == token::BEGIN_LIST) return true; + if( tok == token::BEGIN_BLOCK) return true; + if( tok == token::BEGIN_SQR) return true; + return false; +} + +inline bool isEndToken(const token& tok) +{ + if( tok.good() && !tok.isPunctuation() )return false; + if( tok == token::END_LIST) return true; + if( tok == token::END_BLOCK)return true; + if( tok == token::END_SQR) return true; + return false; +} + +#endif // __helperTstream__ diff --git a/src/phasicFlow/streams/TStream/iTstream.C b/src/phasicFlow/streams/TStream/iTstream.C new file mode 100755 index 00000000..b9d853bb --- /dev/null +++ b/src/phasicFlow/streams/TStream/iTstream.C @@ -0,0 +1,360 @@ + +#include "iTstream.H" +#include "error.H" +#include "iOstream.H" + +bool dFlow::iTstream::isLastToken() +{ + return currentToken_ == tokenList_.end(); +} + +void dFlow::iTstream::setFirstToken() +{ + currentToken_ = tokenList_.begin(); +} + +void dFlow::iTstream::validate() +{ + for (auto it = tokenList_.begin(); it != tokenList_.end(); ) + { + if (!validTokenForStream(*it)) + { + it = tokenList_.erase(it); + } + else + { + ++it; + } + } +} + +dFlow::iTstream::iTstream +( + const word& streamName +) +: + iIstream(), + name_(streamName), + tokenList_(), + currentToken_(tokenList_.begin()) +{ + setOpened(); + setGood(); + rewind(); +} + +dFlow::iTstream::iTstream +( + const word& streamName, + const tokenList& tList +) +: + iIstream(), + name_(streamName), + tokenList_(tList), + currentToken_(tokenList_.begin()) +{ + setOpened(); + setGood(); + // check for invalid tokens in the tList + validate(); + rewind(); +} + +dFlow::iTstream::iTstream +( + const word& streamName, + tokenList&& tList +) +: + iIstream(), + name_(streamName), + tokenList_(std::move(tList)), + currentToken_(tokenList_.begin()) +{ + setOpened(); + setGood(); + + // check for invalid tokens in the tList + validate(); + rewind(); +} + +// copy assignment from tokenList +void dFlow::iTstream::operator=(const tokenList& tList) +{ + tokenList_ = tList; + validate(); + rewind(); +} + +// move assignment from tokenList +void dFlow::iTstream::operator=(tokenList&& tList) +{ + tokenList_ = std::move(tList); + validate(); + rewind(); +} + +const dFlow::word& dFlow::iTstream::name() const +{ + return name_; +} + +dFlow::word& dFlow::iTstream::name() +{ + return name_; +} + + +dFlow::iIstream& dFlow::iTstream::read +( + token& t +) +{ + // Return the put back token if it exists + if (iIstream::getBack(t)) + { + lineNumber_ = t.lineNumber(); + setGood(); + return *this; + } + + if ( !isLastToken() ) + { + //t = operator[](tokenIndex_++); + lineNumber_ = t.lineNumber(); + t = *currentToken_; + setGood(); + currentToken_++; + + if( isLastToken() ) + { + setEof(); + } + } + else + { + if (eof()) + { + fatalErrorInFunction << + "attempt to read beyond EOF \n"; + fatalExit; + setBad(); + } + else + { + setEof(); + } + + t.reset(); + + if (tokenList_.size()) + { + t.lineNumber() = tokenList_.back().lineNumber(); + } + else + { + t.lineNumber() = lineNumber(); + } + } + + return *this; +} + + + +dFlow::iIstream& dFlow::iTstream::read +( + char& c +) +{ + notImplementedFunction; + fatalExit; + CONSUME_PARAM(c); + return *this; +} + + +dFlow::iIstream& dFlow::iTstream::read +( + word& str +) +{ + notImplementedFunction; + fatalExit; + CONSUME_PARAM(str); + return *this; +} + + +dFlow::iIstream& dFlow::iTstream::readString +( + word& str +) +{ + notImplementedFunction; + fatalExit; + CONSUME_PARAM(str); + return *this; +} + + +dFlow::iIstream& dFlow::iTstream::read +( + int64& val +) +{ + notImplementedFunction; + fatalExit; + CONSUME_PARAM(val); + return *this; +} + +dFlow::iIstream& dFlow::iTstream::read +( + int32& val +) +{ + notImplementedFunction; + fatalExit; + CONSUME_PARAM(val); + return *this; +} + +dFlow::iIstream& dFlow::iTstream::read +( + int16& val +) +{ + notImplementedFunction; + fatalExit; + CONSUME_PARAM(val); + return *this; +} + +dFlow::iIstream& dFlow::iTstream::read +( + int8& val +) +{ + notImplementedFunction; + fatalExit; + CONSUME_PARAM(val); + return *this; +} + +dFlow::iIstream& dFlow::iTstream::read +( + label& val +) +{ + notImplementedFunction; + fatalExit; + CONSUME_PARAM(val); + return *this; +} + +dFlow::iIstream& dFlow::iTstream::read +( + uint32& val +) +{ + notImplementedFunction; + fatalExit; + CONSUME_PARAM(val); + return *this; +} + +dFlow::iIstream& dFlow::iTstream::read +( + uint16& val +) +{ + notImplementedFunction; + fatalExit; + CONSUME_PARAM(val); + return *this; +} + + +dFlow::iIstream& dFlow::iTstream::read +( + float& val +) +{ + notImplementedFunction; + fatalExit; + CONSUME_PARAM(val); + return *this; +} + + +dFlow::iIstream& dFlow::iTstream::read +( + double& val +) +{ + + notImplementedFunction; + fatalExit; + CONSUME_PARAM(val); + return *this; +} + + + +void dFlow::iTstream::rewind() +{ + iIstream::resetPutBack(); + setFirstToken(); + setGood(); +} + + +void dFlow::iTstream::reset() +{ + iIstream::resetPutBack(); + tokenList_.clear(); + setFirstToken(); + setGood(); +} + +const dFlow::tokenList& dFlow::iTstream::tokens()const +{ + return tokenList_; +} + +size_t dFlow::iTstream::size()const +{ + return tokenList_.size(); +} + +size_t dFlow::iTstream::numTokens()const +{ + return tokenList_.size(); +} + +void dFlow::iTstream::appendTokens +( + const tokenList & tList +) +{ + + for(auto& t:tList) + { + if(validTokenForStream(t)) tokenList_.push_back(t); + } + rewind(); +} + +void dFlow::iTstream::appendToken +( + const token& t +) +{ + if(validTokenForStream(t)) tokenList_.push_back(t); + rewind(); +} + +// ************************************************************************* // diff --git a/src/phasicFlow/streams/TStream/iTstream.H b/src/phasicFlow/streams/TStream/iTstream.H new file mode 100755 index 00000000..7f4f3b60 --- /dev/null +++ b/src/phasicFlow/streams/TStream/iTstream.H @@ -0,0 +1,176 @@ + +#ifndef __iTstream_H__ +#define __iTstream_H__ + +#include "iIstream.H" +#include "tokenList.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace dFlow +{ + +// helper functions declearation +inline bool validTokenForStream(const token tok); + +inline bool isBeginToken(const token& tok); + +inline bool isEndToken(const token& tok); + + +class iTstream +: + public iIstream +{ +protected: + + // - name of the stream + word name_; + + // - list of tokens in this stream + tokenList tokenList_; + + // - current token + tokenList::iterator currentToken_; + + // - check if end of list is reached + bool isLastToken(); + + // - rewind the stream + void setFirstToken(); + + // - check for valid tokens in the tokenList + void validate(); + +public: + + //// - Constructors + + //- construct with a name + iTstream(const word& streamName); + + // - construct with name and copy + iTstream(const word& streamName, const tokenList& tList); + + // - construct with name and move + iTstream(const word& streamName, tokenList && tList); + + // - copy construct + iTstream(const iTstream&) = default; + // - move construct + iTstream(iTstream&&) = default; + + // - copy assignment + iTstream& operator=(const iTstream&) = default; + + // - move assignment + iTstream& operator=(iTstream&&) = default; + + // copy assignment from tokenList + void operator=(const tokenList& tList); + + // move assignment from tokenList + void operator=(tokenList&& tList); + + //- Destructor + virtual ~iTstream() = default; + + + //// Member Functions + + //- Return the name of the stream + virtual const word& name() const; + + //- Return non-const access to the name of the stream + virtual word& name(); + + //- Return next token from stream + virtual iIstream& read(token& t)override; + + //- Read a character + virtual iIstream& read(char& c)override; + + //- Read a word + virtual iIstream& read(word& str)override; + + //- Read a string + virtual iIstream& readString(word& str)override; + + //- Read a int64 + virtual iIstream& read(int64&) override; + + //- Read a int32 + virtual iIstream& read(int32&) override; + + //- Read a int16 + virtual iIstream& read(int16&) override; + + //- Read a int8 + virtual iIstream& read(int8&) override; + + //- Read a label + virtual iIstream& read(label&) override; + + //- Read a uint32 + virtual iIstream& read(uint32&) override; + + //- Read a uint16 + virtual iIstream& read(uint16&) override; + + //- Read a floatScalar + virtual iIstream& read(float&) override; + + //- Read a doubleScalar + virtual iIstream& read(double&) override; + + // - Rewind the stream so that it may be read again + virtual void rewind(); + + // - reset the iTstream and make the stream empty + virtual void reset(); + + // - const access to token list + const tokenList& tokens()const; + + // - size + size_t size()const; + + // - size + size_t numTokens()const; + + // - append a list of tokens to the end of tokens + // and rewind the stream + void appendTokens(const tokenList & tList); + + // - append token to the end of token and rewind the stream + void appendToken(const token& t); + + //- Return flags of output stream + ios_base::fmtflags flags() const + { + return ios_base::fmtflags(0); + } + + //- Set flags of stream + ios_base::fmtflags flags(const ios_base::fmtflags) + { + return ios_base::fmtflags(0); + } + +}; + +#include "helperTstream.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/phasicFlow/streams/TStream/oTstream.C b/src/phasicFlow/streams/TStream/oTstream.C new file mode 100755 index 00000000..3b14c9c3 --- /dev/null +++ b/src/phasicFlow/streams/TStream/oTstream.C @@ -0,0 +1,179 @@ + +#include "oTstream.H" +#include "error.H" + +dFlow::oTstream::oTstream +( + const word& nm +) +: + iOstream(), + name_(nm), + tokenList_() +{ + setOpened(); + setGood(); +} + +dFlow::oTstream::oTstream +( + const oTstream& src +) +: + iOstream(src), + name_(src.name_), + tokenList_(src.tokenList_) +{ + setOpened(); + setGood(); +} + + +const dFlow::tokenList& dFlow::oTstream::tokens()const +{ + return tokenList_; +} + + +dFlow::tokenList& dFlow::oTstream::tokens() +{ + return tokenList_; +} + + +bool dFlow::oTstream::write(const token& tok) +{ + if (tok.good()) + { + append(tok); + return true; + } + + return false; +} + + +dFlow::iOstream& dFlow::oTstream::write(const char c) +{ + if (!std::isspace(c) && std::isprint(c)) + { + // Should generally work, but need to verify corner cases + append(token(token::punctuationToken(c))); + } + + return *this; +} + + +dFlow::iOstream& dFlow::oTstream::write(const char* str) +{ + + append(token(word(str))); + + return *this; +} + + +dFlow::iOstream& dFlow::oTstream::write(const word& str) +{ + append(token(str)); // tokenType::WORD + + return *this; +} + + +dFlow::iOstream& dFlow::oTstream::writeQuoted +( + const word& str, + const bool quoted +) +{ + + append(token(str, lineNumber(),quoted)); // tokenType::STRING/WORD + + return *this; +} + +dFlow::iOstream& dFlow::oTstream::write(const int64 val) +{ + append(token(val)); // tokenType::INT64 + + return *this; +} + +dFlow::iOstream& dFlow::oTstream::write(const int32 val) +{ + append(token(val)); // tokenType::INT64 + + return *this; +} + + + + +dFlow::iOstream& dFlow::oTstream::write(const label val) +{ + append(token(static_cast(val))); // tokenType::INT64 + + return *this; +} + +dFlow::iOstream& dFlow::oTstream::write(const uint32 val) +{ + append(token(static_cast(val))); // tokenType::INT64 + + return *this; +} + +dFlow::iOstream& dFlow::oTstream::write(const uint16 val) +{ + append(token(static_cast(val))); // tokenType::INT64 + + return *this; +} + + +dFlow::iOstream& dFlow::oTstream::write(const float val) +{ + append(token(val)); // tokenType::FLOAT + + return *this; +} + + +dFlow::iOstream& dFlow::oTstream::write(const double val) +{ + append(token(val)); // tokenType::DOUBLE + + return *this; +} + + + +void dFlow::oTstream::append(const token& tok) +{ + + if( validTokenForStream(tok) ) + tokenList_.push_back(tok); +} + +void dFlow::oTstream::append(const tokenList& tLisk) +{ + for(auto& e:tLisk) + { + append(e); + } +} + +void dFlow::oTstream::reset() +{ + this->rewind(); +} + +//- Rewind the output stream +void dFlow::oTstream::rewind() +{ + tokenList_.clear(); + setGood(); +} +// ************************************************************************* // diff --git a/src/phasicFlow/streams/TStream/oTstream.H b/src/phasicFlow/streams/TStream/oTstream.H new file mode 100755 index 00000000..ef71f2c0 --- /dev/null +++ b/src/phasicFlow/streams/TStream/oTstream.H @@ -0,0 +1,196 @@ + +#ifndef __oTstream_H__ +#define __oTstream_H__ + +#include "tokenList.H" +#include "iOstream.H" + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace dFlow +{ + + +// helper functions declearation +inline bool validTokenForStream(const token tok); + +inline bool isBeginToken(const token& tok); + +inline bool isEndToken(const token& tok); + + +class oTstream +: + public iOstream +{ + +protected: + + // - name of stream + word name_; + + // - tokenList + tokenList tokenList_; + +public: + + //// - Constructors + + // - emtpy stream with a name + oTstream(const word& nm); + + // - copy construcotr + oTstream(const oTstream& src); + + // - move construct + oTstream(oTstream&&) = default; + + // - destructor + virtual ~oTstream() = default; + + + //// - Methods + + // give const access + const tokenList& tokens()const; + + // give access + tokenList& tokens(); + + + //// - Write + + //- Write token to stream or otherwise handle it. + // return false if the token type was not handled by this method + virtual bool write(const token& tok); + + //- Write single character. Whitespace is suppressed. + virtual iOstream& write(const char c); + + //- Write the word-characters of a character string. + // Sends as a single char, or as word. + virtual iOstream& write(const char* str); + + //- Write word + virtual iOstream& write(const word& str); + + + //- Write std::string surrounded by quotes. + // Optional write without quotes. + virtual iOstream& writeQuoted(const std::string& str, const bool quoted=true ); + + //- Write int64 + virtual iOstream& write(const int64 val) override; + + //- Write int32 + virtual iOstream& write(const int32 val) override; + + + //- Write label + virtual iOstream& write(const label val) override; + + //- Write uint32 + virtual iOstream& write(const uint32 val) override; + + //- Write uint16 + virtual iOstream& write(const uint16 val) override; + + //- Write float + virtual iOstream& write(const float val) override; + + //- Write double + virtual iOstream& write(const double val) override; + + // - append token to the stream + virtual void append(const token& tok); + + // - append a list of tokens to the stream + virtual void append(const tokenList& tLisk); + + + + //// - Stream state functions + + //- Reset the output buffer and rewind the stream + void reset(); + + //- Rewind the output stream + virtual void rewind(); + + //- Add indentation characters + virtual void indent() + {} + + //- Flush stream + virtual void flush() + {} + + //- Add newline and flush stream + virtual void endl() + {} + + //- Get the current padding character + // \return previous padding character + virtual char fill() const + { + return 0; + } + + //- Set padding character for formatted field up to field width + virtual char fill(const char) + { + return 0; + } + + //- Get width of output field + virtual int width() const + { + return 0; + } + + //- Set width of output field + // \return previous width + virtual int width(const int) + { + return 0; + } + + //- Get precision of output field + virtual int precision() const + { + return 0; + } + + //- Set precision of output field + // \return old precision + virtual int precision(const int) + { + return 0; + } + + //- Return flags of output stream + virtual ios_base::fmtflags flags() const + { + return ios_base::fmtflags(0); + } + + //- Set flags of stream + ios_base::fmtflags flags(const ios_base::fmtflags) + { + return ios_base::fmtflags(0); + } + +}; + +#include "helperTstream.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace dFlow + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/phasicFlow/streams/iStream/IOstream.C b/src/phasicFlow/streams/iStream/IOstream.C new file mode 100644 index 00000000..048cc2ed --- /dev/null +++ b/src/phasicFlow/streams/iStream/IOstream.C @@ -0,0 +1,60 @@ +/*------------------------------- phasicFlow --------------------------------- + O C enter of + O O E ngineering and + O O M ultiscale modeling of + OOOOOOO F luid flow +------------------------------------------------------------------------------ + Copyright (C): www.cemf.ir + email: hamid.r.norouzi AT gmail.com +------------------------------------------------------------------------------ +Licence: + This file is part of phasicFlow code. It is a free software for simulating + granular and multiphase flows. You can redistribute it and/or modify it under + the terms of GNU General Public License v3 or any other later versions. + + phasicFlow is distributed to help others in their research in the field of + granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +-----------------------------------------------------------------------------*/ + +#include "IOstream.H" +#include "iOstream.H" +#include "error.H" + + +unsigned int pFlow::IOstream::precision_ = 6; + +pFlow::word pFlow::IOstream::staticName_("IOstream"); + + +const pFlow::word& pFlow::IOstream::name() const +{ + return staticName_; +} + + +pFlow::word& pFlow::IOstream::name() +{ + return staticName_; +} + +bool pFlow::IOstream::check(const char* operation) const +{ + return fatalCheck(operation); +} + + +bool pFlow::IOstream::fatalCheck(const char* operation) const +{ + const bool ok = !bad(); + + if (!ok) + { + fatalErrorInFunction + << "error in IOstream " << name() << " for operation " << operation; + fatalExit; + } + + return ok; +} \ No newline at end of file diff --git a/src/phasicFlow/streams/iStream/IOstream.H b/src/phasicFlow/streams/iStream/IOstream.H new file mode 100644 index 00000000..11941111 --- /dev/null +++ b/src/phasicFlow/streams/iStream/IOstream.H @@ -0,0 +1,309 @@ +/*------------------------------- phasicFlow --------------------------------- + O C enter of + O O E ngineering and + O O M ultiscale modeling of + OOOOOOO F luid flow +------------------------------------------------------------------------------ + Copyright (C): www.cemf.ir + email: hamid.r.norouzi AT gmail.com +------------------------------------------------------------------------------ +Licence: + This file is part of phasicFlow code. It is a free software for simulating + granular and multiphase flows. You can redistribute it and/or modify it under + the terms of GNU General Public License v3 or any other later versions. + + phasicFlow is distributed to help others in their research in the field of + granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +-----------------------------------------------------------------------------*/ + + +#ifndef __IOstream_H__ +#define __IOstream_H__ + +// based on OpenFOAM stream, with some modifications/simplifications +// to be tailored to our needs + +#include + +#include "bTypesFunctions.H" + +using std::ios_base; +using std::istream; +using std::ostream; + +using std::cin; +using std::cout; +using std::cerr; + + + +namespace pFlow +{ + +class IOstream +{ + +public: + + + enum streamAccess : char + { + CLOSED = 0, //!< stream is not open + OPENED //!< stream is open + }; + + + //- Default precision + static unsigned int precision_; + +protected: + + //- Name for any generic stream - normally treat as readonly + static word staticName_; + + streamAccess openClosed_; + + ios_base::iostate ioState_; + + + //- The file line + int32 lineNumber_; + + + // Protected Member Functions + + //- Set stream opened + void setOpened() + { + openClosed_ = OPENED; + } + + //- Set stream closed + void setClosed() + { + openClosed_ = CLOSED; + } + + //- Set stream state + void setState(ios_base::iostate state) + { + ioState_ = state; + } + + //- Set stream to be good + void setGood() + { + ioState_ = ios_base::iostate(0); + } + + +public: + + // Constructors + explicit IOstream(): + openClosed_(CLOSED), + ioState_(ios_base::iostate(0)), + lineNumber_(0) + { + setBad(); + } + + IOstream(const IOstream&) = default; + + //- Destructor + virtual ~IOstream() = default; + + + //// Member Functions + + //- Return the name of the stream + virtual const word& name() const; + + //- Return non-const access to the name of the stream + virtual word& name(); + + //- Check IOstream status for given operation. + // Print IOstream state or generate a FatalIOError + // when an error has occurred. + // The base implementation is a fatalCheck + virtual bool check(const char* operation) const; + + //- Check IOstream status for given operation. + // Generate a FatalIOError when an error has occurred. + bool fatalCheck(const char* operation) const; + + //- Return true if stream has been opened + bool opened() const + { + return openClosed_ == OPENED; + } + + //- Return true if stream is closed + bool closed() const + { + return openClosed_ == CLOSED; + } + + //- Return true if next operation might succeed + bool good() const + { + return ioState_ == 0; + } + + //- Return true if end of input seen + bool eof() const + { + return ioState_ & ios_base::eofbit; + } + + //- Return true if next operation will fail + bool fail() const + { + return ioState_ & (ios_base::badbit | ios_base::failbit); + } + + //- Return true if stream is corrupted + bool bad() const + { + return ioState_ & ios_base::badbit; + } + + //- Return true if the stream has not failed + explicit operator bool() const + { + return !fail(); + } + + //- Return true if the stream has failed + bool operator!() const + { + return fail(); + } + + + //- Const access to the current stream line number + int32 lineNumber() const + { + return lineNumber_; + } + + //- Non-const access to the current stream line number + int32& lineNumber() + { + return lineNumber_; + } + + //- Set the stream line number + // \return the previous value + int32 lineNumber(const int32 num) + { + const int32 old(lineNumber_); + lineNumber_ = num; + return old; + } + + //- Return flags of stream + virtual ios_base::fmtflags flags() const = 0; + + //- Return the default precision + static unsigned int defaultPrecision() + { + return precision_; + } + + //- Reset the default precision + // \return the previous value + static unsigned int defaultPrecision(unsigned int prec) + { + unsigned int old(precision_); + precision_ = prec; + return old; + } + + //- Set stream to have reached eof + void setEof() + { + ioState_ |= ios_base::eofbit; + } + + //- Set stream to have failed + void setFail() + { + ioState_ |= ios_base::failbit; + } + + //- Set stream to be bad + void setBad() + { + ioState_ |= ios_base::badbit; + } + + //- Set flags of stream + virtual ios_base::fmtflags flags(const ios_base::fmtflags f) = 0; + + //- Set flags of stream + ios_base::fmtflags setf(const ios_base::fmtflags f) + { + return flags(flags() | f); + } + + //- Set flags of given field of stream + ios_base::fmtflags setf + ( + const ios_base::fmtflags f, + const ios_base::fmtflags mask + ) + { + return flags((flags() & ~mask) | (f & mask)); + } + + //- Unset flags of stream + void unsetf(const ios_base::fmtflags f) + { + flags(flags() & ~f); + } + + +}; // end of IOstream + + +//- An IOstream manipulator +typedef IOstream& (*IOstreamManip)(IOstream&); + +inline IOstream& dec(IOstream& io) +{ + io.setf(ios_base::dec, ios_base::dec|ios_base::hex|ios_base::oct); + return io; +} + +inline IOstream& hex(IOstream& io) +{ + io.setf(ios_base::hex, ios_base::dec|ios_base::hex|ios_base::oct); + return io; +} + +inline IOstream& oct(IOstream& io) +{ + io.setf(ios_base::oct, ios_base::dec|ios_base::hex|ios_base::oct); + return io; +} + +inline IOstream& fixed(IOstream& io) +{ + io.setf(ios_base::fixed, ios_base::floatfield); + return io; +} + +inline IOstream& scientific(IOstream& io) +{ + io.setf(ios_base::scientific, ios_base::floatfield); + return io; +} + + + +} // pFlow + +#endif // __IOstream__H__ diff --git a/src/phasicFlow/streams/iStream/iIstream.C b/src/phasicFlow/streams/iStream/iIstream.C new file mode 100755 index 00000000..5951aa30 --- /dev/null +++ b/src/phasicFlow/streams/iStream/iIstream.C @@ -0,0 +1,337 @@ + +#include "iIstream.H" + + +void dFlow::iIstream::putBack(const token& tok) +{ + if (bad()) + { + ioErrorInFile(name(), lineNumber()) << + "stream is bad.\n"; + fatalExit; + } + else if (putBack_) + { + fatalErrorInFunction << + "putBack is already full. \n"; + fatalExit; + } + else + { + putBackToken_ = tok; + putBack_ = true; + } +} + + +bool dFlow::iIstream::getBack(token& tok) +{ + + if (bad()) + { + fatalErrorInFunction; + return false; + } + else if (putBack_) + { + tok = putBackToken_; + putBack_ = false; + return true; + } + + return false; +} + + +bool dFlow::iIstream::peekBack(token& tok) +{ + if (putBack_) + { + tok = putBackToken_; + } + else + { + tok.reset(); + } + + return putBack_; +} + +bool dFlow::iIstream::findToken( const word & w ) +{ + rewind(); + token next; + + while( !eof() && good() ) + { + read(next); + if(next.error()) + { + fatalErrorInFunction << + "error in reading stream " << name() << + " at line number "<< lineNumber()<(*this); +} \ No newline at end of file diff --git a/src/phasicFlow/streams/iStream/iIstream.H b/src/phasicFlow/streams/iStream/iIstream.H new file mode 100755 index 00000000..4fb0eae9 --- /dev/null +++ b/src/phasicFlow/streams/iStream/iIstream.H @@ -0,0 +1,250 @@ +/*------------------------------- phasicFlow --------------------------------- + O C enter of + O O E ngineering and + O O M ultiscale modeling of + OOOOOOO F luid flow +------------------------------------------------------------------------------ + Copyright (C): www.cemf.ir + email: hamid.r.norouzi AT gmail.com +------------------------------------------------------------------------------ +Licence: + This file is part of phasicFlow code. It is a free software for simulating + granular and multiphase flows. You can redistribute it and/or modify it under + the terms of GNU General Public License v3 or any other later versions. + + phasicFlow is distributed to help others in their research in the field of + granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +-----------------------------------------------------------------------------*/ + +#ifndef __iIstream_H__ +#define __iIstream_H__ + +#include "IOstream.H" +#include "token.H" +#include "error.H" +#include "iOstream.H" + +namespace pFlow +{ + + +class iIstream // interface class for input streams +: + public IOstream +{ + + // Private Data + + //- Has a token been put back on the stream? + bool putBack_; + + //- The last token put back on the stream + token putBackToken_; + +public: + + //// - Constructors + + // - default + iIstream(): + IOstream(), + putBack_(false) + {} + + // - Copy construct + iIstream(const iIstream&) = default; + + // - Destructor + virtual ~iIstream() = default; + + + + //// member methods + + //- Put back token + // Only a single put back is permitted + void putBack(const token& tok); + + //- Get the put back token if there is one and return true. + // Return false if no put back token is available. + bool getBack(token& tok); + + //- Peek at the put back token without removing it. + // Returns false if no put back token is available and set the + // token to undefined. + bool peekBack(token& tok); + + //- reset the put back token; + void resetPutBack() + { + putBackToken_.reset(); + putBack_ = false; + } + + //- Return next token from stream + virtual iIstream& read(token&) = 0; + + //- Read a character + virtual iIstream& read(char&) = 0; + + //- Read a string (including enclosing double-quotes) + virtual iIstream& read(word&) = 0; + + //- Read a string + virtual iIstream& readString(word&) = 0; + + //- Read a int64 + virtual iIstream& read(int64&) = 0; + + //- Read a int32 + virtual iIstream& read(int32&) = 0; + + //- Read a int16 + virtual iIstream& read(int16&) = 0; + + //- Read a int8 + virtual iIstream& read(int8&) = 0; + + //- Read a label + virtual iIstream& read(label&) = 0; + + //- Read a uin32 + virtual iIstream& read(uint32&) = 0; + + //- Read a uin16 + virtual iIstream& read(uint16&) = 0; + + //- Read a floatScalar + virtual iIstream& read(float&) = 0; + + //- Read a doubleScalar + virtual iIstream& read(double&) = 0; + + + //- Rewind the stream so that it may be read again + virtual void rewind() = 0; + + + //// - find and lookups + + // - search for all tokesn and find the first word token tbat matchs w + virtual bool findToken( const word & w ); + + + // - search for all tokesn and find the first word token tbat matchs + virtual bool findTokenSilent( const word & w, int32 limitLine = 100 ); + + // - search for all tokens and find the first word token and also next word token + // chekck if it i seneded with end statement ; + virtual bool findTokenAndNext( const word& w, word& nextW, bool checkEndStatement = true); + + + virtual bool findTokenAndNextSilent( const word& w, word& nextW, int32 limitLine = 100); + + // - find a pair of keyword and data terminated by ; + // keyword data; + // return false if keyword does not exist or reading fails. + template + bool findKeywordAndVal(const word& keyword, T& val, bool checkEndStatement = true); + + // - lookup for keyword and data; + // fatalExit if fails + template + T lookupData(const word& keyword); + + // - lookup for keyword and data; + // set to setVal if lookup fails. + template + T lookupDataOrSet(const word& keyword, const T& setVal); + + // - read the data next to keword + // keyword data; + // check the keyword is correct or not + template + bool nextData(const word& keyword, T& data); + + //// Read List punctuation tokens + + //- Begin read of data chunk, starts with '('. + // return true or FatalIOError + bool readBegin(const char* funcName); + + //- End read of data chunk, ends with ')' + // return true or FatalIOError + bool readEnd(const char* funcName); + + //- Begin read of data chunk, starts with '('. + // return true or FatalIOError + bool readBeginSquare(const char* funcName); + + //- Begin read of data chunk, starts with '('. + // return true or FatalIOError + bool readEndSquare(const char* funcName); + + //- Begin read of list data, starts with '(' or '{' + // return starting delimiter or FatalIOError + char readBeginList(const char* funcName); + + //- End read of list data, ends with ')' or '}' + // return closing delimiter or FatalIOError + char readEndList(const char* funcName); + + // End statement character ; + char readEndStatement(const char* funcName); + + + iIstream& operator()() const; + +}; + + +typedef iIstream& (*iIstreamManip)(iIstream&); + +//- operator>> handling for manipulators without arguments +inline iIstream& operator>>(iIstream& is, iIstreamManip f) +{ + return f(is); +} + +//- operator>> handling for manipulators without arguments +inline iIstream& operator>>(iIstream& is, IOstreamManip f) +{ + f(is); + return is; +} + + +// read operation for basic types it gets from the +// token stream + +inline iIstream& operator>>( iIstream& is, word & w); + +inline iIstream& operator>>( iIstream& is, int64& val); + +inline iIstream& operator>>( iIstream& is, int32& val); + +inline iIstream& operator>>( iIstream& is, int16& val); + +inline iIstream& operator>>( iIstream& is, int8& val); + +inline iIstream& operator>>( iIstream& is, uint32& val); + +inline iIstream& operator>>( iIstream& is, uint16& val); + +inline iIstream& operator>>( iIstream& is, label& val); + +inline iIstream& operator>>( iIstream& is, float& val); + +inline iIstream& operator>>( iIstream& is, double& val); + + + +} // pFlow + + +#include "iIstreamI.H" + + +#endif diff --git a/src/phasicFlow/streams/iStream/iIstreamI.H b/src/phasicFlow/streams/iStream/iIstreamI.H new file mode 100755 index 00000000..f8cea3d3 --- /dev/null +++ b/src/phasicFlow/streams/iStream/iIstreamI.H @@ -0,0 +1,304 @@ +/*------------------------------- phasicFlow --------------------------------- + O C enter of + O O E ngineering and + O O M ultiscale modeling of + OOOOOOO F luid flow +------------------------------------------------------------------------------ + Copyright (C): www.cemf.ir + email: hamid.r.norouzi AT gmail.com +------------------------------------------------------------------------------ +Licence: + This file is part of phasicFlow code. It is a free software for simulating + granular and multiphase flows. You can redistribute it and/or modify it under + the terms of GNU General Public License v3 or any other later versions. + + phasicFlow is distributed to help others in their research in the field of + granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +-----------------------------------------------------------------------------*/ + + +// * * * * * * * * * * * * * * templates * * * * * * * * * * * * * * * * *// +template +bool pFlow::iIstream::findKeywordAndVal(const word& keyword, T& val, bool checkEndStatement) +{ + if( findToken(keyword) ) + { + iIstream& is = *this; + is >> val; + + if( checkEndStatement ) + { + token next(is); + + if( !next.good() || !next.isEndStatement() ) + { + return false; + } + } + } + else + { + return false; + } + + return true; +} + + +template +T pFlow::iIstream::lookupData +( + const word& keyword +) +{ + T val; + if( !findKeywordAndVal(keyword, val) ) + { + ioErrorInFile( name(), lineNumber() )<< + " error in finding keyword "<< keyword <<" and value next to it."; + fatalExit; + } + + return val; +} + +template +T pFlow::iIstream::lookupDataOrSet(const word& keyword, const T& setVal) +{ + T val; + + if(!findKeywordAndVal(keyword, val)) + { + val = setVal; + } + + return val; +} + +template +bool pFlow::iIstream::nextData(const word& keyword, T& data) +{ + + token next; + + if( !eof() && good() ) + { + read(next); + if(next.error()) + { + ioErrorInFile(name(), lineNumber()); + return false; + } + + if( !next.isWord() ) + { + ioErrorInFile(name(), lineNumber())<< + " expected word token."; + return false; + } + if(next.wordToken() != keyword) + { + ioErrorInFile(name(), lineNumber())<< + " expected keyword "<< keyword << " but found "<> data; + + read(next); + + if( !next.good() || !next.isEndStatement() ) + { + ioErrorInFile(name(),lineNumber())<< + " expected ; but found "<< next<>(iIstream& is, word & w) +{ + token t(is); + if (!t.good()) + { + ioErrorInFile(is.name(), is.lineNumber()) + << "Bad token - could not get word/string value"; + fatalExit; + is.setBad(); + return is; + } + + if (t.isString()) + { + w = t.stringToken(); + } + else if(t.isWord() ) + { + w = t.wordToken(); + } + else + { + ioErrorInFile(is.name(), is.lineNumber()) + << "Wrong token type - expected word/string value, found " + << t; + fatalExit; + is.setBad(); + return is; + } + + is.check(FUNCTION_NAME); + return is; +} + +inline pFlow::iIstream& pFlow::operator>>( iIstream& is, int64& val) +{ + token t(is); + + if (!t.good()) + { + ioErrorInFile(is.name(), is.lineNumber()) + << "Bad token - could not get int64 value"; + fatalExit; + is.setBad(); + return is; + } + + if (t.isNumber()) + { + val = t.number(); + } + else + { + ioErrorInFile(is.name(), is.lineNumber()) + << "Wrong token type - expected int64 value, found " + << t; + fatalExit; + is.setBad(); + return is; + + } + + is.check(FUNCTION_NAME); + return is; +} + +inline pFlow::iIstream& pFlow::operator>>( iIstream& is, int32& val) +{ + int64 lval(0); + is>>lval; + val = static_cast(lval); + return is; +} + +inline pFlow::iIstream& pFlow::operator>>( iIstream& is, int16& val) +{ + int64 lval(0); + is>>lval; + val = static_cast(lval); + return is; +} + +inline pFlow::iIstream& pFlow::operator>>( iIstream& is, int8& val) +{ + int64 lval(0); + is>>lval; + val = static_cast(lval); + return is; +} + +inline pFlow::iIstream& pFlow::operator>>( iIstream& is, label& val) +{ + int64 lval(0); + is>>lval; + val = static_cast