commsprocess/commsrootserverconfig/configurator/src/c32cmi.cpp
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 /*
       
     2 * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include <f32file.h>
       
    19 #include "c32cmi.h"
       
    20 #include <cfextras.h>
       
    21 #include <e32base.h>
       
    22 #include "c32cmiutils.h"
       
    23 
       
    24 /** Implements the parser for .CMI configuration files.
       
    25 @file
       
    26 @publishedPartner
       
    27 @released
       
    28 */
       
    29 
       
    30 /** Name of application for logging
       
    31 */
       
    32 __FLOG_STMT(_LIT8(KSubsys,"C32Start");)
       
    33 
       
    34 /** Logging second tag
       
    35 */
       
    36 __FLOG_STMT(_LIT8(KComponent,"Events");)
       
    37 
       
    38 /** .CMI file section "[Loader]" contains the configuration of
       
    39 the CPM and its bindings
       
    40 */
       
    41 _LIT8(KSectionLoader,		"Loader");
       
    42 
       
    43 /** .CMI optional file section "[IniData]" contains application specific
       
    44 data.
       
    45 */
       
    46 _LIT8(KSectionIniData,		"IniData");
       
    47 
       
    48 /** Attribute which can be found in a .CMI file in the [loader] section.
       
    49 */
       
    50 _LIT8(KAttrName,			"Name");
       
    51 
       
    52 /** Attribute which can be found in a .CMI file in the [loader] section.
       
    53 */
       
    54 _LIT8(KAttrFileName,		"FileName");
       
    55 
       
    56 /** Attribute which can be found in a .CMI file in the [loader] section.
       
    57 */
       
    58 _LIT8(KAttrIniDataFile,		"IniData");
       
    59 
       
    60 /** Attribute which can be found in a .CMI file in the [loader] section.
       
    61 */
       
    62 _LIT8(KAttrIsServer,		"IsServer");
       
    63 
       
    64 /** Attribute which can be found in a .CMI file in the [loader] section.
       
    65 */
       
    66 _LIT8(KAttrPriority,		"Priority");
       
    67 
       
    68 /** Attribute which can be found in a .CMI file in the [loader] section.
       
    69 */
       
    70 _LIT8(KAttrStackSize,		"StackSize");
       
    71 
       
    72 /** Attribute which can be found in a .CMI file in the [loader] section.
       
    73 */
       
    74 _LIT8(KAttrHeapOption,		"HeapOption");
       
    75 
       
    76 /** Attribute which can be found in a .CMI file in the [loader] section.
       
    77 */
       
    78 _LIT8(KAttrStartSequence,	"StartSequence");
       
    79 
       
    80 /** Attribute which can be found in a .CMI file in the [loader] section.
       
    81 */
       
    82 _LIT8(KAttrScaledStartupState,	"ScaledStartupState");
       
    83 
       
    84 /** Attribute which can be found in a .CMI file in the [loader] section.
       
    85 */
       
    86 _LIT8(KAttrMinHeapSize,		"MinHeapSize");
       
    87 
       
    88 /** Attribute which can be found in a .CMI file in the [loader] section.
       
    89 */
       
    90 _LIT8(KAttrMaxHeapSize,		"MaxHeapSize");
       
    91 
       
    92 /** Attribute which can be found in a .CMI file in the [loader] section.
       
    93 */
       
    94 _LIT8(KAttrSharedHeapName,	"SharedHeapName");
       
    95 
       
    96 /** Attribute which can be found in a .CMI file in the [loader] section.
       
    97 */
       
    98 _LIT8(KAttrThreadFuncOrdinal,"ThreadFunctionOrdinal");
       
    99 
       
   100 /** Attribute which can be found in a .CMI file in the [loader] section.
       
   101 */
       
   102 _LIT8(KAttrIsSticky,		"IsSticky");
       
   103 
       
   104 /** Attribute which can be found in a .CMI file in the [loader] section.
       
   105 */
       
   106 _LIT8(KAttrSystemCritical,	"SystemCritical");
       
   107 
       
   108 /** Attribute which can be found in a .CMI file in the [loader] section.
       
   109 */
       
   110 _LIT8(KAttrSystemCriticalAfterInit,	"SystemCriticalAfterInit");
       
   111 
       
   112 /** Attribute which can be found in a .CMI file in the [loader] section.
       
   113 */
       
   114 _LIT8(KAttrControlFlags,	"ControlFlags");
       
   115 
       
   116 /**Attribute which can be found in a .CMI file in the [loader] section.
       
   117 */
       
   118 _LIT8(KAttrOnDemand, "OnDemand");
       
   119 
       
   120 /**Attribute which can be found in a .CMI file in the [loader] section.
       
   121 */
       
   122 _LIT8(KAttrGroupName, "Group");
       
   123 
       
   124 /** PANICs which can occur during .CMI file parsing.
       
   125 */
       
   126 enum TIniPanic
       
   127 	{
       
   128 	/** The name of a section is too long.
       
   129 	*/
       
   130 	ESectionNameTooBig,
       
   131 	/** The name of a variable is too big.
       
   132 	*/
       
   133 	EVarNameTooBig
       
   134 	};
       
   135 
       
   136 #ifdef _DEBUG
       
   137 /** Function whch will PANIC the module, but only in debug mode.
       
   138 */
       
   139 static void Panic(TIniPanic aPanic)
       
   140 	{
       
   141 	_LIT(KC32CmiData,"C32CmiData");
       
   142 	User::Panic(KC32CmiData,aPanic);
       
   143 	}
       
   144 #endif
       
   145 
       
   146 
       
   147 
       
   148 /////////////////////////////////////////////////////////////////////////////
       
   149 
       
   150 C32ParseIniFile* C32ParseIniFile::NewL(const TDesC& aFileName, TAutoClose<RFs>& aFileServer)
       
   151 	{
       
   152 	C32ParseIniFile* self = new(ELeave) C32ParseIniFile;
       
   153 	CleanupStack::PushL(self);
       
   154 	self->ConstructL(aFileName, aFileServer);
       
   155 	CleanupStack::Pop();
       
   156 	return self;
       
   157 	}
       
   158 
       
   159 void C32ParseIniFile::ConstructL(const TDesC& aFileName, TAutoClose<RFs>& aFileServer)
       
   160 	{
       
   161 	__FLOG_OPEN(KSubsys,KComponent);
       
   162     iToken = HBufC8::NewL(KTokenSize+2);	// 2 extra chars for [tokenName]
       
   163 	ReadFileL(aFileName, aFileServer);
       
   164 	}
       
   165 
       
   166 C32ParseIniFile::~C32ParseIniFile()
       
   167 	{
       
   168 	delete iCmiData;
       
   169 	delete iToken;
       
   170 	__FLOG_CLOSE;
       
   171 	}
       
   172 
       
   173 TBool C32ParseIniFile::FindVar(const TDesC8 &aSection, const TDesC8 &aVarName, TPtrC8 &aResult, TInt aEnumerator)
       
   174 /** Find a variable's value given a section name and a var name.
       
   175 @param aSection The section to search.
       
   176 @param aVarName The name that will have aEnumerator appended to it to generate the key that will be searched for.
       
   177 @param aResult The result.
       
   178 @param aEnumerator Appended to the var name to generate a the key that will be searched for.
       
   179 @return Success or fail.
       
   180 */
       
   181 	{
       
   182 	__ASSERT_DEBUG(aSection.Length()<=KTokenSize,Panic(ESectionNameTooBig));
       
   183 	__ASSERT_DEBUG(aVarName.Length()<=KTokenSize,Panic(EVarNameTooBig));
       
   184 
       
   185 	// append enumeration to the key name
       
   186 	TBuf8<256> aKey(aVarName);
       
   187 	aKey.AppendNum(aEnumerator);
       
   188 
       
   189 	return CommsFW::GetVarFromIniData(*iCmiData, aSection, aKey, aResult);
       
   190 	}
       
   191 
       
   192 TBool C32ParseIniFile::FindVar(const TDesC8 &aSection, const TDesC8 &aVarName, TPtrC8 &aResult)
       
   193 /** Find a variable's value given a section name and a var name.
       
   194 @param aSection The section to search.
       
   195 @param aVarName The name to find.
       
   196 @param aResult The result.
       
   197 @return Success or fail.
       
   198 */
       
   199 	{
       
   200 	__ASSERT_DEBUG(aSection.Length()<=KTokenSize,Panic(ESectionNameTooBig));
       
   201 	__ASSERT_DEBUG(aVarName.Length()<=KTokenSize,Panic(EVarNameTooBig));
       
   202 	return CommsFW::GetVarFromIniData(*iCmiData, aSection, aVarName, aResult);
       
   203 	}
       
   204 
       
   205 
       
   206 TBool C32ParseIniFile::FindVar(const TDesC8 &aSection, const TDesC8 &aVarName, TInt &aResult)
       
   207 /**
       
   208 @param aSection The section to search.
       
   209 @param aVarName The name to find.
       
   210 @param aResult The result.
       
   211 @return Success or fail.
       
   212 */
       
   213 	{
       
   214 	TPtrC8 ptr(NULL,0);
       
   215 	if (FindVar(aSection,aVarName,ptr))
       
   216 		{
       
   217 		TRadix radix;
       
   218 		_LIT8(KHexPrefix, "0x");
       
   219 		if(ptr.Left(2).CompareF(KHexPrefix) == 0)
       
   220 			{
       
   221 			ptr.Set(ptr.Mid(2));
       
   222 			radix = EHex;
       
   223 			}
       
   224 		else
       
   225 			{
       
   226 			radix = EDecimal;
       
   227 			}
       
   228 		TLex8 lex(ptr);
       
   229 		TUint32 result;
       
   230 		if (lex.Val(result, radix)==KErrNone)
       
   231 			{
       
   232 			aResult = result;
       
   233 			return(ETrue);
       
   234 			}
       
   235 		}
       
   236 	return(EFalse);
       
   237 	}
       
   238 
       
   239 void C32ParseIniFile::ReadFileL(const TDesC& aFileName, TAutoClose<RFs>& aFileServer)
       
   240 /** Reads the file content into a narrow-char buffer. By design the
       
   241 configurator only supports ASCII text, as its purpose is invisible
       
   242 system configuration.
       
   243 @param aFileName The name of the file to be read.
       
   244 */
       
   245 	{
       
   246 	// Open session to the FileServer
       
   247 	//TAutoClose<RFs> fs;
       
   248 	TInt result;
       
   249 	//check if the session is already open
       
   250 	if(aFileServer.iObj.Handle() == 0)
       
   251 		{
       
   252 		if(KErrNone!=(result=aFileServer.iObj.Connect()))
       
   253 			{
       
   254 			__FLOG( _L( "Unable to connect to the File Server" ) );
       
   255 			User::Leave(result);
       
   256 			}
       
   257 		}
       
   258 	//fs.PushL();
       
   259 
       
   260 	// Open file
       
   261 	TAutoClose<RFile> rfile;
       
   262 	result = rfile.iObj.Open(aFileServer.iObj, aFileName, EFileShareReadersOnly);
       
   263 	if(KErrNone==result)
       
   264 		{
       
   265 		rfile.PushL();
       
   266 
       
   267 		// Get filesize for allocating the buffer for the data
       
   268 		TInt size;
       
   269 		result = rfile.iObj.Size(size);
       
   270 		if(KErrNone!=result)
       
   271 			{
       
   272 			__FLOG_1(_L("Couldn't get size of file %S"), &aFileName);
       
   273 			User::Leave(result);
       
   274 			}
       
   275 
       
   276 		if(size<=0)
       
   277 			{
       
   278 			__FLOG_1(_L("File %S has no contents"), &aFileName);
       
   279 			User::Leave(KErrCorrupt);
       
   280 			}
       
   281 
       
   282 		// Allocate a buffer that can contain the file data
       
   283 		iCmiData = HBufC8::NewL(size);
       
   284 		TPtr8 fileDataPtr = iCmiData->Des();
       
   285 
       
   286 		// Read the contents of the file into the buffer
       
   287 		result=rfile.iObj.Read(fileDataPtr);
       
   288 		if(KErrNone!=result)
       
   289 			{
       
   290 			__FLOG_1(_L("Couldn't read contents of file %S"), &aFileName);
       
   291 			User::Leave(result);
       
   292 			}
       
   293 		rfile.Pop();
       
   294 		}
       
   295 	//fs.Pop();
       
   296 	}
       
   297 
       
   298 TPtrC8 C32ParseIniFile::RetrieveSectionStart(const TDesC8& aSectionName)
       
   299 /** Returns a byte descriptor containing the data from the start of a section to the
       
   300 end of the file.
       
   301 */
       
   302 	{
       
   303 	TPtrC8 section;
       
   304 	TPtr8 sectionToken = iToken->Des();
       
   305 	_LIT8(sectionTokenString,"[%S]");
       
   306 	sectionToken.Format(sectionTokenString, &aSectionName);
       
   307 	TInt sectionStart = iCmiData->Find(sectionToken);
       
   308 	if (KErrNotFound==sectionStart)
       
   309 		return section;
       
   310 
       
   311 	section.Set(iCmiData->Mid(sectionStart));
       
   312 	sectionStart += section.Find(TPtrC8(_S8("]")));
       
   313 	if (KErrNotFound==sectionStart)
       
   314 		{
       
   315 		section.Set(KNullDesC8);
       
   316 		}
       
   317 	else
       
   318 		{
       
   319 		sectionStart++;
       
   320 		section.Set(iCmiData->Mid(sectionStart, iCmiData->Length()-sectionStart));
       
   321 		}
       
   322 	return section;
       
   323 	}
       
   324 
       
   325 
       
   326 /////////////////////////////////////////////////////////////////////////////
       
   327 
       
   328 C32CmiData::C32CmiData()
       
   329 /** C'tor. Sets th default values for the attributes as well as
       
   330 the default required attributes.
       
   331 */
       
   332 	{
       
   333 	__FLOG_OPEN(KSubsys,KComponent);
       
   334 	iAttrPriority = EPriorityNormal;
       
   335 //	iAttrThreadFuncOrdinal = 0; // Rootserver uses defaults ordinal when this is set to 0.
       
   336 	iAttrStackSize = KDefaultStackSize * sizeof(TText); // Bigger stack if unicode
       
   337 	iAttrRequired = (AttrName|AttrFileName);
       
   338 	iAttrScaledStartupState = 0x3000;
       
   339 //	iAttrIsSticky=EFalse;
       
   340 //	iAttrSystemCritical=EFalse;
       
   341 //	iAttrControlFlags=0;
       
   342 	}
       
   343 
       
   344 C32CmiData::~C32CmiData()
       
   345 /** D'tor.
       
   346 */
       
   347 	{
       
   348 	delete iCmiFile;
       
   349 	__FLOG_CLOSE;
       
   350 	}
       
   351 
       
   352 /*static*/ C32CmiData* C32CmiData::NewL(const TDesC& aFileName, TAutoClose<RFs>& aFileServer)
       
   353 /**
       
   354 @param aFileName The filename of the file to be read.
       
   355 @return pointer to new C32CmiData object.
       
   356 */
       
   357 	{
       
   358 	C32CmiData* p = new(ELeave) C32CmiData;
       
   359 	CleanupStack::PushL(p);
       
   360 	p->ConstructL(aFileName, aFileServer);
       
   361 	CleanupStack::Pop();
       
   362 	return p;
       
   363 	}
       
   364 
       
   365 void C32CmiData::RetrieveAttribute(TInt aAttr, const TDesC8 &aVarName, TInt &aResult)
       
   366 /**
       
   367 @param aAttr The attibute set and returned.
       
   368 @param aVarName The name to be found.
       
   369 @param aResult The result.
       
   370 */
       
   371 	{
       
   372 	if(FindVar(KSectionLoader, aVarName, aResult))
       
   373 		{
       
   374 		SetAttr(aAttr);
       
   375 		}
       
   376 	}
       
   377 
       
   378 void C32CmiData::RetrieveAttribute(TInt aAttr, const TDesC8 &aVarName, TPtrC8 &aResult)
       
   379 /** Retrieves an option from the file data and
       
   380 if it was found set the requested TPtrC to point to it.
       
   381 @param aAttr The attibute set and returned.
       
   382 @param aVarName The name to be found.
       
   383 @param aResult The result.
       
   384 */
       
   385 	{
       
   386 	if(FindVar(KSectionLoader, aVarName, aResult))
       
   387 		{
       
   388 		SetAttr(aAttr);
       
   389 		}
       
   390 	}
       
   391 
       
   392 void C32CmiData::RetrievePriorityL()
       
   393 /** Retrieves a priority option from the file data. If present, checks it is a valid
       
   394 TThreadPriority enumerator name, and sets the corresponding priority attribute.
       
   395 @leave KErrCorrupt If the priority name is invalid
       
   396 */
       
   397 	{
       
   398 	TPtrC8 priorityName;
       
   399 	if(FindVar(KSectionLoader, KAttrPriority, priorityName))
       
   400 		{
       
   401 		TThreadPriority priority;
       
   402 		if(C32CmiUtils::ThreadPriorityNameToEnum(priorityName, priority) == KErrNone)
       
   403 			{
       
   404 			iAttrPriority = priority;
       
   405 			SetAttr(AttrPriority);
       
   406 			return;
       
   407 			}
       
   408 		__FLOG_1(_L8("Invalid Priority %S"), &priorityName);
       
   409 		User::Leave(KErrCorrupt);
       
   410 		}
       
   411 	}
       
   412 
       
   413 TBool C32CmiData::CompareHeapTypes(const TDesC8 &aType1, const TDesC8 &aType2, TRSHeapType aType3)
       
   414 /** Helper function: Compares two strings and if there
       
   415 is a match set the AttrHeapOption bit and save the requested value.
       
   416 @param aType1 The first descriptor.
       
   417 @param aType2 The second descriptor.
       
   418 @param aType3 Enum type to be set on a positive match.
       
   419 @return Success or fail.
       
   420 */
       
   421 	{
       
   422 	if(0==aType1.CompareF(aType2))
       
   423 		{
       
   424 		iAttrHeapOption=aType3;
       
   425 		SetAttr(AttrHeapOption);
       
   426 		return ETrue;
       
   427 		}
       
   428 	return EFalse;
       
   429 	}
       
   430 
       
   431 void C32CmiData::RetrieveHeapTypeL()
       
   432 /** Determines the heap type required.
       
   433 */
       
   434 	{
       
   435 	TPtrC8 type;
       
   436 	if(FindVar(KSectionLoader, KAttrHeapOption, type))
       
   437 		{
       
   438 		// List of possible heap types
       
   439 		_LIT8(KEDefaultHeap, "EDefaultHeap");
       
   440 		_LIT8(KEShareHeap, "EShareHeap");
       
   441 		_LIT8(KENewHeap, "ENewHeap");
       
   442 		if(CompareHeapTypes(type, KEDefaultHeap, EDefaultHeap))
       
   443 			return;
       
   444 		if(CompareHeapTypes(type, KEShareHeap, EShareHeap))
       
   445 			{
       
   446 			iAttrRequired |= AttrSharedHeapName;
       
   447 			return;
       
   448 			}
       
   449 		if(CompareHeapTypes(type, KENewHeap, ENewHeap))
       
   450 			{
       
   451 			iAttrRequired |= (AttrMinHeapSize|AttrMaxHeapSize);
       
   452 			return;
       
   453 			}
       
   454 		__FLOG_1(_L8("Invalid Heap Type %S"), &type);
       
   455 		User::Leave(KErrCorrupt);
       
   456 		}
       
   457 	}
       
   458 
       
   459 void C32CmiData::RetrieveIniDataSection()
       
   460 /** Sets a narrow ptr to point from the start of
       
   461 the inidata to the end of the file.
       
   462 */
       
   463 	{
       
   464 	TPtrC8 sectionStart = iCmiFile->RetrieveSectionStart(KSectionIniData);
       
   465 	iAttrIniData.Set(sectionStart.Ptr(), sectionStart.Length());
       
   466 	SetAttr(AttrIniData);
       
   467 	}
       
   468 
       
   469 void C32CmiData::RetrieveAttributesL()
       
   470 /** Controls extraction of data.
       
   471 */
       
   472 	{
       
   473 	RetrieveAttribute(AttrName, KAttrName, iAttrName);
       
   474 
       
   475 	RetrieveAttribute(AttrFileName, KAttrFileName, iAttrFileName);
       
   476 	RetrieveAttribute(AttrIniDataFile, KAttrIniDataFile, iAttrIniDataFile);
       
   477 	RetrieveAttribute(AttrIsServer, KAttrIsServer, iAttrIsServer);
       
   478 
       
   479 	RetrievePriorityL();
       
   480 
       
   481 	RetrieveAttribute(AttrStackSize, KAttrStackSize, iAttrStackSize);
       
   482 	RetrieveHeapTypeL();
       
   483 	TInt scaledStartupState = (TInt) iAttrScaledStartupState;
       
   484 	RetrieveAttribute(AttrScaledStartupState, KAttrScaledStartupState, scaledStartupState);
       
   485 	iAttrScaledStartupState = (TUint32) scaledStartupState;
       
   486 	// The original start sequence scheme is remapped to the scaled startup states
       
   487 	TInt attrStartSequence = KC32LowStartSequenceCeiling;
       
   488 	RetrieveAttribute(AttrStartSequence, KAttrStartSequence, attrStartSequence);
       
   489 	if(AttrIsSet(AttrStartSequence))
       
   490 		{
       
   491 		if(AttrIsSet(AttrScaledStartupState))
       
   492 			{
       
   493 			__FLOG(_L("ERROR: Both StartSequence and ScaledStartupState given"));
       
   494 			User::Leave(KErrCorrupt);
       
   495 			}
       
   496 		if(attrStartSequence < KC32LowStartSequenceCeiling)
       
   497 			{
       
   498 			iAttrScaledStartupState = KC32LowStartSequenceScaleBase + attrStartSequence;
       
   499 			}
       
   500 		else if(attrStartSequence < KC32MidStartSequenceCeiling)
       
   501 			{
       
   502 			iAttrScaledStartupState = KC32MidStartSequenceScaleBase + attrStartSequence;
       
   503 			}
       
   504 		else
       
   505 			{
       
   506 			iAttrScaledStartupState = KC32HighStartSequenceScaleBase + attrStartSequence;
       
   507 			}
       
   508 		__FLOG_2(_L("...StartSequence %d converted to ScaledStartupState 0x%x"), attrStartSequence, iAttrScaledStartupState);
       
   509 		SetAttr(AttrScaledStartupState);
       
   510 		}
       
   511 	else
       
   512 		{
       
   513 		__FLOG_1(_L("...ScaledStartupState 0x%x"), iAttrScaledStartupState);
       
   514 		}
       
   515 	RetrieveAttribute(AttrMinHeapSize, KAttrMinHeapSize, iAttrMinHeapSize);
       
   516 	RetrieveAttribute(AttrMaxHeapSize, KAttrMaxHeapSize, iAttrMaxHeapSize);
       
   517 	RetrieveAttribute(AttrSharedHeapName, KAttrSharedHeapName, iAttrSharedHeapName);
       
   518 	RetrieveAttribute(AttrThreadFuncOrdinal, KAttrThreadFuncOrdinal, iAttrThreadFuncOrdinal);
       
   519 	RetrieveAttribute(AttrIsSticky, KAttrIsSticky, iAttrIsSticky);
       
   520 	RetrieveAttribute(AttrSystemCritical, KAttrSystemCritical, iAttrSystemCritical);
       
   521 	RetrieveAttribute(AttrSystemCriticalAfterInit, KAttrSystemCriticalAfterInit, iAttrSystemCriticalAfterInit);
       
   522 
       
   523 	//Added for on demand loading
       
   524 	RetrieveAttribute(AttrOnDemand, KAttrOnDemand, iAttrOnDemand);
       
   525 	RetrieveAttribute(AttrGroupName, KAttrGroupName, iAttrGroupName);
       
   526 
       
   527 	TInt controlFlags = 0;
       
   528 	RetrieveAttribute(AttrControlFlags, KAttrControlFlags, controlFlags);
       
   529 	iAttrControlFlags = (TUint32) controlFlags;
       
   530 
       
   531  	RetrieveIniDataSection();
       
   532 
       
   533 	// Check that the required attributes were set
       
   534 	if(!AttrIsSet(iAttrRequired))
       
   535 		{
       
   536 		__FLOG(_L("Required attributes not set!"));
       
   537 		User::Leave(KErrCorrupt);
       
   538 		}
       
   539 	}
       
   540 
       
   541 void C32CmiData::ConstructL(const TDesC& aFileName, TAutoClose<RFs>& aFileServer)
       
   542 /** Second stage Constructor. Will cause file to be read and content to be parsed.
       
   543 @param aFileName The filename.
       
   544 */
       
   545 	{
       
   546 	iCmiFile = C32ParseIniFile::NewL(aFileName, aFileServer);
       
   547 	RetrieveAttributesL();
       
   548 	}
       
   549 
       
   550 
       
   551 TBool C32CmiData::FindVar(const TDesC8 &aSection,const TDesC8 &aVarName,TPtrC8 &aResult)
       
   552 /** Find a variable's value given a section name and a var name.
       
   553 @param aSection The section to search.
       
   554 @param aVarName The name to find.
       
   555 @param aResult The result.
       
   556 @return Success or fail.
       
   557 */
       
   558 	{
       
   559 	return iCmiFile->FindVar(aSection, aVarName, aResult);
       
   560 	}
       
   561 
       
   562 TBool C32CmiData::FindVar(const TDesC8 &aSection,const TDesC8 &aVarName,TInt &aResult)
       
   563 /**
       
   564 @param aSection The section to search.
       
   565 @param aVarName The name to find.
       
   566 @param aResult The result.
       
   567 @return Success or fail.
       
   568 */
       
   569 	{
       
   570 	return iCmiFile->FindVar(aSection, aVarName, aResult);
       
   571 	}
       
   572 
       
   573 HBufC8* C32CmiData::IniDataL()
       
   574 /**
       
   575 @return Pointer to the ini data.
       
   576 */
       
   577 	{
       
   578 
       
   579 	if((!AttrIsSet(AttrIniDataFile)) && (!AttrIsSet(AttrIniData)))
       
   580 		{
       
   581 		return NULL;
       
   582 		}
       
   583 
       
   584 	// If there was a inidata file specified we read that one, ignoring any inidata section
       
   585 	if(AttrIsSet(AttrIniDataFile))
       
   586 		{
       
   587 
       
   588 		// Open fileserver sesion
       
   589 		TInt result=KErrNone;
       
   590 		TAutoClose<RFs> fs;
       
   591 		if(KErrNone!=(result=fs.iObj.Connect()))
       
   592 			{
       
   593 			__FLOG( _L( "Unable to connect to the File Server" ) );
       
   594 			User::Leave(result);
       
   595 			}
       
   596 		fs.PushL();
       
   597 
       
   598 		// Open File and read content
       
   599 		TInt size = 0;
       
   600 		TAutoClose<RFile> rfile;
       
   601 		TFileName fileName;
       
   602 		fileName.Copy(iAttrIniDataFile);
       
   603 		result = rfile.iObj.Open(fs.iObj, fileName, EFileShareReadersOnly);
       
   604 
       
   605 		if(KErrNone!=result)
       
   606 			{
       
   607 			__FLOG_1(_L("Couldn't open inidata file %S"), &iAttrIniDataFile);
       
   608 			User::Leave(result);
       
   609 			}
       
   610 		else
       
   611 			{
       
   612 			rfile.PushL();
       
   613 			// Get filesize for allocating the buffer
       
   614 			result=rfile.iObj.Size(size);
       
   615 
       
   616 			if(size<=0)
       
   617 				{
       
   618 				__FLOG_1(_L("Inidata file %S has no contents"), &iAttrIniDataFile);
       
   619 				User::Leave(KErrCorrupt);
       
   620 				}
       
   621 
       
   622 			// Allocate buffer and read data
       
   623 			HBufC8* iniData = HBufC8::NewL(size);
       
   624 			CleanupStack::PushL(iniData);
       
   625 			TPtr8 fileDataPtr = iniData->Des();
       
   626 			result = rfile.iObj.Read(fileDataPtr);
       
   627 
       
   628 			if(KErrNone!=result)
       
   629 				{
       
   630 				__FLOG_1(_L("Couldn't read Inidata file %S"), &iAttrIniDataFile);
       
   631 				User::Leave(result);
       
   632 				}
       
   633 
       
   634 			rfile.Pop();
       
   635 			CleanupStack::Pop(iniData);
       
   636 			return iniData;
       
   637 			}
       
   638 		}
       
   639 	// else the inidata is embedded in the file
       
   640 	// If inidata section is empty just return NULL, this is non-critical
       
   641 	if(iAttrIniData.Length()<=0)
       
   642 		{
       
   643 		return NULL;
       
   644 		}
       
   645 
       
   646 	// Allocate heap buffer with room for data and return it
       
   647 	// IniData is required to be Narrow...
       
   648 	HBufC8* iniData = iAttrIniData.AllocL();
       
   649 	return iniData;
       
   650 	}
       
   651 
       
   652 void C32CmiData::SplitBindingL(TPtrC8 aSource, TPtrC8& aAddr1, TPtrC8& aAddr2,
       
   653      TPtrC8& aType, TInt& aForwardQLength, TInt& aReverseQLength)
       
   654 /** Identifies the various components of a line specifying a binding.
       
   655 @param aSource The line to parse.
       
   656 @param aAddr1 Pointer to name.
       
   657 @param aAddr2 Pointer to name.
       
   658 @param aType Pointer to binding type.
       
   659 @leave KErrCorrupt
       
   660 */
       
   661 	{
       
   662 
       
   663 	TPtrC8 temp;
       
   664 	TPtrC8 tempNum;
       
   665 	TLex8 lex;
       
   666 	TInt pos = aSource.Locate(',');
       
   667     //Set aAddr1
       
   668 	if((pos==KErrNotFound) || (pos==0))
       
   669 		{
       
   670 		__FLOG(_L("Binding string corrupt"));
       
   671 		User::Leave(KErrCorrupt);
       
   672 		}
       
   673 	aAddr1.Set(aSource.Ptr(), pos);
       
   674 
       
   675 	//Set aAddr2
       
   676 	if (pos < aSource.Length())
       
   677 		{
       
   678 		temp.Set(aSource.Ptr() + pos + 1, aSource.Length() - pos -1);
       
   679 	    pos = temp.Locate(',');
       
   680 		}
       
   681 	else
       
   682 		{
       
   683 		pos = KErrNotFound;
       
   684 		}
       
   685 	if((pos==KErrNotFound) || (pos==0))
       
   686 		{
       
   687 		__FLOG(_L("Binding string corrupt"));
       
   688 		User::Leave(KErrCorrupt);
       
   689 		}
       
   690 	aAddr2.Set(temp.Ptr(), pos);
       
   691 
       
   692 	//Set aType
       
   693 	if (pos < temp.Length())
       
   694 		{
       
   695 		temp.Set(temp.Ptr() + pos + 1,temp.Length() - pos - 1);
       
   696 		pos = temp.Locate(',');
       
   697 		}
       
   698 	else
       
   699 		{
       
   700 		pos = KErrNotFound;
       
   701 		}
       
   702 	if((pos==KErrNotFound) || (pos==0))
       
   703 		{
       
   704 		__FLOG(_L("Binding string corrupt"));
       
   705 		User::Leave(KErrCorrupt);
       
   706 		}
       
   707 	aType.Set(temp.Ptr(), pos);
       
   708 
       
   709 	//Set aForwardQLength
       
   710 	if (pos < temp.Length())
       
   711 		{
       
   712 		temp.Set(temp.Ptr() + pos + 1,temp.Length() - pos - 1);
       
   713 		pos = temp.Locate(',');
       
   714 		}
       
   715 	else
       
   716 		{
       
   717 		pos = KErrNotFound;
       
   718 		}
       
   719 	if((pos==KErrNotFound) || (pos==0))
       
   720 		{
       
   721 		__FLOG(_L("Binding - no Forward queue length specified set to default of 1"));
       
   722 		aForwardQLength = 1;
       
   723 		aReverseQLength = 1;
       
   724 		return;
       
   725 		}
       
   726 	tempNum.Set(temp.Ptr(),pos);
       
   727 	lex.Assign(tempNum);
       
   728 	if (lex.Val(aForwardQLength) != KErrNone)
       
   729 		{
       
   730 		__FLOG(_L("Binding string corrupt - ForwardQLength Invalid"));
       
   731 		User::Leave(KErrCorrupt);
       
   732 		}
       
   733 
       
   734 	//Set aReverseQLength
       
   735 	if (pos < temp.Length())
       
   736 		{
       
   737 		temp.Set(temp.Ptr() + pos + 1,temp.Length() - pos - 1);
       
   738 		pos = temp.Length();
       
   739 		}
       
   740 	else
       
   741 		{
       
   742 		pos = KErrNotFound;
       
   743 		__FLOG(_L("Binding - no Reverse queue length specified set to default of 1"));
       
   744 		aReverseQLength = 1;
       
   745 		return;
       
   746 		}
       
   747 	tempNum.Set(temp.Ptr(),pos);
       
   748 	lex.Assign(tempNum);
       
   749 	if (lex.Val(aReverseQLength) != KErrNone)
       
   750 		{
       
   751 		__FLOG(_L("Binding string corrupt - ForwardQLength Invalid"));
       
   752 		User::Leave(KErrCorrupt);
       
   753 		}
       
   754 
       
   755 	}
       
   756 
       
   757 void C32CmiData::MakeAddressL(const TPtrC8& aAddress, TCFSubModuleAddress& aSubModuleAddress)
       
   758 /** Generate an aAddress from a string.
       
   759 @param aAddress Pointer to string name.
       
   760 @param aSubModuleAddress The value to be filled and returned.
       
   761 @leave KErrCorrupt
       
   762 */
       
   763 	{
       
   764 	TCFModuleNameF name;
       
   765 	TCFModuleNameF subName;
       
   766 	TInt pos = aAddress.Locate(':');
       
   767 	if((pos==KErrNotFound) || (pos==0))
       
   768 		{
       
   769 		__FLOG(_L("Binding string corrupt"));
       
   770 		User::Leave(KErrCorrupt);
       
   771 		}
       
   772 	TPtrC8 tempptr(aAddress.Ptr(), pos);
       
   773 	name.Copy(tempptr);
       
   774 	name.TrimLeft();
       
   775 	name.TrimRight();
       
   776 	if(name.Length()<=0)
       
   777 		{
       
   778 		__FLOG(_L("Binding string corrupt"));
       
   779 		User::Leave(KErrCorrupt);
       
   780 		}
       
   781 	pos++;
       
   782 	if(aAddress.Length()<=pos)
       
   783 		{
       
   784 		__FLOG(_L("Binding string corrupt"));
       
   785 		User::Leave(KErrCorrupt);
       
   786 		}
       
   787 	tempptr.Set(aAddress.Ptr()+pos, aAddress.Length()-pos);
       
   788 	subName.Copy(tempptr);
       
   789 	subName.TrimLeft();
       
   790 	subName.TrimRight();
       
   791 	aSubModuleAddress.SetModule(name);
       
   792 	aSubModuleAddress.SetSubModule(subName);
       
   793 	}
       
   794 
       
   795 TRSBindType C32CmiData::MakeBindingTypeL(const TDesC8& aTxtType)
       
   796 /** Generate a bindtype object from a string.
       
   797 @param aTxtType The type of binding required in text form.
       
   798 @return Type of binding.
       
   799 @leave KErrCorrupt
       
   800 */
       
   801 	{
       
   802 	TBuf8<32> buf=aTxtType;
       
   803 	buf.TrimLeft();
       
   804 	buf.TrimRight();
       
   805 	buf.LowerCase();
       
   806 
       
   807     _LIT8(KEHierarchical, "ehierarchical");
       
   808     _LIT8(KECustom, "ecustom");
       
   809 
       
   810 	if(0==buf.CompareF(KEHierarchical))
       
   811 		{
       
   812 		return EHierarchical;
       
   813 		}
       
   814 
       
   815 	if(0==buf.CompareF(KECustom))
       
   816 		{
       
   817 		return ECustom;
       
   818 		}
       
   819 
       
   820 	__FLOG(_L("Binding type string corrupt"));
       
   821 	User::Leave(KErrCorrupt);
       
   822 	return ECustom;		//lint !e527 // LINT knows that we can't get here, but the compiler doesn't
       
   823 	}
       
   824 
       
   825 TBool C32CmiData::NextBindingL(TRSBindingInfo& aBinding, TBool aReset/*=EFalse*/)
       
   826 /** Find the next binding.
       
   827 @param aBinding The bindinfo struct to be filled with a found binding.
       
   828 @param TBool aReset Indicates sequence of call to this function - first
       
   829 has aReset=ETrue.
       
   830 @return Found or not.
       
   831 */
       
   832 	{
       
   833 
       
   834 	if(aReset)
       
   835 		{
       
   836 		iNextBinding=0;
       
   837 		}
       
   838 
       
   839 	TBuf8<C32ParseIniFile::KTokenSize> buf;
       
   840 	_LIT8(bindingTgt,"Binding%d");
       
   841 	buf.Format(bindingTgt, iNextBinding);
       
   842 	TPtrC8 ptr(NULL, 0);
       
   843 	TBool found;
       
   844 
       
   845 	// Get next BindingX string
       
   846 	if((found = FindVar(KSectionLoader, buf, ptr)) != EFalse)
       
   847 		{
       
   848 		__FLOG_2(_L8("Found binding: %S=%S"), &buf, &ptr);
       
   849 		++iNextBinding;
       
   850 		TPtrC8 addr1;
       
   851 		TPtrC8 addr2;
       
   852 		TPtrC8 type;
       
   853 		TInt forwardQLength;
       
   854 		TInt reverseQLength;
       
   855 		SplitBindingL(ptr, addr1, addr2, type,
       
   856 		forwardQLength,reverseQLength); // Split into sections between ','
       
   857 
       
   858 		TCFSubModuleAddress address;
       
   859 		MakeAddressL(addr1, address);
       
   860 		aBinding.iParams.iAddress1=address;
       
   861 
       
   862 		MakeAddressL(addr2, address);
       
   863 		aBinding.iParams.iAddress2=address;
       
   864 
       
   865 		aBinding.iParams.iType=MakeBindingTypeL(type);
       
   866 
       
   867 		aBinding.iParams.iForwardQLength = forwardQLength;
       
   868 		aBinding.iParams.iReverseQLength = reverseQLength;
       
   869 		}
       
   870 	return found;
       
   871 	}
       
   872 
       
   873