DataDictionary.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_DATADICTIONARY_H
23 #define FIX_DATADICTIONARY_H
24 
25 #ifdef _MSC_VER
26 #pragma warning( disable : 4503 4355 4786 4290 )
27 #endif
28 
29 #include "Fields.h"
30 #include "FieldMap.h"
31 #include "DOMDocument.h"
32 #include "Exceptions.h"
33 #include <set>
34 #include <map>
35 #include <string.h>
36 
37 namespace FIX
38 {
39 class FieldMap;
40 class Message;
41 
50 {
51  typedef std::set < int > MsgFields;
52  typedef std::map < std::string, MsgFields > MsgTypeToField;
53  typedef std::set < std::string > MsgTypes;
54  typedef std::set < int > Fields;
55  typedef std::map < int, bool > NonBodyFields;
56  typedef std::vector< int > OrderedFields;
58  typedef std::map < int, TYPE::Type > FieldTypes;
59  typedef std::set < std::string > Values;
60  typedef std::map < int, Values > FieldToValue;
61  typedef std::map < int, std::string > FieldToName;
62  typedef std::map < std::string, int > NameToField;
63  typedef std::map < std::pair < int, std::string > , std::string > ValueToName;
64  // while FieldToGroup structure seems to be overcomplicated
65  // in reality it yields a lot of performance because:
66  // 1) avoids memory copying;
67  // 2) first lookup is done by comparing integers and not string objects
68  // TODO: use hash_map with good hashing algorithm
69  typedef std::map < std::string, std::pair < int, DataDictionary* > > FieldPresenceMap;
70  typedef std::map < int, FieldPresenceMap > FieldToGroup;
71 
72 public:
74  DataDictionary( const DataDictionary& copy );
75  DataDictionary( std::istream& stream ) throw( ConfigError );
76  DataDictionary( const std::string& url ) throw( ConfigError );
77  virtual ~DataDictionary();
78 
79  void readFromURL( const std::string& url ) throw( ConfigError );
80  void readFromDocument( DOMDocumentPtr pDoc ) throw( ConfigError );
81  void readFromStream( std::istream& stream ) throw( ConfigError );
82 
83  message_order const& getOrderedFields() const;
84 
85  // storage functions
86  void setVersion( const std::string& beginString )
87  {
88  m_beginString = beginString;
89  m_hasVersion = true;
90  }
91  std::string getVersion() const
92  {
93  return m_beginString.getString();
94  }
95 
96  void addField( int field )
97  {
98  m_fields.insert( field );
99  m_orderedFields.push_back( field );
100  }
101 
102  void addFieldName( int field, const std::string& name )
103  {
104  if( m_names.insert( std::make_pair(name, field) ).second == false )
105  throw ConfigError( "Field named " + name + " defined multiple times" );
106  m_fieldNames[field] = name;
107  }
108 
109  bool getFieldName( int field, std::string& name ) const
110  {
111  FieldToName::const_iterator i = m_fieldNames.find( field );
112  if(i == m_fieldNames.end()) return false;
113  name = i->second;
114  return true;
115  }
116 
117  bool getFieldTag( const std::string& name, int& field ) const
118  {
119  NameToField::const_iterator i = m_names.find( name );
120  if(i == m_names.end()) return false;
121  field = i->second;
122  return true;
123  }
124 
125  void addValueName( int field, const std::string& value, const std::string& name )
126  {
127  m_valueNames[std::make_pair(field, value)] = name;
128  }
129 
130  bool getValueName( int field, const std::string& value, std::string& name ) const
131  {
132  ValueToName::const_iterator i = m_valueNames.find( std::make_pair(field, value) );
133  if(i == m_valueNames.end()) return false;
134  name = i->second;
135  return true;
136  }
137 
138  bool isField( int field ) const
139  {
140  return m_fields.find( field ) != m_fields.end();
141  }
142 
143  void addMsgType( const std::string& msgType )
144  {
145  m_messages.insert( msgType );
146  }
147 
148  bool isMsgType( const std::string& msgType ) const
149  {
150  return m_messages.find( msgType ) != m_messages.end();
151  }
152 
153  void addMsgField( const std::string& msgType, int field )
154  {
155  m_messageFields[ msgType ].insert( field );
156  }
157 
158  bool isMsgField( const std::string& msgType, int field ) const
159  {
160  MsgTypeToField::const_iterator i = m_messageFields.find( msgType );
161  if ( i == m_messageFields.end() ) return false;
162  return i->second.find( field ) != i->second.end();
163  }
164 
165  void addHeaderField( int field, bool required )
166  {
167  m_headerFields[ field ] = required;
168  }
169 
170  bool isHeaderField( int field ) const
171  {
172  return m_headerFields.find( field ) != m_headerFields.end();
173  }
174 
175  void addTrailerField( int field, bool required )
176  {
177  m_trailerFields[ field ] = required;
178  }
179 
180  bool isTrailerField( int field ) const
181  {
182  return m_trailerFields.find( field ) != m_trailerFields.end();
183  }
184 
185  void addFieldType( int field, FIX::TYPE::Type type )
186  {
187  m_fieldTypes[ field ] = type;
188 
189  if( type == FIX::TYPE::Data )
190  m_dataFields.insert( field );
191  }
192 
193  bool getFieldType( int field, FIX::TYPE::Type& type ) const
194  {
195  FieldTypes::const_iterator i = m_fieldTypes.find( field );
196  if ( i == m_fieldTypes.end() ) return false;
197  type = i->second;
198  return true;
199  }
200 
201  void addRequiredField( const std::string& msgType, int field )
202  {
203  m_requiredFields[ msgType ].insert( field );
204  }
205 
206  bool isRequiredField( const std::string& msgType, int field ) const
207  {
208  MsgTypeToField::const_iterator i = m_requiredFields.find( msgType );
209  if ( i == m_requiredFields.end() ) return false;
210  return i->second.find( field ) != i->second.end();
211  }
212 
213  void addFieldValue( int field, const std::string& value )
214  {
215  m_fieldValues[ field ].insert( value );
216  }
217 
218  bool hasFieldValue( int field ) const
219  {
220  FieldToValue::const_iterator i = m_fieldValues.find( field );
221  return i != m_fieldValues.end();
222  }
223 
224  bool isFieldValue( int field, const std::string& value ) const
225  {
226  FieldToValue::const_iterator i = m_fieldValues.find( field );
227  if ( i == m_fieldValues.end() )
228  return false;
229  if( !isMultipleValueField( field ) )
230  return i->second.find( value ) != i->second.end();
231 
232  // MultipleValue
233  std::string::size_type startPos = 0;
234  std::string::size_type endPos = 0;
235  do
236  {
237  endPos = value.find_first_of(' ', startPos);
238  std::string singleValue =
239  value.substr( startPos, endPos - startPos );
240  if( i->second.find( singleValue ) == i->second.end() )
241  return false;
242  startPos = endPos + 1;
243  } while( endPos != std::string::npos );
244  return true;
245  }
246 
247  void addGroup( const std::string& msg, int field, int delim,
248  const DataDictionary& dataDictionary )
249  {
250  DataDictionary * pDD = new DataDictionary( dataDictionary );
251  pDD->setVersion( getVersion() );
252 
253  FieldPresenceMap& presenceMap = m_groups[ field ];
254  presenceMap[ msg ] = std::make_pair( delim, pDD );
255  }
256 
257  bool isGroup( const std::string& msg, int field ) const
258  {
259  FieldToGroup::const_iterator i = m_groups.find( field );
260  if ( i == m_groups.end() ) return false;
261 
262  const FieldPresenceMap& presenceMap = i->second;
263 
264  FieldPresenceMap::const_iterator iter = presenceMap.find( msg );
265  return ( iter != presenceMap.end() );
266  }
267 
268  bool getGroup( const std::string& msg, int field, int& delim,
269  const DataDictionary*& pDataDictionary ) const
270  {
271  FieldToGroup::const_iterator i = m_groups.find( field );
272  if ( i == m_groups.end() ) return false;
273 
274  const FieldPresenceMap& presenceMap = i->second;
275 
276  FieldPresenceMap::const_iterator iter = presenceMap.find( msg );
277  if( iter == presenceMap.end() ) return false;
278 
279  std::pair < int, DataDictionary* > pair = iter->second;
280  delim = pair.first;
281  pDataDictionary = pair.second;
282  return true;
283  }
284 
285  bool isDataField( int field ) const
286  {
287  MsgFields::const_iterator iter = m_dataFields.find( field );
288  return iter != m_dataFields.end();
289  }
290 
291  bool isMultipleValueField( int field ) const
292  {
293  FieldTypes::const_iterator i = m_fieldTypes.find( field );
294  return i != m_fieldTypes.end()
295  && (i->second == TYPE::MultipleValueString
296  || i->second == TYPE::MultipleCharValue
297  || i->second == TYPE::MultipleStringValue );
298  }
299 
300  void checkFieldsOutOfOrder( bool value )
301  { m_checkFieldsOutOfOrder = value; }
302  void checkFieldsHaveValues( bool value )
303  { m_checkFieldsHaveValues = value; }
304  void checkUserDefinedFields( bool value )
305  { m_checkUserDefinedFields = value; }
306 
308  static void validate( const Message& message,
309  const DataDictionary* const pSessionDD,
310  const DataDictionary* const pAppID ) throw( FIX::Exception );
311 
312  void validate( const Message& message ) const throw ( FIX::Exception )
313  { validate( message, false ); }
314  void validate( const Message& message, bool bodyOnly ) const throw( FIX::Exception )
315  { validate( message, bodyOnly ? (DataDictionary*)0 : this, this ); }
316 
317  DataDictionary& operator=( const DataDictionary& rhs );
318 
319 private:
321  void iterate( const FieldMap& map, const MsgType& msgType ) const;
322 
324  void checkMsgType( const MsgType& msgType ) const
325  {
326  if ( !isMsgType( msgType.getValue() ) )
327  throw InvalidMessageType();
328  }
329 
331  bool shouldCheckTag( const FieldBase& field ) const
332  {
334  return false;
335  else
336  return true;
337  }
338 
340  void checkValidTagNumber( const FieldBase& field ) const
341  throw( InvalidTagNumber )
342  {
343  if( m_fields.find( field.getField() ) == m_fields.end() )
344  throw InvalidTagNumber( field.getField() );
345  }
346 
347  void checkValidFormat( const FieldBase& field ) const
348  throw( IncorrectDataFormat )
349  {
350  try
351  {
352  TYPE::Type type = TYPE::Unknown;
353  getFieldType( field.getField(), type );
354  switch ( type )
355  {
356  case TYPE::String:
357  STRING_CONVERTOR::convert( field.getString() ); break;
358  case TYPE::Char:
359  CHAR_CONVERTOR::convert( field.getString() ); break;
360  case TYPE::Price:
361  PRICE_CONVERTOR::convert( field.getString() ); break;
362  case TYPE::Int:
363  INT_CONVERTOR::convert( field.getString() ); break;
364  case TYPE::Amt:
365  AMT_CONVERTOR::convert( field.getString() ); break;
366  case TYPE::Qty:
367  QTY_CONVERTOR::convert( field.getString() ); break;
368  case TYPE::Currency:
369  CURRENCY_CONVERTOR::convert( field.getString() ); break;
371  MULTIPLEVALUESTRING_CONVERTOR::convert( field.getString() ); break;
373  MULTIPLESTRINGVALUE_CONVERTOR::convert( field.getString() ); break;
375  MULTIPLECHARVALUE_CONVERTOR::convert( field.getString() ); break;
376  case TYPE::Exchange:
377  EXCHANGE_CONVERTOR::convert( field.getString() ); break;
378  case TYPE::UtcTimeStamp:
379  UTCTIMESTAMP_CONVERTOR::convert( field.getString() ); break;
380  case TYPE::Boolean:
381  BOOLEAN_CONVERTOR::convert( field.getString() ); break;
382  case TYPE::LocalMktDate:
383  LOCALMKTDATE_CONVERTOR::convert( field.getString() ); break;
384  case TYPE::Data:
385  DATA_CONVERTOR::convert( field.getString() ); break;
386  case TYPE::Float:
387  FLOAT_CONVERTOR::convert( field.getString() ); break;
388  case TYPE::PriceOffset:
389  PRICEOFFSET_CONVERTOR::convert( field.getString() ); break;
390  case TYPE::MonthYear:
391  MONTHYEAR_CONVERTOR::convert( field.getString() ); break;
392  case TYPE::DayOfMonth:
393  DAYOFMONTH_CONVERTOR::convert( field.getString() ); break;
394  case TYPE::UtcDate:
395  UTCDATE_CONVERTOR::convert( field.getString() ); break;
396  case TYPE::UtcTimeOnly:
397  UTCTIMEONLY_CONVERTOR::convert( field.getString() ); break;
398  case TYPE::NumInGroup:
399  NUMINGROUP_CONVERTOR::convert( field.getString() ); break;
400  case TYPE::Percentage:
401  PERCENTAGE_CONVERTOR::convert( field.getString() ); break;
402  case TYPE::SeqNum:
403  SEQNUM_CONVERTOR::convert( field.getString() ); break;
404  case TYPE::Length:
405  LENGTH_CONVERTOR::convert( field.getString() ); break;
406  case TYPE::Country:
407  COUNTRY_CONVERTOR::convert( field.getString() ); break;
408  case TYPE::TzTimeOnly:
409  TZTIMEONLY_CONVERTOR::convert( field.getString() ); break;
410  case TYPE::TzTimeStamp:
411  TZTIMESTAMP_CONVERTOR::convert( field.getString() ); break;
412  case TYPE::XmlData:
413  XMLDATA_CONVERTOR::convert( field.getString() ); break;
414  case TYPE::Language:
415  LANGUAGE_CONVERTOR::convert( field.getString() ); break;
416  case TYPE::Unknown: break;
417  }
418  }
419  catch ( FieldConvertError& )
420  { throw IncorrectDataFormat( field.getField(), field.getString() ); }
421  }
422 
423  void checkValue( const FieldBase& field ) const
424  throw( IncorrectTagValue )
425  {
426  if ( !hasFieldValue( field.getField() ) ) return ;
427 
428  const std::string& value = field.getString();
429  if ( !isFieldValue( field.getField(), value ) )
430  throw IncorrectTagValue( field.getField() );
431  }
432 
434  void checkHasValue( const FieldBase& field ) const
435  throw( NoTagValue )
436  {
437  if ( m_checkFieldsHaveValues && !field.getString().length() )
438  throw NoTagValue( field.getField() );
439  }
440 
442  void checkIsInMessage
443  ( const FieldBase& field, const MsgType& msgType ) const
444  throw( TagNotDefinedForMessage )
445  {
446  if ( !isMsgField( msgType, field.getField() ) )
447  throw TagNotDefinedForMessage( field.getField() );
448  }
449 
451  void checkGroupCount
452  ( const FieldBase& field, const FieldMap& fieldMap, const MsgType& msgType ) const
454  {
455  int fieldNum = field.getField();
456  if( isGroup(msgType, fieldNum) )
457  {
458  if( fieldMap.groupCount(fieldNum)
459  != IntConvertor::convert(field.getString()) )
460  throw RepeatingGroupCountMismatch(fieldNum);
461  }
462  }
463 
465  void checkHasRequired
466  ( const FieldMap& header, const FieldMap& body, const FieldMap& trailer,
467  const MsgType& msgType ) const
468  throw( RequiredTagMissing )
469  {
470  NonBodyFields::const_iterator iNBF;
471  for( iNBF = m_headerFields.begin(); iNBF != m_headerFields.end(); ++iNBF )
472  {
473  if( iNBF->second == true && !header.isSetField(iNBF->first) )
474  throw RequiredTagMissing( iNBF->first );
475  }
476 
477  for( iNBF = m_trailerFields.begin(); iNBF != m_trailerFields.end(); ++iNBF )
478  {
479  if( iNBF->second == true && !trailer.isSetField(iNBF->first) )
480  throw RequiredTagMissing( iNBF->first );
481  }
482 
483  MsgTypeToField::const_iterator iM
484  = m_requiredFields.find( msgType.getString() );
485  if ( iM == m_requiredFields.end() ) return ;
486 
487  const MsgFields& fields = iM->second;
488  MsgFields::const_iterator iF;
489  for( iF = fields.begin(); iF != fields.end(); ++iF )
490  {
491  if( !body.isSetField(*iF) )
492  throw RequiredTagMissing( *iF );
493  }
494 
495  FieldMap::g_iterator groups;
496  for( groups = body.g_begin(); groups != body.g_end(); ++groups )
497  {
498  int delim;
499  const DataDictionary* DD = 0;
500  int field = groups->first;
501  if( getGroup( msgType.getValue(), field, delim, DD ) )
502  {
503  std::vector<FieldMap*>::const_iterator group;
504  for( group = groups->second.begin(); group != groups->second.end(); ++group )
505  DD->checkHasRequired( **group, **group, **group, msgType );
506  }
507  }
508  }
509 
511  void readMSXMLDOM( const std::string& );
512  void readMSXML( const std::string& );
514  void readLibXml( const std::string& );
515 
516  int lookupXMLFieldNumber( DOMDocument*, DOMNode* ) const;
517  int lookupXMLFieldNumber( DOMDocument*, const std::string& name ) const;
518  int addXMLComponentFields( DOMDocument*, DOMNode*, const std::string& msgtype, DataDictionary&, bool );
519  void addXMLGroup( DOMDocument*, DOMNode*, const std::string& msgtype, DataDictionary&, bool );
520  TYPE::Type XMLTypeToType( const std::string& xmlType ) const;
521 
542 };
543 }
544 
545 #endif //FIX_DATADICTIONARY_H
std::set< std::string > Values
MsgTypeToField m_requiredFields
Unable to convert field into its native format.
Definition: Exceptions.h:66
static std::string convert(const UtcTimeOnly &value, bool showMilliseconds=false)
void checkValidFormat(const FieldBase &field) const
Field has a badly formatted value.
Definition: Exceptions.h:146
void validate(const Message &message) const
std::set< std::string > MsgTypes
static std::string convert(char value)
static std::string convert(const UtcTimeStamp &value, bool showMilliseconds=false)
Repeated group count not equal to actual count.
Definition: Exceptions.h:208
Represents a data dictionary for a version of FIX.
std::map< int, bool > NonBodyFields
std::map< int, FieldPresenceMap > FieldToGroup
bool isHeaderField(int field) const
OrderedFields m_orderedFields
void iterate(const FieldMap &map, const MsgType &msgType) const
Iterate through fields while applying checks.
Groups::const_iterator g_iterator
Definition: FieldMap.h:61
std::map< std::string, MsgFields > MsgTypeToField
void validate(const Message &message, bool bodyOnly) const
TYPE::Type XMLTypeToType(const std::string &xmlType) const
void addGroup(const std::string &msg, int field, int delim, const DataDictionary &dataDictionary)
NonBodyFields m_headerFields
void readFromDocument(DOMDocumentPtr pDoc)
std::map< std::string, int > NameToField
void checkIsInMessage(const FieldBase &field, const MsgType &msgType) const
Check if a field is in this message type.
void checkValue(const FieldBase &field) const
int groupCount(int field) const
Count the number of instance of a group.
Definition: FieldMap.cpp:135
void addMsgField(const std::string &msgType, int field)
FieldToName m_fieldNames
bool getFieldTag(const std::string &name, int &field) const
void addTrailerField(int field, bool required)
bool shouldCheckTag(const FieldBase &field) const
If we need to check for the tag in the dictionary.
void readLibXml(const std::string &)
Read XML file using libXML.
BeginString m_beginString
std::map< int, Values > FieldToValue
void addXMLGroup(DOMDocument *, DOMNode *, const std::string &msgtype, DataDictionary &, bool)
void readFromURL(const std::string &url)
bool isMsgType(const std::string &msgType) const
int getField() const
Get the fields integer tag.
Definition: Field.h:69
MsgTypeToField m_messageFields
void checkValidTagNumber(const FieldBase &field) const
Check if field tag number is defined in spec.
Tag number does not exist in specification.
Definition: Exceptions.h:101
message_order const & getOrderedFields() const
static std::string convert(signed_int value)
void checkHasRequired(const FieldMap &header, const FieldMap &body, const FieldMap &trailer, const MsgType &msgType) const
Check if a message has all required fields.
bool getGroup(const std::string &msg, int field, int &delim, const DataDictionary *&pDataDictionary) const
FieldToValue m_fieldValues
void readFromStream(std::istream &stream)
bool getFieldName(int field, std::string &name) const
int addXMLComponentFields(DOMDocument *, DOMNode *, const std::string &msgtype, DataDictionary &, bool)
message_order OrderedFieldsArray
std::auto_ptr< DOMDocument > DOMDocumentPtr
Definition: DOMDocument.h:71
static void validate(const Message &message, const DataDictionary *const pSessionDD, const DataDictionary *const pAppID)
Validate a message.
void checkFieldsOutOfOrder(bool value)
bool isDataField(int field) const
bool isGroup(const std::string &msg, int field) const
Stores and organizes a collection of Fields.
Definition: FieldMap.h:46
std::set< int > Fields
void checkUserDefinedFields(bool value)
void checkGroupCount(const FieldBase &field, const FieldMap &fieldMap, const MsgType &msgType) const
Check if group count matches number of groups in.
Not a known message type.
Definition: Exceptions.h:169
void addHeaderField(int field, bool required)
static std::string convert(double value, int padding=0)
DataDictionary & operator=(const DataDictionary &rhs)
Application is not configured correctly
Definition: Exceptions.h:87
void addValueName(int field, const std::string &value, const std::string &name)
void readMSXMLDOM(const std::string &)
Read XML file using MSXML.
bool isMultipleValueField(int field) const
bool getFieldType(int field, FIX::TYPE::Type &type) const
std::string getVersion() const
bool isField(int field) const
int lookupXMLFieldNumber(DOMDocument *, DOMNode *) const
Base class for all FIX messages.
Definition: Message.h:67
bool isSetField(const FieldBase &field) const
Check to see if a field is set.
Definition: FieldMap.h:144
ValueToName m_valueNames
bool isFieldValue(int field, const std::string &value) const
void addField(int field)
FieldToGroup m_groups
bool isTrailerField(int field) const
const std::string & getString() const
Get the string representation of the fields value.
Definition: Field.h:73
void addFieldName(int field, const std::string &name)
static std::string convert(const UtcDate &value)
static std::string convert(bool value)
g_iterator g_end() const
Definition: FieldMap.h:217
Base representation of all Field classes.
Definition: Field.h:45
void checkMsgType(const MsgType &msgType) const
Check if message type is defined in spec.
void setVersion(const std::string &beginString)
std::map< int, TYPE::Type > FieldTypes
bool getValueName(int field, const std::string &value, std::string &name) const
Sorts fields in header, normal, or trailer order.
bool isMsgField(const std::string &msgType, int field) const
void addFieldValue(int field, const std::string &value)
void checkHasValue(const FieldBase &field) const
Check if a field has a value.
std::vector< int > OrderedFields
std::set< int > MsgFields
const int BeginString
std::map< int, std::string > FieldToName
Interface that represents node from underlying XML parser.
Definition: DOMDocument.h:46
static const std::string & convert(const std::string &value)
Required field is not in message.
Definition: Exceptions.h:110
Field exists in message without a value.
Definition: Exceptions.h:128
void readMSXML(const std::string &)
Field has a value that is out of range.
Definition: Exceptions.h:137
std::map< std::string, std::pair< int, DataDictionary * > > FieldPresenceMap
NonBodyFields m_trailerFields
const int UserMin
Definition: FieldNumbers.h:40
void checkFieldsHaveValues(bool value)
Field does not belong to message.
Definition: Exceptions.h:119
void addMsgType(const std::string &msgType)
const int MsgType
OrderedFieldsArray m_orderedFieldsArray
std::map< std::pair< int, std::string >, std::string > ValueToName
g_iterator g_begin() const
Definition: FieldMap.h:216
bool hasFieldValue(int field) const
bool isRequiredField(const std::string &msgType, int field) const
void addFieldType(int field, FIX::TYPE::Type type)
Base QuickFIX exception type.
Definition: Exceptions.h:33
void addRequiredField(const std::string &msgType, int field)
Interface that represents document of underlying XML parser.
Definition: DOMDocument.h:60

Generated on Sat Mar 29 2014 15:13:31 for QuickFIX by doxygen 1.8.5 written by Dimitri van Heesch, © 1997-2001