diff -r 6edeef394eb7 -r 9397a16b6eb8 testexecmdw/tef/inifileparser/src/iniparser.cpp --- a/testexecmdw/tef/inifileparser/src/iniparser.cpp Fri Sep 03 07:55:01 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,688 +0,0 @@ -/* -* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* CINIDATA.CPP -* -*/ - - - -#include -#include "iniparser.h" - -// Default directory to look for INI file -_LIT(KIniFileDir,"\\System\\Data\\"); -_LIT(KIniSysDrive, "${SYSDRIVE}"); -_LIT(KLegacySysDrive, "C:"); - -// Constant Value changed for defect047130 fix -const TInt KTokenSize=256; - -enum TIniPanic - { - ESectionNameTooBig, - EKeyNameTooBig, - }; - -#ifndef EKA2 -//////////////////////////////////////////////////////////////////////////////// -// -// DLL entry point -// -GLDEF_C TInt E32Dll(TDllReason /*aReason*/) - - { - return (KErrNone); - } -#endif - -//////////////////////////////////////////////////////////////////////////////// -void Panic(TIniPanic aPanic) - { - _LIT(CIniData,"CIniData"); - User::Panic(CIniData,aPanic); - } - -/** - * Updates ${SYSDRIVE} variables in the ini file buffer - * To the system drive set during object constrcution - */ -void CIniData::UpdateVariablesL() - { - if (iIniData != NULL) - { - //prevent re-allocating to copy the same data again - TPtr temp(iIniData->Des()) ; - if(iPtr.Compare(temp) != 0) - { - delete iIniData; - iIniData = NULL ; - } - } - // if iIniData was never allocated or just deleted... - if(iIniData == NULL) - { - iIniData = iPtr.AllocL(); - } - - iPtrExpandedVars.Set(iIniData->Des()); - - if(iPtrExpandedVars.FindF(KIniSysDrive) == KErrNotFound) - return; - - while ( iPtrExpandedVars.Find(KIniSysDrive) != KErrNotFound ) - { - TInt offset = iPtrExpandedVars.Find(KIniSysDrive); - iPtrExpandedVars.Replace(offset, 11, iSysDrive); - } - } - -/** - * Constructor - */ -EXPORT_C CIniData::CIniData() - : iPtr(NULL,0), iPtrExpandedVars(NULL,0) - { - __DECLARE_NAME(_S("CIniData")); - iSysDrive.Copy(KLegacySysDrive); - } - -/** - * Overloaded constructor - * Takes in the system drive letter to overwrite - */ -EXPORT_C CIniData::CIniData(const TDesC& aSysDrive) - : iPtr(NULL,0), iPtrExpandedVars(NULL,0) - { - __DECLARE_NAME(_S("CIniData")); - if ( aSysDrive.Length() == 2 ) - iSysDrive.Copy(aSysDrive); - } - -/** - * Destructor - * Frees the resources located in second-phase constructor - */ -EXPORT_C CIniData::~CIniData() - { - if( iIniData != NULL ) - delete iIniData; - delete (TText*)iPtr.Ptr(); - delete iToken; - delete iName; - } - -/** - * Creates, and returns a pointer to CIniData object, leave on failure - * @param aName - Path and name of the ini file to be parsed - * @return A pointer to the CiniData object - */ -EXPORT_C CIniData* CIniData::NewL(const TDesC& aName) - { - CIniData* p=new(ELeave) CIniData(); - CleanupStack::PushL(p); - p->ConstructL(aName); - CleanupStack::Pop(); - return p; - } - -/** - * Creates, and returns a pointer to CIniData object, leave on failure - * @param aName - Path and name of the ini file to be parsed - * @param aSysDrive - Drive letter to overwrite the default system drive - * @return A pointer to the CiniData object - */ -EXPORT_C CIniData* CIniData::NewL(const TDesC& aName, const TDesC& aSysDrive) - { - CIniData* p=new(ELeave) CIniData(aSysDrive); - CleanupStack::PushL(p); - p->ConstructL(aName); - CleanupStack::Pop(); - return p; - } - -/** - * Second-phase constructor. - * The function attempts to allocate a buffer and Read file's contents into iPtr - * @param aName the name of the file which contains the ini data - * @leave One of the system-wide error codes - */ -EXPORT_C void CIniData::ConstructL(const TDesC& aName) - { - // Allocate space for token - iToken=HBufC::NewL(KTokenSize+2); // 2 extra chars for [tokenName] - - // Connect to file server - TAutoClose fs; - User::LeaveIfError(fs.iObj.Connect()); - fs.PushL(); - - // Find file, given name - TFindFile ff(fs.iObj); - TFileName iniFileDir(KLegacySysDrive); - iniFileDir.Append(KIniFileDir); - User::LeaveIfError(ff.FindByDir(aName, iniFileDir)); - iName=ff.File().AllocL(); - - // Open file - TAutoClose file; - TInt size; - User::LeaveIfError(file.iObj.Open(fs.iObj,*iName,EFileStreamText|EFileShareReadersOrWriters)); - file.PushL(); - - // Get file size and read in - User::LeaveIfError(file.iObj.Size(size)); - TText* data=(TText*)User::AllocL(size); - iPtr.Set(data, size/sizeof(TText), size/sizeof(TText)); - TPtr8 dest((TUint8*)data, 0, size); - User::LeaveIfError(file.iObj.Read(dest)); - TUint8* ptr = (TUint8*)data; - - // - // This is orderred as FEFF assuming the processor is Little Endian - // The data in the file is FFFE. PRR 28/9/98 - // - if(size>=(TInt)sizeof(TText) && iPtr[0]==0xFEFF) - { - // UNICODE Text file so lose the FFFE - Mem::Copy(ptr, ptr+sizeof(TText), size-sizeof(TText)); - iPtr.Set(data, size/sizeof(TText)-1, size/sizeof(TText)-1); - } - else if(size) - { - // NON-UNICODE so convert to UNICODE - TText* newdata = (TText*)User::AllocL(size*sizeof(TText)); - iPtr.Set(newdata, size, size); - TInt i; - for(i=0 ; i 0 ) - { - TBool FoundSection(false); - while ( ! FoundSection ) - { - // Move search buffer to next area of interest - SearchBuf.Set(aIniDataPtr.Mid(posI)); - - // Make up token "[SECTIONNAME]", to search for - TPtr sectionToken=iToken->Des(); - _LIT(sectionTokenFmtString,"[%S]"); - sectionToken.Format(sectionTokenFmtString,&aSectName); - - // Search for next occurrence of aSectName - TInt posSB = SearchBuf.Find(sectionToken); - - if (posSB==KErrNotFound) - return(EFalse); - - // Check this is at beginning of line (ie. non-commented) - // ie. Check preceding char was LF - if(posSB>0) - { - // Create a Buffer, starting one char before found subBuf - TPtrC CharBefore(SearchBuf.Right(SearchBuf.Length()-posSB+1)); - // Check first char is end of prev - if(CharBefore[0] == '\n') - { - FoundSection = ETrue; // found - posI = posI + posSB; - } - else - { - posI = posI + posSB + 1; // try again - } - } - else - { - FoundSection = ETrue; - } - - } // while ( ! FoundSection ) - - // Set start of section, after section name, (incl '[' and ']') - posStartOfSection = posI + aSectName.Length() + 2; - - // Set end of section, by finding begin of next section or end - SearchBuf.Set(aIniDataPtr.Mid(posI)); - _LIT(nextSectionBuf,"\n["); - TInt posSB = SearchBuf.Find(nextSectionBuf); - if(posSB != KErrNotFound) - { - posEndOfSection = posI + posSB; - } - else - { - posEndOfSection = aIniDataPtr.Length(); - } - - } // if( aSectName.Length() > 0 ) - - // Look for key in ini file data Buffer - posI = posStartOfSection; - TBool FoundKey(false); - while ( ! FoundKey ) - { - // Search for next occurrence of aKeyName - SearchBuf.Set(aIniDataPtr.Mid(posI,posEndOfSection-posI)); - TInt posSB = SearchBuf.Find(aKeyName); - - // If not found, return - if (posSB==KErrNotFound) - return(EFalse); - - // Check this is at beginning of line (ie. non-commented) - // ie. Check preceding char was CR or LF - if(posSB>0) - { - // Create a Buffer, starting one char before found subBuf - TPtrC CharBefore(SearchBuf.Right(SearchBuf.Length()-posSB+1)); - // Check if the first char is end of prev and also check - // if the token found is not a substring of another string - TBool beginningOK = ((CharBefore[0] == '\n') || (CharBefore[0] == ' ') || (CharBefore[0] == '\t')); - TBool endingOK = ((CharBefore[aKeyName.Length()+1] == '=') || (CharBefore[aKeyName.Length()+1] == ' ') || (CharBefore[aKeyName.Length()+1] == '\t')); - if (beginningOK && endingOK) - { - FoundKey = ETrue; - posI = posI + posSB; - } - else - { - posI = posI + posSB + 1; - } - } - else - { - FoundKey = ETrue; - } - } // while ( ! FoundKey ) - - // Set pos, to just after '=' sign - SearchBuf.Set(aIniDataPtr.Mid(posI)); - TInt posSB = SearchBuf.Locate('='); - if(posSB==KErrNotFound) // Illegal format, should flag this... - return(EFalse); - - // Identify start and end of data (EOL or EOF) - posI = posI + posSB + 1; // 1 char after '=' - TInt posValStart = posI; - TInt posValEnd; - SearchBuf.Set(aIniDataPtr.Mid(posI)); - posSB = SearchBuf.Locate('\n'); - if(posSB!=KErrNotFound) - { - // ini file uses LF for EOL - posValEnd = posI + posSB; - } - else - { - posValEnd = aIniDataPtr.Length(); - } - - // Check we are still in the section requested - if( aSectName.Length() > 0 ) - { - if( posValEnd > posEndOfSection ) - { - return(EFalse); - } - } - // Parse Buffer from posn of key - // Start one space after '=' - TLex lex(aIniDataPtr.Mid(posValStart, posValEnd-posValStart)); - lex.SkipSpaceAndMark(); // Should be at the start of the data - aResult.Set(lex.MarkedToken().Ptr(),posValEnd-posValStart - lex.Offset() ); - - TInt filterOffset; - - // Mark the offset value to the end of the value string - filterOffset = aResult.Length() - 1; - - // Loop from end of the value string marked by the offset fetched by above process - // And check to see if there is spaces, tabs or carriage returns - while(filterOffset >= 0 && - (aResult[filterOffset] == '\t' || - aResult[filterOffset] == ' ' || - aResult[filterOffset] == '\r')) - { - // If found, reduce the offset by 1 for every space and tab during the while loop - filterOffset--; - } - - // The final offset value indicating end of actual value - // within the ini data is set to the result string reference passed in - aResult.Set(aResult.Mid(0,filterOffset + 1)); - - return(ETrue); - } - -/** - * Find an integer value from given aKeyName regardless the section in the ini data file - * @param aKeyName Key being searched for - * @param aResult On return, contains the TInt result - * @return ETrue if found, otherwise EFalse - */ -EXPORT_C TBool CIniData::FindVar(const TDesC &aKeyName, TInt &aResult) - { - TPtrC ptr(NULL,0); - if (FindVar(aKeyName,ptr)) - { - TLex lex(ptr); - if (lex.Val(aResult)==KErrNone) - return(ETrue); - } - return(EFalse); - } - -/** - * Find an integer value from given aKeyName and aSecName in the ini data file - * @param aSectName Section containing key - * @param aKeyName Key being searched for in aSectName - * @param aResult On return, contains TInt result - * @return ETrue if found, otherwise EFalse - */ -EXPORT_C TBool CIniData::FindVar(const TDesC &aSection,const TDesC &aKeyName,TInt &aResult) - { - TPtrC ptr(NULL,0); - if (FindVar(aSection,aKeyName,ptr)) - { - TLex lex(ptr); - if (lex.Val(aResult)==KErrNone) - return(ETrue); - } - return(EFalse); - } -/** - * Find an 64-bit integer value from given aKeyName and aSecName in the ini data file - * @param aSectName Section containing key - * @param aKeyName Key being searched for in aSectName - * @param aResult On return, contains TInt64 result - * @return ETrue if found, otherwise EFalse - */ -EXPORT_C TBool CIniData::FindVar(const TDesC &aSection, // Section to look under - const TDesC &aKeyName, // Key to look for - TInt64 &aResult) // Int64 ref to store result - { - TPtrC ptr(NULL,0); - if (FindVar(aSection,aKeyName,ptr)) - { - TLex lex(ptr); - if (lex.Val(aResult)==KErrNone) - return(ETrue); - } - return(EFalse); - } -/** - * Set a text value to given aKeyName and aSecName in the ini data file - * @param aSectName Section containing key - * @param aKeyName Key being set in aSectName - * @param aValue A text value set for the aKeyName in section ASecName - * @return KErrNone if sucessful, otherwise system error - */ -EXPORT_C TInt CIniData::SetValue(const TDesC& aSection,const TDesC& aKeyName,const TDesC& aValue) - { - // First find the variable - this gives us a descriptor into the - // ini data giving the bound of the item that has got to be replaced. - TPtrC ptr; - - if (!FindVar(aSection, aKeyName, ptr, iPtr)) - return KErrNotFound; - - TInt pos = ptr.Ptr()-iPtr.Ptr(); - TInt size = iPtr.Length()+aValue.Length()-ptr.Length(); - - if (size>iPtr.MaxLength()) - { - size = size * sizeof(TText); - TText* newdata = (TText*)User::ReAlloc((TUint8*)iPtr.Ptr(), size); - if (newdata == 0) - return KErrNoMemory; - - iPtr.Set(newdata, iPtr.Length(), iPtr.Length()>size/(TInt)sizeof(TText)?iPtr.Length():size/(TInt)sizeof(TText)); - } - iPtr.Replace(pos, ptr.Length(), aValue); - return(KErrNone); - } - -/** - * Set a text value to given aKeyName regardless of the section in the ini data file - * @param aKeyName Key being searched for - * @param aValue A text value set for the aKeyName - * @return KErrNone if sucessful, otherwise system error - */ -EXPORT_C TInt CIniData::SetValue(const TDesC& aKeyName,const TDesC& aValue) - { - // Call with no section, so starts at beginning - return SetValue((TDesC&)KNullDesC, aKeyName, aValue); - } - -/** - * Add key aKeyName to end of ini data file - * @param aKeyName aKeyName Key being added - * @param aValue Text value assigned to the aKeyName - * @return KErrNone if sucessful, otherwise system error - */ -EXPORT_C TInt CIniData::AddValue(const TDesC& aKeyName,const TDesC& aValue) - { - // Call with no section, so starts at beginning - return AddValue((TDesC&)KNullDesC, aKeyName, aValue); - } - -/** - * Add key aKeyName to section aSectName - * @param aSectName Section - * @param aKeyName Key being added to section aSectName - * @param aValue A text value added to the aKeyName - * @return KErrNone if sucessful, otherwise system error - */ -EXPORT_C TInt CIniData::AddValue(const TDesC& aSectName,const TDesC& aKeyName,const TDesC& aValue) - { - // The request will be denied if the variable exists. - // - // If the variable is not there then making an implementation. - // If the Section name existed in the ini file then just append it - // to this section otherwise append the section, key name and - // variable at the end of the ini file. - TPtrC ptr; - - if (FindVar(aSectName, aKeyName, ptr)) - return KErrAlreadyExists; // an key name exists, - // not allow to add value again to same key - ///////////////////////////// - TPtr insertSection =iToken->Des(); - TInt size; - - TInt posEndOfSection(iPtr.Length()); // Default to the entire length of the ini data - TPtrC SearchBuf; - - // If there is a section, set pos to section start - TInt posI(0); // Initiate to 0. Position in internal data Buffer - TInt posSB(0); - if( aSectName.Length() > 0 ) - { - TBool FoundSection(false); - while ( ! FoundSection ) - { - // Move search buffer to next area of interest - SearchBuf.Set(iPtr.Mid(posI)); - - // Make up token "[SECTIONNAME]", to search for - TPtr sectionToken=iToken->Des(); - _LIT(sectionTokenFmtString,"[%S]"); - sectionToken.Format(sectionTokenFmtString,&aSectName); - - // Search for next occurrence of aSectName - posSB = SearchBuf.Find(sectionToken); - - // If not found, return - if (posSB==KErrNotFound) - { - FoundSection = ETrue; //Stop while searching - _LIT(insertSectionfmt,"\r\n[%S]\r\n%S = %S\r\n"); //if there is no section existed - insertSection.Format(insertSectionfmt,&aSectName,&aKeyName, &aValue); - } - - - // Check this is at beginning of line (ie. non-commented) - // ie. Check preceding char was LF - if(posSB>=0) - { - // Create a Buffer, starting one char before found subBuf - TPtrC CharBefore(SearchBuf.Right(SearchBuf.Length()-posSB+1)); - // Check first char is end of prev - if(CharBefore[0] == '\n' or posSB == 0) - { - FoundSection = ETrue; // found - posI = posI + posSB; - _LIT(insertSectionfmt,"\r\n%S = %S\r\n"); //if there is no section existed - insertSection.Format(insertSectionfmt,&aKeyName, &aValue); - } - else - { - posI = posI + posSB + 1; // try again - } - } - else - { - FoundSection = ETrue; //found at the beginning of the search buffer - } - - } // while ( ! FoundSection ) - - // Set start of section, after section name, (incl '[' and ']') - if(posSB!=KErrNotFound) - { - - // Set end of section, by finding begin of next section or end - SearchBuf.Set(iPtr.Mid(posI)); - _LIT(nextSectionBuf,"\n["); - TInt posSB = SearchBuf.Find(nextSectionBuf); - if(posSB != KErrNotFound) - { - posEndOfSection = posI + posSB+1; //insert it between \n and [ - } - else - { - posEndOfSection = iPtr.Length(); - } - } - - } // if( aSectName.Length() > 0 ) - - // append/insert here - size = (iPtr.Length()+ insertSection.Length())*sizeof(TText); - if (size>iPtr.MaxLength()) - { - TText* newdata = (TText*)User::ReAlloc((TUint8*)iPtr.Ptr(), size); - if (newdata == 0) - return KErrNoMemory; - - iPtr.Set(newdata, iPtr.Length(), size/(TInt)sizeof(TText)); - } - - iPtr.Insert(posEndOfSection,insertSection); - return(KErrNone); - } - - -/** - * A method used to flush the data in the buffer to the file given in second-phase constructor - */ -EXPORT_C void CIniData::WriteToFileL() - { - -#ifndef __WINC__ - - TAutoClose fs; - User::LeaveIfError(fs.iObj.Connect()); - fs.PushL(); - - TAutoClose file; - User::LeaveIfError(file.iObj.Replace(fs.iObj,*iName,EFileStreamText|EFileShareExclusive)); - file.PushL(); - - // convert 16 bits to 8 bits stream - - HBufC8* buf8 = HBufC8::NewL(iPtr.Length()); - TPtr8 ptr8(buf8->Des()); - ptr8.Copy(iPtr); - User::LeaveIfError(file.iObj.Write(ptr8)); - - delete buf8; - - // Refresh the iPtrExpandedVars with the new written ini file content - // Repeat the process of expanding the ${SYSDRIVE} - UpdateVariablesL(); - - file.Pop(); - fs.Pop(); -#endif - }