ENH: unify read/write for containers

- handle binary/contiguous first as being the most obvious, followed
  by increasing complexity of ascii.
  Structure reading and writing routines similarly by introducing a
  readList method to compliment the writeList method.
This commit is contained in:
Mark Olesen
2021-02-26 18:10:42 +01:00
committed by Andrew Heather
parent a76a3d760c
commit 498de8a74a
29 changed files with 728 additions and 642 deletions

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2019 OpenCFD Ltd.
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -37,6 +37,8 @@ Description
#include "HashSet.H"
#include "ListOps.H"
#include "cpuTime.H"
#include "StringStream.H"
#include "FlatOutput.H"
#include <vector>
#include <unordered_set>
@ -65,6 +67,28 @@ inline Ostream& report
}
// Create equivalent to flat output
inline void undecorated
(
Ostream& os,
const bitSet& list
)
{
const label len = list.size();
os << token::BEGIN_LIST;
// Contents
for (label i=0; i < len; ++i)
{
if (i) os << token::SPACE;
os << label(list.get(i));
}
os << token::END_LIST;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
@ -97,6 +121,28 @@ int main(int argc, char *argv[])
Info<<"bits used: " << flatOutput(set3b.toc()) << nl;
Info<<"inverted: " << flatOutput(invert(set3b)) << nl;
Info<< "Test read/write (ASCII)" << nl;
OStringStream ostr;
undecorated(ostr, set3a); // like flatOutput
ostr << bitSet();
set3a.flip();
undecorated(ostr, set3a); // like flatOutput
{
IStringStream istr(ostr.str());
Info<< "parse: " << istr.str() << nl;
bitSet bset1(istr);
bitSet bset2(istr);
bitSet bset3(istr);
Info<< "got: " << bset1 << nl
<< "and: " << bset2 << nl
<< "and: " << bset3 << nl;
}
}
Info<< "End\n" << endl;

View File

@ -416,7 +416,7 @@ public:
Ostream& printBits(Ostream& os, bool debugOutput=false) const;
//- Clear list and read from stream
Istream& read(Istream& is);
Istream& readList(Istream& is);
//- Write List, with line-breaks in ASCII when length exceeds shortLen.
// Using '0' suppresses line-breaks entirely.

View File

@ -212,7 +212,7 @@ inline Foam::PackedList<Width>::PackedList(Istream& is)
blocks_(),
size_(0)
{
read(is);
readList(is);
}

View File

@ -61,70 +61,33 @@ Foam::Ostream& Foam::PackedList<Width>::printBits
template<unsigned Width>
Foam::Istream& Foam::PackedList<Width>::read(Istream& is)
Foam::Istream& Foam::PackedList<Width>::readList(Istream& is)
{
PackedList<Width>& list = *this;
// Anull list
list.clear();
is.fatalCheck(FUNCTION_NAME);
token firstTok(is);
is.fatalCheck
(
"PackedList::read(Istream&) : "
"reading first token"
);
token tok(is);
if (firstTok.isLabel())
is.fatalCheck("PackedList::readList(Istream&) : reading first token");
if (tok.isLabel())
{
const label len = firstTok.labelToken();
const label len = tok.labelToken();
// Set list length to that read
list.resize(len);
// Read list contents depending on data format
if (is.format() == IOstream::ASCII)
if (is.format() == IOstream::BINARY)
{
// Read beginning of contents
const char delimiter = is.readBeginList("PackedList");
if (len)
{
if (delimiter == token::BEGIN_LIST)
{
for (label i=0; i<len; ++i)
{
list[i] = list.readValue(is);
is.fatalCheck
(
"PackedList::read(Istream&) : "
"reading entry"
);
}
}
else
{
// Assign for all entries
list = list.readValue(is);
is.fatalCheck
(
"PackedList::read(Istream&) : "
"reading the single entry"
);
}
}
// Read end of contents
is.readEndList("PackedList");
}
else
{
// NOTE: binary content should be independent of WM_LABEL_SIZE
// Binary (always contiguous)
if (len)
{
// NOTE: independent of WM_LABEL_SIZE
is.read
(
reinterpret_cast<char*>(list.data()),
@ -133,37 +96,73 @@ Foam::Istream& Foam::PackedList<Width>::read(Istream& is)
is.fatalCheck
(
"PackedList::read(Istream&) : "
"PackedList::readList(Istream&) : "
"reading the binary block"
);
}
}
}
else if (firstTok.isPunctuation(token::BEGIN_LIST))
else
{
token nextTok(is);
// Begin of contents marker
const char delimiter = is.readBeginList("PackedList");
if (len)
{
if (delimiter == token::BEGIN_LIST)
{
for (label i=0; i<len; ++i)
{
list.set(i, list.readValue(is));
is.fatalCheck
(
"PackedList::readList(Istream&) : "
"reading entry"
);
}
}
else // token::BEGIN_BLOCK
{
// Assign for all entries
list = list.readValue(is);
is.fatalCheck
(
"PackedList::readList(Istream&) : "
"reading the single entry"
);
}
}
// End of contents marker
is.readEndList("PackedList");
}
}
else if (tok.isPunctuation(token::BEGIN_LIST))
{
is >> tok;
is.fatalCheck(FUNCTION_NAME);
while (!nextTok.isPunctuation(token::END_LIST))
while (!tok.isPunctuation(token::END_LIST))
{
is.putBack(nextTok);
is.putBack(tok);
list.append(list.readValue(is));
is >> nextTok;
is >> tok;
is.fatalCheck(FUNCTION_NAME);
}
}
else if (firstTok.isPunctuation(token::BEGIN_BLOCK))
else if (tok.isPunctuation(token::BEGIN_BLOCK))
{
token nextTok(is);
is >> tok;
is.fatalCheck(FUNCTION_NAME);
while (!nextTok.isPunctuation(token::END_BLOCK))
while (!tok.isPunctuation(token::END_BLOCK))
{
is.putBack(nextTok);
is.putBack(tok);
list.setPair(is);
is >> nextTok;
is >> tok;
is.fatalCheck(FUNCTION_NAME);
}
}
@ -171,7 +170,7 @@ Foam::Istream& Foam::PackedList<Width>::read(Istream& is)
{
FatalIOErrorInFunction(is)
<< "incorrect first token, expected <int>, '(' or '{', found "
<< firstTok.info() << nl
<< tok.info() << nl
<< exit(FatalIOError);
}
@ -189,39 +188,10 @@ Foam::Ostream& Foam::PackedList<Width>::writeList
const PackedList<Width>& list = *this;
const label len = list.size();
// Write list contents depending on data format
if (os.format() == IOstream::ASCII)
if (os.format() == IOstream::BINARY)
{
if (len > 1 && list.uniform())
{
// Two or more entries, and all have identical values.
os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
}
else if (!shortLen || len <= shortLen)
{
// Shorter list, or line-breaks suppressed
os << len << token::BEGIN_LIST;
for (label i=0; i < len; ++i)
{
if (i) os << token::SPACE;
os << list[i];
}
os << token::END_LIST;
}
else
{
// Longer list
os << nl << len << nl << token::BEGIN_LIST << nl;
for (label i=0; i < len; ++i)
{
os << list[i] << nl;
}
os << token::END_LIST << nl;
}
}
else
{
// Contents are binary and contiguous
// Binary (always contiguous)
os << nl << len << nl;
if (len)
@ -234,6 +204,44 @@ Foam::Ostream& Foam::PackedList<Width>::writeList
);
}
}
else if (len > 1 && list.uniform())
{
// Two or more entries, and all entries have identical values.
os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
}
else if (!shortLen || len <= shortLen)
{
// Single-line output
// Size and start delimiter
os << len << token::BEGIN_LIST;
// Contents
for (label i=0; i < len; ++i)
{
if (i) os << token::SPACE;
os << label(list.get(i));
}
// End delimiter
os << token::END_LIST;
}
else
{
// Multi-line output
// Size and start delimiter
os << nl << len << nl << token::BEGIN_LIST << nl;
// Contents
for (label i=0; i < len; ++i)
{
os << label(list.get(i)) << nl;
}
// End delimiter
os << token::END_LIST << nl;
}
return os;
}
@ -260,7 +268,7 @@ void Foam::PackedList<Width>::writeEntry
template<unsigned Width>
Foam::Istream& Foam::operator>>(Istream& is, PackedList<Width>& list)
{
return list.read(is);
return list.readList(is);
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2020 OpenCFD Ltd.
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -74,11 +74,6 @@ class bitSet
protected:
// Protected Member Functions
//- Write as a dictionary entry
void writeEntry(Ostream& os) const;
// Logic/Set Operations
//- The set difference
@ -582,16 +577,6 @@ public:
inline bitSet& operator-=(const bitSet& other);
// IO
//- Write bitSet, with line-breaks (ASCII) when length exceeds shortLen.
// Using '0' suppresses line-breaks entirely.
Ostream& writeList(Ostream& os, const label shortLen=0) const;
//- Write as a dictionary entry with keyword
void writeEntry(const word& keyword, Ostream& os) const;
// IOstream Operators
//- Return info proxy
@ -611,8 +596,7 @@ public:
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
//- Write bitset to Ostream, as per bitSet::writeList() with default length
//- of 40 items.
//- Write bitset to Ostream with 40 items per line.
Ostream& operator<<(Ostream& os, const bitSet& bitset);
//- Output bitset information

View File

@ -28,90 +28,6 @@ License
#include "bitSet.H"
#include "IOstreams.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::bitSet::writeEntry(Ostream& os) const
{
os << *this;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::Ostream& Foam::bitSet::writeList
(
Ostream& os,
const label shortLen
) const
{
const bitSet& list = *this;
const label len = list.size();
// Write list contents depending on data format
if (os.format() == IOstream::ASCII)
{
if (len > 1 && list.uniform())
{
// Two or more entries, and all entries have identical values.
os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
}
else if (!shortLen || len <= shortLen)
{
// Shorter list, or line-breaks suppressed
os << len << token::BEGIN_LIST;
for (label i=0; i < len; ++i)
{
if (i) os << token::SPACE;
os << list[i];
}
os << token::END_LIST;
}
else
{
// Longer list
os << nl << len << nl << token::BEGIN_LIST << nl;
for (label i=0; i < len; ++i)
{
os << list[i] << nl;
}
os << token::END_LIST << nl;
}
}
else
{
// Contents are binary and contiguous
os << nl << len << nl;
if (len)
{
// write(...) includes surrounding start/end delimiters
os.write
(
reinterpret_cast<const char*>(list.cdata()),
list.size_bytes()
);
}
}
return os;
}
void Foam::bitSet::writeEntry
(
const word& keyword,
Ostream& os
) const
{
if (keyword.size())
{
os.writeKeyword(keyword);
}
writeEntry(os);
os << token::END_STATEMENT << endl;
}
// * * * * * * * * * * * * * * Ostream Operators * * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const bitSet& bitset)

View File

@ -168,7 +168,10 @@ public:
//- Clear all entries from table and delete any allocated pointers
void clear();
//- Write
// Reading/writing
//- Invoke write() on each non-null entry
void write(Ostream& os) const;
@ -183,6 +186,7 @@ public:
// IOstream Operators
//- Clear table and read from Istream
friend Istream& operator>> <T, Key, Hash>
(
Istream& is,

View File

@ -44,7 +44,7 @@ void Foam::HashPtrTable<T, Key, Hash>::readIstream
{
is.fatalCheck(FUNCTION_NAME);
token firstToken(is);
token tok(is);
is.fatalCheck
(
@ -52,9 +52,9 @@ void Foam::HashPtrTable<T, Key, Hash>::readIstream
"reading first token"
);
if (firstToken.isLabel())
if (tok.isLabel())
{
const label len = firstToken.labelToken();
const label len = tok.labelToken();
// Read beginning of contents
const char delimiter = is.readBeginList("HashPtrTable");
@ -84,7 +84,8 @@ void Foam::HashPtrTable<T, Key, Hash>::readIstream
else
{
FatalIOErrorInFunction(is)
<< "incorrect first token, '(', found " << firstToken.info()
<< "incorrect first token, '(', found "
<< tok.info() << nl
<< exit(FatalIOError);
}
}
@ -92,12 +93,13 @@ void Foam::HashPtrTable<T, Key, Hash>::readIstream
// Read end of contents
is.readEndList("HashPtrTable");
}
else if (firstToken.isPunctuation(token::BEGIN_LIST))
else if (tok.isPunctuation(token::BEGIN_LIST))
{
token lastToken(is);
while (!lastToken.isPunctuation(token::END_LIST))
is >> tok;
while (!tok.isPunctuation(token::END_LIST))
{
is.putBack(lastToken);
is.putBack(tok);
Key key;
is >> key;
this->set(key, inew(key, is).ptr());
@ -108,14 +110,14 @@ void Foam::HashPtrTable<T, Key, Hash>::readIstream
"reading entry"
);
is >> lastToken;
is >> tok;
}
}
else
{
FatalIOErrorInFunction(is)
<< "incorrect first token, expected <int> or '(', found "
<< firstToken.info()
<< tok.info() << nl
<< exit(FatalIOError);
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -105,6 +105,12 @@ template<class T> class UList;
template<class T, unsigned N> class FixedList;
template<class T, class Key, class Hash> class HashTable;
template<class T, class Key, class Hash>
Istream& operator>>(Istream&, HashTable<T, Key, Hash>&);
template<class T, class Key, class Hash>
Ostream& operator<<(Ostream&, const HashTable<T, Key, Hash>&);
/*---------------------------------------------------------------------------*\
Class HashTable Declaration
\*---------------------------------------------------------------------------*/
@ -148,6 +154,12 @@ class HashTable
template<class... Args>
bool setEntry(const bool overwrite, const Key& key, Args&&... args);
//- Read hash table
Istream& readTable(Istream& is);
//- Write hash table
Ostream& writeTable(Ostream& os) const;
public:
@ -893,7 +905,7 @@ public:
inline constexpr const_iterator cend() const noexcept;
// Writing
// Reading/writing
//- Print information
Ostream& printInfo(Ostream& os) const;
@ -902,18 +914,24 @@ public:
//- when length exceeds shortLen.
// Using '0' suppresses line-breaks entirely.
Ostream& writeKeys(Ostream& os, const label shortLen=0) const;
// IOstream Operators
friend Istream& operator>> <T, Key, Hash>
(
Istream&,
HashTable<T, Key, Hash>& tbl
);
friend Ostream& operator<< <T, Key, Hash>
(
Ostream&,
const HashTable<T, Key, Hash>& tbl
);
};
// IOstream Operators
template<class T, class Key, class Hash>
Istream& operator>>(Istream& is, HashTable<T, Key, Hash>& tbl);
template<class T, class Key, class Hash>
Ostream& operator<<(Ostream& os, const HashTable<T, Key, Hash>& tbl);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -141,21 +141,20 @@ Foam::Ostream& Foam::HashTable<T, Key, Hash>::writeKeys
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class T, class Key, class Hash>
Foam::Istream& Foam::operator>>
Foam::Istream& Foam::HashTable<T, Key, Hash>::readTable
(
Istream& is,
HashTable<T, Key, Hash>& tbl
Istream& is
)
{
HashTable<T, Key, Hash>& tbl = *this;
// Anull existing table
tbl.clear();
is.fatalCheck(FUNCTION_NAME);
token firstToken(is);
token tok(is);
is.fatalCheck
(
@ -163,9 +162,9 @@ Foam::Istream& Foam::operator>>
"reading first token"
);
if (firstToken.isLabel())
if (tok.isLabel())
{
const label len = firstToken.labelToken();
const label len = tok.labelToken();
// Read beginning of contents
const char delimiter = is.readBeginList("HashTable");
@ -175,7 +174,8 @@ Foam::Istream& Foam::operator>>
if (delimiter != token::BEGIN_LIST)
{
FatalIOErrorInFunction(is)
<< "incorrect first token, '(', found " << firstToken.info()
<< "incorrect first token, '(', found "
<< tok.info() << nl
<< exit(FatalIOError);
}
@ -203,12 +203,12 @@ Foam::Istream& Foam::operator>>
// Read end of contents
is.readEndList("HashTable");
}
else if (firstToken.isPunctuation(token::BEGIN_LIST))
else if (tok.isPunctuation(token::BEGIN_LIST))
{
token lastToken(is);
while (!lastToken.isPunctuation(token::END_LIST))
is >> tok;
while (!tok.isPunctuation(token::END_LIST))
{
is.putBack(lastToken);
is.putBack(tok);
Key key;
@ -222,14 +222,14 @@ Foam::Istream& Foam::operator>>
"reading entry"
);
is >> lastToken;
is >> tok;
}
}
else
{
FatalIOErrorInFunction(is)
<< "incorrect first token, expected <int> or '(', found "
<< firstToken.info()
<< tok.info() << nl
<< exit(FatalIOError);
}
@ -239,12 +239,13 @@ Foam::Istream& Foam::operator>>
template<class T, class Key, class Hash>
Foam::Ostream& Foam::operator<<
Foam::Ostream& Foam::HashTable<T, Key, Hash>::writeTable
(
Ostream& os,
const HashTable<T, Key, Hash>& tbl
)
Ostream& os
) const
{
const HashTable<T, Key, Hash>& tbl = *this;
const label len = tbl.size();
if (len)
@ -271,4 +272,28 @@ Foam::Ostream& Foam::operator<<
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class T, class Key, class Hash>
Foam::Istream& Foam::operator>>
(
Istream& is,
HashTable<T, Key, Hash>& tbl
)
{
return tbl.readTable(is);
}
template<class T, class Key, class Hash>
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const HashTable<T, Key, Hash>& tbl
)
{
return tbl.writeTable(os);
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2014 OpenFOAM Foundation
Copyright (C) 2016-2019 OpenCFD Ltd.
Copyright (C) 2016-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -44,59 +44,9 @@ Foam::Ostream& Foam::IndirectListBase<T, Addr>::writeList
const label len = list.size();
// Write list contents depending on data format
if (os.format() == IOstream::ASCII || !is_contiguous<T>::value)
if (os.format() == IOstream::BINARY && is_contiguous<T>::value)
{
if (len > 1 && is_contiguous<T>::value && list.uniform())
{
// Two or more entries, and all entries have identical values.
os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
}
else if
(
(len <= 1 || !shortLen)
||
(
(len <= shortLen)
&&
(
Detail::ListPolicy::no_linebreak<T>::value
|| is_contiguous<T>::value
)
)
)
{
// Size and start delimiter
os << len << token::BEGIN_LIST;
// Contents
for (label i=0; i < len; ++i)
{
if (i) os << token::SPACE;
os << list[i];
}
// End delimiter
os << token::END_LIST;
}
else
{
// Size and start delimiter
os << nl << len << nl << token::BEGIN_LIST << nl;
// Contents
for (label i=0; i < len; ++i)
{
os << list[i] << nl;
}
// End delimiter
os << token::END_LIST << nl;
}
}
else
{
// Contents are binary and contiguous
// Binary and contiguous
os << nl << len << nl;
if (len)
@ -119,6 +69,56 @@ Foam::Ostream& Foam::IndirectListBase<T, Addr>::writeList
os.endRawWrite();
}
}
else if (len > 1 && is_contiguous<T>::value && list.uniform())
{
// Two or more entries, and all entries have identical values.
os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
}
else if
(
(len <= 1 || !shortLen)
||
(
(len <= shortLen)
&&
(
is_contiguous<T>::value
|| Detail::ListPolicy::no_linebreak<T>::value
)
)
)
{
// Single-line output
// Size and start delimiter
os << len << token::BEGIN_LIST;
// Contents
for (label i=0; i < len; ++i)
{
if (i) os << token::SPACE;
os << list[i];
}
// End delimiter
os << token::END_LIST;
}
else
{
// Multi-line output
// Size and start delimiter
os << nl << len << nl << token::BEGIN_LIST << nl;
// Contents
for (label i=0; i < len; ++i)
{
os << list[i] << nl;
}
// End delimiter
os << token::END_LIST << nl;
}
os.check(FUNCTION_NAME);
return os;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2018 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -46,7 +46,7 @@ SourceFiles
namespace Foam
{
// Forward declarations
// Forward Declarations
class Istream;
class Ostream;
@ -79,7 +79,7 @@ public:
// Constructors
//- Null construct
//- Default construct
ILList() = default;
//- Construct and insert the initial T item pointer
@ -126,7 +126,7 @@ public:
void transfer(ILList<LListBase, T>& lst);
// Member operators
// Member Operators
//- Copy assignment using the 'clone()' method for each element
void operator=(const ILList<LListBase, T>& lst);
@ -135,7 +135,7 @@ public:
void operator=(ILList<LListBase, T>&& lst);
// Istream operator
// Istream Operator
//- Read from Istream, discarding existing contents.
friend Istream& operator>> <LListBase, T>

View File

@ -38,7 +38,7 @@ void Foam::ILList<LListBase, T>::readIstream(Istream& is, const INew& inew)
{
is.fatalCheck(FUNCTION_NAME);
token firstToken(is);
token tok(is);
is.fatalCheck
(
@ -46,9 +46,9 @@ void Foam::ILList<LListBase, T>::readIstream(Istream& is, const INew& inew)
"reading first token"
);
if (firstToken.isLabel())
if (tok.isLabel())
{
const label len = firstToken.labelToken();
const label len = tok.labelToken();
// Read beginning of contents
const char delimiter = is.readBeginList("ILList");
@ -69,7 +69,7 @@ void Foam::ILList<LListBase, T>::readIstream(Istream& is, const INew& inew)
);
}
}
else
else // BEGIN_BLOCK
{
T* p = inew(is).ptr();
this->append(p);
@ -90,19 +90,19 @@ void Foam::ILList<LListBase, T>::readIstream(Istream& is, const INew& inew)
// Read end of contents
is.readEndList("ILList");
}
else if (firstToken.isPunctuation(token::BEGIN_LIST))
else if (tok.isPunctuation(token::BEGIN_LIST))
{
token lastToken(is);
is >> tok;
is.fatalCheck(FUNCTION_NAME);
while (!lastToken.isPunctuation(token::END_LIST))
while (!tok.isPunctuation(token::END_LIST))
{
is.putBack(lastToken);
is.putBack(tok);
T* p = inew(is).ptr();
this->append(p);
is >> lastToken;
is >> tok;
is.fatalCheck(FUNCTION_NAME);
}
}
@ -110,7 +110,7 @@ void Foam::ILList<LListBase, T>::readIstream(Istream& is, const INew& inew)
{
FatalIOErrorInFunction(is)
<< "incorrect first token, expected <int> or '(', found "
<< firstToken.info()
<< tok.info() << nl
<< exit(FatalIOError);
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -47,7 +47,7 @@ SourceFiles
namespace Foam
{
// Forward declarations
// Forward Declarations
class Istream;
class Ostream;
@ -162,7 +162,7 @@ public:
// Constructors
//- Null construct
//- Default construct
LList() = default;
//- Construct and copy insert the initial T item
@ -283,7 +283,7 @@ public:
void transfer(LList<LListBase, T>& lst);
// Member operators
// Member Operators
//- Copy assignment
void operator=(const LList<LListBase, T>& lst);
@ -295,7 +295,10 @@ public:
void operator=(std::initializer_list<T> lst);
// IOstream operators
// IOstream Operators
//- Read list from Istream
Istream& readList(Istream& is);
//- Write LList with line-breaks when length exceeds shortLen.
// Using '0' suppresses line-breaks entirely.

View File

@ -42,22 +42,24 @@ Foam::LList<LListBase, T>::LList(Istream& is)
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class LListBase, class T>
Foam::Istream& Foam::operator>>(Istream& is, LList<LListBase, T>& lst)
Foam::Istream& Foam::LList<LListBase, T>::readList(Istream& is)
{
LList<LListBase, T>& list = *this;
// Anull list
lst.clear();
list.clear();
is.fatalCheck(FUNCTION_NAME);
token firstToken(is);
token tok(is);
is.fatalCheck("LList::readList : reading first token");
if (firstToken.isLabel())
if (tok.isLabel())
{
const label len = firstToken.labelToken();
const label len = tok.labelToken();
// Read beginning of contents
// Begin of contents marker
const char delimiter = is.readBeginList("LList");
if (len)
@ -68,7 +70,7 @@ Foam::Istream& Foam::operator>>(Istream& is, LList<LListBase, T>& lst)
{
T element;
is >> element;
lst.append(element);
list.append(element);
}
}
else
@ -78,28 +80,28 @@ Foam::Istream& Foam::operator>>(Istream& is, LList<LListBase, T>& lst)
for (label i=0; i<len; ++i)
{
lst.append(element);
list.append(element);
}
}
}
// Read end of contents
// End of contents marker
is.readEndList("LList");
}
else if (firstToken.isPunctuation(token::BEGIN_LIST))
else if (tok.isPunctuation(token::BEGIN_LIST))
{
token lastToken(is);
is >> tok;
is.fatalCheck(FUNCTION_NAME);
while (!lastToken.isPunctuation(token::END_LIST))
while (!tok.isPunctuation(token::END_LIST))
{
is.putBack(lastToken);
is.putBack(tok);
T element;
is >> element;
lst.append(element);
list.append(element);
is >> lastToken;
is >> tok;
is.fatalCheck(FUNCTION_NAME);
}
}
@ -107,7 +109,7 @@ Foam::Istream& Foam::operator>>(Istream& is, LList<LListBase, T>& lst)
{
FatalIOErrorInFunction(is)
<< "incorrect first token, expected <int> or '(', found "
<< firstToken.info()
<< tok.info()
<< exit(FatalIOError);
}
@ -123,6 +125,8 @@ Foam::Ostream& Foam::LList<LListBase, T>::writeList
const label shortLen
) const
{
// NB: no binary, contiguous output
const label len = this->size();
if
@ -167,9 +171,16 @@ Foam::Ostream& Foam::LList<LListBase, T>::writeList
template<class LListBase, class T>
Foam::Ostream& Foam::operator<<(Ostream& os, const LList<LListBase, T>& lst)
Foam::Istream& Foam::operator>>(Istream& is, LList<LListBase, T>& list)
{
return lst.writeList(os, -1); // Always with line breaks
return list.readList(is);
}
template<class LListBase, class T>
Foam::Ostream& Foam::operator<<(Ostream& os, const LList<LListBase, T>& list)
{
return list.writeList(os, -1); // Always with line breaks
}

View File

@ -39,7 +39,7 @@ void Foam::LPtrList<LListBase, T>::readIstream(Istream& is, const INew& inew)
{
is.fatalCheck(FUNCTION_NAME);
token firstToken(is);
token tok(is);
is.fatalCheck
(
@ -47,9 +47,9 @@ void Foam::LPtrList<LListBase, T>::readIstream(Istream& is, const INew& inew)
"reading first token"
);
if (firstToken.isLabel())
if (tok.isLabel())
{
const label len = firstToken.labelToken();
const label len = tok.labelToken();
// Read beginning of contents
const char delimiter = is.readBeginList("LPtrList");
@ -70,7 +70,7 @@ void Foam::LPtrList<LListBase, T>::readIstream(Istream& is, const INew& inew)
);
}
}
else
else // Assumed to be token::BEGIN_BLOCK
{
T* p = inew(is).ptr();
this->append(p);
@ -91,17 +91,17 @@ void Foam::LPtrList<LListBase, T>::readIstream(Istream& is, const INew& inew)
// Read end of contents
is.readEndList("LPtrList");
}
else if (firstToken.isPunctuation(token::BEGIN_LIST))
else if (tok.isPunctuation(token::BEGIN_LIST))
{
token lastToken(is);
is >> tok;
is.fatalCheck(FUNCTION_NAME);
while (!lastToken.isPunctuation(token::END_LIST))
while (!tok.isPunctuation(token::END_LIST))
{
is.putBack(lastToken);
is.putBack(tok);
this->append(inew(is).ptr());
is >> lastToken;
is >> tok;
is.fatalCheck(FUNCTION_NAME);
}
}
@ -109,7 +109,7 @@ void Foam::LPtrList<LListBase, T>::readIstream(Istream& is, const INew& inew)
{
FatalIOErrorInFunction(is)
<< "incorrect first token, expected <int> or '(', found "
<< firstToken.info()
<< tok.info() << nl
<< exit(FatalIOError);
}

View File

@ -47,8 +47,7 @@ SourceFiles
namespace Foam
{
// Forward declarations
// Forward Declarations
class Ostream;
template<class LListBase, class T> class UILList;
@ -107,7 +106,7 @@ public:
// Constructors
//- Null construct
//- Default construct
UILList() = default;
//- Construct and insert the initial T item
@ -179,7 +178,7 @@ public:
bool operator!=(const UILList<LListBase, T>& lst) const;
// IOstream operators
// IOstream Operators
//- Write UILList with line-breaks when length exceeds shortLen.
// Using '0' suppresses line-breaks entirely.

View File

@ -39,6 +39,8 @@ Foam::Ostream& Foam::UILList<LListBase, T>::writeList
const label shortLen
) const
{
// NB: no binary, contiguous output
const label len = this->size();
if

View File

@ -334,20 +334,26 @@ public:
inline void operator=(SortableList<T>&& lst);
// Reading/writing
//- Read from Istream, discarding existing contents
inline Istream& readList(Istream& is);
// IOstream Operators
//- Read from Istream, discarding existing contents
friend Istream& operator>> <T, SizeMin>
(
Istream& is,
DynamicList<T, SizeMin>& rhs
DynamicList<T, SizeMin>& list
);
//- Write to Ostream
friend Ostream& operator<< <T, SizeMin>
(
Ostream& os,
const DynamicList<T, SizeMin>& rhs
const DynamicList<T, SizeMin>& list
);
};

View File

@ -223,9 +223,11 @@ inline Foam::DynamicList<T, SizeMin>::DynamicList
template<class T, int SizeMin>
inline Foam::DynamicList<T, SizeMin>::DynamicList(Istream& is)
:
List<T>(is),
capacity_(List<T>::size())
{}
List<T>(),
capacity_(0)
{
this->readList(is);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -865,20 +867,32 @@ inline void Foam::DynamicList<T, SizeMin>::operator=
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class T, int SizeMin>
inline Foam::Istream& Foam::DynamicList<T, SizeMin>::readList
(
Istream& is
)
{
DynamicList<T, SizeMin>& list = *this;
// Use entire storage - ie, resize(capacity())
(void) list.expandStorage();
static_cast<List<T>&>(list).readList(is);
list.capacity_ = list.size();
return is;
}
template<class T, int SizeMin>
inline Foam::Istream& Foam::operator>>
(
Istream& is,
DynamicList<T, SizeMin>& rhs
DynamicList<T, SizeMin>& list
)
{
// Use entire storage - ie, resize(capacity())
(void) rhs.expandStorage();
is >> static_cast<List<T>&>(rhs);
rhs.capacity_ = rhs.List<T>::size();
return is;
return list.readList(is);
}
@ -886,10 +900,10 @@ template<class T, int SizeMin>
inline Foam::Ostream& Foam::operator<<
(
Ostream& os,
const DynamicList<T, SizeMin>& rhs
const DynamicList<T, SizeMin>& list
)
{
os << static_cast<const List<T>&>(rhs);
os << static_cast<const List<T>&>(list);
return os;
}

View File

@ -430,7 +430,10 @@ public:
bool operator>=(const FixedList<T, N>& list) const;
// Writing
// Reading/writing
//- Read from Istream, discarding contents of existing List
Istream& readList(Istream& is);
//- Write the list as a dictionary entry with keyword
void writeEntry(const word& keyword, Ostream& os) const;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -72,15 +72,22 @@ Foam::Ostream& Foam::FixedList<T, N>::writeList
{
const FixedList<T, N>& list = *this;
// Write list contents depending on data format
// Unlike UList, no compact ascii output since a FixedList is generally
// small and we prefer a consistent appearance.
// Eg, FixedList<T,2> or Pair<T> as "(-1 -1)", never as "2{-1}"
// Unlike UList, no compact output form since a FixedList is generally
// small and we desire a consistent appearance.
// Eg, FixedList<T,2> or Pair<T> as "(-1 -1)", not as "2{-1}"
if (os.format() == IOstream::ASCII || !is_contiguous<T>::value)
if (os.format() == IOstream::BINARY && is_contiguous<T>::value)
{
if
// Binary and contiguous. Size is always non-zero
// write(...) includes surrounding start/end delimiters
os.write
(
reinterpret_cast<const char*>(list.cdata()),
list.size_bytes()
);
}
else if
(
(N <= 1 || !shortLen)
||
@ -88,12 +95,14 @@ Foam::Ostream& Foam::FixedList<T, N>::writeList
(N <= unsigned(shortLen))
&&
(
Detail::ListPolicy::no_linebreak<T>::value
|| is_contiguous<T>::value
is_contiguous<T>::value
|| Detail::ListPolicy::no_linebreak<T>::value
)
)
)
{
// Single-line output
// Start delimiter
os << token::BEGIN_LIST;
@ -109,6 +118,8 @@ Foam::Ostream& Foam::FixedList<T, N>::writeList
}
else
{
// Multi-line output
// Start delimiter
os << nl << token::BEGIN_LIST << nl;
@ -121,73 +132,79 @@ Foam::Ostream& Foam::FixedList<T, N>::writeList
// End delimiter
os << token::END_LIST << nl;
}
}
else
{
// Binary, contiguous
// write(...) includes surrounding start/end delimiters
os.write(reinterpret_cast<const char*>(list.cdata()), N*sizeof(T));
}
os.check(FUNCTION_NAME);
return os;
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class T, unsigned N>
Foam::FixedList<T, N>::FixedList(Istream& is)
Foam::Istream& Foam::FixedList<T, N>::readList
(
Istream& is
)
{
operator>>(is, *this);
}
FixedList<T, N>& list = *this;
template<class T, unsigned N>
Foam::Istream& Foam::operator>>(Foam::Istream& is, FixedList<T, N>& list)
{
is.fatalCheck(FUNCTION_NAME);
if (is.format() == IOstream::ASCII || !is_contiguous<T>::value)
if (is.format() == IOstream::BINARY && is_contiguous<T>::value)
{
token firstToken(is);
// Binary and contiguous
Detail::readContiguous<T>
(
is,
reinterpret_cast<char*>(list.data()),
list.size_bytes()
);
is.fatalCheck
(
"operator>>(Istream&, FixedList<T, N>&) : "
"FixedList<T, N>::readList(Istream&) : "
"reading the binary block"
);
}
else
{
token tok(is);
is.fatalCheck
(
"FixedList<T, N>::readList(Istream&) : "
"reading first token"
);
if (firstToken.isCompound())
if (tok.isCompound())
{
// Compound: transfer contents
list = dynamicCast<token::Compound<List<T>>>
(
firstToken.transferCompoundToken(is)
tok.transferCompoundToken(is)
);
}
else if (firstToken.isLabel())
else if (tok.isLabel())
{
const label len = firstToken.labelToken();
const label len = tok.labelToken();
// List lengths must match
list.checkSize(len);
}
else if (!firstToken.isPunctuation())
else if (!tok.isPunctuation())
{
FatalIOErrorInFunction(is)
<< "incorrect first token, expected <label> "
"or '(' or '{', found "
<< firstToken.info()
<< tok.info() << nl
<< exit(FatalIOError);
}
else
{
// Putback the opening bracket
is.putBack(firstToken);
is.putBack(tok);
}
// Read beginning of contents
// Begin of contents marker
const char delimiter = is.readBeginList("FixedList");
if (delimiter == token::BEGIN_LIST)
@ -198,19 +215,21 @@ Foam::Istream& Foam::operator>>(Foam::Istream& is, FixedList<T, N>& list)
is.fatalCheck
(
"operator>>(Istream&, FixedList<T, N>&) : "
"FixedList<T, N>::readList(Istream&) : "
"reading entry"
);
}
}
else
{
// Uniform content (delimiter == token::BEGIN_BLOCK)
T val;
is >> val;
is.fatalCheck
(
"operator>>(Istream&, FixedList<T, N>&) : "
"FixedList<T, N>::readList(Istream&) : "
"reading the single entry"
);
@ -220,29 +239,28 @@ Foam::Istream& Foam::operator>>(Foam::Istream& is, FixedList<T, N>& list)
}
}
// Read end of contents
// End of contents marker
is.readEndList("FixedList");
}
else
{
// Binary and contiguous
Detail::readContiguous<T>
(
is,
reinterpret_cast<char*>(list.data()),
N*sizeof(T)
);
is.fatalCheck
(
"operator>>(Istream&, FixedList<T, N>&) : "
"reading the binary block"
);
}
return is;
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class T, unsigned N>
Foam::FixedList<T, N>::FixedList(Istream& is)
{
this->readList(is);
}
template<class T, unsigned N>
Foam::Istream& Foam::operator>>(Foam::Istream& is, FixedList<T, N>& list)
{
return list.readList(is);
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -302,7 +302,13 @@ public:
void operator=(SLList<T>&& list);
// Istream Operator
// Reading/writing
//- Read List from Istream, discarding contents of existing List
Istream& readList(Istream& is);
// IOstream Operators
//- Read List from Istream, discarding contents of existing List
friend Istream& operator>> <T>

View File

@ -39,23 +39,25 @@ Foam::List<T>::List(Istream& is)
:
UList<T>(nullptr, 0)
{
operator>>(is, *this);
this->readList(is);
}
template<class T>
Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
Foam::Istream& Foam::List<T>::readList(Istream& is)
{
List<T>& list = *this;
// Anull list
list.resize(0);
list.clear();
is.fatalCheck(FUNCTION_NAME);
token firstToken(is);
token tok(is);
is.fatalCheck(FUNCTION_NAME);
is.fatalCheck("List<T>::readList(Istream&) : reading first token");
if (firstToken.isCompound())
if (tok.isCompound())
{
// Compound: simply transfer contents
@ -63,24 +65,42 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
(
dynamicCast<token::Compound<List<T>>>
(
firstToken.transferCompoundToken(is)
tok.transferCompoundToken(is)
)
);
}
else if (firstToken.isLabel())
else if (tok.isLabel())
{
// Label: could be int(..), int{...} or just a plain '0'
const label len = firstToken.labelToken();
const label len = tok.labelToken();
// Resize to length read
// Resize to actual length read
list.resize(len);
// Read list contents depending on data format
if (is.format() == IOstream::ASCII || !is_contiguous<T>::value)
if (is.format() == IOstream::BINARY && is_contiguous<T>::value)
{
// Read beginning of contents
// Binary and contiguous
if (len)
{
Detail::readContiguous<T>
(
is,
reinterpret_cast<char*>(list.data()),
list.size_bytes()
);
is.fatalCheck
(
"List<T>::readList(Istream&) : "
"reading the binary block"
);
}
}
else
{
// Begin of contents marker
const char delimiter = is.readBeginList("List");
if (len)
@ -93,7 +113,7 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
is.fatalCheck
(
"operator>>(Istream&, List<T>&) : "
"List<T>::readList(Istream&) : "
"reading entry"
);
}
@ -102,48 +122,31 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
{
// Uniform content (delimiter == token::BEGIN_BLOCK)
T element;
is >> element;
T elem;
is >> elem;
is.fatalCheck
(
"operator>>(Istream&, List<T>&) : "
"List<T>::readList(Istream&) : "
"reading the single entry"
);
for (label i=0; i<len; ++i)
{
list[i] = element; // Copy the value
list[i] = elem; // Copy the value
}
}
}
// Read end of contents
// End of contents marker
is.readEndList("List");
}
else if (len)
{
// Non-empty, binary, contiguous
Detail::readContiguous<T>
(
is,
reinterpret_cast<char*>(list.data()),
len*sizeof(T)
);
is.fatalCheck
(
"operator>>(Istream&, List<T>&) : "
"reading the binary block"
);
}
}
else if (firstToken.isPunctuation(token::BEGIN_LIST))
else if (tok.isPunctuation(token::BEGIN_LIST))
{
// "(...)" : read as SLList and transfer contents
is.putBack(firstToken); // Putback the opening bracket
is.putBack(tok); // Putback the opening bracket
SLList<T> sll(is); // Read as singly-linked list
// Reallocate and move assign list elements
@ -153,7 +156,7 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
{
FatalIOErrorInFunction(is)
<< "incorrect first token, expected <int> or '(', found "
<< firstToken.info() << nl
<< tok.info() << nl
<< exit(FatalIOError);
}
@ -161,4 +164,11 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
}
template<class T>
Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
{
return list.readList(is);
}
// ************************************************************************* //

View File

@ -459,7 +459,11 @@ public:
bool operator>=(const UList<T>& a) const;
// Writing
// Reading/writing
//- Read List contents from Istream.
// The List must have the proper size before calling
Istream& readList(Istream& is);
//- Write the List as a dictionary entry with keyword
void writeEntry(const word& keyword, Ostream& os) const;
@ -472,7 +476,7 @@ public:
// IOstream Operators
//- Read List contents from Istream.
// Requires size to have been set before
// The List must have the proper size before calling
friend Istream& operator>> <T>
(
Istream& os,

View File

@ -85,10 +85,23 @@ Foam::Ostream& Foam::UList<T>::writeList
const label len = list.size();
// Write list contents depending on data format
if (os.format() == IOstream::ASCII || !is_contiguous<T>::value)
if (os.format() == IOstream::BINARY && is_contiguous<T>::value)
{
if (len > 1 && is_contiguous<T>::value && list.uniform())
// Binary and contiguous
os << nl << len << nl;
if (len)
{
// write(...) includes surrounding start/end delimiters
os.write
(
reinterpret_cast<const char*>(list.cdata()),
list.size_bytes()
);
}
}
else if (len > 1 && is_contiguous<T>::value && list.uniform())
{
// Two or more entries, and all entries have identical values.
os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
@ -101,12 +114,14 @@ Foam::Ostream& Foam::UList<T>::writeList
(len <= shortLen)
&&
(
Detail::ListPolicy::no_linebreak<T>::value
|| is_contiguous<T>::value
is_contiguous<T>::value
|| Detail::ListPolicy::no_linebreak<T>::value
)
)
)
{
// Single-line output
// Size and start delimiter
os << len << token::BEGIN_LIST;
@ -122,6 +137,8 @@ Foam::Ostream& Foam::UList<T>::writeList
}
else
{
// Multi-line output
// Size and start delimiter
os << nl << len << nl << token::BEGIN_LIST << nl;
@ -134,43 +151,27 @@ Foam::Ostream& Foam::UList<T>::writeList
// End delimiter
os << token::END_LIST << nl;
}
}
else
{
// Contents are binary and contiguous
os << nl << len << nl;
if (len)
{
// write(...) includes surrounding start/end delimiters
os.write
(
reinterpret_cast<const char*>(list.cdata()),
list.size_bytes()
);
}
}
os.check(FUNCTION_NAME);
return os;
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class T>
Foam::Istream& Foam::operator>>(Istream& is, UList<T>& list)
Foam::Istream& Foam::UList<T>::readList(Istream& is)
{
UList<T>& list = *this;
// The target list length - must match with sizes read
const label len = list.size();
is.fatalCheck(FUNCTION_NAME);
token firstToken(is);
token tok(is);
is.fatalCheck("operator>>(Istream&, UList<T>&) : reading first token");
is.fatalCheck("UList<T>::readList(Istream&) : reading first token");
if (firstToken.isCompound())
if (tok.isCompound())
{
// Compound: simply transfer contents
@ -179,7 +180,7 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& list)
(
dynamicCast<token::Compound<List<T>>>
(
firstToken.transferCompoundToken(is)
tok.transferCompoundToken(is)
)
);
@ -199,11 +200,11 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& list)
list[i] = std::move(elems[i]);
}
}
else if (firstToken.isLabel())
else if (tok.isLabel())
{
// Label: could be int(..), int{...} or just a plain '0'
const label inputLen = firstToken.labelToken();
const label inputLen = tok.labelToken();
// List lengths must match
if (inputLen != len)
@ -214,11 +215,29 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& list)
<< exit(FatalIOError);
}
// Read list contents depending on data format
if (is.format() == IOstream::ASCII || !is_contiguous<T>::value)
if (is.format() == IOstream::BINARY && is_contiguous<T>::value)
{
// Read beginning of contents
// Binary and contiguous
if (len)
{
Detail::readContiguous<T>
(
is,
reinterpret_cast<char*>(list.data()),
list.size_bytes()
);
is.fatalCheck
(
"UList<T>::readList(Istream&) : "
"reading binary block"
);
}
}
else
{
// Begin of contents marker
const char delimiter = is.readBeginList("List");
if (len)
@ -231,7 +250,8 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& list)
is.fatalCheck
(
"operator>>(Istream&, UList<T>&) : reading entry"
"UList<T>::readList(Istream&) : "
"reading entry"
);
}
}
@ -239,47 +259,31 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& list)
{
// Uniform content (delimiter == token::BEGIN_BLOCK)
T element;
is >> element;
T elem;
is >> elem;
is.fatalCheck
(
"operator>>(Istream&, UList<T>&) : "
"UList<T>::readList(Istream&) : "
"reading the single entry"
);
for (label i=0; i<len; ++i)
{
list[i] = element; // Copy the value
list[i] = elem; // Copy the value
}
}
}
// Read end of contents
// End of contents marker
is.readEndList("List");
}
else if (len)
{
// Non-empty, binary, contiguous
Detail::readContiguous<T>
(
is,
reinterpret_cast<char*>(list.data()),
len*sizeof(T)
);
is.fatalCheck
(
"operator>>(Istream&, UList<T>&) : reading the binary block"
);
}
}
else if (firstToken.isPunctuation(token::BEGIN_LIST))
else if (tok.isPunctuation(token::BEGIN_LIST))
{
// "(...)" : read as SLList and transfer contents
is.putBack(firstToken); // Putback the opening bracket
is.putBack(tok); // Putback the opening bracket
SLList<T> sll(is); // Read as singly-linked list
// List lengths must match
@ -301,7 +305,7 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& list)
{
FatalIOErrorInFunction(is)
<< "incorrect first token, expected <int> or '(', found "
<< firstToken.info() << nl
<< tok.info() << nl
<< exit(FatalIOError);
}
@ -309,4 +313,11 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& list)
}
template<class T>
Foam::Istream& Foam::operator>>(Istream& is, UList<T>& list)
{
return list.readList(is);
}
// ************************************************************************* //

View File

@ -41,20 +41,16 @@ void Foam::PtrList<T>::readIstream(Istream& is, const INew& inew)
is.fatalCheck(FUNCTION_NAME);
token firstToken(is);
token tok(is);
is.fatalCheck
(
"PtrList::readIstream : "
"reading first token"
);
is.fatalCheck("PtrList::readIstream : reading first token");
if (firstToken.isLabel())
if (tok.isLabel())
{
// Label: could be int(..), int{...} or just a plain '0'
// Read size of list
const label len = firstToken.labelToken();
const label len = tok.labelToken();
// Set list length to that read
resize(len);
@ -78,7 +74,7 @@ void Foam::PtrList<T>::readIstream(Istream& is, const INew& inew)
);
}
}
else
else // Assumed to be BEGIN_BLOCK
{
T* p = inew(is).ptr();
set(0, p);
@ -99,7 +95,7 @@ void Foam::PtrList<T>::readIstream(Istream& is, const INew& inew)
// Read end of contents
is.readEndList("PtrList");
}
else if (firstToken.isPunctuation(token::BEGIN_LIST))
else if (tok.isPunctuation(token::BEGIN_LIST))
{
// "(...)" : read as SLList and transfer contents
// This would be more efficient (fewer allocations, lower overhead)
@ -107,20 +103,20 @@ void Foam::PtrList<T>::readIstream(Istream& is, const INew& inew)
SLList<T*> slList;
token lastToken(is);
while (!lastToken.isPunctuation(token::END_LIST))
is >> tok;
while (!tok.isPunctuation(token::END_LIST))
{
is.putBack(lastToken);
is.putBack(tok);
if (is.eof())
{
FatalIOErrorInFunction(is)
<< "Premature EOF after reading " << lastToken.info()
<< "Premature EOF after reading " << tok.info() << nl
<< exit(FatalIOError);
}
slList.append(inew(is).ptr());
is >> lastToken;
is >> tok;
}
resize(slList.size());
@ -136,7 +132,7 @@ void Foam::PtrList<T>::readIstream(Istream& is, const INew& inew)
{
FatalIOErrorInFunction(is)
<< "incorrect first token, expected <int> or '(', found "
<< firstToken.info() << nl
<< tok.info() << nl
<< exit(FatalIOError);
}
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -68,10 +68,26 @@ bool Foam::Matrix<Form, Type>::readMatrix(Istream& is)
// The total size
const label len = size();
// Read list contents depending on data format
if (is.format() == IOstream::ASCII || !is_contiguous<Type>::value)
if (is.format() == IOstream::BINARY && is_contiguous<Type>::value)
{
// Read beginning of contents
// Binary and contiguous
if (len)
{
Detail::readContiguous<Type>
(
is,
reinterpret_cast<char*>(v_),
this->size_bytes()
);
is.fatalCheck("readMatrix : reading the binary block");
}
}
else
{
// Begin of contents marker
char listDelimiter = is.readBeginList("Matrix");
if (len)
@ -88,14 +104,13 @@ bool Foam::Matrix<Form, Type>::readMatrix(Istream& is)
for (label j = 0; j < nCols_; ++j)
{
is >> v_[idx++];
is.fatalCheck("readMatrix : reading reading entry");
is.fatalCheck("readMatrix : reading entry");
}
is.readEndList("MatrixRow");
}
}
else
else // BEGIN_BLOCK
{
Type element;
is >> element;
@ -106,31 +121,16 @@ bool Foam::Matrix<Form, Type>::readMatrix(Istream& is)
}
}
// Read end of contents
// End of contents marker
is.readEndList("Matrix");
}
else
{
if (len)
{
Detail::readContiguous<Type>
(
is,
reinterpret_cast<char*>(v_),
len*sizeof(Type)
);
is.fatalCheck("readMatrix : reading the binary block");
}
}
return len;
}
FatalIOErrorInFunction(is)
<< "incorrect first token, expected <int>, found "
<< firstToken.info()
<< firstToken.info() << nl
<< exit(FatalIOError);
return 0;
@ -150,10 +150,23 @@ Foam::Ostream& Foam::Matrix<Form, Type>::writeMatrix
const label len = mat.size();
// Rows, columns size
os << mat.m() << token::SPACE << mat.n();
os << mat.nRows() << token::SPACE << mat.nCols();
// Write list contents depending on data format
if (os.format() == IOstream::ASCII || !is_contiguous<Type>::value)
if (os.format() == IOstream::BINARY && is_contiguous<Type>::value)
{
// Binary and contiguous
if (len)
{
// write(...) includes surrounding start/end delimiters
os.write
(
reinterpret_cast<const char*>(mat.cdata()),
mat.size_bytes()
);
}
}
else
{
if (len)
{
@ -173,12 +186,12 @@ Foam::Ostream& Foam::Matrix<Form, Type>::writeMatrix
label idx = 0;
// Loop over rows
for (label i = 0; i < mat.m(); ++i)
for (label i = 0; i < mat.nRows(); ++i)
{
os << token::BEGIN_LIST;
// Write row
for (label j = 0; j < mat.n(); ++j)
for (label j = 0; j < mat.nCols(); ++j)
{
if (j) os << token::SPACE;
os << v[idx++];
@ -198,12 +211,12 @@ Foam::Ostream& Foam::Matrix<Form, Type>::writeMatrix
label idx = 0;
// Loop over rows
for (label i=0; i < mat.m(); ++i)
for (label i=0; i < mat.nRows(); ++i)
{
os << nl << token::BEGIN_LIST;
// Write row
for (label j=0; j < mat.n(); ++j)
for (label j = 0; j < mat.nCols(); ++j)
{
os << nl << v[idx++];
}
@ -217,23 +230,10 @@ Foam::Ostream& Foam::Matrix<Form, Type>::writeMatrix
}
else
{
// Empty matrix
os << token::BEGIN_LIST << token::END_LIST << nl;
}
}
else
{
// Contents are binary and contiguous
if (len)
{
// write(...) includes surrounding start/end delimiters
os.write
(
reinterpret_cast<const char*>(mat.cdata()),
len*sizeof(Type)
);
}
}
os.check(FUNCTION_NAME);
return os;