FieldMap.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /* -*- C++ -*- */
  2. /****************************************************************************
  3. ** Copyright (c) 2001-2014
  4. **
  5. ** This file is part of the QuickFIX FIX Engine
  6. **
  7. ** This file may be distributed under the terms of the quickfixengine.org
  8. ** license as defined by quickfixengine.org and appearing in the file
  9. ** LICENSE included in the packaging of this file.
  10. **
  11. ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
  12. ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  13. **
  14. ** See http://www.quickfixengine.org/LICENSE for licensing information.
  15. **
  16. ** Contact ask@quickfixengine.org if any conditions of this licensing are
  17. ** not clear to you.
  18. **
  19. ****************************************************************************/
  20. #ifndef FIX_FIELDMAP
  21. #define FIX_FIELDMAP
  22. #ifdef _MSC_VER
  23. #pragma warning( disable: 4786 )
  24. #endif
  25. #include "Field.h"
  26. #include "MessageSorters.h"
  27. #include "Exceptions.h"
  28. #include "Utility.h"
  29. #include <map>
  30. #include <vector>
  31. #include <sstream>
  32. #include <algorithm>
  33. namespace FIX
  34. {
  35. /**
  36. * Stores and organizes a collection of Fields.
  37. *
  38. * This is the basis for a message, header, and trailer. This collection
  39. * class uses a sorter to keep the fields in a particular order.
  40. */
  41. class FieldMap
  42. {
  43. public:
  44. #if defined(_MSC_VER) && _MSC_VER < 1300
  45. typedef std::multimap < int, FieldBase, message_order > Fields;
  46. typedef std::map < int, std::vector < FieldMap* >, std::less<int> > Groups;
  47. #else
  48. typedef std::multimap < int, FieldBase, message_order,
  49. ALLOCATOR<std::pair<const int,FieldBase> > > Fields;
  50. typedef std::map < int, std::vector < FieldMap* >, std::less<int>,
  51. ALLOCATOR<std::pair<const int, std::vector< FieldMap* > > > > Groups;
  52. #endif
  53. typedef Fields::const_iterator iterator;
  54. typedef iterator const_iterator;
  55. typedef Groups::const_iterator g_iterator;
  56. typedef Groups::const_iterator g_const_iterator;
  57. FieldMap( const message_order& order =
  58. message_order( message_order::normal ) )
  59. : m_fields( order ) {}
  60. FieldMap( const int order[] )
  61. : m_fields( message_order(order) ) {}
  62. FieldMap( const FieldMap& copy )
  63. { *this = copy; }
  64. virtual ~FieldMap();
  65. FieldMap& operator=( const FieldMap& rhs );
  66. /// Set a field without type checking
  67. void setField( const FieldBase& field, bool overwrite = true )
  68. throw( RepeatedTag )
  69. {
  70. if(!overwrite)
  71. m_fields.insert( Fields::value_type( field.getField(), field ) );
  72. else
  73. {
  74. Fields::iterator i = m_fields.find( field.getField() );
  75. if( i == m_fields.end() )
  76. m_fields.insert( Fields::value_type( field.getField(), field ) );
  77. else
  78. i->second = field;
  79. }
  80. }
  81. /// Set a field without a field class
  82. void setField( int field, const std::string& value )
  83. throw( RepeatedTag, NoTagValue )
  84. {
  85. FieldBase fieldBase( field, value );
  86. setField( fieldBase );
  87. }
  88. /// Get a field if set
  89. bool getFieldIfSet( FieldBase& field ) const
  90. {
  91. Fields::const_iterator iter = m_fields.find( field.getField() );
  92. if ( iter == m_fields.end() )
  93. return false;
  94. field = iter->second;
  95. return true;
  96. }
  97. /// Get a field without type checking
  98. FieldBase& getField( FieldBase& field )
  99. const throw( FieldNotFound )
  100. {
  101. field = getFieldRef( field.getField() );
  102. return field;
  103. }
  104. /// Get a field without a field class
  105. const std::string& getField( int field )
  106. const throw( FieldNotFound )
  107. {
  108. return getFieldRef( field ).getString();
  109. }
  110. /// Get direct access to a field through a reference
  111. const FieldBase& getFieldRef( int field )
  112. const throw( FieldNotFound )
  113. {
  114. Fields::const_iterator iter = m_fields.find( field );
  115. if ( iter == m_fields.end() )
  116. throw FieldNotFound( field );
  117. return iter->second;
  118. }
  119. /// Get direct access to a field through a pointer
  120. const FieldBase* const getFieldPtr( int field )
  121. const throw( FieldNotFound )
  122. {
  123. return &getFieldRef( field );
  124. }
  125. /// Check to see if a field is set
  126. bool isSetField( const FieldBase& field ) const
  127. { return isSetField( field.getField() ); }
  128. /// Check to see if a field is set by referencing its number
  129. bool isSetField( int field ) const
  130. { return m_fields.find( field ) != m_fields.end(); }
  131. /// Remove a field. If field is not present, this is a no-op.
  132. void removeField( int field );
  133. /// Add a group.
  134. void addGroup( int field, const FieldMap& group, bool setCount = true );
  135. /// Acquire ownership of Group object
  136. void addGroupPtr( int field, FieldMap * group, bool setCount = true );
  137. /// Replace a specific instance of a group.
  138. void replaceGroup( int num, int field, const FieldMap& group );
  139. /// Get a specific instance of a group.
  140. FieldMap& getGroup( int num, int field, FieldMap& group ) const
  141. throw( FieldNotFound )
  142. {
  143. return group = getGroupRef( num, field );
  144. }
  145. /// Get direct access to a field through a reference
  146. FieldMap& getGroupRef( int num, int field ) const
  147. throw( FieldNotFound )
  148. {
  149. Groups::const_iterator i = m_groups.find( field );
  150. if( i == m_groups.end() ) throw FieldNotFound( field );
  151. if( num <= 0 ) throw FieldNotFound( field );
  152. if( i->second.size() < (unsigned)num ) throw FieldNotFound( field );
  153. return *( *(i->second.begin() + (num-1) ) );
  154. }
  155. /// Get direct access to a field through a pointer
  156. FieldMap* getGroupPtr( int num, int field ) const
  157. throw( FieldNotFound )
  158. {
  159. return &getGroupRef( num, field );
  160. }
  161. /// Remove a specific instance of a group.
  162. void removeGroup( int num, int field );
  163. /// Remove all instances of a group.
  164. void removeGroup( int field );
  165. /// Check to see any instance of a group exists
  166. bool hasGroup( int field ) const;
  167. /// Check to see if a specific instance of a group exists
  168. bool hasGroup( int num, int field ) const;
  169. /// Count the number of instance of a group
  170. int groupCount( int field ) const;
  171. /// Clear all fields from the map
  172. void clear();
  173. /// Check if map contains any fields
  174. bool isEmpty();
  175. int totalFields() const;
  176. std::string& calculateString( std::string& ) const;
  177. int calculateLength( int beginStringField = FIELD::BeginString,
  178. int bodyLengthField = FIELD::BodyLength,
  179. int checkSumField = FIELD::CheckSum ) const;
  180. int calculateTotal( int checkSumField = FIELD::CheckSum ) const;
  181. iterator begin() const { return m_fields.begin(); }
  182. iterator end() const { return m_fields.end(); }
  183. g_iterator g_begin() const { return m_groups.begin(); }
  184. g_iterator g_end() const { return m_groups.end(); }
  185. private:
  186. Fields m_fields;
  187. Groups m_groups;
  188. };
  189. /*! @} */
  190. }
  191. #define FIELD_SET( MAP, FIELD ) \
  192. bool isSet( const FIELD& field ) const \
  193. { return (MAP).isSetField(field); } \
  194. void set( const FIELD& field ) \
  195. { (MAP).setField(field); } \
  196. FIELD& get( FIELD& field ) const \
  197. { return (FIELD&)(MAP).getField(field); } \
  198. bool getIfSet( FIELD& field ) const \
  199. { return (MAP).getFieldIfSet(field); }
  200. #define FIELD_GET_PTR( MAP, FLD ) \
  201. (const FIX::FLD*)MAP.getFieldPtr( FIX::FIELD::FLD )
  202. #define FIELD_GET_REF( MAP, FLD ) \
  203. (const FIX::FLD&)MAP.getFieldRef( FIX::FIELD::FLD )
  204. #define FIELD_THROW_IF_NOT_FOUND( MAP, FLD ) \
  205. if( !(MAP).isSetField( FIX::FIELD::FLD) ) \
  206. throw FieldNotFound( FIX::FIELD::FLD )
  207. #endif //FIX_FIELDMAP