OnixS C++ CME MDP Premium Market Data Handler 5.11.1
Users' manual and API documentation
Loading...
Searching...
No Matches
SbeMessage.h
Go to the documentation of this file.
1// Copyright Onix Solutions Limited [OnixS]. All rights reserved.
2//
3// This software owned by Onix Solutions Limited [OnixS] and is
4// protected by copyright law and international copyright treaties.
5//
6// Access to and use of the software is governed by the terms of the applicable
7// OnixS Software Services Agreement (the Agreement) and Customer end user license
8// agreements granting a non-assignable, non-transferable and non-exclusive license
9// to use the software for it's own data processing purposes under the terms defined
10// in the Agreement.
11//
12// Except as otherwise granted within the terms of the Agreement, copying or
13// reproduction of any part of this source code or associated reference material
14// to any other location for further reproduction or redistribution, and any
15// amendments to this copyright notice, are expressly prohibited.
16//
17// Any reproduction or redistribution for sale or hiring of the Software not in
18// accordance with the terms of the Agreement is a violation of copyright law.
19//
20
21#pragma once
22
23#include <OnixS/CME/MDH/ABI.h>
34
35#include <cassert>
36#include <cstddef>
37#include <iterator>
38#include <limits>
39#include <new>
40#include <stdexcept>
41
42#if defined(ONIXS_CMEMDH_CXX20)
43#include <ranges>
44#endif
45
47
49typedef MessageHeader::TemplateId MessageTemplateId;
50
52template <typename Message>
53inline void checkBinaryLength(const Message&, MessageSize length, MessageSize minimalRequiredLength)
54{
55 if ONIXS_CMEMDH_UNLIKELY (length < minimalRequiredLength)
56 {
57 throwBinaryBlockIsTooSmall(length, minimalRequiredLength, Message::className());
58 }
59}
60
62{
63protected:
64 ~BinaryBlockBase() = default;
65};
66
72template <class Container, class BlockLength>
74{
77 const Container& container() const noexcept
78 {
79 return *static_cast<const Container*>(this);
80 }
81
82protected:
84 BinaryBlock() = default;
85
86 ~BinaryBlock() = default;
87
89 template <class Value>
91 Value ordinary(BlockLength offset) const noexcept
92 {
93 assert(
94 container().blockLength() >= (offset + size<Value>())
95 && "The requested field exceeds provided block boundaries."
96 );
97
98 const void* const location = advanceByBytes(container().block(), offset);
99 return getValue<Value>(location);
100 }
101
103 template <class Value>
105 Value ordinary(BlockLength offset, SchemaVersion since) const
106 {
107 if ONIXS_CMEMDH_UNLIKELY (since > container().version())
108 throwDisallowedField();
109
110 return ordinary<Value>(offset);
111 }
112
117 template <class Value, class NullValue>
119 bool ordinary(Value& value, BlockLength offset, NullValue null) const noexcept
120 {
121 value = ordinary<Value>(offset);
122
123 return (null != value);
124 }
125
130 template <class Value, class NullValue>
132 bool ordinary(Value& value, BlockLength offset, NullValue null, SchemaVersion since) const noexcept
133 {
134 return (since <= container().version() && ordinary(value, offset, null));
135 }
136
138 template <class Enumeration>
140 typename Enumeration::Enum enumeration(BlockLength offset) const noexcept
141 {
142 typedef typename Enumeration::Base Base;
143 typedef typename Enumeration::Enum Enum;
144
145 return static_cast<Enum>(ordinary<Base>(offset));
146 }
147
149 template <class Enumeration, class NullValue>
151 bool enumeration(typename Enumeration::Enum& value, BlockLength offset, NullValue null) const noexcept
152 {
153 typedef typename Enumeration::Base Base;
154 typedef typename Enumeration::Enum Enum;
155
156 value = static_cast<Enum>(ordinary<Base>(offset));
157 return null != value;
158 }
159
161 template <class Enumeration, class NullValue>
163 bool enumeration(typename Enumeration::Enum& value, BlockLength offset, NullValue null, SchemaVersion since) const noexcept
164 {
165 return (since <= container().version() && enumeration<Enumeration>(value, offset, null));
166 }
167
169 template <class Value>
171 Decimal decimal(BlockLength offset) const
172 {
173 return Decimal(ordinary<Value>(offset));
174 }
175
180 template <class NullValue>
182 bool decimal(Decimal& value, BlockLength offset, NullValue null) const noexcept
183 {
184 typedef typename NullValue::Value Value;
185 const Value optional = ordinary<Value>(offset);
186 value = optional;
187
188 return null != optional;
189 }
190
195 template <class Value, class NullValue>
197 bool decimal(Value& value, BlockLength offset, NullValue null, SchemaVersion since) const noexcept
198 {
199 return (since <= container().version() && decimal(value, offset, null));
200 }
201
203 template <BlockLength Length>
205 StrRef fixedStr(BlockLength offset) const noexcept
206 {
207 assert(
208 container().blockLength() >= (offset + Length) && "The requested field exceeds provided block boundaries."
209 );
210
211 const Char* const text = reinterpret_cast<const Char*>(advanceByBytes(container().block(), offset));
212 return StrRef(text, strnlen(text, Length));
213 }
214
219 template <BlockLength Length>
221 bool fixedStr(StrRef& value, BlockLength offset) const noexcept
222 {
223 value = fixedStr<Length>(offset);
224 return !value.empty();
225 }
226
231 template <BlockLength Length>
233 bool fixedStr(StrRef& value, BlockLength offset, SchemaVersion since) const noexcept
234 {
235 return (since <= container().version() && fixedStr<Length>(value, offset));
236 }
237};
238
243template <class Container, class BlockLength>
244class SbeFields : public BinaryBlock<Container, BlockLength>
245{
246public:
249 Container& container() noexcept
250 {
251 return *static_cast<Container*>(this);
252 }
253
256 void zeroPaddingBytes(BlockLength offset) noexcept
257 {
258 const BlockLength encodedBlockLength = container().blockLength();
259
260 assert(encodedBlockLength >= offset);
261
262 const size_t paddingLength = encodedBlockLength - offset;
263 std::memset(advanceByBytes(container().block(), offset), 0, paddingLength);
264 }
265
267 template <class FieldValue>
269 void setOrdinary(BlockLength offset, FieldValue value) noexcept
270 {
271 assert(
272 container().blockLength() >= (offset + size<FieldValue>())
273 && "The requested field exceeds provided block boundaries."
274 );
275
276 void* const fieldPos = advanceByBytes(container().block(), offset);
277 setValue(fieldPos, value);
278 }
279
281 template <class FieldValue>
283 void setOrdinary(BlockLength offset, FieldValue value, SchemaVersion since)
284 {
285 if ONIXS_CMEMDH_UNLIKELY (since > container().version())
286 {
287 throwDisallowedField();
288 }
289
290 setOrdinary(offset, value);
291 }
292
294 template <class Enumeration>
296 void setEnumeration(BlockLength offset, typename Enumeration::Enum value) noexcept
297 {
298 typedef typename Enumeration::Base Base;
299 setOrdinary<Base>(offset, static_cast<Base>(value));
300 }
301
303 template <class Enumeration>
305 void setEnumeration(BlockLength offset, typename Enumeration::Enum value, SchemaVersion since)
306 {
307 typedef typename Enumeration::Base Base;
308 setOrdinary(offset, static_cast<Base>(value), since);
309 }
310
312 template <BlockLength Size>
314 void setFixedStr(BlockLength offset, StrRef value) noexcept
315 {
316 assert(
317 container().blockLength() >= (offset + Size) && "The requested field exceeds provided block boundaries."
318 );
319 assert(value.size() <= Size && "The string is truncated.");
320
321 void* const fieldPos = advanceByBytes(container().block(), offset);
322 const size_t sizeToCopy = (std::min)(Size, static_cast<BlockLength>(value.size()));
323
324 if (sizeToCopy > 0)
325 std::memcpy(fieldPos, value.data(), sizeToCopy);
326
327 std::memset(advanceByBytes(fieldPos, sizeToCopy), 0, Size - sizeToCopy);
328 }
329
331 template <BlockLength Size>
333 void setFixedStr(BlockLength offset, StrRef value, SchemaVersion since)
334 {
335 if ONIXS_CMEMDH_UNLIKELY (since > container().version())
336 {
337 throwDisallowedField();
338 }
339
340 setFixedStr<Size>(offset, value);
341 }
342
343protected:
345 SbeFields() = default;
346
347 ~SbeFields() = default;
348};
349
351template <class BodySizeType>
352class SbeGroupEntry : public SbeFields<SbeGroupEntry<BodySizeType>, BodySizeType>
353{
354public:
356 typedef BodySizeType BlockLength;
357
360 : encoded_(nullptr)
361 , size_(0)
362 , version_(0)
363 {
364 }
365
369 : encoded_(encoded)
370 , size_(size)
371 , version_(version)
372 {
373 assert(encoded);
374 }
375
378 bool valid() const noexcept
379 {
380 return (encoded_ != nullptr);
381 }
382
385 const void* encoded() const noexcept
386 {
387 assert(valid());
388
389 return encoded_;
390 }
391
394 void* encoded() noexcept
395 {
396 assert(valid());
397
398 return encoded_;
399 }
400
403 const void* block() const noexcept
404 {
405 assert(valid());
406
407 return encoded_;
408 }
409
412 void* block() noexcept
413 {
414 assert(valid());
415
416 return encoded_;
417 }
418
421 BlockLength blockLength() const noexcept
422 {
423 return size_;
424 }
425
428 SchemaVersion version() const noexcept
429 {
430 return version_;
431 }
432
433private:
434 void* encoded_;
435 BodySizeType size_;
436 SchemaVersion version_;
437};
438
439#if defined(ONIXS_CMEMDH_CXX20)
440template <class EntryType, class BlockLength, class NumInGroup, class Length> class SbeGroupRange;
441#endif
442
444template <class EntryType, class BlockLength, class NumInGroup, class Length>
446{
447public:
449 typedef Length EncodedLength;
450
453
455 typedef NumInGroup Size;
456
459 {
460 public:
463
464 typedef Entry* pointer;
465 typedef Entry& reference;
466
467 typedef ptrdiff_t difference_type;
468
469 typedef std::random_access_iterator_tag iterator_category;
470
472 Iterator() noexcept
473 : entry_(nullptr)
474 , size_(0)
475 , version_(0)
476 {
477 }
478
481 Iterator(void* entry, EncodedLength size, SchemaVersion version) noexcept
482 : entry_(entry)
483 , size_(size)
484 , version_(version)
485 {
486 assert(valid());
487 }
488
490 bool valid() const noexcept
491 {
492 return (entry_ != nullptr);
493 }
494
497 Entry get() const
498 {
499 assert(valid());
500
501 return Entry(entry_, size_, version_);
502 }
503
506 {
507 return get();
508 }
509
511 bool operator==(const Iterator& other) const noexcept
512 {
513 return entry_ == other.entry_;
514 }
515
517 bool operator!=(const Iterator& other) const noexcept
518 {
519 return entry_ != other.entry_;
520 }
521
523 bool operator<(const Iterator& other) const noexcept
524 {
525 return entry_ < other.entry_;
526 }
527
529 bool operator>(const Iterator& other) const noexcept
530 {
531 return entry_ > other.entry_;
532 }
533
536 {
537 assert(valid());
538
539 entry_ = advanceByBytes(entry_, size_);
540
541 return *this;
542 }
543
546 {
547 assert(valid());
548
549 entry_ = advanceBackByBytes(entry_, size_);
550
551 return *this;
552 }
553
557 {
558 assert(valid());
559
560 return Iterator(advanceByBytes(entry_, distance * size_), size_, version_);
561 }
562
566 {
567 assert(valid());
568
569 return Iterator(advanceBackByBytes(entry_, distance * size_), size_, version_);
570 }
571
572 private:
573 void* entry_;
574 EncodedLength size_;
575 SchemaVersion version_;
576 };
577
578#if defined(ONIXS_CMEMDH_CXX20)
581#endif
582
585 : encoded_(nullptr)
586 , blockLength_(0)
587 , size_(0)
588 , version_(0)
589 {
590 }
591
593 SbeGroupEntries(void* encoded, BlockLength blockLength, Size groupSize, SchemaVersion version) noexcept
594 : encoded_(encoded)
595 , blockLength_(blockLength)
596 , size_(groupSize)
597 , version_(version)
598 {
599 assert(encoded_);
600 assert(blockLength > 0);
601 assert(version != 0);
602 }
603
605 bool valid() const noexcept
606 {
607 return (nullptr != encoded_);
608 }
609
611 bool empty() const noexcept
612 {
613 return (0 == size_);
614 }
615
617 Size size() const noexcept
618 {
619 return size_;
620 }
621
623 Iterator begin() const
624 {
625 return Iterator(encoded(), blockLength_, version_);
626 }
627
629 Iterator end() const
630 {
631 return Iterator(advanceByBytes(encoded(), encodedLength()), blockLength_, version_);
632 }
633
634#if defined(ONIXS_CMEMDH_CXX20)
640 Range asRange() const noexcept
641 {
642 return Range(begin(), end(), size());
643 }
644#endif
645
649 Entry operator[](Size index) const
650 {
651 assert(index < size_);
652 assert(encoded_);
653
654 return Entry(advanceByBytes(encoded_, static_cast<ptrdiff_t>(index) * blockLength_), blockLength_, version_);
655 }
656
658 void* encoded() const noexcept
659 {
660 return encoded_;
661 }
662
665 {
666 return (static_cast<EncodedLength>(blockLength_) * static_cast<EncodedLength>(size_));
667 }
668
670 template <class OtherEntry, class OtherBlockLength, class OtherNumInGroup, class OtherLength>
672 : encoded_(other.encoded_)
673 , blockLength_(other.blockLength_)
674 , size_(other.size_)
675 , version_(other.version_)
676 {
677 // Dimension types may vary for the different instantiations of the template.
678 // Therefore, truncation of the dimensions must be avoided.
679
680 assert(blockLength_ == other.blockLength_);
681 assert(size_ == other.size_);
682 }
683
684 template <class OtherEntry, class OtherBlockLength, class OtherNumInGroup, class OtherLength>
686 ) noexcept
687 {
688 encoded_ = other.encoded_;
689
690 blockLength_ = other.blockLength_;
691
692 assert(blockLength_ == other.blockLength_);
693
694 size_ = other.size_;
695
696 assert(size_ == other.size_);
697
698 version_ = other.version_;
699
700 return *this;
701 }
702
703private:
704 // Allows coping and cloning for different instantiations.
705 template <class OtherEntry, class OtherBlockLength, class OtherNumInGroup, class OtherLength>
706 friend class SbeGroupEntries;
707
708 void* encoded_;
709 BlockLength blockLength_;
710 NumInGroup size_;
711 SchemaVersion version_;
712};
713
714#if defined(ONIXS_CMEMDH_CXX20)
715
726template <class EntryType, class BlockLength, class NumInGroup, class Length>
727class SbeGroupRange : public std::ranges::view_base
728{
730 typedef NumInGroup Size;
731
732public:
735 {
736 public:
739
742 {
743 public:
746 explicit Pointer(EntryType entry)
747 : entry_(entry)
748 {
749 }
750
755 {
756 return &entry_;
757 }
758
761 const EntryType* operator->() const noexcept
762 {
763 return &entry_;
764 }
765
766 private:
767 EntryType entry_;
768 };
769
775 typedef ptrdiff_t difference_type;
777 typedef std::input_iterator_tag iterator_category;
779 typedef std::forward_iterator_tag iterator_concept;
780
782 Iterator() noexcept = default;
783
786 explicit Iterator(typename Entries::Iterator iterator) noexcept
787 : iterator_(iterator)
788 {
789 }
790
794 {
795 return *iterator_;
796 }
797
801 {
802 return pointer(operator*());
803 }
804
808 {
809 ++iterator_;
810 return *this;
811 }
812
816 {
817 Iterator previous(*this);
818 ++*this;
819 return previous;
820 }
821
825 bool operator==(const Iterator& other) const noexcept
826 {
827 return iterator_ == other.iterator_;
828 }
829
833 bool operator!=(const Iterator& other) const noexcept
834 {
835 return !(*this == other);
836 }
837
838 private:
839 typename Entries::Iterator iterator_;
840 };
841
843 SbeGroupRange() noexcept
844 : begin_()
845 , end_()
846 , size_(0)
847 {
848 }
849
852 Iterator begin() const noexcept
853 {
854 return begin_;
855 }
856
859 Iterator end() const noexcept
860 {
861 return end_;
862 }
863
866 std::size_t size() const noexcept
867 {
868 return size_;
869 }
870
873 bool empty() const noexcept
874 {
875 return size_ == 0;
876 }
877
878private:
879 friend class SbeGroupEntries<EntryType, BlockLength, NumInGroup, Length>;
880
881 SbeGroupRange(typename Entries::Iterator begin, typename Entries::Iterator end, Size size) noexcept
882 : begin_(begin)
883 , end_(end)
884 , size_(size)
885 {
886 }
887
888 Iterator begin_;
889 Iterator end_;
890 Size size_;
891};
892
893#endif
894
896template <class EntryType, class DimensionType, class GroupSizeType>
898{
899public:
901 typedef DimensionType Dimension;
902
904 typedef GroupSizeType BinarySize;
905
907 enum
908 {
910 };
911
913 typedef typename DimensionType::BlockLength EntrySize;
914
918
920 typedef typename Entries::Iterator Iterator;
921
922#if defined(ONIXS_CMEMDH_CXX20)
924 typedef typename Entries::Range Range;
925#endif
926
928 typedef typename Entries::Entry Entry;
929
931 typedef typename Entries::Size Size;
932
934 SbeGroup() noexcept
935 : header_(nullptr)
936 , entries_(nullptr)
937 , version_(0)
938 {
939 }
940
944 : header_(fromExistingBytes<Dimension>(data))
945 , entries_(advanceByBytes(data, Dimension::Size))
946 , version_(version)
947 {
948 ONIXS_CMEMDH_ASSERT(size >= Dimension::Size);
949 assert(header_);
950 assert(entries_);
951
952 assert(valid());
953 }
954
956 bool valid() const noexcept
957 {
958 return (entries_ != nullptr);
959 }
960
962 bool empty() const noexcept
963 {
964 assert(valid());
965
966 return 0 == size();
967 }
968
971 Size size() const noexcept
972 {
973 assert(valid());
974 assert(header_);
975
976 const Dimension* const group = static_cast<const Dimension*>(header_);
977
978 return group->numInGroup();
979 }
980
983 Iterator begin() const noexcept
984 {
985 assert(valid());
986
987 return Iterator(entries_, numericCast<EntrySize>(entrySize()), version_);
988 }
989
992 Iterator end() const noexcept
993 {
994 assert(valid());
995
996 return Iterator(advanceByBytes(binary(), binarySize()), numericCast<EntrySize>(entrySize()), version_);
997 }
998
1003 Entry operator[](Size index) const
1004 {
1005 assert(valid());
1006 assert(index < size());
1007
1008 return Entry(advanceByBytes(entries_, static_cast<ptrdiff_t>(index) * entrySize()), entrySize(), version_);
1009 }
1010
1013 Entries entries() const noexcept
1014 {
1015 assert(valid());
1016 assert(header_);
1017
1018 return Entries(entries_, header_->blockLength(), header_->numInGroup(), version_);
1019 }
1020
1021#if defined(ONIXS_CMEMDH_CXX20)
1027 Range asRange() const noexcept
1028 {
1029 return entries().asRange();
1030 }
1031#endif
1032
1034 const void* encoded() const noexcept
1035 {
1036 return header_;
1037 }
1038
1040 const void* tail() const noexcept
1041 {
1042 return advanceByBytes(toByteBlock(encoded()), binarySize());
1043 }
1044
1047 void* binary() const noexcept
1048 {
1049 return header_;
1050 }
1051
1054 BinarySize binarySize() const noexcept
1055 {
1056 return Dimension::Size + (static_cast<BinarySize>(entrySize()) * static_cast<BinarySize>(size()));
1057 }
1058
1061 EntrySize entrySize() const noexcept
1062 {
1063 assert(valid());
1064 assert(header_);
1065
1066 Dimension* const group = static_cast<Dimension*>(header_);
1067 return group->blockLength();
1068 }
1069
1070private:
1072 void init(EntrySize entrySize) noexcept
1073 {
1074 assert(valid());
1075 assert(header_);
1076
1077 Dimension* const group = fromEmptyStorage<Dimension>(header_);
1078 group->setBlockLength(entrySize);
1079 group->setNumInGroup(0);
1080 }
1081
1083 Size allocate(Size entryCount, const void* messageTail, const void* blockEnd)
1084 {
1085 assert(valid());
1086 assert(blockEnd);
1087 assert(messageTail);
1088
1089 Dimension* const group = static_cast<Dimension*>(header_);
1090
1091 const EntrySize entrySize = group->blockLength();
1092
1093 if ONIXS_CMEMDH_UNLIKELY (entrySize < EntryType::blockLength(version_))
1094 {
1095 throwBadBinaryBlock();
1096 }
1097
1098 const Size oldEntryCount = group->numInGroup();
1099
1100 if (oldEntryCount == entryCount)
1101 return entryCount;
1102
1103 const ptrdiff_t memShift = (entryCount - oldEntryCount) * static_cast<ptrdiff_t>(entrySize);
1104
1105 const void* const newMessageTail = advanceByBytes(messageTail, memShift);
1106
1107 if ONIXS_CMEMDH_UNLIKELY (byteDistance(blockEnd, newMessageTail) < 0)
1108 {
1109 throwNotEnoughSpace();
1110 }
1111
1112 const void* const oldEndOfGroup = advanceByBytes(entries_, static_cast<ptrdiff_t>(entrySize) * oldEntryCount);
1113
1114 void* const newEndGroup = advanceByBytes(entries_, static_cast<ptrdiff_t>(entrySize) * entryCount);
1115
1116 std::memmove(newEndGroup, oldEndOfGroup, byteDistance(messageTail, oldEndOfGroup));
1117
1118 group->setNumInGroup(entryCount);
1119
1120 return oldEntryCount;
1121 }
1122
1125 void setup(Size entryCount, const void* messageTail, const void* blockEnd)
1126 {
1127 assert(valid());
1128 assert(blockEnd);
1129 assert(messageTail);
1130
1131 const Size oldEntryCount = allocate(entryCount, messageTail, blockEnd);
1132
1133 for (Size index = oldEntryCount; index < entryCount; ++index)
1134 zeroPaddingBytes((*this)[index].resetVariableFields());
1135 }
1136
1139 void construct(Size entryCount, const void* messageTail, const void* blockEnd)
1140 {
1141 assert(valid());
1142 assert(blockEnd);
1143 assert(messageTail);
1144
1145 const Size oldEntryCount = allocate(entryCount, messageTail, blockEnd);
1146
1147 for (Size index = oldEntryCount; index < entryCount; ++index)
1148 zeroPaddingBytes((*this)[index].reset());
1149 }
1150
1152 static void zeroPaddingBytes(Entry& entry)
1153 {
1154 assert(entry.valid());
1155 entry.zeroPaddingBytes(EntryType::minimalBlockLength(entry.version()));
1156 }
1157
1158private:
1159 Dimension* header_;
1160 void* entries_;
1161 SchemaVersion version_;
1162
1163 friend class SbeMessage;
1164};
1165
1167template <class BinarySize>
1169{
1170public:
1173 SbeVariableLengthFieldList(void* binary, BinarySize size, SchemaVersion version) noexcept
1174 : binary_(binary)
1175 , size_(size)
1176 , version_(version)
1177 {
1178 }
1179
1181 bool empty() const noexcept
1182 {
1183 return (0 == size_);
1184 }
1185
1187 template <class BinaryVariableLengthFieldType>
1188 BinaryVariableLengthFieldType& head() const noexcept
1189 {
1190 return *static_cast<BinaryVariableLengthFieldType*>(binary_);
1191 }
1192
1194 template <class BinaryVariableLengthFieldType>
1196 {
1197 assert(!empty());
1198
1199 const BinarySize headSize = head<BinaryVariableLengthFieldType>().binarySize();
1200
1201 assert(headSize <= size_);
1202
1203 return SbeVariableLengthFieldList(advanceByBytes(binary_, headSize), size_ - headSize, version_);
1204 }
1205
1209 template <class BinaryVariableLengthFieldType>
1211 {
1212 if ONIXS_CMEMDH_UNLIKELY (empty() || (size_ < BinaryVariableLengthFieldType::Size))
1213 {
1214 throwBadBinaryBlock();
1215 }
1216
1217 const BinarySize headSize = head<BinaryVariableLengthFieldType>().binarySize();
1218
1219 if ONIXS_CMEMDH_UNLIKELY (headSize > size_)
1220 {
1221 throwBadBinaryBlock();
1222 }
1223
1224 return SbeVariableLengthFieldList(advanceByBytes(binary_, headSize), size_ - headSize, version_);
1225 }
1226
1227private:
1228 void* binary_;
1229 BinarySize size_;
1230 SchemaVersion version_;
1231};
1232
1234template <class BinarySize>
1236{
1237public:
1240 SbeGroupList(void* binary, BinarySize size, SchemaVersion version) noexcept
1241 : binary_(binary)
1242 , size_(size)
1243 , version_(version)
1244 {
1245 }
1246
1249 bool empty() const noexcept
1250 {
1251 return (0 == size_);
1252 }
1253
1255 template <class Group>
1257 ONIXS_CMEMDH_HOTPATH Group head() const noexcept
1258 {
1259 assert(!empty());
1260
1261 return Group(binary_, size_, version_);
1262 }
1263
1265 template <class Group>
1267 {
1268 assert(!empty());
1269
1270 const BinarySize headSize = head<Group>().binarySize();
1271
1272 assert(headSize <= size_);
1273
1274 return SbeGroupList(advanceByBytes(binary_, headSize), size_ - headSize, version_);
1275 }
1276
1278 template <class Group>
1280 {
1281 assert(!empty());
1282
1283 const BinarySize headSize = head<Group>().binarySize();
1284
1285 assert(headSize <= size_);
1286
1287 return SbeVariableLengthFieldList<BinarySize>(advanceByBytes(binary_, headSize), size_ - headSize, version_);
1288 }
1289
1293 template <class Group>
1295 {
1296 const BinarySize headSize = checkHead<Group>();
1297
1298 return SbeGroupList(advanceByBytes(binary_, headSize), size_ - headSize, version_);
1299 }
1300
1304 template <class Group>
1306 {
1307 const BinarySize headSize = checkHead<Group>();
1308
1309 return SbeVariableLengthFieldList<BinarySize>(advanceByBytes(binary_, headSize), size_ - headSize, version_);
1310 }
1311
1312private:
1313 template <class Group>
1314 BinarySize checkHead() const
1315 {
1316 if ONIXS_CMEMDH_UNLIKELY (size_ < Group::Dimension::Size)
1317 {
1318 throwBadBinaryBlock();
1319 }
1320
1321 const Group group = head<Group>();
1322
1323 const BinarySize headSize = group.binarySize();
1324
1325 if ONIXS_CMEMDH_UNLIKELY (headSize > size_)
1326 {
1327 throwBadBinaryBlock();
1328 }
1329
1330 if (!group.empty())
1331 {
1332 const BinarySize entrySize = group.entrySize();
1333 const BinarySize expectedEntrySize = Group::Entry::minimalBlockLength(version_);
1334
1335 if ONIXS_CMEMDH_UNLIKELY (entrySize < expectedEntrySize)
1336 {
1337 throwBadBinaryBlock();
1338 }
1339 }
1340
1341 return headSize;
1342 }
1343
1344 void* binary_;
1345 BinarySize size_;
1346 SchemaVersion version_;
1347};
1348
1350template <typename Traits>
1352{
1353 if ONIXS_CMEMDH_UNLIKELY (version < Traits::MinimalVersion)
1354 {
1355 throwBadMessageVersion(version, Traits::MinimalVersion);
1356 }
1357}
1358
1360template <typename Traits>
1362{
1363 checkVersion<Traits>(version);
1364
1365 if ONIXS_CMEMDH_UNLIKELY (version < since)
1366 {
1367 throwBadMessageVersion(version, since);
1368 }
1369}
1370
1372template <typename Traits>
1374{
1375 if ONIXS_CMEMDH_UNLIKELY (id != Traits::Id)
1376 {
1377 throwBadSchemaId(Traits::Id, id);
1378 }
1379}
1380
1382template <typename Traits>
1384{
1386 checkVersion<Traits>(version);
1387}
1388
1390class SbeMessage : public SbeFields<Messaging::SbeMessage, MessageSize>
1391{
1392public:
1395 struct NoInit{};
1396 struct NoCheck{};
1397
1400
1403
1405 SbeMessage() noexcept
1406 : header_(nullptr)
1407 , size_(0)
1408 {
1409 }
1410
1414 : header_(nullptr)
1415 , size_(size)
1416 {
1417 assert(data);
1418 assert(size <= MaxMessageSize);
1419
1420 if ONIXS_CMEMDH_UNLIKELY (size < MessageHeader::Size)
1421 {
1422 throwBinaryBlockIsTooSmall(size, MessageHeader::Size);
1423 }
1424
1425 header_ = fromEmptyStorage<MessageHeader>(data);
1426
1427 this->version(version);
1428 }
1429
1432 SbeMessage(void* data, MessageSize size)
1433 : header_(nullptr)
1434 , size_(size)
1435 {
1436 assert(data);
1437 assert(size <= MaxMessageSize);
1438
1439 if ONIXS_CMEMDH_UNLIKELY (size < MessageHeader::Size)
1440 throwBinaryBlockIsTooSmall(size, MessageHeader::Size);
1441
1442 header_ = fromExistingBytes<MessageHeader>(data);
1443
1444 // Now it is safe to read header_.
1445 if ONIXS_CMEMDH_UNLIKELY (size < (MessageHeader::Size + header_->blockLength()))
1446 {
1447 throwBinaryBlockIsTooSmall(size, MessageHeader::Size + header_->blockLength());
1448 }
1449 }
1450
1455 SbeMessage(void* data, MessageSize size, NoCheck) noexcept
1456 : header_(fromExistingBytes<MessageHeader>(data))
1457 , size_(size)
1458 {
1459 assert(data);
1460 assert(size <= MaxMessageSize);
1461
1462 assert(size >= MessageHeader::Size);
1463 assert(size >= MessageHeader::Size + header_->blockLength());
1464 }
1465
1467 void clear() noexcept
1468 {
1469 *this = SbeMessage();
1470 assert(!valid());
1471 }
1472
1475 bool valid() const noexcept
1476 {
1477 return (nullptr != header_);
1478 }
1479
1483 {
1484 assert(valid());
1485
1486 return header_->templateId();
1487 }
1488
1491 SchemaVersion version() const noexcept
1492 {
1493 assert(valid());
1494
1495 return header_->version();
1496 }
1497
1500 SchemaId schemaId() const noexcept
1501 {
1502 assert(valid());
1503
1504 return header_->schemaId();
1505 }
1506
1509 const void* binary() const noexcept
1510 {
1511 assert(valid());
1512
1513 return header_;
1514 }
1515
1518 void* binary() noexcept
1519 {
1520 assert(valid());
1521
1522 return header_;
1523 }
1524
1525 // \return the end of the memory block.
1527 const void* blockEnd() noexcept
1528 {
1529 assert(valid());
1530
1531 return advanceByBytes(header_, size_);
1532 }
1533
1534 // \return the end of the memory block.
1536 const void* blockEnd() const noexcept
1537 {
1538 assert(valid());
1539
1540 return advanceByBytes(header_, size_);
1541 }
1542
1545 MessageSize bufferSize() const noexcept
1546 {
1547 return size_;
1548 }
1549
1552 void* body() noexcept
1553 {
1554 assert(valid());
1555
1556 return advanceByBytes(header_, MessageHeader::Size);
1557 }
1558
1561 BlockLength blockLength() const noexcept
1562 {
1563 assert(valid());
1564
1565 return header_->blockLength();
1566 }
1567
1570 const void* block() const noexcept
1571 {
1572 assert(valid());
1573
1574 return advanceByBytes(header_, MessageHeader::Size);
1575 }
1576
1579 void* block() noexcept
1580 {
1581 assert(valid());
1582
1583 return advanceByBytes(header_, MessageHeader::Size);
1584 }
1585
1586protected:
1589
1593 {
1594 assert(valid());
1595
1596 header_->setVersion(version);
1597
1598 return *this;
1599 }
1600
1604 {
1605 assert(header_);
1606
1607 void* list = advanceByBytes<void>(body(), blockLength());
1608
1609 const MessageSize listSize = size_ - MessageHeader::Size - header_->blockLength();
1610
1611 return GroupList(list, listSize, header_->version());
1612 }
1613
1616 GroupList groups() const noexcept
1617 {
1618 assert(header_);
1619
1620 const void* list = advanceByBytes(block(), blockLength());
1621
1622 const MessageSize listSize = size_ - MessageHeader::Size - header_->blockLength();
1623
1624 return GroupList(const_cast<void*>(list), listSize, header_->version());
1625 }
1626
1628 template <typename Group>
1629 ONIXS_CMEMDH_HOTPATH void initGroup(Group& group, typename Group::EntrySize entrySize) noexcept
1630 {
1631 assert(group.valid());
1632 group.init(entrySize);
1633 }
1634
1636 template <typename Group>
1637 ONIXS_CMEMDH_HOTPATH void setupGroup(Group& group, typename Group::Size entryCount, const void* messageTail)
1638 {
1639 assert(messageTail);
1640 assert(group.valid());
1641 group.setup(entryCount, messageTail, blockEnd());
1642 }
1643
1645 template <typename Group>
1646 ONIXS_CMEMDH_HOTPATH void constructGroup(Group& group, typename Group::Size entryCount, const void* messageTail)
1647 {
1648 assert(messageTail);
1649 assert(group.valid());
1650 group.construct(entryCount, messageTail, blockEnd());
1651 }
1652
1655
1659 {
1660 assert(header_);
1661
1662 void* list = advanceByBytes<void>(body(), blockLength());
1663
1664 const MessageSize listSize = size_ - MessageHeader::Size - header_->blockLength();
1665
1666 return VariableLengthFieldList(list, listSize, header_->version());
1667 }
1668
1672 {
1673 assert(header_);
1674
1675 const void* list = advanceByBytes(block(), blockLength());
1676
1677 const MessageSize listSize = size_ - MessageHeader::Size - header_->blockLength();
1678
1679 return VariableLengthFieldList(const_cast<void*>(list), listSize, header_->version());
1680 }
1681
1683 void init(
1685 MessageHeader::BlockLength minimalBlockLength,
1687 SchemaId id
1688 ) noexcept
1689 {
1690 assert(header_);
1691 assert(blockLength >= minimalBlockLength);
1692
1693 header_->setTemplateId(value);
1694 header_->setBlockLength(blockLength);
1695 header_->setSchemaId(id);
1696
1697 zeroPaddingBytes(minimalBlockLength);
1698 }
1699
1701 MessageSize calculateBinarySize(const void* tail) const noexcept
1702 {
1703 assert(tail);
1704
1705 const ptrdiff_t distance = byteDistance(tail, binary());
1706
1707 assert(distance > 0);
1708
1709 assert(distance <= (std::numeric_limits<MessageSize>::max)());
1710
1711 const MessageSize size = static_cast<MessageSize>(distance);
1712
1713 assert(size <= size_);
1714
1715 return size;
1716 }
1717
1719 template <class Group, class Callable, class Owner>
1720 void resetGroup(Callable callable, Owner& owner) noexcept
1721 {
1722 const typename Group::EntrySize entrySize = Group::Entry::blockLength(version());
1723
1724 Group grp = callable(owner);
1725
1726 initGroup(grp, entrySize);
1727 }
1728
1730 template <class Callable, class Owner>
1731 void setVariableLengthFieldToNull(Callable callable, SchemaVersion since, Owner& owner) noexcept
1732 {
1733 if ONIXS_CMEMDH_UNLIKELY (since > version())
1734 {
1735 return;
1736 }
1737
1738 setVariableLengthFieldToNull(callable, owner);
1739 }
1740
1742 template <class Group, class Callable, class Owner>
1743 void resetGroup(Callable callable, SchemaVersion since, Owner& owner)
1744 {
1745 if ONIXS_CMEMDH_UNLIKELY (since > version())
1746 {
1747 return;
1748 }
1749
1750 resetGroup<Group>(callable, owner);
1751 }
1752
1754 template <class Group, class Callable, class Owner>
1755 Group getGroup(Callable callable, Owner& owner) const noexcept
1756 {
1757 static_assert(noexcept(callable(owner)), "");
1758 return callable(owner);
1759 }
1760
1762 template <class Group, class Callable, class Owner>
1763 Group getGroup(Callable callable, SchemaVersion since, Owner& owner) const noexcept
1764 {
1765 if ONIXS_CMEMDH_UNLIKELY (since > version())
1766 {
1767 return Group();
1768 }
1769
1770 return getGroup<Group>(callable, owner);
1771 }
1772
1775 template <class Group, class Callable, class Owner>
1776 Group constructGroup(Callable callable, typename Group::Size length, SchemaVersion since, Owner& owner)
1777 {
1778 if ONIXS_CMEMDH_UNLIKELY (since > version())
1779 {
1780 return Group();
1781 }
1782
1783 return constructGroup<Group>(callable, length, owner);
1784 }
1785
1788 template <class Group, class Callable, class Owner>
1789 Group constructGroup(Callable callable, typename Group::Size length, Owner& owner)
1790 {
1791 Group group = callable(owner);
1792
1793 constructGroup(group, length, owner.tail());
1794
1795 return group;
1796 }
1797
1799 template <class Group, class Callable, class Owner>
1800 Group setupGroup(Callable callable, typename Group::Size length, SchemaVersion since, Owner& owner)
1801 {
1802 if ONIXS_CMEMDH_UNLIKELY (since > version())
1803 {
1804 return Group();
1805 }
1806
1807 return setupGroup<Group>(callable, length, owner);
1808 }
1809
1811 template <class Group, class Callable, class Owner>
1812 Group setupGroup(Callable callable, typename Group::Size length, Owner& owner)
1813 {
1814 Group group = callable(owner);
1815
1816 setupGroup(group, length, owner.tail());
1817
1818 return group;
1819 }
1820
1824 static constexpr MessageSize getMaxMessageSize() noexcept
1825 {
1826 return MaxMessageSize;
1827 }
1828
1829private:
1830 MessageHeader* header_;
1831 MessageSize size_;
1832};
1833
1835template <class Message>
1839 const void* data, MessageSize size,
1840 typename std::enable_if<std::is_same<typename std::remove_cv<Message>::type, SbeMessage>::value>::type* = nullptr)
1841{
1842 return SbeMessage(toMutable(data), size);
1843}
1844
1846template <class Message>
1850 const void* data, MessageSize size,
1851 typename std::enable_if<std::is_base_of<SbeMessage, typename std::remove_cv<Message>::type>::value && !std::is_same<typename std::remove_cv<Message>::type, SbeMessage>::value>::type* = nullptr)
1852{
1853 return Message(toMutable(data), size, Messaging::SbeMessage::NoInit{});
1854}
1855
1857template <class Message>
1861 const void* data, MessageSize size, SbeMessage::NoCheck noCheck,
1862 typename std::enable_if<std::is_same<typename std::remove_cv<Message>::type, SbeMessage>::value>::type* = nullptr) noexcept
1863{
1864 return SbeMessage(toMutable(data), size, noCheck);
1865}
1866
1868template <class Message>
1872 const void* data, MessageSize size, SbeMessage::NoCheck noCheck,
1873 typename std::enable_if<std::is_base_of<SbeMessage, typename std::remove_cv<Message>::type>::value && !std::is_same<typename std::remove_cv<Message>::type, SbeMessage>::value>::type* = nullptr) noexcept
1874{
1875 return Message(toMutable(data), size, Messaging::SbeMessage::NoInit{}, noCheck);
1876}
1877
1879
1880#if defined(ONIXS_CMEMDH_CXX20)
1881namespace std { namespace ranges {
1882
1883// Adapter destruction does not invalidate iterators into the message storage.
1884template <class EntryType, class BlockLength, class NumInGroup, class Length>
1885inline constexpr bool enable_borrowed_range<
1886 ONIXS_CMEMDH_MESSAGING_NAMESPACE::SbeGroupRange<EntryType, BlockLength, NumInGroup, Length>> = true;
1887
1888}} // namespace std::ranges
1889#endif
#define ONIXS_CMEMDH_MESSAGING_NAMESPACE_BEGIN
Definition Bootstrap.h:77
#define ONIXS_CMEMDH_MESSAGING_NAMESPACE_END
Definition Bootstrap.h:78
#define ONIXS_CMEMDH_LTWT_EXPORTED
Definition Bootstrap.h:62
#define ONIXS_CMEMDH_FORCEINLINE
Definition Compiler.h:176
#define ONIXS_CMEMDH_NODISCARD
Definition Compiler.h:165
#define ONIXS_CMEMDH_HOTPATH
Definition Compiler.h:167
#define ONIXS_CMEMDH_UNUSED
Definition Compiler.h:177
bool fixedStr(StrRef &value, BlockLength offset) const noexcept
Definition SbeMessage.h:221
Value ordinary(BlockLength offset) const noexcept
Definition SbeMessage.h:91
bool decimal(Decimal &value, BlockLength offset, NullValue null) const noexcept
Definition SbeMessage.h:182
Value ordinary(BlockLength offset, SchemaVersion since) const
Definition SbeMessage.h:105
bool fixedStr(StrRef &value, BlockLength offset, SchemaVersion since) const noexcept
Definition SbeMessage.h:233
bool ordinary(Value &value, BlockLength offset, NullValue null) const noexcept
Definition SbeMessage.h:119
bool decimal(Value &value, BlockLength offset, NullValue null, SchemaVersion since) const noexcept
Definition SbeMessage.h:197
Enumeration::Enum enumeration(BlockLength offset) const noexcept
Definition SbeMessage.h:140
bool enumeration(typename Enumeration::Enum &value, BlockLength offset, NullValue null) const noexcept
Provides access to an optional field value.
Definition SbeMessage.h:151
BinaryBlock()=default
Initializes a blank instance.
bool ordinary(Value &value, BlockLength offset, NullValue null, SchemaVersion since) const noexcept
Definition SbeMessage.h:132
StrRef fixedStr(BlockLength offset) const noexcept
Provides access to a string field value.
Definition SbeMessage.h:205
Decimal decimal(BlockLength offset) const
Definition SbeMessage.h:171
bool enumeration(typename Enumeration::Enum &value, BlockLength offset, NullValue null, SchemaVersion since) const noexcept
Provides access to an optional field value.
Definition SbeMessage.h:163
NumInGroup numInGroup() const noexcept
Definition Composites.h:184
BlockLength blockLength() const noexcept
Definition Composites.h:171
Template ID and length of message root.
Definition Composites.h:308
UInt16 BlockLength
Type alias for the BlockLength.
Definition Composites.h:314
UInt16 TemplateId
Type alias for the TemplateId.
Definition Composites.h:317
SbeFields()=default
Initializes a blank instance.
Container & container() noexcept
Definition SbeMessage.h:249
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...
Definition SbeMessage.h:256
void setFixedStr(BlockLength offset, StrRef value) noexcept
Sets the field value.
Definition SbeMessage.h:314
void setOrdinary(BlockLength offset, FieldValue value, SchemaVersion since)
Sets the field value.
Definition SbeMessage.h:283
void setEnumeration(BlockLength offset, typename Enumeration::Enum value, SchemaVersion since)
Sets the field value.
Definition SbeMessage.h:305
void setEnumeration(BlockLength offset, typename Enumeration::Enum value) noexcept
Sets the field value.
Definition SbeMessage.h:296
void setOrdinary(BlockLength offset, FieldValue value) noexcept
Sets the field value.
Definition SbeMessage.h:269
void setFixedStr(BlockLength offset, StrRef value, SchemaVersion since)
Sets the field value.
Definition SbeMessage.h:333
An iterator over SBE-encoded group entries.
Definition SbeMessage.h:459
Iterator operator+(difference_type distance) const
Advances by given number of entries.
Definition SbeMessage.h:556
bool operator==(const Iterator &other) const noexcept
Compares iterators.
Definition SbeMessage.h:511
std::random_access_iterator_tag iterator_category
Definition SbeMessage.h:469
Iterator operator-(difference_type distance) const
Advances back by given number of entries.
Definition SbeMessage.h:565
Iterator() noexcept
Initializes the instance that refers to nothing.
Definition SbeMessage.h:472
bool operator<(const Iterator &other) const noexcept
Established the order between two iterators.
Definition SbeMessage.h:523
bool operator!=(const Iterator &other) const noexcept
Compares iterators.
Definition SbeMessage.h:517
Iterator & operator++()
Advances the next repeating group entry.
Definition SbeMessage.h:535
bool operator>(const Iterator &other) const noexcept
Established the order between two iterators.
Definition SbeMessage.h:529
Iterator & operator--()
Advances to the previous repeating group entry.
Definition SbeMessage.h:545
Iterator(void *entry, EncodedLength size, SchemaVersion version) noexcept
Initializes the instance to the given repeating group.
Definition SbeMessage.h:481
Operations over SBE-encoded repeating group entries.
Definition SbeMessage.h:446
SbeGroupEntries() noexcept
Initializes a blank instance referencing to nothing.
Definition SbeMessage.h:584
SbeGroupEntries(void *encoded, BlockLength blockLength, Size groupSize, SchemaVersion version) noexcept
Initializes the instance referencing to data.
Definition SbeMessage.h:593
Range asRange() const noexcept
Adapts valid entries for standard input algorithms and C++20 forward-range algorithms.
Definition SbeMessage.h:640
EntryType Entry
The type of the repeating group entry.
Definition SbeMessage.h:452
Iterator end() const
Returns the iterator pointing to the entry behind the end of the group.
Definition SbeMessage.h:629
SbeGroupEntries(const SbeGroupEntries< OtherEntry, OtherBlockLength, OtherNumInGroup, OtherLength > &other) noexcept
Copy constructor.
Definition SbeMessage.h:671
Length EncodedLength
The length of the binary data occupied by the group entries.
Definition SbeMessage.h:449
NumInGroup Size
Number of entries in the collection.
Definition SbeMessage.h:455
SbeGroupEntries & operator=(const SbeGroupEntries< OtherEntry, OtherBlockLength, OtherNumInGroup, OtherLength > &other) noexcept
Definition SbeMessage.h:685
SbeGroupRange< EntryType, BlockLength, NumInGroup, Length > Range
Standard-algorithm adapter borrowing this collection's entry storage.
Definition SbeMessage.h:580
SbeGroupEntry()
Initializes a blank instance.
Definition SbeMessage.h:359
const void * block() const noexcept
Definition SbeMessage.h:403
SbeGroupEntry(void *encoded, BlockLength size, SchemaVersion version)
Initializes the instance from the memory block of the encoded message.
Definition SbeMessage.h:368
BlockLength blockLength() const noexcept
Definition SbeMessage.h:421
BodySizeType BlockLength
Type to present the length of binary data of the repeating group entry.
Definition SbeMessage.h:356
SbeVariableLengthFieldList< BinarySize > checkVariableLengthFields() const
SbeGroupList tail() const noexcept
SbeVariableLengthFieldList< BinarySize > variableLengthFields() const noexcept
SbeGroupList(void *binary, BinarySize size, SchemaVersion version) noexcept
Initializes the list over the memory block.
Holds an entry view for pointer-like access without owning its message bytes.
Definition SbeMessage.h:742
const EntryType * operator->() const noexcept
Provides read-only access to the captured entry view.
Definition SbeMessage.h:761
EntryType * operator->() noexcept
Provides mutable access to the captured entry view.
Definition SbeMessage.h:754
Pointer(EntryType entry)
Captures a view of the current entry.
Definition SbeMessage.h:746
Iterator returning an entry view by value.
Definition SbeMessage.h:735
Iterator() noexcept=default
Initializes a singular iterator that compares equal to another singular iterator.
std::forward_iterator_tag iterator_concept
C++20 algorithms may traverse independent iterator copies repeatedly.
Definition SbeMessage.h:779
bool operator==(const Iterator &other) const noexcept
Compares positions within the same repeating group.
Definition SbeMessage.h:825
std::input_iterator_tag iterator_category
Legacy algorithms use input traversal for entry views returned by value.
Definition SbeMessage.h:777
Pointer pointer
Proxy retaining the temporary entry view used by arrow expressions.
Definition SbeMessage.h:771
EntryType reference
Dereferencing produces a temporary view of the message bytes.
Definition SbeMessage.h:773
EntryType value_type
Entry view returned by dereferencing.
Definition SbeMessage.h:738
EntryType operator*() const
Reads an entry view without transferring ownership of its bytes.
Definition SbeMessage.h:793
Iterator operator++(int)
Advances while retaining the previous position.
Definition SbeMessage.h:815
bool operator!=(const Iterator &other) const noexcept
Compares positions within the same repeating group.
Definition SbeMessage.h:833
ptrdiff_t difference_type
Signed distance between iterator positions.
Definition SbeMessage.h:775
Iterator & operator++()
Advances to the next entry.
Definition SbeMessage.h:807
pointer operator->() const
Provides pointer-like access to the current entry view.
Definition SbeMessage.h:800
Standard-algorithm range over borrowed repeating group entries.
Definition SbeMessage.h:728
bool empty() const noexcept
Checks whether the range contains entries.
Definition SbeMessage.h:873
std::size_t size() const noexcept
Returns the number of entries captured when the adapter was created.
Definition SbeMessage.h:866
Iterator end() const noexcept
Returns the position following the last borrowed entry.
Definition SbeMessage.h:859
Iterator begin() const noexcept
Returns the first borrowed entry position.
Definition SbeMessage.h:852
SbeGroupRange() noexcept
Initializes an empty range that refers to no message storage.
Definition SbeMessage.h:843
const void * tail() const noexcept
SbeGroup() noexcept
Initializes a blank instance referencing to nothing.
Definition SbeMessage.h:934
Entries::Size Size
Number of entries in the group.
Definition SbeMessage.h:931
GroupSizeType BinarySize
Length of group data.
Definition SbeMessage.h:904
Entries::Range Range
Standard-algorithm adapter borrowing this group's entry storage.
Definition SbeMessage.h:924
DimensionType::BlockLength EntrySize
Length of group entry data.
Definition SbeMessage.h:913
SbeGroup(void *data, BinarySize size, SchemaVersion version) noexcept
Initializes an instance referencing to a valid group of a given message.
Definition SbeMessage.h:943
Range asRange() const noexcept
Adapts a valid group for standard input algorithms and C++20 forward-range algorithms.
Entries::Iterator Iterator
The iterator type for group entries.
Definition SbeMessage.h:920
Entries::Entry Entry
Group entry type.
Definition SbeMessage.h:928
Entries entries() const noexcept
Entry operator[](Size index) const
Iterator end() const noexcept
Definition SbeMessage.h:992
const void * encoded() const noexcept
SbeGroupEntries< EntryType, typename Dimension::BlockLength, typename Dimension::NumInGroup, GroupSizeType > Entries
Binary group blocks.
Definition SbeMessage.h:917
DimensionType Dimension
Repeating group dimension type.
Definition SbeMessage.h:901
Iterator begin() const noexcept
Definition SbeMessage.h:983
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.
GroupList groups() const noexcept
Group setupGroup(Callable callable, typename Group::Size length, Owner &owner)
Setups the repeating group with the given number of entries.
const void * blockEnd() const noexcept
SbeMessage(void *data, MessageSize size)
Initializes the instance over the given memory block.
SbeVariableLengthFieldList< MessageSize > VariableLengthFieldList
Binary group list instantiation.
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
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
static constexpr MessageSize getMaxMessageSize() noexcept
Maximal message size.
Group constructGroup(Callable callable, typename Group::Size length, Owner &owner)
Group constructGroup(Callable callable, typename Group::Size length, SchemaVersion since, Owner &owner)
void setVariableLengthFieldToNull(Callable callable, SchemaVersion since, Owner &owner) noexcept
Sets the variable length field to null.
BlockLength blockLength() const noexcept
void resetGroup(Callable callable, SchemaVersion since, Owner &owner)
Resets the repeating group.
SbeMessage() noexcept
Initializes a blank instance.
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.
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.
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
void checkSchemaId(SchemaId id)
Checks the compatibility with the provided SBE Schema ID.
constexpr MessageSize MaxMessageSize
Maximum supported message size.
const SbeMessage constructFromImmutableBlock(const void *data, MessageSize size, typename std::enable_if< std::is_same< typename std::remove_cv< Message >::type, SbeMessage >::value >::type *=nullptr)
Constructs the given message from an immutable memory block.
MessageHeader::Version SchemaVersion
Aliases SBE-encoded data version type.
char Char
Character type alias.
Definition String.h:30
UInt16 MessageSize
Message length type.
Definition Aliases.h:29
std::basic_string_view< Char > StrRef
Definition StrRef.h:46
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.
FloatingPointDecimal< DecimalMantissa, DecimalExponent > Decimal
Universal decimal type.
MessageHeader::TemplateId MessageTemplateId
Message type (template) identification.
STL namespace.