OnixS C++ CME iLink 3 Binary Order Entry Handler  1.18.1
API Documentation
MessageHolder.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 <vector>
24 
29 
30 namespace OnixS
31 {
32  namespace CME
33  {
34  namespace iLink3
35  {
37  }
38  }
39 }
40 
42 
43 /// \return the version of the Session’s message schema.
46 
47 /// The policy to create messages with null-initialized optional fields.
49 {
50  /// \private
51  template <typename SbeMessageType>
52  inline static SbeMessageType createMessage(
53  void* data, MessageSize length, SchemaVersion version)
54  {
55  return SbeMessageType(data, length, version);
56  }
57 
58  /// \private
59  inline static const char* name() ONIXS_ILINK3_NOTHROW
60  {
61  return "FieldsInitPolicy";
62  }
63 };
64 
65 /// The policy to create messages without initialized optional fields.
67 {
68  /// \private
69  template <typename SbeMessageType>
70  inline static SbeMessageType createMessage(
71  void* data, MessageSize length, SchemaVersion version)
72  {
73  return SbeMessageType(
74  data, length, SbeMessage::NoFieldsInit(), version);
75  }
76 
77  /// \private
78  inline static const char* name() ONIXS_ILINK3_NOTHROW
79  {
80  return "FieldsNoInitPolicy";
81  }
82 };
83 
84 /// \private
85 template
86 <
87  typename MessageType,
88  bool isFix =
89  IsBaseOf<TagBased::Message, MessageType>::value
90 >
91 struct HeldAdapter;
92 
93 template <typename MessageType>
94 struct HeldAdapter<MessageType, true> ONIXS_ILINK3_FINAL
95  : public MessageType
96 {
97  ONIXS_ILINK3_STATIC_ASSERT((
98  IsBaseOf<TagBased::Message, MessageType>::value));
99 
100  enum { isFix = true };
101 
102  typedef typename
103  MessageType::Binary
105 
106  typedef typename
107  SbeType::EncodedLength
109 
110  HeldAdapter() ONIXS_ILINK3_DEFAULT;
111 
112  HeldAdapter(
113  void* data,
114  EncodedLength length,
115  SchemaVersion version)
116  : MessageType(SbeType(data, length, version))
117  {
118  }
119 
121  void* data,
122  EncodedLength length,
124  SchemaVersion version)
125  : MessageType(SbeType(data, length, version))
126  {
127  }
128 
130  void* data,
131  EncodedLength length,
133  : MessageType(SbeType(data, length))
134  {
135  }
136 
138  void* data,
139  EncodedLength length,
143  : MessageType(
144  SbeType(
145  data,
146  length,
147  SbeMessage::NoInit(),
148  SbeMessage::NoCheck()))
149  {
150  }
151 };
152 
153 template <typename MessageType>
154 struct HeldAdapter<MessageType, false> ONIXS_ILINK3_FINAL
155  : public MessageType
156 {
157  ONIXS_ILINK3_STATIC_ASSERT((
158  IsBaseOf<SbeMessage, MessageType>::value));
159 
160  enum { isFix = false };
161 
162  typedef MessageType SbeType;
163 
164  typedef typename
165  SbeType::EncodedLength
167 
168  HeldAdapter() ONIXS_ILINK3_DEFAULT;
169 
170  HeldAdapter(
171  void* data,
172  EncodedLength length,
173  SchemaVersion version)
174  : MessageType(data, length, version)
175  {
176  }
177 
179  void* data,
180  EncodedLength length,
182  SchemaVersion version)
183  : MessageType(data, length, version)
184  {
185  }
186 
188  void* data,
189  EncodedLength length,
191  : MessageType(data, length)
192  {
193  }
194 
196  void* data,
197  EncodedLength length,
201  : MessageType(
202  data,
203  length,
204  SbeMessage::NoInit(),
205  SbeMessage::NoCheck())
206  {
207  }
208 };
209 
210 /// \return a human-readable presentation.
211 template <typename, size_t, typename>
213 template <
214  template <typename, size_t, typename> class HolderType,
215  typename MsgType,
216  size_t MaxMessageSize,
217  typename MessageInitializer>
218 inline void toStr(
219  std::string& str,
220  const HolderType<MsgType, MaxMessageSize, MessageInitializer>& holder)
221 {
222  str += "MessageHolder[";
223 
224  str += "BufferSize=";
225  toStr(str, holder.BufferSize);
226 
227  str += ", MessageInitializer=";
228  str += MessageInitializer::name();
229 
230  str += ", ";
231  toStr(str, *holder.header());
232 
233  str += ", ";
234  toStr(str, holder.message());
235 
236  str += "]";
237 }
238 
239 /// \private
240 ONIXS_ILINK3_CONST_OR_CONSTEXPR char magicDebugValue = 0x5A;
241 
242 /// Default maximum number of repeating group items.
244 
245 /**
246  * Contains the SimpleOpenFramingHeader, the SBE message, and the data buffer.
247  */
248 template <
249  typename MessageTypeT,
250  size_t MaxMessageSize =
251  GetMaxMessageSize<typename HeldAdapter<MessageTypeT>::SbeType, DefaultMaxGroupItems>::Size,
252  typename MessageInitializer = FieldsInitPolicy>
253 class MessageHolder
254 {
255  typedef typename HeldAdapter<MessageTypeT>::SbeType SbeType;
256 
257  ONIXS_ILINK3_STATIC_ASSERT_MSG(
258  (MaxMessageSize >= sizeof(MessageHeader)),
259  "MaxMessageSize template parameter is too small");
260 
261  ONIXS_ILINK3_STATIC_ASSERT_MSG(
262  (MaxMessageSize >= GetMinMessageSize<SbeType>::Size),
263  "The buffer can not fit the message");
264 
265  ONIXS_ILINK3_STATIC_ASSERT_MSG(
266  (MaxMessageSize <= MaxILink3MessageSize),
267  "The buffer is too large.");
268 
269 public:
270  /// Message type.
271  typedef HeldAdapter<MessageTypeT> MessageType;
272 
273  /// Size of the data buffer.
274  enum
275  {
276  BufferSize = MaxMessageSize + sizeof(SimpleOpenFramingHeader)
277  };
278 
279  explicit MessageHolder(SchemaVersion version = SbeType::Schema::Version)
280  {
281  init(version);
282  }
283 
284  explicit MessageHolder(const Session& session)
285  {
286  init(getMessagingVersion(session));
287  }
288 
290  {
291  copyFrom(r);
292  }
293 
295  {
296  copyFrom(r);
297  return *this;
298  }
299 
300  /// \return the buffer.
301  const unsigned char* buffer() const ONIXS_ILINK3_NOTHROW
302  {
303  return buffer_;
304  }
305 
306  /// \return the used size of the buffer.
308  {
309  return header()->size();
310  }
311 
312  /// \return the SBE message.
314  {
315  return message_;
316  }
317 
318  /// \return the SBE message.
319  const MessageType& message() const ONIXS_ILINK3_NOTHROW
320  {
321  return message_;
322  }
323 
324  /// \return the SBE message size
326  {
327  return bufferSize() - sizeof(SimpleOpenFramingHeader);
328  }
329 
331  {
332  return &message();
333  }
334 
335  const MessageType* operator->() const ONIXS_ILINK3_NOTHROW
336  {
337  return &message();
338  }
339 
340  const MessageType& operator* () const ONIXS_ILINK3_NOTHROW
341  {
342  return message();
343  }
344 
345  MessageType& operator* () ONIXS_ILINK3_NOTHROW
346  {
347  return message();
348  }
349 
350  /// \return Simple Open Framing Header
352  {
353  return reinterpret_cast<const SimpleOpenFramingHeader*>(buffer_);
354  }
355 
356  /// \return Simple Open Framing Header
358  {
359  return reinterpret_cast<SimpleOpenFramingHeader*>(buffer_);
360  }
361 
362  /// Calculates the binary size of the message and updates
363  /// the Simple Open Framing Header accordingly.
364  ///
365  /// \return SBE message size
367  {
368  const MessageSize calculatedMessageSize =
369  message().calculateBinarySize();
370 
371  assert(calculatedMessageSize <= MaxMessageSize);
372 
373  assert(
374  calculatedMessageSize >=
375  SbeType::blockLength(message().version()) +
377  SbeType::getMinimalVariableFieldsSize(message().version()));
378 
379  messageSize(calculatedMessageSize);
380  return calculatedMessageSize;
381  }
382 
383  ///
385  {
386  setHeader();
387 
388 #ifndef NDEBUG
389  NetworkMessage(buffer_, BufferSize);
390 #endif
391  return NetworkMessage(buffer_, BufferSize, SbeMessage::NoCheck());
392  }
393 
394  /// \return a human-readable presentation.
396  std::string toString() const
397  {
398  return toStr(*this);
399  }
400 
401 private:
402  void init(SchemaVersion version)
403  {
404 #ifdef ONIXS_ILINK3_MEMCHECK_DEBUG
405  std::memset(buffer_, magicDebugValue, BufferSize);
406 #endif
407  messageSize(0);
408 
409  message_ = MessageInitializer::template createMessage<MessageType>(
410  buffer_ + sizeof(SimpleOpenFramingHeader), MaxMessageSize, version);
411  }
412 
413  void messageSize(UInt16 size) ONIXS_ILINK3_NOTHROW
414  {
415  header()->setup(
416  size + sizeof(SimpleOpenFramingHeader));
417  }
418 
419  void copyFrom(const MessageHolder& r)
420  {
421 #ifdef ONIXS_ILINK3_MEMCHECK_DEBUG
422  std::memset(buffer_, magicDebugValue, BufferSize);
423 #endif
424 
425  const size_t sizeToCopy = r.message_.MessageType::calculateBinarySize() + sizeof(SimpleOpenFramingHeader);
426 
427  assert(r.message_.calculateBinarySize() <= MaxMessageSize);
428 
429  std::memcpy(
430  buffer_,
431  r.buffer_,
432  sizeToCopy);
433 
434  message_ =
435  MessageType(
436  buffer_ + sizeof(SimpleOpenFramingHeader),
437  MaxMessageSize,
440  }
441 
442 private:
443  MessageType message_;
444  unsigned char buffer_[BufferSize];
445 };
446 
447 template <
448  template <typename, size_t, typename> class HolderType,
449  typename MsgType,
450  size_t MaxMessageSize,
451  typename MessageInitializer>
452 inline std::string toStr(
453  const HolderType<MsgType, MaxMessageSize, MessageInitializer>& holder)
454 {
455  std::string res;
456  toStr(res, holder);
457  return res;
458 }
459 
460 template <
461  template <typename, size_t, typename> class HolderType,
462  typename MsgType,
463  size_t MaxMessageSize,
464  typename MessageInitializer>
465 std::ostream& operator<<(
466  std::ostream& stream,
467  const HolderType<MsgType, MaxMessageSize, MessageInitializer>& rhs)
468 {
469  return stream << toStr(rhs);
470 }
471 
HeldAdapter(void *data, EncodedLength length, SbeMessage::NoFieldsInit, SchemaVersion version)
An iLink 3 Session.
Definition: Session.h:47
The policy to create messages without initialized optional fields.
Definition: MessageHolder.h:66
#define ONIXS_ILINK3_CONST_OR_CONSTEXPR
Definition: Compiler.h:178
const unsigned char * buffer() const noexcept
HeldAdapter(void *data, EncodedLength length, SbeMessage::NoInit, SbeMessage::NoCheck) noexcept
Contains the SimpleOpenFramingHeader, the SBE message, and the data buffer.
std::string toStr(const HolderType< MsgType, MaxMessageSize, MessageInitializer > &holder)
HeldAdapter< MessageTypeT > MessageType
Message type.
const MessageType & message() const noexcept
SimpleOpenFramingHeader * header() noexcept
const MessageType * operator->() const noexcept
HeldAdapter(void *data, EncodedLength length, SbeMessage::NoInit)
MessageHeader::Version SchemaVersion
SBE-encoded data version type.
Definition: SchemaTraits.h:30
Template ID and length of message root.
Definition: Composites.h:204
HeldAdapter(void *data, EncodedLength length, SbeMessage::NoInit)
#define ONIXS_ILINK3_EXPORTED_CLASS
Definition: ABI.h:44
UInt16 UInt16
uInt16.
Definition: Fields.h:296
Definition: Defines.h:40
#define ONIXS_ILINK3_DEFAULT
Definition: Compiler.h:202
MessageSize setHeader() noexcept
Calculates the binary size of the message and updates the Simple Open Framing Header accordingly...
constexpr UInt8 DefaultMaxGroupItems
Default maximum number of repeating group items.
Messaging::SchemaVersion getMessagingVersion(const Session &) noexcept
#define ONIXS_ILINK3_MESSAGING_NAMESPACE_END
Definition: ABI.h:144
MessageHolder & operator=(const MessageHolder &r)
#define ONIXS_ILINK3_EXPORTED
Definition: Compiler.h:175
std::ostream & operator<<(std::ostream &o, SessionStateId::Enum state)
#define ONIXS_ILINK3_FINAL
Definition: Compiler.h:181
UInt16 MessageSize
Message length type.
Definition: Aliases.h:29
constexpr UInt16 MaxILink3MessageSize
Maximum supported message size.
HeldAdapter(void *data, EncodedLength length, SbeMessage::NoFieldsInit, SchemaVersion version)
The policy to create messages with null-initialized optional fields.
Definition: MessageHolder.h:48
#define ONIXS_ILINK3_MESSAGING_NAMESPACE_BEGIN
Definition: ABI.h:140
MessageHolder(SchemaVersion version=SbeType::Schema::Version)
const SimpleOpenFramingHeader * header() const noexcept
#define ONIXS_ILINK3_NODISCARD
Definition: Compiler.h:185
#define ONIXS_ILINK3_NOTHROW
Definition: Compiler.h:176
NetworkMessage toNetworkMessage() noexcept
HeldAdapter(void *data, EncodedLength length, SbeMessage::NoInit, SbeMessage::NoCheck) noexcept