Index Source Files Annotated Class List Alphabetical Class List Class Hierarchy Graphical Class Hierarchy

# FieldMap.h

Go to the documentation of this file.

    00001 /* -*- C++ -*- */
    00002
    00003 /****************************************************************************
    00004 ** Copyright (c) quickfixengine.org  All rights reserved.
    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_FIELDMAP
    00023 #define FIX_FIELDMAP
    00024
    00025 #ifdef _MSC_VER
    00026 #pragma warning( disable: 4786 )
    00027 #endif
    00028
    00029 #include "Field.h"
    00030 #include "MessageSorters.h"
    00031 #include "Exceptions.h"
    00032 #include "CallStack.h"
    00033 #include "Utility.h"
    00034 #include <map>
    00035 #include <vector>
    00036 #include <sstream>
    00037 #include <algorithm>
    00038
    00039 namespace FIX
    00040 {
    00047 class FieldMap
    00048 {
    00049 public:
    00050 #if defined(_MSC_VER) && _MSC_VER < 1300
    00051   typedef std::multimap < int, FieldBase, message_order > Fields;
    00052   typedef std::map < int, std::vector < FieldMap* >, std::less<int> > Groups;
    00053 #else
    00054   typedef std::multimap < int, FieldBase, message_order,
    00055                           ALLOCATOR<std::pair<const int,FieldBase> > > Fields;
    00056   typedef std::map < int, std::vector < FieldMap* >, std::less<int>,
    00057                      ALLOCATOR<std::pair<const int, std::vector< FieldMap* > > > > Groups;
    00058 #endif
    00059
    00060   typedef Fields::const_iterator iterator;
    00061   typedef iterator const_iterator;
    00062   typedef Groups::const_iterator g_iterator;
    00063   typedef Groups::const_iterator g_const_iterator;
    00064
    00065   FieldMap( const message_order& order =
    00066             message_order( message_order::normal ) )
    00067   : m_fields( order ) {}
    00068
    00069   FieldMap( const int order[] )
    00070   : m_fields( message_order(order) ) {}
    00071
    00072   FieldMap( const FieldMap& copy )
    00073   { *this = copy; }
    00074
    00075   virtual ~FieldMap();
    00076
    00077   FieldMap& operator=( const FieldMap& rhs );
    00078
    00080   void setField( const FieldBase& field, bool overwrite = true )
    00081   throw( RepeatedTag )
    00082   {
    00083     Fields::iterator i = m_fields.find( field.getField() );
    00084     if( i == m_fields.end() )
    00085       m_fields.insert( Fields::value_type( field.getField(), field ) );
    00086     else
    00087     {
    00088       if( overwrite )
    00089         i->second = field;
    00090       else
    00091         m_fields.insert( Fields::value_type( field.getField(), field ) );
    00092     }
    00093   }
    00095   void setField( int field, const std::string& value )
    00096   throw( RepeatedTag, NoTagValue )
    00097   {
    00098     FieldBase fieldBase( field, value );
    00099     setField( fieldBase );
    00100   }
    00101
    00103   FieldBase& getField( FieldBase& field )
    00104   const throw( FieldNotFound )
    00105   {
    00106     Fields::const_iterator iter = m_fields.find( field.getField() );
    00107     if ( iter == m_fields.end() )
    00108       throw FieldNotFound( field.getField() );
    00109     field = iter->second;
    00110     return field;
    00111   }
    00112
    00114   const std::string& getField( int field )
    00115   const throw( FieldNotFound )
    00116   {
    00117     return getFieldRef( field ).getString();
    00118   }
    00119
    00121   const FieldBase& getFieldRef( int field )
    00122   const throw( FieldNotFound )
    00123   {
    00124     Fields::const_iterator iter = m_fields.find( field );
    00125     if ( iter == m_fields.end() )
    00126       throw FieldNotFound( field );
    00127     return iter->second;
    00128   }
    00129
    00131   const FieldBase* const getFieldPtr( int field )
    00132   const throw( FieldNotFound )
    00133   {
    00134     return &getFieldRef( field );
    00135   }
    00136
    00138   bool isSetField( const FieldBase& field ) const
    00139   { return m_fields.find( field.getField() ) != m_fields.end(); }
    00141   bool isSetField( int field ) const
    00142   { return m_fields.find( field ) != m_fields.end(); }
    00143
    00145   void removeField( int field );
    00146
    00148   void addGroup( int field, const FieldMap& group, bool setCount = true );
    00149
    00151   void replaceGroup( int num, int field, FieldMap& group );
    00152
    00154   FieldMap& getGroup( int num, int field, FieldMap& group ) const
    00155   throw( FieldNotFound )
    00156   {
    00157     return group = getGroupRef( num, field );
    00158   }
    00159
    00161   FieldMap& getGroupRef( int num, int field ) const
    00162   throw( FieldNotFound )
    00163   {
    00164     Groups::const_iterator i = m_groups.find( field );
    00165     if( i == m_groups.end() ) throw FieldNotFound( field );
    00166     if( num <= 0 ) throw FieldNotFound( field );
    00167     if( i->second.size() < (unsigned)num ) throw FieldNotFound( field );
    00168     return *( *(i->second.begin() + (num-1) ) );
    00169   }
    00170
    00172   FieldMap* getGroupPtr( int num, int field ) const
    00173   throw( FieldNotFound )
    00174   {
    00175     return &getGroupRef( num, field );
    00176   }
    00177
    00179   void removeGroup( int num, int field );
    00181   void removeGroup( int field );
    00182
    00184   bool hasGroup( int field ) const;
    00186   bool hasGroup( int num, int field ) const;
    00188   int groupCount( int field ) const;
    00189
    00191   void clear();
    00193   bool isEmpty();
    00194
    00195   int totalFields() const;
    00196
    00197   std::string& calculateString( std::string&, bool clear = true ) const;
    00198
    00199   int calculateLength( int beginStringField = FIELD::BeginString,
    00200                        int bodyLengthField = FIELD::BodyLength,
    00201                        int checkSumField = FIELD::CheckSum ) const;
    00202
    00203   int calculateTotal( int checkSumField = FIELD::CheckSum ) const;
    00204
    00205   iterator begin() const { return m_fields.begin(); }
    00206   iterator end() const { return m_fields.end(); }
    00207   g_iterator g_begin() const { return m_groups.begin(); }
    00208   g_iterator g_end() const { return m_groups.end(); }
    00209
    00210 private:
    00211   Fields m_fields;
    00212   Groups m_groups;
    00213 };
    00215 }
    00216
    00217 #define FIELD_SET( MAP, FIELD )           \
    00218 bool isSet( const FIELD& field ) const    \
    00219 { return (MAP).isSetField(field); }       \
    00220 void set( const FIELD& field )            \
    00221 { (MAP).setField(field); }                \
    00222 FIELD& get( FIELD& field ) const          \
    00223 { return (FIELD&)(MAP).getField(field); }
    00224
    00225 #define FIELD_GET_PTR( MAP, FLD ) \
    00226 (const FIX::FLD*)MAP.getFieldPtr( FIX::FIELD::FLD )
    00227 #define FIELD_GET_REF( MAP, FLD ) \
    00228 (const FIX::FLD&)MAP.getFieldRef( FIX::FIELD::FLD )
    00229
    00230 #endif //FIX_FIELDMAP
    00231