mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: additional low-level raw binary output for Ostream.
- low-level beginRaw(), writeRaw(), endRaw() methods. These can be used to directly add '()' decorators for serial output or prepare/cleanup parallel buffers. Used, for example, when outputting indirect lists in binary to avoid.
This commit is contained in:
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -27,15 +27,18 @@ Description
|
|||||||
|
|
||||||
#include "IndirectList.H"
|
#include "IndirectList.H"
|
||||||
#include "IOstreams.H"
|
#include "IOstreams.H"
|
||||||
|
#include "Fstream.H"
|
||||||
#include "ListOps.H"
|
#include "ListOps.H"
|
||||||
#include "labelIndList.H"
|
#include "labelIndList.H"
|
||||||
|
#include "argList.H"
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
template<class ListType>
|
template<class ListType>
|
||||||
void printInfo(const ListType& lst)
|
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
|
<< "list: " << flatOutput(lst) << nl
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
@ -61,6 +64,15 @@ void testFind(const T& val, const ListType& lst)
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
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);
|
List<label> completeList(20);
|
||||||
|
|
||||||
forAll(completeList, i)
|
forAll(completeList, i)
|
||||||
@ -104,6 +116,55 @@ int main(int argc, char *argv[])
|
|||||||
printInfo(idl2);
|
printInfo(idl2);
|
||||||
printInfo(idl3);
|
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;
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -91,10 +91,10 @@ Foam::Ostream& Foam::FixedList<T, Size>::writeList
|
|||||||
// Write size (so it is valid dictionary entry) and start delimiter
|
// Write size (so it is valid dictionary entry) and start delimiter
|
||||||
os << Size << token::BEGIN_BLOCK;
|
os << Size << token::BEGIN_BLOCK;
|
||||||
|
|
||||||
// Write contents
|
// Contents
|
||||||
os << L[0];
|
os << L[0];
|
||||||
|
|
||||||
// Write end delimiter
|
// End delimiter
|
||||||
os << token::END_BLOCK;
|
os << token::END_BLOCK;
|
||||||
}
|
}
|
||||||
else if
|
else if
|
||||||
@ -103,31 +103,31 @@ Foam::Ostream& Foam::FixedList<T, Size>::writeList
|
|||||||
|| (Size <= unsigned(shortListLen) && contiguous<T>())
|
|| (Size <= unsigned(shortListLen) && contiguous<T>())
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Write start delimiter
|
// Start delimiter
|
||||||
os << token::BEGIN_LIST;
|
os << token::BEGIN_LIST;
|
||||||
|
|
||||||
// Write contents
|
// Contents
|
||||||
forAll(L, i)
|
forAll(L, i)
|
||||||
{
|
{
|
||||||
if (i) os << token::SPACE;
|
if (i) os << token::SPACE;
|
||||||
os << L[i];
|
os << L[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write end delimiter
|
// End delimiter
|
||||||
os << token::END_LIST;
|
os << token::END_LIST;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Write start delimiter
|
// Start delimiter
|
||||||
os << nl << token::BEGIN_LIST << nl;
|
os << nl << token::BEGIN_LIST << nl;
|
||||||
|
|
||||||
// Write contents
|
// Contents
|
||||||
forAll(L, i)
|
forAll(L, i)
|
||||||
{
|
{
|
||||||
os << L[i] << nl;
|
os << L[i] << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write end delimiter
|
// End delimiter
|
||||||
os << token::END_LIST << nl;
|
os << token::END_LIST << nl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -64,10 +64,10 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
|
|||||||
}
|
}
|
||||||
else if (firstToken.isLabel())
|
else if (firstToken.isLabel())
|
||||||
{
|
{
|
||||||
const label s = firstToken.labelToken();
|
const label sz = firstToken.labelToken();
|
||||||
|
|
||||||
// Set list length to that read
|
// Set list length to that read
|
||||||
L.setSize(s);
|
L.setSize(sz);
|
||||||
|
|
||||||
// Read list contents depending on data format
|
// Read list contents depending on data format
|
||||||
|
|
||||||
@ -76,11 +76,11 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
|
|||||||
// Read beginning of contents
|
// Read beginning of contents
|
||||||
const char delimiter = is.readBeginList("List");
|
const char delimiter = is.readBeginList("List");
|
||||||
|
|
||||||
if (s)
|
if (sz)
|
||||||
{
|
{
|
||||||
if (delimiter == token::BEGIN_LIST)
|
if (delimiter == token::BEGIN_LIST)
|
||||||
{
|
{
|
||||||
for (label i=0; i<s; ++i)
|
for (label i=0; i<sz; ++i)
|
||||||
{
|
{
|
||||||
is >> L[i];
|
is >> L[i];
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
|
|||||||
"reading the single entry"
|
"reading the single entry"
|
||||||
);
|
);
|
||||||
|
|
||||||
for (label i=0; i<s; ++i)
|
for (label i=0; i<sz; ++i)
|
||||||
{
|
{
|
||||||
L[i] = element;
|
L[i] = element;
|
||||||
}
|
}
|
||||||
@ -115,11 +115,11 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
|
|||||||
}
|
}
|
||||||
else
|
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
|
is.fatalCheck
|
||||||
(
|
(
|
||||||
|
|||||||
@ -48,19 +48,19 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inewt)
|
|||||||
if (firstToken.isLabel())
|
if (firstToken.isLabel())
|
||||||
{
|
{
|
||||||
// Read size of list
|
// Read size of list
|
||||||
const label s = firstToken.labelToken();
|
const label sz = firstToken.labelToken();
|
||||||
|
|
||||||
// Set list length to that read
|
// Set list length to that read
|
||||||
setSize(s);
|
setSize(sz);
|
||||||
|
|
||||||
// Read beginning of contents
|
// Read beginning of contents
|
||||||
const char delimiter = is.readBeginList("PtrList");
|
const char delimiter = is.readBeginList("PtrList");
|
||||||
|
|
||||||
if (s)
|
if (sz)
|
||||||
{
|
{
|
||||||
if (delimiter == token::BEGIN_LIST)
|
if (delimiter == token::BEGIN_LIST)
|
||||||
{
|
{
|
||||||
forAll(*this, i)
|
for (label i=0; i<sz; ++i)
|
||||||
{
|
{
|
||||||
set(i, inewt(is));
|
set(i, inewt(is));
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inewt)
|
|||||||
"reading the single entry"
|
"reading the single entry"
|
||||||
);
|
);
|
||||||
|
|
||||||
for (label i=1; i<s; ++i)
|
for (label i=1; i<sz; ++i)
|
||||||
{
|
{
|
||||||
set(i, tPtr->clone());
|
set(i, tPtr->clone());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,14 +39,16 @@ Foam::Ostream& Foam::UIndirectList<T>::writeList
|
|||||||
{
|
{
|
||||||
const UIndirectList<T>& L = *this;
|
const UIndirectList<T>& L = *this;
|
||||||
|
|
||||||
|
const label sz = L.size();
|
||||||
|
|
||||||
// Write list contents depending on data format
|
// Write list contents depending on data format
|
||||||
if (os.format() == IOstream::ASCII || !contiguous<T>())
|
if (os.format() == IOstream::ASCII || !contiguous<T>())
|
||||||
{
|
{
|
||||||
// Can the contents be considered 'uniform' (ie, identical)?
|
// Can the contents be considered 'uniform' (ie, identical)?
|
||||||
bool uniform = (L.size() > 1 && contiguous<T>());
|
bool uniform = (sz > 1 && contiguous<T>());
|
||||||
if (uniform)
|
if (uniform)
|
||||||
{
|
{
|
||||||
forAll(L, i)
|
for (label i=1; i < sz; ++i)
|
||||||
{
|
{
|
||||||
if (L[i] != L[0])
|
if (L[i] != L[0])
|
||||||
{
|
{
|
||||||
@ -58,66 +60,73 @@ Foam::Ostream& Foam::UIndirectList<T>::writeList
|
|||||||
|
|
||||||
if (uniform)
|
if (uniform)
|
||||||
{
|
{
|
||||||
// Write size and start delimiter
|
// Size and start delimiter
|
||||||
os << L.size() << token::BEGIN_BLOCK;
|
os << sz << token::BEGIN_BLOCK;
|
||||||
|
|
||||||
// Write contents
|
// Contents
|
||||||
os << L[0];
|
os << L[0];
|
||||||
|
|
||||||
// Write end delimiter
|
// End delimiter
|
||||||
os << token::END_BLOCK;
|
os << token::END_BLOCK;
|
||||||
}
|
}
|
||||||
else if
|
else if
|
||||||
(
|
(
|
||||||
L.size() <= 1 || !shortListLen
|
sz <= 1 || !shortListLen
|
||||||
|| (L.size() <= shortListLen && contiguous<T>())
|
|| (sz <= shortListLen && contiguous<T>())
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Write size and start delimiter
|
// Size and start delimiter
|
||||||
os << L.size() << token::BEGIN_LIST;
|
os << sz << token::BEGIN_LIST;
|
||||||
|
|
||||||
// Write contents
|
// Contents
|
||||||
forAll(L, i)
|
for (label i=0; i < sz; ++i)
|
||||||
{
|
{
|
||||||
if (i) os << token::SPACE;
|
if (i) os << token::SPACE;
|
||||||
os << L[i];
|
os << L[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write end delimiter
|
// End delimiter
|
||||||
os << token::END_LIST;
|
os << token::END_LIST;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Write size and start delimiter
|
// Size and start delimiter
|
||||||
os << nl << L.size() << nl << token::BEGIN_LIST << nl;
|
os << nl << sz << nl << token::BEGIN_LIST << nl;
|
||||||
|
|
||||||
// Write contents
|
// Contents
|
||||||
forAll(L, i)
|
for (label i=0; i < sz; ++i)
|
||||||
{
|
{
|
||||||
os << L[i] << nl;
|
os << L[i] << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write end delimiter
|
// End delimiter
|
||||||
os << token::END_LIST << nl;
|
os << token::END_LIST << nl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Contents are binary and contiguous
|
// 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
|
// The TOTAL number of bytes to be written.
|
||||||
List<T> lst = L();
|
// - possibly add start delimiter
|
||||||
|
os.beginRaw(sz*sizeof(T));
|
||||||
|
|
||||||
// write(...) includes surrounding start/end delimiters
|
// Contents
|
||||||
os.write
|
for (label i=0; i < sz; ++i)
|
||||||
|
{
|
||||||
|
os.writeRaw
|
||||||
(
|
(
|
||||||
reinterpret_cast<const char*>(lst.cdata()),
|
reinterpret_cast<const char*>(&(L[i])),
|
||||||
lst.byteSize()
|
sizeof(T)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// End delimiter and/or cleanup.
|
||||||
|
os.endRaw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
os.check(FUNCTION_NAME);
|
os.check(FUNCTION_NAME);
|
||||||
|
|||||||
@ -76,14 +76,16 @@ Foam::Ostream& Foam::UList<T>::writeList
|
|||||||
{
|
{
|
||||||
const UList<T>& L = *this;
|
const UList<T>& L = *this;
|
||||||
|
|
||||||
|
const label sz = L.size();
|
||||||
|
|
||||||
// Write list contents depending on data format
|
// Write list contents depending on data format
|
||||||
if (os.format() == IOstream::ASCII || !contiguous<T>())
|
if (os.format() == IOstream::ASCII || !contiguous<T>())
|
||||||
{
|
{
|
||||||
// Can the contents be considered 'uniform' (ie, identical)?
|
// Can the contents be considered 'uniform' (ie, identical)?
|
||||||
bool uniform = (L.size() > 1 && contiguous<T>());
|
bool uniform = (sz > 1 && contiguous<T>());
|
||||||
if (uniform)
|
if (uniform)
|
||||||
{
|
{
|
||||||
forAll(L, i)
|
for (label i=1; i < sz; ++i)
|
||||||
{
|
{
|
||||||
if (L[i] != L[0])
|
if (L[i] != L[0])
|
||||||
{
|
{
|
||||||
@ -95,58 +97,62 @@ Foam::Ostream& Foam::UList<T>::writeList
|
|||||||
|
|
||||||
if (uniform)
|
if (uniform)
|
||||||
{
|
{
|
||||||
// Write size and start delimiter
|
// Size and start delimiter
|
||||||
os << L.size() << token::BEGIN_BLOCK;
|
os << sz << token::BEGIN_BLOCK;
|
||||||
|
|
||||||
// Write contents
|
// Contents
|
||||||
os << L[0];
|
os << L[0];
|
||||||
|
|
||||||
// Write end delimiter
|
// End delimiter
|
||||||
os << token::END_BLOCK;
|
os << token::END_BLOCK;
|
||||||
}
|
}
|
||||||
else if
|
else if
|
||||||
(
|
(
|
||||||
L.size() <= 1 || !shortListLen
|
sz <= 1 || !shortListLen
|
||||||
|| (L.size() <= shortListLen && contiguous<T>())
|
|| (sz <= shortListLen && contiguous<T>())
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Write size and start delimiter
|
// Size and start delimiter
|
||||||
os << L.size() << token::BEGIN_LIST;
|
os << sz << token::BEGIN_LIST;
|
||||||
|
|
||||||
// Write contents
|
// Contents
|
||||||
forAll(L, i)
|
for (label i=0; i < sz; ++i)
|
||||||
{
|
{
|
||||||
if (i) os << token::SPACE;
|
if (i) os << token::SPACE;
|
||||||
os << L[i];
|
os << L[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write end delimiter
|
// End delimiter
|
||||||
os << token::END_LIST;
|
os << token::END_LIST;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Write size and start delimiter
|
// Size and start delimiter
|
||||||
os << nl << L.size() << nl << token::BEGIN_LIST << nl;
|
os << nl << sz << nl << token::BEGIN_LIST << nl;
|
||||||
|
|
||||||
// Write contents
|
// Contents
|
||||||
forAll(L, i)
|
for (label i=0; i < sz; ++i)
|
||||||
{
|
{
|
||||||
os << L[i] << nl;
|
os << L[i] << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write end delimiter
|
// End delimiter
|
||||||
os << token::END_LIST << nl;
|
os << token::END_LIST << nl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Contents are binary and contiguous
|
// Contents are binary and contiguous
|
||||||
os << nl << L.size() << nl;
|
os << nl << sz << nl;
|
||||||
|
|
||||||
if (L.size())
|
if (sz)
|
||||||
{
|
{
|
||||||
// write(...) includes surrounding start/end delimiters
|
// write(...) includes surrounding start/end delimiters
|
||||||
os.write(reinterpret_cast<const char*>(L.cdata()), L.byteSize());
|
os.write
|
||||||
|
(
|
||||||
|
reinterpret_cast<const char*>(L.cdata()),
|
||||||
|
L.byteSize()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,29 +190,29 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
// Check list length
|
// Check list length
|
||||||
const label s = elems.size();
|
const label sz = elems.size();
|
||||||
|
|
||||||
if (s != L.size())
|
if (sz != L.size())
|
||||||
{
|
{
|
||||||
FatalIOErrorInFunction(is)
|
FatalIOErrorInFunction(is)
|
||||||
<< "incorrect length for UList. Read " << s
|
<< "incorrect length for UList. Read " << sz
|
||||||
<< " expected " << L.size()
|
<< " expected " << L.size()
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
}
|
}
|
||||||
for (label i=0; i<s; ++i)
|
for (label i=0; i<sz; ++i)
|
||||||
{
|
{
|
||||||
L[i] = elems[i];
|
L[i] = elems[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (firstToken.isLabel())
|
else if (firstToken.isLabel())
|
||||||
{
|
{
|
||||||
const label s = firstToken.labelToken();
|
const label sz = firstToken.labelToken();
|
||||||
|
|
||||||
// Set list length to that read
|
// Set list length to that read
|
||||||
if (s != L.size())
|
if (sz != L.size())
|
||||||
{
|
{
|
||||||
FatalIOErrorInFunction(is)
|
FatalIOErrorInFunction(is)
|
||||||
<< "incorrect length for UList. Read " << s
|
<< "incorrect length for UList. Read " << sz
|
||||||
<< " expected " << L.size()
|
<< " expected " << L.size()
|
||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
}
|
}
|
||||||
@ -218,11 +224,11 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
|
|||||||
// Read beginning of contents
|
// Read beginning of contents
|
||||||
const char delimiter = is.readBeginList("List");
|
const char delimiter = is.readBeginList("List");
|
||||||
|
|
||||||
if (s)
|
if (sz)
|
||||||
{
|
{
|
||||||
if (delimiter == token::BEGIN_LIST)
|
if (delimiter == token::BEGIN_LIST)
|
||||||
{
|
{
|
||||||
for (label i=0; i<s; ++i)
|
for (label i=0; i<sz; ++i)
|
||||||
{
|
{
|
||||||
is >> L[i];
|
is >> L[i];
|
||||||
|
|
||||||
@ -245,7 +251,7 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
|
|||||||
"reading the single entry"
|
"reading the single entry"
|
||||||
);
|
);
|
||||||
|
|
||||||
for (label i=0; i<s; ++i)
|
for (label i=0; i<sz; ++i)
|
||||||
{
|
{
|
||||||
L[i] = element;
|
L[i] = element;
|
||||||
}
|
}
|
||||||
@ -259,9 +265,9 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
|
|||||||
{
|
{
|
||||||
// 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
|
is.fatalCheck
|
||||||
(
|
(
|
||||||
|
|||||||
@ -31,18 +31,20 @@ License
|
|||||||
template<class T>
|
template<class T>
|
||||||
Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList<T>& L)
|
Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList<T>& L)
|
||||||
{
|
{
|
||||||
// Write size and start delimiter
|
const label sz = L.size();
|
||||||
os << nl << indent << L.size() << nl
|
|
||||||
<< indent << token::BEGIN_LIST << incrIndent;
|
|
||||||
|
|
||||||
// Write contents
|
// Size and start delimiter
|
||||||
forAll(L, i)
|
os << nl << indent << sz << nl
|
||||||
|
<< indent << token::BEGIN_LIST << incrIndent << nl;
|
||||||
|
|
||||||
|
// Contents
|
||||||
|
for (label i=0; i < sz; ++i)
|
||||||
{
|
{
|
||||||
os << nl << L[i];
|
os << L[i] << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write end delimiter
|
// End delimiter
|
||||||
os << nl << decrIndent << indent << token::END_LIST << nl;
|
os << decrIndent << indent << token::END_LIST << nl;
|
||||||
|
|
||||||
os.check(FUNCTION_NAME);
|
os.check(FUNCTION_NAME);
|
||||||
return os;
|
return os;
|
||||||
|
|||||||
@ -97,47 +97,62 @@ public:
|
|||||||
// Write functions
|
// Write functions
|
||||||
|
|
||||||
//- Write next token to stream
|
//- Write next token to stream
|
||||||
virtual Ostream& write(const token&) = 0;
|
virtual Ostream& write(const token& t) = 0;
|
||||||
|
|
||||||
//- Write character
|
//- Write character
|
||||||
virtual Ostream& write(const char) = 0;
|
virtual Ostream& write(const char c) = 0;
|
||||||
|
|
||||||
//- Write character string
|
//- Write character string
|
||||||
virtual Ostream& write(const char*) = 0;
|
virtual Ostream& write(const char* str) = 0;
|
||||||
|
|
||||||
//- Write word
|
//- Write word
|
||||||
virtual Ostream& write(const word&) = 0;
|
virtual Ostream& write(const word& str) = 0;
|
||||||
|
|
||||||
//- Write keyType
|
//- Write keyType
|
||||||
// A plain word is written unquoted.
|
// A plain word is written unquoted.
|
||||||
// A regular expression is written as a quoted string.
|
// A regular expression is written as a quoted string.
|
||||||
virtual Ostream& write(const keyType&);
|
virtual Ostream& write(const keyType& kw);
|
||||||
|
|
||||||
//- Write string
|
//- Write string
|
||||||
virtual Ostream& write(const string&) = 0;
|
virtual Ostream& write(const string& str) = 0;
|
||||||
|
|
||||||
//- Write std::string surrounded by quotes.
|
//- Write std::string surrounded by quotes.
|
||||||
// Optional write without quotes.
|
// Optional write without quotes.
|
||||||
virtual Ostream& writeQuoted
|
virtual Ostream& writeQuoted
|
||||||
(
|
(
|
||||||
const std::string&,
|
const std::string& str,
|
||||||
const bool quoted=true
|
const bool quoted=true
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
//- Write int32_t
|
//- Write int32_t
|
||||||
virtual Ostream& write(const int32_t) = 0;
|
virtual Ostream& write(const int32_t val) = 0;
|
||||||
|
|
||||||
//- Write int64_t
|
//- Write int64_t
|
||||||
virtual Ostream& write(const int64_t) = 0;
|
virtual Ostream& write(const int64_t val) = 0;
|
||||||
|
|
||||||
//- Write floatScalar
|
//- Write floatScalar
|
||||||
virtual Ostream& write(const floatScalar) = 0;
|
virtual Ostream& write(const floatScalar val) = 0;
|
||||||
|
|
||||||
//- Write doubleScalar
|
//- Write doubleScalar
|
||||||
virtual Ostream& write(const doubleScalar) = 0;
|
virtual Ostream& write(const doubleScalar val) = 0;
|
||||||
|
|
||||||
//- Write binary block
|
//- Write binary block.
|
||||||
virtual Ostream& write(const char*, std::streamsize) = 0;
|
virtual Ostream& write(const char* data, std::streamsize count) = 0;
|
||||||
|
|
||||||
|
//- Emit begin marker for low-level raw binary output.
|
||||||
|
// The count should indicate the number of bytes for subsequent
|
||||||
|
// writeRaw calls.
|
||||||
|
virtual Ostream& beginRaw(std::streamsize count) = 0;
|
||||||
|
|
||||||
|
//- Low-level raw binary output.
|
||||||
|
virtual Ostream& writeRaw
|
||||||
|
(
|
||||||
|
const char* data,
|
||||||
|
std::streamsize count
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
//- Emit end marker for low-level raw binary output.
|
||||||
|
virtual Ostream& endRaw() = 0;
|
||||||
|
|
||||||
//- Add indentation characters
|
//- Add indentation characters
|
||||||
virtual void indent() = 0;
|
virtual void indent() = 0;
|
||||||
@ -164,11 +179,11 @@ public:
|
|||||||
void decrIndent();
|
void decrIndent();
|
||||||
|
|
||||||
//- Write the keyword followed by an appropriate indentation
|
//- Write the keyword followed by an appropriate indentation
|
||||||
virtual Ostream& writeKeyword(const keyType&);
|
virtual Ostream& writeKeyword(const keyType& kw);
|
||||||
|
|
||||||
//- Write begin block group with the given name
|
//- Write begin block group with the given name
|
||||||
// Increments indentation, adds newline.
|
// Increments indentation, adds newline.
|
||||||
virtual Ostream& beginBlock(const keyType&);
|
virtual Ostream& beginBlock(const keyType& keyword);
|
||||||
|
|
||||||
//- Write begin block group without a name
|
//- Write begin block group without a name
|
||||||
// Increments indentation, adds newline.
|
// Increments indentation, adds newline.
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
|
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -26,15 +26,42 @@ License
|
|||||||
#include "UOPstream.H"
|
#include "UOPstream.H"
|
||||||
#include "int.H"
|
#include "int.H"
|
||||||
#include "token.H"
|
#include "token.H"
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class T>
|
inline void Foam::UOPstream::prepareBuffer
|
||||||
inline void Foam::UOPstream::writeToBuffer(const T& t)
|
(
|
||||||
|
const size_t count,
|
||||||
|
const size_t align
|
||||||
|
)
|
||||||
{
|
{
|
||||||
writeToBuffer(&t, sizeof(T), sizeof(T));
|
if (!count)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The current output position
|
||||||
|
label pos = sendBuf_.size();
|
||||||
|
|
||||||
|
if (align > 1)
|
||||||
|
{
|
||||||
|
// Align output position. Pads sendBuf_.size() - oldPos characters.
|
||||||
|
pos = align + ((pos - 1) & ~(align - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extend buffer (as required)
|
||||||
|
sendBuf_.reserve(max(1000, label(pos + count)));
|
||||||
|
|
||||||
|
// Move to the aligned output position
|
||||||
|
sendBuf_.setSize(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline void Foam::UOPstream::writeToBuffer(const T& val)
|
||||||
|
{
|
||||||
|
writeToBuffer(&val, sizeof(T), sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -55,25 +82,26 @@ inline void Foam::UOPstream::writeToBuffer
|
|||||||
const size_t align
|
const size_t align
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!sendBuf_.capacity())
|
if (!count)
|
||||||
{
|
{
|
||||||
sendBuf_.setCapacity(1000);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
label alignedPos = sendBuf_.size();
|
prepareBuffer(count, align);
|
||||||
|
|
||||||
if (align > 1)
|
// The aligned output position
|
||||||
|
const label pos = sendBuf_.size();
|
||||||
|
|
||||||
|
// Extend the addressable range for direct pointer access
|
||||||
|
sendBuf_.setSize(pos + count);
|
||||||
|
|
||||||
|
char* const __restrict__ buf = (sendBuf_.begin() + pos);
|
||||||
|
const char* const __restrict__ input = reinterpret_cast<const char*>(data);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
// Align bufPosition. Pads sendBuf_.size() - oldPos characters.
|
buf[i] = input[i];
|
||||||
alignedPos = align + ((sendBuf_.size() - 1) & ~(align - 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extend if necessary
|
|
||||||
sendBuf_.setSize(alignedPos + count);
|
|
||||||
|
|
||||||
const char* dataPtr = reinterpret_cast<const char*>(data);
|
|
||||||
size_t i = count;
|
|
||||||
while (i--) sendBuf_[alignedPos++] = *dataPtr++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -298,6 +326,41 @@ Foam::Ostream& Foam::UOPstream::write
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::Ostream& Foam::UOPstream::beginRaw
|
||||||
|
(
|
||||||
|
const std::streamsize count
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (format() != BINARY)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "stream format not binary"
|
||||||
|
<< Foam::abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alignment = 8, as per write(const char*, streamsize)
|
||||||
|
prepareBuffer(count, 8);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::Ostream& Foam::UOPstream::writeRaw
|
||||||
|
(
|
||||||
|
const char* data,
|
||||||
|
const std::streamsize count
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// No check for format() == BINARY since this is either done in the
|
||||||
|
// beginRaw() method, or the caller knows what they are doing.
|
||||||
|
|
||||||
|
// Previously aligned and sizes reserved via beginRaw()
|
||||||
|
writeToBuffer(data, count, 1);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::UOPstream::print(Ostream& os) const
|
void Foam::UOPstream::print(Ostream& os) const
|
||||||
{
|
{
|
||||||
os << "Writing from processor " << toProcNo_
|
os << "Writing from processor " << toProcNo_
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -72,9 +72,12 @@ class UOPstream
|
|||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Write a T to the transfer buffer
|
//- Prepare buffer for count bytes of output at specified alignment.
|
||||||
|
inline void prepareBuffer(const size_t count, const size_t align);
|
||||||
|
|
||||||
|
//- Write data to the transfer buffer
|
||||||
template<class T>
|
template<class T>
|
||||||
inline void writeToBuffer(const T& t);
|
inline void writeToBuffer(const T& val);
|
||||||
|
|
||||||
//- Write a char to the transfer buffer
|
//- Write a char to the transfer buffer
|
||||||
inline void writeToBuffer(const char& c);
|
inline void writeToBuffer(const char& c);
|
||||||
@ -182,6 +185,24 @@ public:
|
|||||||
//- Write binary block with 8-byte alignment.
|
//- Write binary block with 8-byte alignment.
|
||||||
Ostream& write(const char* data, const std::streamsize count);
|
Ostream& write(const char* data, const std::streamsize count);
|
||||||
|
|
||||||
|
//- Begin marker for low-level raw binary output.
|
||||||
|
// The count should indicate the number of bytes for subsequent
|
||||||
|
// writeRaw calls.
|
||||||
|
Ostream& beginRaw(const std::streamsize count);
|
||||||
|
|
||||||
|
//- Low-level raw binary output.
|
||||||
|
Ostream& writeRaw
|
||||||
|
(
|
||||||
|
const char* data,
|
||||||
|
const std::streamsize count
|
||||||
|
);
|
||||||
|
|
||||||
|
//- End marker for low-level raw binary output.
|
||||||
|
Ostream& endRaw()
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
//- Add indentation characters
|
//- Add indentation characters
|
||||||
void indent()
|
void indent()
|
||||||
{}
|
{}
|
||||||
|
|||||||
@ -210,7 +210,24 @@ Foam::Ostream& Foam::OSstream::write(const doubleScalar val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Ostream& Foam::OSstream::write(const char* buf, std::streamsize count)
|
Foam::Ostream& Foam::OSstream::write
|
||||||
|
(
|
||||||
|
const char* data,
|
||||||
|
const std::streamsize count
|
||||||
|
)
|
||||||
|
{
|
||||||
|
beginRaw(count);
|
||||||
|
writeRaw(data, count);
|
||||||
|
endRaw();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::Ostream& Foam::OSstream::beginRaw
|
||||||
|
(
|
||||||
|
const std::streamsize count
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (format() != BINARY)
|
if (format() != BINARY)
|
||||||
{
|
{
|
||||||
@ -220,8 +237,6 @@ Foam::Ostream& Foam::OSstream::write(const char* buf, std::streamsize count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
os_ << token::BEGIN_LIST;
|
os_ << token::BEGIN_LIST;
|
||||||
os_.write(buf, count);
|
|
||||||
os_ << token::END_LIST;
|
|
||||||
|
|
||||||
setState(os_.rdstate());
|
setState(os_.rdstate());
|
||||||
|
|
||||||
@ -229,9 +244,34 @@ Foam::Ostream& Foam::OSstream::write(const char* buf, std::streamsize count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::Ostream& Foam::OSstream::writeRaw
|
||||||
|
(
|
||||||
|
const char* data,
|
||||||
|
std::streamsize count
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// No check for format() == BINARY since this is either done in the
|
||||||
|
// beginRaw() method, or the caller knows what they are doing.
|
||||||
|
|
||||||
|
os_.write(data, count);
|
||||||
|
setState(os_.rdstate());
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::Ostream& Foam::OSstream::endRaw()
|
||||||
|
{
|
||||||
|
os_ << token::END_LIST;
|
||||||
|
setState(os_.rdstate());
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::OSstream::indent()
|
void Foam::OSstream::indent()
|
||||||
{
|
{
|
||||||
for (unsigned short i = 0; i < indentLevel_*indentSize_; i++)
|
for (unsigned short i = 0; i < indentLevel_*indentSize_; ++i)
|
||||||
{
|
{
|
||||||
os_ << ' ';
|
os_ << ' ';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -143,7 +143,26 @@ public:
|
|||||||
virtual Ostream& write(const doubleScalar val);
|
virtual Ostream& write(const doubleScalar val);
|
||||||
|
|
||||||
//- Write binary block
|
//- Write binary block
|
||||||
virtual Ostream& write(const char* buf, std::streamsize count);
|
virtual Ostream& write
|
||||||
|
(
|
||||||
|
const char* data,
|
||||||
|
const std::streamsize count
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Begin marker for low-level raw binary output.
|
||||||
|
// The count should indicate the number of bytes for subsequent
|
||||||
|
// writeRaw calls.
|
||||||
|
virtual Ostream& beginRaw(const std::streamsize count);
|
||||||
|
|
||||||
|
//- Low-level raw binary output.
|
||||||
|
virtual Ostream& writeRaw
|
||||||
|
(
|
||||||
|
const char* data,
|
||||||
|
const std::streamsize count
|
||||||
|
);
|
||||||
|
|
||||||
|
//- End marker for low-level raw binary output.
|
||||||
|
virtual Ostream& endRaw();
|
||||||
|
|
||||||
//- Add indentation characters
|
//- Add indentation characters
|
||||||
virtual void indent();
|
virtual void indent();
|
||||||
|
|||||||
Reference in New Issue
Block a user