//## begin module%1.7%.codegen_version preserve=yes // Read the documentation to learn more about C++ code generator // versioning. //## end module%1.7%.codegen_version //## begin module%41F607FA0261.cm preserve=no //## end module%41F607FA0261.cm //## begin module%41F607FA0261.cp preserve=no // C O P Y R I G H T N O T I C E // This material is confidential to ERG and may not be disclosed in whole // or in part to any third party nor used in any manner whatsoever other // than for the purposes expressly consented to by ERG in writing. // // This material is also copyright and may not be reproduced, stored in a // retrieval system or transmitted in any form or by any means in whole or // in part without the express written consent of ERG. //## end module%41F607FA0261.cp //## Module: TransactionSpecification%41F607FA0261; Pseudo Package body //## Subsystem: MASS::Dev::Tools::TxnTestManager::src%41F5A79001E4 //## Source file: Z:\MASS_Dev\Tools\TxnTestManager\src\TransactionSpecification.cpp //## begin module%41F607FA0261.additionalIncludes preserve=no //## end module%41F607FA0261.additionalIncludes //## begin module%41F607FA0261.includes preserve=yes #pragma warn -com #include #pragma warn +com //## end module%41F607FA0261.includes // IXmlSchemaWrapperSchema #include "IXmlSchemaWrapperSchema.h" // IXmlSchemaWrapperString #include "IXmlSchemaWrapperString.h" // Iteration #include "Iteration.h" // TestScenario #include "TestScenario.h" // TimeEstimate #include "TimeEstimate.h" // ProgressBar #include "ProgressBar.h" // IXmlSchemaWrapperByteArray #include "IXmlSchemaWrapperByteArray.h" // IXmlSchemaWrapperElement #include "IXmlSchemaWrapperElement.h" // IXmlSchemaWrapperFactory #include "IXmlSchemaWrapperFactory.h" // IXmlSchemaWrapperStream #include "IXmlSchemaWrapperStream.h" // TransactionSpecificationValue #include "TransactionSpecificationValue.h" // TransactionSpecification #include "TransactionSpecification.h" // MacQualification #include "MacQualification.h" // EvaluationCallback #include "EvaluationCallback.h" // EvaluationContext #include "EvaluationContext.h" // TransactionStream #include "TransactionStream.h" // TransactionStructure #include "TransactionStructure.h" // IHash #include "IHash.h" // IMessageDigest #include "IMessageDigest.h" //## begin module%41F607FA0261.additionalDeclarations preserve=yes #include #include "Utilities.h" #define COMPENSATE_FOR_PARSER_BUG 0 #if COMPENSATE_FOR_PARSER_BUG static void rotateBuffer( unsigned char * buffer, const unsigned int & length ) { unsigned char b; for ( unsigned int i=0, j=length-1; igetIteration().getIterationId(), m_scenario->getIteration().getSchemaWrapperFactory(), m_scenario->getIteration().getSchema(), true ); m_structure.push_back( object ); object = 0; object =new TransactionStructure( payloadStructureName, m_scenario->getIteration().getIterationId(), m_scenario->getIteration().getSchemaWrapperFactory(), m_scenario->getIteration().getSchema(), false ); m_structure.push_back( object ); object = 0; } catch ( ... ) { // Rollback. delete object; object = 0; for ( std::vector< TransactionStructure * >::iterator structure = m_structure.begin(); structure != m_structure.end(); ++structure ) { delete *structure; *structure = 0; } m_structure.clear(); throw; } //## end TransactionSpecification::TransactionSpecification%42045473030D.body } TransactionSpecification::~TransactionSpecification() { //## begin TransactionSpecification::~TransactionSpecification%41F607FA0261_dest.body preserve=yes for ( std::map< std::string, TransactionSpecificationValue * >::iterator transaction = m_value.begin(); transaction != m_value.end(); ++transaction ) { delete transaction->second; transaction->second = 0; } m_value.clear(); for ( std::vector< TransactionStructure * >::iterator structure = m_structure.begin(); structure != m_structure.end(); ++structure ) { delete *structure; *structure = 0; } m_structure.clear(); if ( m_string && m_scenario ) { m_scenario->getIteration().getSchemaWrapperFactory().destroyString( *m_string ); m_string = 0; } m_scenario = 0; // We don't own this object. //## end TransactionSpecification::~TransactionSpecification%41F607FA0261_dest.body } //## Other Operations (implementation) //## Operation: addMacField%4212DBC1031E void TransactionSpecification::addMacField (XMLSchema::IXmlSchemaWrapperElement &element) { //## begin TransactionSpecification::addMacField%4212DBC1031E.body preserve=yes m_macFields.push_back( &element ); //## end TransactionSpecification::addMacField%4212DBC1031E.body } //## Operation: addValue%41F70652035C void TransactionSpecification::addValue (const std::string &xPath, const std::string &value, const bool &obsolete) { //## begin TransactionSpecification::addValue%41F70652035C.body preserve=yes TransactionSpecificationValue * theValue = 0; try { theValue = new TransactionSpecificationValue( xPath, value, obsolete ); if ( !m_value.insert( std::map< std::string, TransactionSpecificationValue * >::value_type( theValue->getXPath(), theValue ) ).second ) { MTHROW( std::runtime_error, \ "Cannot add value \"" \ << theValue->getXPath() \ << "\" to transaction " \ << m_transactionSpecificationNumber \ << '.' ); } } catch ( ... ) { delete theValue; theValue = 0; throw; } //## end TransactionSpecification::addValue%41F70652035C.body } //## Operation: clearMacFields%42130B2D0377 void TransactionSpecification::clearMacFields () { //## begin TransactionSpecification::clearMacFields%42130B2D0377.body preserve=yes XMLSchema::IXmlSchemaWrapperFactory & factory = m_scenario->getIteration().getSchemaWrapperFactory(); for ( std::vector< XMLSchema::IXmlSchemaWrapperElement * > ::iterator element = m_macFields.begin(); element != m_macFields.end(); ++element ) { factory.destroySchemaElement( **element ); *element = 0; } m_macFields.clear(); //## end TransactionSpecification::clearMacFields%42130B2D0377.body } //## Operation: clearMarks%41F705790276 void TransactionSpecification::clearMarks () { //## begin TransactionSpecification::clearMarks%41F705790276.body preserve=yes for ( std::map< std::string, TransactionSpecificationValue * >::iterator where = m_value.begin(); where != m_value.end(); ++where ) { where->second->unmark(); } //## end TransactionSpecification::clearMarks%41F705790276.body } //## Operation: generate%4204564D02F3 const bool TransactionSpecification::generate (TransactionStream& stream, const bool &generateHeaders, EvaluationContext& evaluationContext) { //## begin TransactionSpecification::generate%4204564D02F3.body preserve=yes XMLSchema::IXmlSchemaWrapperFactory & xmlSchemaWrapperFactory = m_scenario->getIteration().getSchemaWrapperFactory(); /** * Traverse the structures associated with this transaction in order, * querying our collection of defined fields for every schema element * that we encounter. When we have a match, then we evaluate the * expression found, and assign the result to the schema element currently * being visited. */ evaluationContext.setTransaction( *this ); EvaluationCallback callback( *this, evaluationContext ); bool generated = false; m_structureIndex = 0; std::vector< TransactionStructure * >::iterator structure; for ( structure = m_structure.begin(); structure != m_structure.end(); ++structure ) { if ( generateHeaders || !(*structure)->isHeader() ) { generated = (*structure)->getSchemaElement().traverse( callback ); if ( !generated ) { break; } } ++m_structureIndex; } if ( generated ) { /** * If we have any MAC fields, then we must compute the MAC and assign * the MAC to each element in the collection. */ if ( m_macFields.size() ) { if ( evaluationContext.haveMessageDigest() ) { /** * Create a serialsation stream, and serialise all attributes * into it that are to be included in the MAC. Then MAC the * stream. We need to do this because we need to MAC the * serialised form, not the internal binary form. */ MacQualification macQualification( evaluationContext ); XMLSchema::IXmlSchemaWrapperStream * stream = 0; XMLSchema::IXmlSchemaWrapperByteArray * digest = 0; try { stream = &xmlSchemaWrapperFactory.createXdrStream(); digest = &xmlSchemaWrapperFactory.createByteArray(); for ( structure = m_structure.begin(); structure != m_structure.end(); ++structure ) { // We only include the structure in the MAC computation, // never the header. if ( !(*structure)->isHeader() ) { if ( !(*structure)->write( *stream, macQualification ) ) { generated = false; break; } } } if ( generated ) { void * buffer = 0; unsigned int length = 0; // When we get a zero-length MAC, we don't assign it. if ( stream->getData( buffer, length ) ) { evaluationContext.getMessageDigest().reset(); if ( evaluationContext.haveHash() ) { IHash & hash = evaluationContext.getHash(); hash.reset(); generated = hash.updateByteArray( buffer, length ) && hash.digest(); if ( generated ) { generated = evaluationContext. getMessageDigest().updateByteArray( hash.getValue(), hash.getLength() ); } } else { generated = evaluationContext.getMessageDigest(). updateByteArray( buffer, length ); } if ( generated ) { if ( evaluationContext.getMessageDigest().digest() ) { if ( evaluationContext.getMessageDigest().getLength() ) { #if COMPENSATE_FOR_PARSER_BUG /** * Compensate for the parser treating * an array of 8 U8 as a U64 (Why does * it do that? Its wrong.). */ unsigned char * b = const_cast< unsigned char * >( evaluationContext.getMessageDigest().getValue() ); length = evaluationContext.getMessageDigest().getLength(); rotateBuffer( b, length ); digest->assign( b, length ); #else digest->assign( evaluationContext.getMessageDigest().getValue(), evaluationContext.getMessageDigest().getLength() ); #endif // #ifdef COMPENSATE_FOR_PARSER_BUG for ( std::vector< XMLSchema::IXmlSchemaWrapperElement * > ::iterator macField = m_macFields.begin(); macField != m_macFields.end(); ++macField ) { if ( !(*macField)->setByteArray( *digest ) ) { generated = false; break; } } } else { generated = false; } } else { generated = false; } } } } } __finally { if ( digest ) { xmlSchemaWrapperFactory.destroyByteArray( *digest ); digest = 0; } if ( stream ) { xmlSchemaWrapperFactory.destroyStream( *stream ); stream = 0; } } } else { generated = false; } if ( !generated ) { std::stringstream message; message << "Cannot compute MAC. Is the security subsystem operational?"; MERROR( message.str() ); message << " Ignore the error and continue?"; generated = ( MessageDlg( message.str().c_str(), mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0 ) == mrYes ); } clearMacFields(); } } if ( generated ) { for ( structure = m_structure.begin(); structure != m_structure.end(); ++structure ) { if ( generateHeaders || !(*structure)->isHeader() ) { /** * Serialise the structure into the transaction stream. */ generated = (*structure)->write( stream ); if ( !generated ) { break; } } } stream.incrementCount(); if ( evaluationContext.haveProgressBar() ) { evaluationContext.getProgressBar().increment(); } evaluationContext.getTimeEstimate().increment(); } return ( generated ); //## end TransactionSpecification::generate%4204564D02F3.body } //## Operation: getCurrentStructure%4213183F01DD const TransactionStructure & TransactionSpecification::getCurrentStructure () const { //## begin TransactionSpecification::getCurrentStructure%4213183F01DD.body preserve=yes return ( *m_structure[ m_structureIndex ] ); //## end TransactionSpecification::getCurrentStructure%4213183F01DD.body } //## Operation: getFormatVersion%4208BB80011D const int & TransactionSpecification::getFormatVersion () const { //## begin TransactionSpecification::getFormatVersion%4208BB80011D.body preserve=yes return ( m_formatVersion ); //## end TransactionSpecification::getFormatVersion%4208BB80011D.body } //## Operation: getScenario%420471B00192 const TestScenario & TransactionSpecification::getScenario () const { //## begin TransactionSpecification::getScenario%420471B00192.body preserve=yes return ( *m_scenario ); //## end TransactionSpecification::getScenario%420471B00192.body } //## Operation: getTransactionField%4204283B033E TransactionSpecificationValue& TransactionSpecification::getTransactionField (const std::string &xpath) { //## begin TransactionSpecification::getTransactionField%4204283B033E.body preserve=yes std::map< std::string, TransactionSpecificationValue * >::const_iterator instance = m_value.find( xpath ); if ( instance != m_value.end() ) { return ( *instance->second ); } else { TransactionSpecificationValue * object = 0; try { object = new TransactionSpecificationValue( xpath, *this ); if ( m_value.insert( std::map< std::string, TransactionSpecificationValue * >::value_type( xpath, object ) ).second ) { return ( *object ); } else { MTHROW( std::runtime_error, \ "Cannot add transaction field \"" \ << xpath \ << "\" to transaction " \ << m_transactionSpecificationNumber \ << '.' ); } } catch ( ... ) { delete object; object = 0; throw; } } //## end TransactionSpecification::getTransactionField%4204283B033E.body } //## Operation: getTransactionSpecificationNumber%41F71AD2002F const int & TransactionSpecification::getTransactionSpecificationNumber () const { //## begin TransactionSpecification::getTransactionSpecificationNumber%41F71AD2002F.body preserve=yes return ( m_transactionSpecificationNumber ); //## end TransactionSpecification::getTransactionSpecificationNumber%41F71AD2002F.body } //## Operation: getUdSubtype%4208AFAF01F7 const unsigned short & TransactionSpecification::getUdSubtype () const { //## begin TransactionSpecification::getUdSubtype%4208AFAF01F7.body preserve=yes return ( m_udSubtype ); //## end TransactionSpecification::getUdSubtype%4208AFAF01F7.body } //## Operation: getUdType%4208AFAF0245 const unsigned short & TransactionSpecification::getUdType () const { //## begin TransactionSpecification::getUdType%4208AFAF0245.body preserve=yes return ( m_udType ); //## end TransactionSpecification::getUdType%4208AFAF0245.body } //## Operation: getValues%41F705A600AC const std::map< std::string, TransactionSpecificationValue * > & TransactionSpecification::getValues () const { //## begin TransactionSpecification::getValues%41F705A600AC.body preserve=yes return ( m_value ); //## end TransactionSpecification::getValues%41F705A600AC.body } //## Operation: isContained%41F70575014E const bool TransactionSpecification::isContained (const std::string &xPath) const { //## begin TransactionSpecification::isContained%41F70575014E.body preserve=yes return ( m_value.find( xPath ) != m_value.end() ); //## end TransactionSpecification::isContained%41F70575014E.body } //## Operation: isMarked%41F708CB0307 const bool TransactionSpecification::isMarked (const std::string &xPath) const { //## begin TransactionSpecification::isMarked%41F708CB0307.body preserve=yes std::map< std::string, TransactionSpecificationValue * >::const_iterator instance = m_value.find( xPath ); if ( instance != m_value.end() ) { return ( instance->second->isMarked() ); } else { MTHROW( std::runtime_error, \ "Cannot find value " << xPath << '.' ); } //## end TransactionSpecification::isMarked%41F708CB0307.body } //## Operation: markValue%41F7069E002F void TransactionSpecification::markValue (const std::string &xPath) { //## begin TransactionSpecification::markValue%41F7069E002F.body preserve=yes std::map< std::string, TransactionSpecificationValue * >::const_iterator instance = m_value.find( xPath ); if ( instance != m_value.end() ) { instance->second->mark(); } else { MTHROW( std::runtime_error, \ "Cannot find value " << xPath << '.' ); } //## end TransactionSpecification::markValue%41F7069E002F.body } //## Operation: setUdSubtype%42044110019A const unsigned short & TransactionSpecification::setUdSubtype (const unsigned short &value) { //## begin TransactionSpecification::setUdSubtype%42044110019A.body preserve=yes return ( m_udSubtype = value ); //## end TransactionSpecification::setUdSubtype%42044110019A.body } //## Operation: setUdType%420440DE038E const unsigned short & TransactionSpecification::setUdType (const unsigned short &value) { //## begin TransactionSpecification::setUdType%420440DE038E.body preserve=yes return ( m_udType = value ); //## end TransactionSpecification::setUdType%420440DE038E.body } //## Operation: evaluate%4205C6F500FC const bool TransactionSpecification::evaluate (XMLSchema::IXmlSchemaWrapperElement &element, EvaluationContext& context) { //## begin TransactionSpecification::evaluate%4205C6F500FC.body preserve=yes /** * Build an XPath from the name of the structure that we are traversing * right now and the xpath reported by the element being visited. Then * look for a field with that XPath. */ std::stringstream xpath; if ( element.getAttributeValue( "xpath", *m_string ) ) { xpath << '/' << m_structure[ m_structureIndex ]->getName() << m_string->c_str(); /** * Find the element if we have it. We get calls for everything, not * just for what we have. When we don't have the element, then we * have nothing to set, which is fine. */ std::map< std::string, TransactionSpecificationValue * >::iterator field = m_value.find( xpath.str() ); if ( field != m_value.end() ) { std::string value; bool postponed = false; if ( field->second->evaluate( value, true, context, postponed ) ) { if ( !postponed ) { *m_string = value.c_str(); if ( element.setString( *m_string ) ) { return ( true ); } else { std::string datatype; if ( element.getAttributeValue( "datatype", *m_string ) ) { datatype = m_string->c_str(); } std::stringstream message; message << "Cannot set value of \"" << xpath.str() << "\" to \"" << value << "\" as \"" << datatype << "\"."; MERROR( message.str() ); message << " Continue?"; return ( MessageDlg( message.str().c_str(), mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0 ) == mrYes ); } } else { return ( true ); } } else { std::stringstream message; message << "Cannot evaluate value of \"" \ << field->second->getExpression() \ << "\" for \"" \ << xpath.str() \ << "\"."; MERROR( message.str() ); message << " Continue?"; return ( MessageDlg( message.str().c_str(), mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0 ) == mrYes ); } } else { // We have no value for this element, which is fine. return ( true ); } } else { MERROR( "Cannot get xpath for schema element " << &element << '.' ); } return ( false ); //## end TransactionSpecification::evaluate%4205C6F500FC.body } // Additional Declarations //## begin TransactionSpecification%41F607FA0261.declarations preserve=yes //## end TransactionSpecification%41F607FA0261.declarations //## begin module%41F607FA0261.epilog preserve=yes //## end module%41F607FA0261.epilog