43template<
typename Message>
inline
44void checkBinaryLength(
const Message&, MessageSize length, MessageSize minimalRequiredLength)
46 if ONIXS_B3_UMDF_MD_UNLIKELY(length < minimalRequiredLength)
47 throwBinaryBlockIsTooSmall(length, minimalRequiredLength, Message::className());
54 ~BinaryBlockBase() =
default;
62template <
class Container,
class BlockLength >
66 const Container& container()
const noexcept
68 return *
static_cast <const Container*
> (
this);
78 template <
class Value > ONIXS_B3_UMDF_MD_HOTPATH
79 Value ordinary(BlockLength
offset)
const noexcept
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);
92 template <
class Value,
class NullValue > ONIXS_B3_UMDF_MD_HOTPATH
93 bool ordinary(Value& value, BlockLength
offset, NullValue
null)
const noexcept
95 value = ordinary<Value>(
offset);
104 template <
class Value,
class NullValue > ONIXS_B3_UMDF_MD_HOTPATH
107 return (since <= container().version() && ordinary (value,
offset,
null ) );
111 template <
class Enumeration > ONIXS_B3_UMDF_MD_HOTPATH
112 typename Enumeration::Enum enumeration(BlockLength offset)
const noexcept
114 typedef typename Enumeration::Base Base;
115 typedef typename Enumeration::Enum Enum;
117 return static_cast<Enum
>(ordinary<Base>(offset));
121 template <
class Enumeration,
class NullValue > ONIXS_B3_UMDF_MD_HOTPATH
122 bool enumeration(
typename Enumeration::Enum& value, BlockLength offset, NullValue null)
const noexcept
124 typedef typename Enumeration::Base Base;
125 typedef typename Enumeration::Enum Enum;
127 value =
static_cast <Enum
>(ordinary<Base>(offset));
128 return null != value;
132 template <
class Enumeration,
class NullValue > ONIXS_B3_UMDF_MD_HOTPATH
133 bool enumeration(
typename Enumeration::Enum& value, BlockLength offset, NullValue null, SchemaVersion since)
const noexcept
135 return (since <= container().version() && enumeration<Enumeration>(value, offset, null) );
139 template <
class Value > ONIXS_B3_UMDF_MD_HOTPATH
140 Value decimal(BlockLength offset)
const noexcept
142 return ordinary<Value>(offset);
149 template <
class Value,
class NullValue > ONIXS_B3_UMDF_MD_HOTPATH
150 bool decimal(Value& value, BlockLength offset, NullValue null)
const noexcept
152 value = ordinary<Value>(offset);
153 return null != value;
160 template <
class Value,
class NullValue > ONIXS_B3_UMDF_MD_HOTPATH
161 bool decimal(Value& value, BlockLength offset, NullValue null, SchemaVersion since)
const noexcept
163 return (since <= container().version() && decimal(value, offset, null));
167 template < BlockLength Length > ONIXS_B3_UMDF_MD_HOTPATH
168 StrRef fixedStr(BlockLength offset)
const noexcept
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));
181 template<BlockLength Length> ONIXS_B3_UMDF_MD_HOTPATH
182 bool fixedStr(StrRef& value, BlockLength offset)
const noexcept
184 value = fixedStr<Length>(offset);
185 return !value.empty();
192 template<BlockLength Length> ONIXS_B3_UMDF_MD_HOTPATH
193 bool fixedStr(StrRef& value, BlockLength offset, SchemaVersion since)
const noexcept
195 return (since <= container().version() && fixedStr<Length>(value, offset));
203template <
class Container,
class BlockLength >
210 return *
static_cast<Container*
>(
this);
214 ONIXS_B3_UMDF_MD_HOTPATH
215 void zeroPaddingBytes(BlockLength
offset)
noexcept
217 const BlockLength encodedBlockLength =
container().blockLength();
221 const size_t paddingLength = encodedBlockLength -
offset;
222 std::memset(advanceByBytes(
container().block(),
offset), 0, paddingLength);
226 template<
class FieldValue> ONIXS_B3_UMDF_MD_HOTPATH
229 assert(
container().blockLength() >= (
offset + size<FieldValue>()) &&
"The requested field exceeds provided block boundaries.");
236 template<
class FieldValue> ONIXS_B3_UMDF_MD_HOTPATH
240 throwDisallowedField();
246 template<
class Enumeration> ONIXS_B3_UMDF_MD_HOTPATH
247 void setEnumeration(BlockLength
offset,
typename Enumeration::Enum
value)
noexcept
249 typedef typename Enumeration::Base Base;
254 template<
class Enumeration> ONIXS_B3_UMDF_MD_HOTPATH
257 typedef typename Enumeration::Base Base;
262 template<BlockLength Size> ONIXS_B3_UMDF_MD_HOTPATH
265 assert(
container().blockLength() >= (
offset + Size) &&
"The requested field exceeds provided block boundaries.");
278 template<BlockLength Size> ONIXS_B3_UMDF_MD_HOTPATH
282 throwDisallowedField();
295template <
class BodySizeType>
311 ONIXS_B3_UMDF_MD_HOTPATH
323 return (encoded_ !=
nullptr);
371 const void* encoded_;
377template <
class EntryType,
class BlockLength,
class NumInGroup,
class Length >
413 ONIXS_B3_UMDF_MD_HOTPATH
425 return (entry_ !=
nullptr);
429 ONIXS_B3_UMDF_MD_HOTPATH
434 return Entry(entry_, size_, version_);
444 bool operator == (
const Iterator& other)
const noexcept
446 return entry_ == other.entry_;
450 bool operator !=(
const Iterator& other)
const noexcept
452 return entry_ != other.entry_;
456 bool operator < (
const Iterator& other)
const noexcept
458 return entry_ < other.entry_;
462 bool operator > (
const Iterator& other)
const noexcept
464 return entry_ > other.entry_;
472 entry_ = advanceByBytes(entry_, size_);
482 entry_ = advanceBackByBytes(entry_, size_);
488 ONIXS_B3_UMDF_MD_HOTPATH
493 return Iterator(advanceByBytes(entry_, distance * size_), size_, version_);
497 ONIXS_B3_UMDF_MD_HOTPATH
502 return Iterator(advanceBackByBytes(entry_, distance * size_), size_, version_);
523 , blockLength_(blockLength)
535 return (
nullptr != encoded_);
553 return Iterator(
encoded(), blockLength_, version_);
570 return Entry(advanceByBytes(encoded_,
static_cast<ptrdiff_t
>(index) * blockLength_), blockLength_, version_);
586 template<
class OtherEntry,
class OtherBlockLength,
class OtherNumInGroup,
class OtherLength >
588 : encoded_(other.encoded_)
589 , blockLength_(other.blockLength_)
591 , version_(other.version_)
596 assert(blockLength_ == other.blockLength_);
597 assert(size_ == other.size_);
600 template <
class OtherEntry,
class OtherBlockLength,
class OtherNumInGroup,
class OtherLength>
601 SbeGroupEntries& operator = (
const SbeGroupEntries <OtherEntry, OtherBlockLength, OtherNumInGroup, OtherLength>& other)
noexcept
603 encoded_ = other.encoded_;
605 blockLength_ = other.blockLength_;
607 assert(blockLength_ == other.blockLength_);
611 assert(size_ == other.size_);
613 version_ = other.version_;
620 template <
class OtherEntry,
class OtherBlockLength,
class OtherNumInGroup,
class OtherLength>
friend class SbeGroupEntries;
623 BlockLength blockLength_;
629template <
class EntryType,
class DimensionType,
class GroupSizeType >
646 typedef SbeGroupEntries <EntryType, typename Dimension::BlockLength, typename Dimension::NumInGroup, GroupSizeType >
Entries;
667 ONIXS_B3_UMDF_MD_HOTPATH
669 : header_(
static_cast <Dimension*
>(data))
683 return (entries_ !=
nullptr);
695 ONIXS_B3_UMDF_MD_HOTPATH
703 return group->numInGroup();
707 ONIXS_B3_UMDF_MD_HOTPATH
712 return Iterator(entries_, numericCast<Size>(entrySize()), version_);
716 ONIXS_B3_UMDF_MD_HOTPATH
721 return Iterator(advanceByBytes(binary(), binarySize()), numericCast<Size>(entrySize()), version_);
727 ONIXS_B3_UMDF_MD_HOTPATH
731 assert(index < size());
733 return Entry(advanceByBytes(entries_,
static_cast<ptrdiff_t
>(index) * entrySize()), entrySize(), version_);
737 ONIXS_B3_UMDF_MD_NODISCARD
743 return Entries (entries_, header_->blockLength(), header_->numInGroup(), version_);
755 return advanceByBytes(toByteBlock(
encoded()), binarySize());
759 ONIXS_B3_UMDF_MD_HOTPATH
766 ONIXS_B3_UMDF_MD_HOTPATH
773 ONIXS_B3_UMDF_MD_HOTPATH
780 return group->blockLength();
785 void init(EntrySize entrySize)
noexcept
790 Dimension*
const group =
static_cast<Dimension*
>(header_);
791 group->setBlockLength(entrySize);
792 group->setNumInGroup(0);
796 Size allocate(Size entryCount,
const void* messageTail,
const void* blockEnd)
802 Dimension*
const group =
static_cast<Dimension*
>(header_);
804 const EntrySize entrySize = group->blockLength();
806 if ONIXS_B3_UMDF_MD_UNLIKELY(
807 entrySize < EntryType::blockLength(version_))
809 throwBadBinaryBlock();
812 const Size oldEntryCount = group->numInGroup();
814 if(oldEntryCount == entryCount)
817 const ptrdiff_t memShift =
818 (entryCount - oldEntryCount) *
static_cast<ptrdiff_t
>(entrySize);
820 const void*
const newMessageTail =
821 advanceByBytes(messageTail, memShift);
823 if ONIXS_B3_UMDF_MD_UNLIKELY(byteDistance(blockEnd, newMessageTail) < 0)
824 throwNotEnoughSpace();
826 const
void* const oldEndOfGroup =
827 advanceByBytes(entries_, static_cast<ptrdiff_t>(entrySize) * oldEntryCount);
829 void* const newEndGroup =
830 advanceByBytes(entries_, static_cast<ptrdiff_t>(entrySize) * entryCount);
835 byteDistance(messageTail, oldEndOfGroup));
837 group->setNumInGroup(entryCount);
839 return oldEntryCount;
843 ONIXS_B3_UMDF_MD_HOTPATH
844 void setup(Size entryCount, const
void* messageTail, const
void* blockEnd)
850 const Size oldEntryCount = allocate(entryCount, messageTail, blockEnd);
852 for(Size index = oldEntryCount; index < entryCount; ++index)
853 zeroPaddingBytes((*
this)[index].resetVariableFields());
857 ONIXS_B3_UMDF_MD_HOTPATH
858 void construct(Size entryCount,
const void* messageTail,
const void* blockEnd)
864 const Size oldEntryCount = allocate(entryCount, messageTail, blockEnd);
866 for(Size index = oldEntryCount; index < entryCount; ++index)
867 zeroPaddingBytes((*
this)[index].reset());
870 ONIXS_B3_UMDF_MD_HOTPATH
871 static void zeroPaddingBytes(Entry& entry)
873 assert(entry.valid());
874 entry.zeroPaddingBytes(EntryType::minimalBlockLength(entry.version()));
880 SchemaVersion version_;
886template <
class BinarySize >
891 ONIXS_B3_UMDF_MD_HOTPATH
906 template<
class BinaryVariableLengthFieldType>
909 return *
static_cast<BinaryVariableLengthFieldType*
>(binary_);
913 template<
class BinaryVariableLengthFieldType> ONIXS_B3_UMDF_MD_HOTPATH
920 assert(headSize <= size_);
928 template<
class BinaryVariableLengthFieldType> ONIXS_B3_UMDF_MD_HOTPATH
931 if ONIXS_B3_UMDF_MD_UNLIKELY(
empty() || (size_ < BinaryVariableLengthFieldType::Size))
933 throwBadBinaryBlock();
938 if ONIXS_B3_UMDF_MD_UNLIKELY(headSize > size_)
940 throwBadBinaryBlock();
954template <
class BinarySize>
959 ONIXS_B3_UMDF_MD_HOTPATH
974 template<
class Group> ONIXS_B3_UMDF_MD_HOTPATH
979 return Group(binary_, size_, version_);
983 template<
class Group> ONIXS_B3_UMDF_MD_HOTPATH
988 const BinarySize headSize = head<Group>().binarySize();
990 assert(headSize <= size_);
992 return SbeGroupList(advanceByBytes(binary_, headSize), size_ - headSize, version_);
996 template <
class Group> ONIXS_B3_UMDF_MD_HOTPATH
1001 const BinarySize headSize = head<Group>().binarySize();
1003 assert(headSize <= size_);
1011 template<
class Group> ONIXS_B3_UMDF_MD_HOTPATH
1014 const BinarySize headSize = checkHead<Group>();
1016 return SbeGroupList(advanceByBytes(binary_, headSize), size_ - headSize, version_);
1022 template <
class Group> ONIXS_B3_UMDF_MD_HOTPATH
1025 const BinarySize headSize = checkHead<Group>();
1031 template<
class Group>
1032 BinarySize checkHead()
const
1034 if ONIXS_B3_UMDF_MD_UNLIKELY(size_ < Group::Dimension::Size)
1036 throwBadBinaryBlock();
1039 const Group group = head<Group>();
1041 const BinarySize headSize = group.binarySize();
1043 if ONIXS_B3_UMDF_MD_UNLIKELY(headSize > size_)
1045 throwBadBinaryBlock();
1050 const BinarySize entrySize = group.entrySize();
1051 const BinarySize expectedEntrySize = Group::Entry::minimalBlockLength(version_);
1053 if ONIXS_B3_UMDF_MD_UNLIKELY(entrySize < expectedEntrySize)
1055 throwBadBinaryBlock();
1064 SchemaVersion version_;
1068template<
typename Traits>
1071 if ONIXS_B3_UMDF_MD_UNLIKELY(version < Traits::MinimalVersion)
1073 throwBadMessageVersion(version, Traits::MinimalVersion);
1078template<
typename Traits>
1083 if ONIXS_B3_UMDF_MD_UNLIKELY(version < since)
1085 throwBadMessageVersion(version, since);
1090template<
typename Traits>
1093 if ONIXS_B3_UMDF_MD_UNLIKELY(
id != Traits::Id)
1095 throwBadSchemaId(Traits::Id,
id);
1100template<
typename Traits>
1145 ONIXS_B3_UMDF_MD_HOTPATH
1164 ONIXS_B3_UMDF_MD_HOTPATH
1186 return (
nullptr != header_);
1194 return header_->templateId();
1202 return header_->version();
1210 return header_->schemaId();
1234 return advanceByBytes(header_, size_);
1242 return advanceByBytes(header_, size_);
1264 return header_->blockLength();
1311 ONIXS_B3_UMDF_MD_HOTPATH
1320 return GroupList(
const_cast<void*
>(list), listSize, header_->version());
1324 template<
typename Group>
1325 ONIXS_B3_UMDF_MD_HOTPATH
1326 void initGroup(Group& group,
typename Group::EntrySize entrySize)
noexcept
1329 group.init(entrySize);
1333 template<
typename Group>
1334 ONIXS_B3_UMDF_MD_HOTPATH
1343 template<
typename Group>
1344 ONIXS_B3_UMDF_MD_HOTPATH
1390 ONIXS_B3_UMDF_MD_HOTPATH
1419 ONIXS_B3_UMDF_MD_HOTPATH
1420 MessageSize calculateBinarySize(
const void* tail)
const noexcept
1424 const ptrdiff_t distance = byteDistance(tail,
binary());
1428 assert(distance <= (std::numeric_limits<MessageSize>::max)());
1438 template<
class Callable,
class Owner>
1441 setVarDataField(callable(owner),
value, owner.tail());
1445 template<
class Callable,
class Owner>
1449 throwDisallowedField();
1455 template<
class Callable,
class Owner>
1459 return callable(owner).varData();
1463 template<
class Callable,
class Owner>
1473 template<
class Callable,
class Owner>
1477 callable(owner).length(0);
1481 template<
class Group,
class Callable,
class Owner>
1484 const typename Group::EntrySize entrySize = Group::Entry::blockLength(
version());
1486 Group grp = callable(owner);
1488 initGroup(grp, entrySize);
1492 template<
class Callable,
class Owner>
1502 template<
class Group,
class Callable,
class Owner>
1512 template<
class Group,
class Callable,
class Owner>
1513 Group
getGroup(Callable callable, Owner& owner)
const noexcept
1516 return callable(owner);
1520 template<
class Group,
class Callable,
class Owner>
1530 template<
class Group,
class Callable,
class Owner>
1540 template<
class Group,
class Callable,
class Owner>
1543 Group group = callable(owner);
1551 template<
class Group,
class Callable,
class Owner>
1561 template<
class Group,
class Callable,
class Owner>
1562 Group
setupGroup(Callable callable,
typename Group::Size length, Owner& owner)
1564 Group group = callable(owner);
1573 ONIXS_B3_UMDF_MD_NODISCARD
#define ONIXS_B3_UMDF_MD_MESSAGING_NAMESPACE_END
#define ONIXS_B3_UMDF_MD_LTWT_EXPORTED
#define ONIXS_B3_UMDF_MD_MESSAGING_NAMESPACE_BEGIN
#define ONIXS_B3_UMDF_MD_LTWT_CLASS
#define ONIXS_B3_UMDF_MD_ASSERT(CHECK)
#define ONIXS_B3_UMDF_MD_CHECK_NOTHROW(equation)
BlockLength NullValue null
BinaryBlock()=default
Initializes a blank instance.
setValue(fieldPos, value)
FieldValue value noexcept
FieldValue SchemaVersion since
setOrdinary(offset, static_cast< Base >(value), since)
SbeFields()=default
Initializes a blank instance.
Container & container() noexcept
setOrdinary(offset, value)
assert(value.size()<=Size &&"The string is truncated.")
setFixedStr(offset, value)
Size SchemaVersion version size_(size)
Size SchemaVersion version version_(version)
std::random_access_iterator_tag iterator_category
Iterator() noexcept
Initializes the instance that refers to nothing.
bool valid() const noexcept
ptrdiff_t difference_type
Size SchemaVersion version noexcept
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.
BlockLength SchemaVersion version
const void * block() const noexcept
SchemaVersion version() const noexcept
bool valid() const noexcept
const void * encoded() const noexcept
BlockLength blockLength() const noexcept
BodySizeType BlockLength
Type to present the length of binary data of the repeating group entry.
bool empty() const noexcept
MessageSize SchemaVersion version noexcept
BinarySize SchemaVersion version version_(version)
BinarySize SchemaVersion version size_(size)
const void * tail() const noexcept
SbeGroup() noexcept
Initializes a blank instance referencing to nothing.
Entries::Size Size
Number of entries in the group.
GroupSizeType BinarySize
Length of group data.
bool empty() const noexcept
DimensionType::BlockLength EntrySize
Length of group entry data.
Entries::Iterator Iterator
The iterator type for group entries.
Entries::Entry Entry
Group entry type.
SchemaVersion version noexcept
SchemaVersion version entries_(advanceByBytes(data, Dimension::Size))
bool valid() const noexcept
const void * encoded() const noexcept
SbeGroupEntries< EntryType, typename Dimension::BlockLength, typename Dimension::NumInGroup, GroupSizeType > Entries
Binary group blocks.
DimensionType Dimension
Repeating group dimension type.
SchemaVersion version version_(version)
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
Group setupGroup(Callable callable, typename Group::Size length, Owner &owner)
Setups the repeating group with the given number of entries.
MessageSize NoCheck size_(size)
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.
MessageSize NoCheck noexcept
SbeVariableLengthFieldList< MessageSize > VariableLengthFieldList
Sets the variable length field value.
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
SchemaVersion version() const noexcept
SbeGroupList< MessageSize > GroupList
Binary group list instantiation.
MessageSize bufferSize() const noexcept
bool valid() const noexcept
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.
Group::Size const void * messageTail
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.
Variable-length fields list.
bool empty() const noexcept
MessageSize SchemaVersion version noexcept
BinaryVariableLengthFieldType & head() const noexcept
BinarySize SchemaVersion version version_(version)
BinarySize SchemaVersion version size_(size)
void checkSchemaId(SchemaId id)
Checks the compatibility with the provided SBE Schema ID.
MessageHeader::Version SchemaVersion
SBE-encoded data version type.
constexpr UInt16 MaxMessageSize
Maximum supported message size.
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.
ptrdiff_t distance noexcept
MessageHeader::TemplateId MessageTemplateId
Message type (template) identification.
Type of the Market Data Entry.