os/textandloc/textrendering/texthandling/spml/T_PMLPAR.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 *
    16 */
    17 
    18 
    19 #include "../incp/T_PMLPAR.H"
    20 
    21 #define UNUSED_VAR(a) a = a
    22 
    23 #define UNUSED_VAR(a) a = a
    24 
    25 ////////////////////////////////////////////
    26 // CParser
    27 ////////////////////////////////////////////
    28 
    29 CParser* CParser::NewL()
    30 	{
    31 	CParser* self=new(ELeave) CParser;
    32 	CleanupStack::PushL(self);
    33 	self->ConstructApplicationL();
    34 	CleanupStack::Pop();
    35 	return self;
    36 	}
    37 
    38 
    39 CParser::CParser()
    40 	{
    41 	// init variables
    42 	iErrorLevel = ENoError;			
    43 	iParagraphIsOpen = EFalse;	
    44 	iLineNo = 1;
    45 	iReadPos = 0;
    46 	iDocInsertPos = 0;
    47 	iDocParaLength = 0;
    48 	iDocPhraseLength = 0;
    49 	iBorderUsed = EFalse;
    50 	iBulletUsed = EFalse;
    51 	}
    52 	 
    53 
    54 void CParser::ConstructApplicationL()
    55 	{ 
    56 	// Construct Rich Text Doc
    57 	// Make the global format layers and associated formats and masks
    58 	iGlobalParaFormatLayer=CParaFormatLayer::NewL();
    59 	iGlobalCharFormatLayer=CCharFormatLayer::NewL();
    60 	iGlobalParaFormat=CParaFormat::NewL();	   	// initialised with factory settings
    61 	iGlobalParaFormatMask.SetAll();
    62 	iGlobalCharFormatMask.SetAll();
    63 	
    64 	// Set the global layers
    65 	iGlobalParaFormatLayer->SetL(iGlobalParaFormat,iGlobalParaFormatMask);
    66 	iGlobalCharFormatLayer->SetL(iGlobalCharFormat, iGlobalCharFormatMask);
    67 
    68 	// Create the rich text document
    69 	iRichTextDoc=CRichText::NewL(iGlobalParaFormatLayer,iGlobalCharFormatLayer);
    70 
    71 	// Initialise the paragraph and character layers
    72 	iParaFormatLayer = CParaFormatLayer::NewL();
    73 	iCharFormatLayer = CCharFormatLayer::NewL();
    74 	iParaFormat = CParaFormat::NewL();
    75 
    76 	// Create temp alias' for compound attributes
    77 	iBorder = new TParaBorder;
    78 	User::LeaveIfNull(iBorder);
    79 	iBullet = new (ELeave) TBullet;
    80 	}
    81 
    82 
    83 CParser::~CParser()
    84 	{
    85 	// destroy Rich Text Document
    86 // 	delete iRichTextDoc;
    87 //	delete iGlobalParaFormatLayer;
    88 //	delete iGlobalCharFormatLayer;
    89 	delete iGlobalParaFormat;
    90 	delete iParaFormatLayer;
    91 	delete iCharFormatLayer;
    92 	delete iParaFormat;
    93 	if (!iBorderUsed)
    94 		delete(iBorder);
    95 	if (!iBulletUsed)
    96 		delete(iBullet);
    97 	}
    98 
    99 
   100 CRichText* CParser::ParseL(CConsoleBase* aConsole)
   101 // version for parsing with console output and interactive file dialog
   102 // primarily for debugging purposes (you can see what's going on!)
   103 	{
   104 	// set console
   105 	iConsoleExists = ETrue;
   106 	iConsole = aConsole;
   107 
   108 	// Construct a CFileApp & load a file
   109 	CFileApp* myFileApp=NULL;
   110 	TRAPD(ret, myFileApp = CFileApp::NewL());
   111     UNUSED_VAR(ret);
   112 	iTextBuf = myFileApp->LoadFileL(iConsole);
   113 	iFileName = myFileApp->ReturnFileName();
   114 
   115 	ParseTextBufL();	   			// parse the buffer
   116 	delete myFileApp;	// destroy file app
   117 
   118 	// Pause before returning
   119 	WriteNewLine();
   120 	WriteNewLine();
   121 	OutputToScreen(_L("Press Space to continue\n"));
   122 	TKeyCode keystroke = EKeyNull;
   123 	while (keystroke != EKeySpace)
   124 		keystroke = iConsole->Getch();
   125 	return iRichTextDoc;
   126 	}
   127 
   128 CRichText* CParser::ParseL(const TFileName &aFileName)
   129 // silent version of the parser
   130 	{
   131 	iConsoleExists = EFalse;
   132 	// Construct a CFileApp & load a file
   133 	CFileApp* myFileApp=NULL;
   134 	TRAPD(ret, myFileApp = CFileApp::NewL());
   135     UNUSED_VAR(ret);
   136 	iTextBuf = myFileApp->LoadFileL(aFileName);
   137 	iFileName = myFileApp->ReturnFileName();
   138 
   139 	ParseTextBufL();	   			// parse the buffer
   140 	delete myFileApp;	// destroy file app
   141 
   142 	return iRichTextDoc;
   143 	}
   144 
   145 
   146 void CParser::EmitErrorMessage()
   147 	{
   148 	TBuf<80> errorMessage;
   149 	switch (iErrorLevel)
   150 		{
   151 		case EUnknownTagType:
   152 			errorMessage.Format(_L("    Unknown tag type: Line %d"),iLineNo);
   153 			break;
   154 		case EUnparagraphedText:
   155 			errorMessage.Format(_L("    Text not contained by paragraph: Line %d"),iLineNo);
   156 			break;
   157 		case EUnknownAttrib:
   158 			errorMessage.Format(_L("    Unknown tag attribute: Line %d"),iLineNo);
   159 			break;
   160 		case ENoAttribValue:
   161 			errorMessage.Format(_L("    Unknown attribute or no attribute value supplied: Line %d"),iLineNo);
   162 			break;
   163 		case EIllegalAttribValue:
   164 			errorMessage.Format(_L("    Illegal attribute value: Line %d"),iLineNo);
   165 			break;
   166 		default:
   167 			errorMessage.Format(_L("    Error: Line %d"),iLineNo);
   168 			break;
   169 		}
   170 	OutputToScreen(_L(""));
   171 	OutputToScreen(_L("*** Error!!\n"));
   172 	OutputToScreen(errorMessage);
   173 	}
   174 
   175 
   176 void CParser::OutputToScreen(const TDesC& aMessageBuffer)
   177 	{
   178 	if (iConsoleExists)
   179 		iConsole->Write(aMessageBuffer);  // output line to screen
   180 	}
   181 
   182 
   183 TBool CParser::Validate()
   184 // Check that document starts with <G> tag - serves as file validation
   185 //  - Read in characters sequentially
   186 //  - if the first alphanumeric characters encountered are not "<G" then error
   187 	{
   188 	TBool fileFormatError = EFalse;
   189 	TBool fileValidated = EFalse;
   190 	TChar charToTest;
   191 	while ((!fileFormatError)&&(!fileValidated))
   192 		{					
   193 		charToTest = ReadChar();
   194 		if (charToTest == '<')
   195 			{
   196 			iReadPos+=KCharLength;
   197 			charToTest = ReadTagChar();
   198 			if (charToTest != 'G')			 // Not a style tag - error
   199 				fileFormatError = ETrue;
   200 			else
   201 				fileValidated = ETrue;
   202 			}
   203 		else
   204 			{
   205 			if (charToTest.IsAlphaDigit())	 // Char is alphanumeric - error
   206 				fileFormatError = ETrue;	 // (File must start with style tag)
   207 			else
   208 				iReadPos+=KCharLength;
   209 			}
   210 		}
   211 	if (fileFormatError)
   212 		{
   213 		OutputToScreen(_L("File format error\n"));
   214 		}
   215 	iReadPos = 0;		// reset after validation
   216 	iLineNo = 1;		// ...
   217 	return fileValidated;
   218 	}
   219 
   220 
   221 void CParser::ParseTextBufL()
   222 // Parses contents of iTextBuf
   223 // Reads in chars sequentially.
   224 // - If a char is a tag open ("<") process the following tag
   225 // - otherwise add the char to the text of the rich text document
   226 // Tidy up at the end of the document 
   227 	{ 
   228 	TChar charToTest;
   229 	TUint textBufSize = iTextBuf->Size();
   230 	if (Validate())
   231 		{
   232 		while ((iReadPos < textBufSize)&&(iErrorLevel == ENoError))
   233 			{
   234 			charToTest = ReadChar();
   235 			if (charToTest == '<')
   236 				ProcessTagL();
   237 			else
   238 				ProcessTextL(charToTest);
   239 			iReadPos+=KCharLength;						
   240 			}
   241 		if ((iReadPos == textBufSize)&&(iReadPos>0)&&(iErrorLevel == ENoError))
   242 			{
   243 			// at end of document apply any outstanding formatting (if there is text to apply it to)
   244 			if (iDocParaLength > 0)
   245 				{
   246 				iParaFormatLayer->SetL(iParaFormat, iParaFormatMask);
   247 				iRichTextDoc->ApplyParaFormatL( iParaFormat,iParaFormatMask,iDocInsertPos-iDocParaLength,iDocParaLength);
   248 				}
   249 			if (iDocPhraseLength > 0)
   250 				{
   251 				iCharFormatLayer->SetL(iCharFormat, iCharFormatMask);
   252 				iRichTextDoc->ApplyCharFormatL(iCharFormat,iCharFormatMask,iDocInsertPos-iDocPhraseLength,iDocPhraseLength);
   253 				}
   254 			}
   255 		if (iErrorLevel != ENoError)
   256 			EmitErrorMessage();
   257 		}
   258 	}
   259 
   260 
   261 TChar CParser::ReadChar()
   262 // Reads the next character from the text buffer
   263 	{
   264 // 	TChar charToTest;
   265 	TText charToTest;
   266 	iTextBuf->Read(iReadPos,&charToTest,KCharLength);
   267 	if (charToTest == (TText)KLineFeed)
   268 		iLineNo++;				   	// Info used only by error messages
   269 	return charToTest;
   270 	}
   271 
   272 
   273 void CParser::ProcessTextL(TChar aChar)
   274 // 1) Check text is in a paragraph
   275 // 2) Check for escape characters
   276 // 3) Check for tabs
   277 // 4) Add to paragraph
   278 	{
   279 	if (!iParagraphIsOpen)
   280 		{
   281 		if (!(aChar.IsControl()))
   282 			iErrorLevel = EUnparagraphedText;	// Text not contained by a paragraph - error!!
   283 		}
   284 	else
   285 		{
   286 		if (aChar == '/')	// Escape character for <
   287 			{
   288 			TChar tempChar;
   289 			iTextBuf->Read(iReadPos+KCharLength,&tempChar,1);	// doesn't increment line counter
   290 			if (tempChar == '<')
   291 				{
   292 				AddCharToParaL(tempChar);
   293 				iReadPos+=2*KCharLength;				  	// Skip escape character
   294 				}
   295 			else
   296 				AddCharToParaL(aChar);
   297 			}
   298 		else if (aChar == KTabChar)
   299 			AddCharToParaL(aChar);
   300 		else if (!(aChar.IsControl()))		// if it's not a control char add it 
   301 			AddCharToParaL(aChar);			//		(this includes spaces)
   302 		}
   303 	}
   304 
   305 
   306 void CParser::AddCharToParaL(TChar aChar)
   307 	{ 
   308 	// Add char to RichText doc...
   309 	iRichTextDoc->InsertL(iDocInsertPos, aChar);
   310 	iDocInsertPos++;
   311 	iDocParaLength++;
   312 	if (iPhraseOpen)
   313 		iDocPhraseLength++;
   314 	// and also write it to screen
   315 	TBuf<4> screenBuf;				// Buffer for text to be written to console
   316 	screenBuf.Append(aChar);		
   317 	OutputToScreen(screenBuf);
   318 	}
   319 
   320 
   321 void CParser::ProcessTagL()
   322 	{
   323 	TChar tagChar;
   324 	iReadPos+=KCharLength;
   325 	tagChar = ReadTagChar();	  	// Read in tag type
   326 	ClassifyTagL(tagChar);		  	
   327 	if (iTagType == EError)
   328 		iErrorLevel = EUnknownTagType;
   329 	else
   330 		{
   331 		ClassifyArgumentsL();
   332 		}
   333 	}
   334 
   335 
   336 TChar CParser::ReadTagChar()
   337 	{ // Returns tag character capitalised - therefore case-insensitive
   338  	TChar charToTest;
   339 	charToTest = ReadChar();
   340 	charToTest.UpperCase();
   341 	return charToTest;
   342 	}
   343 
   344 
   345 void CParser::ClassifyArgumentsL()
   346 // reads tag one argument at a time, dealing with each arg as it is read
   347 // If and argument is followed by a value (ie a=4) it is processed in two passes.
   348 	{
   349 	TChar tagChar(0);
   350 	iArgStored = EFalse;
   351 	iArgValueExpected = EFalse;		// Initialise
   352 	iCancelArg = EFalse;
   353 	while ((tagChar != '>')&&(iErrorLevel == ENoError))	// ">" is end of tag
   354 		{
   355 		iReadPos+=KCharLength;
   356 		tagChar = ReadTagChar();	// Read in next bit of tag
   357 		if (iTagType != EComment)	// text of comments is ignored
   358 			{
   359 			if (tagChar.IsSpace())	// spaces separate args
   360 				ProcessArgBufL();
   361 			if (tagChar == '=')
   362 				{
   363 				iArgValueExpected = ETrue;
   364 				ProcessArgBufL();
   365 				}
   366 			if (tagChar == '!')
   367 				{
   368 				iCancelArg = ETrue;
   369 				OutputToScreen(_L("!"));
   370 				}
   371 			if (tagChar == ',')
   372 				AppendToArgBuf(tagChar);
   373 			if (tagChar.IsAlphaDigit())
   374 				{
   375 				AppendToArgBuf(tagChar);
   376 				}
   377 			}
   378 		}
   379 	if (tagChar == '>')				// Is it end of tag?
   380 		{
   381 		if (iTagType != EComment)
   382 			{
   383 			ProcessArgBufL();
   384 			if ((iTagType == EControl)||(iTagType == EGlobal))	// Control & global style formatting is applied "on the spot"
   385 				SetFormatLayerL();								// While char & paragraph are applied retrospectively
   386 			}
   387 		}
   388 	}
   389 
   390 
   391 void CParser::AppendToArgBuf(TChar aTagChar)
   392 	{
   393 	iArgType.Append(aTagChar);	   	// assume it'll fit
   394 	}
   395 
   396 
   397 void CParser::ProcessArgBufL()
   398 	{
   399 	if (iArgValueExpected)
   400 		{
   401 		if (iArgStored)
   402 			{
   403 			TBuf<32> tempArgBuf;				// Swap the buffers	back as an arg and its value have been stored
   404 			tempArgBuf = iArgType;
   405 			EmptyBuffer(iArgType);
   406 			iArgType = iArgValue;
   407 			EmptyBuffer(iArgValue);
   408 			iArgValue = tempArgBuf;
   409 			TranslateTagArgL();				// Translate the tag argument
   410 			iArgStored = EFalse;			// Reset the flags and buffers
   411 			iArgValueExpected = EFalse;
   412 			EmptyBuffer(iArgType);
   413 			EmptyBuffer(iArgValue);
   414 			}
   415 		else
   416 			{
   417 			iArgValue = iArgType;		 	// Swap the buffers ready to store the value of the arg
   418 			EmptyBuffer(iArgType);			// Empty buffer
   419 			iArgStored = ETrue;
   420 			}
   421 		}
   422 	else
   423 		{
   424 		TranslateTagArgL();			// match to list
   425 		EmptyBuffer(iArgType);
   426 		EmptyBuffer(iArgValue);
   427 		}
   428 	}
   429 
   430 
   431 void CParser::EmptyBuffer(TDes &aBuf)
   432 	{
   433 	aBuf.SetLength(0);
   434 	}
   435 
   436 	 
   437 void CParser::ClassifyTagL(TChar aTagChar)
   438 	{
   439 	switch (aTagChar)
   440 		{
   441 		case 'G':
   442 			iTagType = EGlobal;
   443 			break;
   444 		case 'P':
   445 			{
   446 			iTagType = EParagraph;
   447 			if (iParagraphIsOpen)
   448 				{
   449 				iRichTextDoc->InsertL(iDocInsertPos,CEditableText::EParagraphDelimiter);  // insert para delimiter
   450 				WriteNewLine();				// Write new line to console
   451 				iDocInsertPos++;			// Paragraph delimiters occupy 1 character space
   452 				iDocParaLength++;
   453 				if (iPhraseOpen)
   454 					iDocPhraseLength++;
   455 				SetFormatLayerL();			// apply formatting to old para before starting to fill new one
   456 				}
   457 			else
   458 				iParagraphIsOpen = ETrue;
   459 			break;
   460 			}
   461 		case 'C':
   462 			{
   463 			iTagType = ECharacter;
   464 			if (iPhraseOpen)                                                      
   465 				SetFormatLayerL();	// apply formatting to old phrase retrospectively 			    
   466 			else 
   467 				iPhraseOpen = ETrue;		
   468 			break;
   469 			}
   470 		case 'X':
   471 			iTagType = EControl;
   472 			break;
   473 		case '!':
   474 			iTagType = EComment;
   475 			break;
   476 		default:
   477 			iTagType = EError;
   478 			break;
   479 		}
   480 	}
   481 
   482 
   483 void CParser::SetFormatLayerL()
   484 // Apply format & mask that have been set in the tag to a Layer
   485 // Apply the layer to the RichText doc
   486 	{
   487 	if (iTagType == EGlobal)
   488 		{
   489 		iGlobalParaFormatLayer->SetL(iGlobalParaFormat, iGlobalParaFormatMask);
   490 		iGlobalCharFormatLayer->SetL(iGlobalCharFormat, iGlobalCharFormatMask);
   491 		iRichTextDoc->SetGlobalParaFormat(iGlobalParaFormatLayer);
   492 		iRichTextDoc->SetGlobalCharFormat(iGlobalCharFormatLayer);
   493 		WriteNewLine();
   494 		}
   495 	if (iTagType == EParagraph)
   496 		{
   497 		iParaFormatLayer->SetL(iParaFormat, iParaFormatMask);
   498 		iRichTextDoc->ApplyParaFormatL(iParaFormat,iParaFormatMask,iDocInsertPos-iDocParaLength,iDocParaLength);
   499 		iCharFormatLayer->SetL(iCharFormat, iCharFormatMask);
   500 		if (iDocPhraseLength > 0)
   501 			iRichTextDoc->ApplyCharFormatL(iCharFormat,iCharFormatMask,iDocInsertPos-iDocPhraseLength,iDocPhraseLength);
   502 		iDocParaLength = 0;			// reset ready for new paragraph
   503 		iDocPhraseLength = 0;
   504 		}
   505 	if (iTagType == ECharacter)
   506 		{
   507 		iCharFormatLayer->SetL(iCharFormat, iCharFormatMask);
   508 		if (iDocPhraseLength > 0)
   509 			iRichTextDoc->ApplyCharFormatL(iCharFormat,iCharFormatMask,iDocInsertPos-iDocPhraseLength,iDocPhraseLength);
   510 		iDocPhraseLength = 0;
   511 		}
   512 	}
   513 
   514 
   515 TInt CParser::GetArgValue()
   516 // converts numerals in iArgValue to a TInt, 
   517 // first checking that the buffer is totally numeric in content
   518  	{
   519 	TInt value = 0;
   520 	if (BufIsNumeric(iArgValue))
   521 		{
   522 		TLex tmpLex(iArgValue);
   523 		tmpLex.Val(value);
   524 		}
   525 	else iErrorLevel = EIllegalAttribValue;
   526 	return value;
   527 	}
   528 
   529 
   530 TInt CParser::GetArgValue(const TDes &aBuf)
   531 // converts numerals in aBuf to a TInt as above
   532 	{ 
   533 	TInt value = 0;
   534 	if (BufIsNumeric(aBuf))
   535 		{
   536 		TLex tmpLex(aBuf);
   537 		tmpLex.Val(value);
   538 		}
   539 	else iErrorLevel = EIllegalAttribValue;
   540 	return value;
   541 	}
   542 
   543 
   544 TBool CParser::BufIsNumeric(const TDes &aBuffer)
   545 // checks that aBuffer is totally numeric in content.
   546 // checks all characters sequentially
   547 	{
   548 	TBool isNumeric = ETrue;
   549 	TChar testChar;
   550 	TUint bufLength = aBuffer.Length();
   551 	for (TUint pos=0; ((pos<bufLength)&&(isNumeric)); pos++)
   552 		{
   553 		testChar = (aBuffer[pos]);
   554 		if (!(testChar.IsDigit()&&isNumeric))
   555 			isNumeric = EFalse;
   556 		}
   557 	return isNumeric;
   558 	}
   559 
   560 /* All the TransXxx.. functions translate arguments and their values and apply these 
   561 	to RichText Formats and Masks */
   562 
   563 
   564 void CParser::TranslateTagArgL()
   565 	{
   566 	switch (iTagType)
   567 		{
   568 		case EGlobal:
   569 			TransGlobalArgL();
   570 			break;
   571 		case EParagraph:
   572 			TransParagraphArgL(); 
   573 			break;
   574 		case ECharacter:
   575 			TransCharArg();
   576 			break;
   577 		case EControl:
   578 			TransControlArgL();
   579 			break;
   580 		case EError:
   581 			break;
   582 		}
   583 	iCancelArg = EFalse;  // reset
   584 	}
   585 
   586 
   587 void CParser::TransControlArgL()
   588 	{
   589 	if (iArgType != _L(""))
   590 		{
   591 		if (iArgType == _L("TAB"))
   592 			AddCharToParaL(KTabChar);	// TransTab();
   593 		else
   594 			iErrorLevel = EUnknownAttrib;
   595 		}
   596 	}
   597 
   598 
   599 void CParser::TransGlobalArgL()
   600 // Test for each possible arg in turn
   601 // (a switch statement cannot be used)
   602 	{
   603 	if (iArgType != _L("")) 				// Is there an argument?
   604 		{
   605 		if (iArgType == _L("KEEPTOGETHER"))	
   606 				TransParaKeepTogether();
   607 		else if (iArgType == _L("KEEPWITHNEXT"))
   608 				TransParaKeepWithNext();
   609 		else if (iArgType == _L("STARTNEWPAGE"))	
   610 				TransParaStartNewPage();
   611 		else if (iArgType == _L("WIDOWORPHAN"))	 	
   612 				TransParaWidowOrphan();
   613 
   614 		if (iArgType == _L("ITALIC"))	
   615 				TransCharPosture();
   616 		else if (iArgType == _L("BOLD"))	
   617 				TransCharStrokeWeight();
   618 		else if (iArgType == _L("UNDERLINE"))	
   619 				TransCharUnderline();
   620 		else if (iArgType == _L("STRIKETHROUGH"))
   621 				TransCharStrikethrough();
   622 
   623 		else if (!iArgValueExpected)			// No argument value supplied when one is required for the
   624 				iErrorLevel = ENoAttribValue;	// remaining options or an unknown argument supplied
   625 
   626 		else if (iArgType == _L("PARALANGUAGE")) 
   627 				OutputToScreen(_L("PARA LANGUAGE "));
   628 		else if (iArgType == _L("LEFTMARGIN")) 	 	   
   629 				TransParaArgLeftMargin();
   630 		else if (iArgType == _L("RIGHTMARGIN"))  	
   631 				TransParaArgRightMargin();
   632 		else if (iArgType == _L("INDENT"))		 
   633 				TransParaArgIndent();
   634 		else if (iArgType == _L("ALIGNMENT"))	 
   635 				TransParaArgAlignment();
   636 		else if (iArgType == _L("LINESPACING"))	 
   637 				TransParaLineSpacing();
   638 		else if (iArgType == _L("LINESPACINGCONTROL"))   
   639 				TransParaArgLineSpacingControl();
   640 		else if (iArgType == _L("SPACEBEFORE"))	 	
   641 				TransParaSpaceBefore();
   642 		else if (iArgType == _L("SPACEAFTER"))	 
   643 				TransParaSpaceAfter();
   644 		else if (iArgType == _L("BORDERMARGIN"))	
   645 				TransParaBorderMargin();
   646 		else if (iArgType == _L("TOPBORDER"))	 	
   647 				TransParaBorderL();
   648 		else if (iArgType == _L("BOTTOMBORDER"))	
   649 				TransParaBorderL();
   650 		else if (iArgType == _L("LEFT BORDER"))	 
   651 				TransParaBorderL();
   652 		else if (iArgType == _L("RIGHTBORDER"))	 
   653 				TransParaBorderL();
   654 		else if (iArgType == _L("BULLET"))		 
   655 				TransParaBullet();
   656 		else if (iArgType == _L("DEFAULTTABWIDTH"))
   657 				TransParaTabWidth();
   658 		else if (iArgType == _L("TABSTOP"))
   659 				TransParaTabStopL();
   660 
   661 		else if (iArgType == _L("FONTHEIGHT"))	
   662 				TransCharFontHeight();
   663 		else if (iArgType == _L("PRINTPOS"))	
   664 				TransCharPrintPos();
   665 		else if (iArgType == _L("TYPEFACENAME"))
   666 				TransCharTypefaceName();
   667 		else if (iArgType == _L("TYPEFACEFLAGS"))	
   668 				TransCharTypefaceFlags();
   669 		else if (iArgType == _L("COLOR"))	 	 
   670 				TransCharColor();
   671 		else if (iArgType == _L("LANGUAGE"))	
   672 				TransCharLanguage();
   673 		else 
   674 				iErrorLevel = EUnknownAttrib;
   675 		}
   676 	}
   677 
   678 
   679 void CParser::TransParagraphArgL()
   680 // Test for each possible arg in turn
   681 // (a switch statement cannot be used)
   682 	{
   683 	if (iArgType != _L("")) 				// Is there an argument?
   684 		{
   685 		if (iArgType == _L("DEFAULT"))		
   686 				TransParaDefault();
   687 		else if (iArgType == _L("KEEPTOGETHER"))
   688 				TransParaKeepTogether();
   689 		else if (iArgType == _L("KEEPWITHNEXT"))
   690 				TransParaKeepWithNext();
   691 		else if (iArgType == _L("STARTNEWPAGE"))
   692 				TransParaStartNewPage();
   693 		else if (iArgType == _L("WIDOWORPHAN"))	 
   694 				TransParaWidowOrphan();
   695 		else if (!iArgValueExpected)			// No argument value supplied when one is required for the
   696 				iErrorLevel = ENoAttribValue;	// remaining options or an unknown argument supplied
   697 		else if (iArgType == _L("PARALANGUAGE")) 
   698 				OutputToScreen(_L("PARA LANGUAGE "));
   699 		else if (iArgType == _L("LEFTMARGIN")) 				   
   700 				TransParaArgLeftMargin();
   701 		else if (iArgType == _L("RIGHTMARGIN"))  
   702 				TransParaArgRightMargin();
   703 		else if (iArgType == _L("INDENT"))		 
   704 				TransParaArgIndent();
   705 		else if (iArgType == _L("ALIGNMENT"))	 
   706 				TransParaArgAlignment();
   707 		else if (iArgType == _L("LINESPACING"))	 
   708 				TransParaLineSpacing();
   709 		else if (iArgType == _L("LINESPACINGCONTROL"))  
   710 				TransParaArgLineSpacingControl();
   711 		else if (iArgType == _L("SPACEBEFORE"))	 
   712 				TransParaSpaceBefore();
   713 		else if (iArgType == _L("SPACEAFTER"))	 
   714 				TransParaSpaceAfter();
   715 		else if (iArgType == _L("BORDERMARGIN"))	
   716 				TransParaBorderMargin();
   717 		else if (iArgType == _L("TOPBORDER"))	 
   718 				TransParaBorderL();
   719 		else if (iArgType == _L("BOTTOMBORDER"))
   720 				TransParaBorderL();
   721 		else if (iArgType == _L("LEFT BORDER"))	 
   722 				TransParaBorderL();
   723 		else if (iArgType == _L("RIGHTBORDER"))	 
   724 				TransParaBorderL();
   725 		else if (iArgType == _L("BULLET"))		 
   726 				TransParaBullet();
   727 		else if (iArgType == _L("DEFAULTTABWIDTH")) 
   728 				TransParaTabWidth();
   729 		else if (iArgType == _L("TABSTOP"))
   730 				TransParaTabStopL();
   731 		else 
   732 				iErrorLevel = EUnknownAttrib;
   733 		}
   734 	}
   735 
   736 
   737 void CParser::TransParaDefault()
   738 // turns off all applied para formatting - reverts to global
   739 	{
   740 	iParaFormatMask.ClearAll();
   741 	OutputToScreen(_L("<PARA-DEFAULT>"));
   742 	}
   743 
   744 
   745 void CParser::TransParaArgLeftMargin()
   746 	{
   747 	TInt32 margin = GetArgValue();
   748 	switch (iTagType)
   749 		{
   750 		case EParagraph:		 
   751 			iParaFormat->iLeftMarginInTwips = margin;
   752 			iParaFormatMask.SetAttrib(EAttLeftMargin);
   753 			break;
   754 		case EGlobal:
   755 			iGlobalParaFormat->iLeftMarginInTwips = margin;
   756 			iGlobalParaFormatMask.SetAttrib(EAttLeftMargin);
   757 			break;
   758 		}
   759 	// screen output
   760 	TBuf<80> outputBuf;
   761 	outputBuf.Format(_L("<LEFT MARGIN = %d>"),margin);
   762 	OutputToScreen(outputBuf);
   763 	}
   764 
   765 void CParser::TransParaArgRightMargin()
   766 	{
   767 	TInt32 margin = GetArgValue();		
   768 	switch (iTagType)
   769 		{
   770 		case EParagraph:		 
   771 			iParaFormat->iRightMarginInTwips = margin;
   772 			iParaFormatMask.SetAttrib(EAttRightMargin);
   773 			break;
   774 		case EGlobal:
   775 			iGlobalParaFormat->iRightMarginInTwips = margin;
   776 			iGlobalParaFormatMask.SetAttrib(EAttRightMargin);
   777 			break;
   778 		}
   779 	// screen output
   780 	TBuf<80> outputBuf;
   781 	outputBuf.Format(_L("<RIGHT MARGIN = %d>"),margin);
   782 	OutputToScreen(outputBuf);
   783 	}
   784 
   785 void CParser::TransParaArgIndent()
   786 	{
   787 	TInt32 indent = GetArgValue();
   788 	switch (iTagType)
   789 		{
   790 		case EParagraph:		 
   791 			iParaFormat->iIndentInTwips = indent;
   792 			iParaFormatMask.SetAttrib(EAttIndent);
   793 			break;
   794 		case EGlobal:
   795 			iGlobalParaFormat->iIndentInTwips = indent;
   796 			iGlobalParaFormatMask.SetAttrib(EAttIndent);
   797 			break;
   798 		}
   799 	// screen output
   800 	TBuf<80> outputBuf;
   801 	outputBuf.Format(_L("<INDENT = %d>"),indent);
   802 	OutputToScreen(outputBuf);
   803 	}
   804 
   805 void CParser::TransParaLineSpacing()
   806 	{
   807 	TInt32 lineSpacing = GetArgValue();		  
   808 	switch (iTagType)
   809 		{
   810 		case EParagraph:		 
   811 			iParaFormat->iLineSpacingInTwips = lineSpacing;
   812 			iParaFormatMask.SetAttrib(EAttLineSpacing);
   813 			break;
   814 		case EGlobal:
   815 			iGlobalParaFormat->iLineSpacingInTwips = lineSpacing;
   816 			iGlobalParaFormatMask.SetAttrib(EAttLineSpacing);
   817 			break;
   818 		}
   819 	// screen output
   820 	TBuf<80> outputBuf;
   821 	outputBuf.Format(_L("<LINESPACING = %d>"),lineSpacing);
   822 	OutputToScreen(outputBuf);
   823 	}
   824 
   825 void CParser::TransParaArgLineSpacingControl()
   826 	{
   827 	if (iArgValue == _L("ATLEAST"))
   828 		{
   829 		switch (iTagType)
   830 			{
   831 			case EParagraph:		 
   832 				iParaFormat->iLineSpacingControl = CParaFormat::ELineSpacingAtLeastInTwips;
   833 				iParaFormatMask.SetAttrib(EAttLineSpacingControl);
   834 				break;
   835 			case EGlobal:
   836 				iGlobalParaFormat->iLineSpacingControl = CParaFormat::ELineSpacingAtLeastInTwips;
   837 				iGlobalParaFormatMask.SetAttrib(EAttLineSpacingControl);
   838 				break;
   839 			}
   840 		OutputToScreen(_L("<Line spacing control Atleast>"));
   841 		}
   842 	else if (iArgValue == _L("EXACTLY"))
   843 		{
   844 		switch (iTagType)
   845 			{
   846 			case EParagraph:		 
   847 				iParaFormat->iLineSpacingControl = CParaFormat::ELineSpacingExactlyInTwips;
   848 				iParaFormatMask.SetAttrib(EAttLineSpacingControl);
   849 				break;
   850 			case EGlobal:
   851 				iGlobalParaFormat->iLineSpacingControl = CParaFormat::ELineSpacingExactlyInTwips;
   852 				iGlobalParaFormatMask.SetAttrib(EAttLineSpacingControl);
   853 				break;
   854 			}
   855 		OutputToScreen(_L("<Line spacing control Exactly>"));
   856 		}
   857 	else
   858 		iErrorLevel = EIllegalAttribValue;
   859 	}
   860 
   861 void CParser::TransParaSpaceBefore()
   862 	{
   863 	TInt32 spaceBefore = GetArgValue();		  
   864 	switch (iTagType)
   865 		{
   866 		case EParagraph:		 
   867 			iParaFormat->iSpaceBeforeInTwips = spaceBefore;
   868 			iParaFormatMask.SetAttrib(EAttSpaceBefore);
   869 			break;
   870 		case EGlobal:
   871 			iGlobalParaFormat->iSpaceBeforeInTwips = spaceBefore;
   872 			iGlobalParaFormatMask.SetAttrib(EAttSpaceBefore);
   873 			break;
   874 		}
   875 	// screen output
   876 	TBuf<80> outputBuf;
   877 	outputBuf.Format(_L("<SPACE BEFORE = %d>"),spaceBefore);
   878 	OutputToScreen(outputBuf);
   879 	}
   880 
   881 void CParser::TransParaSpaceAfter()
   882 	{
   883 	TInt32 spaceAfter = GetArgValue();		  
   884 	switch (iTagType)
   885 		{
   886 		case EParagraph:		 
   887 			iParaFormat->iSpaceAfterInTwips = spaceAfter;
   888 			iParaFormatMask.SetAttrib(EAttSpaceAfter);
   889 			break;
   890 		case EGlobal:
   891 			iGlobalParaFormat->iSpaceAfterInTwips = spaceAfter;
   892 			iGlobalParaFormatMask.SetAttrib(EAttSpaceAfter);
   893 			break;
   894 		}
   895 	// screen output
   896 	TBuf<80> outputBuf;
   897 	outputBuf.Format(_L("<SPACE AFTER = %d>"),spaceAfter);
   898 	OutputToScreen(outputBuf);
   899 	}
   900 
   901 void CParser::TransParaBorderMargin()
   902 	{
   903 	TInt32 borderMargin = GetArgValue();		  
   904 	switch (iTagType)
   905 		{
   906 		case EParagraph:		 
   907 			iParaFormat->iBorderMarginInTwips = borderMargin;
   908 			iParaFormatMask.SetAttrib(EAttBorderMargin);
   909 			break;
   910 		case EGlobal:
   911 			iGlobalParaFormat->iBorderMarginInTwips = borderMargin;
   912 			iGlobalParaFormatMask.SetAttrib(EAttBorderMargin);
   913 			break;
   914 		}
   915 	// screen output
   916 	TBuf<80> outputBuf;
   917 	outputBuf.Format(_L("<BORDER MARGIN = %d>"),borderMargin);
   918 	OutputToScreen(outputBuf);
   919 	}
   920 
   921 void CParser::TransParaKeepTogether()
   922 	{
   923 	switch (iTagType)
   924 		{
   925 		case EParagraph:		 
   926 			if (iCancelArg)
   927 				iParaFormat->iKeepTogether = EFalse;
   928 			else
   929 				iParaFormat->iKeepTogether = ETrue;
   930 			iParaFormatMask.SetAttrib(EAttKeepTogether);
   931 			break;
   932 		case EGlobal:
   933 			if (iCancelArg)
   934 				iGlobalParaFormat->iKeepTogether = EFalse;
   935 			else
   936 				iGlobalParaFormat->iKeepTogether = ETrue;
   937 			iGlobalParaFormatMask.SetAttrib(EAttKeepTogether);
   938 			break;
   939 		}
   940 	// screen output
   941 	OutputToScreen(_L("<KEEP TOGETHER>"));
   942 	}
   943 
   944 void CParser::TransParaKeepWithNext()
   945 	{
   946 	switch (iTagType)
   947 		{
   948 		case EParagraph:		 
   949 			if (iCancelArg)
   950 				iParaFormat->iKeepWithNext = EFalse;
   951 			else
   952 				iParaFormat->iKeepWithNext = ETrue;
   953 			iParaFormatMask.SetAttrib(EAttKeepWithNext);
   954 			break;
   955 		case EGlobal:
   956 			if (iCancelArg)
   957 				iGlobalParaFormat->iKeepWithNext = EFalse;
   958 			else
   959 				iGlobalParaFormat->iKeepWithNext = ETrue;
   960 			iGlobalParaFormatMask.SetAttrib(EAttKeepWithNext);
   961 			break;
   962 		}
   963 	// screen output
   964 	OutputToScreen(_L("<KEEP WITH NEXT>"));
   965 	}
   966 
   967 void CParser::TransParaStartNewPage()
   968 	{
   969 	switch (iTagType)
   970 		{
   971 		case EParagraph:		 
   972 			if (iCancelArg)
   973 				iParaFormat->iStartNewPage = EFalse;
   974 			else
   975 				iParaFormat->iStartNewPage = ETrue;
   976 			iParaFormatMask.SetAttrib(EAttStartNewPage);
   977 			break;
   978 		case EGlobal:
   979 			if (iCancelArg)
   980 				iGlobalParaFormat->iStartNewPage = EFalse;
   981 			else
   982 				iGlobalParaFormat->iStartNewPage = ETrue;
   983 			iGlobalParaFormatMask.SetAttrib(EAttStartNewPage);
   984 			break;
   985 		}
   986 	// screen output
   987 	OutputToScreen(_L("<START NEW PAGE>"));
   988 	}
   989 
   990 void CParser::TransParaWidowOrphan()
   991 	{
   992 	switch (iTagType)
   993 		{
   994 		case EParagraph:		 
   995 			if (iCancelArg)
   996 				iParaFormat->iWidowOrphan = EFalse;
   997 			else
   998 				iParaFormat->iWidowOrphan = ETrue;
   999 			iParaFormatMask.SetAttrib(EAttWidowOrphan);
  1000 			break;
  1001 		case EGlobal:
  1002 			if (iCancelArg)
  1003 				iGlobalParaFormat->iWidowOrphan = EFalse;
  1004 			else
  1005 				iGlobalParaFormat->iWidowOrphan = ETrue;
  1006 			iGlobalParaFormatMask.SetAttrib(EAttWidowOrphan);
  1007 			break;
  1008 		}
  1009 	// screen output
  1010 	OutputToScreen(_L("<WIDOWS & ORPHANS>"));
  1011 	}
  1012 
  1013 void CParser::TransParaArgAlignment()
  1014 	{
  1015 	// parse argValue
  1016 	if (iArgValue == _L("LEFT"))
  1017 		{
  1018 		switch (iTagType)
  1019 			{
  1020 			case EParagraph:		 
  1021 				iParaFormat->iHorizontalAlignment = CParaFormat::ELeftAlign;
  1022 				iParaFormatMask.SetAttrib(EAttAlignment);
  1023 				break;
  1024 			case EGlobal:
  1025 				iGlobalParaFormat->iHorizontalAlignment = CParaFormat::ELeftAlign;
  1026 				iGlobalParaFormatMask.SetAttrib(EAttAlignment);
  1027 				break;
  1028 			}
  1029 		OutputToScreen(_L("<ALIGNMENT LEFT>"));
  1030 		}
  1031 	else if (iArgValue == _L("RIGHT"))
  1032 		{
  1033 		switch (iTagType)
  1034 			{
  1035 			case EParagraph:		 
  1036 				iParaFormat->iHorizontalAlignment = CParaFormat::ERightAlign;
  1037 				iParaFormatMask.SetAttrib(EAttAlignment);
  1038 				break;
  1039 			case EGlobal:
  1040 				iGlobalParaFormat->iHorizontalAlignment = CParaFormat::ERightAlign;
  1041 				iGlobalParaFormatMask.SetAttrib(EAttAlignment);
  1042 				break;
  1043 			}
  1044 		OutputToScreen(_L("<ALIGNMENT RIGHT>"));
  1045 		}
  1046 	else if (iArgValue == _L("CENTER"))
  1047 		{
  1048 		switch (iTagType)
  1049 			{
  1050 			case EParagraph:		 
  1051 				iParaFormat->iHorizontalAlignment = CParaFormat::ECenterAlign;
  1052 				iParaFormatMask.SetAttrib(EAttAlignment);
  1053 				break;
  1054 			case EGlobal:
  1055 				iGlobalParaFormat->iHorizontalAlignment = CParaFormat::ECenterAlign;
  1056 				iGlobalParaFormatMask.SetAttrib(EAttAlignment);
  1057 				break;
  1058 			}
  1059 		OutputToScreen(_L("<ALIGNMENT CENTER>"));
  1060 		}
  1061 	else if (iArgValue == _L("JUSTIFIED"))
  1062 		{
  1063 		switch (iTagType)
  1064 			{
  1065 			case EParagraph:		 
  1066 				iParaFormat->iHorizontalAlignment = CParaFormat::EJustifiedAlign;
  1067 				iParaFormatMask.SetAttrib(EAttAlignment);
  1068 				break;
  1069 			case EGlobal:
  1070 				iGlobalParaFormat->iHorizontalAlignment = CParaFormat::EJustifiedAlign;
  1071 				iGlobalParaFormatMask.SetAttrib(EAttAlignment);
  1072 				break;
  1073 			}
  1074 		OutputToScreen(_L("<ALIGNMENT JUSTIFIED>"));
  1075 		}
  1076 	else
  1077 		iErrorLevel = EIllegalAttribValue;
  1078 	}
  1079 
  1080 
  1081 void CParser::TransParaBullet()
  1082 	{
  1083 	TInt characterCode = 0x2022;
  1084 	TUint32 heightInTwips=0;
  1085 	TUint32 flags=0;
  1086 	TBuf<KMaxTypefaceNameLength> name;
  1087 	TBuf<128> component;
  1088 
  1089 	// set first component (character code)
  1090 	TInt commaPos = iArgValue.Locate(KComma);	 // find pos of first comma
  1091 	component = iArgValue.Left(commaPos);
  1092 	if (component != _L(""))					// only third arg remains
  1093 		{
  1094 		if (BufIsNumeric(component))
  1095 			{
  1096 			TLex tmpLex(component);
  1097 			// TUint value;
  1098 			tmpLex.Val(characterCode);
  1099 			}
  1100 		else 
  1101 			iErrorLevel = EIllegalAttribValue;
  1102 		}
  1103 	else
  1104 		iErrorLevel = EIllegalAttribValue;
  1105 
  1106 	// set second component (bullet height)
  1107 	iArgValue.Delete(0,commaPos+1);				// delete previous component & trailing comma 
  1108 	commaPos = iArgValue.Locate(KComma);	// find pos of first comma
  1109 	component = iArgValue.Left(commaPos);
  1110 	if (component != _L(""))					// only third arg remains
  1111 		{
  1112 		if (BufIsNumeric(component))
  1113 			{
  1114 			TLex tmpLex(component);
  1115 			TUint value;
  1116 			tmpLex.Val(value);
  1117 			heightInTwips = value;
  1118 			}
  1119 		else 
  1120 			iErrorLevel = EIllegalAttribValue;
  1121 		}
  1122 	else
  1123 		iErrorLevel = EIllegalAttribValue;
  1124 
  1125 	// set third component (typeface flags)
  1126 	iArgValue.Delete(0,commaPos+1);				// delete previous component & trailing comma 
  1127 	commaPos = iArgValue.Locate(KComma);		// find pos of first comma
  1128 	component = iArgValue.Left(commaPos);
  1129 	if (component != _L(""))					// only third arg remains
  1130 		{
  1131 		flags = GetArgValue(component);
  1132 		if (flags>2)
  1133 			iErrorLevel=EIllegalAttribValue;	// only values 0,1,2 valid for flag
  1134 		}
  1135 	else
  1136 		iErrorLevel = EIllegalAttribValue;
  1137 
  1138 	// set fourth component (typeface name)
  1139 	iArgValue.Delete(0,commaPos+1);				// delete previous component & trailing comma 
  1140 	if (iArgValue != _L(""))					// only third arg remains
  1141 		{
  1142 		name.Copy(iArgValue);		
  1143 //		name = SquashBuf(iArgValue);
  1144 		}
  1145 	else
  1146 		iErrorLevel = EIllegalAttribValue;
  1147 
  1148 	// apply
  1149 	if (iErrorLevel == ENoError)
  1150 		{
  1151 		iBulletUsed = ETrue;
  1152 		iBullet->iCharacterCode = (TText)characterCode;
  1153 		iBullet->iHeightInTwips = heightInTwips;
  1154 		if (flags>=1)
  1155 			iBullet->iTypeface.SetIsProportional(ETrue);
  1156 		if (flags>=3)
  1157 			iBullet->iTypeface.SetIsSerif(ETrue);
  1158 		iBullet->iTypeface.iName = name;
  1159 		switch (iTagType)
  1160 			{
  1161 			case EParagraph:
  1162 				iParaFormat->iBullet = iBullet;  
  1163 				iParaFormatMask.SetAttrib(EAttBullet);
  1164 				break;
  1165 			case EGlobal:
  1166 				iGlobalParaFormat->iBullet = iBullet;
  1167 				iGlobalParaFormatMask.SetAttrib(EAttBullet);
  1168 				break;
  1169 			}
  1170 		OutputToScreen(_L("<BULLET>"));
  1171 		}
  1172 	}
  1173 
  1174 TBuf8<512> CParser::SquashBuf(TDes aBuffer)
  1175 	//
  1176 	// Input 8/16 bit buffer to be returned as an 8-bit version
  1177 	// Used for unicode compatability
  1178 	//
  1179 	{
  1180 	TText16 textPointer;
  1181 
  1182 	TBuf8<512> returnBuf;
  1183 
  1184 	for ( TInt pos=0 ; pos<aBuffer.Length() ; pos++ )
  1185 		{
  1186 		textPointer = aBuffer[pos];
  1187 #pragma warning ( disable : 4244 )
  1188 		returnBuf[pos] = textPointer; // conversion from unsigned short to unsigned char (16 bit to 8 bit) in unicode
  1189 #pragma warning ( default : 4244 )
  1190 		}
  1191 	return returnBuf;
  1192 	}
  1193 
  1194 
  1195 
  1196 void CParser::TransParaBorderL()
  1197 	{
  1198 	TParaBorder::TLineStyle lineStyle=TParaBorder::ENullLineStyle;
  1199 	TBool autoColor=EFalse;
  1200 	TRgb color;
  1201 	TBuf<128> component;
  1202 
  1203 	// set first component
  1204 	TInt commaPos = iArgValue.Locate(KComma);	 // find pos of first comma
  1205 	component = iArgValue.Left(commaPos);
  1206 	if (component != _L(""))
  1207 		{
  1208 		if (component == _L("NULL"))
  1209 			lineStyle = TParaBorder::ENullLineStyle;
  1210 		else if (component == _L("SOLID"))
  1211 			lineStyle = TParaBorder::ESolid;
  1212 		else if (component == _L("DOUBLE"))
  1213 			lineStyle = TParaBorder::EDouble;
  1214 		else if (component == _L("DOTTED"))
  1215 			lineStyle = TParaBorder::EDotted;
  1216 		else if (component == _L("DASHED"))
  1217 			lineStyle = TParaBorder::EDashed;
  1218 		else if (component == _L("DOTDASH"))
  1219 			lineStyle = TParaBorder::EDotDash;
  1220 		else if (component == _L("DOTDOTDASH"))
  1221 			lineStyle = TParaBorder::EDotDotDash;
  1222 		else
  1223 			iErrorLevel = EIllegalAttribValue; 
  1224 		}
  1225 	else
  1226 		iErrorLevel = EIllegalAttribValue;
  1227 	
  1228 	// set second component
  1229 	iArgValue.Delete(0,commaPos+1);				// delete first component & trailing comma 
  1230 	commaPos = iArgValue.Locate(KComma);	 	// find pos of first comma
  1231 	component = iArgValue.Left(commaPos);
  1232 	if (component != _L(""))
  1233 		{
  1234 		if (component == _L("ON"))
  1235 			autoColor = ETrue;
  1236 		else if (component == _L("OFF"))
  1237 			autoColor = EFalse;
  1238 		else
  1239 			iErrorLevel = EIllegalAttribValue; 
  1240 		}
  1241 	else
  1242 		iErrorLevel = EIllegalAttribValue;
  1243 
  1244 	// set third component
  1245 	iArgValue.Delete(0,commaPos+1);				// delete second component & trailing comma 
  1246 	if (component != _L(""))					// only third arg remains
  1247 		{
  1248 		if (BufIsNumeric(iArgValue))
  1249 			{
  1250 			TLex tmpLex(iArgValue);
  1251 			TUint value;
  1252 			tmpLex.Val(value);
  1253 			color=TRgb((TUint32)value);
  1254 			}
  1255 		else 
  1256 			iErrorLevel = EIllegalAttribValue;
  1257 		}
  1258 
  1259 	// apply
  1260 	if (iErrorLevel == ENoError)
  1261 		{
  1262 		iBorderUsed = ETrue;
  1263 		iBorder->iLineStyle = lineStyle;
  1264 		iBorder->iAutoColor = autoColor;
  1265 		iBorder->iColor = color;
  1266 		if (iArgType == _L("TOPBORDER"))
  1267 			{
  1268 			switch (iTagType)
  1269 				{
  1270 				case EParagraph:
  1271 					iParaFormat->SetParaBorderL(CParaFormat::EParaBorderTop,*iBorder);
  1272 					iParaFormatMask.SetAttrib(EAttTopBorder);
  1273 					break;
  1274 				case EGlobal:
  1275 					iGlobalParaFormat->SetParaBorderL(CParaFormat::EParaBorderTop,*iBorder);
  1276 					iGlobalParaFormatMask.SetAttrib(EAttTopBorder);
  1277 					break;
  1278 				}
  1279 			}
  1280 		if (iArgType == _L("BOTTOMBORDER"))
  1281 			{
  1282 			switch (iTagType)
  1283 				{
  1284 				case EParagraph:
  1285 					iParaFormat->SetParaBorderL(CParaFormat::EParaBorderBottom,*iBorder);
  1286 					iParaFormatMask.SetAttrib(EAttBottomBorder);
  1287 					break;
  1288 				case EGlobal:
  1289 					iGlobalParaFormat->SetParaBorderL(CParaFormat::EParaBorderBottom,*iBorder);
  1290 					iGlobalParaFormatMask.SetAttrib(EAttBottomBorder);
  1291 					break;
  1292 				}
  1293 			}
  1294 		if (iArgType == _L("LEFTBORDER"))
  1295 			{
  1296 			switch (iTagType)
  1297 				{
  1298 				case EParagraph:
  1299 					iParaFormat->SetParaBorderL(CParaFormat::EParaBorderLeft,*iBorder);
  1300 					iParaFormatMask.SetAttrib(EAttLeftBorder);
  1301 					break;
  1302 				case EGlobal:
  1303 					iGlobalParaFormat->SetParaBorderL(CParaFormat::EParaBorderLeft,*iBorder);
  1304 					iGlobalParaFormatMask.SetAttrib(EAttLeftBorder);
  1305 					break;
  1306 				}
  1307 			}
  1308 		if (iArgType == _L("RIGHTBORDER"))
  1309 			{
  1310 			switch (iTagType)
  1311 				{
  1312 				case EParagraph:
  1313 					iParaFormat->SetParaBorderL(CParaFormat::EParaBorderRight,*iBorder);
  1314 					iParaFormatMask.SetAttrib(EAttRightBorder);
  1315 					break;
  1316 				case EGlobal:
  1317 					iGlobalParaFormat->SetParaBorderL(CParaFormat::EParaBorderRight,*iBorder);
  1318 					iGlobalParaFormatMask.SetAttrib(EAttRightBorder);
  1319 					break;
  1320 				}
  1321 			}
  1322 		OutputToScreen(_L("<PARA BORDER>"));
  1323 		}
  1324 	}
  1325 
  1326 void CParser::TransParaTabWidth()
  1327 	{
  1328 	TInt32 tabWidth = GetArgValue();
  1329 	switch (iTagType)
  1330 		{
  1331 		case EParagraph:		 
  1332 			iParaFormat->iDefaultTabWidthInTwips = tabWidth;
  1333 			iParaFormatMask.SetAttrib(EAttDefaultTabWidth);
  1334 			break;
  1335 		case EGlobal:
  1336 			iGlobalParaFormat->iDefaultTabWidthInTwips = tabWidth;
  1337 			iGlobalParaFormatMask.SetAttrib(EAttDefaultTabWidth);
  1338 			break;
  1339 		}
  1340 	// screen output
  1341 	TBuf<80> outputBuf;
  1342 	outputBuf.Format(_L("<DEFAULT TAB WIDTH = %d>"),tabWidth);
  1343 	OutputToScreen(outputBuf);
  1344 	}
  1345 
  1346 
  1347 void CParser::TransParaTabStopL()
  1348 // This arg has a compound value of the form Tabstop=value,type
  1349 // It also accepts !Tabstop=value to delete an existing tabstop
  1350 	{
  1351 	TTabStop tabStop;
  1352 	TBuf<128> component;
  1353 	TBuf<6> outputBuf;
  1354 
  1355 	// get first component (tab type)
  1356 	TInt commaPos = iArgValue.Locate(KComma);	 // find pos of first comma (returns -1 if no comma)
  1357 	if (commaPos > 0)	// comma & first component exist
  1358 		{
  1359 		component = iArgValue.Left(commaPos);	// take part to the left of the comma
  1360 		if (component != _L(""))				
  1361 			tabStop.iTwipsPosition = GetArgValue(component);
  1362 		else
  1363 			iErrorLevel = EIllegalAttribValue;
  1364 		}
  1365 	else if ((iCancelArg)&&(commaPos == -1))	// no comma but only one component required (position)
  1366 		{
  1367 		if (iArgValue != _L(""))				
  1368 			tabStop.iTwipsPosition = GetArgValue(iArgValue);
  1369 		else
  1370 			iErrorLevel = EIllegalAttribValue;
  1371 		}
  1372 
  1373 	if (iErrorLevel == ENoError)
  1374 		{
  1375 		if (iCancelArg)
  1376 			// insert a null tab
  1377 			{
  1378 			if ((iParaFormat->LocateTab(tabStop.iTwipsPosition) != KTabNotFound)
  1379 				||(iGlobalParaFormat->LocateTab(tabStop.iTwipsPosition) != KTabNotFound))
  1380 					{
  1381 					tabStop.iType = TTabStop::ENullTab;	// null tab "deletes" existing tab
  1382 					outputBuf = _L("<!TAB>");
  1383 					}
  1384 			else
  1385 				iErrorLevel = EIllegalAttribValue;
  1386 			}
  1387 		else
  1388 			{
  1389 			// set second component (tab position in twips)
  1390 			iArgValue.Delete(0,commaPos+1);				// delete previous component & trailing comma 
  1391 			if (iArgValue != _L(""))				
  1392 				{
  1393 				outputBuf = _L("<TAB>");
  1394 				if (iArgValue == _L("NULL"))
  1395 					tabStop.iType = TTabStop::ENullTab;
  1396 				else if (iArgValue == _L("LEFT"))
  1397 					tabStop.iType = TTabStop::ELeftTab;
  1398 				else if (iArgValue == _L("CENTERED"))
  1399 					tabStop.iType = TTabStop::ECenteredTab;
  1400 				else if (iArgValue == _L("RIGHT"))
  1401 					tabStop.iType = TTabStop::ERightTab;
  1402 				else 
  1403 					iErrorLevel = EIllegalAttribValue;
  1404 				}
  1405 			else
  1406 				iErrorLevel = EIllegalAttribValue;
  1407 			}
  1408 		}
  1409 
  1410  	// Insert the tab
  1411 	if (iErrorLevel == ENoError)
  1412 		{
  1413 		switch (iTagType)
  1414 			{
  1415 			case EParagraph:
  1416 				iParaFormat->StoreTabL(tabStop);
  1417 				iParaFormatMask.SetAttrib(EAttTabStop);
  1418 				break;
  1419 			case EGlobal:
  1420 				iGlobalParaFormat->StoreTabL(tabStop);
  1421 				iGlobalParaFormatMask.SetAttrib(EAttTabStop);
  1422 				break;
  1423 			}
  1424 		// output to screen
  1425 		OutputToScreen(outputBuf);
  1426 		}
  1427 	}
  1428 
  1429  
  1430 void CParser::TransCharArg()
  1431 	{
  1432 	if (iArgType != _L("")) 				// Is there an argument?
  1433 		{
  1434 		if (iArgType == _L("DEFAULT"))
  1435 				TransCharDefault();
  1436 		else if (iArgType == _L("ITALIC"))	
  1437 				TransCharPosture();
  1438 		else if (iArgType == _L("BOLD"))	
  1439 				TransCharStrokeWeight();
  1440 		else if (iArgType == _L("UNDERLINE"))	
  1441 				TransCharUnderline();
  1442 		else if (iArgType == _L("STRIKETHROUGH"))
  1443 				TransCharStrikethrough();
  1444 		else if (!iArgValueExpected)			// No argument value supplied when one is required for the
  1445 				iErrorLevel = ENoAttribValue;	// remaining options or an unknown argument supplied
  1446 		else if (iArgType == _L("FONTHEIGHT"))	
  1447 				TransCharFontHeight();
  1448 		else if (iArgType == _L("PRINTPOS"))	
  1449 				TransCharPrintPos();
  1450 		else if (iArgType == _L("TYPEFACENAME"))
  1451 				TransCharTypefaceName();
  1452 		else if (iArgType == _L("TYPEFACEFLAGS"))	
  1453 				TransCharTypefaceFlags();
  1454 		else if (iArgType == _L("COLOR"))	 	 
  1455 				TransCharColor();
  1456 		else if (iArgType == _L("LANGUAGE"))	
  1457 				TransCharLanguage();
  1458 		else 
  1459 				iErrorLevel = EUnknownAttrib;
  1460 		}
  1461 	}
  1462 
  1463 
  1464 void CParser::TransCharDefault()
  1465 // turns off all applied Char formatting - reverts to global
  1466 	{
  1467 	iCharFormatMask.ClearAll();
  1468 	OutputToScreen(_L("<CHAR-DEFAULT>"));
  1469 	}
  1470 
  1471 
  1472 void CParser::TransCharPosture()
  1473 	{
  1474 	switch (iTagType)
  1475 		{
  1476 		case ECharacter:		 
  1477 			if (iCancelArg)
  1478 				iCharFormat.iFontSpec.iFontStyle.SetPosture(EPostureUpright);
  1479 			else
  1480 				iCharFormat.iFontSpec.iFontStyle.SetPosture(EPostureItalic);
  1481 			iCharFormatMask.SetAttrib(EAttFontPosture);
  1482 			break;
  1483 		case EGlobal:
  1484 			if (iCancelArg)
  1485 				iGlobalCharFormat.iFontSpec.iFontStyle.SetPosture(EPostureUpright);
  1486 			else
  1487 				iGlobalCharFormat.iFontSpec.iFontStyle.SetPosture(EPostureItalic);
  1488 			iGlobalCharFormatMask.SetAttrib(EAttFontPosture);
  1489 			break;
  1490 		}
  1491 	// screen output
  1492 	OutputToScreen(_L("<ITALIC>"));
  1493 	}
  1494 
  1495 
  1496 void CParser::TransCharStrokeWeight()
  1497 	{
  1498 	switch (iTagType)
  1499 		{
  1500 		case ECharacter:		 
  1501 			if (iCancelArg)
  1502 				iCharFormat.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightNormal);
  1503 			else
  1504 				iCharFormat.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
  1505 			iCharFormatMask.SetAttrib(EAttFontStrokeWeight);
  1506 			break;
  1507 		case EGlobal:
  1508 			if (iCancelArg)
  1509 				iGlobalCharFormat.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightNormal);
  1510 			else
  1511 				iGlobalCharFormat.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
  1512 			iGlobalCharFormatMask.SetAttrib(EAttFontStrokeWeight);
  1513 			break;
  1514 		}
  1515 	// screen output
  1516 	OutputToScreen(_L("<BOLD>"));
  1517 	}
  1518 
  1519 
  1520 void CParser::TransCharUnderline()
  1521 	{
  1522 	switch (iTagType)
  1523 		{
  1524 		case ECharacter:		 
  1525 			if (iCancelArg)
  1526 				iCharFormat.iFontPresentation.iUnderline = EUnderlineOff;
  1527 			else
  1528 				iCharFormat.iFontPresentation.iUnderline = EUnderlineOn;
  1529 			iCharFormatMask.SetAttrib(EAttFontUnderline);
  1530 			break;
  1531 		case EGlobal:
  1532 			if (iCancelArg)
  1533 				iGlobalCharFormat.iFontPresentation.iUnderline = EUnderlineOff;
  1534 			else
  1535 				iGlobalCharFormat.iFontPresentation.iUnderline = EUnderlineOn;
  1536 			iGlobalCharFormatMask.SetAttrib(EAttFontUnderline);
  1537 			break;
  1538 		}
  1539 	// screen output
  1540 	OutputToScreen(_L("<UNDERLINE>"));
  1541 	}
  1542 
  1543 
  1544 void CParser::TransCharStrikethrough()
  1545 	{
  1546 	switch (iTagType)
  1547 		{
  1548 		case ECharacter:		 
  1549 			if (iCancelArg)
  1550 				iCharFormat.iFontPresentation.iStrikethrough = EStrikethroughOff;
  1551 			else
  1552 				iCharFormat.iFontPresentation.iStrikethrough = EStrikethroughOn;
  1553 			iCharFormatMask.SetAttrib(EAttFontStrikethrough);
  1554 			break;
  1555 		case EGlobal:
  1556 			if (iCancelArg)
  1557 				iGlobalCharFormat.iFontPresentation.iStrikethrough = EStrikethroughOff;
  1558 			else
  1559 				iGlobalCharFormat.iFontPresentation.iStrikethrough = EStrikethroughOn;
  1560 			iGlobalCharFormatMask.SetAttrib(EAttFontStrikethrough);
  1561 			break;
  1562 		}
  1563 	// screen output
  1564 	OutputToScreen(_L("<STRIKETHROUGH>"));
  1565 	}
  1566 
  1567 
  1568 void CParser::TransCharFontHeight()
  1569 	{
  1570 	TInt32 fontHeight = GetArgValue();		  
  1571 	switch (iTagType)
  1572 		{
  1573 		case ECharacter:		 
  1574 			iCharFormat.iFontSpec.iHeight = fontHeight;
  1575 			iCharFormatMask.SetAttrib(EAttFontHeight);
  1576 			break;
  1577 		case EGlobal:
  1578 			iGlobalCharFormat.iFontSpec.iHeight = fontHeight;
  1579 			iGlobalCharFormatMask.SetAttrib(EAttFontHeight);
  1580 			break;
  1581 		}
  1582 	// screen output
  1583 	TBuf<80> outputBuf;
  1584 	outputBuf.Format(_L("<FONTHEIGHT = %d>"),fontHeight);
  1585 	OutputToScreen(outputBuf);
  1586 	}
  1587 
  1588 void CParser::TransCharPrintPos()
  1589 	{
  1590 	if (iArgValue == _L("NORMAL"))
  1591 		{
  1592 		switch (iTagType)
  1593 			{
  1594 			case ECharacter:		 
  1595 				iCharFormat.iFontSpec.iFontStyle.SetPrintPosition(EPrintPosNormal);
  1596 				iCharFormatMask.SetAttrib(EAttFontPrintPos);
  1597 				break;
  1598 			case EGlobal:
  1599 				iGlobalCharFormat.iFontSpec.iFontStyle.SetPrintPosition(EPrintPosNormal);
  1600 				iGlobalCharFormatMask.SetAttrib(EAttFontPrintPos);
  1601 				break;
  1602 			}
  1603 		OutputToScreen(_L("<PRINT POSITION NORMAL>"));
  1604 		}
  1605 	else if (iArgValue == _L("SUPERSCRIPT"))
  1606 		{
  1607 		switch (iTagType)
  1608 			{
  1609 			case ECharacter:		 
  1610 				iCharFormat.iFontSpec.iFontStyle.SetPrintPosition(EPrintPosSuperscript);
  1611 				iCharFormatMask.SetAttrib(EAttFontPrintPos);
  1612 				break;
  1613 			case EGlobal:
  1614 				iGlobalCharFormat.iFontSpec.iFontStyle.SetPrintPosition(EPrintPosSuperscript);
  1615 				iGlobalCharFormatMask.SetAttrib(EAttFontPrintPos);
  1616 				break;
  1617 			}
  1618 		OutputToScreen(_L("<SUPERSCRIPT>"));
  1619 		}
  1620 	else if (iArgValue == _L("SUBSCRIPT"))
  1621 		{
  1622 		switch (iTagType)
  1623 			{
  1624 			case ECharacter:		 
  1625 				iCharFormat.iFontSpec.iFontStyle.SetPrintPosition(EPrintPosSubscript);
  1626 				iCharFormatMask.SetAttrib(EAttFontPrintPos);
  1627 				break;
  1628 			case EGlobal:
  1629 				iGlobalCharFormat.iFontSpec.iFontStyle.SetPrintPosition(EPrintPosSubscript);
  1630 				iGlobalCharFormatMask.SetAttrib(EAttFontPrintPos);
  1631 				break;
  1632 			}
  1633 		OutputToScreen(_L("<SUBSCRIPT>"));
  1634 		}
  1635 	else
  1636 		iErrorLevel = EIllegalAttribValue;
  1637 	}
  1638 
  1639 
  1640 void CParser::TransCharTypefaceFlags()
  1641 	{
  1642 	TUint flags = GetArgValue();
  1643 	if (flags>2)
  1644 		iErrorLevel=EIllegalAttribValue;	// only values 0,1,2 valid for flag
  1645 	if (iErrorLevel==ENoError)
  1646 		{
  1647 		switch (iTagType)
  1648 			{
  1649 			case ECharacter:		 
  1650 				if (flags>=1)
  1651 					iCharFormat.iFontSpec.iTypeface.SetIsProportional(ETrue);
  1652 				if (flags>=3)
  1653 					iCharFormat.iFontSpec.iTypeface.SetIsSerif(ETrue);
  1654 				iCharFormatMask.SetAttrib(EAttFontTypeface);
  1655 				break;
  1656 			case EGlobal:
  1657 				if (flags>=1)
  1658 					iGlobalCharFormat.iFontSpec.iTypeface.SetIsProportional(ETrue);
  1659 				if (flags>=3)
  1660 					iGlobalCharFormat.iFontSpec.iTypeface.SetIsSerif(ETrue);
  1661 				iGlobalCharFormatMask.SetAttrib(EAttFontTypeface);
  1662 				break;
  1663 			}
  1664 		// screen output
  1665 		TBuf<80> outputBuf;
  1666 		outputBuf.Format(_L("<TYPEFACE FLAGS = %d>"),flags);
  1667 		OutputToScreen(outputBuf);
  1668 		}
  1669 	}
  1670 
  1671 
  1672 void CParser::TransCharTypefaceName()
  1673 	{
  1674 	switch (iTagType)
  1675 		{
  1676 		case ECharacter:
  1677 			iCharFormat.iFontSpec.iTypeface.iName=iArgValue;
  1678 			iCharFormatMask.SetAttrib(EAttFontTypeface);
  1679 			break;
  1680 		case EGlobal:
  1681 			iGlobalCharFormat.iFontSpec.iTypeface.iName=iArgValue;
  1682 			iGlobalCharFormatMask.SetAttrib(EAttFontTypeface);
  1683 			break;
  1684 		}
  1685 	// screen output
  1686 	TBuf<80> outputBuf;
  1687 	outputBuf.Format(_L("<TYPEFACE NAME = %S>"),&iArgValue);
  1688 	OutputToScreen(outputBuf);
  1689 	}
  1690 
  1691 
  1692 void CParser::TransCharColor()
  1693 	{
  1694 	TUint value = GetArgValue();
  1695 	if (iErrorLevel==ENoError)
  1696 		{
  1697 		TRgb color;
  1698 		color=TRgb((TUint32)value);
  1699 		switch (iTagType)
  1700 			{
  1701 			case ECharacter:		 
  1702 				iCharFormat.iFontPresentation.iTextColor = color;
  1703 				iCharFormatMask.SetAttrib(EAttColor);
  1704 				break;
  1705 			case EGlobal:
  1706 				iGlobalCharFormat.iFontPresentation.iTextColor = color;
  1707 				iGlobalCharFormatMask.SetAttrib(EAttColor);
  1708 				break;
  1709 			}
  1710 		// screen output
  1711 		TBuf<80> outputBuf;
  1712 		outputBuf.Format(_L("<COLOR = %d>"),value);
  1713 		OutputToScreen(outputBuf);
  1714 		}
  1715 	}
  1716 
  1717 
  1718 void CParser::TransCharLanguage()
  1719 // Assumes languages are integer coded - will have to change in time
  1720 	{
  1721 	TUint value = GetArgValue();
  1722 	if (iErrorLevel==ENoError)
  1723 		{
  1724 		switch (iTagType)
  1725 			{
  1726 			case ECharacter:		 
  1727 				iCharFormat.iLanguage = value;
  1728 				iCharFormatMask.SetAttrib(EAttCharLanguage);
  1729 				break;
  1730 			case EGlobal:
  1731 				iGlobalCharFormat.iLanguage = value;
  1732 				iGlobalCharFormatMask.SetAttrib(EAttCharLanguage);
  1733 				break;
  1734 			}
  1735 		// screen output
  1736 		TBuf<80> outputBuf;
  1737 		outputBuf.Format(_L("<LANGUAGE = %d>"),value);
  1738 		OutputToScreen(outputBuf);
  1739 		}
  1740 	}
  1741 
  1742 
  1743 
  1744 ////////////////////////////////
  1745 // CFileApp
  1746 ////////////////////////////////
  1747 
  1748 
  1749 CFileApp* CFileApp::NewL()
  1750 	{
  1751 	CFileApp* self=new(ELeave) CFileApp;
  1752 	CleanupStack::PushL(self);
  1753 	self->ConstructApplicationL();
  1754 	CleanupStack::Pop();
  1755 	return self;
  1756 	}
  1757 
  1758 
  1759 CFileApp::CFileApp()
  1760 	{
  1761 	// init variables
  1762 	iConsoleExists = EFalse;
  1763 	iFilePos = 0;
  1764 	}
  1765 	 
  1766 
  1767 void CFileApp::ConstructApplicationL()
  1768 	{
  1769 	iTextBuf = CBufSeg::NewL(64);  // Granularity of 64 bytes
  1770 	}
  1771 
  1772 
  1773 CFileApp::~CFileApp()
  1774 	{
  1775 	delete iTextBuf;
  1776 	}
  1777 
  1778 
  1779 CBufSeg* CFileApp::LoadFileL(CConsoleBase* aConsoleWin)
  1780 // Asks for file name, then loads file into text buffer.
  1781 	{ 
  1782 	iConsoleExists = ETrue;
  1783 	iConsole = aConsoleWin;			// grab console handle
  1784 	GetFileName();
  1785 	FileHandlingL();					// load file & store it
  1786 	return iTextBuf;
  1787 	}
  1788 
  1789 CBufSeg* CFileApp::LoadFileL(const TFileName &aFileName)
  1790 // uses supplied FileName to load file into CBufSeg
  1791 	{ 
  1792 	iFileName = aFileName;
  1793 	FileHandlingL();					// load file & store it
  1794 	return iTextBuf;
  1795 	}
  1796 
  1797 
  1798 void CFileApp::OutputToScreen(const TDesC& aMessageBuffer)
  1799 	{
  1800 	if (iConsoleExists)
  1801 		iConsole->Write(aMessageBuffer);  // output line to screen
  1802 	}
  1803 
  1804 
  1805 TInt CFileApp::SaveFile(CBufSeg* aTextBuf, TFileName aFileName)
  1806 // saves supplied buffer to disc, making the new filename a varient of the PML source filename supplied
  1807 	{
  1808 	// set filename to be saved as
  1809 	TInt length = aFileName.Length();
  1810 	aFileName.Delete(length-1,1);
  1811 	aFileName.Append(_L("G")); // generated filenames end in G
  1812 
  1813 	// create fileserver client and save.
  1814 	RFs fsClient;
  1815 	RFile theFile;
  1816 	TInt err = fsClient.Connect();
  1817 	if (err == 0)
  1818 		err = theFile.Replace(fsClient, aFileName, EFileStream|EFileRead|EFileWrite);
  1819 	if (err == 0)
  1820 		{
  1821 		TInt readWritePos = 0;
  1822 		TBuf8<80> insertBuf;
  1823 		TInt readLength=0;
  1824 		FOREVER
  1825 			{
  1826 			// read from TextBuf into insertBuf
  1827 			readLength=Min(aTextBuf->Size()-readWritePos,insertBuf.MaxLength());
  1828 			insertBuf.SetLength(0); 				// empty buffer
  1829 			aTextBuf->Read(readWritePos,insertBuf,readLength);
  1830 			// insert buf into file
  1831 			theFile.Write(readWritePos, insertBuf);
  1832 			readWritePos += insertBuf.Length();
  1833 			if (readWritePos >= aTextBuf->Size())
  1834 				break;
  1835 			}
  1836 	  	theFile.Close();
  1837 		}
  1838 	return err;
  1839 	}
  1840 
  1841 void CFileApp::GetFileName()
  1842 // read FileName synchronously from console
  1843 	{ 
  1844 	TKeyCode keystroke = EKeyNull;
  1845 	iFileName.SetLength(0);
  1846 
  1847 	//Debuging cheat to hardwire filename
  1848 	//iFileName=_L("d:\\etext\\incp\\dunk.pml");
  1849 	//return;
  1850 
  1851 	OutputToScreen(_L("Enter file to be parsed: "));
  1852 	keystroke = iConsole->Getch();
  1853 	while (keystroke != EKeyEnter)
  1854 		{
  1855 		TBuf<1> uniBuf; // used to ease unicode build
  1856 		uniBuf.Append(keystroke);
  1857 
  1858 		iConsole->Write(uniBuf);
  1859 		iFileName.Append(uniBuf);
  1860 		keystroke = iConsole->Getch();
  1861 		}
  1862 	WriteNewLine();
  1863 	}
  1864 
  1865 void CFileApp::FileHandlingL()
  1866 // Open a file, read contents into buffer, then close file again
  1867 	{
  1868 	// open file
  1869     RFile textFile;
  1870 	RFs fsClient;
  1871 	TInt err = 1;
  1872 	while (err)
  1873 		{
  1874 		err = fsClient.Connect();
  1875 		if (!err)
  1876     		err = textFile.Open(fsClient,iFileName,EFileStream|EFileRead|EFileShareReadersOnly);
  1877     	if (err)
  1878 			return;
  1879 /******GA
  1880 			{
  1881     		OutputToScreen(_L("Error in file open\n\n"));
  1882     		GetFileName();
  1883     		}
  1884 ******/
  1885     	}   	
  1886     
  1887 	OutputToScreen(_L("Parsing "));
  1888 	OutputToScreen(iFileName);
  1889 	WriteNewLine();
  1890 	WriteNewLine();
  1891 
  1892 	// Read file into segmented buffer
  1893 	TUint insertPos = 0;
  1894 
  1895 	TInt max = sizeof(TText) * KFileBufSize;
  1896 
  1897 	FOREVER
  1898 		{
  1899 		iFileBuf.SetLength(0);
  1900 		ReadChunkOfFileContents(textFile);
  1901 		iTextBuf->/*Do*/InsertL(insertPos,iFileBuf.Ptr(),iFileBuf.Size());
  1902 		insertPos += iFileBuf.Size();			// in bytes
  1903 		if (iFileBuf.Size() < max)
  1904 			break;
  1905 		}
  1906 
  1907 	// finish up
  1908  	textFile.Close();
  1909 	iFilePos = 0; // reset
  1910 	}
  1911 
  1912 void CFileApp::ReadChunkOfFileContents(RFile &aFile)
  1913     {
  1914 	TBuf8<KFileBufSize> readBuf;
  1915 	aFile.Read(iFilePos,readBuf);
  1916 	// read into iFileBuf (8/16 bit); 
  1917 	TText textPointer;
  1918 	for ( TInt pos=0 ; pos<readBuf.Length() ; pos++ )
  1919 		{
  1920 		textPointer = readBuf[pos];
  1921 		iFileBuf.Append(textPointer);
  1922 		}
  1923     //TInt ret=aFile.Read(iFilePos,iFileBuf);
  1924 	iFilePos += KFileBufSize;
  1925     }
  1926 
  1927 void CFileApp::WriteNewLine()
  1928 //
  1929 	{
  1930 	TBuf<1> buf(_L("\n"));
  1931 	OutputToScreen(buf);
  1932 	}
  1933