MessageSorters.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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_MESSAGESORTERS_H
  21. #define FIX_MESSAGESORTERS_H
  22. #ifdef _MSC_VER
  23. #pragma warning( disable : 4503 4355 4786 4290 )
  24. #endif
  25. #include "FieldNumbers.h"
  26. #include "SharedArray.h"
  27. #include <stdarg.h>
  28. #include <functional>
  29. #include <map>
  30. namespace FIX
  31. {
  32. /// Sorts fields in correct header order.
  33. struct header_order
  34. {
  35. static bool compare( const int x, const int y )
  36. {
  37. int orderedX = getOrderedPosition( x );
  38. int orderedY = getOrderedPosition( y );
  39. if ( orderedX && orderedY )
  40. return orderedX < orderedY;
  41. else
  42. if ( orderedX )
  43. return true;
  44. else
  45. if ( orderedY )
  46. return false;
  47. else
  48. return x < y;
  49. }
  50. static int getOrderedPosition( const int field )
  51. {
  52. switch ( field )
  53. {
  54. case FIELD::BeginString: return 1;
  55. case FIELD::BodyLength: return 2;
  56. case FIELD::MsgType: return 3;
  57. default: return 0;
  58. };
  59. }
  60. };
  61. /// Sorts fields in correct trailer order.
  62. struct trailer_order
  63. {
  64. static bool compare( const int x, const int y )
  65. {
  66. if ( x == FIELD::CheckSum ) return false;
  67. else
  68. if ( y == FIELD::CheckSum ) return true;
  69. else return x < y;
  70. }
  71. };
  72. /// Sorts fields in correct group order
  73. struct group_order
  74. {
  75. static bool compare( const int x, const int y, int* order, int largest )
  76. {
  77. if ( x <= largest && y <= largest )
  78. {
  79. int iX = order[ x ];
  80. int iY = order[ y ];
  81. if ( iX == 0 && iY == 0 )
  82. return x < y;
  83. else if ( iX == 0 )
  84. return false;
  85. else if ( iY == 0 )
  86. return true;
  87. else
  88. return iX < iY;
  89. }
  90. else if ( x <= largest ) return true;
  91. else if ( y <= largest ) return false;
  92. else return x < y;
  93. }
  94. };
  95. typedef std::less < int > normal_order;
  96. /**
  97. * Sorts fields in header, normal, or trailer order.
  98. *
  99. * Used as a dynamic sorter to create Header, Trailer, and Message
  100. * FieldMaps while maintaining the same base type.
  101. */
  102. struct message_order
  103. {
  104. public:
  105. enum cmp_mode { header, trailer, normal, group };
  106. message_order( cmp_mode mode = normal )
  107. : m_mode( mode ), m_delim( 0 ), m_largest( 0 ) {}
  108. message_order( int first, ... );
  109. message_order( const int order[] );
  110. message_order( const message_order& copy )
  111. { *this = copy; }
  112. bool operator() ( const int x, const int y ) const
  113. {
  114. switch ( m_mode )
  115. {
  116. case header:
  117. return header_order::compare( x, y );
  118. case trailer:
  119. return trailer_order::compare( x, y );
  120. case group:
  121. return group_order::compare( x, y, m_groupOrder, m_largest );
  122. case normal: default:
  123. return x < y;
  124. }
  125. }
  126. message_order& operator=( const message_order& rhs );
  127. operator bool() const
  128. { return !m_groupOrder.empty(); }
  129. private:
  130. void setOrder( int size, const int order[] );
  131. cmp_mode m_mode;
  132. int m_delim;
  133. shared_array<int> m_groupOrder;
  134. int m_largest;
  135. };
  136. }
  137. #endif //FIX_MESSAGESORTERS_H