SIZE Layer
namespace comms
{
// TField is type of the field used to read/write SIZE information
// TNext is the next layer this one wraps
template <typename TField, typename TNext>
class MsgSizeLayer
{
public:
// Type of the field object used to read/write SIZE information.
using Field = TField;
// Take type of the ReadIterator from the next layer
using ReadIterator = typename TNext::ReadIterator;
// Take type of the WriteIterator from the next layer
using WriteIterator = typename TNext::WriteIterator;
// Take type of the message interface from the next layer
using Message = typename TNext::Message;
// Take type of the message interface pointer from the next layer
using MsgPtr = typename TNext::MsgPtr;
template <typename TMsgPtr>
ErrorStatus read(TMsgPtr& msgPtr, ReadIterator& iter, std::size_t len)
{
Field field;
auto es = field.read(iter, len);
if (es != ErrorStatus::Success) {
return es;
}
auto actualRemainingSize = (len - field.length());
auto requiredRemainingSize = static_cast<std::size_t>(field.value());
if (actualRemainingSize < requiredRemainingSize) {
return ErrorStatus::NotEnoughData;
}
es = reader.read(msgPtr, iter, requiredRemainingSize);
if (es == ErrorStatus::NotEnoughData) {
return ErrorStatus::ProtocolError;
}
return es;
}
ErrorStatus write(const Message& msg, WriteIterator& iter, std::size_t len) const
{
Field field;
field.value() = m_next.length(msg);
auto es = field.write(iter, len);
if (es != ErrorStatus::Success) {
return es;
}
return m_next.write(msg, iter, len - field.length());
}
private:
TNext m_next;
};
} // namespace commsLast updated