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 static int const headerOrder[] =
41  {
45  };
46 
47 class Header : public FieldMap
48 {
49 public:
51  {}
52 };
53 
54 class Trailer : public FieldMap
55 {
56 public:
58  {}
59 };
60 
67 class Message : public FieldMap
68 {
69  friend class DataDictionary;
70  friend class Session;
71 
72  enum field_type { header, body, trailer };
73 
74 public:
75  Message();
76 
78  Message( const std::string& string, bool validate = true )
79  throw( InvalidMessage );
80 
82  Message( const std::string& string, const FIX::DataDictionary& dataDictionary,
83  bool validate = true )
84  throw( InvalidMessage );
85 
87  Message( const std::string& string, const FIX::DataDictionary& sessionDataDictionary,
88  const FIX::DataDictionary& applicationDataDictionary, bool validate = true )
89  throw( InvalidMessage );
90 
91  Message( const Message& copy )
92  : FieldMap( copy )
93  {
94  m_header = copy.m_header;
95  m_trailer = copy.m_trailer;
96  m_validStructure = copy.m_validStructure;
97  m_field = copy.m_field;
98  }
99 
101  static bool InitializeXML( const std::string& string );
102 
103  void addGroup( const FIX::Group& group )
104  { FieldMap::addGroup( group.field(), group ); }
105 
106  void replaceGroup( unsigned num, const FIX::Group& group )
107  { FieldMap::replaceGroup( num, group.field(), group ); }
108 
109  Group& getGroup( unsigned num, FIX::Group& group ) const throw( FieldNotFound )
110  { group.clear();
111  return static_cast < Group& >
112  ( FieldMap::getGroup( num, group.field(), group ) );
113  }
114 
115  void removeGroup( unsigned num, const FIX::Group& group )
116  { FieldMap::removeGroup( num, group.field() ); }
117  void removeGroup( const FIX::Group& group )
118  { FieldMap::removeGroup( group.field() ); }
119 
120  bool hasGroup( const FIX::Group& group ) const
121  { return FieldMap::hasGroup( group.field() ); }
122  bool hasGroup( unsigned num, const FIX::Group& group ) const
123  { return FieldMap::hasGroup( num, group.field() ); }
124 
125 protected:
126  // Constructor for derived classes
127  Message( const BeginString& beginString, const MsgType& msgType )
128  : m_validStructure( true )
129  {
130  m_header.setField( beginString );
131  m_header.setField( msgType );
132  }
133 
134 public:
136  std::string toString( int beginStringField = FIELD::BeginString,
137  int bodyLengthField = FIELD::BodyLength,
138  int checkSumField = FIELD::CheckSum ) const;
140  std::string& toString( std::string&,
141  int beginStringField = FIELD::BeginString,
142  int bodyLengthField = FIELD::BodyLength,
143  int checkSumField = FIELD::CheckSum ) const;
145  std::string toXML() const;
147  std::string& toXML( std::string& ) const;
148 
154  void reverseRoute( const Header& );
155 
162  void setString( const std::string& string )
163  throw( InvalidMessage )
164  { setString(string, true); }
165  void setString( const std::string& string, bool validate )
166  throw( InvalidMessage )
167  { setString(string, validate, 0); }
168  void setString( const std::string& string,
169  bool validate,
170  const FIX::DataDictionary* pDataDictionary )
171  throw( InvalidMessage )
172  { setString(string, validate, pDataDictionary, pDataDictionary); }
173 
174  void setString( const std::string& string,
175  bool validate,
176  const FIX::DataDictionary* pSessionDataDictionary,
177  const FIX::DataDictionary* pApplicationDataDictionary )
178  throw( InvalidMessage );
179 
180  void setGroup( const std::string& msg, const FieldBase& field,
181  const std::string& string, std::string::size_type& pos,
182  FieldMap& map, const DataDictionary& dataDictionary );
183 
189  bool setStringHeader( const std::string& string );
190 
192  const Header& getHeader() const { return m_header; }
194  Header& getHeader() { return m_header; }
196  const Trailer& getTrailer() const { return m_trailer; }
198  Trailer& getTrailer() { return m_trailer; }
199 
200  bool hasValidStructure(int& field) const
201  { field = m_field;
202  return m_validStructure;
203  }
204 
205  int bodyLength( int beginStringField = FIELD::BeginString,
206  int bodyLengthField = FIELD::BodyLength,
207  int checkSumField = FIELD::CheckSum ) const
208  { return m_header.calculateLength(beginStringField, bodyLengthField, checkSumField)
209  + calculateLength(beginStringField, bodyLengthField, checkSumField)
210  + m_trailer.calculateLength(beginStringField, bodyLengthField, checkSumField);
211  }
212 
213  int checkSum( int checkSumField = FIELD::CheckSum ) const
214  { return ( m_header.calculateTotal(checkSumField)
215  + calculateTotal(checkSumField)
216  + m_trailer.calculateTotal(checkSumField) ) % 256;
217  }
218 
219  bool isAdmin() const
220  {
221  if( m_header.isSetField(FIELD::MsgType) )
222  {
223  const MsgType& msgType = FIELD_GET_REF( m_header, MsgType );
224  return isAdminMsgType( msgType );
225  }
226  return false;
227  }
228 
229  bool isApp() const
230  {
231  if( m_header.isSetField(FIELD::MsgType) )
232  {
233  const MsgType& msgType = FIELD_GET_REF( m_header, MsgType );
234  return !isAdminMsgType( msgType );
235  }
236  return false;
237  }
238 
239  bool isEmpty()
240  { return m_header.isEmpty() && FieldMap::isEmpty() && m_trailer.isEmpty(); }
241 
242  void clear()
243  {
244  m_field = 0;
245  m_header.clear();
246  FieldMap::clear();
247  m_trailer.clear();
248  }
249 
250  static bool isAdminMsgType( const MsgType& msgType )
251  { if ( msgType.getValue().length() != 1 ) return false;
252  return strchr
253  ( "0A12345",
254  msgType.getValue().c_str() [ 0 ] ) != 0;
255  }
256 
257  static ApplVerID toApplVerID(const BeginString& value)
258  {
259  if( value == BeginString_FIX40 )
260  return ApplVerID(ApplVerID_FIX40);
261  if( value == BeginString_FIX41 )
262  return ApplVerID(ApplVerID_FIX41);
263  if( value == BeginString_FIX42 )
264  return ApplVerID(ApplVerID_FIX42);
265  if( value == BeginString_FIX43 )
266  return ApplVerID(ApplVerID_FIX43);
267  if( value == BeginString_FIX44 )
268  return ApplVerID(ApplVerID_FIX44);
269  if( value == BeginString_FIX50 )
270  return ApplVerID(ApplVerID_FIX50);
271  if( value == "FIX.5.0SP1" )
273  if( value == "FIX.5.0SP2" )
275  return ApplVerID(ApplVerID(value));
276  }
277 
278  static BeginString toBeginString( const ApplVerID& applVerID )
279  {
280  if( applVerID == ApplVerID_FIX40 )
282  else if( applVerID == ApplVerID_FIX41 )
284  else if( applVerID == ApplVerID_FIX42 )
286  else if( applVerID == ApplVerID_FIX43 )
288  else if( applVerID == ApplVerID_FIX44 )
290  else if( applVerID == ApplVerID_FIX50 )
292  else if( applVerID == ApplVerID_FIX50SP1 )
294  else if( applVerID == ApplVerID_FIX50SP2 )
296  else
297  return BeginString("");
298  }
299 
300  static bool isHeaderField( int field );
301  static bool isHeaderField( const FieldBase& field,
302  const DataDictionary* pD = 0 );
303 
304  static bool isTrailerField( int field );
305  static bool isTrailerField( const FieldBase& field,
306  const DataDictionary* pD = 0 );
307 
309  SessionID getSessionID( const std::string& qualifier = "" ) const
310  throw( FieldNotFound );
312  void setSessionID( const SessionID& sessionID );
313 
314 private:
315  FieldBase extractField(
316  const std::string& string, std::string::size_type& pos,
317  const DataDictionary* pSessionDD = 0, const DataDictionary* pAppDD = 0,
318  const Group* pGroup = 0);
319 
320  static bool IsDataField(
321  int field,
322  const DataDictionary* pSessionDD,
323  const DataDictionary* pAppDD )
324  {
325  if( (pSessionDD && pSessionDD->isDataField( field )) ||
326  (pAppDD && pAppDD != pSessionDD && pAppDD->isDataField( field )) )
327  {
328  return true;
329  }
330 
331  return false;
332  }
333 
334  void validate();
335  std::string toXMLFields(const FieldMap& fields, int space) const;
336 
337 protected:
338  mutable Header m_header;
341  int m_field;
342  static std::auto_ptr<DataDictionary> s_dataDictionary;
343 };
346 inline std::ostream& operator <<
347 ( std::ostream& stream, const Message& message )
348 {
349  std::string str;
350  stream << message.toString( str );
351  return stream;
352 }
353 
355 inline MsgType identifyType( const std::string& message )
356 throw( MessageParseError )
357 {
358  std::string::size_type pos = message.find( "\001" "35=" );
359  if ( pos == std::string::npos ) throw MessageParseError();
360 
361  std::string::size_type startValue = pos + 4;
362  std::string::size_type soh = message.find_first_of( '\001', startValue );
363  if ( soh == std::string::npos ) throw MessageParseError();
364 
365  std::string value = message.substr( startValue, soh - startValue );
366  return MsgType( value );
367 }
368 }
369 
370 #endif //FIX_MESSAGE
const int ApplVerID
int checkSum(int checkSumField=FIELD::CheckSum) const
Definition: Message.h:213
Group & getGroup(unsigned num, FIX::Group &group) const
Definition: Message.h:109
int calculateTotal(int checkSumField=FIELD::CheckSum) const
Definition: FieldMap.cpp:218
bool hasGroup(int field) const
Check to see any instance of a group exists.
Definition: FieldMap.cpp:129
const char BeginString_FIX44[]
Definition: Values.h:32
static bool isAdminMsgType(const MsgType &msgType)
Definition: Message.h:250
Trailer & getTrailer()
Mutable getter for the message trailer.
Definition: Message.h:198
static bool IsDataField(int field, const DataDictionary *pSessionDD, const DataDictionary *pAppDD)
Definition: Message.h:320
Message(const Message &copy)
Definition: Message.h:91
const char ApplVerID_FIX44[]
Definition: FixValues.h:816
Represents a data dictionary for a version of FIX.
const char BeginString_FIX42[]
Definition: Values.h:34
Maintains the state and implements the logic of a FIX session.
Definition: Session.h:45
Unable to parse message.
Definition: Exceptions.h:73
bool isApp() const
Definition: Message.h:229
bool isDataField(int field) const
static ApplVerID toApplVerID(const BeginString &value)
Definition: Message.h:257
void removeGroup(int num, int field)
Remove a specific instance of a group.
Definition: FieldMap.cpp:86
const char BeginString_FIX50[]
Definition: Values.h:31
void replaceGroup(unsigned num, const FIX::Group &group)
Definition: Message.h:106
void setString(const std::string &string, bool validate)
Definition: Message.h:165
bool isEmpty()
Definition: Message.h:239
int field() const
Definition: Group.h:56
const char BeginString_FIX43[]
Definition: Values.h:33
Definition: Acceptor.cpp:34
const Header & getHeader() const
Getter for the message header.
Definition: Message.h:192
Base class for all FIX repeating groups.
Definition: Group.h:40
Stores and organizes a collection of Fields.
Definition: FieldMap.h:46
const char ApplVerID_FIX40[]
Definition: FixValues.h:811
void removeGroup(unsigned num, const FIX::Group &group)
Definition: Message.h:115
int bodyLength(int beginStringField=FIELD::BeginString, int bodyLengthField=FIELD::BodyLength, int checkSumField=FIELD::CheckSum) const
Definition: Message.h:205
const Trailer & getTrailer() const
Getter for the message trailer.
Definition: Message.h:196
bool isEmpty()
Check if map contains any fields.
Definition: FieldMap.cpp:157
bool hasGroup(unsigned num, const FIX::Group &group) const
Definition: Message.h:122
const char ApplVerID_FIX43[]
Definition: FixValues.h:815
Base class for all FIX messages.
Definition: Message.h:67
Field not found inside a message.
Definition: Exceptions.h:57
int calculateLength(int beginStringField=FIELD::BeginString, int bodyLengthField=FIELD::BodyLength, int checkSumField=FIELD::CheckSum) const
Definition: FieldMap.cpp:194
const char ApplVerID_FIX50SP1[]
Definition: FixValues.h:807
bool hasGroup(const FIX::Group &group) const
Definition: Message.h:120
Header & getHeader()
Mutable getter for the message header.
Definition: Message.h:194
const char BeginString_FIX41[]
Definition: Values.h:35
void addGroup(const FIX::Group &group)
Definition: Message.h:103
void addGroup(int field, const FieldMap &group, bool setCount=true)
Add a group.
Definition: FieldMap.cpp:58
void removeGroup(const FIX::Group &group)
Definition: Message.h:117
int m_field
Definition: Message.h:341
static std::auto_ptr< DataDictionary > s_dataDictionary
Definition: Message.h:342
Base representation of all Field classes.
Definition: Field.h:45
Sorts fields in header, normal, or trailer order.
void clear()
Definition: Message.h:242
Header m_header
Definition: Message.h:338
const int BeginString
Unique session id consists of BeginString, SenderCompID and TargetCompID.
Definition: SessionID.h:30
const char BeginString_FIX40[]
Definition: Values.h:36
MsgType identifyType(const std::string &message)
Parse the type of a message from a string.
Definition: Message.h:355
const char ApplVerID_FIX50SP2[]
Definition: FixValues.h:809
const char ApplVerID_FIX42[]
Definition: FixValues.h:814
Not a recognizable message.
Definition: Exceptions.h:80
bool hasValidStructure(int &field) const
Definition: Message.h:200
const int BodyLength
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:162
#define FIELD_GET_REF(MAP, FLD)
Definition: FieldMap.h:238
Message(const BeginString &beginString, const MsgType &msgType)
Definition: Message.h:127
void replaceGroup(int num, int field, const FieldMap &group)
Replace a specific instance of a group.
Definition: FieldMap.cpp:77
const int MsgType
const char ApplVerID_FIX50[]
Definition: FixValues.h:810
bool m_validStructure
Definition: Message.h:340
const int CheckSum
static int const headerOrder[]
Definition: Message.h:40
const char ApplVerID_FIX41[]
Definition: FixValues.h:812
Trailer m_trailer
Definition: Message.h:339
void clear()
Clear all fields from the map.
Definition: FieldMap.cpp:143
static BeginString toBeginString(const ApplVerID &applVerID)
Definition: Message.h:278
bool isAdmin() const
Definition: Message.h:219
void setString(const std::string &string, bool validate, const FIX::DataDictionary *pDataDictionary)
Definition: Message.h:168
FieldMap & getGroup(int num, int field, FieldMap &group) const
Get a specific instance of a group.
Definition: FieldMap.h:163

Generated on Thu Sep 5 2019 11:07:58 for QuickFIX by doxygen 1.8.13 written by Dimitri van Heesch, © 1997-2001