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
38namespace FIX
39{
40
41class Header : public FieldMap
42{
43 enum { REQUIRED_FIELDS = 8 };
44
45public:
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
76class Trailer : public FieldMap
77{
78 enum { REQUIRED_FIELDS = 1 };
79
80public:
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
117class Message : public FieldMap
118{
119 friend class DataDictionary;
120 friend class Session;
121
123
124public:
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
183protected:
184 // Constructor for derived classes
185 Message( const BeginString& beginString, const MsgType& msgType );
186
187public:
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; }
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()
289 { return m_header.isEmpty() && FieldMap::isEmpty() && m_trailer.isEmpty(); }
290
291 void clear()
292 {
293 m_tag = 0;
294 m_validStructure = true;
295 m_header.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
373private:
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
396protected:
400 int m_tag;
401#ifdef HAVE_EMX
402 std::string m_subMsgType;
403#endif
404 static SmartPtr<DataDictionary> s_dataDictionary;
405};
408inline 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
417inline MsgType identifyType( const std::string& message )
418throw( 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
Represents a data dictionary for a version of FIX.
bool isDataField(int field) const
Base representation of all Field classes.
Definition Field.h:50
Stores and organizes a collection of Fields.
Definition FieldMap.h:47
void replaceGroup(int num, int tag, const FieldMap &group)
Replace a specific instance of a group.
Definition FieldMap.cpp:102
bool isEmpty()
Check if map contains any fields.
Definition FieldMap.cpp:196
int calculateLength(int beginStringField=FIELD::BeginString, int bodyLengthField=FIELD::BodyLength, int checkSumField=FIELD::CheckSum) const
Definition FieldMap.cpp:233
void clear()
Clear all fields from the map.
Definition FieldMap.cpp:182
bool hasGroup(int tag) const
Check to see any instance of a group exists.
Definition FieldMap.cpp:168
bool getFieldIfSet(FieldBase &field) const
Get a field if set.
Definition FieldMap.h:146
void addGroup(int tag, const FieldMap &group, bool setCount=true)
Add a group.
Definition FieldMap.cpp:83
int calculateTotal(int checkSumField=FIELD::CheckSum) const
Definition FieldMap.cpp:258
void removeGroup(int num, int tag)
Remove a specific instance of a group.
Definition FieldMap.cpp:111
FieldMap & getGroup(int num, int tag, FieldMap &group) const
Get a specific instance of a group.
Definition FieldMap.h:207
Base class for all FIX repeating groups.
Definition Group.h:41
int field() const
Definition Group.h:56
Group & getGroup(unsigned num, FIX::Group &group) const
Definition Message.h:58
@ REQUIRED_FIELDS
Definition Message.h:43
bool hasGroup(unsigned num, const FIX::Group &group) const
Definition Message.h:71
void addGroup(const FIX::Group &group)
Definition Message.h:52
Header(const message_order &order)
Definition Message.h:49
void removeGroup(unsigned num, const FIX::Group &group)
Definition Message.h:64
void replaceGroup(unsigned num, const FIX::Group &group)
Definition Message.h:55
bool hasGroup(const FIX::Group &group) const
Definition Message.h:69
void removeGroup(const FIX::Group &group)
Definition Message.h:66
Base class for all FIX messages.
Definition Message.h:118
Group & getGroup(unsigned num, FIX::Group &group) const
Definition Message.h:167
void clear()
Definition Message.h:291
SessionID getSessionID(const std::string &qualifier="") const
Returns the session ID of the intended recipient.
Definition Message.cpp:576
static bool InitializeXML(const std::string &string)
Set global data dictionary for encoding messages into XML.
Definition Message.cpp:139
int bodyLength(int beginStringField=FIELD::BeginString, int bodyLengthField=FIELD::BodyLength, int checkSumField=FIELD::CheckSum) const
Definition Message.h:258
Trailer m_trailer
Definition Message.h:398
void removeGroup(unsigned num, const FIX::Group &group)
Definition Message.h:173
void validate() const
Definition Message.cpp:597
static bool isHeaderField(int field)
Definition Message.cpp:497
static bool IsDataField(int field, const DataDictionary *pSessionDD, const DataDictionary *pAppDD)
Definition Message.h:379
void setString(const std::string &string, bool validate)
Definition Message.h:218
const Trailer & getTrailer() const
Getter for the message trailer.
Definition Message.h:249
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:475
static bool isTrailerField(int field)
Definition Message.cpp:550
static ApplVerID toApplVerID(const BeginString &value)
Definition Message.h:307
bool isApp() const
Definition Message.h:280
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:215
static BeginString toBeginString(const ApplVerID &applVerID)
Definition Message.h:328
Header & getHeader()
Mutable getter for the message header.
Definition Message.h:247
static bool isAdminMsgType(const MsgType &msgType)
Definition Message.h:300
std::string toXMLFields(const FieldMap &fields, int space) const
Definition Message.cpp:295
friend class DataDictionary
Definition Message.h:119
std::string toXML() const
Get a XML representation of the message.
Definition Message.cpp:270
bool m_validStructure
Definition Message.h:399
int checkSum(int checkSumField=FIELD::CheckSum) const
Definition Message.h:266
void setString(const std::string &string, bool validate, const FIX::DataDictionary *pDataDictionary)
Definition Message.h:221
Trailer & getTrailer()
Mutable getter for the message trailer.
Definition Message.h:251
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:236
void setSessionID(const SessionID &sessionID)
Sets the session ID of the intended recipient.
Definition Message.cpp:590
static SmartPtr< DataDictionary > s_dataDictionary
Definition Message.h:404
void removeGroup(const FIX::Group &group)
Definition Message.h:175
bool hasValidStructure(int &tag) const
Definition Message.h:253
void reverseRoute(const Header &)
Add header informations depending on a source message.
Definition Message.cpp:150
bool isEmpty()
Definition Message.h:288
Header m_header
Definition Message.h:397
void replaceGroup(unsigned num, const FIX::Group &group)
Definition Message.h:164
bool hasGroup(const FIX::Group &group) const
Definition Message.h:178
const Header & getHeader() const
Getter for the message header.
Definition Message.h:245
void addGroup(const FIX::Group &group)
Definition Message.h:161
bool hasGroup(unsigned num, const FIX::Group &group) const
Definition Message.h:180
bool isAdmin() const
Definition Message.h:272
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:639
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:431
Maintains the state and implements the logic of a FIX session.
Definition Session.h:46
Unique session id consists of BeginString, SenderCompID and TargetCompID.
Definition SessionID.h:31
void addGroup(const FIX::Group &group)
Definition Message.h:87
Trailer(const message_order &order)
Definition Message.h:84
void replaceGroup(unsigned num, const FIX::Group &group)
Definition Message.h:90
bool hasGroup(const FIX::Group &group) const
Definition Message.h:104
void removeGroup(const FIX::Group &group)
Definition Message.h:101
Group & getGroup(unsigned num, FIX::Group &group) const
Definition Message.h:93
@ REQUIRED_FIELDS
Definition Message.h:78
bool hasGroup(unsigned num, const FIX::Group &group) const
Definition Message.h:106
void removeGroup(unsigned num, const FIX::Group &group)
Definition Message.h:99
const char BeginString_FIX41[]
Definition Values.h:35
const char BeginString_FIX40[]
Definition Values.h:36
const char BeginString_FIX42[]
Definition Values.h:34
const char BeginString_FIX50[]
Definition Values.h:31
const char BeginString_FIX43[]
Definition Values.h:33
const char BeginString_FIX44[]
Definition Values.h:32
MsgType identifyType(const std::string &message)
Parse the type of a message from a string.
Definition Message.h:417
Field not found inside a message.
Definition Exceptions.h:58
Not a recognizable message.
Definition Exceptions.h:81
Unable to parse message.
Definition Exceptions.h:74
Sorts fields in header, normal, or trailer order.

Generated on Thu May 22 2025 08:23:50 for QuickFIX by doxygen 1.9.8 written by Dimitri van Heesch, © 1997-2001