/*
 * Generates a hash value by reversing the matchLength least significant digits,
 * ignoring non-digits and zeroes at the end of the number.  Returns error if no phone
 * digits are supplied.

 * \param phoneNumberString A descriptor containing a phone number.
 * \param matchLength The number of digits from the right of the phone number to use.
 * \param numPhoneDigits The number of digits found in the phone number string.
 * \param error Qt error code.*
 * \return An integer representation of the phone number string in reverse.
 */
TInt32 CntFilterDetail::TMatch::createHash(
                                    const TDesC& phoneNumberString, 
                                    TInt matchLength, 
                                    TInt& numPhoneDigits)
{
    TInt phoneNumberLength = phoneNumberString.Length();
    TInt startIndex = 0;
    if (phoneNumberLength > matchLength) {
        startIndex = phoneNumberLength - matchLength;
    }
    
    numPhoneDigits = 0;
    TUint reversedDigits = 0;
    TInt mult = 1;
    
    for (TInt chrIndex = startIndex; (numPhoneDigits < matchLength) && (chrIndex < phoneNumberLength); chrIndex++) {
        TChar chr = phoneNumberString[chrIndex];
        if (chr.IsDigit()) {
            reversedDigits += (chr.GetNumericValue()) * mult;
            mult = mult * 10;
            ++numPhoneDigits;
        }
    }
    return reversedDigits ;
}
/**
Generates a hash value by reversing the aMatchLength least significant digits,
ignoring non-digits and zeroes at the end of the number.  Asserts if no phone
digits are supplied.

@param aPhoneNumberString A descriptor containing a phone number.
@param aMatchLength The number of digits from the right of the phone number to use.
@param aNumPhoneDigits The number of digits found in the phone number string.

@return An integer representation of the phone number string in reverse.
*/
TInt32 CPplCommAddrTable::TMatch::CreateHashL(const TDesC& aPhoneNumberString, TInt aMatchLength, TInt& aNumPhoneDigits)
	{
	TInt phoneNumberLength = aPhoneNumberString.Length();
	__ASSERT_DEBUG(phoneNumberLength > 0, User::Leave(KErrNotSupported) );

	TInt startIndex = 0;

	if (phoneNumberLength > aMatchLength)
		{
		startIndex = phoneNumberLength - aMatchLength;
		}

	aNumPhoneDigits = 0;
	TUint reversedDigits = 0;
	TInt mult = 1;

	for (TInt chrIndex = startIndex; (aNumPhoneDigits < aMatchLength) && (chrIndex < phoneNumberLength); chrIndex++)
		{
		TChar chr = aPhoneNumberString[chrIndex];
		if (chr.IsDigit() )
			{
			reversedDigits += (chr.GetNumericValue() ) * mult;
			mult = mult * 10;
			++aNumPhoneDigits;
			}
		}

	return reversedDigits ;
	}
void CntFilterDetail::TMatch::stripOutNonDigitChars(TDes& text)
{
    for (TInt chrPos = 0; chrPos < text.Length(); ++chrPos) {
        TChar chr = text[chrPos];
        if (!chr.IsDigit()) {
            text.Delete(chrPos, 1);
            --chrPos;
        }
    }
}
/**
Strip out any non-digit characters before we convert the phone number to an
integer.

@param aText Phone number which on return will have any non-digit characters
removed.
*/
void CPplCommAddrTable::TMatch::StripOutNonDigitChars(TDes& aText)
	{
	for(TInt chrPos = 0; chrPos < aText.Length(); ++chrPos)
		{
		TChar chr = aText[chrPos];
		if (!chr.IsDigit() )
			{
			aText.Delete(chrPos, 1);
			--chrPos;
			}
		}
	}
Exemple #5
0
// -----------------------------------------------------------------------------
// SdpUtil::IsTokenChar
// Checks if the character is a valid token character
// -----------------------------------------------------------------------------
//
TBool SdpUtil::IsTokenChar( 
    TChar aChar )
	{
    return ( ( aChar == '!')||
	         ( aChar >= '#' && aChar <= '\'' ) ||
	         ( aChar == '*' || aChar == '+' ) ||
	         ( aChar == '-' || aChar == '.' ) ||
	         ( aChar.IsDigit() ) ||
	         ( aChar >= 'a' && aChar <= 'z' ) ||
	         ( aChar >= 'A' && aChar <= 'Z' ) ||
	         ( aChar >= '^' && aChar <= '~' ) );	
	}
/**
Initialize the counter with the numeric equivalent of the descriptor contents
This function is here to demonstrate reading from the client address space.
Note that in this example, the client and the server are part of the same process,
*/
void CCountServSession::SetFromStringL(const RMessage2& aMessage)
	{
	
	  // length of passed descriptor (1st parameter passed from client)
	TInt deslen = aMessage.GetDesLength(0);
	
	  // Passed data will be saved in this descriptor.
    RBuf buffer;
      
      // Max length set to the value of "deslen", but current length is zero
    buffer.CreateL(deslen);
      
      // Do the right cleanup if anything subsequently goes wrong
    buffer.CleanupClosePushL();
    
      // Copy the client's descriptor data into our buffer.
    aMessage.ReadL(0,buffer,0);
    
      // Now do a validation to make sure that the string only has digits
    if (buffer.Length() == 0)
        {
    	User::Leave(ENonNumericString);
        }
    
    TLex16 lexer;
    
    lexer.Assign(buffer);
    while (!lexer.Eos())
        {
        TChar thechar;
        
        thechar = lexer.Peek();
        if (!thechar.IsDigit())
            {
        	User::Leave(ENonNumericString);
            }
        lexer.Inc();
        }
       
      // Convert to a simple TInt value. 
    lexer.Assign(buffer);           
    if (lexer.Val(iCount))
        {
    	User::Leave(ENonNumericString);
        }
    	
	  // Clean up the memory acquired by the RBuf variable "buffer"
	CleanupStack::PopAndDestroy();
	}
// ---------------------------------------------------------------------------
// CMceIceErrorTrigger::ParseErrorCode
// ---------------------------------------------------------------------------
//
TInt CMceIceErrorTrigger::ParseErrorCode() const
	{
	TInt errorCode( 0 );
	TLex8 lex( Value() );

	TChar ch = lex.Peek();
	while ( !ch.IsDigit() && ch != '-' && !ch.Eos() )
		{
		lex.Get();
		ch = lex.Peek();
		}

	if ( ch.Eos() )
		{
		errorCode = KErrNotFound;
		}
	else
		{
		lex.Val( errorCode );
		}
	RDebug::Print( _L("ICEPlugin Dummy: ParseErrorCode=%d" ), errorCode );
	return errorCode;
	}
// Process the received buffer, creating atoms as we go
void CImapIO::ProcessBufferL()
	{
	// Process the buffer
	TChar byte;

	DBG((LogText(_L8("CImapIO::ProcessBuffer(iParserState=%d, Length=%d)"),iParserState,iReceive.Length())));

	for(TInt pos=0;pos<iReceive.Length();pos++)
		{
		// Note that we've processed stuff
		iBytesRead++;

		// Byte to process
		byte=iReceive[pos];

		switch(iParserState)
			{
		case EIOStateAtomWait:
			switch(byte)
				{
			case '(':
			case '[':
			case '<':
				{
				// Make a new current atom
				CImapAtom *newAtom=new (ELeave) CImapAtom();

				iAtomArray.AppendL(newAtom);
				// Add it as a sibling to the current atom
				if (iNextIsChild)
					iAtom->AddChild(newAtom);
				else
					iAtom->AddNext(newAtom);

				// The next item should be a child
				iNextIsChild=ETrue;

				// Push current atom onto atom stack, make new current
				iAtom=newAtom;
				PushL(iAtom);

				// Store the open bracket in the buffer, so we can tell what it is
				TPtrC8 bufptr(iBuffer->Ptr()+iBuffer->Length(),1);
				BufferAppendL(byte);
				iAtom->Set(bufptr);

				break;
				}

			case ')':
			case ']':
				// End of this nesting level: pop last atom off stack and
				// make it the new current one
				iAtom=PopL();

				// Any new atoms will be siblings, not children
				iNextIsChild=EFalse;

				break;

			case '{':
				// Start of a literal length
				iLiteralLength=0;
				iParserState=EIOStateLiteralLength;
				break;

			case ' ':
				// Whitespace. Ignore! This state only happens with whitespace
				// after a close )] or a endquote "
				break;

			case '\r':
				// Newline after a close )] or endquote "
				iParserState=EIOStateWaitLF;
				break;

			case '\"':
				// Quotes: we don't keep them, so the atom starts at the next
				// character.
				iAtomStart=iBuffer->Length();
				iParserState=EIOStateInAtom;
				iParserQuoted=ETrue;
				iGotEscape=EFalse;
				break;

			default:
				// Start new atom in buffer
				iAtomStart=iBuffer->Length();
				BufferAppendL(byte);
				iParserState=EIOStateInAtom;
				iParserQuoted=EFalse;
				break;
				}
			break;

		case EIOStateInAtom:
			if (iParserQuoted)
				{
				// Look for another quote
				if (byte=='\"')
					{
					// Just had an escape character?
					if (iGotEscape)
						{
						// Add the character
						BufferAppendL(byte);
						iGotEscape=EFalse;
						}
					else
						{
						// It's the terminator: Add the atom, minus the quotes
						AddAtomL();
						iParserState=EIOStateAtomWait;
						}
					}
				// fix for INC51597 and DEF053082:if a " has been missed out by the server, this will end the atom at a \r
				else if(!iGotEscape && byte == '\r')
					{
					AddAtomL();
					iParserState = EIOStateWaitLF;
					}
				else
					{
					// Escape character?
					if (!iGotEscape && byte=='\\')
						{
						// Got one
						iGotEscape=ETrue;
						}
					else
						{
						// Add to buffer
						BufferAppendL(byte);
						iGotEscape=EFalse;
						}
					}
				}
			else
				{
				if (byte==' ' || byte=='\r')
					{
					AddAtomL();
				
					// Either go back to looking for an atom, or a LF
					iParserState=(byte=='\r')?EIOStateWaitLF:EIOStateAtomWait;
					}
				else if (byte=='(' || byte=='[')
					{
					// Add this atom
					AddAtomL();

					// Make a new current atom
					CImapAtom *newAtom=new (ELeave) CImapAtom();
					iAtomArray.AppendL(newAtom);

					// Add it as a sibling to the current atom
					if (iNextIsChild)
						iAtom->AddChild(newAtom);
					else
						iAtom->AddNext(newAtom);

					// The next item should be a child
					iNextIsChild=ETrue;

					// Push current atom onto atom stack, make new current
					iAtom=newAtom;
					PushL(iAtom);

					// Store the open bracket in the buffer, so we can tell what it is
					TPtrC8 bufptr(iBuffer->Ptr()+iBuffer->Length(),1);
					BufferAppendL(byte);
					iAtom->Set(bufptr);

					iParserState=EIOStateAtomWait;
					}
				else if (byte==')' || byte==']' || byte == '>')
					{
					// Although these bytes usually indicate the end of an atom,
					// they can also legitimately appear in a text field.
					// If this is the end of an atom, then it must be a child or
					// sibling atom in which case there will be an entry on the atom
					// stack. If there is no entry on the atom stack, then this must
					// be a text field so just add the byte to the buffer.
					if (iAtomStack.Count() > 0)
						{
						// Add this atom
						AddAtomL();

						// End of this nesting level: pop last atom off stack and
						// make it the new current one
						iAtom=PopL();

						// Any new atoms will be siblings, not children
						iNextIsChild=EFalse;

						iParserState=EIOStateAtomWait;
						}
					else
						{
						BufferAppendL(byte);
						}
					}
				else
					{
					// Add to buffer
					BufferAppendL(byte);
					}
				}
			break;

		case EIOStateWaitLF:
			// After LF, this is end of line, finish!
			if (byte=='\n')
				{
				// Remove everything from the buffer, we've finished
				iReceive.Delete(0,pos+1);

				// Reset bytes read count & complete
				iBytesRead=0;

				// Complete with KErrFoundEOL
				DBG((LogText(_L8("CImapIO::ProcessBuffer: Complete in EIOStateWaitLF"))));
				Complete(KErrFoundEOL);
				return;
				}
			break;

		case EIOStateLiteralLength:
			// Digit?
			if (byte.IsDigit())
				{
				// Add it to the total
				iLiteralLength=(iLiteralLength*10)+(byte-(TChar)'0');
				if (iLiteralLength <0)
					User::Leave(KErrCorrupt);
				}
			else if (byte=='}')
				{
				// Need to skip CR, LF
				iLiteralSkip=2;
				iParserState=EIOStateLiteralSkip;

				// Add the atom (with the length we know, but no data) to the
				// structure now, so that the partial structure can be parsed.
				iAtomStart=iBuffer->Length();
				AddAtomL(iLiteralLength);
				}
			break;

		case EIOStateLiteralSkip:
			// Skipping...
			if (--iLiteralSkip==0)
				{
				// Is literal 0 bytes long?
				if (iLiteralLength==0)
					{
					// Nothing to follow
					iParserState=EIOStateAtomWait;
					}
				else
					{
					// Non-empty literal: go into fetch state
					iParserState=EIOStateLiteralFetch;
					}
				}
			break;

		case EIOStateLiteralFetch:
			// Fetching
			
			TInt fetchLength(0);
			if(KReceiveBuffer<iLiteralLength)
				{
				fetchLength = KReceiveBuffer;
				}
			else
				{
				fetchLength = iLiteralLength;
				}
			
			if(fetchLength > iReceive.Length()-pos)
				{
				fetchLength = iReceive.Length()-pos;
				}
// 			need to extend buffer ?
			DBG((LogText(_L8(">>> CImapIO::ProcessBufferL(1):buflen=%d:buffsize=%d:litlen=%d:fetchlen=%d"), iBuffer->Length(),iBufferSize, iLiteralLength,fetchLength)));
			if (iBuffer->Length() + iLiteralLength > iBufferSize)
				{
				HBufC8 *oldbuffer=iBuffer;
				const TText8 *oldbufptr=iBuffer->Ptr();
			
				// Extend by extra amount + round up by KIOBufferGranularity
				iBufferSize += iLiteralLength;
				iBufferSize += (KIOBufferGranularity - (iBufferSize % KIOBufferGranularity));
				iBuffer=iBuffer->ReAllocL(iBufferSize);

				// Buffer moved?
				if (iBuffer!=oldbuffer)
					{
					// Fixup buffer tree pointers
					iRootAtom->FixupL(iBuffer,oldbufptr);
					}
				DBG((LogText(_L8(">>> CImapIO::ProcessBufferL(2):buflen=%d:buffsize=%d:litlen=%d:fetchlen=%d"), iBuffer->Length(),iBufferSize, iLiteralLength,fetchLength)));
				}
			iBuffer->Des().Append(iReceive.Mid(pos,fetchLength));
			// adjust loop to account for data copy
			pos+=fetchLength-1;
			iLiteralLength-=fetchLength; 			
			DBG((LogText(_L8(">>> CImapIO::ProcessBufferL(3):buflen=%d:buffsize=%d:litlen=%d:fetchlen=%d"), iBuffer->Length(),iBufferSize, iLiteralLength,fetchLength)));
			if (iLiteralLength==0)
				{
				// Atom is already saved (we add literal atoms before they
				// are stored)
				iParserState=EIOStateAtomWait;
				}
			break;
			}
		}
	
	iReceive.Zero();
	// At start of line, or if we're not doing a partial return, we need to
	// queue another read here
	if (iBytesRead==0 || !iReturnPartialLine)
		{
		// We've processed this buffer: queue a read. We only complete (above)
		// when we've had a whole reply, including terminating CRLF.
		DBG((LogText(_L8("CImapIO::ProcessBufferL(): queuing read, iBytesRead=%d, iReturnPartialLine is %d"), iBytesRead, iReturnPartialLine)));
                QueueRead();
		}
	else
		{
		// Have we got 'enough' of the partial line?
		if (iBytesRead<iBytesToRead)
			{
			// Not enough yet: queue another partial read, for the remainder
			iBytesToRead-=iBytesRead;
			QueueRead();
			}
		else
			{
			// Partial line parsed: return success (client will requeue)
			DBG((LogText(_L8("CImapIO::ProcessBuffer: Complete on partial line"))));
			Complete(KErrNone);
			}
		}
	}
/**
 * Extracts the real phone number from a contacts phone number field.
 * This method strips away any DTMF strings or extended services. An empty
 * descriptor is returned in aRawNumber if the field doesn't have a valid phone
 * number.
 *
 * @param aTextualNumber Descriptor containing a contacts model phone number field
 * @param aRawNumber Descriptor to write the raw number to (loaned by caller)
 */
void CContactDefaultPhoneNumberParser::ExtractRawNumber(const TDesC& aTextualNumber, TDes& aRawNumber)
{
    aRawNumber.Zero();

    TInt length = aTextualNumber.Length();
    if (length==0)
    {
        return;
    }


    TPtrC numberPtr( aTextualNumber );
    TUint firstChar = numberPtr[0];

    //gobble spaces
    while (TChar(firstChar).IsSpace())
    {
        --length;
        if (length==0)
        {
            return;
        }

        numberPtr.Set(numberPtr.Right(length));
        firstChar = numberPtr[0];
    }

    // Get left hand side
    if ( firstChar == KSymbolAsterisk || firstChar == KSymbolHash )
    {
        //Check if there is plus on first five chars:
        TInt newStartPlace = numberPtr.Locate( KSymbolPlus );
        if ( newStartPlace>=KPlusWithinChars || newStartPlace==KErrNotFound )
        {
            // There is always star or hash...
            newStartPlace = Max( numberPtr.LocateReverse(KSymbolAsterisk ) ,numberPtr.LocateReverse( KSymbolHash) );
        }

        length = length - newStartPlace -1;
        if ( length <= 0 )
        {
            return;
        }
        numberPtr.Set( numberPtr.Right( length ) );
        firstChar = numberPtr[0];
    }

    //test condition to satisfy the removal of '(' the next if
    //statement removes the '+' if needed
    if ( firstChar == KSymbolOpenBrace )
    {
        length--;
        numberPtr.Set( numberPtr.Right( length ) );
        // This may be the only character in the descriptor so only access if
        // 1 or more characters left.
        if (length > 0 )
        {
            firstChar = numberPtr[0];
        }
    }

    if ( firstChar == KSymbolPlus )
    {
        length--;
        numberPtr.Set( numberPtr.Right( length ) );
    }

    if (length==0)
    {
        return;
    }

    // Find right hand side
    TLex numberLexer( numberPtr );
    for ( ; ; )
    {
        TChar nextChar = numberLexer.Peek();
        if ( !nextChar )
        {
            break;
        }

        if ( nextChar.IsDigit() )
        {
            aRawNumber.Append( nextChar );
            numberLexer.Inc();
        }
        else if ( nextChar == KSymbolAsterisk || nextChar == KSymbolHash )
        {
            aRawNumber.Zero();
            return;
        }
        else
        {
            nextChar.LowerCase();
            if ( nextChar == KSymbolPause
                    || nextChar == KSymbolWait
                    || nextChar == KSymbolPlus)
            {
                break;
            }
            numberLexer.Inc();
        }
    }
}
void CActiveConsole::ProcessKeyPressL(TChar aChar)
	{
	if (aChar == EKeyEscape)
		{
		PRINT(_L("CActiveConsole: ESC key pressed -> stopping active scheduler...\n"));
		CActiveScheduler::Stop();
		return;
		}
	aChar.UpperCase();
	if (iCmdGetValue != 0 && aChar == '\r')
		{
		if (iLastChar == 'K')
			{
			iValue *= iGetHexValue ? 0x400 : 1000;
			}
		if (iLastChar == 'M')
			{
			iValue *= iGetHexValue ? 0x10000 : 1000000;
			}
		PRINT1(_L("CActiveConsole: Value %d\n"),iValue);
		ProcessValue();
		}
	if (iCmdGetValue != 0 )
		{
		if (iGetHexValue)
			{
			if (aChar.IsDigit())
				{
				iValue = iValue * 16 + aChar.GetNumericValue();
			}
			else
				{
				if (aChar.IsHexDigit())
					{
					iValue = iValue * 16 + (TUint)aChar - 'A' + 10;
					}
				else
					{
						if (aChar != 'K' && aChar != 'M')
						{
						PRINT(_L("Illegal hexadecimal character - Enter command\n"));
						iCmdGetValue = 0;
						}
					}
				}
			}
		else
			{
			if (aChar.IsDigit())
				{
				iValue = iValue * 10 + aChar.GetNumericValue();
				}
			else
				{
				if ((aChar == 'X') && (iLastChar == '0') && (iValue == 0))
					iGetHexValue = ETrue;
				else
					{
					if (aChar != 'K' && aChar != 'M')
						{
						test.Printf(_L("Illegal decimal character - Enter command\n"));
						iCmdGetValue = 0;							
						}
					}
				}
			}
		}
	else
		{
		switch (aChar)
			{
			case 'F' :
				TESTNEXT(_L("Flushing Cache"));
				test_KErrNone(DPTest::FlushCache());
				ShowMemoryUse();
				iPrompt = ETrue;
				break;
				
			case 'I' :
				CacheSize(0,0);
				ShowMemoryUse();
				iPrompt = ETrue;
				break;
	
			case 'Q' :
				gQuiet = ETrue;
				iPrompt = ETrue;
				break;

			case 'V' :
				gQuiet = EFalse;
				iPrompt = ETrue;
				break;
				
			case '?' :
				ShowHelp();
				break;

			case '=' :
				iCmdGetValue = iLastChar;
				iGetHexValue = EFalse;
				iValue = 0;
				break;
						
			default :
				if (aChar.IsDigit())
					{
					if (iLastChar == 'R')
						{
						if (aChar.GetNumericValue() < (TInt)gNextChunk)
							{
							ReadChunk (&gChunk[aChar.GetNumericValue()]);			
							}
						else
							{
							for (TUint i = 0; i < gNextChunk; i++)
								ReadChunk (&gChunk[i]);			
							}
						iPrompt = ETrue;
						}				
					if (iLastChar == 'W')
						{
						if (aChar.GetNumericValue() < (TInt)gNextChunk)
							{
							WriteChunk (&gChunk[aChar.GetNumericValue()]);			
							}
						else
							{
							for (TUint i = 0; i < gNextChunk; i++)
								WriteChunk (&gChunk[i]);			
							}
						iPrompt = ETrue;
						}
					if (iLastChar == 'M')
						{
						if (aChar.GetNumericValue() == 0)
							{
							iActions = (TUint16)(iPeriod < KFlushQuietLimit ? EFlushQuiet : EFlush);							
							}
						else
							{
							iActions = (TUint16)(aChar.GetNumericValue() << 4);							
							}
						iPrompt = ETrue;
						}
					}
				break;
			}
		}
	iLastChar = aChar;
	GetCharacter();
	return;
	}
Exemple #11
0
EXPORT_C CSTBencode* CSTBencode::ParseL(const TDesC8& aBuffer)
{
	TBencodeParserState parserState = EParsingInProgress;	
	TLex8 lex(aBuffer);	
	TChar c;
	TBool itemParsed = EFalse; 	// state flag, used to indicate that a bencoded 
								// item has been parsed
								
	//TBool keyOnStack = EFalse; // used to indicate that there is a dictionary entry key on the stack
								
	CSTSimpleStack<CSTBencode>* parserStack = 
		new (ELeave) CSTSimpleStack<CSTBencode>;
	CleanupStack::PushL(parserStack);
	
	while (	(c = lex.Peek()) && 
			(parserState == EParsingInProgress))
	{		
		// bencoded string		
		if (c.IsDigit())
		{
			TInt stringLength = 0;
			if ((lex.Val(stringLength) == KErrNone) && (stringLength >= 0))
			{
				while (c && (c != ':'))				
					c = lex.Get();
					
				if (!c || ((lex.Offset() + stringLength) > aBuffer.Length()))
				{
					parserState = EParsingFailed;
					continue;
				}
								
				lex.Mark();
				lex.Inc(stringLength);
				
				CSTBencodedString* string = CSTBencodedString::NewLC(lex.MarkedToken());
				parserStack->PushL(string);
				CleanupStack::Pop();							
				
				c = lex.Peek();
				
				itemParsed = ETrue;
			}
			else
			{							
				parserState = EParsingFailed;			
				continue;
			}
		}
		else
		
		// bencoded integer
		if (c == 'i')
		{
			lex.Inc();
			
			TInt64 value = 0;
			if (lex.Val(value) == KErrNone)
			{
				c = lex.Peek();
				
				while (c && (c != 'e'))
				{
					lex.Inc();
					c = lex.Peek();					
				}
				
				if (c == 'e')
				{
					
					CSTBencodedInteger* bencodedInteger = 
						new (ELeave) CSTBencodedInteger(value);
					
					CleanupStack::PushL(bencodedInteger);
					parserStack->PushL(bencodedInteger);
					CleanupStack::Pop(); // bencodedInteger
				}					
				
			}
			else
			{							
				parserState = EParsingFailed;			
				continue;
			}
			
		}
		else
		
		// bencoded list
		if (c == 'l')
		{
			lex.Inc();
			
			CSTBencodedList* bencodedList = 
				new (ELeave) CSTBencodedList;
			CleanupStack::PushL(bencodedList);
			parserStack->PushL(bencodedList);
			CleanupStack::Pop(); // bencodedList
		}
		else
		
		// bencoded dictionary
		if (c == 'd')
		{
			lex.Inc();
			
			CSTBencodedDictionary* bencodedDictionary = 
				new (ELeave) CSTBencodedDictionary;
			CleanupStack::PushL(bencodedDictionary);
			parserStack->PushL(bencodedDictionary);
			CleanupStack::Pop(); // bencodedDictionary			
		}
		else
		
		// end of bencoded integer/list/dictionary
		if (c == 'e')
		{
			lex.Inc();
			itemParsed = ETrue;			
		}
		else
			parserState = EParsingFailed;
		
		if (itemParsed)
		{
			itemParsed = EFalse;
			
			if (parserStack->Count() == 1)
				parserState = EParsingSucceeded;
			else
			{
				switch (parserStack->FromTop(1)->Type())
				{
					case EBencodedList:
					{
						CSTBencode* item = parserStack->Pop();
						CleanupStack::PushL(item);
						static_cast<CSTBencodedList*>(parserStack->Top())->AppendL(item);
						CleanupStack::Pop(); // item						
					}
					break;
					
					case EBencodedString:
					{
						if (parserStack->FromTop(2)->Type() == EBencodedDictionary)
						{
							CSTBencode* value = parserStack->Pop();
							CSTBencodedString* key = 
								static_cast<CSTBencodedString*>(parserStack->Pop());
						
							CleanupStack::PushL(value);
							CleanupStack::PushL(key);
						
							static_cast<CSTBencodedDictionary*>(parserStack->Top())->AddEntryL(key, value);
						
							CleanupStack::Pop(); // key
							CleanupStack::Pop(); // value							
						}
						else
							parserState = EParsingFailed;												
					}
					break;
					
					case EBencodedDictionary:
						break;
						
					default:
					{
						parserState = EParsingFailed;												
					}
					break;									
				}
			}
		} // if (itemparsed)
	} // while
	
	CSTBencode* parsedItem = NULL;
	if (parserState == EParsingSucceeded)
		parsedItem = parserStack->Pop();		
	
	CleanupStack::PopAndDestroy(); // parserStack
	
	return parsedItem;
}