43template<
typename Message>
inline
44void checkBinaryLength(
const Message&, MessageSize length, MessageSize minimalRequiredLength)
46 if ONIXS_CONFLATEDTCP_UNLIKELY(length < minimalRequiredLength)
47 throwBinaryBlockIsTooSmall(length, minimalRequiredLength, Message::className());
62template < class Container, class BlockLength >
68 return *
static_cast <const Container*
> (
this);
81 assert(container().blockLength() >= (offset + size<Value>()) &&
82 "The requested field exceeds provided block boundaries.");
84 const void*
const location = advanceByBytes(container().block(), offset);
85 return getValue<Value>(location);
97 return (null != value);
107 return (since <= container().version() &&
ordinary (value, offset, null ) );
114 typedef typename Enumeration::Base Base;
115 typedef typename Enumeration::Enum Enum;
124 typedef typename Enumeration::Base Base;
125 typedef typename Enumeration::Enum Enum;
128 return null != value;
153 return null != value;
163 return (since <= container().version() &&
decimal(value, offset, null));
170 assert(container().blockLength() >= (offset + Length) &&
"The requested field exceeds provided block boundaries.");
172 const Char*
const text =
reinterpret_cast <const Char*
> (advanceByBytes(container().block(), offset));
174 return StrRef(text, strnlen(text, Length));
185 return !value.empty();
203template <
class Container,
class BlockLength >
210 return *
static_cast<Container*
>(
this);
217 assert(
container().blockLength() >= (offset + size<FieldValue>()) &&
"The requested field exceeds provided block boundaries.");
219 void*
const fieldPos = advanceByBytes(
container().block(), offset);
220 setValue(fieldPos, value);
227 if ONIXS_CONFLATEDTCP_UNLIKELY(since >
container().version())
228 throwDisallowedField();
237 typedef typename Enumeration::Base Base;
245 typedef typename Enumeration::Base Base;
246 setOrdinary(offset,
static_cast<Base
>(value), since);
253 assert(
container().blockLength() >= (offset + Size) &&
"The requested field exceeds provided block boundaries.");
254 assert(value.size() <= Size &&
"The string is truncated.");
256 void*
const fieldPos = advanceByBytes(
container().block(), offset);
257 const size_t sizeToCopy = (std::min)(Size,
static_cast<BlockLength
>(value.size()));
260 std::memcpy(fieldPos, value.data(), sizeToCopy);
262 std::memset(advanceByBytes(fieldPos, sizeToCopy), 0, Size - sizeToCopy);
269 if ONIXS_CONFLATEDTCP_UNLIKELY(since >
container().version())
270 throwDisallowedField();
283template <class BodySizeType>
365template <
class EntryType,
class BlockLength,
class NumInGroup,
class Length >
422 return Entry(entry_, size_, version_);
434 return entry_ == other.entry_;
440 return entry_ != other.entry_;
446 return entry_ < other.entry_;
452 return entry_ > other.entry_;
460 entry_ = advanceByBytes(entry_, size_);
470 entry_ = advanceBackByBytes(entry_, size_);
481 return Iterator(advanceByBytes(entry_, distance * size_), size_, version_);
490 return Iterator(advanceBackByBytes(entry_, distance * size_), size_, version_);
511 , blockLength_(blockLength)
516 assert(blockLength > 0);
517 assert(version != 0);
541 return Iterator(
encoded(), blockLength_, version_);
555 assert(index < size_);
558 return Entry(advanceByBytes(encoded_,
static_cast<ptrdiff_t
>(index) * blockLength_), blockLength_, version_);
574 template<
class OtherEntry,
class OtherBlockLength,
class OtherNumInGroup,
class OtherLength >
576 : encoded_(other.encoded_)
577 , blockLength_(other.blockLength_)
579 , version_(other.version_)
584 assert(blockLength_ == other.blockLength_);
585 assert(size_ == other.size_);
588 template <
class OtherEntry,
class OtherBlockLength,
class OtherNumInGroup,
class OtherLength>
591 encoded_ = other.encoded_;
593 blockLength_ = other.blockLength_;
595 assert(blockLength_ == other.blockLength_);
599 assert(size_ == other.size_);
601 version_ = other.version_;
608 template <
class OtherEntry,
class OtherBlockLength,
class OtherNumInGroup,
class OtherLength>
friend class SbeGroupEntries;
611 BlockLength blockLength_;
617template <
class EntryType,
class DimensionType,
class GroupSizeType >
634 typedef SbeGroupEntries <EntryType, typename Dimension::BlockLength, typename Dimension::NumInGroup, GroupSizeType >
Entries;
657 : header_(
static_cast <Dimension*
>(data))
720 assert(index <
size());
732 return Entries (entries_, header_->blockLength(), header_->numInGroup(), version_);
779 Dimension*
const group =
static_cast<Dimension*
>(header_);
780 group->setBlockLength(entrySize);
781 group->setNumInGroup(0);
785 Size allocate(Size entryCount,
const void* messageTail,
const void* blockEnd)
791 Dimension*
const group =
static_cast<Dimension*
>(header_);
793 const EntrySize entrySize = group->blockLength();
795 if ONIXS_CONFLATEDTCP_UNLIKELY(
796 entrySize < EntryType::blockLength(version_))
798 throwBadBinaryBlock();
801 const Size oldEntryCount = group->numInGroup();
803 if(oldEntryCount == entryCount)
806 const ptrdiff_t memShift =
807 (entryCount - oldEntryCount) *
static_cast<ptrdiff_t
>(entrySize);
809 const void*
const newMessageTail =
810 advanceByBytes(messageTail, memShift);
812 if ONIXS_CONFLATEDTCP_UNLIKELY(byteDistance(blockEnd, newMessageTail) < 0)
813 throwNotEnoughSpace();
815 const
void* const oldEndOfGroup =
816 advanceByBytes(entries_, static_cast<ptrdiff_t>(entrySize) * oldEntryCount);
818 void* const newEndGroup =
819 advanceByBytes(entries_, static_cast<ptrdiff_t>(entrySize) * entryCount);
824 byteDistance(messageTail, oldEndOfGroup));
826 group->setNumInGroup(entryCount);
828 return oldEntryCount;
833 void setup(Size entryCount, const
void* messageTail, const
void* blockEnd)
839 const Size oldEntryCount = allocate(entryCount, messageTail, blockEnd);
841 for(Size index = oldEntryCount; index < entryCount; ++index)
842 (*
this)[index].resetVariableFields();
847 void construct(Size entryCount,
const void* messageTail,
const void* blockEnd)
853 const Size oldEntryCount = allocate(entryCount, messageTail, blockEnd);
855 for(Size index = oldEntryCount; index < entryCount; ++index)
856 (*
this)[index].reset();
862 SchemaVersion version_;
868template <
class BinarySize >
888 template<
class BinaryVariableLengthFieldType>
891 return *
static_cast<BinaryVariableLengthFieldType*
>(binary_);
902 assert(headSize <= size_);
913 if ONIXS_CONFLATEDTCP_UNLIKELY(
empty() || (size_ < BinaryVariableLengthFieldType::Size))
915 throwBadBinaryBlock();
920 if ONIXS_CONFLATEDTCP_UNLIKELY(headSize > size_)
922 throwBadBinaryBlock();
936template <
class BinarySize>
961 return Group(binary_, size_, version_);
970 const BinarySize headSize =
head<Group>().binarySize();
972 assert(headSize <= size_);
974 return SbeGroupList(advanceByBytes(binary_, headSize), size_ - headSize, version_);
983 const BinarySize headSize =
head<Group>().binarySize();
985 assert(headSize <= size_);
996 const BinarySize headSize = checkHead<Group>();
998 return SbeGroupList(advanceByBytes(binary_, headSize), size_ - headSize, version_);
1007 const BinarySize headSize = checkHead<Group>();
1013 template<
class Group>
1014 BinarySize checkHead()
const
1016 if ONIXS_CONFLATEDTCP_UNLIKELY(size_ < Group::Dimension::Size)
1018 throwBadBinaryBlock();
1021 const Group group = head<Group>();
1023 const BinarySize headSize = group.binarySize();
1025 if ONIXS_CONFLATEDTCP_UNLIKELY(headSize > size_)
1027 throwBadBinaryBlock();
1032 const BinarySize entrySize = group.entrySize();
1033 const BinarySize expectedEntrySize = Group::Entry::blockLength(version_);
1035 if ONIXS_CONFLATEDTCP_UNLIKELY(entrySize < expectedEntrySize)
1037 throwBadBinaryBlock();
1050template<
typename Traits>
1053 Int16 tmp = version;
1054 if ONIXS_CONFLATEDTCP_UNLIKELY (tmp < Traits::MinimalVersion)
1056 throwBadMessageVersion(version, Traits::MinimalVersion);
1061template<
typename Traits>
1066 if ONIXS_CONFLATEDTCP_UNLIKELY(version < since)
1068 throwBadMessageVersion(version, since);
1073template<
typename Traits>
1076 if ONIXS_CONFLATEDTCP_UNLIKELY(
id != Traits::Id)
1078 throwBadSchemaId(Traits::Id,
id);
1083template<
typename Traits>
1177 return header_->templateId();
1185 return header_->version();
1193 return header_->schemaId();
1217 return advanceByBytes(header_, size_);
1225 return advanceByBytes(header_, size_);
1247 return header_->blockLength();
1290 return GroupList(list, listSize, header_->version());
1303 return GroupList(
const_cast<void*
>(list), listSize, header_->version());
1307 template<
typename Group>
1311 assert(group.valid());
1312 group.init(entrySize);
1316 template<
typename Group>
1318 void setupGroup(Group& group,
typename Group::Size entryCount,
const void* messageTail)
1320 assert(messageTail);
1321 assert(group.valid());
1322 group.setup(entryCount, messageTail,
blockEnd());
1326 template<
typename Group>
1328 void constructGroup(Group& group,
typename Group::Size entryCount,
const void* messageTail)
1330 assert(messageTail);
1331 assert(group.valid());
1332 group.construct(entryCount, messageTail,
blockEnd());
1369 header_->setTemplateId(value);
1371 header_->setSchemaId(
id);
1380 assert(encodedBlockLength >= offset);
1382 const size_t paddingLength = encodedBlockLength - offset;
1383 std::memset(advanceByBytes(
container().
block(), offset), 0, paddingLength);
1396 header_->setTemplateId(value);
1398 header_->setSchemaId(
id);
1408 const ptrdiff_t distance = byteDistance(tail,
binary());
1410 assert(distance > 0);
1412 assert(distance <= (std::numeric_limits<MessageSize>::max)());
1416 assert(size <= size_);
1422 template<
class Callable,
class Owner>
1425 setVarDataField(callable(owner), value, owner.tail());
1429 template<
class Callable,
class Owner>
1432 if ONIXS_CONFLATEDTCP_UNLIKELY(since >
version())
1433 throwDisallowedField();
1439 template<
class Callable,
class Owner>
1442 ONIXS_CONFLATEDTCP_CHECK_NOTHROW(callable(owner));
1443 return callable(owner).varData();
1447 template<
class Callable,
class Owner>
1450 if ONIXS_CONFLATEDTCP_UNLIKELY(since >
version())
1457 template<
class Callable,
class Owner>
1460 ONIXS_CONFLATEDTCP_CHECK_NOTHROW(callable(owner));
1461 callable(owner).length(0);
1465 template<
class Group,
class Callable,
class Owner>
1468 const typename Group::EntrySize entrySize = Group::Entry::blockLength(
version());
1470 Group grp = callable(owner);
1476 template<
class Callable,
class Owner>
1479 if ONIXS_CONFLATEDTCP_UNLIKELY(since >
version())
1486 template<
class Group,
class Callable,
class Owner>
1489 if ONIXS_CONFLATEDTCP_UNLIKELY(since >
version())
1496 template<
class Group,
class Callable,
class Owner>
1499 return callable(owner);
1503 template<
class Group,
class Callable,
class Owner>
1506 if ONIXS_CONFLATEDTCP_UNLIKELY(since >
version())
1513 template<
class Group,
class Callable,
class Owner>
1516 if ONIXS_CONFLATEDTCP_UNLIKELY(since >
version())
1523 template<
class Group,
class Callable,
class Owner>
1526 Group group = callable(owner);
1534 template<
class Group,
class Callable,
class Owner>
1537 if ONIXS_CONFLATEDTCP_UNLIKELY(since >
version())
1544 template<
class Group,
class Callable,
class Owner>
1545 Group
setupGroup(Callable callable,
typename Group::Size length, Owner& owner)
1547 Group group = callable(owner);
#define ONIXS_CONFLATEDTCP_LTWT_EXPORTED
#define ONIXS_CONFLATEDTCP_LTWT_CLASS
#define ONIXS_CONFLATEDTCP_MESSAGING_NAMESPACE_BEGIN
#define ONIXS_CONFLATEDTCP_MESSAGING_NAMESPACE_END
#define ONIXS_CONFLATEDTCP_UNUSED
#define ONIXS_CONFLATEDTCP_CONSTEXPR
#define ONIXS_CONFLATEDTCP_NULLPTR
#define ONIXS_CONFLATEDTCP_NOTHROW
#define ONIXS_CONFLATEDTCP_NODISCARD
#define ONIXS_CONFLATEDTCP_HOTPATH
#define ONIXS_CONFLATEDTCP_DEFAULT
bool decimal(Value &value, BlockLength offset, NullValue null) const noexcept
bool fixedStr(StrRef &value, BlockLength offset) const noexcept
Provides access to an optional string field value.
Value ordinary(BlockLength offset) const noexcept
bool fixedStr(StrRef &value, BlockLength offset, SchemaVersion since) const noexcept
Provides access to an optional string field value.
bool ordinary(Value &value, BlockLength offset, NullValue null) const noexcept
Provides access to an optional field value.
bool decimal(Value &value, BlockLength offset, NullValue null, SchemaVersion since) const noexcept
Value decimal(BlockLength offset) const noexcept
Enumeration::Enum enumeration(BlockLength offset) const noexcept
bool enumeration(typename Enumeration::Enum &value, BlockLength offset, NullValue null) const noexcept
Provides access to an optional field value.
BinaryBlock()=default
Initializes a blank instance.
bool ordinary(Value &value, BlockLength offset, NullValue null, SchemaVersion since) const noexcept
Provides access to an optional field value.
StrRef fixedStr(BlockLength offset) const noexcept
Provides access to a string field value.
bool enumeration(typename Enumeration::Enum &value, BlockLength offset, NullValue null, SchemaVersion since) const noexcept
Provides access to an optional field value.
NumInGroup numInGroup() const noexcept
BlockLength blockLength() const noexcept
SbeFields()=default
Initializes a blank instance.
Container & container() noexcept
void setFixedStr(BlockLength offset, StrRef value) noexcept
Sets the field value.
void setOrdinary(BlockLength offset, FieldValue value, SchemaVersion since)
Sets the field value.
void setEnumeration(BlockLength offset, typename Enumeration::Enum value, SchemaVersion since)
Sets the field value.
void setEnumeration(BlockLength offset, typename Enumeration::Enum value) noexcept
Sets the field value.
void setOrdinary(BlockLength offset, FieldValue value) noexcept
Sets the field value.
void setFixedStr(BlockLength offset, StrRef value, SchemaVersion since)
Sets the field value.
An iterator over SBE-encoded group entries.
Iterator(void *entry, Size size, SchemaVersion version) noexcept
Initializes the instance to the given repeating group.
std::random_access_iterator_tag iterator_category
Iterator() noexcept
Initializes the instance that refers to nothing.
bool valid() const noexcept
ptrdiff_t difference_type
SbeGroupEntries() noexcept
Initializes a blank instance referencing to nothing.
bool empty() const noexcept
SbeGroupEntries(void *encoded, BlockLength blockLength, Size groupSize, SchemaVersion version) noexcept
Initializes the instance referencing to data.
EntryType Entry
The type of the repeating group entry.
Iterator end() const
Returns the iterator pointing to the entry behind the end of the group.
Size size() const noexcept
EncodedLength encodedLength() const noexcept
SbeGroupEntries(const SbeGroupEntries< OtherEntry, OtherBlockLength, OtherNumInGroup, OtherLength > &other) noexcept
Copy constructor.
bool valid() const noexcept
friend class SbeGroupEntries
Length EncodedLength
The length of the binary data occupied by the group entries.
NumInGroup Size
Number of entries in the collection.
void * encoded() const noexcept
SbeGroupEntry()
Initializes a blank instance.
const void * block() const noexcept
SbeGroupEntry(void *encoded, BlockLength size, SchemaVersion version)
Initializes the instance from the memory block of the encoded message.
SchemaVersion version() const noexcept
bool valid() const noexcept
const void * encoded() const noexcept
BlockLength blockLength() const noexcept
void * encoded() noexcept
GroupSize::BlockLength BlockLength
SbeVariableLengthFieldList< BinarySize > checkVariableLengthFields() const
Checks the variable length fields list consistency.
bool empty() const noexcept
SbeGroupList tail() const noexcept
SbeGroupList checkTail() const
Checks the list consistency.
Group head() const noexcept
SbeVariableLengthFieldList< BinarySize > variableLengthFields() const noexcept
SbeGroupList(void *binary, BinarySize size, SchemaVersion version) noexcept
Initializes the list over the memory block.
const void * tail() const noexcept
SbeGroup() noexcept
Initializes a blank instance referencing to nothing.
EntrySize entrySize() const noexcept
BinarySize binarySize() const noexcept
bool empty() const noexcept
GroupSize::BlockLength EntrySize
SbeGroup(void *data, BinarySize size, SchemaVersion version) noexcept
Initializes an instance referencing to a valid group of a given message.
Entries::Iterator Iterator
Entries entries() const noexcept
void * binary() const noexcept
Size size() const noexcept
Iterator end() const noexcept
bool valid() const noexcept
const void * encoded() const noexcept
SbeGroupEntries< SecurityGroupsEntry, typename Dimension::BlockLength, typename Dimension::NumInGroup, MessageSize > Entries
Iterator begin() const noexcept
void clear() noexcept
Blank the instance.
const void * binary() const noexcept
MessageTemplateId templateId() const noexcept
SchemaId schemaId() const noexcept
Group setupGroup(Callable callable, typename Group::Size length, SchemaVersion since, Owner &owner)
Setups the repeating group with the given number of entries.
const void * blockEnd() noexcept
GroupList groups() const noexcept
Group setupGroup(Callable callable, typename Group::Size length, Owner &owner)
Setups the repeating group with the given number of entries.
StrRef getVariableLengthField(Callable callable, SchemaVersion since, Owner &owner) const noexcept
const void * blockEnd() const noexcept
void setVariableLengthField(Callable callable, StrRef value, SchemaVersion since, Owner &owner)
Sets the value of the variable length field.
SbeMessage(void *data, MessageSize size)
Initializes the instance over the given memory block.
SbeVariableLengthFieldList< MessageSize > VariableLengthFieldList
Binary group list instantiation.
GroupList groups() noexcept
SbeMessage & version(SchemaVersion version) noexcept
Sets the SBE Schema version.
Group getGroup(Callable callable, Owner &owner) const noexcept
Group getGroup(Callable callable, SchemaVersion since, Owner &owner) const noexcept
MessageSize EncodedLength
Length of the message binary data.
const void * block() const noexcept
SbeMessage(void *data, MessageSize size, NoCheck) noexcept
Initializes the instance over the given memory block.
void initGroup(Group &group, typename Group::EntrySize entrySize) noexcept
Resets the group to the initial state.
void init(MessageHeader::TemplateId value, MessageHeader::BlockLength minimalBlockLength, MessageHeader::BlockLength blockLength, SchemaId id)
void setupGroup(Group &group, typename Group::Size entryCount, const void *messageTail)
Initializes the group header.
VariableLengthFieldList variableLengthFields() const noexcept
SchemaVersion version() const noexcept
SbeGroupList< MessageSize > GroupList
Binary group list instantiation.
SbeMessage(void *data, MessageSize size, SchemaVersion version)
Initializes the instance over the given memory block.
MessageSize bufferSize() const noexcept
bool valid() const noexcept
void initHeader(MessageHeader::TemplateId value, MessageHeader::BlockLength blockLength, SchemaId id) noexcept
static constexpr MessageSize getMaxMessageSize() noexcept
Maximal message size.
Group constructGroup(Callable callable, typename Group::Size length, Owner &owner)
Creates a repeating group with the given number of entries, sets all optional fields of the group ent...
Group constructGroup(Callable callable, typename Group::Size length, SchemaVersion since, Owner &owner)
Creates a repeating group with the given number of entries, sets all optional fields of the group ent...
void setVariableLengthFieldToNull(Callable callable, SchemaVersion since, Owner &owner) noexcept
Sets the variable length field to null.
BlockLength blockLength() const noexcept
void setVariableLengthFieldToNull(Callable callable, Owner &owner) noexcept
Resets the variable length field.
void resetGroup(Callable callable, SchemaVersion since, Owner &owner)
Resets the repeating group.
SbeMessage() noexcept
Initializes a blank instance.
void setVariableLengthField(Callable callable, StrRef value, Owner &owner)
Sets the value of the variable length field.
VariableLengthFieldList variableLengthFields() noexcept
MessageSize BlockLength
Length of the message body representing a block of fixed-length fields.
StrRef getVariableLengthField(Callable callable, const Owner &owner) const noexcept
void resetGroup(Callable callable, Owner &owner) noexcept
Sets the group to the initial state.
MessageSize calculateBinarySize(const void *tail) const noexcept
void constructGroup(Group &group, typename Group::Size entryCount, const void *messageTail)
Initializes the group header, sets all optional fields to null.
void zeroPaddingBytes(BlockLength offset)
If specified, the extra space is padded at the end of each entry and should be set to zeroes by encod...
Variable-length fields list.
bool empty() const noexcept
SbeVariableLengthFieldList(void *binary, BinarySize size, SchemaVersion version) noexcept
Initializes the list over the given memory block.
SbeVariableLengthFieldList tail() const noexcept
BinaryVariableLengthFieldType & head() const noexcept
SbeVariableLengthFieldList checkTail() const
Checks the variable-length field list consistency.
void checkSchemaId(SchemaId id)
Checks the compatibility with the provided SBE Schema ID.
constexpr UInt16 MaxConflatedTcpMessageSize
Maximum supported message size.
MessageHeader::Version SchemaVersion
SBE-encoded data version type.
char Char
Character type alias.
UInt16 MessageSize
Message length type.
void checkVersion(SchemaVersion version)
Checks the compatibility with the provided SBE Schema version.
MessageHeader::SchemaId SchemaId
void checkSchema(SchemaId id, SchemaVersion version)
Checks the compatibility with the provided SBE Schema version.
MessageHeader::TemplateId MessageTemplateId
Message type (template) identification.