Index  Source Files  Annotated Class List  Alphabetical Class List  Class Hierarchy  Graphical Class Hierarchy 

DataDictionary.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** Copyright (c) quickfixengine.org  All rights reserved.
00003 **
00004 ** This file is part of the QuickFIX FIX Engine
00005 **
00006 ** This file may be distributed under the terms of the quickfixengine.org
00007 ** license as defined by quickfixengine.org and appearing in the file
00008 ** LICENSE included in the packaging of this file.
00009 **
00010 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00011 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00012 **
00013 ** See http://www.quickfixengine.org/LICENSE for licensing information.
00014 **
00015 ** Contact ask@quickfixengine.org if any conditions of this licensing are
00016 ** not clear to you.
00017 **
00018 ****************************************************************************/
00019 
00020 #ifdef _MSC_VER
00021 #include "stdafx.h"
00022 #else
00023 #include "config.h"
00024 #endif
00025 #include "CallStack.h"
00026 
00027 #include "DataDictionary.h"
00028 #include "Message.h"
00029 #include <fstream>
00030 #include <memory>
00031 
00032 #ifdef HAVE_LIBXML
00033 #include "LIBXML_DOMDocument.h"
00034 #elif _MSC_VER
00035 #include "MSXML_DOMDocument.h"
00036 #else
00037 #include "LIBXML_DOMDocument.h"
00038 #endif
00039 
00040 #ifdef _MSC_VER
00041 #define RESET_AUTO_PTR(OLD, NEW) OLD = NEW;
00042 #else
00043 #define RESET_AUTO_PTR(OLD, NEW) OLD.reset( NEW.release() );
00044 #endif
00045 
00046 namespace FIX
00047 {
00048 DataDictionary::DataDictionary()
00049 : m_hasVersion( false ), m_checkFieldsOutOfOrder( true ),
00050   m_checkFieldsHaveValues( true ), m_checkUserDefinedFields( true ),
00051   m_orderedFieldsArray(0) {}
00052 
00053 DataDictionary::DataDictionary( std::istream& stream )
00054 throw( ConfigError )
00055 : m_hasVersion( false ), m_checkFieldsOutOfOrder( true ),
00056   m_checkFieldsHaveValues( true ), m_checkUserDefinedFields( true ),
00057   m_orderedFieldsArray(0)
00058 {
00059   readFromStream( stream );
00060 }
00061 
00062 DataDictionary::DataDictionary( const std::string& url )
00063 throw( ConfigError )
00064 : m_hasVersion( false ), m_checkFieldsOutOfOrder( true ),
00065   m_checkFieldsHaveValues( true ), m_checkUserDefinedFields( true ),
00066   m_orderedFieldsArray(0)
00067 {
00068   readFromURL( url );
00069 }
00070 
00071 DataDictionary::DataDictionary( const DataDictionary& copy )
00072 {
00073   *this = copy;
00074 }
00075 
00076 DataDictionary::~DataDictionary()
00077 {
00078   FieldToGroup::iterator i;
00079   for ( i = m_groups.begin(); i != m_groups.end(); ++i )
00080     delete i->second.second;
00081   if( m_orderedFieldsArray )
00082     delete [] m_orderedFieldsArray;
00083 }
00084 
00085 DataDictionary& DataDictionary::operator=( const DataDictionary& rhs )
00086 { QF_STACK_PUSH(DataDictionary::operator=)
00087 
00088   m_hasVersion = rhs.m_hasVersion;
00089   m_checkFieldsOutOfOrder = rhs.m_checkFieldsOutOfOrder;
00090   m_checkFieldsHaveValues = rhs.m_checkFieldsHaveValues;
00091   m_checkUserDefinedFields = rhs.m_checkUserDefinedFields;
00092   m_beginString = rhs.m_beginString;
00093   m_messageFields = rhs.m_messageFields;
00094   m_requiredFields = rhs.m_requiredFields;
00095   m_messages = rhs.m_messages;
00096   m_fields = rhs.m_fields;
00097   m_orderedFields = rhs.m_orderedFields;
00098   m_orderedFieldsArray = 0;
00099   m_headerFields = rhs.m_headerFields;
00100   m_trailerFields = rhs.m_trailerFields;
00101   m_fieldTypes = rhs.m_fieldTypes;
00102   m_fieldValues = rhs.m_fieldValues;
00103   m_fieldNames = rhs.m_fieldNames;
00104   m_names = rhs.m_names;
00105   m_valueNames = rhs.m_valueNames;
00106 
00107   FieldToGroup::const_iterator i = rhs.m_groups.begin();
00108   for ( ; i != rhs.m_groups.end(); ++i )
00109   {
00110     addGroup( i->first.first, i->first.second,
00111               i->second.first, *i->second.second );
00112   }
00113   return *this;
00114 
00115   QF_STACK_POP
00116 }
00117 
00118 void DataDictionary::validate( const Message& message,
00119                                const DataDictionary* const pSessionDD,
00120                                const DataDictionary* const pAppDD )
00121 throw( FIX::Exception )
00122 { QF_STACK_PUSH( DataDictionary::validate )
00123   
00124   const bool bodyOnly = pSessionDD == 0;
00125   const Header& header = message.getHeader();
00126   const BeginString& beginString = FIELD_GET_REF( header, BeginString );
00127   const MsgType& msgType = FIELD_GET_REF( header, MsgType );
00128   if ( pSessionDD != 0 && pSessionDD->m_hasVersion )
00129   {
00130     if( pSessionDD->getVersion() != beginString )
00131     {
00132       throw UnsupportedVersion();
00133     }
00134   }
00135 
00136   int field = 0;
00137   if( (pSessionDD !=0 && pSessionDD->m_checkFieldsOutOfOrder) 
00138       || (pAppDD != 0 && pAppDD->m_checkFieldsOutOfOrder) )
00139   {
00140     if ( !message.hasValidStructure(field) )
00141       throw TagOutOfOrder(field);
00142   }
00143 
00144   if ( pAppDD != 0 && pAppDD->m_hasVersion )
00145   {
00146     pAppDD->checkMsgType( msgType );
00147     pAppDD->checkHasRequired( message.getHeader(), message, message.getTrailer(), msgType );
00148   }
00149 
00150   if( !bodyOnly )
00151   {
00152     pSessionDD->iterate( message.getHeader(), msgType );
00153     pSessionDD->iterate( message.getTrailer(), msgType );
00154   }
00155 
00156   pAppDD->iterate( message, msgType );
00157 
00158   QF_STACK_POP
00159 }
00160 
00161 void DataDictionary::iterate( const FieldMap& map, const MsgType& msgType ) const
00162 { QF_STACK_PUSH(DataDictionary::iterate)
00163 
00164   int lastField = 0;
00165 
00166   FieldMap::iterator i;
00167   for ( i = map.begin(); i != map.end(); ++i )
00168   {
00169     const FieldBase& field = i->second;
00170     if( i != map.begin() && (field.getField() == lastField) )
00171       throw RepeatedTag( lastField );
00172     checkHasValue( field );
00173 
00174     if ( m_hasVersion )
00175     {
00176       checkValidFormat( field );
00177       checkValue( field );
00178     }
00179 
00180     if ( m_beginString.getValue().length() && shouldCheckTag(field) )
00181     {
00182       checkValidTagNumber( field );
00183       if ( !Message::isHeaderField( field, this )
00184            && !Message::isTrailerField( field, this ) )
00185       {
00186         checkIsInMessage( field, msgType );
00187         checkGroupCount( field, map, msgType );
00188       }
00189     }
00190     lastField = field.getField();
00191   }
00192 
00193   QF_STACK_POP
00194 }
00195 
00196 void DataDictionary::readFromURL( const std::string& url )
00197 throw( ConfigError )
00198 { QF_STACK_PUSH(DataDictionary::readFromURL)
00199 
00200 #ifdef HAVE_LIBXML
00201   DOMDocumentPtr pDoc = DOMDocumentPtr(new LIBXML_DOMDocument());
00202 #elif _MSC_VER
00203   DOMDocumentPtr pDoc = DOMDocumentPtr(new MSXML_DOMDocument());
00204 #else
00205   DOMDocumentPtr pDoc = DOMDocumentPtr(new LIBXML_DOMDocument());
00206 #endif
00207 
00208   if(!pDoc->load(url))
00209     throw ConfigError(url + ": Could not parse data dictionary file");
00210 
00211   try
00212   {
00213     readFromDocument( pDoc );
00214   }
00215   catch( ConfigError& e )
00216   {
00217     throw ConfigError( url + ": " + e.what() );
00218   }
00219 
00220   QF_STACK_POP
00221 }
00222 
00223 void DataDictionary::readFromStream( std::istream& stream )
00224 throw( ConfigError )
00225 { QF_STACK_PUSH(DataDictionary::readFromStream)
00226 
00227 #ifdef HAVE_LIBXML
00228   DOMDocumentPtr pDoc = DOMDocumentPtr(new LIBXML_DOMDocument());
00229 #elif _MSC_VER
00230   DOMDocumentPtr pDoc = DOMDocumentPtr(new MSXML_DOMDocument());
00231 #else
00232   DOMDocumentPtr pDoc = DOMDocumentPtr(new LIBXML_DOMDocument());
00233 #endif
00234 
00235   if(!pDoc->load(stream))
00236     throw ConfigError("Could not parse data dictionary stream");
00237 
00238   readFromDocument( pDoc );
00239 
00240   QF_STACK_POP
00241 }
00242 
00243 void DataDictionary::readFromDocument( DOMDocumentPtr pDoc )
00244 throw( ConfigError )
00245 { QF_STACK_PUSH(DataDictionary::readFromDocument)
00246 
00247   // VERSION
00248   DOMNodePtr pFixNode = pDoc->getNode("/fix");
00249   if(!pFixNode.get())
00250     throw ConfigError("Could not parse data dictionary file"
00251                       ", or no <fix> node found at root");
00252   DOMAttributesPtr attrs = pFixNode->getAttributes();
00253   std::string type = "FIX";
00254   if(attrs->get("type", type))
00255   {
00256     if(type != "FIX" && type != "FIXT")
00257       throw ConfigError("type attribute must be FIX or FIXT");
00258   }
00259   std::string major;
00260   if(!attrs->get("major", major))
00261     throw ConfigError("major attribute not found on <fix>");
00262   std::string minor;
00263   if(!attrs->get("minor", minor))
00264     throw ConfigError("minor attribute not found on <fix>");
00265   setVersion(type + "." + major + "." + minor);
00266 
00267   // FIELDS
00268   DOMNodePtr pFieldsNode = pDoc->getNode("/fix/fields");
00269   if(!pFieldsNode.get())
00270     throw ConfigError("<fields> section not found in data dictionary");
00271 
00272   DOMNodePtr pFieldNode = pFieldsNode->getFirstChildNode();
00273   if(!pFieldNode.get()) throw ConfigError("No fields defined");
00274 
00275   while(pFieldNode.get())
00276   {
00277     if(pFieldNode->getName() == "field")
00278     {
00279       DOMAttributesPtr attrs = pFieldNode->getAttributes();
00280       std::string name;
00281       if(!attrs->get("name", name))
00282         throw ConfigError("<field> does not have a name attribute");
00283       std::string number;
00284       if(!attrs->get("number", number))
00285         throw ConfigError("<field> " + name + " does not have a number attribute");
00286       int num = atol(number.c_str());
00287       std::string type;
00288       if(!attrs->get("type", type))
00289         throw ConfigError("<field> " + name + " does not have a type attribute");
00290       addField(num);
00291       addFieldType(num, XMLTypeToType(type));
00292       addFieldName(num, name);
00293 
00294       DOMNodePtr pFieldValueNode = pFieldNode->getFirstChildNode();
00295       while(pFieldValueNode.get())
00296       {
00297         if(pFieldValueNode->getName() == "value")
00298         {
00299           DOMAttributesPtr attrs = pFieldValueNode->getAttributes();
00300           std::string enumeration;
00301           if(!attrs->get("enum", enumeration))
00302             throw ConfigError("<value> does not have enum attribute in field " + name);
00303           addFieldValue(num, enumeration);
00304           std::string description;
00305           if(attrs->get("description", description))
00306             addValueName(num, enumeration, description);
00307         }
00308         RESET_AUTO_PTR(pFieldValueNode, pFieldValueNode->getNextSiblingNode());
00309       }
00310     }
00311     RESET_AUTO_PTR(pFieldNode, pFieldNode->getNextSiblingNode());
00312   }
00313 
00314   // HEADER
00315   if( type == "FIXT" || (type == "FIX" && major < "5") )
00316   {
00317     DOMNodePtr pHeaderNode = pDoc->getNode("/fix/header");
00318     if(!pHeaderNode.get())
00319       throw ConfigError("<header> section not found in data dictionary");
00320 
00321     DOMNodePtr pHeaderFieldNode = pHeaderNode->getFirstChildNode();
00322     if(!pHeaderFieldNode.get()) throw ConfigError("No header fields defined");
00323 
00324     while(pHeaderFieldNode.get())
00325     {
00326       if(pHeaderFieldNode->getName() == "field" || pHeaderFieldNode->getName() == "group" )
00327       {
00328         DOMAttributesPtr attrs = pHeaderFieldNode->getAttributes();
00329         std::string name;
00330         if(!attrs->get("name", name))
00331           throw ConfigError("<field> does not have a name attribute");
00332         std::string required = "false";
00333         attrs->get("required", required);
00334         addHeaderField(lookupXMLFieldNumber(pDoc.get(), name), required == "true");
00335       }
00336       if(pHeaderFieldNode->getName() == "group")
00337       {
00338         DOMAttributesPtr attrs = pHeaderFieldNode->getAttributes();
00339         std::string required;
00340         attrs->get("required", required);
00341         bool isRequired = (required == "Y" || required == "y");
00342         addXMLGroup(pDoc.get(), pHeaderFieldNode.get(), "_header_", *this, isRequired);
00343       }
00344 
00345       RESET_AUTO_PTR(pHeaderFieldNode, pHeaderFieldNode->getNextSiblingNode());
00346     }
00347   }
00348 
00349   // TRAILER
00350     if( type == "FIXT" || (type == "FIX" && major < "5") )
00351     {
00352     DOMNodePtr pTrailerNode = pDoc->getNode("/fix/trailer");
00353     if(!pTrailerNode.get())
00354       throw ConfigError("<trailer> section not found in data dictionary");
00355 
00356     DOMNodePtr pTrailerFieldNode = pTrailerNode->getFirstChildNode();
00357     if(!pTrailerFieldNode.get()) throw ConfigError("No trailer fields defined");
00358 
00359     while(pTrailerFieldNode.get())
00360     {
00361       if(pTrailerFieldNode->getName() == "field" || pTrailerFieldNode->getName() == "group" )
00362       {
00363         DOMAttributesPtr attrs = pTrailerFieldNode->getAttributes();
00364         std::string name;
00365         if(!attrs->get("name", name))
00366           throw ConfigError("<field> does not have a name attribute");
00367         std::string required = "false";
00368         attrs->get("required", required);
00369         addTrailerField(lookupXMLFieldNumber(pDoc.get(), name), required == "true");
00370       }
00371       if(pTrailerFieldNode->getName() == "group")
00372       {
00373         DOMAttributesPtr attrs = pTrailerFieldNode->getAttributes();
00374         std::string required;
00375         attrs->get("required", required);
00376         bool isRequired = (required == "Y" || required == "y");
00377         addXMLGroup(pDoc.get(), pTrailerFieldNode.get(), "_trailer_", *this, isRequired);
00378       }
00379 
00380       RESET_AUTO_PTR(pTrailerFieldNode, pTrailerFieldNode->getNextSiblingNode());
00381     }
00382   }
00383 
00384   // MSGTYPE
00385   DOMNodePtr pMessagesNode = pDoc->getNode("/fix/messages");
00386   if(!pMessagesNode.get())
00387     throw ConfigError("<messages> section not found in data dictionary");
00388 
00389   DOMNodePtr pMessageNode = pMessagesNode->getFirstChildNode();
00390   if(!pMessageNode.get()) throw ConfigError("No messages defined");
00391 
00392   while(pMessageNode.get())
00393   {
00394     if(pMessageNode->getName() == "message")
00395     {
00396       DOMAttributesPtr attrs = pMessageNode->getAttributes();
00397       std::string msgtype;
00398       if(!attrs->get("msgtype", msgtype))
00399         throw ConfigError("<field> does not have a name attribute");
00400       addMsgType(msgtype);
00401 
00402       std::string name;
00403       if(attrs->get("name", name))
00404         addValueName( 35, msgtype, name );
00405 
00406       DOMNodePtr pMessageFieldNode = pMessageNode->getFirstChildNode();
00407       if( !pMessageFieldNode.get() )
00408         throw ConfigError("<message> contains no fields");
00409       while( pMessageFieldNode.get() )
00410       {
00411         if(pMessageFieldNode->getName() == "field"
00412            || pMessageFieldNode->getName() == "group")
00413         {
00414           DOMAttributesPtr attrs = pMessageFieldNode->getAttributes();
00415           std::string name;
00416           if(!attrs->get("name", name))
00417             throw ConfigError("<field> does not have a name attribute");
00418           int num = lookupXMLFieldNumber(pDoc.get(), name);
00419           addMsgField(msgtype, num);
00420 
00421           std::string required;
00422           if(attrs->get("required", required)
00423              && (required == "Y" || required == "y"))
00424           {
00425             addRequiredField(msgtype, num);
00426           }
00427         }
00428         else if(pMessageFieldNode->getName() == "component")
00429         {
00430           DOMAttributesPtr attrs = pMessageFieldNode->getAttributes();
00431           std::string required;
00432           attrs->get("required", required);
00433           bool isRequired = (required == "Y" || required == "y");
00434           addXMLComponentFields(pDoc.get(), pMessageFieldNode.get(),
00435                                 msgtype, *this, isRequired);
00436         }
00437         if(pMessageFieldNode->getName() == "group")
00438         {
00439           DOMAttributesPtr attrs = pMessageFieldNode->getAttributes();
00440           std::string required;
00441           attrs->get("required", required);
00442           bool isRequired = (required == "Y" || required == "y");
00443           addXMLGroup(pDoc.get(), pMessageFieldNode.get(), msgtype, *this, isRequired);
00444         }
00445         RESET_AUTO_PTR(pMessageFieldNode,
00446                        pMessageFieldNode->getNextSiblingNode());
00447       }
00448     }
00449     RESET_AUTO_PTR(pMessageNode, pMessageNode->getNextSiblingNode());
00450   }
00451 
00452   QF_STACK_POP
00453 }
00454 
00455 int* DataDictionary::getOrderedFields() const
00456 { QF_STACK_PUSH(DataDictionary::getOrderedFields)
00457 
00458   if( m_orderedFieldsArray ) return m_orderedFieldsArray;
00459   m_orderedFieldsArray = new int[m_orderedFields.size() + 1];
00460 
00461   int* i = m_orderedFieldsArray;
00462   OrderedFields::const_iterator iter;
00463   for( iter = m_orderedFields.begin(); iter != m_orderedFields.end(); *(i++) = *(iter++) ) {}
00464   *i = 0;
00465   return m_orderedFieldsArray;
00466 
00467   QF_STACK_POP
00468 }
00469 
00470 int DataDictionary::lookupXMLFieldNumber( DOMDocument* pDoc, DOMNode* pNode ) const
00471 { QF_STACK_PUSH(DataDictionary::lookupXMLFieldNumber)
00472 
00473   DOMAttributesPtr attrs = pNode->getAttributes();
00474   std::string name;
00475   if(!attrs->get("name", name))
00476     throw ConfigError("No name given to field");
00477   return lookupXMLFieldNumber( pDoc, name );
00478 
00479   QF_STACK_POP
00480 }
00481 
00482 int DataDictionary::lookupXMLFieldNumber
00483 ( DOMDocument* pDoc, const std::string& name ) const
00484 { QF_STACK_PUSH(DataDictionary::lookupXMLFieldNumber)
00485 
00486   NameToField::const_iterator i = m_names.find(name);
00487   if( i == m_names.end() )
00488     throw ConfigError("Field " + name + " not defined in fields section");
00489   return i->second;
00490 
00491   QF_STACK_POP
00492 }
00493 
00494 int DataDictionary::addXMLComponentFields( DOMDocument* pDoc, DOMNode* pNode,
00495                                             const std::string& msgtype,
00496                                             DataDictionary& DD,
00497                                             bool componentRequired )
00498 { QF_STACK_PUSH(DataDictionary::addXMLComponentFields)
00499 
00500   int firstField = 0;
00501 
00502   DOMAttributesPtr attrs = pNode->getAttributes();
00503   std::string name;
00504   if(!attrs->get("name", name))
00505     throw ConfigError("No name given to component");
00506 
00507   DOMNodePtr pComponentNode =
00508     pDoc->getNode("/fix/components/component[@name='" + name + "']");
00509   if(pComponentNode.get() == 0)
00510     throw ConfigError("Component not found");
00511 
00512   DOMNodePtr pComponentFieldNode = pComponentNode->getFirstChildNode();
00513   while(pComponentFieldNode.get())
00514   {
00515     if(pComponentFieldNode->getName() == "field"
00516        || pComponentFieldNode->getName() == "group")
00517     {
00518       DOMAttributesPtr attrs = pComponentFieldNode->getAttributes();
00519       std::string name;
00520       if(!attrs->get("name", name))
00521         throw ConfigError("No name given to field");
00522       int field = lookupXMLFieldNumber(pDoc, name);
00523       if( firstField == 0 ) firstField = field;
00524 
00525       std::string required;
00526       if(attrs->get("required", required)
00527          && (required == "Y" || required =="y")
00528          && componentRequired)
00529       {
00530         addRequiredField(msgtype, field);
00531       }
00532 
00533       DD.addField(field);
00534       DD.addMsgField(msgtype, field);
00535     }
00536     if(pComponentFieldNode->getName() == "component")
00537     {
00538       DOMAttributesPtr attrs = pComponentFieldNode->getAttributes();
00539       std::string required;
00540       attrs->get("required", required);
00541       bool isRequired = (required == "Y" || required == "y");
00542       addXMLComponentFields(pDoc, pComponentFieldNode.get(),
00543                             msgtype, *this, isRequired);
00544     }
00545     if(pComponentFieldNode->getName() == "group")
00546     {
00547       DOMAttributesPtr attrs = pComponentFieldNode->getAttributes();
00548       std::string required;
00549       attrs->get("required", required);
00550       bool isRequired = (required == "Y" || required == "y");
00551       addXMLGroup(pDoc, pComponentFieldNode.get(), msgtype, DD, isRequired);
00552     }
00553     RESET_AUTO_PTR(pComponentFieldNode,
00554       pComponentFieldNode->getNextSiblingNode());
00555   }
00556   return firstField;
00557 
00558   QF_STACK_POP
00559 }
00560 
00561 void DataDictionary::addXMLGroup( DOMDocument* pDoc, DOMNode* pNode,
00562                                   const std::string& msgtype,
00563                                   DataDictionary& DD, bool groupRequired  )
00564 { QF_STACK_PUSH(DataDictionary::addXMLGroup)
00565 
00566   DOMAttributesPtr attrs = pNode->getAttributes();
00567   std::string name;
00568   if(!attrs->get("name", name))
00569     throw ConfigError("No name given to group");
00570   int group = lookupXMLFieldNumber( pDoc, name );
00571   int delim = 0;
00572   int field = 0;
00573   DataDictionary groupDD;
00574   DOMNodePtr node = pNode->getFirstChildNode();
00575   while(node.get())
00576   {
00577     if( node->getName() == "field" )
00578     {
00579       field = lookupXMLFieldNumber( pDoc, node.get() );
00580       groupDD.addField( field );
00581 
00582       DOMAttributesPtr attrs = node->getAttributes();
00583       std::string required;
00584       if( attrs->get("required", required)
00585          && ( required == "Y" || required =="y" )
00586          && groupRequired )
00587       {
00588         groupDD.addRequiredField(msgtype, field);
00589       }
00590     }
00591     else if( node->getName() == "component" )
00592     {
00593       field = addXMLComponentFields( pDoc, node.get(), msgtype, groupDD, false );
00594     }
00595     else if( node->getName() == "group" )
00596     {
00597       field = lookupXMLFieldNumber( pDoc, node.get() );
00598       groupDD.addField( field );
00599       DOMAttributesPtr attrs = node->getAttributes();
00600       std::string required;
00601       if( attrs->get("required", required )
00602          && ( required == "Y" || required =="y" )
00603          && groupRequired)
00604       {
00605         groupDD.addRequiredField(msgtype, field);
00606       }
00607             bool isRequired = false;
00608             if( attrs->get("required", required) )
00609                   isRequired = (required == "Y" || required == "y");
00610       addXMLGroup( pDoc, node.get(), msgtype, groupDD, isRequired );
00611     }
00612     if( delim == 0 ) delim = field;
00613     RESET_AUTO_PTR(node, node->getNextSiblingNode());
00614   }
00615 
00616   if( delim ) DD.addGroup( msgtype, group, delim, groupDD );
00617 
00618   QF_STACK_POP
00619 }
00620 
00621 TYPE::Type DataDictionary::XMLTypeToType( const std::string& type ) const
00622 { QF_STACK_PUSH(DataDictionary::XMLTypeToType)
00623 
00624   if ( m_beginString < "FIX.4.2" && type == "CHAR" )
00625     return TYPE::String;
00626 
00627   if ( type == "STRING" ) return TYPE::String;
00628   if ( type == "CHAR" ) return TYPE::Char;
00629   if ( type == "PRICE" ) return TYPE::Price;
00630   if ( type == "INT" ) return TYPE::Int;
00631   if ( type == "AMT" ) return TYPE::Amt;
00632   if ( type == "QTY" ) return TYPE::Qty;
00633   if ( type == "CURRENCY" ) return TYPE::Currency;
00634   if ( type == "MULTIPLEVALUESTRING" ) return TYPE::MultipleValueString;
00635   if ( type == "MULTIPLESTRINGVALUE" ) return TYPE::MultipleStringValue;
00636   if ( type == "MULTIPLECHARVALUE" ) return TYPE::MultipleCharValue;
00637   if ( type == "EXCHANGE" ) return TYPE::Exchange;
00638   if ( type == "UTCTIMESTAMP" ) return TYPE::UtcTimeStamp;
00639   if ( type == "BOOLEAN" ) return TYPE::Boolean;
00640   if ( type == "LOCALMKTDATE" ) return TYPE::LocalMktDate;
00641   if ( type == "DATA" ) return TYPE::Data;
00642   if ( type == "FLOAT" ) return TYPE::Float;
00643   if ( type == "PRICEOFFSET" ) return TYPE::PriceOffset;
00644   if ( type == "MONTHYEAR" ) return TYPE::MonthYear;
00645   if ( type == "DAYOFMONTH" ) return TYPE::DayOfMonth;
00646   if ( type == "UTCDATE" ) return TYPE::UtcDate;
00647   if ( type == "UTCDATEONLY" ) return TYPE::UtcDateOnly;
00648   if ( type == "UTCTIMEONLY" ) return TYPE::UtcTimeOnly;
00649   if ( type == "NUMINGROUP" ) return TYPE::NumInGroup;
00650   if ( type == "PERCENTAGE" ) return TYPE::Percentage;
00651   if ( type == "SEQNUM" ) return TYPE::SeqNum;
00652   if ( type == "LENGTH" ) return TYPE::Length;
00653   if ( type == "COUNTRY" ) return TYPE::Country;
00654   if ( type == "TIME" ) return TYPE::UtcTimeStamp;
00655   return TYPE::Unknown;
00656 
00657   QF_STACK_POP
00658 }
00659 }

Generated on Mon Apr 5 20:59:50 2010 for QuickFIX by doxygen 1.6.1 written by Dimitri van Heesch, © 1997-2001