DataDictionary.cpp
Go to the documentation of this file.
1/****************************************************************************
2** Copyright (c) 2001-2014
3**
4** This file is part of the QuickFIX FIX Engine
5**
6** This file may be distributed under the terms of the quickfixengine.org
7** license as defined by quickfixengine.org and appearing in the file
8** LICENSE included in the packaging of this file.
9**
10** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
11** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
12**
13** See http://www.quickfixengine.org/LICENSE for licensing information.
14**
15** Contact ask@quickfixengine.org if any conditions of this licensing are
16** not clear to you.
17**
18****************************************************************************/
19
20#ifdef _MSC_VER
21#include "stdafx.h"
22#else
23#include "config.h"
24#endif
25
26#include "DataDictionary.h"
27#include "Message.h"
28#include <fstream>
29#include <memory>
30
31#include "PUGIXML_DOMDocument.h"
32
33#ifdef _MSC_VER
34#define RESET_AUTO_PTR(OLD, NEW) OLD = NEW;
35#else
36#define RESET_AUTO_PTR(OLD, NEW) OLD.reset( NEW.release() );
37#endif
38
39namespace FIX
40{
42: m_hasVersion( false ), m_checkFieldsOutOfOrder( true ),
43 m_checkFieldsHaveValues( true ), m_checkUserDefinedFields( true ), m_allowUnknownMessageFields( false ), m_storeMsgFieldsOrder(false)
44{}
45
46DataDictionary::DataDictionary( std::istream& stream, bool preserveMsgFldsOrder )
47throw( ConfigError )
48: m_hasVersion( false ), m_checkFieldsOutOfOrder( true ),
49 m_checkFieldsHaveValues( true ), m_checkUserDefinedFields( true ), m_allowUnknownMessageFields( false ), m_storeMsgFieldsOrder(preserveMsgFldsOrder)
50{
51 readFromStream( stream );
52}
53
54DataDictionary::DataDictionary( const std::string& url, bool preserveMsgFldsOrder )
55throw( ConfigError )
56: m_hasVersion( false ), m_checkFieldsOutOfOrder( true ),
57 m_checkFieldsHaveValues( true ), m_checkUserDefinedFields( true ), m_allowUnknownMessageFields( false ), m_storeMsgFieldsOrder(preserveMsgFldsOrder), m_orderedFieldsArray(0)
58{
59 readFromURL( url );
60}
61
63{
64 *this = copy;
65}
66
68{
69 FieldToGroup::iterator i;
70 for ( i = m_groups.begin(); i != m_groups.end(); ++i )
71 {
72 const FieldPresenceMap& presenceMap = i->second;
73
74 FieldPresenceMap::const_iterator iter = presenceMap.begin();
75 for ( ; iter != presenceMap.end(); ++iter )
76 delete iter->second.second;
77 }
78}
79
81{
92 m_fields = rhs.m_fields;
100 m_names = rhs.m_names;
108
109 FieldToGroup::const_iterator i = rhs.m_groups.begin();
110 for ( ; i != rhs.m_groups.end(); ++i )
111 {
112 const FieldPresenceMap& presenceMap = i->second;
113
114 FieldPresenceMap::const_iterator iter = presenceMap.begin();
115 for ( ; iter != presenceMap.end(); ++iter )
116 {
117 addGroup( iter->first, i->first, iter->second.first, *iter->second.second );
118 }
119 }
120 return *this;
121}
122
124 const DataDictionary* const pSessionDD,
125 const DataDictionary* const pAppDD )
126throw( FIX::Exception )
127{
128 const Header& header = message.getHeader();
129 const BeginString& beginString = FIELD_GET_REF( header, BeginString );
130#ifdef HAVE_EMX
131 const std::string & msgType = message.getSubMessageType();
132 if (msgType.empty())
133 {
134 throw InvalidMessageType("empty subMsgType, check Tag 9426/MESSAGE_ID");
135 }
136#else
137 const MsgType& msgType = FIELD_GET_REF( header, MsgType );
138#endif
139 if ( pSessionDD != 0 && pSessionDD->m_hasVersion )
140 {
141 if( pSessionDD->getVersion() != beginString )
142 {
143 throw UnsupportedVersion();
144 }
145 }
146
147 int field = 0;
148 if( (pSessionDD !=0 && pSessionDD->m_checkFieldsOutOfOrder) ||
149 (pAppDD != 0 && pAppDD->m_checkFieldsOutOfOrder) )
150 {
151 if ( !message.hasValidStructure(field) )
152 throw TagOutOfOrder(field);
153 }
154
155 if ( pAppDD != 0 && pAppDD->m_hasVersion )
156 {
157 pAppDD->checkMsgType( msgType );
158 pAppDD->checkHasRequired( message.getHeader(), message, message.getTrailer(), msgType );
159 }
160
161 if( pSessionDD != 0 )
162 {
163 pSessionDD->iterate( message.getHeader(), msgType );
164 pSessionDD->iterate( message.getTrailer(), msgType );
165 }
166
167 if( pAppDD != 0 )
168 {
169 pAppDD->iterate( message, msgType );
170 }
171}
172
173void DataDictionary::iterate( const FieldMap& map, const MsgType& msgType ) const
174{
175 int lastField = 0;
176
178 for ( i = map.begin(); i != map.end(); ++i )
179 {
180 const FieldBase& field = (*i);
181 if( i != map.begin() && (field.getTag() == lastField) )
182 throw RepeatedTag( lastField );
183 checkHasValue( field );
184
185 if ( m_hasVersion )
186 {
187 checkValidFormat( field );
188 checkValue( field );
189 }
190
191 if ( m_beginString.getValue().length() && shouldCheckTag(field) )
192 {
193 checkValidTagNumber( field );
194 if ( !Message::isHeaderField( field, this )
195 && !Message::isTrailerField( field, this ) )
196 {
197 checkIsInMessage( field, msgType );
198 checkGroupCount( field, map, msgType );
199 }
200 }
201 lastField = field.getTag();
202 }
203}
204
205void DataDictionary::readFromURL( const std::string& url )
206throw( ConfigError )
207{
209
210 if(!pDoc->load(url))
211 throw ConfigError(url + ": Could not parse data dictionary file");
212
213 try
214 {
215 readFromDocument( pDoc );
216 }
217 catch( ConfigError& e )
218 {
219 throw ConfigError( url + ": " + e.what() );
220 }
221}
222
223void DataDictionary::readFromStream( std::istream& stream )
224throw( ConfigError )
225{
227
228 if(!pDoc->load(stream))
229 throw ConfigError("Could not parse data dictionary stream");
230
231 readFromDocument( pDoc );
232}
233
235throw( ConfigError )
236{
237 // VERSION
238 DOMNodePtr pFixNode = pDoc->getNode("/fix");
239 if(!pFixNode.get())
240 throw ConfigError("Could not parse data dictionary file"
241 ", or no <fix> node found at root");
242 DOMAttributesPtr attrs = pFixNode->getAttributes();
243 std::string type = "FIX";
244 if(attrs->get("type", type))
245 {
246 if(type != "FIX" && type != "FIXT")
247 throw ConfigError("type attribute must be FIX or FIXT");
248 }
249 std::string major;
250 if(!attrs->get("major", major))
251 throw ConfigError("major attribute not found on <fix>");
252 std::string minor;
253 if(!attrs->get("minor", minor))
254 throw ConfigError("minor attribute not found on <fix>");
255 setVersion(type + "." + major + "." + minor);
256
257 // FIELDS
258 DOMNodePtr pFieldsNode = pDoc->getNode("/fix/fields");
259 if(!pFieldsNode.get())
260 throw ConfigError("<fields> section not found in data dictionary");
261
262 DOMNodePtr pFieldNode = pFieldsNode->getFirstChildNode();
263 if(!pFieldNode.get()) throw ConfigError("No fields defined");
264
265 while(pFieldNode.get())
266 {
267 if(pFieldNode->getName() == "field")
268 {
269 DOMAttributesPtr attrs = pFieldNode->getAttributes();
270 std::string name;
271 if(!attrs->get("name", name))
272 throw ConfigError("<field> does not have a name attribute");
273 std::string number;
274 if(!attrs->get("number", number))
275 throw ConfigError("<field> " + name + " does not have a number attribute");
276 int num = atoi(number.c_str());
277 std::string type;
278 if(!attrs->get("type", type))
279 throw ConfigError("<field> " + name + " does not have a type attribute");
280 addField(num);
281 addFieldType(num, XMLTypeToType(type));
282 addFieldName(num, name);
283
284 DOMNodePtr pFieldValueNode = pFieldNode->getFirstChildNode();
285 while(pFieldValueNode.get())
286 {
287 if(pFieldValueNode->getName() == "value")
288 {
289 DOMAttributesPtr attrs = pFieldValueNode->getAttributes();
290 std::string enumeration;
291 if(!attrs->get("enum", enumeration))
292 throw ConfigError("<value> does not have enum attribute in field " + name);
293 addFieldValue(num, enumeration);
294 std::string description;
295 if(attrs->get("description", description))
296 addValueName(num, enumeration, description);
297 }
298 RESET_AUTO_PTR(pFieldValueNode, pFieldValueNode->getNextSiblingNode());
299 }
300 }
301 RESET_AUTO_PTR(pFieldNode, pFieldNode->getNextSiblingNode());
302 }
303
304 // HEADER
305 if( type == "FIXT" || (type == "FIX" && major < "5") )
306 {
307 DOMNodePtr pHeaderNode = pDoc->getNode("/fix/header");
308 if(!pHeaderNode.get())
309 throw ConfigError("<header> section not found in data dictionary");
310
311 DOMNodePtr pHeaderFieldNode = pHeaderNode->getFirstChildNode();
312 if(!pHeaderFieldNode.get()) throw ConfigError("No header fields defined");
313
314 while(pHeaderFieldNode.get())
315 {
316 if(pHeaderFieldNode->getName() == "field" || pHeaderFieldNode->getName() == "group" )
317 {
318 DOMAttributesPtr attrs = pHeaderFieldNode->getAttributes();
319 std::string name;
320 if(!attrs->get("name", name))
321 throw ConfigError("<field> does not have a name attribute");
322 std::string required = "false";
323 attrs->get("required", required);
324 addHeaderField(lookupXMLFieldNumber(pDoc.get(), name), required == "true");
325 }
326 if(pHeaderFieldNode->getName() == "group")
327 {
328 DOMAttributesPtr attrs = pHeaderFieldNode->getAttributes();
329 std::string required;
330 attrs->get("required", required);
331 bool isRequired = (required == "Y" || required == "y");
332 addXMLGroup(pDoc.get(), pHeaderFieldNode.get(), "_header_", *this, isRequired);
333 }
334
335 RESET_AUTO_PTR(pHeaderFieldNode, pHeaderFieldNode->getNextSiblingNode());
336 }
337 }
338
339 // TRAILER
340 if( type == "FIXT" || (type == "FIX" && major < "5") )
341 {
342 DOMNodePtr pTrailerNode = pDoc->getNode("/fix/trailer");
343 if(!pTrailerNode.get())
344 throw ConfigError("<trailer> section not found in data dictionary");
345
346 DOMNodePtr pTrailerFieldNode = pTrailerNode->getFirstChildNode();
347 if(!pTrailerFieldNode.get()) throw ConfigError("No trailer fields defined");
348
349 while(pTrailerFieldNode.get())
350 {
351 if(pTrailerFieldNode->getName() == "field" || pTrailerFieldNode->getName() == "group" )
352 {
353 DOMAttributesPtr attrs = pTrailerFieldNode->getAttributes();
354 std::string name;
355 if(!attrs->get("name", name))
356 throw ConfigError("<field> does not have a name attribute");
357 std::string required = "false";
358 attrs->get("required", required);
359 addTrailerField(lookupXMLFieldNumber(pDoc.get(), name), required == "true");
360 }
361 if(pTrailerFieldNode->getName() == "group")
362 {
363 DOMAttributesPtr attrs = pTrailerFieldNode->getAttributes();
364 std::string required;
365 attrs->get("required", required);
366 bool isRequired = (required == "Y" || required == "y");
367 addXMLGroup(pDoc.get(), pTrailerFieldNode.get(), "_trailer_", *this, isRequired);
368 }
369
370 RESET_AUTO_PTR(pTrailerFieldNode, pTrailerFieldNode->getNextSiblingNode());
371 }
372 }
373
374 // MSGTYPE
375 DOMNodePtr pMessagesNode = pDoc->getNode("/fix/messages");
376 if(!pMessagesNode.get())
377 throw ConfigError("<messages> section not found in data dictionary");
378
379 DOMNodePtr pMessageNode = pMessagesNode->getFirstChildNode();
380 if(!pMessageNode.get()) throw ConfigError("No messages defined");
381
382 while(pMessageNode.get())
383 {
384 if(pMessageNode->getName() == "message")
385 {
386 DOMAttributesPtr attrs = pMessageNode->getAttributes();
387 std::string msgtype;
388 if(!attrs->get("msgtype", msgtype))
389 throw ConfigError("<field> does not have a name attribute");
390 addMsgType(msgtype);
391
392 std::string name;
393 if(attrs->get("name", name))
394 addValueName( 35, msgtype, name );
395
396 DOMNodePtr pMessageFieldNode = pMessageNode->getFirstChildNode();
397 while( pMessageFieldNode.get() )
398 {
399 if(pMessageFieldNode->getName() == "field"
400 || pMessageFieldNode->getName() == "group")
401 {
402 DOMAttributesPtr attrs = pMessageFieldNode->getAttributes();
403 std::string name;
404 if(!attrs->get("name", name))
405 throw ConfigError("<field> does not have a name attribute");
406 int num = lookupXMLFieldNumber(pDoc.get(), name);
407 addMsgField(msgtype, num);
408
409 std::string required;
410 if(attrs->get("required", required)
411 && (required == "Y" || required == "y"))
412 {
413 addRequiredField(msgtype, num);
414 }
415 }
416 else if(pMessageFieldNode->getName() == "component")
417 {
418 DOMAttributesPtr attrs = pMessageFieldNode->getAttributes();
419 std::string required;
420 attrs->get("required", required);
421 bool isRequired = (required == "Y" || required == "y");
422 addXMLComponentFields(pDoc.get(), pMessageFieldNode.get(),
423 msgtype, *this, isRequired);
424 }
425 if(pMessageFieldNode->getName() == "group")
426 {
427 DOMAttributesPtr attrs = pMessageFieldNode->getAttributes();
428 std::string required;
429 attrs->get("required", required);
430 bool isRequired = (required == "Y" || required == "y");
431 addXMLGroup(pDoc.get(), pMessageFieldNode.get(), msgtype, *this, isRequired);
432 }
433 RESET_AUTO_PTR(pMessageFieldNode,
434 pMessageFieldNode->getNextSiblingNode());
435 }
436 }
437 RESET_AUTO_PTR(pMessageNode, pMessageNode->getNextSiblingNode());
438 }
439}
440
442{
444
445 int * tmp = new int[m_orderedFields.size() + 1];
446 int * i = tmp;
447
448 OrderedFields::const_iterator iter;
449 for( iter = m_orderedFields.begin(); iter != m_orderedFields.end(); *(i++) = *(iter++) ) {}
450 *i = 0;
451
453 delete [] tmp;
454
456}
457
459{
460 if( m_headerOrder ) return m_headerOrder;
461
462 if (m_headerOrderedFields.size() == 0)
463 throw ConfigError("<Header> does not have a stored message order");
464
465 int * tmp = new int[m_headerOrderedFields.size() + 1];
466 int * i = tmp;
467
468 OrderedFields::const_iterator iter;
469 for( iter = m_headerOrderedFields.begin(); iter != m_headerOrderedFields.end(); *(i++) = *(iter++) ) {}
470 *i = 0;
471
473 delete [] tmp;
474
475 return m_headerOrder;
476}
477
479{
480 if( m_trailerOrder ) return m_trailerOrder;
481
482 if (m_trailerOrderedFields.size() == 0)
483 throw ConfigError("<Trailer> does not have a stored message order");
484
485 int * tmp = new int[m_trailerOrderedFields.size() + 1];
486 int * i = tmp;
487
488 OrderedFields::const_iterator iter;
489 for( iter = m_trailerOrderedFields.begin(); iter != m_trailerOrderedFields.end(); *(i++) = *(iter++) ) {}
490 *i = 0;
491
493 delete [] tmp;
494
495 return m_trailerOrder;
496}
497
498const message_order &DataDictionary::getMessageOrderedFields(const std::string & msgType) const throw( ConfigError )
499{
500 MsgTypeToOrderedFields::const_iterator iter = m_messageOrderedFields.find(msgType);
501 if (iter == m_messageOrderedFields.end())
502 throw ConfigError("<Message> " + msgType + " does not have a stored message order");
503
504 return iter->second.getMessageOrder();
505}
506
508{
509 DOMAttributesPtr attrs = pNode->getAttributes();
510 std::string name;
511 if(!attrs->get("name", name))
512 throw ConfigError("No name given to field");
513 return lookupXMLFieldNumber( pDoc, name );
514}
515
517( DOMDocument* pDoc, const std::string& name ) const
518{
519 NameToField::const_iterator i = m_names.find(name);
520 if( i == m_names.end() )
521 throw ConfigError("Field " + name + " not defined in fields section");
522 return i->second;
523}
524
526 const std::string& msgtype,
527 DataDictionary& DD,
528 bool componentRequired )
529{
530 int firstField = 0;
531
532 DOMAttributesPtr attrs = pNode->getAttributes();
533 std::string name;
534 if(!attrs->get("name", name))
535 throw ConfigError("No name given to component");
536
537 DOMNodePtr pComponentNode =
538 pDoc->getNode("/fix/components/component[@name='" + name + "']");
539 if(pComponentNode.get() == 0)
540 throw ConfigError("Component not found: " + name);
541
542 DOMNodePtr pComponentFieldNode = pComponentNode->getFirstChildNode();
543 while(pComponentFieldNode.get())
544 {
545 if(pComponentFieldNode->getName() == "field"
546 || pComponentFieldNode->getName() == "group")
547 {
548 DOMAttributesPtr attrs = pComponentFieldNode->getAttributes();
549 std::string name;
550 if(!attrs->get("name", name))
551 throw ConfigError("No name given to field");
552 int field = lookupXMLFieldNumber(pDoc, name);
553 if( firstField == 0 ) firstField = field;
554
555 std::string required;
556 if(attrs->get("required", required)
557 && (required == "Y" || required =="y")
558 && componentRequired)
559 {
560 addRequiredField(msgtype, field);
561 }
562
563 DD.addField(field);
564 DD.addMsgField(msgtype, field);
565 }
566 if(pComponentFieldNode->getName() == "component")
567 {
568 DOMAttributesPtr attrs = pComponentFieldNode->getAttributes();
569 std::string required;
570 attrs->get("required", required);
571 bool isRequired = (required == "Y" || required == "y");
572 addXMLComponentFields(pDoc, pComponentFieldNode.get(),
573 msgtype, DD, isRequired);
574 }
575 if(pComponentFieldNode->getName() == "group")
576 {
577 DOMAttributesPtr attrs = pComponentFieldNode->getAttributes();
578 std::string required;
579 attrs->get("required", required);
580 bool isRequired = (required == "Y" || required == "y");
581 addXMLGroup(pDoc, pComponentFieldNode.get(), msgtype, DD, isRequired);
582 }
583 RESET_AUTO_PTR(pComponentFieldNode,
584 pComponentFieldNode->getNextSiblingNode());
585 }
586 return firstField;
587}
588
590 const std::string& msgtype,
591 DataDictionary& DD, bool groupRequired )
592{
593 DOMAttributesPtr attrs = pNode->getAttributes();
594 std::string name;
595 if(!attrs->get("name", name))
596 throw ConfigError("No name given to group");
597 int group = lookupXMLFieldNumber( pDoc, name );
598 int delim = 0;
599 int field = 0;
600 DataDictionary groupDD;
601 DOMNodePtr node = pNode->getFirstChildNode();
602 while(node.get())
603 {
604 if( node->getName() == "field" )
605 {
606 field = lookupXMLFieldNumber( pDoc, node.get() );
607 groupDD.addField( field );
608
609 DOMAttributesPtr attrs = node->getAttributes();
610 std::string required;
611 if( attrs->get("required", required)
612 && ( required == "Y" || required =="y" )
613 && groupRequired )
614 {
615 groupDD.addRequiredField(msgtype, field);
616 }
617 }
618 else if( node->getName() == "component" )
619 {
620 field = addXMLComponentFields( pDoc, node.get(), msgtype, groupDD, false );
621 }
622 else if( node->getName() == "group" )
623 {
624 field = lookupXMLFieldNumber( pDoc, node.get() );
625 groupDD.addField( field );
626 DOMAttributesPtr attrs = node->getAttributes();
627 std::string required;
628 if( attrs->get("required", required )
629 && ( required == "Y" || required =="y" )
630 && groupRequired)
631 {
632 groupDD.addRequiredField(msgtype, field);
633 }
634 bool isRequired = false;
635 if( attrs->get("required", required) )
636 isRequired = (required == "Y" || required == "y");
637 addXMLGroup( pDoc, node.get(), msgtype, groupDD, isRequired );
638 }
639 if( delim == 0 ) delim = field;
640 RESET_AUTO_PTR(node, node->getNextSiblingNode());
641 }
642
643 if( delim ) DD.addGroup( msgtype, group, delim, groupDD );
644}
645
646TYPE::Type DataDictionary::XMLTypeToType( const std::string& type ) const
647{
648 if ( m_beginString < "FIX.4.2" && type == "CHAR" )
649 return TYPE::String;
650
651 if ( type == "STRING" ) return TYPE::String;
652 if ( type == "CHAR" ) return TYPE::Char;
653 if ( type == "PRICE" ) return TYPE::Price;
654 if ( type == "INT" ) return TYPE::Int;
655 if ( type == "AMT" ) return TYPE::Amt;
656 if ( type == "QTY" ) return TYPE::Qty;
657 if ( type == "CURRENCY" ) return TYPE::Currency;
658 if ( type == "MULTIPLEVALUESTRING" ) return TYPE::MultipleValueString;
659 if ( type == "MULTIPLESTRINGVALUE" ) return TYPE::MultipleStringValue;
660 if ( type == "MULTIPLECHARVALUE" ) return TYPE::MultipleCharValue;
661 if ( type == "EXCHANGE" ) return TYPE::Exchange;
662 if ( type == "UTCTIMESTAMP" ) return TYPE::UtcTimeStamp;
663 if ( type == "BOOLEAN" ) return TYPE::Boolean;
664 if ( type == "LOCALMKTDATE" ) return TYPE::LocalMktDate;
665 if ( type == "DATA" ) return TYPE::Data;
666 if ( type == "FLOAT" ) return TYPE::Float;
667 if ( type == "PRICEOFFSET" ) return TYPE::PriceOffset;
668 if ( type == "MONTHYEAR" ) return TYPE::MonthYear;
669 if ( type == "DAYOFMONTH" ) return TYPE::DayOfMonth;
670 if ( type == "UTCDATE" ) return TYPE::UtcDate;
671 if ( type == "UTCDATEONLY" ) return TYPE::UtcDateOnly;
672 if ( type == "UTCTIMEONLY" ) return TYPE::UtcTimeOnly;
673 if ( type == "NUMINGROUP" ) return TYPE::NumInGroup;
674 if ( type == "PERCENTAGE" ) return TYPE::Percentage;
675 if ( type == "SEQNUM" ) return TYPE::SeqNum;
676 if ( type == "LENGTH" ) return TYPE::Length;
677 if ( type == "COUNTRY" ) return TYPE::Country;
678 if ( type == "TIME" ) return TYPE::UtcTimeStamp;
679 return TYPE::Unknown;
680}
681}
#define RESET_AUTO_PTR(OLD, NEW)
#define FIELD_GET_REF(MAP, FLD)
Definition FieldMap.h:376
Interface that represents document of underlying XML parser.
Definition DOMDocument.h:63
virtual SmartPtr< DOMNode > getNode(const std::string &)=0
Interface that represents node from underlying XML parser.
Definition DOMDocument.h:49
virtual SmartPtr< DOMAttributes > getAttributes()=0
virtual SmartPtr< DOMNode > getFirstChildNode()=0
Represents a data dictionary for a version of FIX.
void checkValue(const FieldBase &field) const
OrderedFieldsArray m_orderedFieldsArray
void addRequiredField(const std::string &msgType, int field)
OrderedFields m_headerOrderedFields
DataDictionary & operator=(const DataDictionary &rhs)
void readFromURL(const std::string &url)
message_order const & getTrailerOrderedFields() const
OrderedFieldsArray m_trailerOrder
void addMsgField(const std::string &msgType, int field)
void addField(int field)
bool shouldCheckTag(const FieldBase &field) const
If we need to check for the tag in the dictionary.
OrderedFields m_trailerOrderedFields
int addXMLComponentFields(DOMDocument *, DOMNode *, const std::string &msgtype, DataDictionary &, bool)
std::map< std::string, std::pair< int, DataDictionary * > > FieldPresenceMap
void checkGroupCount(const FieldBase &field, const FieldMap &fieldMap, const MsgType &msgType) const
Check if group count matches number of groups in.
OrderedFields m_orderedFields
void checkIsInMessage(const FieldBase &field, const MsgType &msgType) const
Check if a field is in this message type.
TYPE::Type XMLTypeToType(const std::string &xmlType) const
void readFromStream(std::istream &stream)
OrderedFieldsArray m_headerOrder
void addGroup(const std::string &msg, int field, int delim, const DataDictionary &dataDictionary)
static void validate(const Message &message, const DataDictionary *const pSessionDD, const DataDictionary *const pAppID)
Validate a message.
FieldToValue m_fieldValues
MsgTypeToField m_requiredFields
void checkValidTagNumber(const FieldBase &field) const
Check if field tag number is defined in spec.
message_order const & getOrderedFields() const
void readFromDocument(const DOMDocumentPtr &pDoc)
BeginString m_beginString
message_order const & getHeaderOrderedFields() const
int lookupXMLFieldNumber(DOMDocument *, DOMNode *) const
MsgTypeToField m_messageFields
void iterate(const FieldMap &map, const MsgType &msgType) const
Iterate through fields while applying checks.
MsgTypeToOrderedFields m_messageOrderedFields
void checkHasValue(const FieldBase &field) const
Check if a field has a value.
NonBodyFields m_headerFields
message_order const & getMessageOrderedFields(const std::string &msgType) const
void addXMLGroup(DOMDocument *, DOMNode *, const std::string &msgtype, DataDictionary &, bool)
NonBodyFields m_trailerFields
void checkValidFormat(const FieldBase &field) const
Base representation of all Field classes.
Definition Field.h:50
int getTag() const
Get the fields integer tag.
Definition Field.h:144
Stores and organizes a collection of Fields.
Definition FieldMap.h:47
iterator begin()
Definition FieldMap.h:258
iterator end()
Definition FieldMap.h:259
Fields::const_iterator const_iterator
Definition FieldMap.h:100
Base class for all FIX messages.
Definition Message.h:118
static bool isHeaderField(int field)
Definition Message.cpp:497
static bool isTrailerField(int field)
Definition Message.cpp:550
XML document as represented by pugixml.
@ MultipleValueString
Definition FieldTypes.h:919
@ MultipleStringValue
Definition FieldTypes.h:920
@ MultipleCharValue
Definition FieldTypes.h:921
SmartPtr< DOMAttributes > DOMAttributesPtr
Definition DOMDocument.h:45
SmartPtr< DOMNode > DOMNodePtr
Definition DOMDocument.h:59
SmartPtr< DOMDocument > DOMDocumentPtr
Definition DOMDocument.h:73
Application is not configured correctly
Definition Exceptions.h:88
Base QuickFIX exception type.
Definition Exceptions.h:34
Not a known message type.
Definition Exceptions.h:170
Repeated tag not part of repeating group.
Definition Exceptions.h:200
Tag is not in the correct order.
Definition Exceptions.h:191
Version of FIX is not supported.
Definition Exceptions.h:184
Sorts fields in header, normal, or trailer order.

Generated on Sat Feb 3 2024 04:23:15 for QuickFIX by doxygen 1.9.8 written by Dimitri van Heesch, © 1997-2001