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

# FieldMap.cpp

Go to the documentation of this file.

    00001 /****************************************************************************
    00002 ** Copyright (c) quickfixengine.org  All rights reserved.
    00003 **
    00004 ** This file is part of the QuickFIX FIX Engine
    00005 **
    00006 ** This file may be distributed under the terms of the quickfixengine.org
    00007 ** license as defined by quickfixengine.org and appearing in the file
    00008 ** LICENSE included in the packaging of this file.
    00009 **
    00010 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
    00011 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    00012 **
    00013 ** See http://www.quickfixengine.org/LICENSE for licensing information.
    00014 **
    00015 ** Contact ask@quickfixengine.org if any conditions of this licensing are
    00016 ** not clear to you.
    00017 **
    00018 ****************************************************************************/
    00019
    00020 #ifdef _MSC_VER
    00021 #include "stdafx.h"
    00022 #else
    00023 #include "config.h"
    00024 #endif
    00025 #include "CallStack.h"
    00026
    00027 #include "FieldMap.h"
    00028 #include <algorithm>
    00029 #include <iterator>
    00030
    00031 namespace FIX
    00032 {
    00033 FieldMap::~FieldMap()
    00034 { QF_STACK_IGNORE_BEGIN
    00035   clear();
    00036   QF_STACK_IGNORE_END
    00037 }
    00038
    00039 FieldMap& FieldMap::operator=( const FieldMap& rhs )
    00040 { QF_STACK_PUSH(FieldMap::operator=)
    00041
    00042   m_fields = rhs.m_fields;
    00043
    00044   clear();
    00045
    00046   std::copy( rhs.m_fields.begin (), rhs.m_fields.end(),
    00047              std::inserter(m_fields, m_fields.begin()) );
    00048
    00049   Groups::const_iterator i;
    00050   for ( i = rhs.m_groups.begin(); i != rhs.m_groups.end(); ++i )
    00051   {
    00052     std::vector < FieldMap* > ::const_iterator j;
    00053     for ( j = i->second.begin(); j != i->second.end(); ++j )
    00054       addGroup( i->first, **j );
    00055   }
    00056
    00057   return *this;
    00058
    00059   QF_STACK_POP
    00060 }
    00061
    00062 void FieldMap::addGroup( int field, const FieldMap& group, bool setCount )
    00063 { QF_STACK_PUSH(FieldMap::addGroup)
    00064
    00065   FieldMap * pGroup = new FieldMap( group.m_fields.key_comp() );
    00066   *pGroup = group;
    00067   m_groups[ field ].push_back( pGroup );
    00068   Groups::iterator i = m_groups.find( field );
    00069   if( setCount )
    00070     setField( IntField( field, i->second.size() ) );
    00071
    00072   QF_STACK_POP
    00073 }
    00074
    00075 void FieldMap::replaceGroup( int num, int field, FieldMap& group )
    00076 { QF_STACK_PUSH(FieldMap::replaceGroup)
    00077
    00078   Groups::const_iterator i = m_groups.find( field );
    00079   if ( i == m_groups.end() ) return;
    00080   if ( num <= 0 ) return;
    00081   if ( i->second.size() < ( unsigned ) num ) return;
    00082   *( *( i->second.begin() + ( num - 1 ) ) ) = group;
    00083
    00084   QF_STACK_POP
    00085 }
    00086
    00087 void FieldMap::removeGroup( int num, int field )
    00088 {
    00089   Groups::iterator i = m_groups.find( field );
    00090   if ( i == m_groups.end() ) return;
    00091   if ( num <= 0 ) return;
    00092   std::vector< FieldMap* >& vector = i->second;
    00093   if ( vector.size() < ( unsigned ) num ) return;
    00094
    00095   std::deque< FieldMap* > queue;
    00096   while( vector.size() > (unsigned)num )
    00097   {
    00098     queue.push_back( vector.back() );
    00099     vector.pop_back();
    00100   }
    00101   delete vector.back();
    00102   vector.pop_back();
    00103   while( queue.size() )
    00104   {
    00105     vector.push_back( queue.front() );
    00106     queue.pop_front();
    00107   }
    00108
    00109   if( vector.size() == 0 )
    00110   {
    00111     m_groups.erase( field );
    00112   }
    00113   else
    00114   {
    00115     IntField groupCount( field, vector.size() );
    00116     setField( groupCount, true );
    00117   }
    00118 }
    00119
    00120 void FieldMap::removeGroup( int field )
    00121 { QF_STACK_PUSH(FieldMap::removeGroup)
    00122   removeGroup( groupCount(field), field );
    00123   QF_STACK_POP
    00124 }
    00125
    00126 void FieldMap::removeField( int field )
    00127 { QF_STACK_PUSH(FieldMap::removeField)
    00128
    00129   Fields::iterator i = m_fields.find( field );
    00130   if ( i != m_fields.end() )
    00131     m_fields.erase( i );
    00132
    00133   QF_STACK_POP
    00134 }
    00135
    00136 bool FieldMap::hasGroup( int num, int field ) const
    00137 { QF_STACK_PUSH(FieldMap::hasGroup)
    00138
    00139   return groupCount(field) >= num;
    00140
    00141   QF_STACK_POP
    00142 }
    00143
    00144 bool FieldMap::hasGroup( int field ) const
    00145 { QF_STACK_PUSH(FieldMap::hasGroup)
    00146
    00147   Groups::const_iterator i = m_groups.find( field );
    00148   return i != m_groups.end();
    00149
    00150   QF_STACK_POP
    00151 }
    00152
    00153 int FieldMap::groupCount( int field ) const
    00154 { QF_STACK_PUSH(FieldMap::groupCount)
    00155
    00156   Groups::const_iterator i = m_groups.find( field );
    00157   if( i == m_groups.end() )
    00158     return 0;
    00159   return i->second.size();
    00160
    00161   QF_STACK_POP
    00162 }
    00163
    00164 void FieldMap::clear()
    00165 { QF_STACK_PUSH(FieldMap::clear)
    00166
    00167   m_fields.clear();
    00168
    00169   Groups::iterator i;
    00170   for ( i = m_groups.begin(); i != m_groups.end(); ++i )
    00171   {
    00172     std::vector < FieldMap* > ::iterator j;
    00173     for ( j = i->second.begin(); j != i->second.end(); ++j )
    00174       delete *j;
    00175   }
    00176   m_groups.clear();
    00177
    00178   QF_STACK_POP
    00179 }
    00180
    00181 bool FieldMap::isEmpty()
    00182 { QF_STACK_PUSH(FieldMap::isEmpty)
    00183   return m_fields.size() == 0;
    00184   QF_STACK_POP
    00185 }
    00186
    00187 int FieldMap::totalFields() const
    00188 {
    00189   int result = m_fields.size();
    00190
    00191   Groups::const_iterator i;
    00192   for ( i = m_groups.begin(); i != m_groups.end(); ++i )
    00193   {
    00194     std::vector < FieldMap* > ::const_iterator j;
    00195     for ( j = i->second.begin(); j != i->second.end(); ++j )
    00196       result += ( *j ) ->totalFields();
    00197   }
    00198   return result;
    00199 }
    00200
    00201 std::string& FieldMap::calculateString( std::string& result, bool clear ) const
    00202 { QF_STACK_PUSH(FieldMap::calculateString)
    00203
    00204 #if defined(_MSC_VER) && _MSC_VER < 1300
    00205   if( clear ) result = "";
    00206 #else
    00207   if( clear ) result.clear();
    00208 #endif
    00209
    00210   if( !result.size() )
    00211     result.reserve( totalFields() * 32 );
    00212
    00213   Fields::const_iterator i;
    00214   for ( i = m_fields.begin(); i != m_fields.end(); ++i )
    00215   {
    00216     result += i->second.getValue();
    00217
    00218     // add groups if they exist
    00219     if( !m_groups.size() ) continue;
    00220     Groups::const_iterator j = m_groups.find( i->first );
    00221     if ( j == m_groups.end() ) continue;
    00222     std::vector < FieldMap* > ::const_iterator k;
    00223     for ( k = j->second.begin(); k != j->second.end(); ++k )
    00224       ( *k ) ->calculateString( result, false );
    00225   }
    00226   return result;
    00227
    00228   QF_STACK_POP
    00229 }
    00230
    00231 int FieldMap::calculateLength( int beginStringField,
    00232                                int bodyLengthField,
    00233                                int checkSumField ) const
    00234 {
    00235   int result = 0;
    00236   Fields::const_iterator i;
    00237   for ( i = m_fields.begin(); i != m_fields.end(); ++i )
    00238   {
    00239     if ( i->first != beginStringField
    00240          && i->first != bodyLengthField
    00241          && i->first != checkSumField )
    00242     { result += i->second.getLength(); }
    00243   }
    00244
    00245   Groups::const_iterator j;
    00246   for ( j = m_groups.begin(); j != m_groups.end(); ++j )
    00247   {
    00248     std::vector < FieldMap* > ::const_iterator k;
    00249     for ( k = j->second.begin(); k != j->second.end(); ++k )
    00250       result += ( *k ) ->calculateLength();
    00251   }
    00252   return result;
    00253 }
    00254
    00255 int FieldMap::calculateTotal( int checkSumField ) const
    00256 { QF_STACK_PUSH(FieldMap::calculateTotal)
    00257
    00258   int result = 0;
    00259   Fields::const_iterator i;
    00260   for ( i = m_fields.begin(); i != m_fields.end(); ++i )
    00261   {
    00262     if ( i->first != checkSumField )
    00263       result += i->second.getTotal();
    00264   }
    00265
    00266   Groups::const_iterator j;
    00267   for ( j = m_groups.begin(); j != m_groups.end(); ++j )
    00268   {
    00269     std::vector < FieldMap* > ::const_iterator k;
    00270     for ( k = j->second.begin(); k != j->second.end(); ++k )
    00271       result += ( *k ) ->calculateTotal();
    00272   }
    00273   return result;
    00274
    00275   QF_STACK_POP
    00276 }
    00277 }