00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 <map>
00034 #include <vector>
00035 #include <sstream>
00036 #include <algorithm>
00037
00038 namespace FIX
00039 {
00046 class FieldMap
00047 {
00048 public:
00049 typedef std::multimap < int, FieldBase, message_order > Fields;
00050 typedef std::map < int, std::vector < FieldMap* > > Groups;
00051 typedef Fields::const_iterator iterator;
00052 typedef iterator const_iterator;
00053 typedef Groups::const_iterator g_iterator;
00054 typedef Groups::const_iterator g_const_iterator;
00055
00056 FieldMap( const message_order& order =
00057 message_order( message_order::normal ) )
00058 : m_fields( order ) {}
00059
00060 FieldMap( const int order[] )
00061 : m_fields( message_order(order) ) {}
00062
00063 FieldMap( const FieldMap& copy )
00064 { *this = copy; }
00065
00066 virtual ~FieldMap();
00067
00068 FieldMap& operator=( const FieldMap& rhs );
00069
00071 void setField( const FieldBase& field, bool overwrite = true )
00072 throw( RepeatedTag )
00073 {
00074 Fields::iterator i = m_fields.find( field.getField() );
00075 if( i == m_fields.end() )
00076 m_fields.insert( Fields::value_type( field.getField(), field ) );
00077 else
00078 {
00079 if( overwrite )
00080 i->second = field;
00081 else
00082 m_fields.insert( Fields::value_type( field.getField(), field ) );
00083 }
00084 }
00086 void setField( int field, const std::string& value )
00087 throw( RepeatedTag, NoTagValue )
00088 {
00089 FieldBase fieldBase( field, value );
00090 setField( fieldBase );
00091 }
00092
00094 FieldBase& getField( FieldBase& field )
00095 const throw( FieldNotFound )
00096 {
00097 Fields::const_iterator iter = m_fields.find( field.getField() );
00098 if ( iter == m_fields.end() )
00099 throw FieldNotFound( field.getField() );
00100 field = iter->second;
00101 return field;
00102 }
00104 std::string getField( int field )
00105 const throw( FieldNotFound )
00106 {
00107 FieldBase fieldBase( field, "" );
00108 getField( fieldBase );
00109 return fieldBase.getString();
00110 }
00111
00113 bool isSetField( const FieldBase& field ) const
00114 { return m_fields.find( field.getField() ) != m_fields.end(); }
00116 bool isSetField( int field ) const
00117 { return m_fields.find( field ) != m_fields.end(); }
00118
00120 void removeField( int field );
00121
00123 void addGroup( int field, const FieldMap& group, bool setCount = true );
00124
00126 void replaceGroup( int num, int field, FieldMap& group );
00127
00129 FieldMap& getGroup( int num, int field, FieldMap& group ) const
00130 throw( FieldNotFound );
00131
00133 void removeGroup( int num, int field );
00135 void removeGroup( int field );
00136
00138 bool hasGroup( int field ) const;
00140 bool hasGroup( int num, int field ) const;
00142 int groupCount( int field ) const;
00143
00145 void clear();
00147 bool isEmpty();
00148
00149 std::string& calculateString( std::string&, bool clear = true ) const;
00150
00151 int calculateLength( int beginStringField = FIELD::BeginString,
00152 int bodyLengthField = FIELD::BodyLength,
00153 int checkSumField = FIELD::CheckSum ) const;
00154
00155 int calculateTotal( int checkSumField = FIELD::CheckSum ) const;
00156
00157 iterator begin() const { return m_fields.begin(); }
00158 iterator end() const { return m_fields.end(); }
00159 g_iterator g_begin() const { return m_groups.begin(); }
00160 g_iterator g_end() const { return m_groups.end(); }
00161
00162 private:
00163 Fields m_fields;
00164 Groups m_groups;
00165 };
00167 }
00168
00169 #define FIELD_SET( MAP, FIELD ) \
00170 bool isSet( const FIELD& field ) const \
00171 { return (MAP).isSetField(field); } \
00172 void set( const FIELD& field ) \
00173 { (MAP).setField(field); } \
00174 FIELD& get( FIELD& field ) const \
00175 { return (FIELD&)(MAP).getField(field); }
00176
00177 #endif //FIX_FIELDMAP
00178