OnixS C++ B3 Binary UMDF Market Data Handler  1.4.2
API documentation
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 
31 
32 #include <cassert>
33 #include <limits>
34 #include <stdexcept>
35 
37 
38 /// Message type (template) identification.
39 typedef
40 MessageHeader::TemplateId MessageTemplateId;
41 
42 /// \private
43 template<typename Message> inline
44 void checkBinaryLength(const Message&, MessageSize length, MessageSize minimalRequiredLength)
45 {
46  if ONIXS_B3_UMDF_MD_UNLIKELY(length < minimalRequiredLength)
47  throwBinaryBlockIsTooSmall(length, minimalRequiredLength, Message::className());
48 }
49 
50 /// \private
51 ONIXS_B3_UMDF_MD_LTWT_CLASS BinaryBlockBase
52 {
53 protected:
54  ~BinaryBlockBase() ONIXS_B3_UMDF_MD_DEFAULT;
55 };
56 
57 /// Services to access fields stored
58 /// in an SBE-encoded block of fixed-length fields.
59 ///
60 /// The given class represents an abstraction to be used
61 /// by descendants as a base class with static polymorphism.
62 template < class Container, class BlockLength >
63 ONIXS_B3_UMDF_MD_LTWT_CLASS BinaryBlock : public BinaryBlockBase
64 {
65  /// \return The block container that provides access to the encoded data.
66  const Container& container() const ONIXS_B3_UMDF_MD_NOTHROW
67  {
68  return *static_cast <const Container*> (this);
69  }
70 
71 protected:
72  /// Initializes a blank instance.
74 
76 
77  /// \return the field value.
78  template < class Value > ONIXS_B3_UMDF_MD_HOTPATH
79  Value ordinary(BlockLength offset) const ONIXS_B3_UMDF_MD_NOTHROW
80  {
81  assert(container().blockLength() >= (offset + size<Value>()) &&
82  "The requested field exceeds provided block boundaries.");
83 
84  const void* const location = advanceByBytes(container().block(), offset);
85  return getValue<Value>(location);
86  }
87 
88  /// Provides access to an optional field value.
89  ///
90  /// \return `true` if the field is present in the field block and its value was copied,
91  /// otherwise - `false`.
92  template <class Value, class NullValue > ONIXS_B3_UMDF_MD_HOTPATH
93  bool ordinary(Value& value, BlockLength offset, NullValue null) const ONIXS_B3_UMDF_MD_NOTHROW
94  {
95  value = ordinary<Value>(offset);
96 
97  return (null != value);
98  }
99 
100  /// Provides access to an optional field value.
101  ///
102  /// \return `true` if the field is present in the field block and its value was copied,
103  /// otherwise - `false`.
104  template < class Value, class NullValue > ONIXS_B3_UMDF_MD_HOTPATH
105  bool ordinary(Value& value, BlockLength offset, NullValue null, SchemaVersion since) const ONIXS_B3_UMDF_MD_NOTHROW
106  {
107  return (since <= container().version() && ordinary (value, offset, null ) );
108  }
109 
110  /// \return the field value.
111  template < class Enumeration > ONIXS_B3_UMDF_MD_HOTPATH
112  typename Enumeration::Enum enumeration(BlockLength offset) const ONIXS_B3_UMDF_MD_NOTHROW
113  {
114  typedef typename Enumeration::Base Base;
115  typedef typename Enumeration::Enum Enum;
116 
117  return static_cast<Enum>(ordinary<Base>(offset));
118  }
119 
120  /// Provides access to an optional field value.
121  template < class Enumeration, class NullValue > ONIXS_B3_UMDF_MD_HOTPATH
122  bool enumeration(typename Enumeration::Enum& value, BlockLength offset, NullValue null) const ONIXS_B3_UMDF_MD_NOTHROW
123  {
124  typedef typename Enumeration::Base Base;
125  typedef typename Enumeration::Enum Enum;
126 
127  value = static_cast <Enum>(ordinary<Base>(offset));
128  return null != value;
129  }
130 
131  /// Provides access to an optional field value.
132  template < class Enumeration, class NullValue > ONIXS_B3_UMDF_MD_HOTPATH
133  bool enumeration(typename Enumeration::Enum& value, BlockLength offset, NullValue null, SchemaVersion since) const ONIXS_B3_UMDF_MD_NOTHROW
134  {
135  return (since <= container().version() && enumeration<Enumeration>(value, offset, null) );
136  }
137 
138  /// \return a Decimal field value.
139  template < class Value > ONIXS_B3_UMDF_MD_HOTPATH
140  Value decimal(BlockLength offset) const ONIXS_B3_UMDF_MD_NOTHROW
141  {
142  return ordinary<Value>(offset);
143  }
144 
145  /// \return an optional Decimal field value.
146  ///
147  /// \return `true` if the field is present in the field block and its value was copied,
148  /// otherwise - `false`.
149  template < class Value, class NullValue > ONIXS_B3_UMDF_MD_HOTPATH
150  bool decimal(Value& value, BlockLength offset, NullValue null) const ONIXS_B3_UMDF_MD_NOTHROW
151  {
152  value = ordinary<Value>(offset);
153  return null != value;
154  }
155 
156  /// \return an optional Decimal field value.
157  ///
158  /// \return `true` if the field is present in the field block and its value was copied,
159  /// otherwise - `false`.
160  template < class Value, class NullValue > ONIXS_B3_UMDF_MD_HOTPATH
161  bool decimal(Value& value, BlockLength offset, NullValue null, SchemaVersion since) const ONIXS_B3_UMDF_MD_NOTHROW
162  {
163  return (since <= container().version() && decimal(value, offset, null));
164  }
165 
166  /// Provides access to a string field value.
167  template < BlockLength Length > ONIXS_B3_UMDF_MD_HOTPATH
168  StrRef fixedStr(BlockLength offset) const ONIXS_B3_UMDF_MD_NOTHROW
169  {
170  assert(container().blockLength() >= (offset + Length) && "The requested field exceeds provided block boundaries.");
171 
172  const Char* const text = reinterpret_cast <const Char*> (advanceByBytes(container().block(), offset));
173 
174  return StrRef(text, strnlen(text, Length));
175  }
176 
177  /// Provides access to an optional string field value.
178  ///
179  /// \return `true` if the field is present in the field block and its value was copied,
180  /// otherwise - `false`.
181  template<BlockLength Length> ONIXS_B3_UMDF_MD_HOTPATH
182  bool fixedStr(StrRef& value, BlockLength offset) const ONIXS_B3_UMDF_MD_NOTHROW
183  {
184  value = fixedStr<Length>(offset);
185  return !value.empty();
186  }
187 
188  /// Provides access to an optional string field value.
189  ///
190  /// \return `true` if the field is present in the field block and its value was copied,
191  /// otherwise - `false`.
192  template<BlockLength Length> ONIXS_B3_UMDF_MD_HOTPATH
193  bool fixedStr(StrRef& value, BlockLength offset, SchemaVersion since) const ONIXS_B3_UMDF_MD_NOTHROW
194  {
195  return (since <= container().version() && fixedStr<Length>(value, offset));
196  }
197 };
198 
199 /// Base services to access fields stored in an SBE-encoded block of memory.
200 ///
201 /// This class represents an abstraction to be used
202 /// by descendants as a base class with static polymorphism.
203 template <class Container, class BlockLength >
205 {
206 public:
207  /// \return The block container that provides access to the encoded data.
209  {
210  return *static_cast<Container*>(this);
211  }
212 
213  /// If specified, the extra space is padded at the end of each entry and should be set to zeroes by encoders.
214  ONIXS_B3_UMDF_MD_HOTPATH
216  {
217  const BlockLength encodedBlockLength = container().blockLength();
218 
219  assert(encodedBlockLength >= offset);
220 
221  const size_t paddingLength = encodedBlockLength - offset;
222  std::memset(advanceByBytes(container().block(), offset), 0, paddingLength);
223  }
224 
225  /// Sets the field value.
226  template<class FieldValue> ONIXS_B3_UMDF_MD_HOTPATH
227  void setOrdinary(BlockLength offset, FieldValue value) ONIXS_B3_UMDF_MD_NOTHROW
228  {
229  assert(container().blockLength() >= (offset + size<FieldValue>()) && "The requested field exceeds provided block boundaries.");
230 
231  void* const fieldPos = advanceByBytes(container().block(), offset);
232  setValue(fieldPos, value);
233  }
234 
235  /// Sets the field value.
236  template<class FieldValue> ONIXS_B3_UMDF_MD_HOTPATH
237  void setOrdinary(BlockLength offset, FieldValue value, SchemaVersion since)
238  {
239  if ONIXS_B3_UMDF_MD_UNLIKELY(since > container().version())
240  throwDisallowedField();
241 
242  setOrdinary(offset, value);
243  }
244 
245  /// Sets the field value.
246  template<class Enumeration> ONIXS_B3_UMDF_MD_HOTPATH
247  void setEnumeration(BlockLength offset, typename Enumeration::Enum value) ONIXS_B3_UMDF_MD_NOTHROW
248  {
249  typedef typename Enumeration::Base Base;
250  setOrdinary<Base>(offset, static_cast<Base>(value));
251  }
252 
253  /// Sets the field value.
254  template<class Enumeration> ONIXS_B3_UMDF_MD_HOTPATH
255  void setEnumeration(BlockLength offset, typename Enumeration::Enum value, SchemaVersion since)
256  {
257  typedef typename Enumeration::Base Base;
258  setOrdinary(offset, static_cast<Base>(value), since);
259  }
260 
261  /// Sets the field value.
262  template<BlockLength Size> ONIXS_B3_UMDF_MD_HOTPATH
263  void setFixedStr(BlockLength offset, StrRef value) ONIXS_B3_UMDF_MD_NOTHROW
264  {
265  assert(container().blockLength() >= (offset + Size) && "The requested field exceeds provided block boundaries.");
266  assert(value.size() <= Size && "The string is truncated.");
267 
268  void* const fieldPos = advanceByBytes(container().block(), offset);
269  const size_t sizeToCopy = (std::min)(Size, static_cast<BlockLength>(value.size()));
270 
271  if(sizeToCopy > 0)
272  std::memcpy(fieldPos, value.data(), sizeToCopy);
273 
274  std::memset(advanceByBytes(fieldPos, sizeToCopy), 0, Size - sizeToCopy);
275  }
276 
277  /// Sets the field value.
278  template<BlockLength Size> ONIXS_B3_UMDF_MD_HOTPATH
279  void setFixedStr(BlockLength offset, StrRef value, SchemaVersion since)
280  {
281  if ONIXS_B3_UMDF_MD_UNLIKELY(since > container().version())
282  throwDisallowedField();
283 
284  setFixedStr<Size>(offset, value);
285  }
286 
287 protected:
288  /// Initializes a blank instance.
290 
292 };
293 
294 /// Operations over a repeating group instance.
295 template <class BodySizeType>
297 {
298 public:
299  /// Type to present the length of binary data of the repeating group entry.
300  typedef BodySizeType BlockLength;
301 
302  /// Initializes a blank instance.
304  : encoded_(ONIXS_B3_UMDF_MD_NULLPTR)
305  , size_(0)
306  , version_(0)
307  {
308  }
309 
310  /// Initializes the instance from the memory block of the encoded message.
311  ONIXS_B3_UMDF_MD_HOTPATH
312  SbeGroupEntry(const void* encoded, BlockLength size, SchemaVersion version)
313  : encoded_(encoded)
314  , size_(size)
315  , version_(version)
316  {
317  assert(encoded);
318  }
319 
320  /// \return `true` if the instance refers to a valid content, otherwise - `false`.
322  {
323  return (encoded_ != ONIXS_B3_UMDF_MD_NULLPTR);
324  }
325 
326  /// \return the beginning of the group entry body.
327  const void* encoded() const ONIXS_B3_UMDF_MD_NOTHROW
328  {
329  assert(valid());
330 
331  return encoded_;
332  }
333 
334  ///// \return the beginning of the group entry body.
335  //void* encoded() ONIXS_B3_UMDF_MD_NOTHROW
336  //{
337  // assert(valid());
338 
339  // return encoded_;
340  //}
341 
342  /// \return the pointer to the block containing fixed-length fields.
343  const void* block() const ONIXS_B3_UMDF_MD_NOTHROW
344  {
345  assert(valid());
346 
347  return encoded_;
348  }
349 
350  ///// \return the pointer to the block containing fixed-length fields.
351  //void* block() ONIXS_B3_UMDF_MD_NOTHROW
352  //{
353  // assert(valid());
354 
355  // return encoded_;
356  //}
357 
358  /// \return Block length.
360  {
361  return size_;
362  }
363 
364  /// \return SBE Schema version.
366  {
367  return version_;
368  }
369 
370  private:
371  const void* encoded_;
372  BodySizeType size_;
373  SchemaVersion version_;
374 };
375 
376 /// Operations over SBE-encoded repeating group entries.
377 template <class EntryType, class BlockLength, class NumInGroup, class Length >
379 {
380 public:
381  /// The length of the binary data occupied by the group entries.
382  typedef Length EncodedLength;
383 
384  /// The type of the repeating group entry.
385  typedef EntryType Entry;
386 
387  /// Number of entries in the collection.
388  typedef NumInGroup Size;
389 
390  /// An iterator over SBE-encoded group entries.
392  {
393  public:
394  typedef EntryType Entry;
395  typedef Entry value_type;
396 
397  typedef Entry* pointer;
398  typedef Entry& reference;
399 
400  typedef ptrdiff_t difference_type;
401 
402  typedef std::random_access_iterator_tag iterator_category;
403 
404  /// Initializes the instance that refers to nothing.
406  : entry_(ONIXS_B3_UMDF_MD_NULLPTR)
407  , size_(0)
408  , version_(0)
409  {
410  }
411 
412  /// Initializes the instance to the given repeating group.
413  ONIXS_B3_UMDF_MD_HOTPATH
414  Iterator(void* entry, Size size, SchemaVersion version) ONIXS_B3_UMDF_MD_NOTHROW
415  : entry_(entry)
416  , size_(size)
417  , version_(version)
418  {
419  assert(valid());
420  }
421 
422  /// \return `true` if the instance is valid, otherwise - `false`.
424  {
425  return (entry_ != ONIXS_B3_UMDF_MD_NULLPTR);
426  }
427 
428  /// \return the repeating group entry.
429  ONIXS_B3_UMDF_MD_HOTPATH
430  Entry get() const
431  {
432  assert(valid());
433 
434  return Entry(entry_, size_, version_);
435  }
436 
437  /// \return the repeating group entry.
438  Entry operator *() const
439  {
440  return get();
441  }
442 
443  /// Compares iterators.
445  {
446  return entry_ == other.entry_;
447  }
448 
449  /// Compares iterators.
451  {
452  return entry_ != other.entry_;
453  }
454 
455  /// Established the order between two iterators.
457  {
458  return entry_ < other.entry_;
459  }
460 
461  /// Established the order between two iterators.
463  {
464  return entry_ > other.entry_;
465  }
466 
467  /// Advances the next repeating group entry.
468  Iterator& operator ++()
469  {
470  assert(valid());
471 
472  entry_ = advanceByBytes(entry_, size_);
473 
474  return *this;
475  }
476 
477  /// Advances to the previous repeating group entry.
478  Iterator& operator --()
479  {
480  assert(valid());
481 
482  entry_ = advanceBackByBytes(entry_, size_);
483 
484  return *this;
485  }
486 
487  /// Advances by given number of entries.
488  ONIXS_B3_UMDF_MD_HOTPATH
489  Iterator operator +(difference_type distance) const
490  {
491  assert(valid());
492 
493  return Iterator(advanceByBytes(entry_, distance * size_), size_, version_);
494  }
495 
496  /// Advances back by given number of entries.
497  ONIXS_B3_UMDF_MD_HOTPATH
498  Iterator operator - (difference_type distance) const
499  {
500  assert(valid());
501 
502  return Iterator(advanceBackByBytes(entry_, distance * size_), size_, version_);
503  }
504 
505  private:
506  void* entry_;
507  Size size_;
508  SchemaVersion version_;
509  };
510 
511  /// Initializes a blank instance referencing to nothing.
513  : encoded_(ONIXS_B3_UMDF_MD_NULLPTR)
514  , blockLength_(0)
515  , size_(0)
516  , version_(0)
517  {
518  }
519 
520  /// Initializes the instance referencing to data.
521  SbeGroupEntries(void* encoded, BlockLength blockLength, Size groupSize, SchemaVersion version) ONIXS_B3_UMDF_MD_NOTHROW
522  : encoded_(encoded)
523  , blockLength_(blockLength)
524  , size_(groupSize)
525  , version_(version)
526  {
527  assert(encoded_);
528  assert(blockLength > 0);
529  assert(version != 0);
530  }
531 
532  /// \return `true` if the instance refers to a valid repeating group, otherwise - `false`.
534  {
535  return (ONIXS_B3_UMDF_MD_NULLPTR != encoded_);
536  }
537 
538  /// \return `true` if the referenced repeating group is empty, otherwise - `false`.
540  {
541  return (0 == size_);
542  }
543 
544  /// \return number of blocks.
546  {
547  return size_;
548  }
549 
550  /// \return the iterator pointing to the first repeating group entry.
551  Iterator begin() const
552  {
553  return Iterator(encoded(), blockLength_, version_);
554  }
555 
556  /// Returns the iterator pointing to the entry behind the end of the group.
557  Iterator end() const
558  {
559  return Iterator(advanceByBytes(encoded(), encodedLength()), blockLength_, version_);
560  }
561 
562  /// Provides access to the group entry by its index in the repeating group.
563  ///
564  /// \note Index validness is not checked due to performance considerations.
565  Entry operator [](Size index) const
566  {
567  assert(index < size_);
568  assert(encoded_);
569 
570  return Entry(advanceByBytes(encoded_, static_cast<ptrdiff_t>(index) * blockLength_), blockLength_, version_);
571  }
572 
573  /// \return Binary data occupied by the group entries.
575  {
576  return encoded_;
577  }
578 
579  /// \return the length of the binary data occupied by the group entries.
581  {
582  return (static_cast<EncodedLength>(blockLength_) * static_cast<EncodedLength>(size_) );
583  }
584 
585  /// Copy constructor.
586  template<class OtherEntry, class OtherBlockLength, class OtherNumInGroup, class OtherLength >
588  : encoded_(other.encoded_)
589  , blockLength_(other.blockLength_)
590  , size_(other.size_)
591  , version_(other.version_)
592  {
593  // Dimension types may vary for the different instantiations of the template.
594  // Therefore, truncation of the dimensions must be avoided.
595 
596  assert(blockLength_ == other.blockLength_);
597  assert(size_ == other.size_);
598  }
599 
600  template <class OtherEntry, class OtherBlockLength, class OtherNumInGroup, class OtherLength>
602  {
603  encoded_ = other.encoded_;
604 
605  blockLength_ = other.blockLength_;
606 
607  assert(blockLength_ == other.blockLength_);
608 
609  size_ = other.size_;
610 
611  assert(size_ == other.size_);
612 
613  version_ = other.version_;
614 
615  return *this;
616  }
617 
618 private:
619  // Allows coping and cloning for different instantiations.
620  template <class OtherEntry, class OtherBlockLength, class OtherNumInGroup, class OtherLength> friend class SbeGroupEntries;
621 
622  void* encoded_;
623  BlockLength blockLength_;
624  NumInGroup size_;
625  SchemaVersion version_;
626 };
627 
628 /// SBE-encoded repeating group.
629 template < class EntryType, class DimensionType, class GroupSizeType >
631 {
632 public:
633  /// Repeating group dimension type.
634  typedef DimensionType Dimension;
635 
636  /// Length of group data.
637  typedef GroupSizeType BinarySize;
638 
639  /// Length of an empty group.
640  enum { EmptySize = Dimension::Size };
641 
642  /// Length of group entry data.
643  typedef typename DimensionType::BlockLength EntrySize;
644 
645  /// Binary group blocks.
647 
648  /// The iterator type for group entries.
649  typedef typename Entries::Iterator Iterator;
650 
651  /// Group entry type.
652  typedef typename Entries::Entry Entry;
653 
654  /// Number of entries in the group.
655  typedef typename Entries::Size Size;
656 
657  /// Initializes a blank instance referencing to nothing.
660  : header_(ONIXS_B3_UMDF_MD_NULLPTR)
661  , entries_(ONIXS_B3_UMDF_MD_NULLPTR)
662  , version_(0)
663  {
664  }
665 
666  /// Initializes an instance referencing to a valid group of a given message.
667  ONIXS_B3_UMDF_MD_HOTPATH
668  SbeGroup(void* data, ONIXS_B3_UMDF_MD_UNUSED BinarySize size, SchemaVersion version) ONIXS_B3_UMDF_MD_NOTHROW
669  : header_(static_cast <Dimension*>(data))
670  , entries_(advanceByBytes(data, Dimension::Size))
671  , version_(version)
672  {
673  ONIXS_B3_UMDF_MD_ASSERT(size >= Dimension::Size);
674  assert(header_);
675  assert(entries_);
676 
677  assert(valid());
678  }
679 
680  /// \return `true` if the instance refers to a valid repeating group, otherwise - `false`.
682  {
683  return (entries_ != ONIXS_B3_UMDF_MD_NULLPTR);
684  }
685 
686  /// \return `true` if the repeating group is empty, otherwise - `false`.
688  {
689  assert(valid());
690 
691  return 0 == size();
692  }
693 
694  /// \return the number of entries in the repeating group.
695  ONIXS_B3_UMDF_MD_HOTPATH
697  {
698  assert(valid());
699  assert(header_);
700 
701  const Dimension* const group = static_cast<const Dimension*>(header_);
702 
703  return group->numInGroup();
704  }
705 
706  /// \return an iterator pointing to the first repeating group entry.
707  ONIXS_B3_UMDF_MD_HOTPATH
709  {
710  assert(valid());
711 
712  return Iterator(entries_, numericCast<Size>(entrySize()), version_);
713  }
714 
715  /// \return an iterator pointing to the entry behind the end of the group.
716  ONIXS_B3_UMDF_MD_HOTPATH
717  Iterator end() const ONIXS_B3_UMDF_MD_NOTHROW
718  {
719  assert(valid());
720 
721  return Iterator(advanceByBytes(binary(), binarySize()), numericCast<Size>(entrySize()), version_);
722  }
723 
724  /// Provides access to a repeating group entry by the given index.
725  ///
726  /// \note Index validness is not checked due to performance considerations.
727  ONIXS_B3_UMDF_MD_HOTPATH
728  Entry operator [](Size index) const
729  {
730  assert(valid());
731  assert(index < size());
732 
733  return Entry(advanceByBytes(entries_, static_cast<ptrdiff_t>(index) * entrySize()), entrySize(), version_);
734  }
735 
736  /// \return Repeating group entries.
737  ONIXS_B3_UMDF_MD_NODISCARD
739  {
740  assert(valid());
741  assert(header_);
742 
743  return Entries (entries_, header_->blockLength(), header_->numInGroup(), version_);
744  }
745 
746  /// \return SBE-encoded data that represents the repeating group.
747  const void* encoded() const ONIXS_B3_UMDF_MD_NOTHROW
748  {
749  return header_;
750  }
751 
752  /// \return the end of SBE-encoded data that represents the repeating group.
753  const void* tail() const ONIXS_B3_UMDF_MD_NOTHROW
754  {
755  return advanceByBytes(toByteBlock(encoded()), binarySize());
756  }
757 
758  /// \return SBE-encoded data that represents the repeating group.
759  ONIXS_B3_UMDF_MD_HOTPATH
761  {
762  return header_;
763  }
764 
765  /// \return the size of SBE-encoded data that represents the repeating group.
766  ONIXS_B3_UMDF_MD_HOTPATH
768  {
769  return Dimension::Size + (static_cast<BinarySize>(entrySize()) * static_cast<BinarySize>(size()));
770  }
771 
772  /// \return the size of a single repeating group entry.
773  ONIXS_B3_UMDF_MD_HOTPATH
775  {
776  assert(valid());
777  assert(header_);
778 
779  Dimension* const group = static_cast<Dimension*>(header_);
780  return group->blockLength();
781  }
782 
783 private:
784  /// Resets the group to the initial state, must be invoked only during the message construction.
785  void init(EntrySize entrySize) ONIXS_B3_UMDF_MD_NOTHROW
786  {
787  assert(valid());
788  assert(header_);
789 
790  Dimension* const group = static_cast<Dimension*>(header_);
791  group->setBlockLength(entrySize);
792  group->setNumInGroup(0);
793  }
794 
795  /// Allocates a group.
796  Size allocate(Size entryCount, const void* messageTail, const void* blockEnd)
797  {
798  assert(valid());
799  assert(blockEnd);
800  assert(messageTail);
801 
802  Dimension* const group = static_cast<Dimension*>(header_);
803 
804  const EntrySize entrySize = group->blockLength();
805 
806  if ONIXS_B3_UMDF_MD_UNLIKELY(
807  entrySize < EntryType::blockLength(version_))
808  {
809  throwBadBinaryBlock();
810  }
811 
812  const Size oldEntryCount = group->numInGroup();
813 
814  if(oldEntryCount == entryCount)
815  return entryCount;
816 
817  const ptrdiff_t memShift =
818  (entryCount - oldEntryCount) * static_cast<ptrdiff_t>(entrySize);
819 
820  const void* const newMessageTail =
821  advanceByBytes(messageTail, memShift);
822 
823  if ONIXS_B3_UMDF_MD_UNLIKELY(byteDistance(blockEnd, newMessageTail) < 0)
824  throwNotEnoughSpace();
825 
826  const void* const oldEndOfGroup =
827  advanceByBytes(entries_, static_cast<ptrdiff_t>(entrySize) * oldEntryCount);
828 
829  void* const newEndGroup =
830  advanceByBytes(entries_, static_cast<ptrdiff_t>(entrySize) * entryCount);
831 
832  std::memmove(
833  newEndGroup,
834  oldEndOfGroup,
835  byteDistance(messageTail, oldEndOfGroup));
836 
837  group->setNumInGroup(entryCount);
838 
839  return oldEntryCount;
840  }
841 
842  /// Sets up the group.
843  ONIXS_B3_UMDF_MD_HOTPATH
844  void setup(Size entryCount, const void* messageTail, const void* blockEnd)
845  {
846  assert(valid());
847  assert(blockEnd);
848  assert(messageTail);
849 
850  const Size oldEntryCount = allocate(entryCount, messageTail, blockEnd);
851 
852  for(Size index = oldEntryCount; index < entryCount; ++index)
853  zeroPaddingBytes((*this)[index].resetVariableFields());
854  }
855 
856  /// Sets up the group, sets all optional fields to `null`.
857  ONIXS_B3_UMDF_MD_HOTPATH
858  void construct(Size entryCount, const void* messageTail, const void* blockEnd)
859  {
860  assert(valid());
861  assert(blockEnd);
862  assert(messageTail);
863 
864  const Size oldEntryCount = allocate(entryCount, messageTail, blockEnd);
865 
866  for(Size index = oldEntryCount; index < entryCount; ++index)
867  zeroPaddingBytes((*this)[index].reset());
868  }
869 
870  ONIXS_B3_UMDF_MD_HOTPATH
871  static void zeroPaddingBytes(Entry& entry)
872  {
873  assert(entry.valid());
874  entry.zeroPaddingBytes(EntryType::minimalBlockLength(entry.version()));
875  }
876 
877 private:
878  Dimension* header_;
879  void* entries_;
880  SchemaVersion version_;
881 
882  friend class SbeMessage;
883 };
884 
885 /// Variable-length fields list.
886 template < class BinarySize >
888 {
889 public:
890  /// Initializes the list over the given memory block.
891  ONIXS_B3_UMDF_MD_HOTPATH
892  SbeVariableLengthFieldList(void* binary, BinarySize size, SchemaVersion version) ONIXS_B3_UMDF_MD_NOTHROW
893  : binary_(binary)
894  , size_(size)
895  , version_(version)
896  {
897  }
898 
899  /// \return `true` if the list is empty, otherwise - `false.
901  {
902  return (0 == size_);
903  }
904 
905  /// \return the head of the list.
906  template<class BinaryVariableLengthFieldType>
907  BinaryVariableLengthFieldType& head() const ONIXS_B3_UMDF_MD_NOTHROW
908  {
909  return *static_cast<BinaryVariableLengthFieldType*>(binary_);
910  }
911 
912  /// \return the list of variable-length fields following the head.
913  template<class BinaryVariableLengthFieldType> ONIXS_B3_UMDF_MD_HOTPATH
915  {
916  assert(!empty());
917 
918  const BinarySize headSize = head<BinaryVariableLengthFieldType>().binarySize();
919 
920  assert(headSize <= size_);
921 
922  return SbeVariableLengthFieldList(advanceByBytes( binary_, headSize), size_ - headSize, version_);
923  }
924 
925  /// Checks the variable-length field list consistency.
926  ///
927  /// \return the list of fields following the head.
928  template<class BinaryVariableLengthFieldType> ONIXS_B3_UMDF_MD_HOTPATH
930  {
931  if ONIXS_B3_UMDF_MD_UNLIKELY(empty() || (size_ < BinaryVariableLengthFieldType::Size))
932  {
933  throwBadBinaryBlock();
934  }
935 
936  const BinarySize headSize = head<BinaryVariableLengthFieldType>().binarySize();
937 
938  if ONIXS_B3_UMDF_MD_UNLIKELY(headSize > size_)
939  {
940  throwBadBinaryBlock();
941  }
942 
943  return SbeVariableLengthFieldList(advanceByBytes(binary_, headSize), size_ - headSize, version_);
944  }
945 
946  private:
947  void* binary_;
948  BinarySize size_;
949  SchemaVersion version_;
950 
951 };
952 
953 /// Groups list.
954 template <class BinarySize>
956 {
957 public:
958  /// Initializes the list over the memory block.
959  ONIXS_B3_UMDF_MD_HOTPATH
960  SbeGroupList(void* binary, BinarySize size, SchemaVersion version) ONIXS_B3_UMDF_MD_NOTHROW
961  : binary_(binary)
962  , size_(size)
963  , version_(version)
964  {
965  }
966 
967  /// \return `true` if the list is empty, otherwise - `false`.
969  {
970  return (0 == size_);
971  }
972 
973  /// \return the head group.
974  template<class Group> ONIXS_B3_UMDF_MD_HOTPATH
976  {
977  assert(!empty());
978 
979  return Group(binary_, size_, version_);
980  }
981 
982  /// \return the list of groups that follow the head.
983  template<class Group> ONIXS_B3_UMDF_MD_HOTPATH
985  {
986  assert(!empty());
987 
988  const BinarySize headSize = head<Group>().binarySize();
989 
990  assert(headSize <= size_);
991 
992  return SbeGroupList(advanceByBytes(binary_, headSize), size_ - headSize, version_);
993  }
994 
995  /// \return variable length fields.
996  template <class Group> ONIXS_B3_UMDF_MD_HOTPATH
998  {
999  assert(!empty());
1000 
1001  const BinarySize headSize = head<Group>().binarySize();
1002 
1003  assert(headSize <= size_);
1004 
1005  return SbeVariableLengthFieldList<BinarySize>(advanceByBytes(binary_, headSize), size_ - headSize, version_);
1006  }
1007 
1008  /// Checks the list consistency.
1009  ///
1010  /// \return the list of groups that follow the head.
1011  template<class Group> ONIXS_B3_UMDF_MD_HOTPATH
1013  {
1014  const BinarySize headSize = checkHead<Group>();
1015 
1016  return SbeGroupList(advanceByBytes(binary_, headSize), size_ - headSize, version_);
1017  }
1018 
1019  /// Checks the variable length fields list consistency.
1020  ///
1021  /// \return the list of fields that follow the head.
1022  template <class Group> ONIXS_B3_UMDF_MD_HOTPATH
1024  {
1025  const BinarySize headSize = checkHead<Group>();
1026 
1027  return SbeVariableLengthFieldList<BinarySize>(advanceByBytes(binary_, headSize), size_ - headSize, version_);
1028  }
1029 
1030 private:
1031  template<class Group>
1032  BinarySize checkHead() const
1033  {
1034  if ONIXS_B3_UMDF_MD_UNLIKELY(size_ < Group::Dimension::Size)
1035  {
1036  throwBadBinaryBlock();
1037  }
1038 
1039  const Group group = head<Group>();
1040 
1041  const BinarySize headSize = group.binarySize();
1042 
1043  if ONIXS_B3_UMDF_MD_UNLIKELY(headSize > size_)
1044  {
1045  throwBadBinaryBlock();
1046  }
1047 
1048  if(!group.empty())
1049  {
1050  const BinarySize entrySize = group.entrySize();
1051  const BinarySize expectedEntrySize = Group::Entry::minimalBlockLength(version_);
1052 
1053  if ONIXS_B3_UMDF_MD_UNLIKELY(entrySize < expectedEntrySize)
1054  {
1055  throwBadBinaryBlock();
1056  }
1057  }
1058 
1059  return headSize;
1060  }
1061 
1062  void* binary_;
1063  BinarySize size_;
1064  SchemaVersion version_;
1065 };
1066 
1067 /// Checks the compatibility with the provided SBE Schema version.
1068 template<typename Traits>
1070 {
1071  if ONIXS_B3_UMDF_MD_UNLIKELY(version < Traits::MinimalVersion)
1072  {
1073  throwBadMessageVersion(version, Traits::MinimalVersion);
1074  }
1075 }
1076 
1077 /// Checks the compatibility with the provided SBE Schema version.
1078 template<typename Traits>
1080 {
1081  checkVersion<Traits>(version);
1082 
1083  if ONIXS_B3_UMDF_MD_UNLIKELY(version < since)
1084  {
1085  throwBadMessageVersion(version, since);
1086  }
1087 }
1088 
1089 /// Checks the compatibility with the provided SBE Schema ID.
1090 template<typename Traits>
1092 {
1093  if ONIXS_B3_UMDF_MD_UNLIKELY(id != Traits::Id)
1094  {
1095  throwBadSchemaId(Traits::Id, id);
1096  }
1097 }
1098 
1099 /// Checks the compatibility with the provided SBE Schema version.
1100 template<typename Traits>
1102 {
1103  checkSchemaId<Traits>(id);
1104  checkVersion<Traits>(version);
1105 }
1106 
1107 /// SBE-encoded message.
1109 {
1110 public:
1111  /// For tagged constructors
1112  struct NoFieldsInit{};
1113  struct NoInit{};
1114  struct NoCheck{};
1115 
1116  /// Length of the message binary data.
1118 
1119  /// Length of the message body representing a block of fixed-length fields.
1121 
1122  /// Initializes a blank instance.
1124  : header_(ONIXS_B3_UMDF_MD_NULLPTR)
1125  , size_(0)
1126  {
1127  }
1128 
1129  ///// Initializes the instance over the given memory block.
1130  //ONIXS_B3_UMDF_MD_HOTPATH
1131  //SbeMessage(void* data, MessageSize size, SchemaVersion version)
1132  // : header_(static_cast<MessageHeader*>(data))
1133  // , size_(size)
1134  //{
1135  // assert(data);
1136  // assert(size <= MaxMessageSize);
1137 
1138  // if ONIXS_B3_UMDF_MD_UNLIKELY(size < MessageHeader::Size)
1139  // throwBinaryBlockIsTooSmall(size, MessageHeader::Size);
1140 
1141  // this->version(version);
1142  //}
1143 
1144  /// Initializes the instance over the given memory block.
1145  ONIXS_B3_UMDF_MD_HOTPATH
1146  SbeMessage(const void* data, MessageSize size)
1147  : header_(static_cast<const MessageHeader*>(data))
1148  , size_(size)
1149  {
1150  assert(data);
1151  assert(size <= MaxMessageSize);
1152 
1153  if ONIXS_B3_UMDF_MD_UNLIKELY(size < MessageHeader::Size)
1154  throwBinaryBlockIsTooSmall(size, MessageHeader::Size);
1155 
1156  // Now it is safe to read header_.
1157  if ONIXS_B3_UMDF_MD_UNLIKELY(size < (MessageHeader::Size + header_->blockLength()))
1158  throwBinaryBlockIsTooSmall(size, MessageHeader::Size + header_->blockLength());
1159  }
1160 
1161  /// Initializes the instance over the given memory block.
1162  ///
1163  /// \note Performs no check of the data consistency
1164  ONIXS_B3_UMDF_MD_HOTPATH
1166  : header_(static_cast<MessageHeader*>(data))
1167  , size_(size)
1168  {
1169  assert(data);
1170  assert(size <= MaxMessageSize);
1171 
1172  assert(size >= MessageHeader::Size);
1173  assert(size >= MessageHeader::Size + header_->blockLength());
1174  }
1175 
1176  /// Blank the instance.
1178  {
1179  *this = SbeMessage();
1180  assert(!valid());
1181  }
1182 
1183  /// \return `true` if the instance refers to a valid message, otherwise - `false`.
1185  {
1186  return (ONIXS_B3_UMDF_MD_NULLPTR != header_);
1187  }
1188 
1189  /// \return SBE Template identifier.
1191  {
1192  assert(valid());
1193 
1194  return header_->templateId();
1195  }
1196 
1197  /// \return SBE Schema version.
1199  {
1200  assert(valid());
1201 
1202  return header_->version();
1203  }
1204 
1205  /// \return SBE Schema ID.
1207  {
1208  assert(valid());
1209 
1210  return header_->schemaId();
1211  }
1212 
1213  /// \return SBE-encoded message content.
1214  const void* binary() const ONIXS_B3_UMDF_MD_NOTHROW
1215  {
1216  assert(valid());
1217 
1218  return header_;
1219  }
1220 
1221  ///// \return SBE-encoded message content.
1222  //void* binary() ONIXS_B3_UMDF_MD_NOTHROW
1223  //{
1224  // assert(valid());
1225 
1226  // return header_;
1227  //}
1228 
1229  // \return the end of the memory block.
1231  {
1232  assert(valid());
1233 
1234  return advanceByBytes(header_, size_);
1235  }
1236 
1237  // \return the end of the memory block.
1239  {
1240  assert(valid());
1241 
1242  return advanceByBytes(header_, size_);
1243  }
1244 
1245  /// \return the size of the message buffer.
1247  {
1248  return size_;
1249  }
1250 
1251  // /// \return the beginning of the message body.
1252  //void* body() ONIXS_B3_UMDF_MD_NOTHROW
1253  //{
1254  // assert(valid());
1255 
1256  // return advanceByBytes(header_, MessageHeader::Size);
1257  //}
1258 
1259  /// \return the size of the message body in bytes.
1261  {
1262  assert(valid());
1263 
1264  return header_->blockLength();
1265  }
1266 
1267  /// \return the beginning of the message body.
1268  const void* block() const ONIXS_B3_UMDF_MD_NOTHROW
1269  {
1270  assert(valid());
1271 
1272  return advanceByBytes(header_, MessageHeader::Size);
1273  }
1274 
1275  ///// \return the beginning of the message body.
1276  //void* block() ONIXS_B3_UMDF_MD_NOTHROW
1277  //{
1278  // assert(valid());
1279 
1280  // return advanceByBytes(header_, MessageHeader::Size);
1281  //}
1282 
1283 protected:
1284  /// Binary group list instantiation.
1286 
1287  ///// Sets the SBE Schema version.
1288  //SbeMessage& version(SchemaVersion version) ONIXS_B3_UMDF_MD_NOTHROW
1289  //{
1290  // assert(valid());
1291 
1292  // header_->setVersion(version);
1293 
1294  // return *this;
1295  //}
1296 
1297  ///// \return the list of repeating groups
1298  //ONIXS_B3_UMDF_MD_HOTPATH
1299  //GroupList groups() ONIXS_B3_UMDF_MD_NOTHROW
1300  //{
1301  // assert(header_);
1302 
1303  // void* list = advanceByBytes<void>(body(), blockLength());
1304 
1305  // const MessageSize listSize = size_ - MessageHeader::Size - header_->blockLength();
1306 
1307  // return GroupList(list, listSize, header_->version());
1308  //}
1309 
1310  /// \return the list of repeating groups
1311  ONIXS_B3_UMDF_MD_HOTPATH
1313  {
1314  assert(header_);
1315 
1316  const void* list = advanceByBytes(block(), blockLength());
1317 
1318  const MessageSize listSize = size_ - MessageHeader::Size - header_->blockLength();
1319 
1320  return GroupList(const_cast<void*>(list), listSize, header_->version());
1321  }
1322 
1323  /// Resets the group to the initial state.
1324  template<typename Group>
1325  ONIXS_B3_UMDF_MD_HOTPATH
1326  void initGroup(Group& group, typename Group::EntrySize entrySize) ONIXS_B3_UMDF_MD_NOTHROW
1327  {
1328  assert(group.valid());
1329  group.init(entrySize);
1330  }
1331 
1332  /// Initializes the group header.
1333  template<typename Group>
1334  ONIXS_B3_UMDF_MD_HOTPATH
1335  void setupGroup(Group& group, typename Group::Size entryCount, const void* messageTail)
1336  {
1337  assert(messageTail);
1338  assert(group.valid());
1339  group.setup(entryCount, messageTail, blockEnd());
1340  }
1341 
1342  /// Initializes the group header, sets all optional fields to `null`.
1343  template<typename Group>
1344  ONIXS_B3_UMDF_MD_HOTPATH
1345  void constructGroup(Group& group, typename Group::Size entryCount, const void* messageTail)
1346  {
1347  assert(messageTail);
1348  assert(group.valid());
1349  group.construct(entryCount, messageTail, blockEnd());
1350  }
1351 
1352  /// Sets the variable length field value.
1353  //void setVarDataField(DATA& data, StrRef value, const void* oldMessageTail)
1354  //{
1355  // assert(oldMessageTail);
1356 
1357  // const ptrdiff_t lengthChange = static_cast<ptrdiff_t>(value.length() - data.length());
1358 
1359  // const void* const newMessageTail = advanceByBytes(oldMessageTail, lengthChange);
1360 
1361  // if ONIXS_B3_UMDF_MD_UNLIKELY(byteDistance(blockEnd(), newMessageTail) < 0)
1362  // throwNotEnoughSpace();
1363 
1364  // const void* const oldEndOfData = advanceByBytes(data.varData().data(), data.varData().size());
1365 
1366  // void* const newEndOfData = toOpaquePtr(advanceByBytes(&data, value.length() + DATA::Size));
1367 
1368  // std::memmove(newEndOfData, oldEndOfData, byteDistance(oldMessageTail, oldEndOfData));
1369 
1370  // data.varData(value);
1371  //}
1372 
1373  /// Binary group list instantiation.
1375 
1376  ///// \return the list of variable-length fields.
1377  //ONIXS_B3_UMDF_MD_HOTPATH
1378  //VariableLengthFieldList variableLengthFields() ONIXS_B3_UMDF_MD_NOTHROW
1379  //{
1380  // assert(header_);
1381 
1382  // void* list = advanceByBytes<void>(body(), blockLength());
1383 
1384  // const MessageSize listSize = size_ - MessageHeader::Size - header_->blockLength();
1385 
1386  // return VariableLengthFieldList(list, listSize, header_->version());
1387  //}
1388 
1389  /// \return the list of variable-length fields.
1390  ONIXS_B3_UMDF_MD_HOTPATH
1391  VariableLengthFieldList variableLengthFields() const ONIXS_B3_UMDF_MD_NOTHROW
1392  {
1393  assert(header_);
1394 
1395  const void* list = advanceByBytes(block(), blockLength());
1396 
1397  const MessageSize listSize = size_ - MessageHeader::Size - header_->blockLength();
1398 
1399  return VariableLengthFieldList(const_cast<void*>(list), listSize, header_->version());
1400  }
1401 
1402  //ONIXS_B3_UMDF_MD_HOTPATH
1403  //void init(
1404  // MessageHeader::TemplateId value,
1405  // MessageHeader::BlockLength minimalBlockLength,
1406  // MessageHeader::BlockLength blockLength,
1407  // SchemaId id) ONIXS_B3_UMDF_MD_NOTHROW
1408  //{
1409  // assert(header_);
1410  // assert(blockLength >= minimalBlockLength);
1411 
1412  // header_->setTemplateId(value);
1413  // header_->setBlockLength(blockLength);
1414  // header_->setSchemaId(id);
1415 
1416  // zeroPaddingBytes(minimalBlockLength);
1417  //}
1418 
1419  ONIXS_B3_UMDF_MD_HOTPATH
1421  {
1422  assert(tail);
1423 
1424  const ptrdiff_t distance = byteDistance(tail, binary());
1425 
1426  assert(distance > 0);
1427 
1428  assert(distance <= (std::numeric_limits<MessageSize>::max)());
1429 
1430  const MessageSize size = static_cast<MessageSize>(distance);
1431 
1432  assert(size <= size_);
1433 
1434  return size;
1435  }
1436 
1437  /// Sets the value of the variable length field.
1438  template<class Callable, class Owner>
1439  void setVariableLengthField(Callable callable, StrRef value, Owner& owner)
1440  {
1441  setVarDataField(callable(owner), value, owner.tail());
1442  }
1443 
1444  /// Sets the value of the variable length field.
1445  template<class Callable, class Owner>
1446  void setVariableLengthField(Callable callable, StrRef value, SchemaVersion since, Owner& owner)
1447  {
1448  if ONIXS_B3_UMDF_MD_UNLIKELY(since > version())
1449  throwDisallowedField();
1450 
1451  setVariableLengthField(callable, value, owner);
1452  }
1453 
1454  /// \return the value of the variable length field.
1455  template<class Callable, class Owner>
1456  StrRef getVariableLengthField(Callable callable, const Owner& owner) const ONIXS_B3_UMDF_MD_NOTHROW
1457  {
1458  ONIXS_B3_UMDF_MD_CHECK_NOTHROW(callable(owner));
1459  return callable(owner).varData();
1460  }
1461 
1462  /// \return the value of the variable length field.
1463  template<class Callable, class Owner>
1464  StrRef getVariableLengthField(Callable callable, SchemaVersion since, Owner& owner) const ONIXS_B3_UMDF_MD_NOTHROW
1465  {
1466  if ONIXS_B3_UMDF_MD_UNLIKELY(since > version())
1467  return StrRef();
1468 
1469  return getVariableLengthField(callable, owner);
1470  }
1471 
1472  /// Resets the variable length field.
1473  template<class Callable, class Owner>
1474  void setVariableLengthFieldToNull(Callable callable, Owner& owner) ONIXS_B3_UMDF_MD_NOTHROW
1475  {
1476  ONIXS_B3_UMDF_MD_CHECK_NOTHROW(callable(owner));
1477  callable(owner).length(0);
1478  }
1479 
1480  /// Sets the group to the initial state.
1481  template<class Group, class Callable, class Owner>
1482  void resetGroup(Callable callable, Owner& owner) ONIXS_B3_UMDF_MD_NOTHROW
1483  {
1484  const typename Group::EntrySize entrySize = Group::Entry::blockLength(version());
1485 
1486  Group grp = callable(owner);
1487 
1488  initGroup(grp, entrySize);
1489  }
1490 
1491  /// Sets the variable length field to `null`.
1492  template<class Callable, class Owner>
1493  void setVariableLengthFieldToNull(Callable callable, SchemaVersion since, Owner& owner) ONIXS_B3_UMDF_MD_NOTHROW
1494  {
1495  if ONIXS_B3_UMDF_MD_UNLIKELY(since > version())
1496  return;
1497 
1498  setVariableLengthFieldToNull(callable, owner);
1499  }
1500 
1501  /// Resets the repeating group.
1502  template<class Group, class Callable, class Owner>
1503  void resetGroup(Callable callable, SchemaVersion since, Owner& owner)
1504  {
1505  if ONIXS_B3_UMDF_MD_UNLIKELY(since > version())
1506  return;
1507 
1508  resetGroup<Group>(callable, owner);
1509  }
1510 
1511  /// \return the repeating group.
1512  template<class Group, class Callable, class Owner>
1513  Group getGroup(Callable callable, Owner& owner) const ONIXS_B3_UMDF_MD_NOTHROW
1514  {
1515  ONIXS_B3_UMDF_MD_CHECK_NOTHROW(callable(owner));
1516  return callable(owner);
1517  }
1518 
1519  /// \return the repeating group.
1520  template<class Group, class Callable, class Owner>
1521  Group getGroup(Callable callable, SchemaVersion since, Owner& owner) const ONIXS_B3_UMDF_MD_NOTHROW
1522  {
1523  if ONIXS_B3_UMDF_MD_UNLIKELY(since > version())
1524  return Group();
1525 
1526  return getGroup<Group>(callable, owner);
1527  }
1528 
1529  /// Creates a repeating group with the given number of entries, sets all optional fields of the group entries to null.
1530  template<class Group, class Callable, class Owner>
1531  Group constructGroup(Callable callable, typename Group::Size length, SchemaVersion since, Owner& owner)
1532  {
1533  if ONIXS_B3_UMDF_MD_UNLIKELY(since > version())
1534  return Group();
1535 
1536  return constructGroup<Group>(callable, length, owner);
1537  }
1538 
1539  /// Creates a repeating group with the given number of entries, sets all optional fields of the group entries to null.
1540  template<class Group, class Callable, class Owner>
1541  Group constructGroup(Callable callable, typename Group::Size length, Owner& owner)
1542  {
1543  Group group = callable(owner);
1544 
1545  constructGroup(group, length, owner.tail());
1546 
1547  return group;
1548  }
1549 
1550  /// Setups the repeating group with the given number of entries.
1551  template<class Group, class Callable, class Owner>
1552  Group setupGroup(Callable callable, typename Group::Size length, SchemaVersion since, Owner& owner)
1553  {
1554  if ONIXS_B3_UMDF_MD_UNLIKELY(since > version())
1555  return Group();
1556 
1557  return setupGroup<Group>(callable, length, owner);
1558  }
1559 
1560  /// Setups the repeating group with the given number of entries.
1561  template<class Group, class Callable, class Owner>
1562  Group setupGroup(Callable callable, typename Group::Size length, Owner& owner)
1563  {
1564  Group group = callable(owner);
1565 
1566  setupGroup(group, length, owner.tail());
1567 
1568  return group;
1569  }
1570 
1571  /// Maximal message size.
1573  ONIXS_B3_UMDF_MD_NODISCARD
1576  {
1577  return
1579  }
1580 
1581 private:
1582  const MessageHeader* header_;
1583  MessageSize size_;
1584 };
1585 
ONIXS_B3_UMDF_MD_HOTPATH void setOrdinary(BlockLength offset, FieldValue value)
Sets the field value.
Definition: SbeMessage.h:227
ONIXS_B3_UMDF_MD_HOTPATH StrRef fixedStr(BlockLength offset) const
Provides access to a string field value.
Definition: SbeMessage.h:168
ONIXS_B3_UMDF_MD_HOTPATH bool enumeration(typename Enumeration::Enum &value, BlockLength offset, NullValue null, SchemaVersion since) const
Provides access to an optional field value.
Definition: SbeMessage.h:133
ONIXS_B3_UMDF_MD_HOTPATH bool fixedStr(StrRef &value, BlockLength offset) const
Provides access to an optional string field value.
Definition: SbeMessage.h:182
DimensionType Dimension
Repeating group dimension type.
Definition: SbeMessage.h:634
BodySizeType BlockLength
Type to present the length of binary data of the repeating group entry.
Definition: SbeMessage.h:300
ONIXS_B3_UMDF_MD_HOTPATH Group head() const
Definition: SbeMessage.h:975
DimensionType::BlockLength EntrySize
Length of group entry data.
Definition: SbeMessage.h:643
Iterator end() const
Returns the iterator pointing to the entry behind the end of the group.
Definition: SbeMessage.h:557
SbeGroupList< MessageSize > GroupList
Binary group list instantiation.
Definition: SbeMessage.h:1285
#define ONIXS_B3_UMDF_MD_DEFAULT
Definition: Compiler.h:122
bool operator!=(const TimeSpan &left, const TimeSpan &right)
Compares with other instance for in-equality.
Definition: Time.h:337
ONIXS_B3_UMDF_MD_HOTPATH Iterator(void *entry, Size size, SchemaVersion version)
Initializes the instance to the given repeating group.
Definition: SbeMessage.h:414
SbeGroupEntries(const SbeGroupEntries< OtherEntry, OtherBlockLength, OtherNumInGroup, OtherLength > &other)
Copy constructor.
Definition: SbeMessage.h:587
ONIXS_B3_UMDF_MD_HOTPATH Enumeration::Enum enumeration(BlockLength offset) const
Definition: SbeMessage.h:112
#define ONIXS_B3_UMDF_MD_NOTHROW
Definition: Compiler.h:114
#define ONIXS_B3_UMDF_MD_CONSTEXPR
Definition: Compiler.h:120
ONIXS_B3_UMDF_MD_HOTPATH SbeGroupList tail() const
Definition: SbeMessage.h:984
ONIXS_B3_UMDF_MD_HOTPATH SbeMessage(void *data, MessageSize size, NoCheck)
Initializes the instance over the given memory block.
Definition: SbeMessage.h:1165
MessageSize EncodedLength
Length of the message binary data.
Definition: SbeMessage.h:1117
GroupSizeType BinarySize
Length of group data.
Definition: SbeMessage.h:637
void setVariableLengthFieldToNull(Callable callable, Owner &owner)
Resets the variable length field.
Definition: SbeMessage.h:1474
void resetGroup(Callable callable, SchemaVersion since, Owner &owner)
Resets the repeating group.
Definition: SbeMessage.h:1503
Services to access fields stored in an SBE-encoded block of fixed-length fields.
Definition: SbeMessage.h:63
#define ONIXS_B3_UMDF_MD_NULLPTR
Definition: Compiler.h:128
ONIXS_B3_UMDF_MD_HOTPATH EntrySize entrySize() const
Definition: SbeMessage.h:774
ONIXS_B3_UMDF_MD_HOTPATH void setOrdinary(BlockLength offset, FieldValue value, SchemaVersion since)
Sets the field value.
Definition: SbeMessage.h:237
#define ONIXS_B3_UMDF_MD_ASSERT(CHECK)
Definition: Compiler.h:156
ONIXS_B3_UMDF_MD_HOTPATH Iterator end() const
Definition: SbeMessage.h:717
SbeGroupEntry()
Initializes a blank instance.
Definition: SbeMessage.h:303
Operations over a repeating group instance.
Definition: SbeMessage.h:296
SbeMessage()
Initializes a blank instance.
Definition: SbeMessage.h:1123
Entries::Entry Entry
Group entry type.
Definition: SbeMessage.h:652
Type of the Market Data Entry.
Definition: Fields.h:1050
Group setupGroup(Callable callable, typename Group::Size length, Owner &owner)
Setups the repeating group with the given number of entries.
Definition: SbeMessage.h:1562
ONIXS_B3_UMDF_MD_HOTPATH bool ordinary(Value &value, BlockLength offset, NullValue null) const
Provides access to an optional field value.
Definition: SbeMessage.h:93
bool operator<(const TimeSpan &left, const TimeSpan &right)
Checks whether left time interval less than right one.
Definition: Time.h:347
ONIXS_B3_UMDF_MD_HOTPATH void setupGroup(Group &group, typename Group::Size entryCount, const void *messageTail)
Initializes the group header.
Definition: SbeMessage.h:1335
ONIXS_B3_UMDF_MD_HOTPATH Value decimal(BlockLength offset) const
Definition: SbeMessage.h:140
bool operator>(const TimeSpan &left, const TimeSpan &right)
Checks whether left time interval greater than right one.
Definition: Time.h:357
ONIXS_B3_UMDF_MD_HOTPATH void setFixedStr(BlockLength offset, StrRef value, SchemaVersion since)
Sets the field value.
Definition: SbeMessage.h:279
ONIXS_B3_UMDF_MD_HOTPATH bool decimal(Value &value, BlockLength offset, NullValue null) const
Definition: SbeMessage.h:150
SbeGroupEntries(void *encoded, BlockLength blockLength, Size groupSize, SchemaVersion version)
Initializes the instance referencing to data.
Definition: SbeMessage.h:521
ONIXS_B3_UMDF_MD_HOTPATH SbeVariableLengthFieldList< BinarySize > variableLengthFields() const
Definition: SbeMessage.h:997
void checkVersion(SchemaVersion since, SchemaVersion version)
Checks the compatibility with the provided SBE Schema version.
Definition: SbeMessage.h:1079
Message identifiers and length of message root..
Definition: Composites.h:37
char Char
Character type alias.
Definition: String.h:30
ONIXS_B3_UMDF_MD_HOTPATH void setFixedStr(BlockLength offset, StrRef value)
Sets the field value.
Definition: SbeMessage.h:263
void checkSchema(SchemaId id, SchemaVersion version)
Checks the compatibility with the provided SBE Schema version.
Definition: SbeMessage.h:1101
Operations over SBE-encoded repeating group entries.
Definition: SbeMessage.h:378
#define ONIXS_B3_UMDF_MD_MESSAGING_NAMESPACE_END
Definition: ABI.h:151
ONIXS_B3_UMDF_MD_HOTPATH BinarySize binarySize() const
Definition: SbeMessage.h:767
void setVariableLengthField(Callable callable, StrRef value, SchemaVersion since, Owner &owner)
Sets the value of the variable length field.
Definition: SbeMessage.h:1446
ONIXS_B3_UMDF_MD_HOTPATH SbeGroup(void *data, ONIXS_B3_UMDF_MD_UNUSED BinarySize size, SchemaVersion version)
Initializes an instance referencing to a valid group of a given message.
Definition: SbeMessage.h:668
ONIXS_B3_UMDF_MD_HOTPATH Iterator begin() const
Definition: SbeMessage.h:708
UInt16 MessageSize
Message length type.
Definition: Aliases.h:29
ONIXS_B3_UMDF_MD_HOTPATH bool decimal(Value &value, BlockLength offset, NullValue null, SchemaVersion since) const
Definition: SbeMessage.h:161
SbeGroup()
Initializes a blank instance referencing to nothing.
Definition: SbeMessage.h:658
void setVariableLengthField(Callable callable, StrRef value, Owner &owner)
Sets the value of the variable length field.
Definition: SbeMessage.h:1439
MessageSize BlockLength
Length of the message body representing a block of fixed-length fields.
Definition: SbeMessage.h:1120
An iterator over SBE-encoded group entries.
Definition: SbeMessage.h:391
Iterator()
Initializes the instance that refers to nothing.
Definition: SbeMessage.h:405
ONIXS_B3_UMDF_MD_HOTPATH bool ordinary(Value &value, BlockLength offset, NullValue null, SchemaVersion since) const
Provides access to an optional field value.
Definition: SbeMessage.h:105
StrRef getVariableLengthField(Callable callable, SchemaVersion since, Owner &owner) const
Definition: SbeMessage.h:1464
BinaryBlock()
Initializes a blank instance.
Definition: SbeMessage.h:73
void resetGroup(Callable callable, Owner &owner)
Sets the group to the initial state.
Definition: SbeMessage.h:1482
ONIXS_B3_UMDF_MD_HOTPATH void constructGroup(Group &group, typename Group::Size entryCount, const void *messageTail)
Initializes the group header, sets all optional fields to null.
Definition: SbeMessage.h:1345
ONIXS_B3_UMDF_MD_HOTPATH void setEnumeration(BlockLength offset, typename Enumeration::Enum value)
Sets the field value.
Definition: SbeMessage.h:247
ONIXS_B3_UMDF_MD_HOTPATH void setEnumeration(BlockLength offset, typename Enumeration::Enum value, SchemaVersion since)
Sets the field value.
Definition: SbeMessage.h:255
Group getGroup(Callable callable, Owner &owner) const
Definition: SbeMessage.h:1513
NumInGroup Size
Number of entries in the collection.
Definition: SbeMessage.h:388
#define ONIXS_B3_UMDF_MD_MESSAGING_NAMESPACE_BEGIN
Definition: ABI.h:146
ONIXS_B3_UMDF_MD_HOTPATH SbeVariableLengthFieldList tail() const
Definition: SbeMessage.h:914
MessageHeader::Version SchemaVersion
SBE-encoded data version type.
Definition: SchemaTraits.h:30
#define ONIXS_B3_UMDF_MD_LTWT_EXPORTED
Definition: ABI.h:98
SbeVariableLengthFieldList< MessageSize > VariableLengthFieldList
Sets the variable length field value.
Definition: SbeMessage.h:1374
ONIXS_B3_UMDF_MD_HOTPATH void zeroPaddingBytes(BlockLength offset)
If specified, the extra space is padded at the end of each entry and should be set to zeroes by encod...
Definition: SbeMessage.h:215
Group getGroup(Callable callable, SchemaVersion since, Owner &owner) const
Definition: SbeMessage.h:1521
#define ONIXS_B3_UMDF_MD_LTWT_CLASS
Definition: ABI.h:90
const UInt16 MaxMessageSize
Maximum supported message size.
Entries::Iterator Iterator
The iterator type for group entries.
Definition: SbeMessage.h:649
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...
Definition: SbeMessage.h:1541
ONIXS_B3_UMDF_MD_HOTPATH void * binary() const
Definition: SbeMessage.h:760
#define ONIXS_B3_UMDF_MD_CHECK_NOTHROW(equation)
Definition: Compiler.h:115
StrRef getVariableLengthField(Callable callable, const Owner &owner) const
Definition: SbeMessage.h:1456
Entries::Size Size
Number of entries in the group.
Definition: SbeMessage.h:655
Timestamp operator-(const Timestamp &timestamp, const TimeSpan &timeSpan)
Subtracts time interval from given time point.
Definition: Time.h:805
void setVariableLengthFieldToNull(Callable callable, SchemaVersion since, Owner &owner)
Sets the variable length field to null.
Definition: SbeMessage.h:1493
EntryType Entry
The type of the repeating group entry.
Definition: SbeMessage.h:385
ONIXS_B3_UMDF_MD_HOTPATH SbeMessage(const void *data, MessageSize size)
Initializes the instance over the given memory block.
Definition: SbeMessage.h:1146
SbeFields()
Initializes a blank instance.
Definition: SbeMessage.h:289
ONIXS_B3_UMDF_MD_HOTPATH SbeVariableLengthFieldList(void *binary, BinarySize size, SchemaVersion version)
Initializes the list over the given memory block.
Definition: SbeMessage.h:892
Base services to access fields stored in an SBE-encoded block of memory.
Definition: SbeMessage.h:204
ONIXS_B3_UMDF_MD_API static ONIXS_B3_UMDF_MD_NODISCARD MessageSize getMaxMessageSize()
Maximal message size.
Definition: SbeMessage.h:1575
ONIXS_B3_UMDF_MD_HOTPATH MessageSize calculateBinarySize(const void *tail) const
Definition: SbeMessage.h:1420
ONIXS_B3_UMDF_MD_HOTPATH SbeGroupList(void *binary, BinarySize size, SchemaVersion version)
Initializes the list over the memory block.
Definition: SbeMessage.h:960
ONIXS_B3_UMDF_MD_HOTPATH SbeVariableLengthFieldList< BinarySize > checkVariableLengthFields() const
Checks the variable length fields list consistency.
Definition: SbeMessage.h:1023
Group setupGroup(Callable callable, typename Group::Size length, SchemaVersion since, Owner &owner)
Setups the repeating group with the given number of entries.
Definition: SbeMessage.h:1552
MessageHeader::SchemaId SchemaId
Definition: SchemaTraits.h:34
ONIXS_B3_UMDF_MD_HOTPATH GroupList groups() const
Definition: SbeMessage.h:1312
bool operator==(const TimeSpan &left, const TimeSpan &right)
Compares with other instance for equality.
Definition: Time.h:327
ONIXS_B3_UMDF_MD_HOTPATH VariableLengthFieldList variableLengthFields() const
Definition: SbeMessage.h:1391
ONIXS_B3_UMDF_MD_HOTPATH SbeGroupList checkTail() const
Checks the list consistency.
Definition: SbeMessage.h:1012
ONIXS_B3_UMDF_MD_HOTPATH SbeGroupEntry(const void *encoded, BlockLength size, SchemaVersion version)
Initializes the instance from the memory block of the encoded message.
Definition: SbeMessage.h:312
Length EncodedLength
The length of the binary data occupied by the group entries.
Definition: SbeMessage.h:382
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...
Definition: SbeMessage.h:1531
SbeGroupEntries()
Initializes a blank instance referencing to nothing.
Definition: SbeMessage.h:512
ONIXS_B3_UMDF_MD_HOTPATH void initGroup(Group &group, typename Group::EntrySize entrySize)
Resets the group to the initial state.
Definition: SbeMessage.h:1326
Timestamp operator+(const Timestamp &timestamp, const TimeSpan &timeSpan)
Adds time interval to given time point.
Definition: Time.h:791
ONIXS_B3_UMDF_MD_HOTPATH Size size() const
Definition: SbeMessage.h:696
void checkSchemaId(SchemaId id)
Checks the compatibility with the provided SBE Schema ID.
Definition: SbeMessage.h:1091
ONIXS_B3_UMDF_MD_HOTPATH bool fixedStr(StrRef &value, BlockLength offset, SchemaVersion since) const
Provides access to an optional string field value.
Definition: SbeMessage.h:193
SbeGroupEntries< EntryType, typename Dimension::BlockLength, typename Dimension::NumInGroup, GroupSizeType > Entries
Binary group blocks.
Definition: SbeMessage.h:646
ONIXS_B3_UMDF_MD_HOTPATH bool enumeration(typename Enumeration::Enum &value, BlockLength offset, NullValue null) const
Provides access to an optional field value.
Definition: SbeMessage.h:122
MessageHeader::TemplateId MessageTemplateId
Message type (template) identification.
ONIXS_B3_UMDF_MD_NODISCARD Entries entries() const
Definition: SbeMessage.h:738
ONIXS_B3_UMDF_MD_HOTPATH SbeVariableLengthFieldList checkTail() const
Checks the variable-length field list consistency.
Definition: SbeMessage.h:929