43template<
typename Message>
inline
44void checkBinaryLength(
const Message&, MessageSize length, MessageSize minimalRequiredLength)
48 throwBinaryBlockIsTooSmall(length, minimalRequiredLength, Message::className());
56 ~BinaryBlockBase() =
default;
64template <
class Container,
class BlockLength >
68 const Container& container()
const noexcept
70 return *
static_cast <const Container*
> (
this);
81 Value
ordinary(BlockLength offset)
const noexcept
83 assert(container().blockLength() >= (offset + size<Value>()) &&
84 "The requested field exceeds provided block boundaries.");
86 const void*
const location = advanceByBytes(container().block(), offset);
87 return getValue<Value>(location);
96 throwDisallowedField();
107 bool ordinary(Value& value, BlockLength offset, NullValue null)
const noexcept
111 return (null != value);
121 return (since <= container().
version() &&
ordinary (value, offset, null ) );
126 typename Enumeration::Enum
enumeration(BlockLength offset)
const noexcept
128 typedef typename Enumeration::Base Base;
129 typedef typename Enumeration::Enum Enum;
136 bool enumeration(
typename Enumeration::Enum& value, BlockLength offset, NullValue null)
const noexcept
138 typedef typename Enumeration::Base Base;
139 typedef typename Enumeration::Enum Enum;
142 return null != value;
154 Value
decimal(BlockLength offset)
const noexcept
164 bool decimal(Value& value, BlockLength offset, NullValue null)
const noexcept
167 return null != value;
177 return (since <= container().
version() &&
decimal(value, offset, null));
184 assert(container().blockLength() >= (offset + Length) &&
"The requested field exceeds provided block boundaries.");
186 const Char*
const text =
reinterpret_cast <const Char*
> (advanceByBytes(container().block(), offset));
188 return StrRef(text, strnlen(text, Length));
199 return !value.empty();
217template <
class Container,
class BlockLength >
224 return *
static_cast<Container*
>(
this);
231 const BlockLength encodedBlockLength =
container().blockLength();
233 assert(encodedBlockLength >= offset);
235 const size_t paddingLength = encodedBlockLength - offset;
236 std::memset(advanceByBytes(
container().block(), offset), 0, paddingLength);
243 assert(
container().blockLength() >= (offset + size<FieldValue>()) &&
"The requested field exceeds provided block boundaries.");
245 void*
const fieldPos = advanceByBytes(
container().block(), offset);
246 setValue(fieldPos, value);
255 throwDisallowedField();
263 void setEnumeration(BlockLength offset,
typename Enumeration::Enum value)
noexcept
265 typedef typename Enumeration::Base Base;
273 typedef typename Enumeration::Base Base;
274 setOrdinary(offset,
static_cast<Base
>(value), since);
281 assert(
container().blockLength() >= (offset + Size) &&
"The requested field exceeds provided block boundaries.");
282 assert(value.size() <= Size &&
"The string is truncated.");
284 void*
const fieldPos = advanceByBytes(
container().block(), offset);
285 const size_t sizeToCopy = (std::min)(Size,
static_cast<BlockLength
>(value.size()));
288 std::memcpy(fieldPos, value.data(), sizeToCopy);
290 std::memset(advanceByBytes(fieldPos, sizeToCopy), 0, Size - sizeToCopy);
299 throwDisallowedField();
313template <
class BodySizeType>
341 return (encoded_ !=
nullptr);
395template <
class EntryType,
class BlockLength,
class NumInGroup,
class Length >
443 return (entry_ !=
nullptr);
452 return Entry(entry_, size_, version_);
462 bool operator == (
const Iterator& other)
const noexcept
464 return entry_ == other.entry_;
468 bool operator !=(
const Iterator& other)
const noexcept
470 return entry_ != other.entry_;
474 bool operator < (
const Iterator& other)
const noexcept
476 return entry_ < other.entry_;
480 bool operator > (
const Iterator& other)
const noexcept
482 return entry_ > other.entry_;
490 entry_ = advanceByBytes(entry_, size_);
500 entry_ = advanceBackByBytes(entry_, size_);
511 return Iterator(advanceByBytes(entry_, distance * size_), size_, version_);
520 return Iterator(advanceBackByBytes(entry_, distance * size_), size_, version_);
541 , blockLength_(blockLength)
546 assert(blockLength > 0);
553 return (
nullptr != encoded_);
571 return Iterator(
encoded(), blockLength_, version_);
585 assert(index < size_);
588 return Entry(advanceByBytes(encoded_,
static_cast<ptrdiff_t
>(index) * blockLength_), blockLength_, version_);
604 template<
class OtherEntry,
class OtherBlockLength,
class OtherNumInGroup,
class OtherLength >
606 : encoded_(other.encoded_)
607 , blockLength_(other.blockLength_)
609 , version_(other.version_)
614 assert(blockLength_ == other.blockLength_);
615 assert(size_ == other.size_);
618 template <
class OtherEntry,
class OtherBlockLength,
class OtherNumInGroup,
class OtherLength>
619 SbeGroupEntries& operator = (
const SbeGroupEntries <OtherEntry, OtherBlockLength, OtherNumInGroup, OtherLength>& other)
noexcept
621 encoded_ = other.encoded_;
623 blockLength_ = other.blockLength_;
625 assert(blockLength_ == other.blockLength_);
629 assert(size_ == other.size_);
631 version_ = other.version_;
638 template <
class OtherEntry,
class OtherBlockLength,
class OtherNumInGroup,
class OtherLength>
friend class SbeGroupEntries;
641 BlockLength blockLength_;
647template <
class EntryType,
class DimensionType,
class GroupSizeType >
664 typedef SbeGroupEntries <EntryType, typename Dimension::BlockLength, typename Dimension::NumInGroup, GroupSizeType >
Entries;
687 : header_(
static_cast <Dimension*
>(data))
701 return (entries_ !=
nullptr);
749 assert(index <
size());
761 return Entries (entries_, header_->blockLength(), header_->numInGroup(), version_);
771 const void*
tail() const noexcept
803 void init(EntrySize entrySize)
noexcept
808 Dimension*
const group =
static_cast<Dimension*
>(header_);
809 group->setBlockLength(entrySize);
810 group->setNumInGroup(0);
814 Size allocate(Size entryCount,
const void* messageTail,
const void* blockEnd)
820 Dimension*
const group =
static_cast<Dimension*
>(header_);
822 const EntrySize entrySize = group->blockLength();
826 throwBadBinaryBlock();
829 const Size oldEntryCount = group->numInGroup();
831 if(oldEntryCount == entryCount)
834 const ptrdiff_t memShift =
835 (entryCount - oldEntryCount) *
static_cast<ptrdiff_t
>(entrySize);
837 const void*
const newMessageTail =
838 advanceByBytes(messageTail, memShift);
842 throwNotEnoughSpace();
845 const void*
const oldEndOfGroup =
846 advanceByBytes(entries_,
static_cast<ptrdiff_t
>(entrySize) * oldEntryCount);
848 void*
const newEndGroup =
849 advanceByBytes(entries_,
static_cast<ptrdiff_t
>(entrySize) * entryCount);
854 byteDistance(messageTail, oldEndOfGroup));
856 group->setNumInGroup(entryCount);
858 return oldEntryCount;
863 void setup(Size entryCount,
const void* messageTail,
const void* blockEnd)
869 const Size oldEntryCount = allocate(entryCount, messageTail, blockEnd);
871 for(Size index = oldEntryCount; index < entryCount; ++index)
872 zeroPaddingBytes((*
this)[index].resetVariableFields());
877 void construct(Size entryCount,
const void* messageTail,
const void* blockEnd)
883 const Size oldEntryCount = allocate(entryCount, messageTail, blockEnd);
885 for(Size index = oldEntryCount; index < entryCount; ++index)
886 zeroPaddingBytes((*
this)[index].reset());
890 static void zeroPaddingBytes(Entry& entry)
892 assert(entry.valid());
893 entry.zeroPaddingBytes(EntryType::minimalBlockLength(entry.version()));
905template <
class BinarySize >
925 template<
class BinaryVariableLengthFieldType>
926 BinaryVariableLengthFieldType&
head() const noexcept
928 return *
static_cast<BinaryVariableLengthFieldType*
>(binary_);
939 assert(headSize <= size_);
952 throwBadBinaryBlock();
959 throwBadBinaryBlock();
973template <
class BinarySize>
998 return Group(binary_, size_, version_);
1007 const BinarySize headSize =
head<Group>().binarySize();
1009 assert(headSize <= size_);
1011 return SbeGroupList(advanceByBytes(binary_, headSize), size_ - headSize, version_);
1020 const BinarySize headSize =
head<Group>().binarySize();
1022 assert(headSize <= size_);
1033 const BinarySize headSize = checkHead<Group>();
1035 return SbeGroupList(advanceByBytes(binary_, headSize), size_ - headSize, version_);
1044 const BinarySize headSize = checkHead<Group>();
1050 template<
class Group>
1051 BinarySize checkHead()
const
1055 throwBadBinaryBlock();
1058 const Group group = head<Group>();
1060 const BinarySize headSize = group.binarySize();
1064 throwBadBinaryBlock();
1069 const BinarySize entrySize = group.entrySize();
1070 const BinarySize expectedEntrySize = Group::Entry::minimalBlockLength(version_);
1074 throwBadBinaryBlock();
1087template<
typename Traits>
1092 throwBadMessageVersion(
version, Traits::MinimalVersion);
1097template<
typename Traits>
1104 throwBadMessageVersion(
version, since);
1109template<
typename Traits>
1114 throwBadSchemaId(Traits::Id,
id);
1119template<
typename Traits>
1209 return (
nullptr != header_);
1217 return header_->templateId();
1225 return header_->version();
1233 return header_->schemaId();
1257 return advanceByBytes(header_, size_);
1265 return advanceByBytes(header_, size_);
1287 return header_->blockLength();
1330 return GroupList(list, listSize, header_->version());
1343 return GroupList(
const_cast<void*
>(list), listSize, header_->version());
1347 template<
typename Group>
1349 void initGroup(Group& group,
typename Group::EntrySize entrySize)
noexcept
1351 assert(group.valid());
1352 group.init(entrySize);
1356 template<
typename Group>
1358 void setupGroup(Group& group,
typename Group::Size entryCount,
const void* messageTail)
1360 assert(messageTail);
1361 assert(group.valid());
1362 group.setup(entryCount, messageTail,
blockEnd());
1366 template<
typename Group>
1368 void constructGroup(Group& group,
typename Group::Size entryCount,
const void* messageTail)
1370 assert(messageTail);
1371 assert(group.valid());
1372 group.construct(entryCount, messageTail,
blockEnd());
1378 assert(oldMessageTail);
1380 const ptrdiff_t lengthChange =
static_cast<ptrdiff_t
>(value.length() - data.
length());
1382 const void*
const newMessageTail = advanceByBytes(oldMessageTail, lengthChange);
1386 throwNotEnoughSpace();
1389 const void*
const oldEndOfData = advanceByBytes(data.
varData().data(), data.
varData().size());
1391 void*
const newEndOfData = toOpaquePtr(advanceByBytes(&data, value.length() +
DATA::Size));
1393 std::memmove(newEndOfData, oldEndOfData, byteDistance(oldMessageTail, oldEndOfData));
1437 header_->setTemplateId(value);
1439 header_->setSchemaId(
id);
1449 const ptrdiff_t distance = byteDistance(tail,
binary());
1451 assert(distance > 0);
1453 assert(distance <= (std::numeric_limits<MessageSize>::max)());
1457 assert(size <= size_);
1463 template<
class Callable,
class Owner>
1470 template<
class Callable,
class Owner>
1475 throwDisallowedField();
1482 template<
class Callable,
class Owner>
1486 return callable(owner).varData();
1490 template<
class Callable,
class Owner>
1502 template<
class Callable,
class Owner>
1506 callable(owner).length(0);
1510 template<
class Group,
class Callable,
class Owner>
1513 const typename Group::EntrySize entrySize = Group::Entry::blockLength(
version());
1515 Group grp = callable(owner);
1521 template<
class Callable,
class Owner>
1533 template<
class Group,
class Callable,
class Owner>
1545 template<
class Group,
class Callable,
class Owner>
1546 Group
getGroup(Callable callable, Owner& owner)
const noexcept
1549 return callable(owner);
1553 template<
class Group,
class Callable,
class Owner>
1565 template<
class Group,
class Callable,
class Owner>
1577 template<
class Group,
class Callable,
class Owner>
1580 Group group = callable(owner);
1588 template<
class Group,
class Callable,
class Owner>
1600 template<
class Group,
class Callable,
class Owner>
1601 Group
setupGroup(Callable callable,
typename Group::Size length, Owner& owner)
1603 Group group = callable(owner);
#define ONIXS_ILINK3_MESSAGING_NAMESPACE_END
#define ONIXS_ILINK3_LTWT_CLASS
#define ONIXS_ILINK3_MESSAGING_NAMESPACE_BEGIN
#define ONIXS_ILINK3_LTWT_EXPORTED
#define ONIXS_ILINK3_UNLIKELY(cond)
#define ONIXS_ILINK3_HOTPATH
#define ONIXS_ILINK3_NODISCARD
#define ONIXS_ILINK3_CHECK_NOTHROW(equation)
#define ONIXS_ILINK3_UNUSED
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
Value ordinary(BlockLength offset, SchemaVersion since) const
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 zeroPaddingBytes(BlockLength offset) noexcept
If specified, the extra space is padded at the end of each entry and should be set to zeroes by encod...
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< QuoteEntry, 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 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
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.
void setVarDataField(DATA &data, StrRef value, const void *oldMessageTail)
Sets the variable length field value.
void init(MessageHeader::TemplateId value, MessageHeader::BlockLength minimalBlockLength, MessageHeader::BlockLength blockLength, SchemaId id) noexcept
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.
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.
MessageHeader::Version SchemaVersion
SBE-encoded data version type.
constexpr UInt16 MaxILink3MessageSize
Maximum supported message size.
char Char
Character type alias.
UInt16 MessageSize
Message length type.
std::basic_string_view< Char > StrRef
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.
const char * version() noexcept
StrRef varData() const noexcept
Length length() const noexcept