FieldMap.h
Go to the documentation of this file.
1/* -*- C++ -*- */
2
3/****************************************************************************
4** Copyright (c) 2001-2014
5**
6** This file is part of the QuickFIX FIX Engine
7**
8** This file may be distributed under the terms of the quickfixengine.org
9** license as defined by quickfixengine.org and appearing in the file
10** LICENSE included in the packaging of this file.
11**
12** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14**
15** See http://www.quickfixengine.org/LICENSE for licensing information.
16**
17** Contact ask@quickfixengine.org if any conditions of this licensing are
18** not clear to you.
19**
20****************************************************************************/
21
22#ifndef FIX_FIELDMAP
23#define FIX_FIELDMAP
24
25#ifdef _MSC_VER
26#pragma warning( disable: 4786 )
27#endif
28
29#include "Field.h"
30#include "MessageSorters.h"
31#include "Exceptions.h"
32#include "Utility.h"
33#include <map>
34#include <vector>
35#include <sstream>
36#include <algorithm>
37
38namespace FIX
39{
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:
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
89protected:
90
91 FieldMap( const message_order& order, int size );
92
93public:
94
95 typedef std::vector < FieldBase, ALLOCATOR< FieldBase > > Fields;
96 typedef std::map < int, std::vector < FieldMap* >, std::less<int>,
97 ALLOCATOR<std::pair<const int, std::vector< FieldMap* > > > > Groups;
98
99 typedef Fields::iterator iterator;
100 typedef Fields::const_iterator const_iterator;
101 typedef Groups::iterator g_iterator;
102 typedef Groups::const_iterator g_const_iterator;
103
104 FieldMap( const message_order& order =
106
107 FieldMap( const int order[] );
108
109 FieldMap( const FieldMap& copy );
110
111 virtual ~FieldMap();
112
113 FieldMap& operator=( const FieldMap& rhs );
114
116 void setField( const FieldBase& field, bool overwrite = true )
117 throw( RepeatedTag )
118 {
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 }
130 else
131 {
132 i->setString( field.getString() );
133 }
134 }
135 }
136
138 void setField( int tag, const std::string& value )
139 throw( RepeatedTag, NoTagValue )
140 {
141 FieldBase fieldBase( tag, value );
142 setField( fieldBase );
143 }
144
146 bool getFieldIfSet( FieldBase& field ) const
147 {
148 Fields::const_iterator iter = findTag( field.getTag() );
149 if ( iter == m_fields.end() )
150 return false;
151 field = (*iter);
152 return true;
153 }
154
157 const throw( FieldNotFound )
158 {
159 field = getFieldRef( field.getTag() );
160 return field;
161 }
162
164 const std::string& getField( int tag )
165 const throw( FieldNotFound )
166 {
167 return getFieldRef( tag ).getString();
168 }
169
171 const FieldBase& getFieldRef( int tag )
172 const throw( FieldNotFound )
173 {
174 Fields::const_iterator iter = findTag( tag );
175 if ( iter == m_fields.end() )
176 throw FieldNotFound( tag );
177 return (*iter);
178 }
179
181 const FieldBase* const getFieldPtr( int tag )
182 const throw( FieldNotFound )
183 {
184 return &getFieldRef( tag );
185 }
186
188 bool isSetField( const FieldBase& field ) const
189 { return isSetField( field.getTag() ); }
191 bool isSetField( int tag ) const
192 { return findTag( tag ) != m_fields.end(); }
193
195 void removeField( int tag );
196
198 void addGroup( int tag, const FieldMap& group, bool setCount = true );
199
201 void addGroupPtr( int tag, FieldMap * group, bool setCount = true );
202
204 void replaceGroup( int num, int tag, const FieldMap& group );
205
207 FieldMap& getGroup( int num, int tag, FieldMap& group ) const
208 throw( FieldNotFound )
209 {
210 return group = getGroupRef( num, tag );
211 }
212
214 FieldMap& getGroupRef( int num, int tag ) const
215 throw( FieldNotFound )
216 {
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 );
221 return *( *(i->second.begin() + (num-1) ) );
222 }
223
225 FieldMap* getGroupPtr( int num, int tag ) const
226 throw( FieldNotFound )
227 {
228 return &getGroupRef( num, tag );
229 }
230
232 void removeGroup( int num, int tag );
234 void removeGroup( int tag );
235
237 bool hasGroup( int tag ) const;
239 bool hasGroup( int num, int tag ) const;
241 size_t groupCount( int tag ) const;
242
244 void clear();
246 bool isEmpty();
247
248 size_t totalFields() const;
249
250 std::string& calculateString( std::string& ) const;
251
252 int calculateLength( int beginStringField = FIELD::BeginString,
253 int bodyLengthField = FIELD::BodyLength,
254 int checkSumField = FIELD::CheckSum ) const;
255
256 int calculateTotal( int checkSumField = FIELD::CheckSum ) const;
257
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
267protected:
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
304 {
305 std::sort( m_fields.begin(), m_fields.end(), sorter(m_order) );
306 }
307
308private:
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
360};
362}
363
364#define FIELD_SET( MAP, FIELD ) \
365bool isSet( const FIELD& field ) const \
366{ return (MAP).isSetField(field); } \
367void set( const FIELD& field ) \
368{ (MAP).setField(field); } \
369FIELD& get( FIELD& field ) const \
370{ return (FIELD&)(MAP).getField(field); } \
371bool getIfSet( FIELD& field ) const \
372{ return (MAP).getFieldIfSet(field); }
373
374#define FIELD_GET_PTR( MAP, FLD ) \
375(const FIX::FLD*)MAP.getFieldPtr( FIX::FIELD::FLD )
376#define FIELD_GET_REF( MAP, FLD ) \
377(const FIX::FLD&)MAP.getFieldRef( FIX::FIELD::FLD )
378#define FIELD_THROW_IF_NOT_FOUND( MAP, FLD ) \
379if( !(MAP).isSetField( FIX::FIELD::FLD) ) \
380 throw FieldNotFound( FIX::FIELD::FLD )
381#endif //FIX_FIELDMAP
382
Base representation of all Field classes.
Definition Field.h:50
const std::string & getString() const
Get the string representation of the fields value.
Definition Field.h:152
int getTag() const
Get the fields integer tag.
Definition Field.h:144
bool operator()(const FieldBase &field) const
Definition FieldMap.h:78
const message_order & m_order
Definition FieldMap.h:70
sorter(const message_order &order)
Definition FieldMap.h:52
bool operator()(int tag, const FieldBase &right) const
Definition FieldMap.h:54
bool operator()(const FieldBase &left, int tag) const
Definition FieldMap.h:59
bool operator()(const FieldBase &left, const FieldBase &right) const
Definition FieldMap.h:64
Stores and organizes a collection of Fields.
Definition FieldMap.h:47
std::vector< FieldBase, ALLOCATOR< FieldBase > > Fields
Definition FieldMap.h:95
void setField(const FieldBase &field, bool overwrite=true)
Set a field without type checking.
Definition FieldMap.h:116
void replaceGroup(int num, int tag, const FieldMap &group)
Replace a specific instance of a group.
Definition FieldMap.cpp:102
void sortFields()
Definition FieldMap.h:303
void addField(const FieldBase &field)
Definition FieldMap.h:271
Fields::iterator iterator
Definition FieldMap.h:99
bool isEmpty()
Check if map contains any fields.
Definition FieldMap.cpp:196
iterator begin()
Definition FieldMap.h:258
void appendField(const FieldBase &field)
Definition FieldMap.h:297
Groups::iterator g_iterator
Definition FieldMap.h:101
g_iterator g_begin()
Definition FieldMap.h:262
Fields::const_iterator findTag(int tag) const
Definition FieldMap.h:310
int calculateLength(int beginStringField=FIELD::BeginString, int bodyLengthField=FIELD::BodyLength, int checkSumField=FIELD::CheckSum) const
Definition FieldMap.cpp:233
void removeField(int tag)
Remove a field. If field is not present, this is a no-op.
Definition FieldMap.cpp:156
const_iterator end() const
Definition FieldMap.h:261
std::map< int, std::vector< FieldMap * >, std::less< int >, ALLOCATOR< std::pair< const int, std::vector< FieldMap * > > > > Groups
Definition FieldMap.h:97
FieldMap * getGroupPtr(int num, int tag) const
Get direct access to a field through a pointer.
Definition FieldMap.h:225
Iterator lookup(Iterator begin, Iterator end, int tag) const
Definition FieldMap.h:321
Groups::const_iterator g_const_iterator
Definition FieldMap.h:102
FieldMap & getGroupRef(int num, int tag) const
Get direct access to a field through a reference.
Definition FieldMap.h:214
g_const_iterator g_end() const
Definition FieldMap.h:265
iterator end()
Definition FieldMap.h:259
void clear()
Clear all fields from the map.
Definition FieldMap.cpp:182
FieldBase & getField(FieldBase &field) const
Get a field without type checking.
Definition FieldMap.h:156
message_order m_order
Definition FieldMap.h:359
void setField(int tag, const std::string &value)
Set a field without a field class.
Definition FieldMap.h:138
Groups m_groups
Definition FieldMap.h:358
bool hasGroup(int tag) const
Check to see any instance of a group exists.
Definition FieldMap.cpp:168
void addGroupPtr(int tag, FieldMap *group, bool setCount=true)
Acquire ownership of Group object.
Definition FieldMap.cpp:90
bool getFieldIfSet(FieldBase &field) const
Get a field if set.
Definition FieldMap.h:146
Fields::const_iterator const_iterator
Definition FieldMap.h:100
const FieldBase & getFieldRef(int tag) const
Get direct access to a field through a reference.
Definition FieldMap.h:171
std::string & calculateString(std::string &) const
Definition FieldMap.cpp:215
const FieldBase & reverse_find(int tag) const
Definition FieldMap.h:286
Fields::iterator findPositionFor(int tag)
Definition FieldMap.h:342
virtual ~FieldMap()
Definition FieldMap.cpp:57
const_iterator begin() const
Definition FieldMap.h:260
g_iterator g_end()
Definition FieldMap.h:263
void addGroup(int tag, const FieldMap &group, bool setCount=true)
Add a group.
Definition FieldMap.cpp:83
FieldMap & operator=(const FieldMap &rhs)
Definition FieldMap.cpp:62
int calculateTotal(int checkSumField=FIELD::CheckSum) const
Definition FieldMap.cpp:258
size_t totalFields() const
Definition FieldMap.cpp:201
Fields m_fields
Definition FieldMap.h:357
void removeGroup(int num, int tag)
Remove a specific instance of a group.
Definition FieldMap.cpp:111
bool isSetField(const FieldBase &field) const
Check to see if a field is set.
Definition FieldMap.h:188
FieldMap & getGroup(int num, int tag, FieldMap &group) const
Get a specific instance of a group.
Definition FieldMap.h:207
const FieldBase *const getFieldPtr(int tag) const
Get direct access to a field through a pointer.
Definition FieldMap.h:181
bool isSetField(int tag) const
Check to see if a field is set by referencing its number.
Definition FieldMap.h:191
const std::string & getField(int tag) const
Get a field without a field class.
Definition FieldMap.h:164
size_t groupCount(int tag) const
Count the number of instance of a group.
Definition FieldMap.cpp:174
g_const_iterator g_begin() const
Definition FieldMap.h:264
Fields::iterator findTag(int tag)
Definition FieldMap.h:315
Base class for all FIX messages.
Definition Message.h:118
Field not found inside a message.
Definition Exceptions.h:58
Field exists in message without a value.
Definition Exceptions.h:129
Repeated tag not part of repeating group.
Definition Exceptions.h:200
Sorts fields in header, normal, or trailer order.

Generated on Thu Feb 29 2024 22:38:19 for QuickFIX by doxygen 1.9.8 written by Dimitri van Heesch, © 1997-2001