Message.h
Go to the documentation of this file.
00001 /* -*- C++ -*- */
00002 
00003 /****************************************************************************
00004 ** Copyright (c) 2001-2014
00005 **
00006 ** This file is part of the QuickFIX FIX Engine
00007 **
00008 ** This file may be distributed under the terms of the quickfixengine.org
00009 ** license as defined by quickfixengine.org and appearing in the file
00010 ** LICENSE included in the packaging of this file.
00011 **
00012 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 **
00015 ** See http://www.quickfixengine.org/LICENSE for licensing information.
00016 **
00017 ** Contact ask@quickfixengine.org if any conditions of this licensing are
00018 ** not clear to you.
00019 **
00020 ****************************************************************************/
00021 
00022 #ifndef FIX_MESSAGE
00023 #define FIX_MESSAGE
00024 
00025 #ifdef _MSC_VER
00026 #pragma warning( disable: 4786 )
00027 #endif
00028 
00029 #include "FieldMap.h"
00030 #include "Fields.h"
00031 #include "Group.h"
00032 #include "SessionID.h"
00033 #include "DataDictionary.h"
00034 #include "Values.h"
00035 #include <vector>
00036 #include <memory>
00037 
00038 namespace FIX
00039 {
00040 static int const headerOrder[] =
00041   {
00042     FIELD::BeginString,
00043     FIELD::BodyLength,
00044     FIELD::MsgType
00045   };
00046 
00047 class Header : public FieldMap 
00048 {
00049 public:
00050   Header() : FieldMap(message_order( message_order::header ) )
00051   {}
00052 };
00053 
00054 class Trailer : public FieldMap 
00055 {
00056 public:
00057   Trailer() : FieldMap(message_order( message_order::trailer ) )
00058   {}
00059 };
00060 
00067 class Message : public FieldMap
00068 {
00069   friend class DataDictionary;
00070   friend class Session;
00071 
00072   enum field_type { header, body, trailer };
00073 
00074 public:
00075   Message();
00076 
00078   Message( const std::string& string, bool validate = true )
00079   throw( InvalidMessage );
00080 
00082   Message( const std::string& string, const FIX::DataDictionary& dataDictionary,
00083            bool validate = true )
00084   throw( InvalidMessage );
00085 
00087   Message( const std::string& string, const FIX::DataDictionary& sessionDataDictionary,
00088            const FIX::DataDictionary& applicationDataDictionary, bool validate = true )
00089   throw( InvalidMessage );
00090 
00091   Message( const Message& copy )
00092   : FieldMap( copy )
00093   {
00094     m_header = copy.m_header;
00095     m_trailer = copy.m_trailer;
00096     m_validStructure = copy.m_validStructure;
00097     m_field = copy.m_field;
00098   }
00099 
00101   static bool InitializeXML( const std::string& string );
00102 
00103   void addGroup( const FIX::Group& group )
00104   { FieldMap::addGroup( group.field(), group ); }
00105 
00106   void replaceGroup( unsigned num, const FIX::Group& group )
00107   { FieldMap::replaceGroup( num, group.field(), group ); }
00108 
00109   Group& getGroup( unsigned num, FIX::Group& group ) const throw( FieldNotFound )
00110   { group.clear();
00111     return static_cast < Group& >
00112       ( FieldMap::getGroup( num, group.field(), group ) );
00113   }
00114 
00115   void removeGroup( unsigned num, const FIX::Group& group )
00116   { FieldMap::removeGroup( num, group.field() ); }
00117   void removeGroup( const FIX::Group& group )
00118   { FieldMap::removeGroup( group.field() ); }
00119 
00120   bool hasGroup( const FIX::Group& group ) const
00121   { return FieldMap::hasGroup( group.field() ); }
00122   bool hasGroup( unsigned num, const FIX::Group& group ) const
00123   { return FieldMap::hasGroup( num, group.field() ); }
00124 
00125 protected:
00126   // Constructor for derived classes
00127   Message( const BeginString& beginString, const MsgType& msgType )
00128   : m_validStructure( true )
00129   {
00130     m_header.setField( beginString );
00131     m_header.setField( msgType );
00132   }
00133 
00134 public:
00136   std::string toString( int beginStringField = FIELD::BeginString,
00137                         int bodyLengthField = FIELD::BodyLength,
00138                         int checkSumField = FIELD::CheckSum ) const;
00140   std::string& toString( std::string&,
00141                          int beginStringField = FIELD::BeginString,
00142                          int bodyLengthField = FIELD::BodyLength, 
00143                          int checkSumField = FIELD::CheckSum ) const;
00145   std::string toXML() const;
00147   std::string& toXML( std::string& ) const;
00148 
00154   void reverseRoute( const Header& );
00155 
00162   void setString( const std::string& string )
00163   throw( InvalidMessage )
00164   { setString(string, true); }
00165   void setString( const std::string& string, bool validate )
00166   throw( InvalidMessage )
00167   { setString(string, validate, 0); }
00168   void setString( const std::string& string,
00169                   bool validate,
00170                   const FIX::DataDictionary* pDataDictionary )
00171   throw( InvalidMessage )
00172   { setString(string, validate, pDataDictionary, pDataDictionary); }
00173 
00174   void setString( const std::string& string,
00175                   bool validate,
00176                   const FIX::DataDictionary* pSessionDataDictionary,
00177                   const FIX::DataDictionary* pApplicationDataDictionary )
00178   throw( InvalidMessage );
00179 
00180   void setGroup( const std::string& msg, const FieldBase& field,
00181                  const std::string& string, std::string::size_type& pos,
00182                  FieldMap& map, const DataDictionary& dataDictionary );
00183 
00189   bool setStringHeader( const std::string& string );
00190 
00192   const Header& getHeader() const { return m_header; }
00194   Header& getHeader() { return m_header; }
00196   const Trailer& getTrailer() const { return m_trailer; }
00198   Trailer& getTrailer() { return m_trailer; }
00199 
00200   bool hasValidStructure(int& field) const
00201   { field = m_field;
00202     return m_validStructure;
00203   }
00204 
00205   int bodyLength( int beginStringField = FIELD::BeginString, 
00206                   int bodyLengthField = FIELD::BodyLength, 
00207                   int checkSumField = FIELD::CheckSum ) const
00208   { return m_header.calculateLength(beginStringField, bodyLengthField, checkSumField)
00209            + calculateLength(beginStringField, bodyLengthField, checkSumField)
00210            + m_trailer.calculateLength(beginStringField, bodyLengthField, checkSumField);
00211   }
00212 
00213   int checkSum( int checkSumField = FIELD::CheckSum ) const
00214   { return ( m_header.calculateTotal(checkSumField)
00215              + calculateTotal(checkSumField)
00216              + m_trailer.calculateTotal(checkSumField) ) % 256;
00217   }
00218 
00219   bool isAdmin() const
00220   { 
00221     if( m_header.isSetField(FIELD::MsgType) )
00222     {
00223       const MsgType& msgType = FIELD_GET_REF( m_header, MsgType );
00224       return isAdminMsgType( msgType );
00225     }
00226     return false;
00227   }
00228 
00229   bool isApp() const
00230   { 
00231     if( m_header.isSetField(FIELD::MsgType) )
00232     {
00233       const MsgType& msgType = FIELD_GET_REF( m_header, MsgType );
00234       return !isAdminMsgType( msgType );
00235     }
00236     return false;
00237   }
00238 
00239   bool isEmpty()
00240   { return m_header.isEmpty() && FieldMap::isEmpty() && m_trailer.isEmpty(); }
00241 
00242   void clear()
00243   { 
00244     m_field = 0;
00245     m_header.clear();
00246     FieldMap::clear();
00247     m_trailer.clear();
00248   }
00249 
00250   static bool isAdminMsgType( const MsgType& msgType )
00251   { if ( msgType.getValue().length() != 1 ) return false;
00252     return strchr
00253            ( "0A12345",
00254              msgType.getValue().c_str() [ 0 ] ) != 0;
00255   }
00256 
00257   static ApplVerID toApplVerID(const BeginString& value)
00258   {
00259     if( value == BeginString_FIX40 )
00260       return ApplVerID(ApplVerID_FIX40);
00261     if( value == BeginString_FIX41 )
00262       return ApplVerID(ApplVerID_FIX41);
00263     if( value == BeginString_FIX42 )
00264       return ApplVerID(ApplVerID_FIX42);
00265     if( value == BeginString_FIX43 )
00266       return ApplVerID(ApplVerID_FIX43);
00267     if( value == BeginString_FIX44 )
00268       return ApplVerID(ApplVerID_FIX44);
00269     if( value == BeginString_FIX50 )
00270       return ApplVerID(ApplVerID_FIX50);
00271     if( value == "FIX.5.0SP1" )
00272       return ApplVerID(ApplVerID_FIX50SP1);
00273     if( value == "FIX.5.0SP2" )
00274       return ApplVerID(ApplVerID_FIX50SP2);
00275     return ApplVerID(ApplVerID(value));
00276   }
00277 
00278   static BeginString toBeginString( const ApplVerID& applVerID )
00279   {
00280     if( applVerID == ApplVerID_FIX40 )
00281       return BeginString(BeginString_FIX40);
00282     else if( applVerID == ApplVerID_FIX41 )
00283       return BeginString(BeginString_FIX41);
00284     else if( applVerID == ApplVerID_FIX42 )
00285       return BeginString(BeginString_FIX42);
00286     else if( applVerID == ApplVerID_FIX43 )
00287       return BeginString(BeginString_FIX43);
00288     else if( applVerID == ApplVerID_FIX44 )
00289       return BeginString(BeginString_FIX44);
00290     else if( applVerID == ApplVerID_FIX50 )
00291       return BeginString(BeginString_FIX50);
00292     else if( applVerID == ApplVerID_FIX50SP1 )
00293       return BeginString(BeginString_FIX50);
00294     else if( applVerID == ApplVerID_FIX50SP2 )
00295       return BeginString(BeginString_FIX50);
00296     else
00297       return BeginString("");
00298   }
00299 
00300   static bool isHeaderField( int field );
00301   static bool isHeaderField( const FieldBase& field,
00302                              const DataDictionary* pD = 0 );
00303 
00304   static bool isTrailerField( int field );
00305   static bool isTrailerField( const FieldBase& field,
00306                               const DataDictionary* pD = 0 );
00307 
00309   SessionID getSessionID( const std::string& qualifier = "" ) const
00310   throw( FieldNotFound );
00312   void setSessionID( const SessionID& sessionID );
00313 
00314 private:
00315   FieldBase extractField( 
00316     const std::string& string, std::string::size_type& pos,
00317     const DataDictionary* pSessionDD = 0, const DataDictionary* pAppDD = 0,
00318     const Group* pGroup = 0);
00319 
00320   static bool IsDataField( 
00321     int field, 
00322     const DataDictionary* pSessionDD, 
00323     const DataDictionary* pAppDD )
00324   {
00325     if( (pSessionDD && pSessionDD->isDataField( field )) ||
00326         (pAppDD && pAppDD != pSessionDD && pAppDD->isDataField( field )) )
00327     {
00328       return true;
00329     }
00330 
00331     return false;
00332   }
00333 
00334   void validate();
00335   std::string toXMLFields(const FieldMap& fields, int space) const;
00336 
00337 protected:
00338   mutable Header m_header;
00339   mutable Trailer m_trailer;
00340   bool m_validStructure;
00341   int m_field;
00342   static std::auto_ptr<DataDictionary> s_dataDictionary;
00343 };
00346 inline std::ostream& operator <<
00347 ( std::ostream& stream, const Message& message )
00348 {
00349   std::string str;
00350   stream << message.toString( str );
00351   return stream;
00352 }
00353 
00355 inline MsgType identifyType( const std::string& message )
00356 throw( MessageParseError )
00357 {
00358   std::string::size_type pos = message.find( "\001" "35=" );
00359   if ( pos == std::string::npos ) throw MessageParseError();
00360 
00361   std::string::size_type startValue = pos + 4;
00362   std::string::size_type soh = message.find_first_of( '\001', startValue );
00363   if ( soh == std::string::npos ) throw MessageParseError();
00364 
00365   std::string value = message.substr( startValue, soh - startValue );
00366   return MsgType( value );
00367 }
00368 }
00369 
00370 #endif //FIX_MESSAGE

Generated on Mon Sep 15 2014 01:23:54 for QuickFIX by doxygen 1.7.6.1 written by Dimitri van Heesch, © 1997-2001