added streams and fileSystem

This commit is contained in:
hamidrezanorouzi 2022-09-01 13:27:42 +04:30
parent bf4ff2503e
commit 908a2217cf
31 changed files with 7100 additions and 0 deletions

View File

@ -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()<<endl;
fatalExit;
}
}
pFlow::fileSystem::fileSystem( const char* dir, const char* file)
:
fileSystem(word(dir),word(file))
{
}
pFlow::fileSystem::fileSystem( const pathType& path )
:
path_(path)
{
isDir_ = isDirectory(*this);
}
pFlow::fileSystem pFlow::fileSystem::dirPath() const
{
if( isDir())
{
return *this;
}
else
{
return fileSystem(path_.parent_path().c_str());
}
}
pFlow::word pFlow::fileSystem::fileName() const
{
if( isDir())
return word("");
try
{
return word( path_.filename());
}
catch (std::filesystem::filesystem_error & ec)
{
fatalErrorInFunction<<
ec.what()<<endl;
fatalExit;
}
return word("");
}
pFlow::fileSystem pFlow::fileSystem::absolute
(
) const
{
std::error_code ec;
pathType abPath;
if( abPath = std::filesystem::absolute( path_, ec); ec )
{
fatalErrorInFunction <<
"The absolute path of "<< path_.c_str() <<" is invalid: "<<
ec.message()<<endl;
fatalExit;
}
fileSystem res;
res.path_ = abPath;
res.isDir_ = isDir_;
return res;
}
pFlow::fileSystem pFlow::fileSystem::canonical
(
)const
{
std::error_code ec;
pathType cnPath;
if( cnPath = std::filesystem::canonical( path_, ec); ec )
{
fatalErrorInFunction <<
"The canonical path of "<< path_.c_str() <<" cannot be obtained: "<<
ec.message()<<endl;
fatalExit;
}
fileSystem res;
res.path_ = cnPath;
res.isDir_ = isDir_;
return res;
}
bool pFlow::fileSystem::dirExist
(
) const
{
if(!isDir())
{
fatalErrorInFunction<<
"This function only operates on dir path, the path is "<<
path_.c_str()<<endl;
fatalExit;
return false;
}
return exist();
}
bool pFlow::fileSystem::exist
(
)const
{
try
{
return std::filesystem::exists(path_);
}
catch (std::filesystem::filesystem_error & ec)
{
fatalErrorInFunction<<
ec.what()<<endl;
fatalExit;
return false;
}
}
pFlow::fileSystem pFlow::fileSystem::createDirs
(
) const
{
if(! isDir())
{
fatalErrorInFunction<<
"This function only operates on dir path, the path is "<<
path_.c_str()<<endl;
fatalExit;
}
try
{
std::filesystem::create_directories(path_);
return canonical();
}
catch (std::filesystem::filesystem_error & ec)
{
fatalErrorInFunction<<
ec.what()<<endl;
fatalExit;
return *this;
}
}
pFlow::fileSystem pFlow::fileSystem::operator()
(
bool retDir
) const
{
if(retDir)
return dirPath();
else
return *this;
}
void pFlow::fileSystem::operator += (const word& fileName)
{
checkFileName(fileName);
if( isDir())
{
path_ /= fileName;
isDir_ = false;
}
else
{
path_ = path_.parent_path()/fileName;
}
}
void pFlow::fileSystem::operator /=
(
const fileSystem& fs
)
{
if(!isDir())
{
fatalErrorInFunction<<
"This operator should be used on dir path only"<<endl;
fatalExit;
}
path_/= fs.dirPath().path_;
}
pFlow::fileSystem pFlow::operator /
(
const fileSystem& fs1,
const fileSystem& fs2
)
{
fileSystem::pathType cmbPath(fs1.dirPath().path_ / fs2.dirPath().path_);
return fileSystem( cmbPath.c_str() );
}
pFlow::fileSystem pFlow::operator +
(
const fileSystem& fs1,
const word fName
)
{
fileSystem path = fs1;
path+= fName;
return path;
}
pFlow::iOstream& pFlow::operator << (iOstream& os, fileSystem fs)
{
os << fs.path_.c_str();
return os;
}
std::ostream& pFlow::operator << (std::ostream& os, fileSystem fs)
{
os << fs.path_.c_str();
return os;
}
bool pFlow::isDirectory
(
const fileSystem& path
)
{
return std::filesystem::is_directory(path.path());
}
bool pFlow::isRegularFile(const fileSystem& path)
{
return std::filesystem::is_regular_file(path.path());
}
pFlow::fileSystemList pFlow::subDirectories
(
const fileSystem& path
)
{
fileSystemList dirs;
if( isDirectory(path) )
{
auto dOps = std::filesystem::directory_options::skip_permission_denied;
for( auto& subPath: std::filesystem::directory_iterator(path.path(), dOps) )
{
if(isDirectory( subPath.path() ) )
{
dirs.emplace_back(subPath.path());
}
}
}
return dirs;
}
pFlow::fileSystemList pFlow::containingFiles
(
const fileSystem& path
)
{
fileSystemList files;
if( isDirectory(path) )
{
auto dOps = std::filesystem::directory_options::skip_permission_denied;
for( auto& subPath: std::filesystem::directory_iterator(path.path(), dOps) )
{
if( std::filesystem::is_regular_file(subPath.path()) )
{
files.emplace_back(subPath.path());
}
}
}
return files;
}

View File

@ -0,0 +1,201 @@
/*------------------------------- 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 __fileSystem_H__
#define __fileSystem_H__
#include <filesystem>
#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<fileSystem>;
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

View File

@ -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<std::ifstream>( 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_();
}

View File

@ -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 <fstream>
#include "fileSystem.H"
#include "uniquePtr.H"
namespace pFlow
{
class fileStream
{
protected:
// - in file stream
uniquePtr<std::ifstream> inStream_;
// - out file stream
uniquePtr<std::ofstream> 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

View File

@ -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())
{
}

View File

@ -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

View File

@ -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())
{
}

View File

@ -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

View File

@ -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<int32>(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<int32>(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<int32>(nChar) << " characters\n";
fatalExit;
ioErrorInFile(name(), lineNumber());
return *this;
}
if (depth)
{
warningInFunction
<< "Missing " << static_cast<int32>(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<std::streamsize>::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<int32>(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<int32>(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<int32>(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<int32>(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<int32>(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);
}
// ************************************************************************* //

View File

@ -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 <limits>
#include <iostream>
#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

View File

@ -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);
}
// ************************************************************************* //

View File

@ -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 <iostream>
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

View File

@ -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__

View File

@ -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();
}
// ************************************************************************* //

View File

@ -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
// ************************************************************************* //

View File

@ -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<int64>(val))); // tokenType::INT64
return *this;
}
dFlow::iOstream& dFlow::oTstream::write(const uint32 val)
{
append(token(static_cast<int64>(val))); // tokenType::INT64
return *this;
}
dFlow::iOstream& dFlow::oTstream::write(const uint16 val)
{
append(token(static_cast<int64>(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();
}
// ************************************************************************* //

View File

@ -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
// ************************************************************************* //

View File

@ -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;
}

View File

@ -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 <iostream>
#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__

View File

@ -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()<<endl;
return false;
}
if( next.isWord() )
{
if(next.wordToken() == w) return true;
}
}
return false;
}
bool dFlow::iIstream::findTokenSilent( const word & w, int32 limitLine )
{
rewind();
token next;
while( !eof() && good() && lineNumber()<limitLine )
{
read(next);
if(next.error())
{
return false;
}
if( next.isWord() )
{
if(next.wordToken() == w) return true;
}
}
return false;
}
bool dFlow::iIstream::findTokenAndNext
(
const word& w,
word& nextW,
bool checkEndStatement
)
{
if( findToken(w) )
{
// next token
token next(*this);
if(next.error())
{
ioErrorInFile( name(), lineNumber());
return false;
}
if( next.isWord() )
{
nextW = next.wordToken();
if( checkEndStatement )
{
read(next);
if( !next.isEndStatement() )
{
ioErrorInFile(name(), lineNumber()) <<
" expected ; but found " << next;
return false;
}
}
return true;
}else
{
ioErrorInFile( name(), lineNumber() ) <<
" token is not a word" << next <<endl;
return false;
}
}
return false;
}
bool dFlow::iIstream::findTokenAndNextSilent(const word& w, word& nextW, int32 limitLine)
{
if( findTokenSilent(w, limitLine) )
{
// next token
token next(*this);
if(next.error())
{
return false;
}
if( next.isWord() )
{
nextW = next.wordToken();
read(next);
if( !next.isEndStatement() )
{
return false;
}
return true;
}else
{
return false;
}
}
return false;
}
bool dFlow::iIstream::readBegin(const char* funcName)
{
const token delimiter(*this);
if (delimiter != token::BEGIN_LIST)
{
setBad();
ioErrorInFile( name(), lineNumber() )
<< "Expected a '" << token::BEGIN_LIST
<< "' while reading " << funcName
<< ", found " << delimiter << endl;
fatalExit;
}
return true;
}
bool dFlow::iIstream::readEnd(const char* funcName)
{
const token delimiter(*this);
if (delimiter != token::END_LIST)
{
setBad();
ioErrorInFile( name(), lineNumber())
<< "Expected a '" << token::END_LIST
<< "' while reading " << funcName
<< ", found "
<< delimiter <<endl;
fatalExit;
}
return true;
}
bool dFlow::iIstream::readBeginSquare(const char* funcName)
{
const token delimiter(*this);
if (delimiter != token::BEGIN_SQR)
{
setBad();
ioErrorInFile( name(), lineNumber())
<< "Expected a '" << token::BEGIN_SQR
<< "' while reading " << funcName
<< ", found "
<< delimiter <<endl;
fatalExit;
}
return true;
}
bool dFlow::iIstream::readEndSquare(const char* funcName)
{
const token delimiter(*this);
if (delimiter != token::END_SQR)
{
setBad();
ioErrorInFile( name(), lineNumber())
<< "Expected a '" << token::END_SQR
<< "' while reading " << funcName
<< ", found "
<< delimiter <<endl;
fatalExit;
}
return true;
}
char dFlow::iIstream::readBeginList(const char* funcName)
{
const token delimiter(*this);
if (delimiter != token::BEGIN_LIST && delimiter != token::BEGIN_BLOCK)
{
setBad();
ioErrorInFile( name(), lineNumber() )
<< "Expected a '" << token::BEGIN_LIST
<< "' or a '" << token::BEGIN_BLOCK
<< "' while reading " << funcName
<< ", found " << delimiter<<endl;
fatalExit;
return '\0';
}
return delimiter.pToken();
}
char dFlow::iIstream::readEndList(const char* funcName)
{
const token delimiter(*this);
if (delimiter != token::END_LIST && delimiter != token::END_BLOCK)
{
setBad();
ioErrorInFile( name(), lineNumber() )
<< "Expected a '" << token::END_LIST
<< "' or a '" << token::END_BLOCK
<< "' while reading " << funcName
<< ", found " << delimiter
<< " at stream position " << endl;
fatalExit;
return '\0';
}
return delimiter.pToken();
}
char dFlow::iIstream::readEndStatement(const char* funcName)
{
CONSUME_PARAM(funcName);
const token delimiter(*this);
if (!delimiter.isEndStatement())
{
setBad();
ioErrorInFile( name(), lineNumber() ) <<
" expected ; but found " << delimiter << endl;
fatalExit;
return '\0';
}
return delimiter.pToken();
}
dFlow::iIstream& dFlow::iIstream::operator()() const
{
if (!good())
{
check("iIstream::operator()");
fatalExit;
}
return const_cast<iIstream&>(*this);
}

View File

@ -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<typename T>
bool findKeywordAndVal(const word& keyword, T& val, bool checkEndStatement = true);
// - lookup for keyword and data;
// fatalExit if fails
template<typename T>
T lookupData(const word& keyword);
// - lookup for keyword and data;
// set to setVal if lookup fails.
template<typename T>
T lookupDataOrSet(const word& keyword, const T& setVal);
// - read the data next to keword
// keyword data;
// check the keyword is correct or not
template<typename T>
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

View File

@ -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<typename T>
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<typename T>
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<typename T>
T pFlow::iIstream::lookupDataOrSet(const word& keyword, const T& setVal)
{
T val;
if(!findKeywordAndVal(keyword, val))
{
val = setVal;
}
return val;
}
template<typename T>
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 "<<next.wordToken()<<endl;
return false;
}
iIstream& is = *this;
is >> data;
read(next);
if( !next.good() || !next.isEndStatement() )
{
ioErrorInFile(name(),lineNumber())<<
" expected ; but found "<< next<<endl;
return false;
}
return true;
}
return false;
}
// * * * * * * * * * * * * * * IO operations * * * * * * * * * * * * * * * * *//
inline pFlow::iIstream& pFlow::operator>>(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<int32>(lval);
return is;
}
inline pFlow::iIstream& pFlow::operator>>( iIstream& is, int16& val)
{
int64 lval(0);
is>>lval;
val = static_cast<int16>(lval);
return is;
}
inline pFlow::iIstream& pFlow::operator>>( iIstream& is, int8& val)
{
int64 lval(0);
is>>lval;
val = static_cast<int8>(lval);
return is;
}
inline pFlow::iIstream& pFlow::operator>>( iIstream& is, label& val)
{
int64 lval(0);
is>>lval;
val = static_cast<label>(lval);
return is;
}
inline pFlow::iIstream& pFlow::operator>>( iIstream& is, uint32& val)
{
int64 lval(0);
is>>lval;
val = static_cast<uint32>(lval);
return is;
}
inline pFlow::iIstream& pFlow::operator>>( iIstream& is, uint16& val)
{
int64 lval(0);
is>>lval;
val = static_cast<uint16>(lval);
return is;
}
inline pFlow::iIstream& pFlow::operator>>( iIstream& is, float& val)
{
token t(is);
if (!t.good())
{
ioErrorInFile(is.name(), is.lineNumber())
<< "Bad token - could not get float value";
fatalExit;
is.setBad();
return is;
}
if (t.isNumber())
{
val = t.number();
}
else
{
ioErrorInFile(is.name(), is.lineNumber())
<< "Wrong token type - expected float value, found "
<< t;
fatalExit;
is.setBad();
return is;
}
is.check(FUNCTION_NAME);
return is;
}
inline pFlow::iIstream& pFlow::operator>>( iIstream& is, double& val)
{
token t(is);
if (!t.good())
{
ioErrorInFile(is.name(), is.lineNumber())
<< "Bad token - could not get double value";
fatalExit;
is.setBad();
return is;
}
if (t.isNumber())
{
val = t.number();
}
else
{
ioErrorInFile(is.name(), is.lineNumber())
<< "Wrong token type - expected double value, found "
<< t;
fatalExit;
is.setBad();
return is;
}
is.check(FUNCTION_NAME);
return is;
}

View File

@ -0,0 +1,180 @@
/*------------------------------- 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 "token.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void pFlow::iOstream::decrIndent()
{
if (!indentLevel_)
{
std::cerr
<< "iOstream::decrIndent() : attempt to decrement 0 indent level\n";
}
else
{
--indentLevel_;
}
}
pFlow::iOstream& pFlow::iOstream::writeWordKeyword(const word& kw)
{
indent();
writeQuoted(kw, false);
if (indentSize_ <= 1)
{
write(char(token::SPACE));
return *this;
}
int32 nSpaces = entryIndentation_ - int32(kw.size());
// Could also increment by indentSize_ ...
if (nSpaces < 1)
{
nSpaces = 1;
}
while (nSpaces--)
{
write(char(token::SPACE));
}
return *this;
}
pFlow::iOstream& pFlow::iOstream::beginBlock(const word& kw)
{
indent(); write(kw); newLine();
beginBlock();
return *this;
}
pFlow::iOstream& pFlow::iOstream::beginBlock()
{
indent(); write(char(token::BEGIN_BLOCK)); newLine();
incrIndent();
return *this;
}
pFlow::iOstream& pFlow::iOstream::endBlock()
{
decrIndent();
indent(); write(char(token::END_BLOCK)); newLine();
return *this;
}
pFlow::iOstream& pFlow::iOstream::endEntry()
{
write(char(token::END_STATEMENT)); newLine();
return *this;
}
//- Write a newLine to stream
pFlow::iOstream& pFlow::iOstream::newLine()
{
write(char(token::NL));
return *this;
}
pFlow::iOstream& pFlow::iOstream::space
(
int32 n
)
{
for(int32 i=0; i<n; i++)
{
write(char(token::SPACE));
}
return *this;
}
pFlow::iOstream& pFlow::iOstream::beginList
(
)
{
write(char(token::BEGIN_LIST));
return *this;
}
pFlow::iOstream& pFlow::iOstream::beginList
(
const word& kw
)
{
writeWordKeyword(kw); beginList();
return *this;
}
pFlow::iOstream& pFlow::iOstream::endList
(
)
{
write(char(token::END_LIST));
return *this;
}
pFlow::iOstream& pFlow::iOstream::beginSquare
(
)
{
write(char(token::BEGIN_SQR));
return *this;
}
pFlow::iOstream& pFlow::iOstream::beginSquare
(
const word& kw
)
{
writeWordKeyword(kw); beginSquare();
return *this;
}
pFlow::iOstream& pFlow::iOstream::endSquare
(
)
{
write(char(token::END_SQR));
return *this;
}
// ************************************************************************* //

View File

@ -0,0 +1,419 @@
/*------------------------------- 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 "IOstream.H"
const inline char* defaultColor = "\033[0m";
const inline char* blackColor = "\033[30m";
const inline char* redColor = "\033[31m";
const inline char* greenColor = "\033[32m";
const inline char* yellowColor = "\033[33m";
const inline char* blueColor = "\033[34m";
const inline char* magentaColor = "\033[35m";
const inline char* cyanColor = "\033[36m";
const inline char* whiteColor = "\033[37m";
const inline char* boldChar = "\033[1m";
namespace pFlow
{
// Forward Declarations
class token;
class iOstream
:
public IOstream
{
protected:
// Protected Data
//- Indentation of the entry from the start of the keyword
static constexpr const unsigned short entryIndentation_ = 16;
//- Number of spaces per indent level
unsigned short indentSize_ = 4;
//- Current indent level
unsigned short indentLevel_ = 0;
public:
// Constructor
explicit iOstream()
{}
//- Copy construct
iOstream(const iOstream&) = default;
//- Destructor
virtual ~iOstream() = default;
// Write Functions
//- 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) = 0;
//- Write character
virtual iOstream& write(const char c) = 0;
//- Write character string
virtual iOstream& write(const char* str) = 0;
//- Write word
virtual iOstream& write(const word& str) = 0;
//- Write std::string surrounded by quotes.
// Optional write without quotes.
virtual iOstream& writeQuoted
(
const word& str,
const bool quoted=true
) = 0;
//- Write int64
virtual iOstream& write(const int64 val) = 0;
//- Write int32
virtual iOstream& write(const int32 val) = 0;
//- Write label
virtual iOstream& write(const label val) = 0;
//- Write uint32
virtual iOstream& write(const uint32 val) = 0;
//- Write uint16
virtual iOstream& write(const uint16 val) = 0;
//- Write float
virtual iOstream& write(const float val) = 0;
//- Write double
virtual iOstream& write(const double val) = 0;
//- Add indentation characters
virtual void indent() = 0;
//- Return indent level
unsigned short indentSize() const
{
return indentSize_;
}
//- Access to indent size
unsigned short& indentSize()
{
return indentSize_;
}
//- Return indent level
unsigned short indentLevel() const
{
return indentLevel_;
}
//- Access to indent level
unsigned short& indentLevel()
{
return indentLevel_;
}
//- Increment the indent level
void incrIndent()
{
++indentLevel_;
}
//- Decrement the indent level
void decrIndent();
//- Write begin block group with a name
// Increments indentation, adds newline.
virtual iOstream& beginBlock(const word& kw);
//- Write begin block group without a name
// Increments indentation, adds newline.
virtual iOstream& beginBlock();
//- Write end block group
// Decrements indentation, adds newline.
virtual iOstream& endBlock();
//- Write begin list "("
virtual iOstream& beginList();
//- Write begin list with keyword "kw ("
virtual iOstream& beginList(const word& kw);
//- Write end list ")"
virtual iOstream& endList();
//- Write begin list "["
virtual iOstream& beginSquare();
//- Write begin list with keyword "kw ["
virtual iOstream& beginSquare(const word& kw);
//- Write end list "]"
virtual iOstream& endSquare();
//- Write end entry (';') followed by newline.
virtual iOstream& endEntry();
//- Write a newLine to stream
virtual iOstream& newLine();
//- Write space to stream
virtual iOstream& space(int32 n=1);
//- Write the keyword followed by an appropriate indentation
virtual iOstream& writeWordKeyword(const word& kw);
//- Write a keyword/value entry.
template<class T>
iOstream& writeWordEntry(const word& key, const T& value)
{
writeWordKeyword(key) << value;
return endEntry();
}
//// Stream state functions
//- Flush stream
virtual void flush() = 0;
//- Add newline and flush stream
virtual void endl() = 0;
//- Get padding character
virtual char fill() const = 0;
//- Set padding character for formatted field up to field width
virtual char fill(const char fillch) = 0;
//- Get width of output field
virtual int width() const = 0;
//- Set width of output field (and return old width)
virtual int width(const int w) = 0;
//- Get precision of output field
virtual int precision() const = 0;
//- Set precision of output field (and return old precision)
virtual int precision(const int p) = 0;
// Member Operators
//- Return a non-const reference to const iOstream
// Needed for write functions where the stream argument is temporary:
// e.g. thing thisThing(OFstream("thingFileName")());
iOstream& operator()() const
{
return const_cast<iOstream&>(*this);
}
};
//- An iOstream manipulator
typedef iOstream& (*iOstreamManip)(iOstream&);
//- operator<< handling for manipulators without arguments
inline iOstream& operator<<(iOstream& os, iOstreamManip f)
{
return f(os);
}
//- operator<< handling for manipulators without arguments
inline iOstream& operator<<(iOstream& os, IOstreamManip f)
{
f(os);
return os;
}
//- Indent stream
inline iOstream& indent(iOstream& os)
{
os.indent();
return os;
}
//- Increment the indent level
inline iOstream& incrIndent(iOstream& os)
{
os.incrIndent();
return os;
}
//- Decrement the indent level
inline iOstream& decrIndent(iOstream& os)
{
os.decrIndent();
return os;
}
//- Flush stream
inline iOstream& flush(iOstream& os)
{
os.flush();
return os;
}
//- Add newline and flush stream
inline iOstream& endl(iOstream& os)
{
os.endl();
return os;
}
//- Write begin block group without a name
// Increments indentation, adds newline.
inline iOstream& beginBlock(iOstream& os)
{
os.beginBlock();
return os;
}
//- Write end block group
// Decrements indentation, adds newline.
inline iOstream& endBlock(iOstream& os)
{
os.endBlock();
return os;
}
//- Write end entry (';') followed by newline.
inline iOstream& endEntry(iOstream& os)
{
os.endEntry();
return os;
}
// overloading for basic types
inline iOstream& operator<<( iOstream& os, const char c)
{
return os.write(c);
}
inline iOstream& operator<<( iOstream& os, const char * buf)
{
return os.write(buf);
}
inline iOstream& operator<<( iOstream& os, const word& w)
{
return os.write(w);
}
inline iOstream& operator<<( iOstream& os, const int64& val)
{
return os.write(val);
}
inline iOstream& operator<<( iOstream& os, const int32& val)
{
return os.write(val);
}
inline iOstream& operator<<( iOstream& os, const int16& val)
{
return os.write(val);
}
inline iOstream& operator<<( iOstream& os, const int8& val)
{
return os.write(val);
}
inline iOstream& operator<<( iOstream& os, const label& val)
{
return os.write(val);
}
inline iOstream& operator<<( iOstream& os, const uint32& val)
{
return os.write(val);
}
inline iOstream& operator<<( iOstream& os, const uint16& val)
{
return os.write(val);
}
inline iOstream& operator<<( iOstream& os, const float& val)
{
return os.write(val);
}
inline iOstream& operator<<( iOstream& os, const double& val)
{
return os.write(val);
}
// Useful aliases for tab and newline characters
constexpr char tab = '\t';
constexpr char nl = '\n';
} // pFlow
#endif
// ************************************************************************* //

View File

@ -0,0 +1,8 @@
#include "streams.H"
dFlow::Ostream dFlow::output(std::cout, "dFlow Ostream");
dFlow::Istream dFlow::input( std::cin, "sFlow Istream");
dFlow::Ostream dFlow::errReport( std::cerr, "dFlow error report stream");

View File

@ -0,0 +1,49 @@
#ifndef __streams_H__
#define __streams_H__
#include "Istream.H"
#include "Ostream.H"
#include "iFstream.H"
#include "oFstream.H"
#include "oTstream.H"
#include "iTstream.H"
namespace dFlow
{
extern Ostream output;
extern Istream input;
extern Ostream errReport;
}
#define redText(text) redColor<<text<<defaultColor
#define yellowText(text) yellowColor<<text<<defaultColor
#define blueText(text) blueColor<<text<<defaultColor
#define greenText(text) greenColor<<text<<defaultColor
#define magentaText(text) magentaColor<<text<<defaultColor
#define cyanText(text) cyanColor<<text<<defaultColor
#define boldText(text) boldChar<<text<<defaultColor
#define Info dFlow::output<<boldChar<<magentaColor<<"> Info: "<<defaultColor<<magentaColor
#define endInfo defaultColor<<dFlow::nl
#define Report(n) dFlow::output.space(2*n)
#define endReport dFlow::nl
#define Warning dFlow::output<<boldChar<<yellowColor<<"> Warning\n"<<defaultColor<<yellowColor<<" "
#define endWarning defaultColor<<dFlow::nl
#define Err dFlow::output<<boldChar<<redColor<<"> Error\n"<<defaultColor<<redColor<<" "
#define endErr defaultColor<<dFlow::nl
#endif

View File

@ -0,0 +1,39 @@
/*------------------------------- 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 "token.H"
#include "error.H"
#include "iOstream.H"
void pFlow::token::parseError(const char* expected) const
{
fatalError
<< "Parse error, expected a " << expected
<< ", found \n " << *this << endl;
}

View File

@ -0,0 +1,542 @@
/*------------------------------- 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 __token_H__
#define __token_H__
#include "bTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace pFlow
{
// Forward Declarations
class token;
class iIstream;
class iOstream;
iOstream& operator<<(iOstream& os, const token& tok);
class token
{
public:
//- Enumeration defining the types of token.
// Since these values are also used to tag content in Pstream,
// the maximum number of types is limited to 30.
enum tokenType
{
UNDEFINED = 0, //!< An undefined token-type
// Fundamental types
FLAG, //!< stream flag (1-byte bitmask)
PUNCTUATION, //!< single character punctuation
BOOL, //!< boolean type
INT64, //!< int64 (integer) type
FLOAT, //!< float (single-precision) type
DOUBLE, //!< double (double-precision) type
// Pointer types
WORD, //!< A pFlow::word
STRING, //!< A string whth double quuote
DIRECTIVE, //!< A dictionary \c \#directive (word variant)
VARIABLE, //!< A dictionary \c \$variable (string variant)
ERROR, //!< A token error encountered
};
//**************- Stream or output control flags (1-byte width)
enum flagType
{
NO_FLAG = 0, //!< No flags
ASCII = 1, //!< ASCII-mode stream
BINARY = 2 //!< BINARY-mode stream
};
//- Standard punctuation tokens (a character)
enum punctuationToken : char
{
NULL_TOKEN = '\0', //!< Nul character
SPACE = ' ', //!< Space [isspace]
TAB = '\t', //!< Tab [isspace]
NL = '\n', //!< Newline [isspace]
END_STATEMENT = ';', //!< End entry [#isseparator]
BEGIN_LIST = '(', //!< Begin list [#isseparator]
END_LIST = ')', //!< End list [#isseparator]
BEGIN_SQR = '[', //!< Begin dimensions [#isseparator]
END_SQR = ']', //!< End dimensions [#isseparator]
BEGIN_BLOCK = '{', //!< Begin block [#isseparator]
END_BLOCK = '}', //!< End block [#isseparator]
COLON = ':', //!< Colon [#isseparator]
COMMA = ',', //!< Comma [#isseparator]
DOLLAR = '$', //!< Dollar - start variable
SQUOTE = '\'', //!< Single quote
DQUOTE = '"', //!< Double quote
SUBTRACT = '-', //!< Subtract or start of negative number
DIVIDE = '/', //!< Divide [#isseparator]
BEGIN_STRING = DQUOTE, //!< Begin string with double quote
END_STRING = DQUOTE //!< End string with double quote
};
//- An undefined token
static const inline token undefinedToken();
static token endList()
{
return token(punctuationToken::END_LIST);
}
static token beginList()
{
return token(punctuationToken::BEGIN_LIST);
}
static token endStatement()
{
return token(punctuationToken::END_STATEMENT);
}
static token beginBlock()
{
return token(punctuationToken::BEGIN_BLOCK);
}
static token endBlocK()
{
return token(punctuationToken::END_BLOCK);
}
static token beginSquare()
{
return token(punctuationToken::BEGIN_SQR);
}
static token endSquare()
{
return token(punctuationToken::END_SQR);
}
static token space()
{
return token(punctuationToken::SPACE);
}
static token newLine()
{
return token(punctuationToken::NL);
}
private:
//- A %union of token types
union content
{
// Fundamental values. Largest first for any {} initialization.
int64_t int64Val;
int flagVal; // bitmask - stored as int, not enum
punctuationToken punctuationVal;
float floatVal;
double doubleVal;
// Pointers
word* wordPtr;
word* stringPtr;
};
// Private Data
//- The data content (as a union).
// For memory alignment this should appear as the first member.
content data_;
//- The token type
tokenType type_;
//- Line number in the file the token was read from
int32 lineNumber_;
// Private Member Functions
//- Set as UNDEFINED and zero the union content without any checking
inline void setUndefined();
// Parse error, expected 'expected', found ...
void parseError(const char* expected) const;
public:
// Static Data Members
// Constructors
//- Default construct, initialized to an UNDEFINED token.
inline constexpr token() noexcept;
//- Copy construct
inline token(const token& t);
//- Move construct. The original token is left as UNDEFINED.
inline token(token&& t);
//- Construct punctuation character token
inline explicit token(punctuationToken p, int32 lineNumber=0);
//- Construct label token
inline explicit token(const label val, int32 lineNumber=0);
//- Construct uint32 token
inline explicit token(const uint32 val, int32 lineNumber=0);
//- Construct int64 token
inline explicit token(const int64 val, int32 lineNumber=0);
//- Construct int64 token
inline explicit token(const int32 val, int32 lineNumber=0);
//- Construct float token
inline explicit token(const float val, int32 lineNumber=0);
//- Construct double token
inline explicit token(const double val, int32 lineNumber=0);
//- Copy construct word & string token
inline explicit token(const word& w, int32 lineNumber=0, bool isString = false);
//- Move construct word & string token
inline explicit token(word&& w, int32 lineNumber=0, bool isString = false);
//- Construct from iIstream
explicit token(iIstream& is);
//- Destructor
inline ~token();
// Static Functions
//- Create a bool token.
inline static token boolean(bool on);
//- Create a token with stream flags, no sanity check
//
// \param bitmask the flags to set
inline static token flag(int bitmask);
//- True if the character is a punctuation separator (eg, in ISstream).
// Since it could also start a number, SUBTRACT is not included as
// a separator.
//
// \param c the character to test, passed as int for consistency with
// isdigit, isspace etc.
inline static bool isseparator(int c);
// Member Functions
// Status
//- Return the name of the token type
word name() const;
//- Return the token type
inline tokenType type() const;
//- Change the token type, for similar types.
// This can be used to change between string-like variants
// (eg, STRING, VARIABLE, etc)
// To change types entirely (eg, STRING to DOUBLE),
// use the corresponding assignment operator.
//
// \return true if the change was successful or no change was required
inline bool setType(const tokenType tokType);
//- The line number for the token
inline int32 lineNumber() const;
//- The line number for the token
inline int32& lineNumber();
//- True if token is not UNDEFINED or ERROR
inline bool good() const;
//- Token is UNDEFINED
inline bool undefined() const;
//- Token is ERROR
inline bool error() const;
//- Token is BOOL
inline bool isBool() const;
//- Token is FLAG
inline bool isFlag() const;
//- Token is PUNCTUATION
inline bool isPunctuation() const;
//- Token is PUNCTUATION and isseparator
inline bool isSeparator() const;
//- Tolen is end statement
inline bool isEndStatement() const;
//- Token is INT64
inline bool isInt64() const;
//- Token is INT32
inline bool isInt32() const;
//- Token is FLOAT
inline bool isFloat() const;
//- Token is DOUBLE
inline bool isDouble() const;
//- Token is FLOAT or DOUBLE
inline bool isReal() const;
//- Token is INT64, FLOAT or DOUBLE
inline bool isNumber() const;
//- Token is WORD or DIRECTIVE word
inline bool isWord() const;
//- Token is DIRECTIVE (word variant)
inline bool isDirective() const;
//- Token is STRING, VARIABLE or VERBATIM string
inline bool isString() const;
//- Token is VARIABLE (string variant)
inline bool isVariable() const;
//- Token is WORD, DIRECTIVE, STRING, VARIABLE or VERBATIM
inline bool isStringType() const;
// Access
//- Return boolean token value.
// Report FatalIOError and return false if token is not BOOL or INT64
inline bool boolToken() const;
//- Return flag bitmask value.
// Report FatalIOError and return NO_FLAG if token is not FLAG
inline int flagToken() const;
//- Return punctuation character.
// Report FatalIOError and return \b \\0 if token is not PUNCTUATION
inline punctuationToken pToken() const;
//- Return int64 value.
// Report FatalIOError and return \b 0 if token is not INT64
inline int64 int64Token() const;
//- Return int32 value.
// Report FatalIOError and return \b 0 if token is not INT64
inline int32 int32Token() const;
//- Return float value.
// Report FatalIOError and return \b 0 if token is not FLOAT
inline float floatToken() const;
//- Return double value.
// Report FatalIOError and return \b 0 if token is not DOUBLE
inline double doubleToken() const;
//- Return float or double value.
// Report FatalIOError and return \b 0 if token is not a
// FLOAT or DOUBLE
inline real realToken() const;
//- Return int64, float or double value.
// Report FatalIOError and return \b 0 if token is not a
// INT64, FLOAT or DOUBLE
inline real number() const;
//- Return const reference to the word contents.
// Report FatalIOError and return \b "" if token is not a
// WORD or DIRECTIVE
inline const word& wordToken() const;
//- Return const reference to the string contents.
// Report FatalIOError and return \b "" if token is not a
// STRING, VARIABLE, VERBATIM or an upcast WORD or DIRECTIVE
inline const word& stringToken() const;
// Edit
//- Reset token to UNDEFINED and clear any allocated storage
inline void reset();
//- Clear token and set to be ERROR.
inline void setBad();
//- Swap token contents: type, data, line-number
inline void swap(token& tok);
// Assignment
//- Copy assign
inline void operator=(const token& tok);
//- Move assign
inline void operator=(token&& tok);
//- Copy assign from punctuation
inline void operator=(const punctuationToken p);
//- Copy assign from int64
inline void operator=(const int64 val);
//- Copy assign from int32
inline void operator=(const int32 val);
//- Copy assign from float
inline void operator=(const float val);
//- Copy assign from double
inline void operator=(const double val);
//- Copy assign from word
inline void operator=(const word& w);
//- Move assign from word
inline void operator=(word&& w);
// Equality
inline bool operator==(const token& tok) const;
inline bool operator==(const punctuationToken p) const;
inline bool operator==(const int64 val) const;
inline bool operator==(const int32 val) const;
inline bool operator==(const float val) const;
inline bool operator==(const double val) const;
inline bool operator==(const word& w) const;
// Inequality
inline bool operator!=(const token& tok) const;
inline bool operator!=(const punctuationToken p) const;
inline bool operator!=(const int64 val) const;
inline bool operator!=(const int32 val) const;
inline bool operator!=(const float val) const;
inline bool operator!=(const double val) const;
inline bool operator!=(const word& w) const;
iOstream& printInfo(iOstream& os)const;
std::ostream& printInfo(std::ostream& os)const;
// IOstream Operators
friend iOstream& operator<<(iOstream& os, const token& tok);
friend iOstream& operator<<(iOstream& os, const punctuationToken& pt);
// mostly used for debuging and developement
friend std::ostream& operator<<(std::ostream& os, const token& tok);
friend std::ostream& operator<<(std::ostream& os, const punctuationToken& pt);
void operator=(word*) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// IOstream Operators
iIstream& operator>>(iIstream& is, token& tok);
iOstream& operator<<(iOstream& os, const token::punctuationToken& pt);
std::ostream& operator<<(std::ostream& os, const token::punctuationToken& pt);
std::ostream& operator<<(std::ostream& os, const token& tok);
inline token endListToken()
{
return token::endList();
}
inline token beginListToken()
{
return token::beginList();
}
inline token endStatementToken()
{
return token::endStatement();
}
inline token beginBlockToken()
{
return token::beginBlock();
}
inline token endBlocKToken()
{
return token::endBlocK();
}
inline token spaceToken()
{
return token::space();
}
inline token newLineToken()
{
return token::newLine();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace pFlow
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "tokenI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,903 @@
/*------------------------------- 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 <algorithm>
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
inline pFlow::token pFlow::token::boolean(bool on)
{
token tok;
tok.type_ = tokenType::BOOL;
tok.data_.int64Val = on;
return tok;
}
inline pFlow::token pFlow::token::flag(int bitmask)
{
token tok;
tok.type_ = tokenType::FLAG;
tok.data_.flagVal = bitmask;
return tok;
}
inline bool pFlow::token::isseparator(int c)
{
// NOTE: keep synchronized with ISstream::read(token&)
switch (c)
{
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 :
// Excluded token::SUBTRACT since it could start a number
case token::DIVIDE :
{
return true;
}
default:
break;
}
return false;
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
inline void pFlow::token::setUndefined()
{
type_ = tokenType::UNDEFINED;
data_.int64Val = 0; // bit-wise zero for union content
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline constexpr pFlow::token::token() noexcept
:
data_(), // bit-wise zero for union content
type_(tokenType::UNDEFINED),
lineNumber_(0)
{}
inline pFlow::token::token(const token& tok)
:
data_(tok.data_), // bit-wise copy of union content
type_(tok.type_),
lineNumber_(tok.lineNumber_)
{
// Fundamental: values already handled by bit-wise copy
// Pointer: duplicate content or increase refCount
switch (type_)
{
case tokenType::WORD:
case tokenType::DIRECTIVE:
{
data_.wordPtr = new word(*tok.data_.wordPtr);
break;
}
case tokenType::STRING:
case tokenType::VARIABLE:
{
data_.stringPtr = new word(*tok.data_.stringPtr);
break;
}
default:
break;
}
}
inline pFlow::token::token(token&& tok)
:
data_(tok.data_), // bit-wise copy of union content
type_(tok.type_),
lineNumber_(tok.lineNumber_)
{
tok.setUndefined(); // zero the union content without any checking
tok.lineNumber_ = 0;
}
inline pFlow::token::token(punctuationToken p, int32 lineNumber)
:
data_(),
type_(tokenType::PUNCTUATION),
lineNumber_(lineNumber)
{
data_.punctuationVal = p;
}
inline pFlow::token::token(const label val, int32 lineNumber)
:
data_(),
type_(tokenType::INT64),
lineNumber_(lineNumber)
{
data_.int64Val = static_cast<int64>(val);
}
inline pFlow::token::token(const uint32 val, int32 lineNumber)
:
data_(),
type_(tokenType::INT64),
lineNumber_(lineNumber)
{
data_.int64Val = static_cast<int64>(val);
}
inline pFlow::token::token(const int64 val, int32 lineNumber)
:
data_(),
type_(tokenType::INT64),
lineNumber_(lineNumber)
{
data_.int64Val = val;
}
inline pFlow::token::token(const int32 val, int32 lineNumber)
:
data_(),
type_(tokenType::INT64),
lineNumber_(lineNumber)
{
data_.int64Val = static_cast<int64>(val);
}
inline pFlow::token::token(const float val, int32 lineNumber)
:
data_(),
type_(tokenType::FLOAT),
lineNumber_(lineNumber)
{
data_.floatVal = val;
}
inline pFlow::token::token(const double val, int32 lineNumber)
:
data_(),
type_(tokenType::DOUBLE),
lineNumber_(lineNumber)
{
data_.doubleVal = val;
}
inline pFlow::token::token(const word& w, int32 lineNumber, bool isString)
:
data_(),
type_(tokenType::WORD),
lineNumber_(lineNumber)
{
if(isString)
{
data_.stringPtr = new word(w);
type_ = tokenType::STRING;
} else
{
data_.wordPtr = new word(w);
}
}
inline pFlow::token::token(word&& w, int32 lineNumber, bool isString)
:
data_(),
type_(tokenType::WORD),
lineNumber_(lineNumber)
{
if(isString)
{
data_.stringPtr = new word(std::move(w));
type_ = tokenType::STRING;
} else
{
data_.wordPtr = new word(std::move(w));
}
}
inline pFlow::token::~token()
{
reset();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline void pFlow::token::reset()
{
switch (type_)
{
case tokenType::WORD:
case tokenType::DIRECTIVE:
{
delete data_.wordPtr;
break;
}
case tokenType::STRING:
case tokenType::VARIABLE:
{
delete data_.stringPtr;
break;
}
default:
break;
}
setUndefined();
}
inline void pFlow::token::swap(token& tok)
{
if (this == &tok)
{
return; // Self-swap is a no-op
}
std::swap(data_, tok.data_);
std::swap(type_, tok.type_);
std::swap(lineNumber_, tok.lineNumber_);
}
inline pFlow::token::tokenType pFlow::token::type() const
{
return type_;
}
inline bool pFlow::token::setType(token::tokenType tokType)
{
if (type_ == tokType)
{
// No change required
return true;
}
switch (tokType)
{
case tokenType::BOOL:
case tokenType::INT64:
{
switch (type_)
{
case tokenType::BOOL:
case tokenType::INT64:
type_ = tokType;
return true;
break;
default:
break;
}
}
break;
case tokenType::WORD:
case tokenType::DIRECTIVE:
{
switch (type_)
{
case tokenType::WORD:
case tokenType::DIRECTIVE:
type_ = tokType;
return true;
break;
default:
break;
}
}
break;
case tokenType::STRING:
case tokenType::VARIABLE:
{
switch (type_)
{
// could also go from WORD to STRING etc - to be decided
case tokenType::STRING:
case tokenType::VARIABLE:
type_ = tokType;
return true;
break;
default:
break;
}
}
break;
default:
break;
}
return false;
}
inline pFlow::int32 pFlow::token::lineNumber() const
{
return lineNumber_;
}
inline pFlow::int32& pFlow::token::lineNumber()
{
return lineNumber_;
}
inline bool pFlow::token::good() const
{
return (type_ != tokenType::UNDEFINED && type_ != tokenType::ERROR);
}
inline bool pFlow::token::undefined() const
{
return (type_ == tokenType::UNDEFINED);
}
inline bool pFlow::token::error() const
{
return (type_ == tokenType::ERROR);
}
inline bool pFlow::token::isBool() const
{
return (type_ == tokenType::BOOL);
}
inline bool pFlow::token::boolToken() const
{
if (type_ == tokenType::BOOL || type_ == tokenType::INT64)
{
return data_.int64Val;
}
parseError("bool");
return false;
}
inline bool pFlow::token::isFlag() const
{
return (type_ == tokenType::FLAG);
}
inline int pFlow::token::flagToken() const
{
if (type_ == tokenType::FLAG)
{
return data_.flagVal;
}
parseError("flag bitmask");
return NO_FLAG;
}
inline bool pFlow::token::isPunctuation() const
{
return (type_ == tokenType::PUNCTUATION);
}
inline bool pFlow::token::isEndStatement() const
{
if( type_ == tokenType::PUNCTUATION )
{
return pToken() == punctuationToken::END_STATEMENT;
}
return false;
}
inline pFlow::token::punctuationToken pFlow::token::pToken() const
{
if (type_ == tokenType::PUNCTUATION)
{
return data_.punctuationVal;
}
parseError("punctuation character");
return punctuationToken::NULL_TOKEN;
}
inline bool pFlow::token::isSeparator() const
{
return
(
type_ == tokenType::PUNCTUATION
&& isseparator(data_.punctuationVal)
);
}
inline bool pFlow::token::isInt64() const
{
return (type_ == tokenType::INT64);
}
inline bool pFlow::token::isInt32() const
{
return (type_ == tokenType::INT64);
}
inline pFlow::int64 pFlow::token::int64Token() const
{
if (type_ == tokenType::INT64)
{
return data_.int64Val;
}
parseError("int64");
return 0;
}
inline pFlow::int32 pFlow::token::int32Token() const
{
return static_cast<int32>(int64Token());
}
inline bool pFlow::token::isFloat() const
{
return (type_ == tokenType::FLOAT);
}
inline float pFlow::token::floatToken() const
{
if (type_ == tokenType::FLOAT)
{
return data_.floatVal;
}
parseError("float");
return 0;
}
inline bool pFlow::token::isDouble() const
{
return (type_ == tokenType::DOUBLE);
}
inline double pFlow::token::doubleToken() const
{
if (type_ == tokenType::DOUBLE)
{
return data_.doubleVal;
}
parseError("double");
return 0;
}
inline bool pFlow::token::isReal() const
{
return
(
type_ == tokenType::FLOAT
|| type_ == tokenType::DOUBLE
);
}
inline pFlow::real pFlow::token::realToken() const
{
if (type_ == tokenType::FLOAT)
{
return data_.floatVal;
}
else if (type_ == tokenType::DOUBLE)
{
return data_.doubleVal;
}
parseError("real");
return 0;
}
inline bool pFlow::token::isNumber() const
{
return (type_ == tokenType::INT64 || isReal());
}
inline pFlow::real pFlow::token::number() const
{
if (isInt64())
{
return int64Token();
}
if (isReal())
{
return realToken();
}
parseError("number (int64 or real)");
return 0;
}
inline bool pFlow::token::isWord() const
{
return
(
type_ == tokenType::WORD
|| type_ == tokenType::DIRECTIVE
);
}
inline bool pFlow::token::isDirective() const
{
return (type_ == tokenType::DIRECTIVE);
}
inline const pFlow::word& pFlow::token::wordToken() const
{
if
(
type_ == tokenType::WORD
|| type_ == tokenType::DIRECTIVE
)
{
return *data_.wordPtr;
}
parseError("word");
return nullWord;
}
inline bool pFlow::token::isString() const
{
return
(
type_ == tokenType::STRING
|| type_ == tokenType::VARIABLE
);
}
inline const pFlow::word& pFlow::token::stringToken() const
{
if
(
type_ == tokenType::STRING
|| type_ == tokenType::VARIABLE
)
{
return *data_.stringPtr;
}
else if
(
type_ == tokenType::WORD
|| type_ == tokenType::DIRECTIVE
)
{
// pFlow::word derives from pFlow::string, no need to cast.
return *data_.wordPtr;
}
parseError("string");
return nullWord;
}
inline bool pFlow::token::isVariable() const
{
return (type_ == tokenType::VARIABLE);
}
inline bool pFlow::token::isStringType() const
{
return (isWord() || isString());
}
inline void pFlow::token::setBad()
{
reset();
type_ = tokenType::ERROR;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline void pFlow::token::operator=(const token& tok)
{
if (this == &tok)
{
return; // Self-assignment is a no-op
}
reset();
type_ = tok.type_;
data_ = tok.data_; // bit-wise copy of union content
lineNumber_ = tok.lineNumber_;
// Fundamental: values already handled by bit-wise copy
// Pointer: duplicate content or increase refCount
switch (type_)
{
case tokenType::WORD:
case tokenType::DIRECTIVE:
{
data_.wordPtr = new word(*tok.data_.wordPtr);
}
break;
case tokenType::STRING:
case tokenType::VARIABLE:
{
data_.stringPtr = new word(*tok.data_.stringPtr);
}
break;
default:
break;
}
}
inline void pFlow::token::operator=(token&& tok)
{
if (this == &tok)
{
return; // Self-assignment is a no-op
}
reset();
lineNumber_ = 0;
swap(tok);
}
inline void pFlow::token::operator=(const punctuationToken p)
{
reset();
type_ = tokenType::PUNCTUATION;
data_.punctuationVal = p;
}
inline void pFlow::token::operator=(const int64 val)
{
reset();
type_ = tokenType::INT64;
data_.int64Val = val;
}
inline void pFlow::token::operator=(const int32 val)
{
reset();
type_ = tokenType::INT64;
data_.int64Val = static_cast<int64>(val);
}
inline void pFlow::token::operator=(const float val)
{
reset();
type_ = tokenType::FLOAT;
data_.floatVal = val;
}
inline void pFlow::token::operator=(const double val)
{
reset();
type_ = tokenType::DOUBLE;
data_.doubleVal = val;
}
inline void pFlow::token::operator=(const word& w)
{
reset();
type_ = tokenType::WORD;
data_.wordPtr = new word(w);
}
inline void pFlow::token::operator=(word&& w)
{
reset();
type_ = tokenType::WORD;
data_.wordPtr = new word(std::move(w));
}
inline bool pFlow::token::operator==(const token& tok) const
{
if (type_ != tok.type_)
{
return false;
}
switch (type_)
{
case tokenType::UNDEFINED:
return true;
case tokenType::BOOL:
return data_.int64Val == tok.data_.int64Val;
case tokenType::FLAG:
return data_.flagVal == tok.data_.flagVal;
case tokenType::PUNCTUATION:
return data_.punctuationVal == tok.data_.punctuationVal;
case tokenType::INT64:
return data_.int64Val == tok.data_.int64Val;
case tokenType::FLOAT:
return equal(data_.floatVal, tok.data_.floatVal);
case tokenType::DOUBLE:
return equal(static_cast<real>(data_.doubleVal), static_cast<real>(tok.data_.doubleVal));
case tokenType::WORD:
case tokenType::DIRECTIVE:
return *data_.wordPtr == *tok.data_.wordPtr;
case tokenType::STRING:
case tokenType::VARIABLE:
return *data_.stringPtr == *tok.data_.stringPtr;
case tokenType::ERROR:
return true;
}
return false;
}
inline bool pFlow::token::operator==(const punctuationToken p) const
{
return (type_ == tokenType::PUNCTUATION && data_.punctuationVal == p);
}
inline bool pFlow::token::operator==(const int64 val) const
{
return
(
type_ == tokenType::INT64
&& data_.int64Val == val
);
}
inline bool pFlow::token::operator==(const int32 val) const
{
return
(
type_ == tokenType::INT64
&& data_.int64Val == static_cast<int64>(val)
);
}
inline bool pFlow::token::operator==(const float val) const
{
return
(
type_ == tokenType::FLOAT
&& equal(data_.floatVal, val)
);
}
inline bool pFlow::token::operator==(const double val) const
{
return
(
type_ == tokenType::DOUBLE
&& equal( static_cast<real>(data_.doubleVal), static_cast<real>(val))
);
}
inline bool pFlow::token::operator==(const word& w) const
{
return
(
type_== tokenType::WORD
&& *data_.wordPtr == w
);
}
inline bool pFlow::token::operator!=(const token& tok) const
{
return !operator==(tok);
}
inline bool pFlow::token::operator!=(const punctuationToken p) const
{
return !operator==(p);
}
inline bool pFlow::token::operator!=(const int64 val) const
{
return !operator==(val);
}
inline bool pFlow::token::operator!=(const int32 val) const
{
return !operator==(val);
}
inline bool pFlow::token::operator!=(const float val) const
{
return !operator==(val);
}
inline bool pFlow::token::operator!=(const double val) const
{
return !operator==(val);
}
inline bool pFlow::token::operator!=(const word& w) const
{
return !operator==(w);
}
// ************************************************************************* //

View File

@ -0,0 +1,234 @@
/*------------------------------- 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 "iIstream.H"
#include "iOstream.H"
namespace pFlow
{
template<class OS>
static OS& printTokenInfo(OS& os, const token& tok)
{
os << "on line " << tok.lineNumber() << ": ";
switch (tok.type())
{
case token::tokenType::UNDEFINED:
os << "UNDEFINED";
warningInFunction
<< "Undefined token" << endl;
break;
case token::tokenType::FLAG:
// Swallow the flag
break;
case token::tokenType::PUNCTUATION:
os << tok.pToken();
break;
case token::tokenType::BOOL:
case token::tokenType::INT64:
os << tok.int64Token();
break;
case token::tokenType::FLOAT:
os << tok.floatToken();
break;
case token::tokenType::DOUBLE:
os <<tok.doubleToken();
break;
// Different behaviour for (serial/parallel) streams: preserve types
case token::tokenType::DIRECTIVE:
case token::tokenType::VARIABLE:
//case token::tokenType::VERBATIMSTRING:
os << tok.stringToken();
break;
case token::tokenType::WORD:
os << tok.wordToken();
break;
case token::tokenType::STRING:
os << tok.stringToken();
break;
case token::tokenType::ERROR:
os << "ERROR";
warningInFunction
<< "Error token" << endl;
break;
default:
os << "UNKNOWN";
warningInFunction
<< "Unknown token" << endl;
}
return os;
}
} // pFlow
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
pFlow::token::token(iIstream& is)
:
token()
{
is.read(*this);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
pFlow::word pFlow::token::name() const
{
switch (type_)
{
case token::tokenType::UNDEFINED: return "undefined";
case token::tokenType::BOOL: return "bool";
case token::tokenType::FLAG: return "flag";
case token::tokenType::PUNCTUATION: return "punctuation";
case token::tokenType::INT64: return "int64/int32";
case token::tokenType::FLOAT: return "float";
case token::tokenType::DOUBLE: return "double";
case token::tokenType::WORD: return "word";
case token::tokenType::DIRECTIVE: return "directive";
case token::tokenType::STRING: return "string";
//case token::tokenType::VERBATIM: return "verbatim";
case token::tokenType::VARIABLE: return "variable";
//case token::tokenType::COMPOUND: return "compound";
case token::tokenType::ERROR: return "error";
default:
break;
}
return "unknown(" + std::to_string(int(type_)) + ")";
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
pFlow::iIstream& pFlow::operator>>(iIstream& is, token& tok)
{
tok.reset();
return is.read(tok);
}
pFlow::iOstream& pFlow::operator<<(iOstream& os, const token& tok)
{
switch (tok.type_)
{
case token::tokenType::UNDEFINED:
os << "UNDEFINED";
warningInFunction
<< "Undefined token" << endl;
break;
case token::tokenType::FLAG:
// Swallow the flag
break;
case token::tokenType::PUNCTUATION:
os << tok.pToken();
break;
case token::tokenType::BOOL:
case token::tokenType::INT64:
os << tok.int64Token();
break;
case token::tokenType::FLOAT:
os << tok.floatToken();
break;
case token::tokenType::DOUBLE:
os <<tok.doubleToken();
break;
// Different behaviour for (serial/parallel) streams: preserve types
case token::tokenType::DIRECTIVE:
case token::tokenType::VARIABLE:
//case token::tokenType::VERBATIMSTRING:
os.write(tok);
break;
case token::tokenType::WORD:
os << tok.wordToken();
break;
case token::tokenType::STRING:
os << tok.stringToken();
break;
case token::tokenType::ERROR:
os << "ERROR";
warningInFunction
<< "Error token" << endl;
break;
default:
os << "UNKNOWN";
warningInFunction
<< "Unknown token" << endl;
}
os.check(FUNCTION_NAME);
return os;
}
pFlow::iOstream& pFlow::operator<<(iOstream& os, const token::punctuationToken& pt)
{
return os << char(pt);
}
std::ostream& pFlow::operator<<(std::ostream& os, const token::punctuationToken& pt)
{
return os << char(pt);
}
std::ostream& pFlow::operator<<(std::ostream& os, const token& tok)
{
return printTokenInfo(os, tok);
}
pFlow::iOstream& pFlow::token::printInfo(iOstream& os)const
{
return printTokenInfo(os, *this);
}
std::ostream& pFlow::token::printInfo(std::ostream& os)const
{
return printTokenInfo(os, *this);
}

View File

@ -0,0 +1,39 @@
/*------------------------------- 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 __tokenFList_H__
#define __tokenFList_H__
#include "token.H"
#include "List.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace pFlow
{
using tokenList = List<token> ;
using tokenTypeList = List<token::tokenType> ;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //