windowing/windowserver/test/PARSEINIDATA.CPP
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Parse the ini file
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19 @file
       
    20 @test
       
    21 @internalComponent
       
    22 */
       
    23 
       
    24 #include "PARSEINIDATA.H"
       
    25 #include <f32file.h>
       
    26 #include <e32std.h>
       
    27 
       
    28 // Default directory to look for INI file
       
    29 _LIT(KIniFileDir,"Z:\\System\\Data\\");
       
    30 
       
    31 // Constant Value changed for DEF047130 fix
       
    32 const TInt KTokenSize = 256;
       
    33 
       
    34 enum TIniPanic
       
    35 	{
       
    36 	ESectionNameTooBig,
       
    37 	EKeyNameTooBig,
       
    38 	};
       
    39 
       
    40 //
       
    41 void Panic(TIniPanic aPanic)
       
    42 	{
       
    43 	_LIT(CIniData,"CIniData");
       
    44 	User::Panic(CIniData,aPanic);
       
    45 	}
       
    46 
       
    47 /**
       
    48 Constructor
       
    49 */
       
    50 CIniData::CIniData() : iPtr(NULL,0)
       
    51 	{
       
    52 	__DECLARE_NAME(_S("CIniData"));
       
    53 	}
       
    54 
       
    55 /**
       
    56 Destructor.
       
    57 Frees the resources located in second-phase constructor
       
    58 */
       
    59 CIniData::~CIniData()
       
    60 	{
       
    61 	delete (TText*)iPtr.Ptr();
       
    62 	delete iToken;
       
    63 	delete iName;
       
    64 	}
       
    65 
       
    66 /**
       
    67  Creates, and returns a pointer to CIniData object, leave on failure
       
    68  @param aName the name of the file which contains the ini data
       
    69  @param aDelimeter	Delimiter used in wsini.ini file between variable and value
       
    70  @return A pointer to the CiniData object
       
    71 */
       
    72 CIniData* CIniData::NewL(const TDesC& aName, char aDelimiter)
       
    73 	{
       
    74 	CIniData* p = new(ELeave) CIniData;
       
    75 	CleanupStack::PushL(p);
       
    76 	p->ConstructL(aName, aDelimiter);
       
    77 	CleanupStack::Pop();
       
    78 	return p;
       
    79 	}
       
    80 
       
    81 /**
       
    82  Second-phase constructor.
       
    83  The function attempts to allocate a buffer and Read file's contents into iPtr
       
    84  @param aName the name of the file which contains the ini data
       
    85  @param aDelimeter	Delimiter used in wsini.ini file between variable and value
       
    86  @leave One of the system-wide error codes
       
    87 */
       
    88 void CIniData::ConstructL(const TDesC& aName, char aDelimiter)
       
    89 	{
       
    90 	//Set delimiter
       
    91 	iDelimiter = aDelimiter;
       
    92 	
       
    93  	// Allocate space for token
       
    94 	iToken=HBufC::NewL(KTokenSize+2);	// 2 extra chars for [tokenName]
       
    95 
       
    96 	// Connect to file server
       
    97 	TAutoClose<RFs> fs;
       
    98 	User::LeaveIfError(fs.iObj.Connect());
       
    99 	fs.PushL();
       
   100 
       
   101 	// Find file, given name
       
   102 	TFindFile ff(fs.iObj);
       
   103 	User::LeaveIfError(ff.FindByDir(aName, KIniFileDir));
       
   104 	iName = ff.File().AllocL();
       
   105 
       
   106 	// Open file
       
   107 	TAutoClose<RFile> file;
       
   108 	TInt size;
       
   109 	User::LeaveIfError(file.iObj.Open(fs.iObj,*iName,EFileStreamText|EFileShareReadersOrWriters));
       
   110 	file.PushL();
       
   111 
       
   112 	// Get file size and read in
       
   113 	User::LeaveIfError(file.iObj.Size(size));
       
   114 	TText* data = (TText*)User::AllocL(size);
       
   115 	iPtr.Set(data, size/sizeof(TText), size/sizeof(TText));
       
   116 	TPtr8 dest((TUint8*)data, 0, size);
       
   117 	User::LeaveIfError(file.iObj.Read(dest));
       
   118 	TUint8* ptr = (TUint8*)data;
       
   119 
       
   120 	//
       
   121 	// This is orderred as FEFF assuming the processor is Little Endian
       
   122 	// The data in the file is FFFE.		PRR 28/9/98
       
   123 	//
       
   124 	if(size>=(TInt)sizeof(TText) && iPtr[0]==0xFEFF)
       
   125 	{
       
   126 		// UNICODE Text file so lose the FFFE
       
   127 		Mem::Copy(ptr, ptr+sizeof(TText), size-sizeof(TText));
       
   128 		iPtr.Set(data, size/sizeof(TText)-1, size/sizeof(TText)-1);
       
   129 	}
       
   130 	else if(size)
       
   131 	{
       
   132 		// NON-UNICODE so convert to UNICODE
       
   133 		TText* newdata = (TText*)User::AllocL(size*sizeof(TText));
       
   134 		iPtr.Set(newdata, size, size);
       
   135 		TInt i;
       
   136 		for(i = 0 ; i<size ; ++i)
       
   137 			iPtr[i] = ptr[i];
       
   138 		delete data;
       
   139 	}
       
   140 
       
   141 	file.Pop();
       
   142 	fs.Pop();
       
   143 }
       
   144 
       
   145 /**
       
   146 Find a text value from given aKeyName regardless the section in the ini data file
       
   147 @param aKeyName Key being searched for
       
   148 @param aResult On return, contains the text result 
       
   149 @return ETrue if found, otherwise EFalse
       
   150 */
       
   151 TBool CIniData::FindVar(const TDesC& aKeyName, TPtrC& aResult)
       
   152 	{
       
   153 	// Call with no section, so starts at beginning
       
   154 	if (FindVar((TDesC&)KNullDesC , aKeyName, aResult))
       
   155 		return(ETrue);
       
   156 	else
       
   157 		return(EFalse);
       
   158 	}
       
   159 
       
   160 /**
       
   161 Find a text value from given aKeyName and aSecName in the ini data file
       
   162 @param aSectName Section containing key
       
   163 @param aKeyName Key being searched for in aSectName
       
   164 @param aResult On return, contains the text result 
       
   165 @return ETrue if found, otherwise EFalse
       
   166 */
       
   167 TBool CIniData::FindVar(const TDesC& aSectName,const TDesC& aKeyName,TPtrC& aResult)
       
   168 	{
       
   169 
       
   170 	__ASSERT_DEBUG(aSectName.Length()<=KTokenSize,Panic(ESectionNameTooBig));
       
   171 	__ASSERT_DEBUG(aKeyName.Length()<=KTokenSize,Panic(EKeyNameTooBig));
       
   172 
       
   173 	TInt posStartOfSection(0);
       
   174 	TInt posEndOfSection(iPtr.Length()); // Default to the entire length of the ini data
       
   175 	TPtrC SearchBuf;
       
   176 
       
   177 	// If we have a section, set pos to section start
       
   178 	TInt posI(0);	// Position in internal data Buffer
       
   179 	if( aSectName.Length() > 0 )
       
   180 		{
       
   181 		TBool FoundSection(false);
       
   182 		while ( ! FoundSection )
       
   183 			{
       
   184 			// Move search buffer to next area of interest
       
   185 			SearchBuf.Set(iPtr.Mid(posI));
       
   186 
       
   187 			// Make up token "[SECTIONNAME]", to search for
       
   188 			TPtr sectionToken = iToken->Des();
       
   189 			_LIT(sectionTokenFmtString,"[%S]");
       
   190 			sectionToken.Format(sectionTokenFmtString,&aSectName);
       
   191 
       
   192 			// Search for next occurrence of aSectName
       
   193 			TInt posSB = SearchBuf.Find(sectionToken);
       
   194 
       
   195 			if (posSB == KErrNotFound)
       
   196 				return(EFalse);
       
   197 
       
   198 			// Check this is at beginning of line (ie. non-commented)
       
   199 			// ie. Check preceding char was LF
       
   200 			if(posSB>0)
       
   201 				{
       
   202 				// Create a Buffer, starting one char before found subBuf
       
   203 				TPtrC CharBefore(SearchBuf.Right(SearchBuf.Length()-posSB+1));
       
   204 				// Check first char is end of prev
       
   205 				if(CharBefore[0] == '\n')
       
   206 					{
       
   207 					FoundSection = ETrue;		// found
       
   208 					posI = posI + posSB;
       
   209 					}
       
   210 				else
       
   211 					{
       
   212 					posI = posI + posSB + 1;	// try again
       
   213 					}
       
   214 				}
       
   215 			else
       
   216 				{
       
   217 				FoundSection = ETrue;
       
   218 				}
       
   219 
       
   220 			}	// while ( ! FoundSection ) 
       
   221 
       
   222 		// Set start of section, after section name, (incl '[' and ']')
       
   223 		posStartOfSection = posI + aSectName.Length() + 2;
       
   224 
       
   225 		// Set end of section, by finding begin of next section or end
       
   226 		SearchBuf.Set(iPtr.Mid(posI));
       
   227 		_LIT(nextSectionBuf,"\n[");
       
   228 		TInt posSB = SearchBuf.Find(nextSectionBuf);
       
   229 		if(posSB != KErrNotFound)
       
   230 			{
       
   231 			posEndOfSection = posI + posSB;
       
   232 			}
       
   233 		else
       
   234 			{
       
   235 			posEndOfSection = iPtr.Length();
       
   236 			}
       
   237 
       
   238 		}	// if( aSectName.Length() > 0 )
       
   239 
       
   240 	// Look for key in ini file data Buffer
       
   241 	posI = posStartOfSection;
       
   242 	TBool FoundKey(false);
       
   243 	while ( ! FoundKey )
       
   244 		{
       
   245 		// Search for next occurrence of aKeyName
       
   246 		SearchBuf.Set(iPtr.Mid(posI,posEndOfSection-posI));
       
   247 		TInt posSB = SearchBuf.Find(aKeyName);
       
   248 
       
   249 		// If not found, return
       
   250 		if (posSB == KErrNotFound)
       
   251 			return(EFalse);
       
   252 
       
   253 		// Check this is at beginning of line (ie. non-commented)
       
   254 		// ie. Check preceding char was CR or LF
       
   255 		if(posSB>0)
       
   256 			{
       
   257 			// Create a Buffer, starting one char before found subBuf
       
   258 			TPtrC CharBefore(SearchBuf.Right(SearchBuf.Length()-posSB+1));
       
   259 			// Check if the first char is end of prev and also check 
       
   260 			// if the token found is not a substring of another string  
       
   261 			TBool beginningOK = ((CharBefore[0] == '\n') || (CharBefore[0] == ' ') || (CharBefore[0] == '\t'));
       
   262 			TBool endingOK = ((CharBefore[aKeyName.Length()+1] == iDelimiter) || (CharBefore[aKeyName.Length()+1] == ' ') || (CharBefore[aKeyName.Length()+1] == '\t'));
       
   263 			if (beginningOK && endingOK)
       
   264 				{
       
   265 				FoundKey = ETrue;
       
   266 				posI = posI + posSB;
       
   267 				}
       
   268 			else
       
   269 				{
       
   270 				posI = posI + posSB + 1;
       
   271 				}
       
   272 			}
       
   273 		else
       
   274 			{
       
   275 			FoundKey = ETrue;
       
   276 			}
       
   277 		}	// while ( ! FoundKey )
       
   278 
       
   279 	// Set pos, to just after iDelimiter sign
       
   280 	SearchBuf.Set(iPtr.Mid(posI));
       
   281 	TInt posSB = SearchBuf.Locate(iDelimiter);
       
   282 	if(posSB==KErrNotFound)		// Illegal format, should flag this...
       
   283 		return(EFalse);
       
   284 
       
   285 	// Identify start and end of data (EOL or EOF)
       
   286 	posI = posI + posSB + 1;	// 1 char after iDelimiter
       
   287 	TInt posValStart = posI;
       
   288 	TInt posValEnd;
       
   289 	SearchBuf.Set(iPtr.Mid(posI));
       
   290 	posSB = SearchBuf.Locate('\r');
       
   291 	if(posSB != KErrNotFound)
       
   292 		{
       
   293 		posValEnd = posI + posSB;
       
   294 		}
       
   295 	else
       
   296 		{
       
   297 		posValEnd = iPtr.Length();
       
   298 		}
       
   299 
       
   300 	// Check we are still in the section requested
       
   301 	if( aSectName.Length() > 0 )
       
   302 		{
       
   303 		if( posValEnd > posEndOfSection )
       
   304 			{
       
   305 			return(EFalse);
       
   306 			}
       
   307 		}
       
   308 	// Parse Buffer from posn of key
       
   309 	// Start one space after '='
       
   310 	TLex lex(iPtr.Mid(posValStart, posValEnd-posValStart));
       
   311 	lex.SkipSpaceAndMark();		// Should be at the start of the data
       
   312 	aResult.Set(lex.MarkedToken().Ptr(),posValEnd-posValStart - lex.Offset() );
       
   313 	return(ETrue);
       
   314 	}
       
   315 
       
   316 /**
       
   317 Find an integer value from given aKeyName regardless the section in the ini data file
       
   318 @param aKeyName Key being searched for
       
   319 @param aResult On return, contains the TInt result 
       
   320 @return ETrue if found, otherwise EFalse
       
   321 */
       
   322 TBool CIniData::FindVar(const TDesC& aKeyName, TInt& aResult)
       
   323 	{
       
   324 	TPtrC ptr(NULL,0);
       
   325 	if (FindVar(aKeyName,ptr))
       
   326 		{
       
   327 		TLex lex(ptr);
       
   328 		if (lex.Val(aResult) == KErrNone)
       
   329 			return(ETrue);
       
   330 		}
       
   331 	return(EFalse);
       
   332 	}
       
   333 
       
   334 /**
       
   335 Find an integer value from given aKeyName and aSecName in the ini data file
       
   336 @param aSectName Section containing key
       
   337 @param aKeyName Key being searched for  in aSectName
       
   338 @param aResult On return, contains TInt result 
       
   339 @return ETrue if found, otherwise EFalse
       
   340 */
       
   341 TBool CIniData::FindVar(const TDesC& aSection,const TDesC& aKeyName,TInt& aResult)
       
   342 	{
       
   343 	TPtrC ptr(NULL,0);
       
   344 	if (FindVar(aSection,aKeyName,ptr))
       
   345 		{
       
   346 		TLex lex(ptr);
       
   347 		if (lex.Val(aResult) == KErrNone)
       
   348 			return(ETrue);
       
   349 		}
       
   350 	return(EFalse);
       
   351 }