Message.h
Go to the documentation of this file.
1 /* -*- C++ -*- */
2 
3 /****************************************************************************
4 ** Copyright (c) 2001-2014
5 **
6 ** This file is part of the QuickFIX FIX Engine
7 **
8 ** This file may be distributed under the terms of the quickfixengine.org
9 ** license as defined by quickfixengine.org and appearing in the file
10 ** LICENSE included in the packaging of this file.
11 **
12 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14 **
15 ** See http://www.quickfixengine.org/LICENSE for licensing information.
16 **
17 ** Contact ask@quickfixengine.org if any conditions of this licensing are
18 ** not clear to you.
19 **
20 ****************************************************************************/
21 
22 #ifndef FIX_MESSAGE
23 #define FIX_MESSAGE
24 
25 #ifdef _MSC_VER
26 #pragma warning( disable: 4786 )
27 #endif
28 
29 #include "FieldMap.h"
30 #include "Fields.h"
31 #include "Group.h"
32 #include "SessionID.h"
33 #include "DataDictionary.h"
34 #include "Values.h"
35 #include <vector>
36 #include <memory>
37 
38 namespace FIX
39 {
40 
41 class Header : public FieldMap
42 {
43  enum { REQUIRED_FIELDS = 8 };
44 
45 public:
46  Header() : FieldMap( message_order( message_order::header ), REQUIRED_FIELDS )
47  {}
48 
49  Header(const message_order & order) : FieldMap(order)
50  {}
51 
52  void addGroup( const FIX::Group& group )
53  { FieldMap::addGroup( group.field(), group ); }
54 
55  void replaceGroup( unsigned num, const FIX::Group& group )
56  { FieldMap::replaceGroup( num, group.field(), group ); }
57 
58  Group& getGroup( unsigned num, FIX::Group& group ) const throw( FieldNotFound )
59  { group.clear();
60  return static_cast < Group& >
61  ( FieldMap::getGroup( num, group.field(), group ) );
62  }
63 
64  void removeGroup( unsigned num, const FIX::Group& group )
65  { FieldMap::removeGroup( num, group.field() ); }
66  void removeGroup( const FIX::Group& group )
67  { FieldMap::removeGroup( group.field() ); }
68 
69  bool hasGroup( const FIX::Group& group ) const
70  { return FieldMap::hasGroup( group.field() ); }
71  bool hasGroup( unsigned num, const FIX::Group& group ) const
72  { return FieldMap::hasGroup( num, group.field() ); }
73 
74 };
75 
76 class Trailer : public FieldMap
77 {
78  enum { REQUIRED_FIELDS = 1 };
79 
80 public:
82  {}
83 
84  Trailer(const message_order & order) : FieldMap(order)
85  {}
86 
87  void addGroup( const FIX::Group& group )
88  { FieldMap::addGroup( group.field(), group ); }
89 
90  void replaceGroup( unsigned num, const FIX::Group& group )
91  { FieldMap::replaceGroup( num, group.field(), group ); }
92 
93  Group& getGroup( unsigned num, FIX::Group& group ) const throw( FieldNotFound )
94  { group.clear();
95  return static_cast < Group& >
96  ( FieldMap::getGroup( num, group.field(), group ) );
97  }
98 
99  void removeGroup( unsigned num, const FIX::Group& group )
100  { FieldMap::removeGroup( num, group.field() ); }
101  void removeGroup( const FIX::Group& group )
102  { FieldMap::removeGroup( group.field() ); }
103 
104  bool hasGroup( const FIX::Group& group ) const
105  { return FieldMap::hasGroup( group.field() ); }
106  bool hasGroup( unsigned num, const FIX::Group& group ) const
107  { return FieldMap::hasGroup( num, group.field() ); }
108 
109 };
110 
117 class Message : public FieldMap
118 {
119  friend class DataDictionary;
120  friend class Session;
121 
122  enum field_type { header, body, trailer };
123 
124 public:
125  Message();
126 
128  Message( const message_order& hdrOrder, const message_order& trlOrder, const message_order& order);
129 
131  Message( const std::string& string, bool validate = true )
132  throw( InvalidMessage );
133 
135  Message( const std::string& string, const FIX::DataDictionary& dataDictionary,
136  bool validate = true )
137  throw( InvalidMessage );
138 
140  Message( const std::string& string, const FIX::DataDictionary& sessionDataDictionary,
141  const FIX::DataDictionary& applicationDataDictionary, bool validate = true )
142  throw( InvalidMessage );
143 
145  Message( const message_order& hdrOrder, const message_order& trlOrder, const message_order& order, const std::string& string, const FIX::DataDictionary& dataDictionary,
146  bool validate = true )
147  throw( InvalidMessage );
148 
150  Message( const message_order& hdrOrder, const message_order& trlOrder, const message_order& order, const std::string& string, const FIX::DataDictionary& sessionDataDictionary,
151  const FIX::DataDictionary& applicationDataDictionary, bool validate = true )
152  throw( InvalidMessage );
153 
154  Message( const Message& copy );
155 
156  ~Message();
157 
159  static bool InitializeXML( const std::string& string );
160 
161  void addGroup( const FIX::Group& group )
162  { FieldMap::addGroup( group.field(), group ); }
163 
164  void replaceGroup( unsigned num, const FIX::Group& group )
165  { FieldMap::replaceGroup( num, group.field(), group ); }
166 
167  Group& getGroup( unsigned num, FIX::Group& group ) const throw( FieldNotFound )
168  { group.clear();
169  return static_cast < Group& >
170  ( FieldMap::getGroup( num, group.field(), group ) );
171  }
172 
173  void removeGroup( unsigned num, const FIX::Group& group )
174  { FieldMap::removeGroup( num, group.field() ); }
175  void removeGroup( const FIX::Group& group )
176  { FieldMap::removeGroup( group.field() ); }
177 
178  bool hasGroup( const FIX::Group& group ) const
179  { return FieldMap::hasGroup( group.field() ); }
180  bool hasGroup( unsigned num, const FIX::Group& group ) const
181  { return FieldMap::hasGroup( num, group.field() ); }
182 
183 protected:
184  // Constructor for derived classes
185  Message( const BeginString& beginString, const MsgType& msgType );
186 
187 public:
189  std::string toString( int beginStringField = FIELD::BeginString,
190  int bodyLengthField = FIELD::BodyLength,
191  int checkSumField = FIELD::CheckSum ) const;
193  std::string& toString( std::string&,
194  int beginStringField = FIELD::BeginString,
195  int bodyLengthField = FIELD::BodyLength,
196  int checkSumField = FIELD::CheckSum ) const;
198  std::string toXML() const;
200  std::string& toXML( std::string& ) const;
201 
207  void reverseRoute( const Header& );
208 
215  void setString( const std::string& string )
216  throw( InvalidMessage )
217  { setString(string, true); }
218  void setString( const std::string& string, bool validate )
219  throw( InvalidMessage )
220  { setString(string, validate, 0); }
221  void setString( const std::string& string,
222  bool validate,
223  const FIX::DataDictionary* pDataDictionary )
224  throw( InvalidMessage )
225  { setString(string, validate, pDataDictionary, pDataDictionary); }
226 
227  void setString( const std::string& string,
228  bool validate,
229  const FIX::DataDictionary* pSessionDataDictionary,
230  const FIX::DataDictionary* pApplicationDataDictionary )
231  throw( InvalidMessage );
232 
233  void setGroup( const std::string& msg, const FieldBase& field,
234  const std::string& string, std::string::size_type& pos,
235  FieldMap& map, const DataDictionary& dataDictionary );
236 
242  bool setStringHeader( const std::string& string );
243 
245  const Header& getHeader() const { return m_header; }
247  Header& getHeader() { return m_header; }
249  const Trailer& getTrailer() const { return m_trailer; }
251  Trailer& getTrailer() { return m_trailer; }
252 
253  bool hasValidStructure(int& tag) const
254  { tag = m_tag;
255  return m_validStructure;
256  }
257 
258  int bodyLength( int beginStringField = FIELD::BeginString,
259  int bodyLengthField = FIELD::BodyLength,
260  int checkSumField = FIELD::CheckSum ) const
261  { return m_header.calculateLength(beginStringField, bodyLengthField, checkSumField)
262  + calculateLength(beginStringField, bodyLengthField, checkSumField)
263  + m_trailer.calculateLength(beginStringField, bodyLengthField, checkSumField);
264  }
265 
266  int checkSum( int checkSumField = FIELD::CheckSum ) const
267  { return ( m_header.calculateTotal(checkSumField)
268  + calculateTotal(checkSumField)
269  + m_trailer.calculateTotal(checkSumField) ) % 256;
270  }
271 
272  bool isAdmin() const
273  {
274  MsgType msgType;
275  if( m_header.getFieldIfSet( msgType ) )
276  return isAdminMsgType( msgType );
277  return false;
278  }
279 
280  bool isApp() const
281  {
282  MsgType msgType;
283  if( m_header.getFieldIfSet( msgType ) )
284  return !isAdminMsgType( msgType );
285  return false;
286  }
287 
288  bool isEmpty()
290 
291  void clear()
292  {
293  m_tag = 0;
294  m_validStructure = true;
295  m_header.clear();
296  FieldMap::clear();
298  }
299 
300  static bool isAdminMsgType( const MsgType& msgType )
301  { if ( msgType.getValue().length() != 1 ) return false;
302  return strchr
303  ( "0A12345",
304  msgType.getValue().c_str() [ 0 ] ) != 0;
305  }
306 
307  static ApplVerID toApplVerID(const BeginString& value)
308  {
309  if( value == BeginString_FIX40 )
310  return ApplVerID(ApplVerID_FIX40);
311  if( value == BeginString_FIX41 )
312  return ApplVerID(ApplVerID_FIX41);
313  if( value == BeginString_FIX42 )
314  return ApplVerID(ApplVerID_FIX42);
315  if( value == BeginString_FIX43 )
316  return ApplVerID(ApplVerID_FIX43);
317  if( value == BeginString_FIX44 )
318  return ApplVerID(ApplVerID_FIX44);
319  if( value == BeginString_FIX50 )
320  return ApplVerID(ApplVerID_FIX50);
321  if( value == "FIX.5.0SP1" )
322  return ApplVerID(ApplVerID_FIX50SP1);
323  if( value == "FIX.5.0SP2" )
324  return ApplVerID(ApplVerID_FIX50SP2);
325  return ApplVerID(ApplVerID(value));
326  }
327 
328  static BeginString toBeginString( const ApplVerID& applVerID )
329  {
330  if( applVerID == ApplVerID_FIX40 )
331  return BeginString(BeginString_FIX40);
332  else if( applVerID == ApplVerID_FIX41 )
333  return BeginString(BeginString_FIX41);
334  else if( applVerID == ApplVerID_FIX42 )
335  return BeginString(BeginString_FIX42);
336  else if( applVerID == ApplVerID_FIX43 )
337  return BeginString(BeginString_FIX43);
338  else if( applVerID == ApplVerID_FIX44 )
339  return BeginString(BeginString_FIX44);
340  else if( applVerID == ApplVerID_FIX50 )
341  return BeginString(BeginString_FIX50);
342  else if( applVerID == ApplVerID_FIX50SP1 )
343  return BeginString(BeginString_FIX50);
344  else if( applVerID == ApplVerID_FIX50SP2 )
345  return BeginString(BeginString_FIX50);
346  else
347  return BeginString("");
348  }
349 
350  static bool isHeaderField( int field );
351  static bool isHeaderField( const FieldBase& field,
352  const DataDictionary* pD = 0 );
353  static bool isHeaderField( int field,
354  const DataDictionary* pD );
355 
356  static bool isTrailerField( int field );
357  static bool isTrailerField( const FieldBase& field,
358  const DataDictionary* pD = 0 );
359  static bool isTrailerField( int field,
360  const DataDictionary* pD );
361 
363  SessionID getSessionID( const std::string& qualifier = "" ) const
364  throw( FieldNotFound );
366  void setSessionID( const SessionID& sessionID );
367 
368 #ifdef HAVE_EMX
369  void setSubMessageType(const std::string & subMsgType) { m_subMsgType.assign(subMsgType); }
370  const std::string & getSubMessageType() const { return m_subMsgType; }
371 #endif
372 
373 private:
374  FieldBase extractField(
375  const std::string& string, std::string::size_type& pos,
376  const DataDictionary* pSessionDD = 0, const DataDictionary* pAppDD = 0,
377  const Group* pGroup = 0) const;
378 
379  static bool IsDataField(
380  int field,
381  const DataDictionary* pSessionDD,
382  const DataDictionary* pAppDD )
383  {
384  if( (pSessionDD && pSessionDD->isDataField( field )) ||
385  (pAppDD && pAppDD != pSessionDD && pAppDD->isDataField( field )) )
386  {
387  return true;
388  }
389 
390  return false;
391  }
392 
393  void validate() const;
394  std::string toXMLFields(const FieldMap& fields, int space) const;
395 
396 protected:
397  mutable Header m_header;
398  mutable Trailer m_trailer;
399  bool m_validStructure;
400  int m_tag;
401 #ifdef HAVE_EMX
402  std::string m_subMsgType;
403 #endif
404  static SmartPtr<DataDictionary> s_dataDictionary;
405 };
408 inline std::ostream& operator <<
409 ( std::ostream& stream, const Message& message )
410 {
411  std::string str;
412  stream << message.toString( str );
413  return stream;
414 }
415 
417 inline MsgType identifyType( const std::string& message )
418 throw( MessageParseError )
419 {
420  std::string::size_type pos = message.find( "\001" "35=" );
421  if ( pos == std::string::npos ) throw MessageParseError();
422 
423  std::string::size_type startValue = pos + 4;
424  std::string::size_type soh = message.find_first_of( '\001', startValue );
425  if ( soh == std::string::npos ) throw MessageParseError();
426 
427  std::string value = message.substr( startValue, soh - startValue );
428  return MsgType( value );
429 }
430 }
431 
432 #endif //FIX_MESSAGE
FIX::FieldMap
Stores and organizes a collection of Fields.
Definition: FieldMap.h:63
SessionID.h
FIX::BeginString_FIX41
const char BeginString_FIX41[]
Definition: Values.h:52
FIX::Message::toApplVerID
static ApplVerID toApplVerID(const BeginString &value)
Definition: Message.h:324
FIX::Header::replaceGroup
void replaceGroup(unsigned num, const FIX::Group &group)
Definition: Message.h:89
Fields.h
FIX::Message::header
@ header
Definition: Message.h:139
FIX::FieldMap::calculateTotal
int calculateTotal(int checkSumField=FIELD::CheckSum) const
Definition: FieldMap.cpp:275
FIX::BeginString_FIX44
const char BeginString_FIX44[]
Definition: Values.h:49
FIX::FieldMap::hasGroup
bool hasGroup(int tag) const
Check to see any instance of a group exists.
Definition: FieldMap.cpp:185
FIX::Header::Header
Header()
Definition: Message.h:80
FIX::BeginString_FIX40
const char BeginString_FIX40[]
Definition: Values.h:53
FIX::Message::DataDictionary
friend class DataDictionary
Definition: Message.h:136
FIX::FieldMap::clear
void clear()
Clear all fields from the map.
Definition: FieldMap.cpp:199
FIX::Message::replaceGroup
void replaceGroup(unsigned num, const FIX::Group &group)
Definition: Message.h:181
FIX::BeginString_FIX42
const char BeginString_FIX42[]
Definition: Values.h:51
FIX::FieldMap::FieldMap
FieldMap(const message_order &order, int size)
Definition: FieldMap.cpp:51
FIX::FieldMap::isEmpty
bool isEmpty()
Check if map contains any fields.
Definition: FieldMap.cpp:213
FIX::Message::trailer
@ trailer
Definition: Message.h:139
FIX::Message::getTrailer
const Trailer & getTrailer() const
Getter for the message trailer.
Definition: Message.h:266
FIX::Message::m_validStructure
bool m_validStructure
Definition: Message.h:416
FIX::Group::field
int field() const
Definition: Group.h:90
FIX::Trailer::hasGroup
bool hasGroup(const FIX::Group &group) const
Definition: Message.h:121
FIX::Message::body
@ body
Definition: Message.h:139
FIX::Trailer::removeGroup
void removeGroup(unsigned num, const FIX::Group &group)
Definition: Message.h:116
FIX::Message::hasGroup
bool hasGroup(const FIX::Group &group) const
Definition: Message.h:195
FIX::Trailer::addGroup
void addGroup(const FIX::Group &group)
Definition: Message.h:104
Values.h
FIX::Message::Message
Message()
Definition: Message.cpp:60
FIX::Message::field_type
field_type
Definition: Message.h:139
FIX::Trailer::getGroup
Group & getGroup(unsigned num, FIX::Group &group) const
Definition: Message.h:110
FIX::Message::toXML
std::string toXML() const
Get a XML representation of the message.
Definition: Message.cpp:287
FIX::FieldMap::getGroup
FieldMap & getGroup(int num, int tag, FieldMap &group) const
Get a specific instance of a group.
Definition: FieldMap.h:241
FIX::FieldMap::getFieldIfSet
bool getFieldIfSet(FieldBase &field) const
Get a field if set.
Definition: FieldMap.h:180
FIX::Message::getSessionID
SessionID getSessionID(const std::string &qualifier="") const
Returns the session ID of the intended recipient.
Definition: Message.cpp:593
FIX::SessionID
Unique session id consists of BeginString, SenderCompID and TargetCompID.
Definition: SessionID.h:47
FIX::BeginString_FIX50
const char BeginString_FIX50[]
Definition: Values.h:48
FIX::Message::toString
std::string toString(int beginStringField=FIELD::BeginString, int bodyLengthField=FIELD::BodyLength, int checkSumField=FIELD::CheckSum) const
Get a string representation of the message.
Definition: Message.cpp:253
FIX::Trailer
Definition: Message.h:93
FIX::Message::clear
void clear()
Definition: Message.h:308
FIX::Message::reverseRoute
void reverseRoute(const Header &)
Add header informations depending on a source message.
Definition: Message.cpp:167
FIX::FieldMap::replaceGroup
void replaceGroup(int num, int tag, const FieldMap &group)
Replace a specific instance of a group.
Definition: FieldMap.cpp:119
FIX::Message::m_trailer
Trailer m_trailer
Definition: Message.h:415
FIX::Message::toBeginString
static BeginString toBeginString(const ApplVerID &applVerID)
Definition: Message.h:345
FIX::Message::isTrailerField
static bool isTrailerField(int field)
Definition: Message.cpp:567
FIX::Message::s_dataDictionary
static SmartPtr< DataDictionary > s_dataDictionary
Definition: Message.h:421
FIX::BeginString_FIX43
const char BeginString_FIX43[]
Definition: Values.h:50
FIX::Message::setStringHeader
bool setStringHeader(const std::string &string)
Set a messages header from a string This is an optimization that can be used to get useful informatio...
Definition: Message.cpp:492
FIX::Message::extractField
FieldBase extractField(const std::string &string, std::string::size_type &pos, const DataDictionary *pSessionDD=0, const DataDictionary *pAppDD=0, const Group *pGroup=0) const
Definition: Message.cpp:656
FIX::Message::isAdmin
bool isAdmin() const
Definition: Message.h:289
FIX::Trailer::replaceGroup
void replaceGroup(unsigned num, const FIX::Group &group)
Definition: Message.h:107
FieldMap.h
FIX::Message::isAdminMsgType
static bool isAdminMsgType(const MsgType &msgType)
Definition: Message.h:317
FIX::Header::REQUIRED_FIELDS
@ REQUIRED_FIELDS
Definition: Message.h:94
FIX::Message::InitializeXML
static bool InitializeXML(const std::string &string)
Set global data dictionary for encoding messages into XML.
Definition: Message.cpp:156
FIX::FieldNotFound
Field not found inside a message.
Definition: Exceptions.h:74
FIX::Message::hasValidStructure
bool hasValidStructure(int &tag) const
Definition: Message.h:270
FIX::Message
Base class for all FIX messages.
Definition: Message.h:134
FIX::Trailer::Trailer
Trailer()
Definition: Message.h:98
FIX::Header::hasGroup
bool hasGroup(const FIX::Group &group) const
Definition: Message.h:103
FIX
Definition: Acceptor.cpp:34
FIX::Message::m_header
Header m_header
Definition: Message.h:414
FIX::DataDictionary
Represents a data dictionary for a version of FIX.
Definition: DataDictionary.h:66
FIX::MessageParseError
Unable to parse message.
Definition: Exceptions.h:90
FIX::Message::toXMLFields
std::string toXMLFields(const FieldMap &fields, int space) const
Definition: Message.cpp:312
FIX::Message::m_tag
int m_tag
Definition: Message.h:417
FIX::Header
Definition: Message.h:58
FIX::Group
Base class for all FIX repeating groups.
Definition: Group.h:57
FIX::Message::isHeaderField
static bool isHeaderField(int field)
Definition: Message.cpp:514
FIX::Header::getGroup
Group & getGroup(unsigned num, FIX::Group &group) const
Definition: Message.h:92
FIX::Message::isApp
bool isApp() const
Definition: Message.h:297
FIX::Message::setString
void setString(const std::string &string)
Set a message based on a string representation This will fill in the fields on the message by parsing...
Definition: Message.h:232
FIX::FieldMap::addGroup
void addGroup(int tag, const FieldMap &group, bool setCount=true)
Add a group.
Definition: FieldMap.cpp:100
FIX::identifyType
MsgType identifyType(const std::string &message)
Parse the type of a message from a string.
Definition: Message.h:434
FIX::Trailer::REQUIRED_FIELDS
@ REQUIRED_FIELDS
Definition: Message.h:95
FIX::Message::setGroup
void setGroup(const std::string &msg, const FieldBase &field, const std::string &string, std::string::size_type &pos, FieldMap &map, const DataDictionary &dataDictionary)
Definition: Message.cpp:448
FIX::Message::setSessionID
void setSessionID(const SessionID &sessionID)
Sets the session ID of the intended recipient.
Definition: Message.cpp:607
FIX::FieldBase
Base representation of all Field classes.
Definition: Field.h:66
FIX::Message::getGroup
Group & getGroup(unsigned num, FIX::Group &group) const
Definition: Message.h:184
FIX::Header::addGroup
void addGroup(const FIX::Group &group)
Definition: Message.h:86
FIX::InvalidMessage
Not a recognizable message.
Definition: Exceptions.h:97
FIX::Message::checkSum
int checkSum(int checkSumField=FIELD::CheckSum) const
Definition: Message.h:283
FIX::FieldMap::removeGroup
void removeGroup(int num, int tag)
Remove a specific instance of a group.
Definition: FieldMap.cpp:128
FIX::message_order
Sorts fields in header, normal, or trailer order.
Definition: MessageSorters.h:130
Group.h
FIX::Header::removeGroup
void removeGroup(unsigned num, const FIX::Group &group)
Definition: Message.h:98
FIX::FieldMap::calculateLength
int calculateLength(int beginStringField=FIELD::BeginString, int bodyLengthField=FIELD::BodyLength, int checkSumField=FIELD::CheckSum) const
Definition: FieldMap.cpp:250
FIX::Message::validate
void validate() const
Definition: Message.cpp:614
FIX::Message::addGroup
void addGroup(const FIX::Group &group)
Definition: Message.h:178
FIX::Message::isEmpty
bool isEmpty()
Definition: Message.h:305
FIX::Message::removeGroup
void removeGroup(unsigned num, const FIX::Group &group)
Definition: Message.h:190
FIX::Message::bodyLength
int bodyLength(int beginStringField=FIELD::BeginString, int bodyLengthField=FIELD::BodyLength, int checkSumField=FIELD::CheckSum) const
Definition: Message.h:275
FIX::Message::getHeader
const Header & getHeader() const
Getter for the message header.
Definition: Message.h:262
FIX::Message::IsDataField
static bool IsDataField(int field, const DataDictionary *pSessionDD, const DataDictionary *pAppDD)
Definition: Message.h:396
FIX::Session
Maintains the state and implements the logic of a FIX session.
Definition: Session.h:62
DataDictionary.h

Generated on Wed Apr 29 2020 19:41:30 for QuickFIX by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2001