Commit 7cadae56 authored by Andrew Heather's avatar Andrew Heather
Browse files

Merge branch 'feature-io-streams' into 'develop'

low-level binary Ostream output, additional stream classes

See merge request !156
parents 58f46a6b 5aa783f1
......@@ -36,20 +36,22 @@ using namespace Foam;
int main(int argc, char *argv[])
{
IStringStream testStream(Foam::string("1002 sfsd sdfsd"));
IStringStream testStream(Foam::string(" 1002 abcd defg;"));
label i(readLabel(testStream));
Info<< i << endl;
Info<< "label=" << i << nl;
word bla(testStream);
word bla2(testStream);
word w1(testStream);
word w2(testStream);
Info<< bla << tab << bla2 << endl;
Info<< "word=" << w1 << nl;
Info<< "word=" << w2 << nl;
wordList wl(IStringStream("(hello1")());
testStream.reset("(hello1)");
Info<< wl << endl;
wordList wl(testStream);
Info<< wl << nl;
Info<< "\nEnd\n" << endl;
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -27,15 +27,18 @@ Description
#include "IndirectList.H"
#include "IOstreams.H"
#include "Fstream.H"
#include "ListOps.H"
#include "labelIndList.H"
#include "argList.H"
using namespace Foam;
template<class ListType>
void printInfo(const ListType& lst)
{
Info<< "addr: " << flatOutput(lst.addressing()) << nl
Info<< "full: " << flatOutput(lst.completeList()) << nl
<< "addr: " << flatOutput(lst.addressing()) << nl
<< "list: " << flatOutput(lst) << nl
<< endl;
}
......@@ -61,6 +64,15 @@ void testFind(const T& val, const ListType& lst)
int main(int argc, char *argv[])
{
argList::addOption
(
"binary",
"file",
"write lists in binary to specified file"
);
argList args(argc, argv);
List<label> completeList(20);
forAll(completeList, i)
......@@ -104,6 +116,55 @@ int main(int argc, char *argv[])
printInfo(idl2);
printInfo(idl3);
fileName binaryOutput;
if (args.optionReadIfPresent("binary", binaryOutput))
{
Info<<"Writing output to " << binaryOutput << endl;
OFstream os(binaryOutput, IOstream::BINARY);
os.writeEntry("idl1", idl1);
os.writeEntry("idl2", idl2);
os.writeEntry("idl3", idl3);
}
if (Pstream::parRun())
{
if (Pstream::master())
{
Pout<< "full: " << flatOutput(idl3.completeList()) << nl
<< "send: " << flatOutput(idl3) << endl;
for
(
int slave = Pstream::firstSlave();
slave <= Pstream::lastSlave();
++slave
)
{
OPstream toSlave(Pstream::commsTypes::scheduled, slave);
toSlave << idl3;
}
}
else
{
// From master
IPstream fromMaster
(
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
List<label> recv(fromMaster);
Pout<<"recv: " << flatOutput(recv) << endl;
}
// MPI barrier
bool barrier = true;
Pstream::scatter(barrier);
}
Info<< "End\n" << endl;
return 0;
......
Test-OListStream.C
EXE = $(FOAM_USER_APPBIN)/Test-OListStream
/* EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude */
/* EXE_LIBS = -lfiniteVolume */
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
\*---------------------------------------------------------------------------*/
#include "OListStream.H"
#include "wordList.H"
#include "IOstreams.H"
#include "argList.H"
using namespace Foam;
Ostream& toString(Ostream& os, const UList<char>& list)
{
os << '"';
for (const char c : list)
{
os << c;
}
os << '"';
return os;
}
void printInfo(const OListStream& buf)
{
Info<< nl << buf.size() << " chars (" << buf.capacity() << " capacity) ";
toString(Info, buf.list()) << endl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
// Buffer storage
DynamicList<char> storage(8);
OListStream obuf(std::move(storage));
obuf << 1002 << " " << "abcd" << " " << "def" << " " << 3.14159 << ";\n";
printInfo(obuf);
obuf.rewind();
obuf << 100;
printInfo(obuf);
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //
Test-UIBufStream.C
EXE = $(FOAM_USER_APPBIN)/Test-UIBufStream
/* EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude */
/* EXE_LIBS = -lfiniteVolume */
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
\*---------------------------------------------------------------------------*/
#include "UIBufStream.H"
#include "UOBufStream.H"
#include "wordList.H"
#include "IOstreams.H"
#include "argList.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
// Buffer storage
DynamicList<char> storage(1000);
UOBufStream obuf(storage);
obuf << 1002 << " " << "abcd" << " " << "def" << " " << 3.14159 << ";\n";
Info<<"formatted: " << obuf.size() << " chars" << endl;
// Match size
storage.resize(obuf.size());
Info<<"as string: " << string(storage.cdata(), storage.size()) << endl;
// Attach input buffer - could also do without previous resize
UIBufStream ibuf(storage, storage.size());
token t;
while (ibuf.good())
{
ibuf >> t;
if (t.good())
{
Info<<"token: " << t << endl;
}
}
Info<< nl << "Repeat..." << endl;
ibuf.rewind();
while (ibuf.good())
{
ibuf >> t;
if (t.good())
{
Info<<"token: " << t << endl;
}
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //
......@@ -91,10 +91,10 @@ Foam::Ostream& Foam::FixedList<T, Size>::writeList
// Write size (so it is valid dictionary entry) and start delimiter
os << Size << token::BEGIN_BLOCK;
// Write contents
// Contents
os << L[0];
// Write end delimiter
// End delimiter
os << token::END_BLOCK;
}
else if
......@@ -103,31 +103,31 @@ Foam::Ostream& Foam::FixedList<T, Size>::writeList
|| (Size <= unsigned(shortListLen) && contiguous<T>())
)
{
// Write start delimiter
// Start delimiter
os << token::BEGIN_LIST;
// Write contents
// Contents
forAll(L, i)
{
if (i) os << token::SPACE;
os << L[i];
}
// Write end delimiter
// End delimiter
os << token::END_LIST;
}
else
{
// Write start delimiter
// Start delimiter
os << nl << token::BEGIN_LIST << nl;
// Write contents
// Contents
forAll(L, i)
{
os << L[i] << nl;
}
// Write end delimiter
// End delimiter
os << token::END_LIST << nl;
}
}
......
......@@ -64,10 +64,10 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
}
else if (firstToken.isLabel())
{
const label s = firstToken.labelToken();
const label sz = firstToken.labelToken();
// Set list length to that read
L.setSize(s);
L.setSize(sz);
// Read list contents depending on data format
......@@ -76,11 +76,11 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
// Read beginning of contents
const char delimiter = is.readBeginList("List");
if (s)
if (sz)
{
if (delimiter == token::BEGIN_LIST)
{
for (label i=0; i<s; ++i)
for (label i=0; i<sz; ++i)
{
is >> L[i];
......@@ -103,7 +103,7 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
"reading the single entry"
);
for (label i=0; i<s; ++i)
for (label i=0; i<sz; ++i)
{
L[i] = element;
}
......@@ -115,11 +115,11 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
}
else
{
// contents are binary and contiguous
// Contents are binary and contiguous
if (s)
if (sz)
{
is.read(reinterpret_cast<char*>(L.data()), s*sizeof(T));
is.read(reinterpret_cast<char*>(L.data()), sz*sizeof(T));
is.fatalCheck
(
......
......@@ -48,19 +48,19 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inewt)
if (firstToken.isLabel())
{
// Read size of list
const label s = firstToken.labelToken();
const label sz = firstToken.labelToken();
// Set list length to that read
setSize(s);
setSize(sz);
// Read beginning of contents
const char delimiter = is.readBeginList("PtrList");
if (s)
if (sz)
{
if (delimiter == token::BEGIN_LIST)
{
forAll(*this, i)
for (label i=0; i<sz; ++i)
{
set(i, inewt(is));
......@@ -82,7 +82,7 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inewt)
"reading the single entry"
);
for (label i=1; i<s; ++i)
for (label i=1; i<sz; ++i)
{
set(i, tPtr->clone());
}
......
......@@ -39,14 +39,16 @@ Foam::Ostream& Foam::UIndirectList<T>::writeList
{
const UIndirectList<T>& L = *this;
const label sz = L.size();
// Write list contents depending on data format
if (os.format() == IOstream::ASCII || !contiguous<T>())
{
// Can the contents be considered 'uniform' (ie, identical)?
bool uniform = (L.size() > 1 && contiguous<T>());
bool uniform = (sz > 1 && contiguous<T>());
if (uniform)
{
forAll(L, i)
for (label i=1; i < sz; ++i)
{
if (L[i] != L[0])
{
......@@ -58,65 +60,72 @@ Foam::Ostream& Foam::UIndirectList<T>::writeList
if (uniform)
{
// Write size and start delimiter
os << L.size() << token::BEGIN_BLOCK;
// Size and start delimiter
os << sz << token::BEGIN_BLOCK;
// Write contents
// Contents
os << L[0];
// Write end delimiter
// End delimiter
os << token::END_BLOCK;
}
else if
(
L.size() <= 1 || !shortListLen
|| (L.size() <= shortListLen && contiguous<T>())
sz <= 1 || !shortListLen
|| (sz <= shortListLen && contiguous<T>())
)
{
// Write size and start delimiter
os << L.size() << token::BEGIN_LIST;
// Size and start delimiter
os << sz << token::BEGIN_LIST;
// Write contents
forAll(L, i)
// Contents
for (label i=0; i < sz; ++i)
{
if (i) os << token::SPACE;
os << L[i];
}
// Write end delimiter
// End delimiter
os << token::END_LIST;
}
else
{
// Write size and start delimiter
os << nl << L.size() << nl << token::BEGIN_LIST << nl;
// Size and start delimiter
os << nl << sz << nl << token::BEGIN_LIST << nl;
// Write contents
forAll(L, i)
// Contents
for (label i=0; i < sz; ++i)
{
os << L[i] << nl;
}
// Write end delimiter
// End delimiter
os << token::END_LIST << nl;
}
}
else
{
// Contents are binary and contiguous
os << nl << L.size() << nl;
os << nl << sz << nl;
if (L.size())
if (sz)
{
// This is annoying, and wasteful, but currently no alternative
List<T> lst = L();
// write(...) includes surrounding start/end delimiters
os.write
(
reinterpret_cast<const char*>(lst.cdata()),
lst.byteSize()
);
// The TOTAL number of bytes to be written.
// - possibly add start delimiter
os.beginRaw(sz*sizeof(T));
// Contents
for (label i=0; i < sz; ++i)
{
os.writeRaw
(
reinterpret_cast<const char*>(&(L[i])),
sizeof(T)
);
}
// End delimiter and/or cleanup.
os.endRaw();
}
}
......
......@@ -76,14 +76,16 @@ Foam::Ostream& Foam::UList<T>::writeList
{
const UList<T>& L = *this;
const label sz = L.size();
// Write list contents depending on data format
if (os.format() == IOstream::ASCII || !contiguous<T>())
{
// Can the contents be considered 'uniform' (ie, identical)?
bool uniform = (L.size() > 1 && contiguous<T>());
bool uniform = (sz > 1 && contiguous<T>());
if (uniform)
{
forAll(L, i)
for (label i=1; i < sz; ++i)
{
if (L[i] != L[0])
{
......@@ -95,58 +97,62 @@ Foam::Ostream& Foam::UList<T>::writeList
if (uniform)
{
// Write size and start delimiter
os << L.size() << token::BEGIN_BLOCK;
// Size and start delimiter
os << sz << token::BEGIN_BLOCK;
// Write contents
// Contents
os << L[0];