quickfix_ruby 1.14.3.1 → 1.15.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/quickfix/Acceptor.h +2 -0
- data/ext/quickfix/AtomicCount.h +82 -12
- data/ext/quickfix/DOMDocument.h +9 -7
- data/ext/quickfix/DataDictionary.cpp +77 -14
- data/ext/quickfix/DataDictionary.h +90 -16
- data/ext/quickfix/Dictionary.cpp +1 -2
- data/ext/quickfix/Exceptions.h +3 -5
- data/ext/quickfix/Field.h +83 -32
- data/ext/quickfix/FieldConvertors.cpp +93 -0
- data/ext/quickfix/FieldConvertors.h +129 -275
- data/ext/quickfix/FieldMap.cpp +53 -13
- data/ext/quickfix/FieldMap.h +200 -62
- data/ext/quickfix/FieldTypes.cpp +10 -10
- data/ext/quickfix/FieldTypes.h +293 -44
- data/ext/quickfix/FileLog.cpp +6 -10
- data/ext/quickfix/FileLog.h +4 -10
- data/ext/quickfix/FileStore.cpp +19 -6
- data/ext/quickfix/FileStore.h +4 -0
- data/ext/quickfix/FixFieldNumbers.h +1462 -1461
- data/ext/quickfix/FixFields.h +1462 -1461
- data/ext/quickfix/FixValues.h +3230 -3227
- data/ext/quickfix/HttpConnection.cpp +1 -1
- data/ext/quickfix/Initiator.cpp +7 -1
- data/ext/quickfix/Initiator.h +2 -0
- data/ext/quickfix/Log.h +6 -12
- data/ext/quickfix/Message.cpp +186 -57
- data/ext/quickfix/Message.h +109 -47
- data/ext/quickfix/MySQLConnection.h +1 -1
- data/ext/quickfix/PostgreSQLConnection.h +1 -1
- data/ext/quickfix/QuickfixRuby.cpp +79141 -77959
- data/ext/quickfix/QuickfixRuby.h +1 -1
- data/ext/quickfix/SSLSocketAcceptor.cpp +410 -0
- data/ext/quickfix/SSLSocketAcceptor.h +185 -0
- data/ext/quickfix/SSLSocketConnection.cpp +427 -0
- data/ext/quickfix/SSLSocketConnection.h +206 -0
- data/ext/quickfix/SSLSocketInitiator.cpp +485 -0
- data/ext/quickfix/SSLSocketInitiator.h +196 -0
- data/ext/quickfix/Session.cpp +113 -20
- data/ext/quickfix/Session.h +18 -4
- data/ext/quickfix/SessionFactory.cpp +10 -3
- data/ext/quickfix/SessionSettings.cpp +5 -3
- data/ext/quickfix/SessionSettings.h +97 -5
- data/ext/quickfix/Settings.cpp +72 -2
- data/ext/quickfix/Settings.h +3 -0
- data/ext/quickfix/SharedArray.h +140 -6
- data/ext/quickfix/SocketConnection.cpp +2 -2
- data/ext/quickfix/SocketConnector.cpp +5 -2
- data/ext/quickfix/SocketConnector.h +3 -2
- data/ext/quickfix/SocketInitiator.cpp +28 -4
- data/ext/quickfix/SocketInitiator.h +1 -1
- data/ext/quickfix/SocketMonitor.cpp +5 -5
- data/ext/quickfix/ThreadedSSLSocketAcceptor.cpp +455 -0
- data/ext/quickfix/ThreadedSSLSocketAcceptor.h +217 -0
- data/ext/quickfix/ThreadedSSLSocketConnection.cpp +404 -0
- data/ext/quickfix/ThreadedSSLSocketConnection.h +189 -0
- data/ext/quickfix/ThreadedSSLSocketInitiator.cpp +469 -0
- data/ext/quickfix/ThreadedSSLSocketInitiator.h +201 -0
- data/ext/quickfix/ThreadedSocketAcceptor.cpp +5 -1
- data/ext/quickfix/ThreadedSocketConnection.cpp +8 -2
- data/ext/quickfix/ThreadedSocketConnection.h +4 -1
- data/ext/quickfix/ThreadedSocketInitiator.cpp +24 -4
- data/ext/quickfix/ThreadedSocketInitiator.h +1 -1
- data/ext/quickfix/Utility.cpp +23 -1
- data/ext/quickfix/Utility.h +28 -2
- data/ext/quickfix/UtilitySSL.cpp +1733 -0
- data/ext/quickfix/UtilitySSL.h +277 -0
- data/ext/quickfix/config-all.h +10 -0
- data/ext/quickfix/dirent_windows.h +838 -0
- data/ext/quickfix/double-conversion/bignum-dtoa.cc +641 -0
- data/ext/quickfix/double-conversion/bignum-dtoa.h +84 -0
- data/ext/quickfix/double-conversion/bignum.cc +766 -0
- data/ext/quickfix/double-conversion/bignum.h +144 -0
- data/ext/quickfix/double-conversion/cached-powers.cc +176 -0
- data/ext/quickfix/double-conversion/cached-powers.h +64 -0
- data/ext/quickfix/double-conversion/diy-fp.cc +57 -0
- data/ext/quickfix/double-conversion/diy-fp.h +118 -0
- data/ext/quickfix/double-conversion/double-conversion.cc +994 -0
- data/ext/quickfix/double-conversion/double-conversion.h +543 -0
- data/ext/quickfix/double-conversion/fast-dtoa.cc +665 -0
- data/ext/quickfix/double-conversion/fast-dtoa.h +88 -0
- data/ext/quickfix/double-conversion/fixed-dtoa.cc +404 -0
- data/ext/quickfix/double-conversion/fixed-dtoa.h +56 -0
- data/ext/quickfix/double-conversion/ieee.h +402 -0
- data/ext/quickfix/double-conversion/strtod.cc +557 -0
- data/ext/quickfix/double-conversion/strtod.h +45 -0
- data/ext/quickfix/double-conversion/utils.h +372 -0
- data/ext/quickfix/stdint_msvc.h +254 -0
- data/lib/quickfix44.rb +3329 -10
- data/lib/quickfix50.rb +6649 -81
- data/lib/quickfix50sp1.rb +8054 -142
- data/lib/quickfix50sp2.rb +10900 -234
- data/lib/quickfix_fields.rb +7662 -7649
- data/spec/FIX40.xml +28 -28
- data/spec/FIX41.xml +29 -29
- data/spec/FIX42.xml +47 -47
- data/spec/FIX43.xml +148 -148
- data/spec/FIX44.xml +1078 -1081
- data/spec/FIX50.xml +1292 -1289
- data/spec/FIX50SP1.xml +1811 -1802
- data/spec/FIX50SP2.xml +1948 -1939
- data/spec/FIXT11.xml +5 -8
- data/test/test_FieldBaseTestCase.rb +1 -1
- data/test/test_MessageTestCase.rb +2 -2
- metadata +42 -6
data/ext/quickfix/FieldMap.cpp
CHANGED
@@ -30,6 +30,30 @@
|
|
30
30
|
|
31
31
|
namespace FIX
|
32
32
|
{
|
33
|
+
|
34
|
+
FieldMap::FieldMap( const message_order& order, int size )
|
35
|
+
: m_order(order)
|
36
|
+
{
|
37
|
+
m_fields.reserve(size);
|
38
|
+
}
|
39
|
+
|
40
|
+
FieldMap::FieldMap( const message_order& order /*= message_order(message_order::normal)*/)
|
41
|
+
: m_order(order)
|
42
|
+
{
|
43
|
+
m_fields.reserve(DEFAULT_SIZE);
|
44
|
+
}
|
45
|
+
|
46
|
+
FieldMap::FieldMap( const int order[] )
|
47
|
+
: m_order(message_order(order))
|
48
|
+
{
|
49
|
+
m_fields.reserve(DEFAULT_SIZE);
|
50
|
+
}
|
51
|
+
|
52
|
+
FieldMap::FieldMap( const FieldMap& copy )
|
53
|
+
{
|
54
|
+
*this = copy;
|
55
|
+
}
|
56
|
+
|
33
57
|
FieldMap::~FieldMap()
|
34
58
|
{
|
35
59
|
clear();
|
@@ -40,6 +64,7 @@ FieldMap& FieldMap::operator=( const FieldMap& rhs )
|
|
40
64
|
clear();
|
41
65
|
|
42
66
|
m_fields = rhs.m_fields;
|
67
|
+
m_order = rhs.m_order;
|
43
68
|
|
44
69
|
Groups::const_iterator i;
|
45
70
|
for ( i = rhs.m_groups.begin(); i != rhs.m_groups.end(); ++i )
|
@@ -99,24 +124,38 @@ void FieldMap::removeGroup( int num, int field )
|
|
99
124
|
|
100
125
|
if( vector.size() == 0 )
|
101
126
|
{
|
102
|
-
m_groups.erase(
|
127
|
+
m_groups.erase( i );
|
103
128
|
removeField( field );
|
104
129
|
}
|
105
130
|
else
|
106
131
|
{
|
107
132
|
IntField groupCount( field, (int)vector.size() );
|
108
|
-
setField( groupCount
|
133
|
+
setField( groupCount );
|
109
134
|
}
|
110
135
|
}
|
111
136
|
|
112
137
|
void FieldMap::removeGroup( int field )
|
113
138
|
{
|
114
|
-
|
139
|
+
Groups::iterator i = m_groups.find( field );
|
140
|
+
if ( i == m_groups.end() ) return;
|
141
|
+
|
142
|
+
removeField( field );
|
143
|
+
|
144
|
+
std::vector< FieldMap* > tmp;
|
145
|
+
tmp.swap( i->second );
|
146
|
+
|
147
|
+
m_groups.erase( i );
|
148
|
+
|
149
|
+
while ( !tmp.empty() )
|
150
|
+
{
|
151
|
+
delete tmp.back();
|
152
|
+
tmp.pop_back();
|
153
|
+
}
|
115
154
|
}
|
116
155
|
|
117
156
|
void FieldMap::removeField( int field )
|
118
157
|
{
|
119
|
-
Fields::iterator i =
|
158
|
+
Fields::iterator i = findTag( field );
|
120
159
|
if ( i != m_fields.end() )
|
121
160
|
m_fields.erase( i );
|
122
161
|
}
|
@@ -156,7 +195,7 @@ void FieldMap::clear()
|
|
156
195
|
|
157
196
|
bool FieldMap::isEmpty()
|
158
197
|
{
|
159
|
-
return m_fields.
|
198
|
+
return m_fields.empty();
|
160
199
|
}
|
161
200
|
|
162
201
|
size_t FieldMap::totalFields() const
|
@@ -178,11 +217,11 @@ std::string& FieldMap::calculateString( std::string& result ) const
|
|
178
217
|
Fields::const_iterator i;
|
179
218
|
for ( i = m_fields.begin(); i != m_fields.end(); ++i )
|
180
219
|
{
|
181
|
-
result += i->
|
220
|
+
result += i->getFixString();
|
182
221
|
|
183
222
|
// add groups if they exist
|
184
223
|
if( !m_groups.size() ) continue;
|
185
|
-
Groups::const_iterator j = m_groups.find( i->
|
224
|
+
Groups::const_iterator j = m_groups.find( i->getTag() );
|
186
225
|
if ( j == m_groups.end() ) continue;
|
187
226
|
std::vector < FieldMap* > ::const_iterator k;
|
188
227
|
for ( k = j->second.begin(); k != j->second.end(); ++k )
|
@@ -199,10 +238,11 @@ int FieldMap::calculateLength( int beginStringField,
|
|
199
238
|
Fields::const_iterator i;
|
200
239
|
for ( i = m_fields.begin(); i != m_fields.end(); ++i )
|
201
240
|
{
|
202
|
-
|
203
|
-
|
204
|
-
&&
|
205
|
-
|
241
|
+
int tag = i->getTag();
|
242
|
+
if ( tag != beginStringField
|
243
|
+
&& tag != bodyLengthField
|
244
|
+
&& tag != checkSumField )
|
245
|
+
{ result += i->getLength(); }
|
206
246
|
}
|
207
247
|
|
208
248
|
Groups::const_iterator j;
|
@@ -221,8 +261,8 @@ int FieldMap::calculateTotal( int checkSumField ) const
|
|
221
261
|
Fields::const_iterator i;
|
222
262
|
for ( i = m_fields.begin(); i != m_fields.end(); ++i )
|
223
263
|
{
|
224
|
-
if ( i->
|
225
|
-
result += i->
|
264
|
+
if ( i->getTag() != checkSumField )
|
265
|
+
result += i->getTotal();
|
226
266
|
}
|
227
267
|
|
228
268
|
Groups::const_iterator j;
|
data/ext/quickfix/FieldMap.h
CHANGED
@@ -45,31 +45,68 @@ namespace FIX
|
|
45
45
|
*/
|
46
46
|
class FieldMap
|
47
47
|
{
|
48
|
+
|
49
|
+
class sorter
|
50
|
+
{
|
51
|
+
public:
|
52
|
+
explicit sorter( const message_order& order ) : m_order( order ) {}
|
53
|
+
|
54
|
+
bool operator()( int tag, const FieldBase& right ) const
|
55
|
+
{
|
56
|
+
return m_order( tag, right.getTag() );
|
57
|
+
}
|
58
|
+
|
59
|
+
bool operator()( const FieldBase& left, int tag ) const
|
60
|
+
{
|
61
|
+
return m_order( left.getTag(), tag );
|
62
|
+
}
|
63
|
+
|
64
|
+
bool operator()( const FieldBase& left, const FieldBase& right ) const
|
65
|
+
{
|
66
|
+
return m_order( left.getTag(), right.getTag() );
|
67
|
+
}
|
68
|
+
|
69
|
+
private:
|
70
|
+
const message_order& m_order;
|
71
|
+
};
|
72
|
+
|
73
|
+
class finder
|
74
|
+
{
|
75
|
+
public:
|
76
|
+
explicit finder( int tag ) : m_tag( tag ) {}
|
77
|
+
|
78
|
+
bool operator()( const FieldBase& field ) const
|
79
|
+
{
|
80
|
+
return m_tag == field.getTag();
|
81
|
+
}
|
82
|
+
|
83
|
+
private:
|
84
|
+
int m_tag;
|
85
|
+
};
|
86
|
+
|
87
|
+
enum { DEFAULT_SIZE = 16 };
|
88
|
+
|
89
|
+
protected:
|
90
|
+
|
91
|
+
FieldMap( const message_order& order, int size );
|
92
|
+
|
48
93
|
public:
|
49
|
-
|
50
|
-
typedef std::
|
51
|
-
typedef std::map < int, std::vector < FieldMap* >, std::less<int
|
52
|
-
#else
|
53
|
-
typedef std::multimap < int, FieldBase, message_order,
|
54
|
-
ALLOCATOR<std::pair<const int,FieldBase> > > Fields;
|
55
|
-
typedef std::map < int, std::vector < FieldMap* >, std::less<int>,
|
94
|
+
|
95
|
+
typedef std::vector < FieldBase, ALLOCATOR< FieldBase > > Fields;
|
96
|
+
typedef std::map < int, std::vector < FieldMap* >, std::less<int>,
|
56
97
|
ALLOCATOR<std::pair<const int, std::vector< FieldMap* > > > > Groups;
|
57
|
-
#endif
|
58
98
|
|
59
|
-
typedef Fields::
|
60
|
-
typedef
|
61
|
-
typedef Groups::
|
99
|
+
typedef Fields::iterator iterator;
|
100
|
+
typedef Fields::const_iterator const_iterator;
|
101
|
+
typedef Groups::iterator g_iterator;
|
62
102
|
typedef Groups::const_iterator g_const_iterator;
|
63
103
|
|
64
104
|
FieldMap( const message_order& order =
|
65
|
-
message_order( message_order::normal ) )
|
66
|
-
: m_fields( order ) {}
|
105
|
+
message_order( message_order::normal ) );
|
67
106
|
|
68
|
-
FieldMap( const int order[] )
|
69
|
-
: m_fields( message_order(order) ) {}
|
107
|
+
FieldMap( const int order[] );
|
70
108
|
|
71
|
-
FieldMap( const FieldMap& copy )
|
72
|
-
{ *this = copy; }
|
109
|
+
FieldMap( const FieldMap& copy );
|
73
110
|
|
74
111
|
virtual ~FieldMap();
|
75
112
|
|
@@ -79,32 +116,39 @@ public:
|
|
79
116
|
void setField( const FieldBase& field, bool overwrite = true )
|
80
117
|
throw( RepeatedTag )
|
81
118
|
{
|
82
|
-
|
83
|
-
|
119
|
+
if( !overwrite )
|
120
|
+
{
|
121
|
+
addField( field );
|
122
|
+
}
|
123
|
+
else
|
124
|
+
{
|
125
|
+
Fields::iterator i = findTag( field.getTag() );
|
126
|
+
if( i == m_fields.end() )
|
127
|
+
{
|
128
|
+
addField( field );
|
129
|
+
}
|
84
130
|
else
|
85
131
|
{
|
86
|
-
|
87
|
-
if( i == m_fields.end() )
|
88
|
-
m_fields.insert( Fields::value_type( field.getField(), field ) );
|
89
|
-
else
|
90
|
-
i->second = field;
|
132
|
+
i->setString( field.getString() );
|
91
133
|
}
|
134
|
+
}
|
92
135
|
}
|
136
|
+
|
93
137
|
/// Set a field without a field class
|
94
|
-
void setField( int
|
138
|
+
void setField( int tag, const std::string& value )
|
95
139
|
throw( RepeatedTag, NoTagValue )
|
96
140
|
{
|
97
|
-
FieldBase fieldBase(
|
141
|
+
FieldBase fieldBase( tag, value );
|
98
142
|
setField( fieldBase );
|
99
143
|
}
|
100
144
|
|
101
145
|
/// Get a field if set
|
102
146
|
bool getFieldIfSet( FieldBase& field ) const
|
103
147
|
{
|
104
|
-
Fields::const_iterator iter =
|
148
|
+
Fields::const_iterator iter = findTag( field.getTag() );
|
105
149
|
if ( iter == m_fields.end() )
|
106
150
|
return false;
|
107
|
-
field = iter
|
151
|
+
field = (*iter);
|
108
152
|
return true;
|
109
153
|
}
|
110
154
|
|
@@ -112,89 +156,89 @@ public:
|
|
112
156
|
FieldBase& getField( FieldBase& field )
|
113
157
|
const throw( FieldNotFound )
|
114
158
|
{
|
115
|
-
field = getFieldRef( field.
|
159
|
+
field = getFieldRef( field.getTag() );
|
116
160
|
return field;
|
117
161
|
}
|
118
162
|
|
119
163
|
/// Get a field without a field class
|
120
|
-
const std::string& getField( int
|
164
|
+
const std::string& getField( int tag )
|
121
165
|
const throw( FieldNotFound )
|
122
166
|
{
|
123
|
-
return getFieldRef(
|
167
|
+
return getFieldRef( tag ).getString();
|
124
168
|
}
|
125
169
|
|
126
170
|
/// Get direct access to a field through a reference
|
127
|
-
const FieldBase& getFieldRef( int
|
171
|
+
const FieldBase& getFieldRef( int tag )
|
128
172
|
const throw( FieldNotFound )
|
129
173
|
{
|
130
|
-
Fields::const_iterator iter =
|
174
|
+
Fields::const_iterator iter = findTag( tag );
|
131
175
|
if ( iter == m_fields.end() )
|
132
|
-
throw FieldNotFound(
|
133
|
-
return iter
|
176
|
+
throw FieldNotFound( tag );
|
177
|
+
return (*iter);
|
134
178
|
}
|
135
179
|
|
136
180
|
/// Get direct access to a field through a pointer
|
137
|
-
const FieldBase* const getFieldPtr( int
|
181
|
+
const FieldBase* const getFieldPtr( int tag )
|
138
182
|
const throw( FieldNotFound )
|
139
183
|
{
|
140
|
-
return &getFieldRef(
|
184
|
+
return &getFieldRef( tag );
|
141
185
|
}
|
142
186
|
|
143
187
|
/// Check to see if a field is set
|
144
188
|
bool isSetField( const FieldBase& field ) const
|
145
|
-
{ return isSetField( field.
|
189
|
+
{ return isSetField( field.getTag() ); }
|
146
190
|
/// Check to see if a field is set by referencing its number
|
147
|
-
bool isSetField( int
|
148
|
-
{ return
|
191
|
+
bool isSetField( int tag ) const
|
192
|
+
{ return findTag( tag ) != m_fields.end(); }
|
149
193
|
|
150
194
|
/// Remove a field. If field is not present, this is a no-op.
|
151
|
-
void removeField( int
|
195
|
+
void removeField( int tag );
|
152
196
|
|
153
197
|
/// Add a group.
|
154
|
-
void addGroup( int
|
198
|
+
void addGroup( int tag, const FieldMap& group, bool setCount = true );
|
155
199
|
|
156
200
|
/// Acquire ownership of Group object
|
157
|
-
void addGroupPtr( int
|
201
|
+
void addGroupPtr( int tag, FieldMap * group, bool setCount = true );
|
158
202
|
|
159
203
|
/// Replace a specific instance of a group.
|
160
|
-
void replaceGroup( int num, int
|
204
|
+
void replaceGroup( int num, int tag, const FieldMap& group );
|
161
205
|
|
162
206
|
/// Get a specific instance of a group.
|
163
|
-
FieldMap& getGroup( int num, int
|
207
|
+
FieldMap& getGroup( int num, int tag, FieldMap& group ) const
|
164
208
|
throw( FieldNotFound )
|
165
209
|
{
|
166
|
-
return group = getGroupRef( num,
|
210
|
+
return group = getGroupRef( num, tag );
|
167
211
|
}
|
168
212
|
|
169
213
|
/// Get direct access to a field through a reference
|
170
|
-
FieldMap& getGroupRef( int num, int
|
214
|
+
FieldMap& getGroupRef( int num, int tag ) const
|
171
215
|
throw( FieldNotFound )
|
172
216
|
{
|
173
|
-
Groups::const_iterator i = m_groups.find(
|
174
|
-
if( i == m_groups.end() ) throw FieldNotFound(
|
175
|
-
if( num <= 0 ) throw FieldNotFound(
|
176
|
-
if( i->second.size() < (unsigned)num ) throw FieldNotFound(
|
217
|
+
Groups::const_iterator i = m_groups.find( tag );
|
218
|
+
if( i == m_groups.end() ) throw FieldNotFound( tag );
|
219
|
+
if( num <= 0 ) throw FieldNotFound( tag );
|
220
|
+
if( i->second.size() < (unsigned)num ) throw FieldNotFound( tag );
|
177
221
|
return *( *(i->second.begin() + (num-1) ) );
|
178
222
|
}
|
179
223
|
|
180
224
|
/// Get direct access to a field through a pointer
|
181
|
-
FieldMap* getGroupPtr( int num, int
|
225
|
+
FieldMap* getGroupPtr( int num, int tag ) const
|
182
226
|
throw( FieldNotFound )
|
183
227
|
{
|
184
|
-
return &getGroupRef( num,
|
228
|
+
return &getGroupRef( num, tag );
|
185
229
|
}
|
186
230
|
|
187
231
|
/// Remove a specific instance of a group.
|
188
|
-
void removeGroup( int num, int
|
232
|
+
void removeGroup( int num, int tag );
|
189
233
|
/// Remove all instances of a group.
|
190
|
-
void removeGroup( int
|
234
|
+
void removeGroup( int tag );
|
191
235
|
|
192
236
|
/// Check to see any instance of a group exists
|
193
|
-
bool hasGroup( int
|
237
|
+
bool hasGroup( int tag ) const;
|
194
238
|
/// Check to see if a specific instance of a group exists
|
195
|
-
bool hasGroup( int num, int
|
239
|
+
bool hasGroup( int num, int tag ) const;
|
196
240
|
/// Count the number of instance of a group
|
197
|
-
size_t groupCount( int
|
241
|
+
size_t groupCount( int tag ) const;
|
198
242
|
|
199
243
|
/// Clear all fields from the map
|
200
244
|
void clear();
|
@@ -211,14 +255,108 @@ public:
|
|
211
255
|
|
212
256
|
int calculateTotal( int checkSumField = FIELD::CheckSum ) const;
|
213
257
|
|
214
|
-
iterator begin()
|
215
|
-
iterator end()
|
216
|
-
|
217
|
-
|
258
|
+
iterator begin() { return m_fields.begin(); }
|
259
|
+
iterator end() { return m_fields.end(); }
|
260
|
+
const_iterator begin() const { return m_fields.begin(); }
|
261
|
+
const_iterator end() const { return m_fields.end(); }
|
262
|
+
g_iterator g_begin() { return m_groups.begin(); }
|
263
|
+
g_iterator g_end() { return m_groups.end(); }
|
264
|
+
g_const_iterator g_begin() const { return m_groups.begin(); }
|
265
|
+
g_const_iterator g_end() const { return m_groups.end(); }
|
266
|
+
|
267
|
+
protected:
|
268
|
+
|
269
|
+
friend class Message;
|
270
|
+
|
271
|
+
void addField( const FieldBase& field )
|
272
|
+
{
|
273
|
+
Fields::iterator iter = findPositionFor( field.getTag() );
|
274
|
+
if( iter == m_fields.end() )
|
275
|
+
{
|
276
|
+
m_fields.push_back( field );
|
277
|
+
}
|
278
|
+
else
|
279
|
+
{
|
280
|
+
m_fields.insert( iter, field );
|
281
|
+
}
|
282
|
+
}
|
283
|
+
|
284
|
+
// used to find data length fields during message decoding
|
285
|
+
// message fields are not yet sorted so regular find*** functions might return wrong results
|
286
|
+
const FieldBase& reverse_find( int tag ) const
|
287
|
+
{
|
288
|
+
Fields::const_reverse_iterator iter = std::find_if( m_fields.rbegin(), m_fields.rend(), finder( tag ) );
|
289
|
+
if( iter == m_fields.rend() )
|
290
|
+
throw FieldNotFound( tag );
|
291
|
+
|
292
|
+
return *iter;
|
293
|
+
}
|
294
|
+
|
295
|
+
// append field to message without sorting
|
296
|
+
// only applicable during message decoding
|
297
|
+
void appendField( const FieldBase& field )
|
298
|
+
{
|
299
|
+
m_fields.push_back( field );
|
300
|
+
}
|
301
|
+
|
302
|
+
// sort fields after message decoding
|
303
|
+
void sortFields()
|
304
|
+
{
|
305
|
+
std::sort( m_fields.begin(), m_fields.end(), sorter(m_order) );
|
306
|
+
}
|
218
307
|
|
219
308
|
private:
|
309
|
+
|
310
|
+
Fields::const_iterator findTag( int tag ) const
|
311
|
+
{
|
312
|
+
return lookup( m_fields.begin(), m_fields.end(), tag );
|
313
|
+
}
|
314
|
+
|
315
|
+
Fields::iterator findTag( int tag )
|
316
|
+
{
|
317
|
+
return lookup( m_fields.begin(), m_fields.end(), tag );
|
318
|
+
}
|
319
|
+
|
320
|
+
template <typename Iterator>
|
321
|
+
Iterator lookup(Iterator begin, Iterator end, int tag) const
|
322
|
+
{
|
323
|
+
#if defined(__SUNPRO_CC)
|
324
|
+
std::size_t numElements;
|
325
|
+
std::distance( begin, end, numElements );
|
326
|
+
#else
|
327
|
+
std::size_t numElements = std::distance( begin, end );
|
328
|
+
#endif
|
329
|
+
if( numElements < 16 )
|
330
|
+
return std::find_if( begin, end, finder( tag ) );
|
331
|
+
|
332
|
+
Iterator iter = std::lower_bound( begin, end, tag, sorter( m_order ) );
|
333
|
+
if( iter != end &&
|
334
|
+
iter->getTag() == tag )
|
335
|
+
{
|
336
|
+
return iter;
|
337
|
+
}
|
338
|
+
|
339
|
+
return end;
|
340
|
+
}
|
341
|
+
|
342
|
+
Fields::iterator findPositionFor( int tag )
|
343
|
+
{
|
344
|
+
if( m_fields.empty() )
|
345
|
+
return m_fields.end();
|
346
|
+
|
347
|
+
const FieldBase& last = m_fields.back();
|
348
|
+
if( m_order( last.getTag(), tag ) ||
|
349
|
+
last.getTag() == tag )
|
350
|
+
{
|
351
|
+
return m_fields.end();
|
352
|
+
}
|
353
|
+
|
354
|
+
return std::upper_bound( m_fields.begin(), m_fields.end(), tag, sorter( m_order ) );
|
355
|
+
}
|
356
|
+
|
220
357
|
Fields m_fields;
|
221
358
|
Groups m_groups;
|
359
|
+
message_order m_order;
|
222
360
|
};
|
223
361
|
/*! @} */
|
224
362
|
}
|