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