Commit 5d5aa01a authored by mark's avatar mark

ENH: improve type-safeness when accessing parcel fragments

parent 08fd5fa3
......@@ -26,6 +26,7 @@ License
#include "ParcelEncoding.H"
#include "particle.H"
#include "DynamicList.H"
#include "IStringStream.H"
#include "token.H"
......@@ -233,7 +234,8 @@ void Foam::ParcelEncoding::setNames(Istream& is)
}
}
// Info<<"read in " << size() << " types and " << nNames << " names" << endl;
// Info<<"read in " << size() << " types and "
// << nNames << " names" << endl;
}
......@@ -371,6 +373,22 @@ Foam::List<int> Foam::ParcelEncoding::sizes() const
}
const Foam::ParcelEncoding::Fragment*
Foam::ParcelEncoding::lookupPtr(const word& name) const
{
forAllConstIter(Container, *this, iter)
{
const Fragment& frag = iter();
if (frag.name() == name)
{
return &frag;
}
}
return nullptr;
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<
......
......@@ -32,7 +32,8 @@ Description
#ifndef ParcelEncoding_H
#define ParcelEncoding_H
#include "DynamicList.H"
#include "error.H"
#include "UList.H"
#include "ParcelEncodingFragment.H"
#include "IOstreams.H"
......@@ -40,12 +41,9 @@ Description
namespace Foam
{
// forward declaration
class ParcelEncoding;
/*---------------------------------------------------------------------------*\
Class ParticleBinaryFragment Declaration
Class ParcelEncoding Declaration
\*---------------------------------------------------------------------------*/
class ParcelEncoding
:
......@@ -56,6 +54,7 @@ public:
typedef SLList<ParcelEncodingFragment> Container;
typedef ParcelEncodingFragment Fragment;
private:
// Private data
......@@ -129,6 +128,10 @@ public:
List<int> sizes() const;
//- Lookup a fragment by name, or null on failure.
const Fragment* lookupPtr(const word& name) const;
using Container::size;
using Container::begin;
using Container::end;
......@@ -148,7 +151,6 @@ public:
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
......
......@@ -25,29 +25,17 @@ License
#include "ParcelEncodingFragment.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
size_t Foam::ParcelEncodingFragment::width(const word& typeTok)
template<class PrimitiveType>
bool Foam::ParcelEncodingFragment::setPrimitiveType()
{
if (typeTok == pTraits<label>::typeName)
{
return sizeof(label);
}
if (typeTok == pTraits<scalar>::typeName)
{
return sizeof(scalar);
}
if (typeTok == pTraits<vector>::typeName)
{
return sizeof(vector);
}
return 0;
width_ = sizeof(pTraits<PrimitiveType>);
nComponents = pTraits<PrimitiveType>::nComponents;
return true;
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::ParcelEncodingFragment::set(const word& typeTok)
{
if (typeTok == pTraits<label>::typeName)
......@@ -79,14 +67,12 @@ Foam::ParcelEncodingFragment::ParcelEncodingFragment
width_(0),
count_(0),
nComponents(1),
container_(),
type_(type),
name_("__unnamed__")
name_("__unnamed__"),
container_()
{
set(type_);
width_ = width(type_);
if (width_ > 0)
{
count_ = 1;
......@@ -104,12 +90,12 @@ Foam::Ostream& Foam::operator<<
{
// Write contents
os.writeKeyword("type") << frag.type_ << token::END_STATEMENT << endl;
os.writeKeyword("name") << frag.name_ << token::END_STATEMENT << endl;
os.writeKeyword("offset") << frag.offset() << token::END_STATEMENT << endl;
os.writeKeyword("width") << frag.width() << token::END_STATEMENT << endl;
os.writeKeyword("count") << frag.count() << token::END_STATEMENT << endl;
os.writeKeyword("end") << frag.end() << token::END_STATEMENT << endl;
os.writeEntry("type", frag.type_);
os.writeEntry("name", frag.name_);
os.writeEntry("offset", frag.offset());
os.writeEntry("width", frag.width());
os.writeEntry("count", frag.count());
os.writeEntry("end", frag.end());
os.check
(
......
......@@ -43,11 +43,15 @@ Description
namespace Foam
{
// forward declaration
class ParcelEncoding;
// forward declaration
class ParcelEncoding;
template<class Type>
class ParcelEncodingAccessor;
/*---------------------------------------------------------------------------*\
Class ParcelEncodingFragment Declaration
Class ParcelEncodingFragment Declaration
\*---------------------------------------------------------------------------*/
class ParcelEncodingFragment
{
......@@ -67,145 +71,192 @@ class ParcelEncodingFragment
//- Number of components for the primitive type
int nComponents;
//- Name of enclosing container, if any (future use)
word container_;
//- Name of the primitive (base) type
word type_;
//- Name of the associated variable
word name_;
//- Name of enclosing container, if any (future use)
word container_;
// Private Member Functions
//- Width and nComponents for supported primitives
template<class PrimitiveType>
bool setPrimitiveType();
//- Width and nComponents for supported primitives
bool set(const word& typeTok);
//- Disallow default bitwise assignment
void operator=(const ParcelEncodingFragment&) = delete;
//- Width and nComponents for supported primitives
template<class PrimitiveType>
bool setPrimitiveType()
public:
// Constructors
//- Construct for specified type and offset
ParcelEncodingFragment
(
const word& type,
size_t offset
);
// Member Functions
//- The name associated with this byte sequence
inline const word& name() const
{
width_ = sizeof(pTraits<PrimitiveType>);
nComponents = pTraits<PrimitiveType>::nComponents;
return true;
return name_;
}
//- Width for supported primitives
static size_t width(const word& typeTok);
//- The primitive type for this byte sequence
inline const word& type() const
{
return type_;
}
//- Width and nComponents for supported primitives
bool set(const word& typeTok);
//- If the fragment has no size
inline bool empty() const
{
return !width_;
}
public:
//- Construct for specified type and offset
ParcelEncodingFragment
(
const word& type,
size_t offset
);
//- The beginning of this byte sequence
inline size_t offset() const
{
return offset_;
}
//- The name associated with this byte sequence
inline const word& name() const
{
return name_;
}
//- The size of an individual element
inline size_t width() const
{
return width_;
}
//- The number of individual elements
inline size_t count() const
{
return count_;
}
//- Total number of bytes
inline size_t sizeOf() const
{
return width_ * count_;
}
//- The primitive type for this byte sequence
inline const word& type() const
{
return type_;
}
//- The end of this byte sequence
inline size_t end() const
{
return offset_ + sizeOf();
}
//- The beginning of this byte sequence
inline size_t offset() const
{
return offset_;
}
//- True if this byte sequence corresponds to the given type
template<class Type>
bool isType() const
{
return (type_ == pTraits<Type>::typeName);
}
//- The size of an individual element
inline size_t width() const
{
return width_;
}
//- Return typed accessor for the fragment
template<class Type>
inline ParcelEncodingAccessor<Type> getAccessor() const
{
return ParcelEncodingAccessor<Type>(*this);
}
//- The number of individual elements
inline size_t count() const
{
return count_;
}
// IOstream operators
friend Ostream& operator<<
(
Ostream& os,
const ParcelEncodingFragment&
);
//- Total number of bytes
inline size_t sizeOf() const
{
return width_ * count_;
}
};
//- The end of this byte sequence
inline size_t end() const
{
return offset_ + sizeOf();
}
//- Accessor for typed parcel fragments
template<class Type>
class ParcelEncodingAccessor
{
// Private data
//- Offset in bytes from beginning of local binary content
const size_t offset_;
//- Name of the associated variable
const word name_;
// TODO
// restrict to the respective type
inline label getLabel(const char* buffer) const
{
return *(reinterpret_cast<const label*>(buffer + offset_));
}
// Private Member Functions
//- Disallow default bitwise copy
ParcelEncodingAccessor(const ParcelEncodingAccessor&) = delete;
inline scalar getScalar(const char* buffer) const
{
return *(reinterpret_cast<const scalar*>(buffer + offset_));
}
//- Disallow default bitwise assignment
void operator=(const ParcelEncodingAccessor&) = delete;
public:
inline vector getVector(const char* buffer) const
{
return *(reinterpret_cast<const vector*>(buffer + offset_));
}
// Constructors
//- Construct from base components (offset, name)
inline ParcelEncodingAccessor(const ParcelEncodingFragment& frag)
:
offset_(frag.offset()),
name_(frag.name())
{
if (pTraits<Type>::typeName != frag.type())
{
FatalErrorInFunction
<< "Cannot create a parcel accessor for '" << frag.name()
<< "' of type '" << pTraits<Type>::typeName
<< "' from a parcel fragment of type '" << frag.type()
<< "'" << endl
<< exit(FatalError);
}
}
inline label getLabel(const UList<char>& buffer) const
{
return getLabel(buffer.cdata());
}
// Member Functions
inline scalar getScalar(const UList<char>& buffer) const
{
return getScalar(buffer.cdata());
}
const word& name() const
{
return name_;
}
inline vector getVector(const UList<char>& buffer) const
{
return getVector(buffer.cdata());
}
// Member operators
//- Extract primitive at fixed offset
const Type& operator()(const char* buffer) const
{
return *(reinterpret_cast<const Type*>(buffer + offset_));
}
// IOstream operators
friend Ostream& operator<<
(
Ostream& os,
const ParcelEncodingFragment&
);
//- Extract primitive at fixed offset
const Type& operator()(const UList<char>& buffer) const
{
return operator()(buffer.cdata());
}
};
......
......@@ -36,8 +36,8 @@ Foam::ParcelEncoding::ParcelEncoding
names_(),
length_(0)
{
Info<< "inputTypes: " << CloudType::particleType::propertyTypes() << endl;
Info<< "inputNames: " << CloudType::particleType::propertyList() << endl;
// Info<< "inputTypes: " << CloudType::particleType::propertyTypes() << endl;
// Info<< "inputNames: " << CloudType::particleType::propertyList() << endl;
setTypes(IStringStream(CloudType::particleType::propertyTypes())());
setNames(IStringStream(CloudType::particleType::propertyList())());
......
......@@ -256,41 +256,42 @@ Foam::label Foam::adiosWrite::writeCloud
{
const ParcelEncoding::Fragment& frag = *iter;
if (frag.type() == pTraits<label>::typeName)
if (frag.isType<label>())
{
const ParcelEncodingAccessor<label> getter(frag);
label i = 0;
forAllConstIter(typename CloudType, cld, pIter)
{
os.rewind();
os << *pIter; // binary content
labelBuffer[i] = frag.getLabel(parcelBuf);
labelBuffer[i] = getter(parcelBuf);
++i;
}
// Info<< frag.name() << " (" << frag.type() << ") = "
// << flatOutput(SubList<int>(labelBuffer, i)) << nl;
defineVariable
(
varName/frag.name(),
varName/getter.name(),
adiosTraits<label>::adiosType,
localDims,
globalDims,
offsetDims
);
writeVariable(varName/frag.name(), labelBuffer);
writeVariable(varName/getter.name(), labelBuffer);
}
else if (frag.type() == pTraits<scalar>::typeName)
else if (frag.isType<scalar>())
{
const ParcelEncodingAccessor<scalar> getter(frag);
label i = 0;
forAllConstIter(typename CloudType, cld, pIter)
{
os.rewind();
os << *pIter; // binary content
scalarBuffer[i] = frag.getScalar(parcelBuf);
scalarBuffer[i] = getter(parcelBuf);
++i;
}
......@@ -299,23 +300,25 @@ Foam::label Foam::adiosWrite::writeCloud
defineVariable
(
varName/frag.name(),
varName/getter.name(),
adiosTraits<scalar>::adiosType,
localDims,
globalDims,
offsetDims
);
writeVariable(varName/frag.name(), scalarBuffer);
writeVariable(varName/getter.name(), scalarBuffer);
}
else if (frag.type() == pTraits<vector>::typeName)
else if (frag.isType<vector>())
{
const ParcelEncodingAccessor<vector> getter(frag);
label i = 0;
forAllConstIter(typename CloudType, cld, pIter)
{
os.rewind();
os << *pIter; // binary content
vector val = frag.getVector(parcelBuf);
const vector& val = getter(parcelBuf);
scalarBuffer[3*i+0] = val.x();
scalarBuffer[3*i+1] = val.y();
......@@ -325,7 +328,7 @@ Foam::label Foam::adiosWrite::writeCloud
defineVariable
(
varName/frag.name(),
varName/getter.name(),
adiosTraits<scalar>::adiosType,
localDims3,
globalDims3,
......@@ -335,7 +338,7 @@ Foam::label Foam::adiosWrite::writeCloud
// Info<< frag.name() << " (" << frag.type() << ") = "
// << flatOutput(SubList<scalar>(scalarBuffer, i)) << nl;
writeVariable(varName/frag.name(), scalarBuffer);
writeVariable(varName/getter.name(), scalarBuffer);
}
}
}
......
......@@ -33,7 +33,6 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::label Foam::adiosWrite::writeCloudObject
(
const regIOobject& obj,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment