43template<
typename Message>
inline
44void checkBinaryLength(
const Message&, MessageSize length, MessageSize minimalRequiredLength)
46 if ONIXS_B3_BOE_UNLIKELY(length < minimalRequiredLength)
47 throwBinaryBlockIsTooSmall(length, minimalRequiredLength, Message::className());
63template < class Container, class BlockLength >
69 return *
static_cast <const Container*
> (
this);
82 assert(container().blockLength() >= (offset + size<Value>()) &&
83 "The requested field exceeds provided block boundaries.");
85 const void*
const location = advanceByBytes(container().block(), offset);
86 return getValue<Value>(location);
93 assert(container().blockLength() >= (offset + size<Value>()) &&
94 "The requested field exceeds provided block boundaries.");
96 const void* location = advanceByBytes(container().block(), offset);
97 const Value* valuePtr =
static_cast<const Value*
>(location);
117 return (null != value);
127 return (since <= container().version() &&
ordinary (value, offset, null ) );
134 typedef typename Enumeration::Base Base;
135 typedef typename Enumeration::Enum Enum;
144 typedef typename Enumeration::Base Base;
145 typedef typename Enumeration::Enum Enum;
148 return null != value;
173 return null != value;
183 return (since <= container().version() &&
decimal(value, offset, null));
190 assert(container().blockLength() >= (offset + Length) &&
"The requested field exceeds provided block boundaries.");
192 const Char*
const text =
reinterpret_cast <const Char*
> (advanceByBytes(container().block(), offset));
194 return StrRef(text, strnlen(text, Length));
205 return !value.empty();
223template <
class Container,
class BlockLength >
230 return *
static_cast<Container*
>(
this);
237 const BlockLength encodedBlockLength =
container().blockLength();
239 assert(encodedBlockLength >= offset);
241 const size_t paddingLength = encodedBlockLength - offset;
242 std::memset(advanceByBytes(
container().block(), offset), 0, paddingLength);
249 assert(
container().blockLength() >= (offset + size<FieldValue>()) &&
"The requested field exceeds provided block boundaries.");
251 void*
const fieldPos = advanceByBytes(
container().block(), offset);
252 setValue(fieldPos, value);
259 if ONIXS_B3_BOE_UNLIKELY(since >
container().version())
260 throwDisallowedField();
269 typedef typename Enumeration::Base Base;
277 typedef typename Enumeration::Base Base;
278 setOrdinary(offset,
static_cast<Base
>(value), since);
285 assert(
container().blockLength() >= (offset + Size) &&
"The requested field exceeds provided block boundaries.");
286 assert(value.size() <= Size &&
"The string is truncated.");
288 void*
const fieldPos = advanceByBytes(
container().block(), offset);
289 const size_t sizeToCopy = (std::min)(Size,
static_cast<BlockLength
>(value.size()));
292 std::memcpy(fieldPos, value.data(), sizeToCopy);
294 std::memset(advanceByBytes(fieldPos, sizeToCopy), 0, Size - sizeToCopy);
301 if ONIXS_B3_BOE_UNLIKELY(since >
container().version())
302 throwDisallowedField();
315template <class BodySizeType>
397template <
class EntryType,
class BlockLength,
class NumInGroup,
class Length >
454 return Entry(entry_, size_, version_);
466 return entry_ == other.entry_;
472 return entry_ != other.entry_;
478 return entry_ < other.entry_;
484 return entry_ > other.entry_;
492 entry_ = advanceByBytes(entry_, size_);
502 entry_ = advanceBackByBytes(entry_, size_);
513 return Iterator(advanceByBytes(entry_, distance * size_), size_, version_);
522 return Iterator(advanceBackByBytes(entry_, distance * size_), size_, version_);
543 , blockLength_(blockLength)
548 assert(blockLength > 0);
549 assert(version != 0);
573 return Iterator(
encoded(), blockLength_, version_);
587 assert(index < size_);
590 return Entry(advanceByBytes(encoded_,
static_cast<ptrdiff_t
>(index) * blockLength_), blockLength_, version_);
606 template<
class OtherEntry,
class OtherBlockLength,
class OtherNumInGroup,
class OtherLength >
608 : encoded_(other.encoded_)
609 , blockLength_(other.blockLength_)
611 , version_(other.version_)
616 assert(blockLength_ == other.blockLength_);
617 assert(size_ == other.size_);
620 template <
class OtherEntry,
class OtherBlockLength,
class OtherNumInGroup,
class OtherLength>
623 encoded_ = other.encoded_;
625 blockLength_ = other.blockLength_;
627 assert(blockLength_ == other.blockLength_);
631 assert(size_ == other.size_);
633 version_ = other.version_;
640 template <
class OtherEntry,
class OtherBlockLength,
class OtherNumInGroup,
class OtherLength>
friend class SbeGroupEntries;
643 BlockLength blockLength_;
649template <
class EntryType,
class DimensionType,
class GroupSizeType >
666 typedef SbeGroupEntries <EntryType, typename Dimension::BlockLength, typename Dimension::NumInGroup, GroupSizeType >
Entries;
689 : header_(
static_cast <Dimension*
>(data))
751 assert(index <
size());
763 return Entries (entries_, header_->blockLength(), header_->numInGroup(), version_);
810 Dimension*
const group =
static_cast<Dimension*
>(header_);
811 group->setBlockLength(entrySize);
812 group->setNumInGroup(0);
816 Size allocate(Size entryCount,
const void* messageTail,
const void* blockEnd)
822 Dimension*
const group =
static_cast<Dimension*
>(header_);
824 const EntrySize entrySize = group->blockLength();
826 if ONIXS_B3_BOE_UNLIKELY(
827 entrySize < EntryType::blockLength(version_))
829 throwBadBinaryBlock();
832 const Size oldEntryCount = group->numInGroup();
834 if(oldEntryCount == entryCount)
837 const ptrdiff_t memShift =
838 (entryCount - oldEntryCount) *
static_cast<ptrdiff_t
>(entrySize);
840 const void*
const newMessageTail =
841 advanceByBytes(messageTail, memShift);
843 if ONIXS_B3_BOE_UNLIKELY(byteDistance(blockEnd, newMessageTail) < 0)
844 throwNotEnoughSpace();
846 const
void* const oldEndOfGroup =
847 advanceByBytes(entries_, static_cast<ptrdiff_t>(entrySize) * oldEntryCount);
849 void* const newEndGroup =
850 advanceByBytes(entries_, static_cast<ptrdiff_t>(entrySize) * entryCount);
855 byteDistance(messageTail, oldEndOfGroup));
857 group->setNumInGroup(entryCount);
859 return oldEntryCount;
864 void setup(Size entryCount, const
void* messageTail, const
void* blockEnd)
870 const Size oldEntryCount = allocate(entryCount, messageTail, blockEnd);
872 for(Size index = oldEntryCount; index < entryCount; ++index)
873 zeroPaddingBytes((*
this)[index].resetVariableFields());
878 void construct(Size entryCount,
const void* messageTail,
const void* blockEnd)
884 const Size oldEntryCount = allocate(entryCount, messageTail, blockEnd);
886 for(Size index = oldEntryCount; index < entryCount; ++index)
887 zeroPaddingBytes((*
this)[index].reset());
891 static void zeroPaddingBytes(Entry& entry)
893 assert(entry.valid());
894 entry.zeroPaddingBytes(EntryType::minimalBlockLength(entry.version()));
906template <
class BinarySize >
926 template<
class BinaryVariableLengthFieldType>
929 return *
static_cast<BinaryVariableLengthFieldType*
>(binary_);
940 assert(headSize <= size_);
951 if ONIXS_B3_BOE_UNLIKELY(
empty() || (size_ < BinaryVariableLengthFieldType::Size))
953 throwBadBinaryBlock();
958 if ONIXS_B3_BOE_UNLIKELY(headSize > size_)
960 throwBadBinaryBlock();
974template <
class BinarySize>
999 return Group(binary_, size_, version_);
1008 const BinarySize headSize =
head<Group>().binarySize();
1010 assert(headSize <= size_);
1012 return SbeGroupList(advanceByBytes(binary_, headSize), size_ - headSize, version_);
1021 const BinarySize headSize =
head<Group>().binarySize();
1023 assert(headSize <= size_);
1034 const BinarySize headSize = checkHead<Group>();
1036 return SbeGroupList(advanceByBytes(binary_, headSize), size_ - headSize, version_);
1045 const BinarySize headSize = checkHead<Group>();
1051 template<
class Group>
1052 BinarySize checkHead()
const
1054 if ONIXS_B3_BOE_UNLIKELY(size_ < Group::Dimension::Size)
1056 throwBadBinaryBlock();
1059 const Group group = head<Group>();
1061 const BinarySize headSize = group.binarySize();
1063 if ONIXS_B3_BOE_UNLIKELY(headSize > size_)
1065 throwBadBinaryBlock();
1070 const BinarySize entrySize = group.entrySize();
1071 const BinarySize expectedEntrySize = Group::Entry::minimalBlockLength(version_);
1073 if ONIXS_B3_BOE_UNLIKELY(entrySize < expectedEntrySize)
1075 throwBadBinaryBlock();
1088template<
typename Traits>
1091 if ONIXS_B3_BOE_UNLIKELY(version < Traits::MinimalVersion)
1093 throwBadMessageVersion(version, Traits::MinimalVersion);
1098template<
typename Traits>
1103 if ONIXS_B3_BOE_UNLIKELY(version < since)
1105 throwBadMessageVersion(version, since);
1110template<
typename Traits>
1113 if ONIXS_B3_BOE_UNLIKELY(
id != Traits::Id)
1115 throwBadSchemaId(Traits::Id,
id);
1120template<
typename Traits>
1214 return header_->templateId();
1222 return header_->version();
1230 return header_->schemaId();
1254 return advanceByBytes(header_, size_);
1262 return advanceByBytes(header_, size_);
1284 return header_->blockLength();
1327 return GroupList(list, listSize, header_->version());
1340 return GroupList(
const_cast<void*
>(list), listSize, header_->version());
1344 template<
typename Group>
1348 assert(group.valid());
1349 group.init(entrySize);
1353 template<
typename Group>
1355 void setupGroup(Group& group,
typename Group::Size entryCount,
const void* messageTail)
1357 assert(messageTail);
1358 assert(group.valid());
1359 group.setup(entryCount, messageTail,
blockEnd());
1363 template<
typename Group>
1365 void constructGroup(Group& group,
typename Group::Size entryCount,
const void* messageTail)
1367 assert(messageTail);
1368 assert(group.valid());
1369 group.construct(entryCount, messageTail,
blockEnd());
1373 template<
typename DATA>
1376 assert(oldMessageTail);
1378 const ptrdiff_t lengthChange =
static_cast<ptrdiff_t
>(value.length() - data.length());
1380 const void*
const newMessageTail = advanceByBytes(oldMessageTail, lengthChange);
1382 if ONIXS_B3_BOE_UNLIKELY(byteDistance(
blockEnd(), newMessageTail) < 0)
1383 throwNotEnoughSpace();
1385 const void*
const oldEndOfData = advanceByBytes(data.varData().data(), data.varData().size());
1387 void*
const newEndOfData = toOpaquePtr(advanceByBytes(&data, value.length() + DATA::Size));
1389 std::memmove(newEndOfData, oldEndOfData, byteDistance(oldMessageTail, oldEndOfData));
1391 data.varData(value);
1433 header_->setTemplateId(value);
1435 header_->setSchemaId(
id);
1445 const ptrdiff_t distance = byteDistance(tail,
binary());
1447 assert(distance > 0);
1449 assert(distance <= (std::numeric_limits<MessageSize>::max)());
1453 assert(size <= size_);
1459 template<
class Callable,
class Owner>
1466 template<
class Callable,
class Owner>
1469 if ONIXS_B3_BOE_UNLIKELY(since >
version())
1470 throwDisallowedField();
1476 template<
class Callable,
class Owner>
1479 ONIXS_B3_BOE_CHECK_NOTHROW(callable(owner));
1480 return callable(owner).varData();
1484 template<
class Callable,
class Owner>
1487 if ONIXS_B3_BOE_UNLIKELY(since >
version())
1494 template<
class Callable,
class Owner>
1497 ONIXS_B3_BOE_CHECK_NOTHROW(callable(owner));
1498 callable(owner).length(0);
1502 template<
class Group,
class Callable,
class Owner>
1505 const typename Group::EntrySize entrySize = Group::Entry::blockLength(
version());
1507 Group grp = callable(owner);
1513 template<
class Callable,
class Owner>
1516 if ONIXS_B3_BOE_UNLIKELY(since >
version())
1523 template<
class Group,
class Callable,
class Owner>
1526 if ONIXS_B3_BOE_UNLIKELY(since >
version())
1533 template<
class Group,
class Callable,
class Owner>
1536 ONIXS_B3_BOE_CHECK_NOTHROW(callable(owner));
1537 return callable(owner);
1541 template<
class Group,
class Callable,
class Owner>
1544 if ONIXS_B3_BOE_UNLIKELY(since >
version())
1551 template<
class Group,
class Callable,
class Owner>
1554 if ONIXS_B3_BOE_UNLIKELY(since >
version())
1561 template<
class Group,
class Callable,
class Owner>
1564 Group group = callable(owner);
1572 template<
class Group,
class Callable,
class Owner>
1575 if ONIXS_B3_BOE_UNLIKELY(since >
version())
1582 template<
class Group,
class Callable,
class Owner>
1583 Group
setupGroup(Callable callable,
typename Group::Size length, Owner& owner)
1585 Group group = callable(owner);
#define ONIXS_B3_BOE_LTWT_EXPORTED
#define ONIXS_B3_BOE_MESSAGING_NAMESPACE_END
#define ONIXS_B3_BOE_MESSAGING_NAMESPACE_BEGIN
#define ONIXS_B3_BOE_LTWT_CLASS
#define ONIXS_B3_BOE_UNUSED
#define ONIXS_B3_BOE_CONSTEXPR
#define ONIXS_B3_BOE_NODISCARD
#define ONIXS_B3_BOE_DEFAULT
#define ONIXS_B3_BOE_NULLPTR
#define ONIXS_B3_BOE_NOTHROW
#define ONIXS_B3_BOE_HOTPATH
bool decimal(Value &value, BlockLength offset, NullValue null) const noexcept
bool fixedStr(StrRef &value, BlockLength offset) const noexcept
Value ordinary(BlockLength offset) const noexcept
Value & accessOrdinary(BlockLength offset) noexcept
const Value & accessOrdinary(BlockLength offset) const noexcept
bool fixedStr(StrRef &value, BlockLength offset, SchemaVersion since) const noexcept
bool ordinary(Value &value, BlockLength offset, NullValue null) const noexcept
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
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
Root block length.
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.
std::random_access_iterator_tag iterator_category
Iterator() noexcept
Initializes the instance that refers to nothing.
bool valid() const noexcept
ptrdiff_t difference_type
Iterator(void *entry, EncodedLength size, SchemaVersion version) noexcept
Initializes the instance to the given repeating group.
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
BodySizeType BlockLength
Type to present the length of binary data of the repeating group entry.
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.
Entries::Size Size
Number of entries in the group.
GroupSizeType BinarySize
Length of group data.
EntrySize entrySize() const noexcept
BinarySize binarySize() const noexcept
bool empty() const noexcept
DimensionType::BlockLength EntrySize
Length of group entry data.
SbeGroup(void *data, BinarySize size, SchemaVersion version) noexcept
Initializes an instance referencing to a valid group of a given message.
Entries::Iterator Iterator
The iterator type for group entries.
Entries::Entry Entry
Group entry type.
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< EntryType, typename Dimension::BlockLength, typename Dimension::NumInGroup, GroupSizeType > Entries
Binary group blocks.
DimensionType Dimension
Repeating group dimension type.
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
void setVarDataField(DATA &data, StrRef value, const void *oldMessageTail)
Sets the variable length field value.
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 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.
constexpr UInt16 MaxB3BOEMessageSize
Maximum supported message size.
void checkSchemaId(SchemaId id)
Checks the compatibility with the provided SBE Schema ID.
MessageHeader::Version SchemaVersion
SBE-encoded data version type.
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.