Subversion Repositories DevTools

Rev

Rev 2224 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2218 sbetterm 1
//## begin module%1.7%.codegen_version preserve=yes
2
//   Read the documentation to learn more about C++ code generator
3
//   versioning.
4
//## end module%1.7%.codegen_version
5
 
6
//## begin module%420AC16002C1.cm preserve=no
7
//## end module%420AC16002C1.cm
8
 
9
//## begin module%420AC16002C1.cp preserve=no
10
//	C O P Y R I G H T   N O T I C E
11
//	This material is confidential to ERG and may not be disclosed in whole
12
//	or in part to any third party nor used in any manner whatsoever other
13
//	than for the purposes expressly consented to by ERG in writing.
14
//
15
//	This material is also copyright and may not be reproduced, stored in a
16
//	retrieval system or transmitted in any form or by any means in whole or
17
//	in part without the express written consent of ERG.
18
//## end module%420AC16002C1.cp
19
 
20
//## Module: FieldExpression%420AC16002C1; Pseudo Package body
21
//## Subsystem: MASS::Dev::Tools::TxnTestManager::src%41F5A79001E4
22
//## Source file: Z:\MASS_Dev\Tools\TxnTestManager\src\FieldExpression.cpp
23
 
24
//## begin module%420AC16002C1.additionalIncludes preserve=no
25
//## end module%420AC16002C1.additionalIncludes
26
 
27
//## begin module%420AC16002C1.includes preserve=yes
28
#pragma warn -com
29
#include <LoggingMacros.h>
30
#pragma warn +com
31
 
32
#include <vcl.h>
33
#pragma hdrstop
34
//## end module%420AC16002C1.includes
35
 
2222 sbetterm 36
// ICryptographicServerProxy
37
#include "ICryptographicServerProxy.h"
38
// IMessageDigest
39
#include "IMessageDigest.h"
40
// IXmlSchemaWrapperElement
41
#include "IXmlSchemaWrapperElement.h"
2218 sbetterm 42
// TransactionSpecification
43
#include "TransactionSpecification.h"
44
// EvaluationContext
45
#include "EvaluationContext.h"
46
// SequenceCollection
47
#include "SequenceCollection.h"
48
// Sequence
49
#include "Sequence.h"
50
// FieldExpression
51
#include "FieldExpression.h"
52
// DefinedVariable
53
#include "DefinedVariable.h"
54
// DefinedVariableTable
55
#include "DefinedVariableTable.h"
56
//## begin module%420AC16002C1.additionalDeclarations preserve=yes
57
#include <locale>
58
#include <sstream>
59
 
60
enum TokenId
61
{
62
	TOKENID_INVALID = 0,
63
	TOKENID_FUNCTION,
64
	TOKENID_VARIABLE,
65
	TOKENID_CONSTANT
66
};
67
enum FunctionId
68
{
69
	EXPRESSIONID_INVALID = 0,
70
	EXPRESSIONID_FORMATVERSION,
71
	EXPRESSIONID_NOW,
72
	EXPRESSIONID_UTCNOW,
73
	EXPRESSIONID_TODAY,
74
	EXPRESSIONID_YESTERDAY,
75
	EXPRESSIONID_TOMORROW,
76
	EXPRESSIONID_RAND,
77
	EXPRESSIONID_UDTYPE,
78
	EXPRESSIONID_UDSUBTYPE,
79
	EXPRESSIONID_ACCOUNTTYPE,
80
	EXPRESSIONID_SEQ,
81
	EXPRESSIONID_KEYVERSION,
82
	EXPRESSIONID_KEYNUMBER,
2222 sbetterm 83
	EXPRESSIONID_MAC,
84
	EXPRESSIONID_SAMID,
2226 sbetterm 85
	EXPRESSIONID_SCENARIO_INDEX,
86
	EXPRESSIONID_HOSTNAME,
87
	EXPRESSIONID_USERNAME
2218 sbetterm 88
};
89
struct PredefinedFunction
90
{
91
	const char *	functor;
92
	FunctionId		functionId;
93
};
94
 
95
static const PredefinedFunction functions[] =
96
{
97
	{ "FORMATVERSION",	EXPRESSIONID_FORMATVERSION },
98
	{ "NOW",			EXPRESSIONID_NOW },
99
	{ "UTCNOW",			EXPRESSIONID_UTCNOW },
100
	{ "TODAY",			EXPRESSIONID_TODAY },
101
	{ "YESTERDAY",		EXPRESSIONID_YESTERDAY },
102
	{ "TOMORROW",		EXPRESSIONID_TOMORROW },
103
	{ "RAND",			EXPRESSIONID_RAND },
104
	{ "UDTYPE",			EXPRESSIONID_UDTYPE },
105
	{ "UDSUBTYPE",		EXPRESSIONID_UDSUBTYPE },
106
	{ "ACCOUNTTYPE",	EXPRESSIONID_ACCOUNTTYPE },
107
	{ "SEQ",			EXPRESSIONID_SEQ },
108
	{ "KEYVERSION",		EXPRESSIONID_KEYVERSION },
109
	{ "KEYNUMBER",		EXPRESSIONID_KEYNUMBER },
110
	{ "MAC",			EXPRESSIONID_MAC },
2222 sbetterm 111
	{ "SAMID",			EXPRESSIONID_SAMID },
112
	{ "SCENARIOINDEX",	EXPRESSIONID_SCENARIO_INDEX },
2226 sbetterm 113
	{ "HOSTNAME",		EXPRESSIONID_HOSTNAME },
114
	{ "USERNAME",		EXPRESSIONID_USERNAME },
2218 sbetterm 115
	{ 0,				EXPRESSIONID_INVALID }
116
};
117
 
118
static const std::locale myLocale;
119
 
120
const FunctionId & getFunctionId( const std::string & string )
121
{
122
	PredefinedFunction const * where = 0;
123
 
124
	for ( where = functions; where->functor; ++where )
125
	{
126
		if ( string == where->functor )
127
		{
128
			break;
129
		}
130
	}
131
 
132
	return ( where->functionId );
133
}
134
 
2224 sbetterm 135
const bool readExpression( std::istream & stream, std::string & symbol, TokenId & token, EvaluationContext& evaluationContext )
2218 sbetterm 136
{
137
	symbol.erase();
138
 
139
	char character = 0;
140
	while ( stream.get( character ).good() )
141
	{
142
		if ( std::isalnum( character ) || character == '_' )
143
		{
144
			symbol += character;
145
		}
146
		else
147
		{
148
			stream.putback( character );	// Always put this back.
149
 
150
			if ( character == '(' )
151
			{
152
				token = TOKENID_FUNCTION;
153
				return ( true );
154
			}
155
 
156
			break;	// We have read in a lexeme, now tokenise it.
157
		}
158
	}
159
 
160
	// Only do this when we didn't fail reading from the stream.
161
	if ( stream.good() || stream.eof() )
162
	{
2224 sbetterm 163
		token = ( evaluationContext.getSymbolTable().isVariable( symbol, evaluationContext )
2218 sbetterm 164
			? TOKENID_VARIABLE
165
			: TOKENID_CONSTANT );
166
		return ( true );
167
	}
168
 
169
	return ( false );
170
}
171
//## end module%420AC16002C1.additionalDeclarations
172
 
173
 
174
// Class FieldExpression 
175
 
176
FieldExpression::FieldExpression()
177
  //## begin FieldExpression::FieldExpression%420AC16002C1_const.initialization preserve=yes
178
  //## end FieldExpression::FieldExpression%420AC16002C1_const.initialization
179
{
180
  //## begin FieldExpression::FieldExpression%420AC16002C1_const.body preserve=yes
181
  //## end FieldExpression::FieldExpression%420AC16002C1_const.body
182
}
183
 
184
//## Operation: FieldExpression%42105AAC0084
185
FieldExpression::FieldExpression (const std::string &expression)
186
  //## begin FieldExpression::FieldExpression%42105AAC0084.hasinit preserve=no
187
  //## end FieldExpression::FieldExpression%42105AAC0084.hasinit
188
  //## begin FieldExpression::FieldExpression%42105AAC0084.initialization preserve=yes
189
 
190
:	m_expression( expression )
191
 
192
  //## end FieldExpression::FieldExpression%42105AAC0084.initialization
193
{
194
  //## begin FieldExpression::FieldExpression%42105AAC0084.body preserve=yes
195
  //## end FieldExpression::FieldExpression%42105AAC0084.body
196
}
197
 
198
 
199
FieldExpression::~FieldExpression()
200
{
201
  //## begin FieldExpression::~FieldExpression%420AC16002C1_dest.body preserve=yes
202
  //## end FieldExpression::~FieldExpression%420AC16002C1_dest.body
203
}
204
 
205
 
206
 
207
//## Other Operations (implementation)
208
//## Operation: evaluate%420456630303
209
const bool FieldExpression::evaluate (std::string &value, const bool &sideEffect, EvaluationContext& evaluationContext, std::vector< DefinedVariable * > &path, bool &postponed)
210
{
211
  //## begin FieldExpression::evaluate%420456630303.body preserve=yes
212
 
213
	if ( m_cachedValue.length() )
214
	{
215
		value = m_cachedValue;
216
		return ( true );
217
	}
218
 
219
	/**
220
	 *	TODO: Eventually replace the use of streams with a char buffer, but
221
	 *	right now I just need to get it working.
222
	 */
223
	if ( ( m_expression[ 0 ] == '\"' ) &&
224
		 ( m_expression[ m_expression.length() - 1 ] == '\"' ) )
225
	{
226
		value = m_cachedValue = m_expression.substr( 1, m_expression.length() - 2 );
227
		return ( true );
228
	}
229
 
230
	std::istringstream is( m_expression );
231
	skipCharacter( is, '=' );	// Skip the '=' if its there.
232
 
233
	/**
234
	 *	TODO: evaluate this field using the defined collection of variables
235
	 *	and sequence generators, making sure we respect the sideEffect flag.
236
	 */
237
	/**
238
		For now, we assume a very simple syntax:
239
 
240
			expression		::= function | variable | constant
241
			function		::= =functor ( [ argument list ] )
242
			variable		::= =variable
243
			constant		::= alphanumeric
244
			argument list	::= argument[, argument list ]
245
			argument		::= expression
246
	 */
247
	std::string	symbol;
248
	TokenId		token = TOKENID_INVALID;
2224 sbetterm 249
	while ( readExpression( is, symbol, token, evaluationContext ) )
2218 sbetterm 250
	{
251
		switch ( token )
252
		{
253
		case TOKENID_FUNCTION:
254
			return ( evaluateFunction( is, value, symbol, sideEffect, evaluationContext, path, postponed ) );
255
		case TOKENID_VARIABLE:
256
			return ( evaluateVariable( is, value, symbol, sideEffect, evaluationContext, path, postponed ) );
257
		case TOKENID_CONSTANT:
258
			// Its not a defined variable or function, so just evaluate to
259
			// it.
260
			m_cachedValue = value = m_expression;
261
			return ( true );
262
		}
263
	}
264
 
265
	return ( true );
266
 
267
  //## end FieldExpression::evaluate%420456630303.body
268
}
269
 
270
//## Operation: evaluateFunction%4208AE9D0216
271
const bool FieldExpression::evaluateFunction (std::istream &is, std::string &value, std::string &symbol, const bool &sideEffect, EvaluationContext& evaluationContext, std::vector< DefinedVariable * > &path, bool &postponed)
272
{
273
  //## begin FieldExpression::evaluateFunction%4208AE9D0216.body preserve=yes
274
 
275
	/**
276
	 *	Check parameter lists on all functions calls, and report an error
277
	 *	when a function is called with superfluous arguments.
278
	 */
279
 
280
	postponed = false;
281
	switch ( getFunctionId( symbol ) )
282
	{
283
	case EXPRESSIONID_UDTYPE:
284
		{
285
			AnsiString os;
286
			os.sprintf( "%hu", evaluationContext.getTransaction().getUdType() );
287
			m_cachedValue = value = os.c_str();
288
		}
289
		return ( true );
290
	case EXPRESSIONID_UDSUBTYPE:
291
		{
292
			AnsiString os;
293
			os.sprintf( "%hu", evaluationContext.getTransaction().getUdSubtype() );
294
			m_cachedValue = value = os.c_str();
295
		}
296
		return ( true );
297
	case EXPRESSIONID_TODAY:
298
		m_cachedValue = value = TDateTime::CurrentDateTime().FormatString( "dd-mm-yyyy" ).c_str();
299
		return ( true );
300
	case EXPRESSIONID_FORMATVERSION:
301
		{
302
			AnsiString os;
303
			os.sprintf( "%d", evaluationContext.getTransaction().getFormatVersion() );
304
			m_cachedValue = value = os.c_str();
305
		}
306
		return ( true );
307
	case EXPRESSIONID_NOW:
308
		m_cachedValue = value = TDateTime::CurrentDateTime().FormatString( "dd-mm-yyyy hh:nn:ss" ).c_str();
309
		return ( true );
310
	case EXPRESSIONID_UTCNOW:
311
		{
312
			const TDateTime time = TDateTime::CurrentDateTime() + ( ( _timezone / 3600.0 ) / 24.0 );
313
 
314
			m_cachedValue = value = time.FormatString( "dd-mm-yyyy hh:nn:ss" ).c_str();
315
		}
316
		return ( true );
317
	case EXPRESSIONID_YESTERDAY:
318
		{
319
			const TDateTime time = TDateTime::CurrentDateTime() - 1;
320
 
321
			m_cachedValue = value = time.FormatString( "dd-mm-yyyy" ).c_str();
322
		}
323
		return ( true );
324
	case EXPRESSIONID_TOMORROW:
325
		{
326
			const TDateTime time = TDateTime::CurrentDateTime() + 1;
327
 
328
			m_cachedValue = value = time.FormatString( "dd-mm-yyyy" ).c_str();
329
		}
330
		return ( true );
331
	case EXPRESSIONID_ACCOUNTTYPE:
332
		switch( evaluationContext.getTransaction().getUdType() )
333
		{
334
		case 1:	// Card
335
			value = "2";
336
			break;
337
		case 2:	// Application
338
			value = "1";
339
			break;
340
		case 3:	// Product
341
			value = "3";
342
			break;
343
		case 4:	// Other
344
			value = "4";
345
			break;
346
		case 5:	// Audit
347
			value = "4";
348
			break;
349
		case 6:	// Event
350
			value = "4";
351
			break;
352
		case 7:	// Project
353
			value = "4";
354
			break;
355
		default:
356
			value.erase();
357
			break;
358
		}
359
		m_cachedValue = value;
360
		return ( true );
361
	case EXPRESSIONID_RAND:
362
		{
363
			std::string lowerBound;
364
			std::string upperBound;
365
			if ( skipCharacter( is, '(' ) &&
366
				 readTerm( is, lowerBound ) &&
367
				 skipCharacter( is, ',' ) &&
368
				 readTerm( is, upperBound ) &&
369
				 skipCharacter( is, ')' ) )
370
			{
371
				const int first	= std::min< int >(
372
									atoi( lowerBound.c_str() ),
373
									atoi( upperBound.c_str() ) );
374
				const int last	= std::max< int >(
375
									atoi( lowerBound.c_str() ),
376
									atoi( upperBound.c_str() ) );
377
 
378
				AnsiString os;
379
				os.sprintf( "%d",
380
					int( ( rand() / double( RAND_MAX ) ) *
381
						 ( last - first + 1 ) + first ) );
382
				value = os.c_str();
383
				return ( true );
384
			}
385
			else
386
			{
387
				MERROR( "Cannot parse argument list." );
388
			}
389
		}
390
		break;
391
	case EXPRESSIONID_SEQ:
392
		{
393
			bool persisted = false;
394
			std::string name;
395
			std::string first;
396
			std::string increment;
397
			std::string last;
398
			std::string discriminant;
399
			std::string	fullName;
400
 
401
			/**
402
			 *	SEQ( name, first, increment, last[, discriminant] )
403
			 *	name ::= transient name | # persisted name
404
			 */
405
			if ( skipCharacter( is, '(' ) )
406
			{
407
				persisted = skipCharacter( is, '#' );
408
 
409
				if ( readIdentifier( is, name ) &&
410
					 skipCharacter( is, ',' ) &&
411
					 readTerm( is, first ) &&
412
					 skipCharacter( is, ',' ) &&
413
					 readTerm( is, last ) &&
414
					 skipCharacter( is, ',' ) &&
415
					 readTerm( is, increment ) &&
416
					 ( ( skipCharacter( is, ',' ) &&
417
						 readIdentifier( is, discriminant ) ) ||
418
					   skipCharacter( is, ')' ) ) )
419
				{
420
					if ( discriminant.length() )
421
					{
422
						/**
423
						 *	We have a discriminant, so we evaluate it to form
424
						 *	our name,
425
						 */
426
						FieldExpression subexpression( discriminant );
427
 
428
						std::string discriminantValue;
429
						if ( subexpression.evaluate( discriminantValue, true, evaluationContext, path, postponed ) )
430
						{
431
							AnsiString full;
432
							full.sprintf( "%s[%s]", name.c_str(), discriminantValue.c_str() );
433
							fullName = full.c_str();
434
						}
435
					}
436
					else
437
					{
438
						fullName = name;
439
					}
440
 
441
					Sequence & sequence = evaluationContext.
442
						getSequenceCollection().getSequence(
443
							fullName,
444
							persisted,
445
							atoi( first.c_str() ) );
446
					AnsiString os;
447
					os.sprintf( "%d", sequence.getValue() );
448
					value = os.c_str();
449
 
450
					sequence.incrementValue(
451
						atoi( first.c_str() ),
452
						atoi( last.c_str() ),
453
						atoi( increment.c_str() ) );
454
 
455
					return ( true );
456
				}
457
			}
458
 
459
			MERROR( "Cannot parse argument list." );
460
		}
461
		break;
462
	case EXPRESSIONID_KEYVERSION:
463
		if ( evaluationContext.haveMessageDigest() )
464
		{
465
			AnsiString os;
466
			os.sprintf( "%hu", evaluationContext.getMessageDigest().getKeyVersion() );
467
			value = os.c_str();
468
 
469
			return ( true );
470
		}
471
		break;
472
	case EXPRESSIONID_KEYNUMBER:
473
		if ( evaluationContext.haveMessageDigest() )
474
		{
475
			AnsiString os;
476
			os.sprintf( "%hu", evaluationContext.getMessageDigest().getKeyNumber() );
477
			value = os.c_str();
478
 
479
			return ( true );
480
		}
481
		break;
482
	case EXPRESSIONID_MAC:
483
		/**
484
		 *	We add the schema element to the collection of schema elements to
485
		 *	which we must assign the MAC.  Because we can compute the MAC only
486
		 *	when all fields have been evaluated, this must be postponed, and
487
		 *	until then we must report success.
488
		 */
489
		if ( evaluationContext.haveSchemaElement() )
490
		{
491
			evaluationContext.getTransaction().addMacField(
492
				evaluationContext.getSchemaElement().clone() );
493
			postponed = true;
494
 
495
			return ( true );
496
		}
497
		break;
2222 sbetterm 498
	case EXPRESSIONID_SAMID:
499
		if ( evaluationContext.haveCryptographicServer() )
500
		{
501
			/**
502
			 *	We don't know which module will be used to compute the
503
			 *	MAC (security doesn't tell us), so until they do we
504
			 *	assume its the first module.
505
			 */
506
			if ( evaluationContext.getCryptographicServer().getModuleCount() )
507
			{
508
				AnsiString os;
509
				os.sprintf( "%hu", evaluationContext.getCryptographicServer().getSamId( 0 ) );
510
				value = os.c_str();
511
				return ( true );
512
			}
513
		}
514
		break;
515
	case EXPRESSIONID_SCENARIO_INDEX:
516
		{
517
			AnsiString os;
518
			os.sprintf( "%u", evaluationContext.getScenarioIndex() );
519
			value = os.c_str();
520
		}
521
		return ( true );
2226 sbetterm 522
	case EXPRESSIONID_HOSTNAME:
523
		{
524
			char name[ 1024 ];
525
			unsigned long size = sizeof( name );
526
			if ( GetComputerName( name, &size ) )
527
			{
528
				value = name;
529
				return ( true );
530
			}
531
		}
532
	case EXPRESSIONID_USERNAME:
533
		{
534
			char name[ 1024 ];
535
			unsigned long size = sizeof( name );
536
			if ( GetUserName( name, &size ) )
537
			{
538
				value = name;
539
				return ( true );
540
			}
541
		}
2218 sbetterm 542
	default:
2222 sbetterm 543
		MERROR( "Function \"" << symbol << "\" is not implemented." );
2218 sbetterm 544
		break;
545
	}
546
 
547
	return ( false );
548
 
549
  //## end FieldExpression::evaluateFunction%4208AE9D0216.body
550
}
551
 
552
//## Operation: evaluateVariable%420AE22101D7
553
const bool FieldExpression::evaluateVariable (std::istream &is, std::string &value, std::string &symbol, const bool &sideEffect, EvaluationContext& evaluationContext, std::vector< DefinedVariable * > &path, bool &postponed)
554
{
555
  //## begin FieldExpression::evaluateVariable%420AE22101D7.body preserve=yes
556
 
2224 sbetterm 557
	return ( evaluationContext.getSymbolTable().getVariable( symbol, evaluationContext ).
2218 sbetterm 558
				evaluate( value, sideEffect, evaluationContext, path, postponed ) );
559
 
560
  //## end FieldExpression::evaluateVariable%420AE22101D7.body
561
}
562
 
563
//## Operation: getExpression%420AC68F02E4
564
const std::string & FieldExpression::getExpression () const
565
{
566
  //## begin FieldExpression::getExpression%420AC68F02E4.body preserve=yes
567
 
568
	return ( m_expression );
569
 
570
  //## end FieldExpression::getExpression%420AC68F02E4.body
571
}
572
 
573
//## Operation: isFunctor%4209B773036F
574
const bool FieldExpression::isFunctor (const std::string &string)
575
{
576
  //## begin FieldExpression::isFunctor%4209B773036F.body preserve=yes
577
 
578
	PredefinedFunction const * where = 0;
579
 
580
	for ( where = functions; where->functor; ++where )
581
	{
582
		if ( string == where->functor )
583
		{
584
			return ( true );
585
		}
586
	}
587
 
588
	return ( false );
589
 
590
  //## end FieldExpression::isFunctor%4209B773036F.body
591
}
592
 
593
//## Operation: readIdentifier%42102FB70219
594
const bool FieldExpression::readIdentifier (std::istream &is, std::string &identifier)
595
{
596
  //## begin FieldExpression::readIdentifier%42102FB70219.body preserve=yes
597
 
598
	char character = 0;
599
 
600
	identifier.clear();
601
 
602
	is >> std::ws;
603
	if ( is.get( character ).good() )
604
	{
605
		if ( std::isalpha( character ) )
606
		{
607
			do
608
			{
609
				identifier += character;
610
			}
611
			while ( is.get( character ).good() &&
612
					( std::isalnum( character ) || ( character == '_' ) ) );
613
		}
614
 
615
		if ( is.good() )
616
		{
617
			is.putback( character );
618
		}
619
	}
620
 
621
	return ( identifier.length() > 0 );
622
 
623
  //## end FieldExpression::readIdentifier%42102FB70219.body
624
}
625
 
626
//## Operation: readTerm%420B0EB603D2
627
const bool FieldExpression::readTerm (std::istream &is, std::string &term)
628
{
629
  //## begin FieldExpression::readTerm%420B0EB603D2.body preserve=yes
630
 
631
	char character = 0;
632
 
633
	term.clear();
634
 
635
	is >> std::ws;
636
	if ( is.get( character ).good() )
637
	{
638
		const bool quoted = ( character == '\"' );
639
		if ( std::isalnum( character ) || ( character == '-' ) || quoted )
640
		{
641
			do
642
			{
643
				term += character;
644
			}
645
			while ( is.get( character ).good() && std::isalnum( character ) );
646
		}
647
 
648
		if ( is.good() && ( !quoted || character != '\"' ) )
649
		{
650
			is.putback( character );
651
		}
652
	}
653
 
654
	return ( term.length() > 0 );
655
 
656
  //## end FieldExpression::readTerm%420B0EB603D2.body
657
}
658
 
659
//## Operation: setExpression%420AC68F02F3
660
const std::string & FieldExpression::setExpression (const std::string &value)
661
{
662
  //## begin FieldExpression::setExpression%420AC68F02F3.body preserve=yes
663
 
664
	return ( m_expression = value );
665
 
666
  //## end FieldExpression::setExpression%420AC68F02F3.body
667
}
668
 
669
//## Operation: skipCharacter%420B100701E7
670
const bool FieldExpression::skipCharacter (std::istream &is, const char &character)
671
{
672
  //## begin FieldExpression::skipCharacter%420B100701E7.body preserve=yes
673
 
674
	char c = 0;
675
	is >> std::ws >> c;
676
 
677
	if ( is.good() )
678
	{
679
		if ( c == character )
680
		{
681
			return ( true );
682
		}
683
 
684
		is.putback( c );
685
	}
686
 
687
	return ( false );
688
 
689
  //## end FieldExpression::skipCharacter%420B100701E7.body
690
}
691
 
692
// Additional Declarations
693
  //## begin FieldExpression%420AC16002C1.declarations preserve=yes
694
  //## end FieldExpression%420AC16002C1.declarations
695
 
696
//## begin module%420AC16002C1.epilog preserve=yes
697
//## end module%420AC16002C1.epilog