Subversion Repositories DevTools

Rev

Rev 2273 | Blame | Compare with Previous | Last modification | View Log | RSS feed

//## 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%420AC16002C1.cm preserve=no
//## end module%420AC16002C1.cm

//## begin module%420AC16002C1.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%420AC16002C1.cp

//## Module: FieldExpression%420AC16002C1; Pseudo Package body
//## Subsystem: MASS::Dev::Tools::TxnTestManager::src%41F5A79001E4
//## Source file: Z:\MASS_Dev\Tools\TxnTestManager\src\FieldExpression.cpp

//## begin module%420AC16002C1.additionalIncludes preserve=no
//## end module%420AC16002C1.additionalIncludes

//## begin module%420AC16002C1.includes preserve=yes
#pragma warn -com
#include <LoggingMacros.h>
#pragma warn +com

#include <vcl.h>
#pragma hdrstop
//## end module%420AC16002C1.includes

// ICryptographicServerProxy
#include "ICryptographicServerProxy.h"
// IMessageDigest
#include "IMessageDigest.h"
// IXmlSchemaWrapperElement
#include "IXmlSchemaWrapperElement.h"
// TransactionSpecification
#include "TransactionSpecification.h"
// EvaluationContext
#include "EvaluationContext.h"
// SequenceCollection
#include "SequenceCollection.h"
// Sequence
#include "Sequence.h"
// FieldExpression
#include "FieldExpression.h"
// DefinedVariable
#include "DefinedVariable.h"
// DefinedVariableTable
#include "DefinedVariableTable.h"
//## begin module%420AC16002C1.additionalDeclarations preserve=yes
#include <time>
#include <locale>
#include <sstream>

enum TokenId
{
        TOKENID_INVALID = 0,
        TOKENID_FUNCTION,
        TOKENID_VARIABLE,
        TOKENID_CONSTANT
};
enum FunctionId
{
        EXPRESSIONID_INVALID = 0,
        EXPRESSIONID_FORMATVERSION,
        EXPRESSIONID_NOW,
        EXPRESSIONID_UTCNOW,
        EXPRESSIONID_TODAY,
        EXPRESSIONID_YESTERDAY,
        EXPRESSIONID_TOMORROW,
        EXPRESSIONID_RAND,
        EXPRESSIONID_UDTYPE,
        EXPRESSIONID_UDSUBTYPE,
        EXPRESSIONID_ACCOUNTTYPE,
        EXPRESSIONID_SEQ,
        EXPRESSIONID_KEYVERSION,
        EXPRESSIONID_KEYNUMBER,
        EXPRESSIONID_MAC,
        EXPRESSIONID_SAMID,
        EXPRESSIONID_SCENARIO_INDEX,
        EXPRESSIONID_HOSTNAME,
        EXPRESSIONID_USERNAME,
        EXPRESSIONID_USESEQ,
    EXPRESSIONID_SETSHIFTSTART,   
    EXPRESSIONID_USESHIFTSTART,
    };
struct PredefinedFunction
{
        const char *    functor;
        FunctionId              functionId;
};

static const PredefinedFunction functions[] =
{
        { "FORMATVERSION",      EXPRESSIONID_FORMATVERSION },
        { "NOW",                        EXPRESSIONID_NOW },
        { "UTCNOW",                     EXPRESSIONID_UTCNOW },
        { "TODAY",                      EXPRESSIONID_TODAY },
        { "YESTERDAY",          EXPRESSIONID_YESTERDAY },
        { "TOMORROW",           EXPRESSIONID_TOMORROW },
        { "RAND",                       EXPRESSIONID_RAND },
        { "UDTYPE",                     EXPRESSIONID_UDTYPE },
        { "UDSUBTYPE",          EXPRESSIONID_UDSUBTYPE },
        { "ACCOUNTTYPE",        EXPRESSIONID_ACCOUNTTYPE },
        { "SEQ",                        EXPRESSIONID_SEQ },
        { "KEYVERSION",         EXPRESSIONID_KEYVERSION },
        { "KEYNUMBER",          EXPRESSIONID_KEYNUMBER },
        { "MAC",                        EXPRESSIONID_MAC },
        { "SAMID",                      EXPRESSIONID_SAMID },
        { "SCENARIOINDEX",      EXPRESSIONID_SCENARIO_INDEX },
        { "HOSTNAME",           EXPRESSIONID_HOSTNAME },
        { "USERNAME",           EXPRESSIONID_USERNAME },
        { "USESEQ",                     EXPRESSIONID_USESEQ },
        { "SETSHIFTSTART",      EXPRESSIONID_SETSHIFTSTART },
        { "USESHIFTSTART",      EXPRESSIONID_USESHIFTSTART },
        { 0,                            EXPRESSIONID_INVALID }
};

static const std::locale myLocale;

const FunctionId & getFunctionId( const std::string & string )
{
        PredefinedFunction const * where = 0;

        for ( where = functions; where->functor; ++where )
        {
                if ( string == where->functor )
                {
                        break;
                }
        }

        return ( where->functionId );
}

const bool readExpression( std::istream & stream, std::string & symbol, TokenId & token, EvaluationContext& evaluationContext )
{
        symbol.erase();

        char character = 0;
        while ( stream.get( character ).good() )
        {
                if ( std::isalnum( character ) || character == '_' )
                {
                        symbol += character;
                }
                else
                {
                        stream.putback( character );    // Always put this back.

                        if ( character == '(' )
                        {
                                token = TOKENID_FUNCTION;
                                return ( true );
                        }

                        break;  // We have read in a lexeme, now tokenise it.
                }
        }

        // Only do this when we didn't fail reading from the stream.
        if ( stream.good() || stream.eof() )
        {
                token = ( evaluationContext.getSymbolTable().isVariable( symbol, evaluationContext )
                        ? TOKENID_VARIABLE
                        : TOKENID_CONSTANT );
                return ( true );
        }

        return ( false );
}
//## end module%420AC16002C1.additionalDeclarations


// Class FieldExpression 

FieldExpression::FieldExpression()
  //## begin FieldExpression::FieldExpression%420AC16002C1_const.initialization preserve=yes
  //## end FieldExpression::FieldExpression%420AC16002C1_const.initialization
{
  //## begin FieldExpression::FieldExpression%420AC16002C1_const.body preserve=yes
  //## end FieldExpression::FieldExpression%420AC16002C1_const.body
}

//## Operation: FieldExpression%42105AAC0084
FieldExpression::FieldExpression (const std::string &expression)
  //## begin FieldExpression::FieldExpression%42105AAC0084.hasinit preserve=no
  //## end FieldExpression::FieldExpression%42105AAC0084.hasinit
  //## begin FieldExpression::FieldExpression%42105AAC0084.initialization preserve=yes

:       m_expression( expression )

  //## end FieldExpression::FieldExpression%42105AAC0084.initialization
{
  //## begin FieldExpression::FieldExpression%42105AAC0084.body preserve=yes
  //## end FieldExpression::FieldExpression%42105AAC0084.body
}


FieldExpression::~FieldExpression()
{
  //## begin FieldExpression::~FieldExpression%420AC16002C1_dest.body preserve=yes
  //## end FieldExpression::~FieldExpression%420AC16002C1_dest.body
}



//## Other Operations (implementation)
//## Operation: evaluate%420456630303
const bool FieldExpression::evaluate (std::string &value, const bool &sideEffect, EvaluationContext& evaluationContext, std::vector< DefinedVariable * > &path, bool &postponed)
{
  //## begin FieldExpression::evaluate%420456630303.body preserve=yes

        if ( m_cachedValue.length() )
        {
                value = m_cachedValue;
                return ( true );
        }

        /**
         *      TODO: Eventually replace the use of streams with a char buffer, but
         *      right now I just need to get it working.
         */
        if ( ( m_expression[ 0 ] == '\"' ) &&
                 ( m_expression[ m_expression.length() - 1 ] == '\"' ) )
        {
                value = m_cachedValue = m_expression.substr( 1, m_expression.length() - 2 );
                return ( true );
        }

        std::istringstream is( m_expression );
        skipCharacter( is, '=' );       // Skip the '=' if its there.

        /**
         *      TODO: evaluate this field using the defined collection of variables
         *      and sequence generators, making sure we respect the sideEffect flag.
         */
        /**
                For now, we assume a very simple syntax:

                        expression              ::= function | variable | constant
                        function                ::= =functor ( [ argument list ] )
                        variable                ::= =variable
                        constant                ::= alphanumeric
                        argument list   ::= argument[, argument list ]
                        argument                ::= expression
         */
        std::string     symbol;
        TokenId         token = TOKENID_INVALID;
        while ( readExpression( is, symbol, token, evaluationContext ) )
        {
                switch ( token )
                {
                case TOKENID_FUNCTION:
                        return ( evaluateFunction( is, value, symbol, sideEffect, evaluationContext, path, postponed ) );
                case TOKENID_VARIABLE:
                        return ( evaluateVariable( is, value, symbol, sideEffect, evaluationContext, path, postponed ) );
                case TOKENID_CONSTANT:
                        // Its not a defined variable or function, so just evaluate to
                        // it.
                        m_cachedValue = value = m_expression;
                        return ( true );
                }
        }

        return ( true );

  //## end FieldExpression::evaluate%420456630303.body
}

//## Operation: evaluateFunction%4208AE9D0216
const bool FieldExpression::evaluateFunction (std::istream &is, std::string &value, std::string &symbol, const bool &sideEffect, EvaluationContext& evaluationContext, std::vector< DefinedVariable * > &path, bool &postponed)
{
  //## begin FieldExpression::evaluateFunction%4208AE9D0216.body preserve=yes

        /**
         *      Check parameter lists on all functions calls, and report an error
         *      when a function is called with superfluous arguments.
         */

        postponed = false;
        switch ( getFunctionId( symbol ) )
        {
        case EXPRESSIONID_UDTYPE:
                {
                        AnsiString os;
                        os.sprintf( "%hu", evaluationContext.getTransaction().getUdType() );
                        m_cachedValue = value = os.c_str();
                }
                return ( true );
        case EXPRESSIONID_UDSUBTYPE:
                {
                        AnsiString os;
                        os.sprintf( "%hu", evaluationContext.getTransaction().getUdSubtype() );
                        m_cachedValue = value = os.c_str();
                }
                return ( true );
        case EXPRESSIONID_TODAY:
                m_cachedValue = value = TDateTime::CurrentDateTime().FormatString( "dd-mm-yyyy" ).c_str();
                return ( true );
        case EXPRESSIONID_FORMATVERSION:
                {
                        AnsiString os;
                        os.sprintf( "%d", evaluationContext.getTransaction().getFormatVersion() );
                        m_cachedValue = value = os.c_str();
                }
                return ( true );
        case EXPRESSIONID_NOW:
                value = TDateTime::CurrentDateTime().FormatString( "dd-mm-yyyy hh:nn:ss" ).c_str();
                return ( true );
        case EXPRESSIONID_UTCNOW:
                {
                        const TDateTime time = TDateTime::CurrentDateTime() + ( ( _timezone / 3600.0 ) / 24.0 );

                        value = time.FormatString( "dd-mm-yyyy hh:nn:ss" ).c_str();
                }
                return ( true );
        case EXPRESSIONID_YESTERDAY:
                {
                        const TDateTime time = TDateTime::CurrentDateTime() - 1;

                        m_cachedValue = value = time.FormatString( "dd-mm-yyyy" ).c_str();
                }
                return ( true );
        case EXPRESSIONID_TOMORROW:
                {      
                std::string days;
            int advanceDays;
                        if ( skipCharacter( is, '(' ) &&
                                 readTerm( is, days ) &&
                                 skipCharacter( is, ')' ) )
                        {
                                advanceDays     =       atoi( days.c_str() );
                if (advanceDays == 0) advanceDays = 1; //for invalid format default to tomorrow
            }
            else
            {
                advanceDays = 1;
            }                                                   
        
                        const TDateTime time = TDateTime::CurrentDateTime() + advanceDays;

                        m_cachedValue = value = time.FormatString( "dd-mm-yyyy" ).c_str();
                }
                return ( true );        
    case EXPRESSIONID_SETSHIFTSTART:
                {                                         
            const TDateTime time = TDateTime::CurrentDateTime() + ( ( _timezone / 3600.0 ) / 24.0 );
            
                        value = ( time.FormatString( "dd-mm-yyyy hh:nn:ss" ).c_str());
            
            evaluationContext.setStartTime (value);
                }
                return ( true );    
    case EXPRESSIONID_USESHIFTSTART:
                {                  
            value = evaluationContext.getStartTime();
                }
                return ( true );
        case EXPRESSIONID_ACCOUNTTYPE:
                switch( evaluationContext.getTransaction().getUdType() )
                {
                case 1: // Card
                        value = "2";
                        break;
                case 2: // Application
                        value = "1";
                        break;
                case 3: // Product
                        value = "3";
                        break;
                case 4: // Other
                        value = "4";
                        break;
                case 5: // Audit
                        value = "4";
                        break;
                case 6: // Event
                        value = "4";
                        break;
                case 7: // Project
                        value = "4";
                        break;
                default:
                        value.erase();
                        break;
                }
                m_cachedValue = value;
                return ( true );
        case EXPRESSIONID_RAND:
                {
                        std::string lowerBound;
                        std::string upperBound;
                        if ( skipCharacter( is, '(' ) &&
                                 readTerm( is, lowerBound ) &&
                                 skipCharacter( is, ',' ) &&
                                 readTerm( is, upperBound ) &&
                                 skipCharacter( is, ')' ) )
                        {
                                const int first = std::min< int >(
                                                                        atoi( lowerBound.c_str() ),
                                                                        atoi( upperBound.c_str() ) );
                                const int last  = std::max< int >(
                                                                        atoi( lowerBound.c_str() ),
                                                                        atoi( upperBound.c_str() ) );

                                AnsiString os;
                                os.sprintf( "%d",
                                        int( ( rand() / double( RAND_MAX ) ) *
                                                 ( last - first + 1 ) + first ) );
                                value = os.c_str();
                                return ( true );
                        }
                        else
                        {
                                MERROR( "Cannot parse argument list." );
                        }
                }
                break;
        case EXPRESSIONID_SEQ:
                {
                        bool persisted = false;
                        std::string name;
                        std::string first;
                        std::string increment;
                        std::string last;
                        std::string discriminant;
                        std::string     fullName;

                        /**
                         *      SEQ( name, first, increment, last[, discriminant] )
                         *      name ::= transient name | # persisted name
                         */
                        if ( skipCharacter( is, '(' ) )
                        {
                                persisted = skipCharacter( is, '#' );

                                if ( readIdentifier( is, name ) &&
                                         skipCharacter( is, ',' ) &&
                                         readTerm( is, first ) &&
                                         skipCharacter( is, ',' ) &&
                                         readTerm( is, last ) &&
                                         skipCharacter( is, ',' ) &&
                                         readTerm( is, increment ) &&
                                         ( ( skipCharacter( is, ',' ) &&
                                                 readIdentifier( is, discriminant ) ) ||
                                           skipCharacter( is, ')' ) ) )
                                {
                                        if ( discriminant.length() )
                                        {
                                                /**
                                                 *      We have a discriminant, so we evaluate it to form
                                                 *      our name,
                                                         *     With a special cases for auto udsn, ssn, trip and psn
                                                 */
                         
                        if (name == "UDSN")
                        {
                            fullName = "UDSN["+evaluationContext.getDeviceId()+"]";
                        }
                        else if (name == "AUTOSSN")
                        {
                            fullName = "AUTOSSN["+evaluationContext.getDeviceId()+"]";
                        }
                        else if (name == "AUTOTRIP")
                        {
                            fullName = "AUTOTRIP["+evaluationContext.getDeviceId()+"]";
                        }                         
                        else if (name == "AUTOPSN")
                        {
                            fullName = "AUTOPSN["+evaluationContext.getCsn()+"]";
                        } 
                        else  
                        {
                                                   FieldExpression subexpression( discriminant );

                                                   std::string discriminantValue;
                                                   if ( subexpression.evaluate( discriminantValue, true, evaluationContext, path, postponed ) )
                                                   {
                                                       AnsiString full;
                                                           full.sprintf( "%s[%s]", name.c_str(), discriminantValue.c_str() );
                                                           fullName = full.c_str();
                                                   }
                        }
                                        }
                                        else
                                        {
                                                fullName = name;
                                        }

                                        Sequence & sequence = evaluationContext.
                                                getSequenceCollection().getSequence(
                                                        fullName,
                                                        persisted,
                                                        atoi( first.c_str() ) );
                    
                    // don't increment on very first use of a new sequence  
                    if(sequence.isDirty() || sequence.isUpdate())
                    {                    
                                        sequence.incrementValue(
                                                atoi( first.c_str() ),
                                                atoi( last.c_str() ),
                                                atoi( increment.c_str() ) );
                    }    
                                        AnsiString os;
                                        os.sprintf( "%d", sequence.getValue() );
                                        value = os.c_str();
                        
                    sequence.setDirty (true); //used to force an increment next time round as well as db refresh    

                                        return ( true );
                                }
                        }

                        MERROR( "Cannot parse argument list." );
                }
                break;
        case EXPRESSIONID_USESEQ:
                {
                        bool persisted = false;
                        std::string name;
                        std::string discriminant;
                        std::string     fullName;

                        /**
                         *      SEQ( name, first, increment, last[, discriminant] )
                         *      name ::= transient name | # persisted name
                         */
                        if ( skipCharacter( is, '(' ) )
                        {
                                persisted = skipCharacter( is, '#' );
                                if ( readIdentifier( is, name ) &&
                                         ( ( skipCharacter( is, ',' ) &&
                                                 readIdentifier( is, discriminant ) ) ||
                                           skipCharacter( is, ')' ) ) )
                                {
                                        if ( discriminant.length() )
                                        {
                                                /**
                                                 *      We have a discriminant, so we evaluate it to form
                                                 *      our name,
                                                 */
                        if (name == "AUTOSSN")
                        {
                            fullName = "AUTOSSN["+evaluationContext.getDeviceId()+"]";
                        }
                        else if (name == "AUTOTRIP")
                        {
                            fullName = "AUTOTRIP["+evaluationContext.getDeviceId()+"]";
                        } 
                        else if (name == "AUTOPSN")
                        {
                            fullName = "AUTOPSN["+evaluationContext.getCsn()+"]";
                        }                         
                        else  
                        {
                                                   FieldExpression subexpression( discriminant );

                                                   std::string discriminantValue;
                                                   if ( subexpression.evaluate( discriminantValue, true, evaluationContext, path, postponed ) )
                                                   {
                                                       AnsiString full;
                                                           full.sprintf( "%s[%s]", name.c_str(), discriminantValue.c_str() );
                                                           fullName = full.c_str();
                                                   }
                        }                         
                                        }
                                        else
                                        {
                                                fullName = name;
                                        }

                                        Sequence & sequence = evaluationContext.
                                                getSequenceCollection().getSequence(
                                                        fullName,
                                                        true,      // really don't care
                                                        1 );       // default if seq not already created
                                        AnsiString os;
                                        os.sprintf( "%d", sequence.getValue() );
                                        value = os.c_str();
                    
                    // note: there is intentionally no increment

                                        return ( true );
                                }
                        }

                        MERROR( "Cannot parse argument list." );
                }
                break;        
        case EXPRESSIONID_KEYVERSION:
                if ( evaluationContext.haveMessageDigest() )
                {
                        AnsiString os;
                        os.sprintf( "%hu", evaluationContext.getMessageDigest().getKeyVersion() );
                        value = os.c_str();

                        return ( true );
                }
                break;
        case EXPRESSIONID_KEYNUMBER:
                if ( evaluationContext.haveMessageDigest() )
                {
                        AnsiString os;
                        os.sprintf( "%hu", evaluationContext.getMessageDigest().getKeyNumber() );
                        value = os.c_str();

                        return ( true );
                }
                break;
        case EXPRESSIONID_MAC:
                /**
                 *      We add the schema element to the collection of schema elements to
                 *      which we must assign the MAC.  Because we can compute the MAC only
                 *      when all fields have been evaluated, this must be postponed, and
                 *      until then we must report success.
                 */
                if ( evaluationContext.haveSchemaElement() )
                {
                        evaluationContext.getTransaction().addMacField(
                                evaluationContext.getSchemaElement().clone() );
                        postponed = true;

                        return ( true );
                }
                break;
        case EXPRESSIONID_SAMID:
                if ( evaluationContext.haveCryptographicServer() )
                {
                        /**
                         *      We don't know which module will be used to compute the
                         *      MAC (security doesn't tell us), so until they do we
                         *      assume its the first module.
                         */
                        /*
      if ( evaluationContext.getCryptographicServer().getModuleCount() )
                        {
                                AnsiString os;
                                os.sprintf( "%hu", evaluationContext.getCryptographicServer().getSamId( 0 ) );
                                value = os.c_str();
                                return ( true );
                        }
                        */
                        value = 1;
                        return ( true );
                }
                break;
        case EXPRESSIONID_SCENARIO_INDEX:
                {
                        AnsiString os;
                        os.sprintf( "%u", evaluationContext.getScenarioIndex() );
                        value = os.c_str();
                }
                return ( true );
        case EXPRESSIONID_HOSTNAME:
                {
                        char name[ 1024 ];
                        unsigned long size = sizeof( name );
                        if ( GetComputerName( name, &size ) )
                        {
                                value = name;
                                return ( true );
                        }
                }
        case EXPRESSIONID_USERNAME:
                {
                        char name[ 1024 ];
                        unsigned long size = sizeof( name );
                        if ( GetUserName( name, &size ) )
                        {
                                value = name;
                                return ( true );
                        }
                }
        default:
                MERROR( "Function \"" << symbol << "\" is not implemented." );
                break;
        }

        return ( false );

  //## end FieldExpression::evaluateFunction%4208AE9D0216.body
}

//## Operation: evaluateVariable%420AE22101D7
const bool FieldExpression::evaluateVariable (std::istream &is, std::string &value, std::string &symbol, const bool &sideEffect, EvaluationContext& evaluationContext, std::vector< DefinedVariable * > &path, bool &postponed)
{
  //## begin FieldExpression::evaluateVariable%420AE22101D7.body preserve=yes

        return ( evaluationContext.getSymbolTable().getVariable( symbol, evaluationContext ).
                                evaluate( value, sideEffect, evaluationContext, path, postponed ) );

  //## end FieldExpression::evaluateVariable%420AE22101D7.body
}

//## Operation: getExpression%420AC68F02E4
const std::string & FieldExpression::getExpression () const
{
  //## begin FieldExpression::getExpression%420AC68F02E4.body preserve=yes

        return ( m_expression );

  //## end FieldExpression::getExpression%420AC68F02E4.body
}

//## Operation: isFunctor%4209B773036F
const bool FieldExpression::isFunctor (const std::string &string)
{
  //## begin FieldExpression::isFunctor%4209B773036F.body preserve=yes

        PredefinedFunction const * where = 0;

        for ( where = functions; where->functor; ++where )
        {
                if ( string == where->functor )
                {
                        return ( true );
                }
        }

        return ( false );

  //## end FieldExpression::isFunctor%4209B773036F.body
}

//## Operation: readIdentifier%42102FB70219
const bool FieldExpression::readIdentifier (std::istream &is, std::string &identifier)
{
  //## begin FieldExpression::readIdentifier%42102FB70219.body preserve=yes

        char character = 0;

        identifier.clear();

        is >> std::ws;
        if ( is.get( character ).good() )
        {
                if ( std::isalpha( character ) )
                {
                        do
                        {
                                identifier += character;
                        }
                        while ( is.get( character ).good() &&
                                        ( std::isalnum( character ) || ( character == '_' ) ) );
                }

                if ( is.good() )
                {
                        is.putback( character );
                }
        }

        return ( identifier.length() > 0 );

  //## end FieldExpression::readIdentifier%42102FB70219.body
}

//## Operation: readTerm%420B0EB603D2
const bool FieldExpression::readTerm (std::istream &is, std::string &term)
{
  //## begin FieldExpression::readTerm%420B0EB603D2.body preserve=yes

        char character = 0;

        term.clear();

        is >> std::ws;
        if ( is.get( character ).good() )
        {
                const bool quoted = ( character == '\"' );
                if ( std::isalnum( character ) || ( character == '-' ) || quoted )
                {
                        do
                        {
                                term += character;
                        }
                        while ( is.get( character ).good() && std::isalnum( character ) );
                }

                if ( is.good() && ( !quoted || character != '\"' ) )
                {
                        is.putback( character );
                }
        }

        return ( term.length() > 0 );

  //## end FieldExpression::readTerm%420B0EB603D2.body
}

//## Operation: setExpression%420AC68F02F3
const std::string & FieldExpression::setExpression (const std::string &value)
{
  //## begin FieldExpression::setExpression%420AC68F02F3.body preserve=yes

        return ( m_expression = value );

  //## end FieldExpression::setExpression%420AC68F02F3.body
}

//## Operation: skipCharacter%420B100701E7
const bool FieldExpression::skipCharacter (std::istream &is, const char &character)
{
  //## begin FieldExpression::skipCharacter%420B100701E7.body preserve=yes

        char c = 0;
        is >> std::ws >> c;

        if ( is.good() )
        {
                if ( c == character )
                {
                        return ( true );
                }

                is.putback( c );
        }

        return ( false );

  //## end FieldExpression::skipCharacter%420B100701E7.body
}

// Additional Declarations
  //## begin FieldExpression%420AC16002C1.declarations preserve=yes
  //## end FieldExpression%420AC16002C1.declarations

//## begin module%420AC16002C1.epilog preserve=yes
//## end module%420AC16002C1.epilog