os/textandloc/textrendering/texthandling/stext/ParseLst.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200 (2012-06-15)
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
#include "TXTSTD.H"
sl@0
    20
#include "ParseLst.h"
sl@0
    21
#include "OstTraceDefinitions.h"
sl@0
    22
#ifdef OST_TRACE_COMPILER_IN_USE
sl@0
    23
#include "ParseLstTraces.h"
sl@0
    24
#endif
sl@0
    25
sl@0
    26
sl@0
    27
sl@0
    28
//++ sort out definitive hash includes
sl@0
    29
sl@0
    30
sl@0
    31
CParserList::CParserItem::CParserItem(MParser* aParser, const TUint aTagIndex)
sl@0
    32
: iParser(aParser),
sl@0
    33
  iTagIndex(aTagIndex)
sl@0
    34
	{
sl@0
    35
	}
sl@0
    36
sl@0
    37
sl@0
    38
// Panic the process with UikParse as the category.
sl@0
    39
void CParserList::Panic(TParserListPanic aPanic) const
sl@0
    40
	{
sl@0
    41
	OstTraceExt2( TRACE_FATAL, DUP1_CPARSERLIST_PANIC, "CParserList::Panic;this=%x;aPanic=%x", (unsigned int)this, ( TUint )&( aPanic ) );
sl@0
    42
	_LIT(panicStr, "ParseLst");
sl@0
    43
	User::Panic(panicStr, aPanic);
sl@0
    44
	}
sl@0
    45
sl@0
    46
sl@0
    47
CParserList::CParserList()
sl@0
    48
: iParserList(4)
sl@0
    49
	{
sl@0
    50
	iHighestIndex = 0;
sl@0
    51
	iNumberInList = 0;
sl@0
    52
	}
sl@0
    53
sl@0
    54
sl@0
    55
CParserList::~CParserList()
sl@0
    56
	{
sl@0
    57
	iParserList.ResetAndDestroy();	// Reset the list and destroy the CParserItems
sl@0
    58
	iParserList.Close();			// but leave the parsers and free the resources
sl@0
    59
	}
sl@0
    60
sl@0
    61
sl@0
    62
// Add parser to appropriate list
sl@0
    63
void CParserList::ActivateAParserL(MParser* aParser, const TBool aDefaultParser)
sl@0
    64
	{
sl@0
    65
	// Check the index isn't rolling over
sl@0
    66
	// N.B. This is somewhat unlikely. Since index is effectively a 29-bit
sl@0
    67
	// uint (I'm using the top 3 bits as flags) this allows 268435456 parsers
sl@0
    68
	// to be installed. (Assuming we deinstall almost as many, as we went
sl@0
    69
	// along, to avoid OOM.) At 50 per sec that's 20 years continuous action!
sl@0
    70
	if (iHighestIndex >= EMaxParserIndex)
sl@0
    71
	    {
sl@0
    72
	    OstTrace0( TRACE_DUMP, CPARSERLIST_ACTIVATEAPARSERL, "EParserIndexRollover" );
sl@0
    73
	    }
sl@0
    74
	__ASSERT_DEBUG((iHighestIndex < EMaxParserIndex), Panic(EParserIndexRollover));
sl@0
    75
	if (!aParser)
sl@0
    76
	    {
sl@0
    77
	    OstTrace0( TRACE_DUMP, DUP1_CPARSERLIST_ACTIVATEAPARSERL, "EParserNullPtr" );
sl@0
    78
	    }
sl@0
    79
	__ASSERT_DEBUG(aParser, Panic(EParserNullPtr));
sl@0
    80
	TUint parserIndex = iHighestIndex + 1;
sl@0
    81
	// Adjust flags to describe parser
sl@0
    82
	if (aParser->ReformatOnRecognise())
sl@0
    83
		parserIndex |= static_cast<TUint>( EReformatOnRecogniseFlag );
sl@0
    84
	if (aParser->ReformatOnRollover())
sl@0
    85
		parserIndex |= EReformatOnRolloverFlag;
sl@0
    86
	if (aDefaultParser)
sl@0
    87
		parserIndex |= EDefaultParserFlag;
sl@0
    88
	// Create a parser item
sl@0
    89
	TInt result;
sl@0
    90
	CParserItem* parserItem = new (ELeave) CParserItem(aParser, parserIndex);
sl@0
    91
	++iHighestIndex;
sl@0
    92
	if (aDefaultParser)
sl@0
    93
		{
sl@0
    94
		CleanupStack::PushL(parserItem);
sl@0
    95
		result = iParserList.Append(parserItem);
sl@0
    96
		if (result) // We couldn't get it in the main list
sl@0
    97
			User::Leave(result);
sl@0
    98
		CleanupStack::Pop();
sl@0
    99
		}
sl@0
   100
	else
sl@0
   101
		{
sl@0
   102
		// Look for the end of the specific parsers and the start of the default set
sl@0
   103
		TInt count;
sl@0
   104
		for (count = 0; count < iNumberInList; count++)
sl@0
   105
			{
sl@0
   106
			if (DefaultParser(iParserList[count]->TagIndex()))
sl@0
   107
				break;
sl@0
   108
			}
sl@0
   109
		CleanupStack::PushL(parserItem);
sl@0
   110
		result = iParserList.Insert(parserItem, count);
sl@0
   111
		if (result) // We couldn't get it in the main list
sl@0
   112
			User::Leave(result);
sl@0
   113
		CleanupStack::Pop();
sl@0
   114
		}
sl@0
   115
	iNumberInList++;
sl@0
   116
	}
sl@0
   117
sl@0
   118
sl@0
   119
// Activate an individual parser
sl@0
   120
void CParserList::ActivateParserL(MParser* aParser)
sl@0
   121
	{
sl@0
   122
	ActivateAParserL(aParser, EFalse);
sl@0
   123
	}
sl@0
   124
sl@0
   125
sl@0
   126
// N.B. We can't just delete CParserList and zero TLS when we get back
sl@0
   127
// to a list with no specific or default parsers because there could be
sl@0
   128
// an EText left with a local ptr to it.
sl@0
   129
void CParserList::DeactivateParser(MParser* aParser)
sl@0
   130
	{
sl@0
   131
	if (!iNumberInList)
sl@0
   132
	    {
sl@0
   133
	    OstTrace0( TRACE_DUMP, CPARSERLIST_DEACTIVATEPARSER, "EParserNoneActive" );
sl@0
   134
	    }
sl@0
   135
	__ASSERT_DEBUG(iNumberInList, Panic(EParserNoneActive));
sl@0
   136
	if (!aParser)
sl@0
   137
	    {
sl@0
   138
	    OstTrace0( TRACE_DUMP, DUP1_CPARSERLIST_DEACTIVATEPARSER, "EParserNullPtr" );
sl@0
   139
	    }
sl@0
   140
	__ASSERT_DEBUG(aParser, Panic(EParserNullPtr));
sl@0
   141
	// Run thru list till find entry we need
sl@0
   142
	TInt count;
sl@0
   143
	for (count = 0; count < iNumberInList; count++)
sl@0
   144
		{
sl@0
   145
		if (iParserList[count]->Parser() == aParser)
sl@0
   146
			{
sl@0
   147
			delete iParserList[count];
sl@0
   148
			iParserList.Remove(count);
sl@0
   149
			break;
sl@0
   150
			}
sl@0
   151
		}
sl@0
   152
	if (count >= iNumberInList)
sl@0
   153
	    {
sl@0
   154
	    OstTrace0( TRACE_DUMP, DUP2_CPARSERLIST_DEACTIVATEPARSER, "EParserInstanceNotActive" );
sl@0
   155
	     }
sl@0
   156
	__ASSERT_DEBUG((count < iNumberInList), Panic(EParserInstanceNotActive));
sl@0
   157
	iNumberInList--;
sl@0
   158
	}
sl@0
   159
sl@0
   160
sl@0
   161
// Activate a parser as one of the default set
sl@0
   162
void CParserList::ActivateDefaultParserL(MParser* aParser)
sl@0
   163
	{
sl@0
   164
	ActivateAParserL(aParser, ETrue);
sl@0
   165
	}
sl@0
   166
sl@0
   167
sl@0
   168
//++ Put comment here
sl@0
   169
void CParserList::DeactivateParserDefaults()
sl@0
   170
	{
sl@0
   171
	if (iNumberInList)
sl@0
   172
		{
sl@0
   173
		// Take them out of the list
sl@0
   174
		while (iNumberInList && DefaultParser(iParserList[iNumberInList - 1]->TagIndex()))
sl@0
   175
			{
sl@0
   176
			// Tell the parser to free itself
sl@0
   177
			iParserList[iNumberInList - 1]->Parser()->Release();
sl@0
   178
			// Delete the item that refers to it
sl@0
   179
			delete iParserList[iNumberInList - 1];
sl@0
   180
			// Remove the entry from the list
sl@0
   181
			iParserList.Remove(iNumberInList - 1);
sl@0
   182
			iNumberInList--;
sl@0
   183
			}
sl@0
   184
		}
sl@0
   185
	}
sl@0
   186
sl@0
   187
sl@0
   188
// Called by EText to scan an area of text
sl@0
   189
TBool CParserList::ParseThisText(CRichText& aTextObj,TInt aStartScan,TInt aScanLength,TInt& aStartOfTags,TInt& aLength)
sl@0
   190
	{
sl@0
   191
	TBool foundSomething = EFalse;
sl@0
   192
	TCharFormatX format;
sl@0
   193
	TCharFormatXMask varies;
sl@0
   194
	TPtrC ptr;
sl@0
   195
	TInt endRange;
sl@0
   196
sl@0
   197
	// Scan either side of the range in case part of some tagged text was deleted.
sl@0
   198
	if (aStartScan > 0)
sl@0
   199
		{
sl@0
   200
		aStartScan--;
sl@0
   201
		aScanLength++;
sl@0
   202
		}
sl@0
   203
	if (aStartScan + aScanLength < aTextObj.DocumentLength())
sl@0
   204
		aScanLength++;
sl@0
   205
sl@0
   206
	if (iNumberInList && aScanLength)
sl@0
   207
		{
sl@0
   208
		aStartOfTags = aStartScan + aScanLength;
sl@0
   209
		aLength = 0;
sl@0
   210
		for (TInt count = 0; count < iNumberInList; count++)
sl@0
   211
			{
sl@0
   212
			// For each parser in the list
sl@0
   213
			TUint tagIndex = iParserList[count]->TagIndex();
sl@0
   214
			TInt pos;
sl@0
   215
			MParser* parser = iParserList[count]->Parser();
sl@0
   216
			TInt localStartScan = aStartScan;
sl@0
   217
			TInt localScanLength = aScanLength;
sl@0
   218
			// Start by removing existing tags for this parser. This ensures
sl@0
   219
			// that old tags that have been invalidated by subsequent editing
sl@0
   220
			// are removed. Any that are still valid will be replaced.
sl@0
   221
			aTextObj.GetExtendedCharFormat(format, varies, localStartScan, aScanLength);
sl@0
   222
sl@0
   223
			if (format.iParserTag || varies.AttribIsSet(EAttParserTag))
sl@0
   224
				{
sl@0
   225
				// At least some of the object contains a non-zero tag - go through it
sl@0
   226
				// Are we starting part way through a tag?
sl@0
   227
				aTextObj.GetExtendedCharFormat(format, varies, localStartScan, 1);
sl@0
   228
				if (format.iParserTag == tagIndex)
sl@0
   229
					{
sl@0
   230
					// The first char of this range has the current parsers tag
sl@0
   231
					// so we need to check backwards for the start of that tag
sl@0
   232
					for (pos = localStartScan; pos > 0; pos--)
sl@0
   233
						{
sl@0
   234
						aTextObj.GetExtendedCharFormat(format, varies, pos - 1, 1);
sl@0
   235
						if (format.iParserTag != tagIndex)
sl@0
   236
							break;
sl@0
   237
						}
sl@0
   238
					// Since we are going to remove a tag starting from here
sl@0
   239
					// we need to allow this area to be rescanned
sl@0
   240
					localScanLength += localStartScan - pos;
sl@0
   241
					localStartScan = pos;
sl@0
   242
					}
sl@0
   243
				// What about off the end?
sl@0
   244
				aTextObj.GetExtendedCharFormat(format, varies, localStartScan + localScanLength - 1, 1);
sl@0
   245
				if (format.iParserTag == tagIndex)
sl@0
   246
					{
sl@0
   247
					// The last char of this range has the current parsers tag
sl@0
   248
					// so we need to check forwards for the end of that tag
sl@0
   249
					pos = localStartScan + localScanLength;
sl@0
   250
					TInt end = aTextObj.DocumentLength();
sl@0
   251
					while (pos < end)
sl@0
   252
						{
sl@0
   253
						aTextObj.GetTextAndExtendedFormat(ptr, format, pos);
sl@0
   254
						if (format.iParserTag != tagIndex)
sl@0
   255
							break;
sl@0
   256
						pos += ptr.Length();
sl@0
   257
						}
sl@0
   258
					// Adjust scan length
sl@0
   259
					localScanLength = pos - localStartScan;
sl@0
   260
					}
sl@0
   261
				pos = localStartScan;
sl@0
   262
				while (pos < localStartScan + localScanLength)
sl@0
   263
					{
sl@0
   264
					// Run along the scan range
sl@0
   265
					aTextObj.GetTextAndExtendedFormat(ptr, format, pos);
sl@0
   266
					if (format.iParserTag == tagIndex)
sl@0
   267
						{
sl@0
   268
						// Remove this tag
sl@0
   269
						format.iParserTag = 0;
sl@0
   270
						varies.ClearAll();
sl@0
   271
						varies.SetAttrib(EAttParserTag);
sl@0
   272
						TRAPD(leaveCode, aTextObj.ApplyExtendedCharFormatL(format, varies, pos, ptr.Length()));
sl@0
   273
						if (leaveCode==KErrNone)
sl@0
   274
							foundSomething = ETrue;	// We are removing a tag
sl@0
   275
						if (aLength)
sl@0
   276
							{
sl@0
   277
							if (pos < aStartOfTags)
sl@0
   278
								{
sl@0
   279
								aLength += aStartOfTags - pos;
sl@0
   280
								aStartOfTags = pos;
sl@0
   281
								}
sl@0
   282
							if (pos + ptr.Length() > aStartOfTags + aLength)
sl@0
   283
								aLength = pos + ptr.Length() - aStartOfTags;
sl@0
   284
							}
sl@0
   285
						else
sl@0
   286
							{
sl@0
   287
							aStartOfTags = pos;
sl@0
   288
							aLength = ptr.Length();
sl@0
   289
							}
sl@0
   290
						}
sl@0
   291
					pos += ptr.Length();
sl@0
   292
					}
sl@0
   293
				}
sl@0
   294
			endRange = localStartScan + localScanLength;
sl@0
   295
sl@0
   296
			// For this parser, run through text looking for changes
sl@0
   297
			TBool allowBack = ETrue;
sl@0
   298
			for (;;)	// Run forever
sl@0
   299
				{
sl@0
   300
				TInt localStartTag = aTextObj.DocumentLength();
sl@0
   301
				TInt localTagLength = 0;
sl@0
   302
				TInt result = parser->ParseThisText(aTextObj, allowBack, localStartScan, localScanLength, localStartTag, localTagLength);
sl@0
   303
				if (!result)
sl@0
   304
					break;
sl@0
   305
				if (!allowBack && (localStartTag < localStartScan))
sl@0
   306
				    {
sl@0
   307
				    OstTrace0( TRACE_DUMP, CPARSERLIST_PARSETHISTEXT, "EParserIgnoringAllowFlag" );
sl@0
   308
				    }
sl@0
   309
				__ASSERT_DEBUG(allowBack || (localStartTag >= localStartScan), Panic(EParserIgnoringAllowFlag));
sl@0
   310
				TInt startNewTag = localStartTag;
sl@0
   311
				TInt lengthNewTag = localTagLength;
sl@0
   312
				aTextObj.GetExtendedCharFormat(format, varies, localStartTag, localTagLength);
sl@0
   313
				if (format.iParserTag || varies.AttribIsSet(EAttParserTag))
sl@0
   314
					{
sl@0
   315
					// At least some of this area contains a non-zero tag - go through it
sl@0
   316
					pos = localStartTag;
sl@0
   317
					TBool higher = EFalse;
sl@0
   318
					while (pos < localStartTag + localTagLength)
sl@0
   319
						{
sl@0
   320
						aTextObj.GetTextAndExtendedFormat(ptr, format, pos);
sl@0
   321
						if (format.iParserTag && (MaskedTag(format.iParserTag) < MaskedTag(tagIndex)))
sl@0
   322
							{
sl@0
   323
							// A higher precedence tag is already here so we can't
sl@0
   324
							// insert our tag - let's see how far it goes
sl@0
   325
							TUint tag = format.iParserTag;	// Stash tag before overwriting it
sl@0
   326
							TInt len = aTextObj.DocumentLength();
sl@0
   327
							while (pos < len)
sl@0
   328
								{
sl@0
   329
								aTextObj.GetTextAndExtendedFormat(ptr, format, pos);
sl@0
   330
								if (format.iParserTag != tag)
sl@0
   331
									break;
sl@0
   332
								pos += ptr.Length();
sl@0
   333
								}
sl@0
   334
							result = EFalse;
sl@0
   335
							startNewTag = pos;
sl@0
   336
							lengthNewTag = 0;
sl@0
   337
							break;
sl@0
   338
							}
sl@0
   339
						// If there aren't any higher precedence tags in here then this
sl@0
   340
						// will save us having to go through again if there aren't any
sl@0
   341
						// lower precedence tags either
sl@0
   342
						if (MaskedTag(format.iParserTag) >= MaskedTag(tagIndex))
sl@0
   343
							higher = ETrue;
sl@0
   344
						pos += ptr.Length();
sl@0
   345
						}
sl@0
   346
					if (higher)
sl@0
   347
						{
sl@0
   348
						// There are lower or equal precedence tags in this range
sl@0
   349
						// Do they extend back off the start?
sl@0
   350
						aTextObj.GetExtendedCharFormat(format, varies, localStartTag, 1);
sl@0
   351
						if (format.iParserTag)
sl@0
   352
							{
sl@0
   353
							// need to check backwards
sl@0
   354
							TUint tag = format.iParserTag;	// Stash tag before overwriting it
sl@0
   355
							for (pos = localStartTag; pos > 0; pos--)
sl@0
   356
								{
sl@0
   357
								aTextObj.GetExtendedCharFormat(format, varies, pos - 1, 1);
sl@0
   358
								if (format.iParserTag != tag)
sl@0
   359
									break;
sl@0
   360
								}
sl@0
   361
							localTagLength += localStartTag - pos;
sl@0
   362
							localStartTag = pos;
sl@0
   363
							}
sl@0
   364
						// What about off the end?
sl@0
   365
						pos = localStartTag + localTagLength;
sl@0
   366
						aTextObj.GetExtendedCharFormat(format, varies, pos - 1, 1);
sl@0
   367
						if (format.iParserTag)
sl@0
   368
							{
sl@0
   369
							// need to check forwards
sl@0
   370
							TUint tag = format.iParserTag;	// Stash tag before overwriting it
sl@0
   371
							TInt len = aTextObj.DocumentLength();
sl@0
   372
							while (pos < len)
sl@0
   373
								{
sl@0
   374
								aTextObj.GetTextAndExtendedFormat(ptr, format, pos);
sl@0
   375
								if (format.iParserTag != tag)
sl@0
   376
									break;
sl@0
   377
								pos += ptr.Length();
sl@0
   378
								}
sl@0
   379
							localTagLength = pos - localStartTag;
sl@0
   380
							}
sl@0
   381
sl@0
   382
						// Remove all tags in this area - they all have lower precedence
sl@0
   383
						format.iParserTag = 0;
sl@0
   384
						varies.ClearAll();
sl@0
   385
						varies.SetAttrib(EAttCharLanguage);
sl@0
   386
						TRAPD(leaveCode, aTextObj.ApplyExtendedCharFormatL(format, varies, localStartTag, localTagLength));
sl@0
   387
						if (leaveCode==KErrNone)
sl@0
   388
							foundSomething = ETrue;	// We are removing a tag
sl@0
   389
						}
sl@0
   390
					}
sl@0
   391
sl@0
   392
				if (result)
sl@0
   393
					{
sl@0
   394
					// Format tag this area with tagIndex
sl@0
   395
					format.iParserTag = tagIndex;
sl@0
   396
					varies.ClearAll();
sl@0
   397
					varies.SetAttrib(EAttParserTag);
sl@0
   398
					// Use the original length, not the possibly expanded version
sl@0
   399
					TRAPD(leaveCode, aTextObj.ApplyExtendedCharFormatL(format, varies, startNewTag, lengthNewTag));
sl@0
   400
					if (leaveCode==KErrNone)
sl@0
   401
						foundSomething = ETrue;		// We are applying a tag
sl@0
   402
					if (aLength)
sl@0
   403
						{
sl@0
   404
						if (localStartTag < aStartOfTags)
sl@0
   405
							{
sl@0
   406
							aLength += aStartOfTags - localStartTag;
sl@0
   407
							aStartOfTags = localStartTag;
sl@0
   408
							}
sl@0
   409
						if (localStartTag + localTagLength > aStartOfTags + aLength)
sl@0
   410
							aLength = localStartTag + localTagLength - aStartOfTags;
sl@0
   411
						}
sl@0
   412
					else
sl@0
   413
						{
sl@0
   414
						aStartOfTags = localStartTag;
sl@0
   415
						aLength = localTagLength;
sl@0
   416
						}
sl@0
   417
					}
sl@0
   418
				// Jump over
sl@0
   419
				localScanLength -= startNewTag + lengthNewTag - localStartScan;
sl@0
   420
				localStartScan = startNewTag + lengthNewTag;	// Adjust start of next scan run
sl@0
   421
				if (localStartScan >= endRange)	// Have we reached the end of the range yet?
sl@0
   422
					break;
sl@0
   423
				allowBack = EFalse;
sl@0
   424
				}
sl@0
   425
			}
sl@0
   426
		}
sl@0
   427
sl@0
   428
	return foundSomething;
sl@0
   429
	}
sl@0
   430
sl@0
   431
sl@0
   432
// given a tag, fetch a ptr to the parser - or null
sl@0
   433
MParser* CParserList::ParserWithThisTag(const TUint aTagIndex) const
sl@0
   434
	{
sl@0
   435
	MParser* parser = NULL;
sl@0
   436
	for (TInt count = 0; count < iNumberInList; count++)
sl@0
   437
		{
sl@0
   438
		if (aTagIndex == iParserList[count]->TagIndex())
sl@0
   439
			{
sl@0
   440
			parser = iParserList[count]->Parser();
sl@0
   441
			break;
sl@0
   442
			}
sl@0
   443
		}
sl@0
   444
	return parser;
sl@0
   445
	}
sl@0
   446
sl@0
   447
// given a ptr to a parser, fetch a tag - or zero
sl@0
   448
TUint CParserList::TagForThisParser(const MParser *const aParser) const
sl@0
   449
	{
sl@0
   450
	TUint tagIndex = 0;
sl@0
   451
	for (TInt count = 0; count < iNumberInList; count++)
sl@0
   452
		{
sl@0
   453
		if (aParser == iParserList[count]->Parser())
sl@0
   454
			{
sl@0
   455
			tagIndex = iParserList[count]->TagIndex();
sl@0
   456
			break;
sl@0
   457
			}
sl@0
   458
		}
sl@0
   459
	if (!tagIndex)
sl@0
   460
	    {
sl@0
   461
	    OstTrace0( TRACE_DUMP, CPARSERLIST_TAGFORTHISPARSER, "EParserNoSuchTag" );
sl@0
   462
	    }
sl@0
   463
	__ASSERT_DEBUG(tagIndex, Panic(EParserNoSuchTag));
sl@0
   464
	return tagIndex;
sl@0
   465
	}
sl@0
   466
sl@0
   467
sl@0
   468
CParserData::CParserData(TInt aEndParse):
sl@0
   469
	iStartParse(0),
sl@0
   470
	iEndParse(aEndParse)
sl@0
   471
	{
sl@0
   472
	// Get parser data
sl@0
   473
	iActiveParserList = (CParserList*)Dll::Tls();
sl@0
   474
	iLastKnownCursor = -1;
sl@0
   475
	if (iActiveParserList)
sl@0
   476
		iActiveParserList->iRefCount++;
sl@0
   477
	}
sl@0
   478
sl@0
   479
sl@0
   480
CParserData::~CParserData()
sl@0
   481
	{
sl@0
   482
	if (iActiveParserList)
sl@0
   483
		{
sl@0
   484
		iActiveParserList->iRefCount--;
sl@0
   485
		if ((iActiveParserList->iRefCount == 0) && (iActiveParserList->iNumberInList == 0))
sl@0
   486
			{
sl@0
   487
			Dll::FreeTls();
sl@0
   488
			delete iActiveParserList;
sl@0
   489
			}
sl@0
   490
		}
sl@0
   491
	}
sl@0
   492
sl@0
   493
sl@0
   494
// Merge the specified range, which may have changed length, into the current range.
sl@0
   495
// aOldLength is the # of chars deleted and to be removed from the range
sl@0
   496
// aNewLength is the # of chars inserted and to be added to the range
sl@0
   497
void CParserData::MergeRange(TInt aStart,TInt aOldLength,TInt aNewLength)
sl@0
   498
	{
sl@0
   499
	if (iStartParse == -1) // no current range
sl@0
   500
		{
sl@0
   501
		iStartParse = aStart;
sl@0
   502
		iEndParse = aStart + aNewLength;
sl@0
   503
		}
sl@0
   504
	else
sl@0
   505
		{
sl@0
   506
		if (aStart < iStartParse)
sl@0
   507
			iStartParse = aStart;
sl@0
   508
		if (aStart + aOldLength > iEndParse)
sl@0
   509
			iEndParse = aStart + aOldLength;
sl@0
   510
		iEndParse += aNewLength - aOldLength;
sl@0
   511
		}
sl@0
   512
	}