OnixS C++ CBOE CFE Binary Order Entry (BOE) Handler  1.11.0
API documentation
MessagePtr.h
Go to the documentation of this file.
1 /*
2 * Copyright Onix Solutions Limited [OnixS]. All rights reserved.
3 *
4 * This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
5 * and international copyright treaties.
6 *
7 * Access to and use of the software is governed by the terms of the applicable ONIXS Software
8 * Services Agreement (the Agreement) and Customer end user license agreements granting
9 * a non-assignable, non-transferable and non-exclusive license to use the software
10 * for it's own data processing purposes under the terms defined in the Agreement.
11 *
12 * Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
13 * of this source code or associated reference material to any other location for further reproduction
14 * or redistribution, and any amendments to this copyright notice, are expressly prohibited.
15 *
16 * Any reproduction or redistribution for sale or hiring of the Software not in accordance with
17 * the terms of the Agreement is a violation of copyright law.
18  */
19 #pragma once
20 
21 #include <OnixS/CboeCFE/Trading/BOE/Compiler.h>
22 
23 #if ONIXS_BATS_BOE_HAS_GATEWAY_EMULATOR
24 
25 #include <memory>
26 #include <utility>
27 
32 
33 namespace OnixS {
34 namespace CboeCFE {
35 namespace Trading {
36 namespace BOE {
37 namespace Testing {
38 
39 ONIXS_CBOE_CFE_BOE_API
40 ONIXS_BATS_BOE_NORETURN
41 void throwWrongType(MessageType::Enum expected, MessageType::Enum provided);
42 
43 template<class Message>
44 Message typify(const BinaryMessage& message)
45 {
46  return Message(message.binary(), message.binarySize());
47 }
48 
49 /// Message container.
50 template <typename Message>
51 class MessagePtr
52 {
53 public:
54  using Container = std::shared_ptr<UInt8>;
55 
56  /// Creates from the given memory block.
57  MessagePtr(Container&&, MessageSize, MessageType::Enum, SeqNumber);
58 
59  /// Create from another type.
60  template <class AnotherType>
61  explicit MessagePtr(const MessagePtr<AnotherType>& rhs)
62  : type_(rhs.type_)
63  , size_(rhs.size_)
64  , container_(rhs.container_)
65  , message_()
66  , seqNumber_(rhs.seqNumber_)
67  {
68  fromAnotherType(rhs);
69  }
70 
71  /// Creates from the given type.
72  template <class AnotherType>
73  explicit MessagePtr(MessagePtr<AnotherType>&& rhs)
74  : type_(rhs.type_)
75  , size_(rhs.size_)
76  , container_(std::move(rhs.container_))
77  , message_()
78  , seqNumber_(rhs.seqNumber_)
79  {
80  fromAnotherType(rhs);
81  }
82 
83  /// Creates an empty message container.
84  MessagePtr()
85  : type_(MessageType::Undefined)
86  , size_(0)
87  , container_()
88  , message_()
89  , seqNumber_(SeqNumberTraits::InvalidValue)
90  {
91  }
92 
93  MessagePtr(const MessagePtr&) = default;
94  MessagePtr& operator=(const MessagePtr&) = default;
95 
96  ///
97  MessagePtr(MessagePtr&& rhs) noexcept
98  {
99  rhs.swap(*this);
100  rhs.reset();
101  }
102 
103  ///
104  MessagePtr& operator=(MessagePtr&& rhs) noexcept
105  {
106  if (&rhs == this)
107  return *this;
108 
109  rhs.swap(*this);
110  rhs.reset();
111 
112  return *this;
113  }
114 
115  ///
116  bool valid() const noexcept
117  {
118  return static_cast<bool>(message_);
119  }
120 
121  /// \return message sequence number
122  SeqNumber seqNumber() const noexcept
123  {
124  return seqNumber_;
125  }
126 
127  ///
128  void swap(MessagePtr& rhs) noexcept
129  {
130  std::swap(rhs.type_, type_);
131  std::swap(rhs.size_, size_);
132  std::swap(rhs.container_, container_);
133  std::swap(rhs.message_, message_);
134  std::swap(rhs.seqNumber_, seqNumber_);
135  }
136 
137  ///
138  Message* operator->() noexcept
139  {
140  assert(valid());
141  return &message_;
142  }
143 
144  ///
145  const Message* operator->() const noexcept
146  {
147  assert(valid());
148  return &message_;
149  }
150 
151  ///
152  Message& operator*() noexcept
153  {
154  return message_;
155  }
156 
157  ///
158  const Message& operator*() const noexcept
159  {
160  return message_;
161  }
162 
163  /// \return the underlying message.
164  Message& message() noexcept
165  {
166  assert(valid());
167  return message_;
168  }
169 
170  /// \return the underlying message.
171  const Message& message() const noexcept
172  {
173  assert(valid());
174  return message_;
175  }
176 
177  ///
178  operator Message() noexcept
179  {
180  return message();
181  }
182 
183  ///
184  operator const Message() const noexcept
185  {
186  return message();
187  }
188 
189  /// \return the underlying buffer.
190  UInt8* buf() noexcept
191  {
192  return container_.get();
193  }
194 
195  /// Resets the message.
196  void reset() noexcept
197  {
198  type_ = MessageType::Undefined;
199  size_ = 0;
200  container_.reset();
201  message_ = Message();
202  }
203 
204  /// \return the human-readable presentation.
205  std::string toString() const
206  {
207  return toStr(message_);
208  }
209 
210  /// \return message type
211  MessageType::Enum getType() const noexcept
212  {
213  return type_;
214  }
215 
216  Container release()
217  {
218  Container c = container_;
219  reset();
220  return c;
221  }
222 
223 private:
224  template<typename MessageT>
225  static typename MessageType::Enum getMessageType()
226  {
227  return MessageT::type();
228  }
229 
230  template <class AnotherType>
231  void fromAnotherType(const MessagePtr<AnotherType>& rhs)
232  {
233  if(getType() != getMessageType<Message>())
234  throwWrongType(getMessageType<Message>(), getType());
235 
236  message_ = typify<Message>(rhs);
237  }
238 
239 private:
240  MessageType::Enum type_;
241  MessageSize size_;
242  Container container_;
243  Message message_;
244  SeqNumber seqNumber_;
245 
246  template<class T> friend class MessagePtr;
247 };
248 
249 template<>
250 inline MessagePtr<BinaryMessage>::MessagePtr(Container&& container, MessageSize size, MessageType::Enum type, SeqNumber seqNumber)
251  : type_(type)
252  , size_(size)
253  , container_(std::move(container))
254  , message_(container_.get(), size_)
255  , seqNumber_(seqNumber)
256 {
257 }
258 
259 /// Tries to cast to another type.
260 template <BOE::MessageType::Enum AnotherType>
261 MessagePtr<typename MessageTypeTraits<AnotherType>::MessageType> cast(const MessagePtr<BinaryMessage>& ptr)
262 {
263  static_assert(std::is_base_of<BinaryMessage, typename MessageTypeTraits<AnotherType>::MessageType>::value, "");
264  return MessagePtr<typename MessageTypeTraits<AnotherType>::MessageType>(ptr);
265 }
266 
267 using MessageBasePtr = MessagePtr<BinaryMessage>;
268 using NewOrderV2Ptr = MessagePtr<ConstantNewOrderV2>;
269 using ModifyOrderPtr = MessagePtr<ConstantModifyOrder>;
270 using CancelOrderPtr = MessagePtr<ConstantCancelOrder>;
271 using MassCancelOrderPtr = MessagePtr<ConstantMassCancelOrder>;
272 using PurgeOrdersPtr = MessagePtr<ConstantPurgeOrders>;
273 using QuoteUpdatePtr = MessagePtr<ConstantQuoteUpdate>;
274 using ResetRiskPtr = MessagePtr<ConstantResetRisk>;
275 using LoginRequestPtr = MessagePtr<ConstantLoginRequest>;
276 using LogoutRequestPtr = MessagePtr<ConstantLogoutRequest>;
277 using ClientHeartbeatPtr = MessagePtr<ConstantClientHeartbeat>;
278 
279 typedef MessageBasePtr::Container PacketContainer;
280 
281 }}}}}
282 
283 #endif
STL namespace.
Binary2 MessageSize
Aliases message length type.
ONIXS_CBOE_CFE_BOE_API void toStr(std::string &, const ConstantNewOrderV2 &)
Serializes object into string.