예제 #1
0
/**
 * Function that will look at all the devices on the RConnection
 * and update the device array accordingly.
 */		
TInt CPanConnections::UpdateCurrentConnections()
	{
	TInt rerr = KErrNone;
	HBufC8* buffer=0;
	const TInt KAddrLen = sizeof(TBTDevAddr);

	TRAP(rerr, buffer = HBufC8::NewL(7*KAddrLen));// create a buffer to house the device address
	if(rerr == KErrNone)
		{
		TPtr8 ptr = buffer->Des();
		// use RConnection to enumerate all the devices
		rerr = iConnection.Control(KCOLAgent, KCOAgentPanEnumerateDevices, ptr);
		if(rerr == KErrNone)
			{
			iActiveConnections.Reset();
			while(ptr.Length()>=KBTDevAddrSize)
				{
				// inspect the addr's in the descriptor and append them to the array.
				TBTDevAddr parsedAddr(ptr.Mid(ptr.Length()-KAddrLen, KBTDevAddrSize));
				ptr.SetLength(Max(ptr.Length()-KAddrLen, 0));
				iActiveConnections.Append(parsedAddr);
				}
			}
		}
	delete buffer;
	return rerr;
	}
예제 #2
0
TInt CTlsEncrypt::DecryptAndVerifyL(const TDesC8& aInput,HBufC8*& aOutput,
                                    TInt64& aSeqNumber, TRecordProtocol& aType)
{

    if(!aInput.Length())
        return KErrBadDescriptor;

    TLSPROV_LOG2(_L("Before Decryption...RecordType: %d"),(TInt)aType)

    TLSPROV_LOG_HEX(aInput.Ptr(),aInput.Size() )


    TInt nAlloc = iCryptos.iDecryptor->MaxFinalOutputLength(aInput.Size()) + 24;
    if ( !aOutput || aOutput->Des().MaxLength() < nAlloc )
    {
        delete aOutput;
        aOutput = NULL;
        aOutput = HBufC8::NewL( nAlloc );
    }
    TPtr8 DecOutput = aOutput->Des();
    DecOutput.Zero();

    TRAP_IGNORE(iCryptos.iDecryptor->ProcessFinalL(aInput,DecOutput));

    TUint HashSize = KSetOfTLSCipherSuites[iCipherIndex].iHashSize;

    if(DecOutput.Length() < HashSize)
    {
        return KErrSSLAlertDecryptError;
    }

    //set ptr to MAC
    TPtrC8 ReceivedMac = DecOutput.Mid(DecOutput.Length()-HashSize,HashSize);
    //& set length to trim MAC
    DecOutput.SetLength( DecOutput.Length()-HashSize );

    TBuf8<64> CalculatedMac;

    ComputeMacL(CalculatedMac,DecOutput,ETrue,aSeqNumber,aType);

    TInt err = KErrBadMAC;
    if(ReceivedMac.Compare(CalculatedMac) == 0)
    {
        err = KErrNone;
    }
    else
    {
        TLSPROV_LOG(_L("Decryption: Received MAC error"))
        err =  KErrSSLAlertBadRecordMac;
    }

    TLSPROV_LOG(_L("After Decryption , no mac"))
    TLSPROV_LOG_HEX(aOutput->Ptr(),aOutput->Size() )

    return err;

}
예제 #3
0
TInt RBTBaseband::Enumerate(RBTDevAddrArray& aBTDevAddrArray, TUint aMaxNumber)
	{
	if (!SubSessionHandle())
		{
		return KErrNotReady;
		}

	__ASSERT_DEBUG(aMaxNumber>=1, Panic(EBadArgument));
	if(!aMaxNumber)
		{
		return KErrArgument;
		}
	HBufC8* buffer=0;
	const TInt KAddrLen = sizeof(TBTDevAddr);

	TRAPD(err, buffer = HBufC8::NewL(aMaxNumber*KAddrLen));
	if(err)
		{
		return KErrNoMemory;
		}

	TPtr8 ptr = buffer->Des();
	err = iSocket.GetOpt(EBBEnumeratePhysicalLinks, KSolBtLMProxy, ptr);
	if (err)
		{
		delete buffer;
		return err;
		}

	/**
	Parse the supplied descriptor
	*/
	
	aBTDevAddrArray.Reset();
	while(ptr.Length()>=KBTDevAddrSize)
		{
		TBTDevAddr parsedAddr(ptr.Mid(ptr.Length()-KAddrLen, KBTDevAddrSize));
		ptr.SetLength(Max(ptr.Length()-KAddrLen, 0));
		aBTDevAddrArray.Append(parsedAddr);
		}

	delete buffer;
	return KErrNone;
	}
/**
CountLinesOfHtmlL()
Counts the number of lines of HTML

@param aEntry
A reference to an object representing the email

@return
Number of lines of HTML
*/
TInt CT_MsgComparePopEmailMsgs::CountLinesOfHtmlL(CMsvEntry& aEntry)
	{ 
	TInt lines = 0;
	aEntry.SetEntryL(aEntry.EntryId());
	
	
	CMsvStore* store = aEntry.ReadStoreL();
	CleanupStack::PushL(store);
	
	MMsvAttachmentManager& attManager = store->AttachmentManagerL();
	
	RFile htmlFile = attManager.GetAttachmentFileL(0);
	CleanupClosePushL(htmlFile);
	
	_LIT8(KFindData, "\r\n");
	TInt htmlSize = 0;
	User::LeaveIfError(htmlFile.Size(htmlSize));
	HBufC8* fBuf = HBufC8::NewLC(htmlSize);
	TPtr8 p = fBuf->Des();
	htmlFile.Read(p);
	TInt pos = 0;
	for(;;)
		{
		pos = p.Find(KFindData);
		if(pos < 0)
			{
			break;
			}
		p = p.Mid(pos+2);
		lines++;
		}
		
	CleanupStack::PopAndDestroy(fBuf);
	CleanupStack::PopAndDestroy(); // htmlFile
	CleanupStack::PopAndDestroy(store);
	
	return lines;
	}
예제 #5
0
/*
-----------------------------------------------------------------------
-----------------------------------------------------------------------
*/
void CZipCompressor::AddFileL(const TDesC8& aFileData,const TDesC& aFileName)
{
	if(iDebugFile.SubSessionHandle())
	{	
		iDebugFile.Write(_L8("Add-F, "));
	}
	
	TFileEntry fileEntry;

	HBufC8* out = HBufC8::New( aFileData.Size() + 100);
	if(out)
	{	
		CleanupStack::PushL(out);
		
		if(iDebugFile.SubSessionHandle())
		{	
			iDebugFile.Write(_L8("AF1, "));
		}
	
		TEntry entry;
		iFs.Entry( aFileName, entry ); 

		TPtr8 outPtr = out->Des();

		fileEntry.iVersion 		= 0x000A;
		// we could always make settings to handle different compressions within a file
	    fileEntry.iCompression 	= 0x0008;
		
		TInt ErrNo(KErrNone);
		
		TRAP(ErrNo,CEZCompressor::CompressL( outPtr, aFileData, CEZCompressor::EDefaultCompression ));
		if(ErrNo != KErrNone)
		{
			fileEntry.iCompression 	= 0;
			out->Des().Copy(aFileData);
		}
		
		if(iDebugFile.SubSessionHandle())
		{	
			iDebugFile.Write(_L8("AF2, "));
		}
		
		iFileCounter++;
		
		TParsePtrC NameHelp(aFileName);
		fileEntry.iFileName.Copy(NameHelp.NameAndExt());
		
	    fileEntry.iCompressedSize 	= outPtr.Length() - 6;
	    fileEntry.iUncompressedSize = aFileData.Length();
	 	
	    fileEntry.iRelativeOffset 	= iStream.Sink()->SizeL();
		fileEntry.iAttributes 		= entry.iAtt;
		fileEntry.iDateTime 		= MsDosDateTime( entry.iModified );
		
		if(iDebugFile.SubSessionHandle())
		{	
			iDebugFile.Write(_L8("AF3, "));
		}
		
		iStream.WriteInt32L( 0x04034b50 );				// sign
		iStream.WriteInt16L( fileEntry.iVersion );		// version
		iStream.WriteInt16L( 0x0000 );					// general purpose bit flag
		iStream.WriteInt16L( fileEntry.iCompression );	// compression method
		iStream.WriteInt32L( fileEntry.iDateTime );		// time

		TUint32 crc = crc32(0L, Z_NULL, 0);
		fileEntry.iCrc32 = crc32( crc, aFileData.Ptr(), aFileData.Length() );

		iStream.WriteUint32L( fileEntry.iCrc32 );				// crc
		iStream.WriteInt32L( fileEntry.iCompressedSize );		// compressed size
		iStream.WriteInt32L( fileEntry.iUncompressedSize );		// uncompressed size
		iStream.WriteInt16L( fileEntry.iFileName.Length() );	// filename length
		iStream.WriteInt16L( 0x0000 );							// extra field length

		iStream.WriteL( fileEntry.iFileName );

		iStream.WriteL( outPtr.Mid( 2, outPtr.Length() - 6 ) );

		iFileEntries.Append( fileEntry );

		CleanupStack::PopAndDestroy(out); 
		
		if(iDebugFile.SubSessionHandle())
		{	
			iDebugFile.Write(_L8("AF3, "));
		}
		
		CYBRecognitionResult* Res = new(ELeave)CYBRecognitionResult(); 
		CleanupStack::PushL(Res);
		
		iObserver.GetFileHandler().GetFileUtils().RecognizeData(*Res,aFileData,NameHelp.NameAndExt());
		
		TInt TypeIdNum(iObserver.GetFileHandler().GetFileUtils().GetGeneralFileItem().iTypeId);
		
		if(Res->iIdString)
		{
			TypeIdNum = iObserver.GetFileHandler().GetIconUtils().GetIconIndex(*Res->iIdString);
		}
		
		CleanupStack::PopAndDestroy(Res);
		
		if(iDebugFile.SubSessionHandle())
		{	
			iDebugFile.Write(_L8("AF4, "));
		}
		
		iObserver.AddFileToListL(fileEntry.iCompressedSize,fileEntry.iUncompressedSize,NameHelp.NameAndExt(),TypeIdNum);
	}
	else
	{
		iError = KErrNoMemory;
	}
	
	if(iDebugFile.SubSessionHandle())
	{	
		iDebugFile.Write(_L8("Add-Done, "));
	}
}
예제 #6
0
void CActionSet::PerformAction(TRequestStatus& aStatus)
{
    __UHEAP_MARK;
    TRequestStatus* status = &aStatus;
    iResult = EFalse;
    HBufC8* pkcs12Pwd = 0;

    // default value is NULL to avoid RVCT warning
    // C2874W: set may be used before being set
    CPBEncryptSet* set = 0;
    if (iKdf == 0)
    {
        CleanupStack::PushL(pkcs12Pwd);
        set = CPBEncryptSet::NewLC(*iPasswd, iCipher);
    }
    else
    {
        // if supply KDF, must also supply salt len and iteration count
        ASSERT(iSaltLenBytes != 0 && iIterCount != 0);

        CPBEncryptParms* ep = CPBEncryptParms::NewLC();

        ep->SetCipher(iCipher);

        TInt saltLenBytes;
        TInt r = TLex8(*iSaltLenBytes).Val(saltLenBytes);
        ASSERT(r == KErrNone);
        ep->ResizeSaltL(saltLenBytes);

        TInt iterCount;
        r = TLex8(*iIterCount).Val(iterCount);
        ASSERT(r == KErrNone);
        ep->SetIterations(iterCount);

        CleanupStack::PushL((CBase*)0);
        CleanupStack::Pop((CBase*)0);

        if (*iKdf == _L8("PKCS#5"))
        {
            ep->SetKdf(CPBEncryptParms::EKdfPkcs5);
            set = CPBEncryptSet::NewL(*iPasswd, *ep);
        }
        else if (*iKdf == _L8("PKCS#12"))
        {
            pkcs12Pwd = PKCS12KDF::GeneratePasswordLC(*iPasswd);
            ep->SetKdf(CPBEncryptParms::EKdfPkcs12);
            set = CPBEncryptSet::NewL(*pkcs12Pwd, *ep);
            CleanupStack::Pop(pkcs12Pwd);
        }
        else
            User::Panic(_L("Unrec KDF"), 0);

        CleanupStack::PopAndDestroy(ep);
        // encryption could leak here, but for reservation above
        CleanupStack::PushL(pkcs12Pwd);
        CleanupStack::PushL(set);
    }
    CPBEncryptor* encryptor = set->NewEncryptLC();
    HBufC8* ciphertextTemp = HBufC8::NewLC(encryptor->MaxFinalOutputLength(iInput->Length()));

    TPtr8 ciphertext = ciphertextTemp->Des();
    encryptor->ProcessFinalL(*iInput, ciphertext);
    TBuf<128> newPwdTemp(*iPasswd);
    newPwdTemp.Append('a');

    TBuf8<128> newPwdTemp8;

    TPBPassword newPassword(KNullDesC);
    if (pkcs12Pwd == 0)
        new(&newPassword) TPBPassword(newPwdTemp);
    else
    {
        HBufC8* newPwd = PKCS12KDF::GeneratePasswordLC(newPwdTemp);
        newPwdTemp8.Copy(*newPwd);
        new(&newPassword) TPBPassword(newPwdTemp8);
        CleanupStack::PopAndDestroy(newPwd);
    }

    set->ChangePasswordL(newPassword);

    //create a mem  buffer store
    CBufStore* store = CBufStore::NewLC(100);
    RStoreWriteStream write;

    //write the encrypted master key to a stream
    TStreamId keyStreamId = write.CreateLC(*store);
    write << set->EncryptedMasterKey();
    write.CommitL();
    CleanupStack::PopAndDestroy(); //CreateLC()

    //write the encryption data to another stream
    TStreamId dataStreamId = write.CreateLC(*store);
    set->EncryptionData().ExternalizeL(write);
    write.CommitL();
    CleanupStack::PopAndDestroy(); //CreateLC()

    //prepare to read the streams back in, creating a new TPBEncryptionData
    RStoreReadStream read;
    read.OpenLC(*store, dataStreamId);

    //read in Encryption data
    CPBEncryptionData* data = CPBEncryptionData::NewL(read);
    CleanupStack::PopAndDestroy(); //OpenLC()
    CleanupStack::PushL(data);

    //read in encrypted master key
    read.OpenLC(*store, keyStreamId);
    HBufC8* encryptedMasterKey = HBufC8::NewLC(read, 10000); //some large number

    //create a new set encryption class
    CPBEncryptSet* set2 = CPBEncryptSet::NewLC(*data, *encryptedMasterKey, newPassword);

    HBufC8* plaintextTemp = HBufC8::NewLC(ciphertext.Length());
    TPtr8 plaintext = plaintextTemp->Des();

    CPBDecryptor* decryptor = set2->NewDecryptLC();
    decryptor->Process(ciphertext, plaintext);

    //this Mid call is due to get rid of the decrypted padding at the end
    if(plaintext.Mid(0,iInput->Length()) == *iInput)
    {
        iResult = ETrue;
    }

    CleanupStack::PopAndDestroy(decryptor);
    CleanupStack::PopAndDestroy(plaintextTemp);
    CleanupStack::PopAndDestroy(set2);
    CleanupStack::PopAndDestroy(encryptedMasterKey);
    CleanupStack::PopAndDestroy(1); //OpenLC
    CleanupStack::PopAndDestroy(data);
    CleanupStack::PopAndDestroy(store);
    CleanupStack::PopAndDestroy(ciphertextTemp);
    CleanupStack::PopAndDestroy(encryptor);
    CleanupStack::PopAndDestroy(set);
    CleanupStack::PopAndDestroy(pkcs12Pwd);

    User::RequestComplete(status, KErrNone);
    iActionState = CTestAction::EPostrequisite;
    __UHEAP_MARKEND;
}
/**
@SYMTestCaseID			PDS-SQL-UT-4151
@SYMTestCaseDesc		Measures the performance of inserting multiple records
						into the Music Player MPX database.  This test is based on 
						a real Music Player Harvesting use case
@SYMTestPriority		Medium
@SYMTestActions			Reads SQL transactions from a file and executes them.  
						Records the time for executing each statement
@SYMTestExpectedResults All statements should be executed without error and 
						performance measurements logged
@SYMDEF					DEF142306
*/
void RunTest()
	{
	//Open the file with the sql statements 
	_LIT(KSqlFileName,"z:\\test\\t_sqlperformance4.sql");
	RFile sqlFile;
	TInt err = sqlFile.Open(TheFs, KSqlFileName, EFileRead); 
	TEST2(err, KErrNone);
	
	TInt fileLen = 0;
	err = sqlFile.Size(fileLen); 
	TEST2(err, KErrNone);
	
	HBufC8* sqlBuf = HBufC8::New(fileLen); 
	TEST(sqlBuf != NULL);
	TPtr8 sql = sqlBuf->Des();
	err = sqlFile.Read(sql);
	
	sqlFile.Close();
	TEST2(err, KErrNone);
	TEST2(sql.Length(), fileLen);
	
	//Open main database
	err = TheDbC.Open(TheDbFileName, &TheSqlConfigString);
	TEST2(err, KErrNone);
	
	TheTest.Printf(_L("Beginning INSERTS...\n"));
	
	const TInt KRecordCount = 6544;
	TInt recordCount = 0;
	TInt insertCnt = 0;
	TInt updateCnt = 0;
	TInt selectCnt = 0;
	TInt trnCnt = 0;
	TInt totalTime = 0;

	TInt insertTrnCnt = 0;
	TInt updateTrnCnt = 0;
	TInt selectTrnCnt = 0;
	
	for(;sql.Length()>0;)
		{
		TInt eolPos = sql.Locate(TChar('\n'));
		if(eolPos < 0)
			{
			break;//No more SQL statements
			}
		TInt stmtLength = eolPos;
		while (stmtLength > 0 && (sql[stmtLength-1] == '\r'))
			{
			--stmtLength; //Reduce length to remove carriage return characters from the end of the statement string
			}
		TPtrC8 sqlStmt8(sql.Ptr(), stmtLength);
		TPtrC8 ptr = sql.Mid(eolPos + 1);//"eolPos + 1" - first character after '\n'
		sql.Set(const_cast <TUint8*> (ptr.Ptr()), ptr.Length(), ptr.Length());
		++recordCount;
		
		//Convert to 16 bit query string
		TBuf<1024> query;
		query.Copy(sqlStmt8);
		
		//Execute the statement
		TInt start = User::FastCounter();
		err = TheDbC.Exec(query);
		TInt end = User::FastCounter();
		
		TEST(err >= 0);
		
		//Get the execution time for that statement
		TInt duration = GetDuration(start, end);
		totalTime += duration;
		
		if(query == KBeginTransaction)
			{		
			TheTest.Printf(_L("Execute Statement - BEGIN: %d us\n"), duration);
			}
		
		else if(query == KCommitTransaction)
			{
			++trnCnt;
			TheTest.Printf(_L("Execute Statement - COMMIT: %d us, Trn#%d, \"INSERT\" count: %d, \"UPDATE\" count: %d, \"SELECT\" count: %d\n"), 
					duration, trnCnt, insertTrnCnt, updateTrnCnt, selectTrnCnt);
			insertTrnCnt = updateTrnCnt = selectTrnCnt = 0;
			}

		else
			{	
			TPtrC queryType(query.Ptr(), 6);
			TheTest.Printf(_L("Execute Statement - %S: %d us\n"),&queryType, duration);
			if(queryType.FindF(_L("INSERT")) >= 0)
				{
				++insertCnt;
				++insertTrnCnt;
				}
			else if(queryType.FindF(_L("UPDATE")) >= 0)
				{
				++updateCnt;
				++updateTrnCnt;
				}
			else if(queryType.FindF(_L("SELECT")) >= 0)
				{
				++selectCnt;
				++selectTrnCnt;
				}
			}
		}
	delete sqlBuf;
	
	TheDbC.Close();
	
	TheTest.Printf(_L("Total time to process Songs: %d us\n"), totalTime);
	TheTest.Printf(_L("Transactions count: %d, \"INSERT\" count: %d, \"UPDATE\" count: %d, \"SELECT\" count: %d\n"), 
			               trnCnt, insertCnt, updateCnt, selectCnt);
	TEST2(recordCount, KRecordCount);
	}
예제 #8
0
EXPORT_C TInt CHTTPResponse::LocateField(THttpHeaderField aField,
								TInt aStartIndex) const
    {
	// Content-Type is a special case; it appears to always be at the first
	// byte of the header, and doesn't have any encoding of the field name -
	// just straight into the Field Value at byte 0.  This is an assumption
	// however, since the WSP spec is not explicit - could it possibly be just
	// the NWSS GW's implementation of WSP that does this?
	if ( (aStartIndex == 0) && (aField == EHttpContentType) )
		{
		return aStartIndex; // the content-type field value position - ie. 0
		}
	
	// Deal with other Field Names, (Possibly including Content-Type if the
	// start index is offset into the header? Note that this is not likely to
	// occur though, with the abbreviated encoding.)
	TInt respLength = iResponse->Length();
	TPtr8 respChars  = iResponse->Des();
    for (TInt index = aStartIndex; index < respLength; index++)
        {
		// Examine the byte at this position in the header
        TUint8 byteCode = respChars[index];

		// Expect byteCode to be a Field Name code (unless the search is at
		// position zero, which has a missing content-type field name). Check
		// for the search field, remembering to clear the top bit
        if ( ( (byteCode & 0x7f) == aField) && (index != 0) )
            {
			// Got it - return the next position to locate the field value,
			// checking for potential overrun
			if (index < respLength - 1)
				{
				// Advance 1 to the header field value
				++index;
				return index;
				}
			else
				{
				return KErrNotFound;
				}
            }
        else
            {
			// Check that we aren't dealing with the Content-Type field
			// (expected at position 0), since it doesn't use a field type
			if (index != 0)
				{
				// WSP Spec Section 8.4.1.1 - Field Names
				//
				// If the byte is an alphanumeric, then it must be a field name that doesn't have
				// a WSP encoding.  In this circumstance, we can't handle the field, and must
				// therefore skip over it
				if ((byteCode >= 32) && (byteCode <= 127))
					{
					// Hit the start of a Header Name string - this will be assumed
					// continuous until the NUL is found or until the end
					// of the header is hit (which would be an error)
					while ( (respChars[index] != 0) && (index < respLength - 1) )
						++index;
					}

				// WSP Spec Section 8.4.1.2 - Field Values
				//
				// Now examine the field value by advancing one place.  If that advance takes us off
				// the end of the buffer, then (a) the WSP is invalid, and (b) the field is not found!
				++index;
				if (index == respLength)
					return KErrNotFound;
				}

			// Read the next byte at this position in the header
            byteCode = respChars[index];

			// Codes 0-30 represent that number of following data octets, so
			// they should be skipped
			if (byteCode == 0)			// 0 data octets follow !???? : (Strange but true)
				{
				// __DEBUGGER();
				}
            else if (byteCode <= 30)
				{
                index += byteCode;
				}
            else
                {
				// Code 31 indicates that the following bytes make a UIntVar,
				// which indicates the number of data octets after it. The
				// UIntVar itself could be composed of upto 5 bytes
                if (byteCode == 31)
					{
					// Copy a full 5 bytes from the header - note that actually
					// fewer might have been used; the UIntVar to Int
					// converter function returns the exact number that were
					// used.
					TInt value = 0;
					TInt consumed = ParseUIntVar(respChars.Mid(index + 1), value);
					
					if( consumed < KErrNone )
						return KErrCorrupt;

					// Advance to the last byte of data in this header
                    index += consumed + value;
					}
                else
					// Codes 32-127 are alphanumerics representing a text
					// string, up to a NUL termination
                    if (byteCode <= 127)
						// Hit the start of a string - this will be assumed
						// continuous until the NUL is found or until the end
						// of the header is hit (which would be an error)
                        while ( (respChars[index] != 0) && (index < respLength - 1) )
							++index;
                }
            }
        }

	// This return only occurs if the search ran off the end of the header
    return KErrNotFound;
    }
예제 #9
0
EXPORT_C TBool CHTTPResponse::CharSet(TPtrC8& aDesc) const
    {
//	__LOG_ENTER(_L("CHTTPResponse::CharSet"));
	// Find the byte index in the header for the content type value
    TInt index = LocateField(EHttpContentType);

    TUint8 byteCode = 0;
	TInt paramByteCode = KErrNotFound;
	TInt valueByteCode1 = KErrNotFound;
	TInt charsetCode = 0;
	// Read the byte code, unless KErrNotFound was returned
	if (index != KErrNotFound)
		{
		TPtr8 respChars = iResponse->Des();
		TInt respLength = iResponse->Length();

		// If the byteCode is in the range 0-30 then a range of bytes is
		// indicated: the following byte gives the content type and the
		// remainder are arranged as a series of parameter attribute-value
		// pairs. This method checks for the presence of a 'charset' parameter.
		byteCode = respChars[index];
//		__LOG1(_L("CHTTPResponse::CharSet : found bytecode = %d"), byteCode);

		// Check valid range ... note that a range of zero could not contain a charset
		// parameter anyway, so exclude it...
		if ((byteCode > 0) && (byteCode <= 30))
			{
			// Check for overrun... if this occurs it should be an error.  Note that
			// corruption _could_ occur in this response buffer - some gateways, which
			// don't return error decks (e.g. AnyTime GW) send a response buffer 1 byte
			// long, containing only the value 0x01 - which is invalid WSP.
			// Be conservative and safe here - we can't overrun.  Use the value of byte-
			// -Code (which should be the WSP encoding of how many bytes follow), or the
			// total length of the response - whichever is smaller.
			if (index + byteCode < respLength)
				{
				// e,g, header to illustrate use of offsets in this code:
				// 03 94 81 84 : Content-Type: application/vnd.wap.wmlc; charset=iso-8859-1
				// +0 +1 +2 +3 : 03 = no. bytes in Content-Type header
				//			   : 94 = 14 | 80 = application/vnd.wap.wmlc
				//			   : 81 = 01 | 80 = Charset parameter
				//			   : 84 = 04 | 80 = iso-8859-1
				paramByteCode = respChars[index + 2];

				if ((paramByteCode & 0x7f) == EHttpCharset)
					{
					// We have a charset
					paramByteCode &= 0x7f;
					valueByteCode1 = respChars[index + 3];

					if (valueByteCode1 & 0x80)
						{
						// A short one-byte value
						charsetCode = valueByteCode1 & 0x7f;
						}
					else
						{
						// A multibyte value
						ExtractMultiOctetInteger(charsetCode, 
												 respChars.Mid(index + 3));
						}
					}
				}
			else
				{
				index = KErrNotFound;
				}
			}
		}

	// If a parameter-value pair was found, determine whether it encodes a
	// charset
	if ( (index != KErrNotFound) && (paramByteCode == EHttpCharset) )
		{
		// Look up the value from the charset table.
		const TText8* chset;
		chset = CharSet(charsetCode);

		// Convert the charset string to the supplied descriptor
		if (chset)
			aDesc.Set(TPtrC8(chset));
		else
			index = KErrNotFound; // We've found a charset but we don't recognise it
		}
	else	// Either no content-type header (hence no charset) or a content-type
			// header with a parameter other than charset
		{
		index = KErrNotFound;
		}

//	__LOG1(_L("CHTTPResponse::CharSet : CharSet = %S"), &aDesc);
//	__LOG_RETURN;
	return (index !=KErrNotFound);
    }