messagingfw/biomsgfw/BDBSRC/BIODB.CPP
changeset 62 db3f5fa34ec7
parent 0 8e480a14352b
equal deleted inserted replaced
60:9f5ae1728557 62:db3f5fa34ec7
       
     1 // Copyright (c) 1999-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 // BIODB.CPP
       
    15 //
       
    16 
       
    17 #include "BIODB.H"
       
    18 #include "BDBPAN.H"
       
    19 #include "cbifentry.h"
       
    20 
       
    21 #include <s32file.h>		// CFileStore
       
    22 #include <bautils.h>
       
    23 
       
    24 #include <basched.h>
       
    25 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS 
       
    26 #include <bifchangeobserver.h>
       
    27 #endif
       
    28 
       
    29 //
       
    30 // Globals & Constants
       
    31 //
       
    32 // Old search paths are /system/bif
       
    33 // New (platsec) search paths are /resource/messaging/bif
       
    34 
       
    35 _LIT(KSecureBifPath, "\\resource\\messaging\\Bif\\");     
       
    36 _LIT(KSecureBifSearchString, "?:\\resource\\messaging\\Bif\\");
       
    37 
       
    38 _LIT(KLanguageFileExt, ".r");
       
    39 _LIT(KDotRsc, ".rsc");
       
    40 
       
    41 // 30 seconds between attempts to scan drives if we get completed with an error,
       
    42 const TInt KBifRetryTimeOut=30000000;
       
    43 // Maximam attempts to scan drives if we get completed with an error,
       
    44 const TInt KMaxRetries = 1;
       
    45 
       
    46 // default size of array of entries in a bif directory
       
    47 const TInt KBifEntryArrayDefaultSize=5;
       
    48 const TInt KMinFileNameLength = 5;
       
    49 
       
    50 /*
       
    51  *	CBifChangeObserver
       
    52  */
       
    53  
       
    54 /** Allocates and constructs a new BIF change observer.
       
    55 
       
    56 @param	aObserver 
       
    57 Callback interface to notify when a change occurs
       
    58 
       
    59 @param	afileSystem 
       
    60 Connected file system handle
       
    61 
       
    62 @return 
       
    63 New BIF change observer 
       
    64 */
       
    65 EXPORT_C CBifChangeObserver* CBifChangeObserver::NewL(MBifChangeObserver& aObserver, RFs& aFs)
       
    66 	{
       
    67 	CBifChangeObserver* self=new(ELeave) CBifChangeObserver(aObserver, aFs);
       
    68 	CleanupStack::PushL(self);
       
    69 	self->ConstructL();
       
    70 	CleanupStack::Pop(self);
       
    71 	return self;
       
    72 	}
       
    73 
       
    74 void CBifChangeObserver::ConstructL()
       
    75 	{
       
    76 	iBioDB = CBIODatabase::NewL(iFs);
       
    77 	User::LeaveIfError(iTimer.CreateLocal());
       
    78 	}
       
    79 
       
    80 CBifChangeObserver::CBifChangeObserver(MBifChangeObserver& aObserver, RFs& aFs)
       
    81 : CActive(EPriorityStandard), iChangeObserver(aObserver), iFs(aFs)
       
    82 	{
       
    83 	CActiveScheduler::Add(this);
       
    84 	}
       
    85 
       
    86 /** Destructor. */
       
    87 CBifChangeObserver::~CBifChangeObserver()
       
    88 	{
       
    89 	Cancel();
       
    90 	iTimer.Close();
       
    91 	delete iBioDB;
       
    92 	iEntries.ResetAndDestroy();
       
    93 	}
       
    94 
       
    95 /** Starts the object watching for changes.
       
    96 
       
    97 To stop the object, simply delete it.
       
    98 */
       
    99 EXPORT_C void CBifChangeObserver::Start()
       
   100 	{
       
   101 	// just complete myself so that RunL builds the list of entries and asks the file
       
   102 	// sever to notify us of changes.
       
   103 	TRequestStatus *status=&iStatus;
       
   104 	User::RequestComplete(status,KErrNone);
       
   105 	SetActive();
       
   106 	}
       
   107 
       
   108 void CBifChangeObserver::RunL()
       
   109 	{
       
   110 	TInt err=KErrNone;
       
   111 	if(iStatus.Int()==KErrNone)
       
   112 		{
       
   113 		// ignore the error
       
   114 		TRAP(err, DoRunL());
       
   115 		}
       
   116 #ifdef _DEBUG
       
   117  	else
       
   118 		{
       
   119 		// I don't expect to get here, it means that RFs::NotifyChangeL has completed
       
   120 		// this class with an error, which means we would loop rather quickly.
       
   121 		User::Invariant();
       
   122 		}
       
   123 #endif
       
   124 	
       
   125 	if((iStatus.Int() != KErrNone || err != KErrNone) && iRetryCount < KMaxRetries)
       
   126 		{
       
   127 		iTimer.After(iStatus,KBifRetryTimeOut);
       
   128 		iRetryCount ++;
       
   129 		SetActive();
       
   130 		}
       
   131 	else
       
   132 		{
       
   133 		WaitForFileNotification();	
       
   134 		iRetryCount = 0;
       
   135 		}
       
   136 	}
       
   137 
       
   138 void CBifChangeObserver::DoRunL()
       
   139     {
       
   140     TBool notify=EFalse;
       
   141 	// build a list of all the TEntrys in KBifPath on all drives/
       
   142 	RPointerArray<CBifEntry> entryList(KBifEntryArrayDefaultSize);
       
   143 	TCleanupItem cleanup(CleanupBifArray, &entryList);
       
   144 	CleanupStack::PushL(cleanup);
       
   145 	
       
   146 	TFindFile fileFinder(iFs);     
       
   147 	CDir *dir=NULL;     
       
   148 	// Scan this folder from V1.5 onwards
       
   149 	TInt err = fileFinder.FindWildByDir(_L("*"),KSecureBifPath,dir);
       
   150 	while(err==KErrNone)
       
   151 		{
       
   152 		CleanupStack::PushL(dir);
       
   153 		TInt count=dir->Count();
       
   154 		while(count--)
       
   155 			{
       
   156 			CBifEntry* bifEntry = CBifEntry::NewLC((*dir)[count]);
       
   157 			entryList.AppendL(bifEntry);
       
   158 			CleanupStack::Pop(bifEntry);
       
   159 			}
       
   160 		CleanupStack::PopAndDestroy(dir);
       
   161 		err=fileFinder.Find();
       
   162 		} 
       
   163 	
       
   164 	if (err != KErrNotFound)
       
   165 		User::LeaveIfError(err);
       
   166 
       
   167 	// Check to see if iEntries matches entryList
       
   168 	if(iEntries.Count()!=0) // iEntries is empty the first time in so don't notify anyone.
       
   169 		{
       
   170 		// check to see if the two lists of entries are the same
       
   171 		if(iEntries.Count()!=entryList.Count())
       
   172 			notify=ETrue;  // not the same if one is larger than the other
       
   173 		else
       
   174 			{
       
   175 			TInt count=entryList.Count();
       
   176 			while(count-- && notify==EFalse)
       
   177 				{
       
   178 				TInt index;
       
   179 				TInt found=FindEntry(*(entryList)[count],iEntries,index);
       
   180 				if(found==KErrNone)
       
   181 					{
       
   182 					delete (iEntries)[index];
       
   183 					iEntries.Remove(index);
       
   184 					}
       
   185 				else
       
   186 					notify=ETrue; // not the same if entryList contains something not in iEntries
       
   187 				}
       
   188 			if(iEntries.Count()!=0)
       
   189 				notify=ETrue; // not the same if iEntries contains something not in entryList;
       
   190 			}
       
   191 		}
       
   192 		
       
   193 	// replace old iEntries with new entryList
       
   194 	CleanupStack::Pop(&entryList);
       
   195 	iEntries.ResetAndDestroy();
       
   196 	iEntries=entryList;
       
   197 	
       
   198 	// notify observers if iEntries was != entryList;
       
   199 	if(notify!=EFalse) 
       
   200 		NotifyObserverL();
       
   201 	}
       
   202 
       
   203 TInt CBifChangeObserver::FindEntry(const CBifEntry& aBifEntry, const RPointerArray<CBifEntry>& aEntries, TInt& aIndex) const
       
   204 	{
       
   205 	aIndex = aEntries.Count();
       
   206 
       
   207 	while (aIndex--)
       
   208 		{
       
   209 		if ( aBifEntry == *aEntries[aIndex] )
       
   210 			{
       
   211 			return KErrNone;
       
   212 			}
       
   213 		}
       
   214 
       
   215 	return KErrNotFound;
       
   216 	}
       
   217 
       
   218 void CBifChangeObserver::WaitForFileNotification()
       
   219 	{
       
   220 	// Observe this folder from V1.5 onwards
       
   221 	iFs.NotifyChange(ENotifyAll, iStatus, KSecureBifSearchString);
       
   222 	SetActive();
       
   223 	}
       
   224 
       
   225 void CBifChangeObserver::DoCancel()
       
   226 	{
       
   227     iTimer.Cancel();
       
   228 	
       
   229 	iFs.NotifyChangeCancel(iStatus);	// Cancel only the specific
       
   230 										// request made by this observer
       
   231 	}
       
   232 
       
   233 TBool CBifChangeObserver::CompareReaders(const CBioInfoFileReader& aReader1, const CBioInfoFileReader& aReader2) const
       
   234 	{
       
   235 	TBool retVal = aReader1.BifEntry() == aReader2.BifEntry();
       
   236 
       
   237 	if (retVal)
       
   238 		{
       
   239 		//Compare the readers
       
   240 		retVal = 
       
   241 			   (aReader1.MessageParserName().Compare(aReader2.MessageParserName()) == 0)
       
   242 			&& (aReader1.MessageAppCtrlName().Compare(aReader2.MessageAppCtrlName()) == 0)
       
   243 			&& (aReader1.MessageAppUid() == aReader2.MessageAppUid())
       
   244 			&& (aReader1.GeneralData1() == aReader2.GeneralData1())
       
   245 			&& (aReader1.GeneralData2() == aReader2.GeneralData2())
       
   246 			&& (aReader1.GeneralData3() == aReader2.GeneralData3())
       
   247 			&& (aReader1.IconsFilename().Compare(aReader2.IconsFilename()) == 0)
       
   248 			&& (aReader1.Description().Compare(aReader2.Description()) == 0);
       
   249 
       
   250 		//To Do: Should aReader1.IdsLC() and aReader2.IdsLC() be compared?
       
   251 		}
       
   252 
       
   253 	return retVal;
       
   254 	}
       
   255 
       
   256 void CBifChangeObserver::NotifyObserverL()
       
   257 	{
       
   258 	CArrayFixFlat<TUid>* addedBifs = new (ELeave) CArrayFixFlat<TUid>(1);
       
   259 	CleanupStack::PushL(addedBifs);
       
   260 
       
   261 	CArrayFixFlat<TUid>* changedBifs = new (ELeave) CArrayFixFlat<TUid>(1);
       
   262 	CleanupStack::PushL(changedBifs);
       
   263 
       
   264 	CArrayFixFlat<TUid>* deletedBifs = new (ELeave) CArrayFixFlat<TUid>(1);
       
   265 	CleanupStack::PushL(deletedBifs);
       
   266 
       
   267 	// Figure out what kind of change really happened here
       
   268 	CBIODatabase* newBioDB = CBIODatabase::NewL(iFs);
       
   269 	CleanupStack::PushL(newBioDB);
       
   270 
       
   271 
       
   272 	TInt err = KErrNone;
       
   273 
       
   274 	TUid uid;
       
   275 	TInt index = 0;
       
   276 	TKeyArrayFix key(0, ECmpTInt);
       
   277 	TInt count = newBioDB->BIOCount();
       
   278 	
       
   279 	while (count--)
       
   280 		{
       
   281 		newBioDB->GetBioMsgID(count, uid);
       
   282 		TRAP(err, iBioDB->GetBioIndexWithMsgIDL(uid, index));
       
   283 		
       
   284 		if (err)
       
   285 			{
       
   286 			//BIF in New BIO DB not found in Old BIO DB
       
   287 			addedBifs->InsertIsqL(uid, key);
       
   288 			}
       
   289 		else
       
   290 			{
       
   291 			
       
   292 			//BIF in both BIO DBs, therefore check to see if the files have changed
       
   293 			if  (!CompareReaders(iBioDB->BifReader(index), newBioDB->BifReader(count)))
       
   294 				{
       
   295 				changedBifs->InsertIsqL(uid, key);
       
   296 				}
       
   297 
       
   298 			//Remove this BIF from the Old BIO DB for efficiency in the next while loop.
       
   299 			iBioDB->RemoveBifL(index);
       
   300 			}
       
   301 		}
       
   302 
       
   303 	count = iBioDB->BIOCount();
       
   304 
       
   305 	while (count--)
       
   306 		{
       
   307 		//All remaining members of iBioDB are deleted BIFs
       
   308 		iBioDB->GetBioMsgID(count, uid);
       
   309 		deletedBifs->InsertIsqL(uid, key);
       
   310 		}
       
   311 
       
   312 	count = addedBifs->Count();
       
   313 
       
   314 	while (count--)
       
   315 		{
       
   316 		iChangeObserver.HandleBifChangeL(MBifChangeObserver::EBifAdded, addedBifs->At(count));
       
   317 		}
       
   318 
       
   319 	count = deletedBifs->Count();
       
   320 
       
   321 	while (count--)
       
   322 		{
       
   323 		iChangeObserver.HandleBifChangeL(MBifChangeObserver::EBifDeleted, deletedBifs->At(count));
       
   324 		}
       
   325 
       
   326 	count = changedBifs->Count();
       
   327 
       
   328 	while (count--)
       
   329 		{
       
   330 		iChangeObserver.HandleBifChangeL(MBifChangeObserver::EBifChanged, changedBifs->At(count));
       
   331 		}
       
   332 
       
   333 	// update the list we're holding onto
       
   334 	delete iBioDB;
       
   335 	iBioDB = newBioDB;
       
   336 	
       
   337 	CleanupStack::Pop(); //newBioDB
       
   338   	CleanupStack::PopAndDestroy(3); //arrays
       
   339 	}
       
   340 	
       
   341 void CBifChangeObserver::CleanupBifArray( TAny* aBifArray )
       
   342 	{
       
   343 	RPointerArray<CBifEntry>* bifArray = static_cast<RPointerArray<CBifEntry>*>(aBifArray);
       
   344 	bifArray->ResetAndDestroy();
       
   345 	}
       
   346 
       
   347 //
       
   348 // CBIODatabase
       
   349 //
       
   350 
       
   351 //
       
   352 // Construction
       
   353 //	protected
       
   354 //
       
   355 CBIODatabase::CBIODatabase()
       
   356 	{
       
   357 	// We're a CBase derived class so we can assume that our data members are intialized to 0
       
   358 	}
       
   359 
       
   360 //
       
   361 EXPORT_C CBIODatabase* CBIODatabase::NewLC(RFs& afileSystem)
       
   362 /** Allocates and constructs a new BIO database object, leaving the object on the 
       
   363 cleanup stack.
       
   364 
       
   365 It initialises the object from all the BIF files in the system\\bif directory.
       
   366 
       
   367 @param afileSystem Connected file system handle
       
   368 @return New BIO database object */
       
   369 	{
       
   370 	CBIODatabase* self=new(ELeave) CBIODatabase();
       
   371 	CleanupStack::PushL(self);
       
   372 	self->ConstructL(afileSystem);
       
   373 	return self;
       
   374 	}
       
   375 
       
   376 //
       
   377 EXPORT_C CBIODatabase* CBIODatabase::NewL(RFs& afileSystem)
       
   378 /** Allocates and constructs a new BIO database object.
       
   379 
       
   380 It initialises the object from all the BIF files in the system\\bif directory.
       
   381 
       
   382 @param afileSystem Connected file system handle
       
   383 @return New BIO database object */
       
   384 	{
       
   385 	CBIODatabase* self=CBIODatabase::NewLC(afileSystem);
       
   386 	CleanupStack::Pop();		// self
       
   387 	return self;
       
   388 	}
       
   389 
       
   390 //
       
   391 // Construction/destruction
       
   392 void CBIODatabase::ConstructL(RFs& afileSystem)
       
   393 	{
       
   394 	// put the real construction here
       
   395 	iBifReaders= new (ELeave) CArrayPtrFlat<CBioInfoFileReader>(10);
       
   396 	AddAllBifsL(afileSystem);
       
   397 	}
       
   398 
       
   399 //
       
   400 // Construction/destruction
       
   401 EXPORT_C CBIODatabase::~CBIODatabase()
       
   402 /** Destructor. */
       
   403 	{
       
   404 	if (iBifReaders)
       
   405 		iBifReaders->ResetAndDestroy();
       
   406 	delete iBifReaders;
       
   407 	}
       
   408 
       
   409 
       
   410 //
       
   411 EXPORT_C TInt CBIODatabase::BIOCount()
       
   412 /** Gets the number of BIF files.
       
   413 
       
   414 @return Number of BIF files */
       
   415 	{
       
   416 	return iBifReaders->Count();
       
   417 	}
       
   418 
       
   419 //
       
   420 EXPORT_C void CBIODatabase::AddAllBifsL(RFs& afileSystem)
       
   421 /** Initialises the object from all the BIF files in the system\\bif or resource\\messaging\\bif directory.
       
   422 
       
   423 @param afileSystem Connected file system handle */
       
   424 	{
       
   425 	// Walk through all the BIF Files, adding each one
       
   426 	// to the iBifReaders array
       
   427 	TDriveList drvList;
       
   428 
       
   429 	// User::LeaveIfError(afileSystem.Connect());
       
   430 	User::LeaveIfError(afileSystem.DriveList(drvList));
       
   431 
       
   432 	for (TInt n=0 ; n<KMaxDrives ; ++n)
       
   433 		{
       
   434 		if (drvList[n]!=0)
       
   435 			{
       
   436 			TDriveInfo driveinfo;
       
   437 			TInt ret=afileSystem.Drive(driveinfo,n);
       
   438 			if ((ret==KErrNone) && (driveinfo.iType!=EMediaNotPresent) && (driveinfo.iType!=EMediaRemote) 
       
   439 												&& (!(driveinfo.iMediaAtt & KMediaAttLocked)) )
       
   440 				{
       
   441 				TDriveUnit driveUnit(n);
       
   442 				TPath fullPath; // Length must hold x:\resource\messaging\bif\ 
       
   443 				fullPath.FillZ();
       
   444 				fullPath = driveUnit.Name();
       
   445 				fullPath += KSecureBifPath;
       
   446 
       
   447 				if (afileSystem.SetSessionPath(fullPath) == KErrNone)
       
   448 					{
       
   449 					CDir* entryList = NULL;
       
   450 
       
   451 					// Walk through all the BIF Files, adding each one
       
   452 
       
   453  					ret = afileSystem.GetDir( fullPath,
       
   454 											  KEntryAttNormal|KEntryAttAllowUid,
       
   455 											  ESortByDate,
       
   456 											  entryList );
       
   457 					if (ret==KErrNone)
       
   458 						{
       
   459 						CleanupStack::PushL(entryList);
       
   460 						TInt cnt = entryList->Count();
       
   461 						for (TInt i = 0; i < cnt; ++i)
       
   462 							{
       
   463 							// get the file
       
   464 							TEntry entry = (*entryList)[i];
       
   465 							
       
   466 								TFileName fileName(fullPath);
       
   467 								fileName.Append(entry.iName);
       
   468 
       
   469 								// Remove localization index from the filename and replace it with "rsc"
       
   470 								// example, abc.r05 -> abc.rsc
       
   471 								TInt extLength(0);
       
   472 								if ( IsLanguageFileL(entry.iName, extLength) && (fileName.Length() >= KMinFileNameLength) )
       
   473 									{
       
   474 									fileName.Replace(fileName.Length() - extLength, extLength, KDotRsc);
       
   475 									}
       
   476 								// Use the file most appropriate to the current language
       
   477 								BaflUtils::NearestLanguageFile(afileSystem,fileName);
       
   478 
       
   479 								// Load the bif file
       
   480 								CBioInfoFileReader* bifReader = NULL;
       
   481 								TRAPD(error, bifReader=CBioInfoFileReader::NewL(afileSystem,fileName));
       
   482 								if (!error)
       
   483 									{
       
   484 									AddBifL(bifReader);									
       
   485 									}
       
   486 								else
       
   487 									{
       
   488 									// Ignore corrupt files
       
   489 									delete bifReader;
       
   490 
       
   491 									if (error != KErrCorrupt && error != KErrExtended && error != KErrNotFound)
       
   492 										{
       
   493 										User::LeaveIfError(error);
       
   494 										}
       
   495 									}
       
   496 							}
       
   497 						CleanupStack::PopAndDestroy(entryList); 
       
   498 						}
       
   499 					}
       
   500 				}
       
   501 				if (!(ret==KErrNone || 
       
   502 					  ret==KErrPathNotFound || 
       
   503 					  ret==KErrNotFound || 
       
   504 					  ret==KErrNotReady  || 
       
   505 					  ret==KErrCorrupt ||
       
   506 					  ret==KErrInUse ||
       
   507 					  ret==KErrLocked || 
       
   508 					  ret==KErrNotSupported))
       
   509 					{
       
   510 					User::LeaveIfError(ret);
       
   511 					}
       
   512 			}
       
   513 		}
       
   514 
       
   515 	}
       
   516 
       
   517 // Is the file a language file
       
   518 TBool CBIODatabase::IsLanguageFileL(const TDesC& aFileName, TInt& aExtLength) const
       
   519 	{
       
   520 	// Check the extension to see if it's a language file. we
       
   521  	// have to assume ".rXXX" is a resource file
       
   522  	TParse parse;
       
   523  	User::LeaveIfError(parse.Set(aFileName, NULL, NULL));
       
   524 	aExtLength=parse.Ext().Length();
       
   525  	return parse.Ext().Left(2).CompareF(KLanguageFileExt) == 0;
       
   526 	}
       
   527 
       
   528 //
       
   529 // This will add the Parser
       
   530 // Error returned
       
   531 EXPORT_C void CBIODatabase::AddBifL(CBioInfoFileReader* aBifReader)
       
   532 /** Adds a specified BIF.
       
   533 
       
   534 @param abifReader BIF file to add */
       
   535 	{
       
   536 	// This will manage the array - if a conflicting message
       
   537 	// id comes in, it will take the one with higher confidence
       
   538 	// or if a tie, the first one in
       
   539 	CleanupStack::PushL(aBifReader);
       
   540 
       
   541 	// Check if we have a reader with this message id
       
   542 	TInt index = 0;
       
   543     
       
   544 	TRAPD(leaveValue,GetBioIndexWithMsgIDL(aBifReader->MessageTypeUid(), index));
       
   545     
       
   546 	// We haven't read a BIF with the msgID in yet
       
   547 	if (leaveValue == KErrNotFound)
       
   548 		{
       
   549 		// just add it
       
   550 		iBifReaders->AppendL(aBifReader);
       
   551 		CleanupStack::Pop(); // aBifReader
       
   552 		}
       
   553 	else
       
   554 		{
       
   555 		CApaDataRecognizerType::TRecognitionConfidence newBifConf, oldBifConf;
       
   556 
       
   557 		// If we do have a match, take the one with higher confidence
       
   558 		const CArrayFix<TBioMsgId>* msgIDArray = BIOEntryLC(index);
       
   559 		oldBifConf = (*msgIDArray)[0].iConfidence;
       
   560 		CleanupStack::PopAndDestroy(); //msgIDArray
       
   561 		
       
   562 		newBifConf = (*(aBifReader->IdsLC()))[0].iConfidence; 
       
   563 		CleanupStack::PopAndDestroy(); //IdsLC
       
   564 		
       
   565 		if ( newBifConf > oldBifConf )
       
   566 			{
       
   567 			CleanupStack::PushL(aBifReader);
       
   568 			RemoveBifL(aBifReader->MessageTypeUid());
       
   569 			iBifReaders->AppendL(aBifReader);
       
   570 			CleanupStack::Pop();	// aBifReader
       
   571 			}
       
   572 		else
       
   573 			CleanupStack::PopAndDestroy();// aBifReader
       
   574 
       
   575 		}
       
   576 
       
   577 	}
       
   578 
       
   579 //
       
   580 // Error returned
       
   581 EXPORT_C void CBIODatabase::RemoveBifL(TUid aMsgID)
       
   582 /** Removes a BIF specified by UID.
       
   583 
       
   584 @param aMsgID BIO type UID */
       
   585 	{
       
   586 	TInt index = 0;
       
   587     
       
   588 	TRAPD(leaveValue,GetBioIndexWithMsgIDL(aMsgID, index));
       
   589     
       
   590 	// We haven't read a BIF with the msgID in yet
       
   591 	if (leaveValue == KErrNone)
       
   592 		{
       
   593 		// just remove it
       
   594 		RemoveBifL(index);
       
   595 		}
       
   596 	else
       
   597 		{
       
   598 		//__ASSERT_DEBUG(Panic(EBioDBNotFound));
       
   599 		}
       
   600 	}
       
   601 
       
   602 EXPORT_C void CBIODatabase::RemoveBifL(TInt aIndex)
       
   603 /** Removes a BIF specified by index.
       
   604 
       
   605 @param aIndex Index of file in this object */
       
   606 	{
       
   607 	CBioInfoFileReader *bifReader = iBifReaders->At(aIndex);
       
   608 	iBifReaders->Delete(aIndex);
       
   609 	delete bifReader;
       
   610 	}
       
   611 
       
   612 
       
   613 //
       
   614 // Get the BioEntry at this index
       
   615 // Return Index if found, error if not
       
   616 EXPORT_C const CBioInfoFileReader& CBIODatabase::BifReader(TInt aIndex) const
       
   617 /** Gets a BIF reader for a BIF at a specified index.
       
   618 
       
   619 @param aIndex Index
       
   620 @return BIF file reader */
       
   621 	{
       
   622 		__ASSERT_DEBUG(aIndex >= 0 && aIndex <= iBifReaders->Count(),
       
   623 								Panic(EBioDBNotFound));
       
   624 		return *iBifReaders->At(aIndex);
       
   625 	}
       
   626 
       
   627 //
       
   628 // Get the BioEntry at this index
       
   629 // Return Index if found, error if not
       
   630 EXPORT_C const CArrayFix<TBioMsgId>* CBIODatabase::BIOEntryLC(TInt index)
       
   631 /** Gets the ID array of a BIF at a specified index.
       
   632 
       
   633 @param index Index
       
   634 @return ID array, or NULL if not found */
       
   635 	{
       
   636 	if (index >= 0 && index < iBifReaders->Count())
       
   637 		{
       
   638 		return iBifReaders->At(index)->IdsLC();
       
   639 		}
       
   640 	else
       
   641 		return NULL;
       
   642 	}
       
   643 
       
   644 //
       
   645 // Get the Index for the BioMessageID
       
   646 EXPORT_C void CBIODatabase::GetBioIndexWithMsgIDL(TUid aMsgID, TInt& rIndex)
       
   647 /** Gets the index of a BIF of a specified BIO message type.
       
   648 
       
   649 @param aMsgID BIO message type
       
   650 @param rIndex On return, index of found BIF
       
   651 @leave KErrNotFound Not found */
       
   652 	{
       
   653 	rIndex = iBifReaders->Count();
       
   654 
       
   655 	// See if we have one of these Messages
       
   656 	while (rIndex--)
       
   657 		{
       
   658 		if ((*iBifReaders)[rIndex]->MessageTypeUid() == aMsgID)
       
   659 			{
       
   660 			return;
       
   661 			}
       
   662 		}
       
   663 	User::Leave(KErrNotFound);
       
   664 	}
       
   665 
       
   666 
       
   667 //
       
   668 // Get the BioMessageID for the Index
       
   669 EXPORT_C void CBIODatabase::GetBioMsgID(TInt aIndex, TUid& rMsgID)
       
   670 /** Gets the BIO message type for a specified index.
       
   671 
       
   672 @param aIndex Index
       
   673 @param rMsgID On return, BIO message type */
       
   674 	{
       
   675 	__ASSERT_DEBUG(aIndex >= 0 && aIndex <= iBifReaders->Count(),
       
   676 								Panic(EBioDBNotFound));
       
   677 	
       
   678 	rMsgID =  (*iBifReaders)[aIndex]->MessageTypeUid();
       
   679 	}
       
   680 
       
   681 
       
   682 //
       
   683 // Get the BioParserName for the Index
       
   684 EXPORT_C const TPtrC CBIODatabase::GetBioParserName(TInt aIndex)
       
   685 /** Gets the BIO parser name for a specified index.
       
   686 
       
   687 @param aIndex Index
       
   688 @return BIO parser name */
       
   689 	{
       
   690 	__ASSERT_DEBUG( aIndex >= 0 && aIndex <= iBifReaders->Count(),
       
   691 								Panic(EBioDBNotFound));
       
   692 	return (*iBifReaders)[aIndex]->MessageParserName();	
       
   693 	}
       
   694 	
       
   695 /** Depreacated method.
       
   696 
       
   697 Need to use CBIODatabase::GetBioControlName instead.
       
   698 
       
   699 @see CBIODatabase::GetBioControlName
       
   700 
       
   701 @param aIndex Not used
       
   702 @param rControlID Not used 
       
   703 
       
   704 @panic USER	EInvariantFalse
       
   705 
       
   706 @deprecated */
       
   707 EXPORT_C void CBIODatabase::GetBioControlID(TInt /*aIndex*/, TUid& /*rControlID*/)
       
   708 	{
       
   709 	User::Invariant();
       
   710 	}
       
   711 	
       
   712 /** Gets the BIO control name for a specified index.
       
   713 
       
   714 @param aIndex Index
       
   715 @return BIO control name */
       
   716 EXPORT_C const TPtrC CBIODatabase::GetBioControlName(TInt aIndex)
       
   717 	{
       
   718 	__ASSERT_DEBUG( aIndex >= 0 && aIndex <= iBifReaders->Count(), 
       
   719 								Panic(EBioDBNotFound));
       
   720 	return (*iBifReaders)[aIndex]->MessageAppCtrlName();
       
   721 	}
       
   722  
       
   723 
       
   724 //
       
   725 // Get the first Port Number for this messaga type 
       
   726 EXPORT_C void CBIODatabase::GetPortNumberL(TUid aMsgID, TBioMsgIdType aPortType, TInt& aPortNumber)
       
   727 /** Gets the port number for the BIF ID entry for a specified BIO message type 
       
   728 and bearer type.
       
   729 
       
   730 @param aMsgID BIO message type
       
   731 @param aPortType Bearer type
       
   732 @param aPortNumber On return, the port number
       
   733 @leave KErrNotFound Not found */
       
   734 	{
       
   735 	TInt index = 0;
       
   736 	GetBioIndexWithMsgIDL(aMsgID, index);
       
   737 	
       
   738 	// We haven't read a BIF with the msgID in yet
       
   739 	TBioMsgId tranportID;
       
   740 	GetTransportIDL(index, aPortType, tranportID);
       
   741 	aPortNumber = tranportID.iPort;
       
   742 	}
       
   743 
       
   744 
       
   745 //
       
   746 // Get the first ID String for this messaga type 
       
   747 EXPORT_C void CBIODatabase::GetIdentifierTextL(TUid aMsgID, TBioMsgIdType aPortType, TBioMsgIdText& aText)
       
   748 /** Gets the identifier text for the BIF ID entry for a specified BIO message type 
       
   749 and bearer type.
       
   750 
       
   751 @param aMsgID BIO message type
       
   752 @param aPortType Bearer type
       
   753 @param aText On return, the identifier text */
       
   754 	{
       
   755 	TInt index = 0;
       
   756 	GetBioIndexWithMsgIDL(aMsgID, index);
       
   757 	
       
   758 	TBioMsgId tranportID;
       
   759 	GetTransportIDL(index, aPortType, tranportID);
       
   760 	aText.Copy(tranportID.iText);
       
   761 	}
       
   762 
       
   763 //
       
   764 // Get the GetTransportIDL 
       
   765 void CBIODatabase::GetTransportIDL(TInt aIndex, TBioMsgIdType aPortType, TBioMsgId& aBioMsgID) 
       
   766 	{
       
   767 	TBioMsgId tranportID;
       
   768 	TBool found = EFalse;
       
   769 
       
   770 	const CArrayFix<TBioMsgId>* msgIDArray = BIOEntryLC(aIndex);
       
   771 
       
   772 	for (TInt i = 0; i < msgIDArray->Count() && !found ; i++)
       
   773 		{
       
   774 		if ( (*msgIDArray)[i].iType == aPortType)
       
   775 			{
       
   776 			tranportID = (*msgIDArray)[i];
       
   777 
       
   778 			// Really should make a copy contructor & = operator
       
   779 			aBioMsgID.iType = (*msgIDArray)[i].iType;
       
   780 			aBioMsgID.iConfidence = (*msgIDArray)[i].iConfidence;			
       
   781 			aBioMsgID.iText.Copy((*msgIDArray)[i].iText);
       
   782 			aBioMsgID.iPort = (*msgIDArray)[i].iPort;
       
   783 			aBioMsgID.iCharacterSet = (*msgIDArray)[i].iCharacterSet;
       
   784 			aBioMsgID.iGeneralIdData = (*msgIDArray)[i].iGeneralIdData;
       
   785 			found = ETrue;
       
   786 			}
       
   787 		}
       
   788 	CleanupStack::PopAndDestroy(); //msgIDArray
       
   789 	
       
   790 	if (!found)
       
   791 		User::Leave(KErrNotFound);
       
   792 	}
       
   793 
       
   794 
       
   795 //
       
   796 // Get the BioParserName for the Message ID
       
   797 EXPORT_C const TPtrC CBIODatabase::GetBioParserNameL(TUid aMsgID)
       
   798 /** Gets the BIO parser name for a specified BIO message type.
       
   799 
       
   800 @param aMsgID BIO message type
       
   801 @return BIO parser name
       
   802 @leave KErrNotFound Not found */
       
   803 	{
       
   804 	TInt index = 0;
       
   805 	TRAPD(leaveValue, GetBioIndexWithMsgIDL(aMsgID, index));
       
   806 
       
   807 	// We haven't read a BIF with the msgID in yet
       
   808 	if (leaveValue != KErrNone)
       
   809 		{
       
   810 		__ASSERT_DEBUG(0, Panic(EBioDBNotFound));
       
   811 		User::Leave(leaveValue);
       
   812 		}
       
   813 		
       
   814 	return GetBioParserName(index);
       
   815 	}
       
   816 
       
   817 
       
   818 /** Depreacated method.
       
   819 
       
   820 Need to use CBIODatabase::GetBioControlNameL instead.
       
   821 
       
   822 @see CBIODatabase::GetBioControlNameL
       
   823 
       
   824 @param aIndex Not used
       
   825 @param rControlID Not used
       
   826 
       
   827 @panic USER	EInvariantFalse
       
   828 
       
   829 @deprecated */
       
   830 EXPORT_C void CBIODatabase::GetBioControlIDL(TUid /*aMsgID*/, TUid& /*rControlID*/)
       
   831 	{
       
   832 	User::Invariant();
       
   833 	}
       
   834 	
       
   835 /** Gets the BIO control name for a specified BIO message type.
       
   836 
       
   837 @param aMsgID BIO message type
       
   838 @return BIO Control name
       
   839 
       
   840 @leave KErrNotFound BIO message type does not exist */
       
   841 EXPORT_C const TPtrC CBIODatabase::GetBioControlNameL(TUid aMsgID)
       
   842  	{
       
   843  	TInt index = 0;
       
   844 	TRAPD(leaveValue, GetBioIndexWithMsgIDL(aMsgID, index));
       
   845      
       
   846  	// We haven't read a BIF with the msgID in yet
       
   847 	if( leaveValue != KErrNone )
       
   848  		{
       
   849  		__ASSERT_DEBUG(0, Panic(EBioDBNotFound));
       
   850 		User::Leave(leaveValue);
       
   851  		}
       
   852 		
       
   853 	return GetBioControlName(index);
       
   854  	}
       
   855  
       
   856 
       
   857 //
       
   858 // Get the String Extension for the BioMessageID
       
   859 EXPORT_C const TPtrC CBIODatabase::GetFileExtL(TUid aMsgID)
       
   860 /** Gets the BIO file extension for a specified BIO message type.
       
   861 
       
   862 @param aMsgID BIO message type
       
   863 @leave KErrNotFound Not found
       
   864 @return BIO file extension */
       
   865 {
       
   866 	TInt index = 0;
       
   867 	GetBioIndexWithMsgIDL(aMsgID, index);
       
   868 	return (*iBifReaders)[index]->FileExtension();
       
   869 }
       
   870 
       
   871 
       
   872 //
       
   873 EXPORT_C void CBIODatabase::GetDefaultSendBearerL(TUid aBioUID, TBioMsgId& rBioMsgIdentifier)
       
   874 /** Gets the default BIF ID entry for a specified BIO message type.
       
   875 
       
   876 @param aBioUID BIO message type
       
   877 @param rBioMsgIdentifier On return, the default BIF ID entry
       
   878 @leave KErrNotFound Not found */
       
   879 	{
       
   880 	TInt index = 0;
       
   881 	TBioMsgIdType portType = EBioMsgIdUnknown;
       
   882 	GetBioIndexWithMsgIDL(aBioUID, index);
       
   883 	GetDefaultSendBearerTypeL(aBioUID, portType);
       
   884 	GetTransportIDL(index, portType, rBioMsgIdentifier);
       
   885 	}
       
   886 
       
   887 //
       
   888 EXPORT_C void CBIODatabase::GetDefaultSendBearerTypeL(TUid aBioUID, TBioMsgIdType& rPortType)
       
   889 /** Gets the bearer type for the default BIF ID entry for a specified BIO message 
       
   890 type.
       
   891 
       
   892 @param aBioUID BIO message type
       
   893 @param rPortType On return, the bearer type
       
   894 @leave KErrNotFound Not found */
       
   895 	{
       
   896 	TInt index = 0;
       
   897 	GetBioIndexWithMsgIDL(aBioUID, index);
       
   898 	const CArrayFix<TBioMsgId>* msgIDArray = BIOEntryLC(index);
       
   899 	rPortType = (*msgIDArray)[0].iType;
       
   900 	CleanupStack::PopAndDestroy(); 
       
   901 	}
       
   902 
       
   903 //
       
   904 EXPORT_C void CBIODatabase::GetDefaultSendBearerByTypeL(TUid aBioUID, TBioMsgIdType aPortType, TBioMsgId& rBioMsgIdentifier)
       
   905 /** Gets the default BIF ID entry for a specified BIO message type and bearer type.
       
   906 
       
   907 @param aBioUID BIO message type
       
   908 @param aPortType Bearer type
       
   909 @param rBioMsgIdentifier On return, the default BIF ID entry
       
   910 @leave KErrNotFound Not found */
       
   911 	{
       
   912 	TInt index = 0;
       
   913 	GetBioIndexWithMsgIDL(aBioUID, index);
       
   914 	GetTransportIDL(index, aPortType, rBioMsgIdentifier);
       
   915 	}
       
   916 
       
   917 //
       
   918 // Get the BIO Entry based on what type it is, pos indicates where to start looking after
       
   919 // if it can't be found, NULL returned
       
   920 EXPORT_C const CArrayFix<TBioMsgId>* CBIODatabase::BioEntryByTypeLC(
       
   921 							TSearchList aSearchType,
       
   922 							TBioMsgIdType portType, 
       
   923 							TInt& rIndex)
       
   924 /** Gets the ID array of a BIF of a specified bearer source type.
       
   925 
       
   926 @param aSearchType Search type
       
   927 @param portType Bearer source type
       
   928 @param rIndex On return, index of found BIF
       
   929 @return ID array, or NULL if not found */
       
   930 	{
       
   931 	
       
   932 	switch(aSearchType)
       
   933 	{
       
   934 		case EStart:
       
   935 			rIndex = 0;
       
   936 			break;
       
   937 		case ENext:
       
   938 			rIndex++;
       
   939 			break;
       
   940 		default:
       
   941 			__ASSERT_DEBUG(0 ,Panic(EBioDBNotFound));
       
   942 			break;
       
   943 	}
       
   944 
       
   945 
       
   946 		
       
   947 	const CArrayFix<TBioMsgId>* msgIDArray = BIOEntryLC(rIndex);
       
   948 	
       
   949 	while (msgIDArray)
       
   950 		{
       
   951 		for (TInt i = 0; i < msgIDArray->Count() ; i++)
       
   952 			{
       
   953 			if ( (*msgIDArray)[i].iType == portType)
       
   954 				return msgIDArray;
       
   955 			}
       
   956 		CleanupStack::PopAndDestroy(); //msgIDArray
       
   957 		msgIDArray = BIOEntryLC(++rIndex);
       
   958 		}
       
   959 	return NULL;
       
   960 	
       
   961 	}	
       
   962 
       
   963 
       
   964 
       
   965 //
       
   966 // This will compare strings for both NBS & IANA types handy when you have a start string
       
   967 // and want to know if there's a Bio Message to support this
       
   968 
       
   969 EXPORT_C TInt CBIODatabase::IsBioMessageL(TBioMsgIdType aPortType, const TDesC& aPattern, TUint16 aPort, TUid& rBioMsgUID)
       
   970 /** Tests if there is a BIO parser for the specificed BIF ID settings.
       
   971 
       
   972 @param aPortType Bearer type
       
   973 @param aPattern Text identifier to match
       
   974 @param aPort Port to match
       
   975 @param rBioMsgUID On return, the matching BIO message type
       
   976 @return KErrNone if found, else KErrNotFound */
       
   977 {
       
   978 	TBioMsgId bioMessageData;
       
   979 	bioMessageData.iType = aPortType;
       
   980 	bioMessageData.iText.Copy(aPattern.Left(KMaxBioIdText));
       
   981 	bioMessageData.iPort = aPort;
       
   982 
       
   983 	return ( IsBioMessageL(bioMessageData, rBioMsgUID) );
       
   984 }
       
   985 
       
   986 //
       
   987 EXPORT_C TInt CBIODatabase::IsBioMessageL(TBioMsgId bioMessageData, TUid& rBioMsgUID)
       
   988 /** Tests if there is a BIO parser for a specified BIF ID.
       
   989 
       
   990 @param bioMessageData BIF ID to match
       
   991 @param rBioMsgUID On return, the matching BIO message type
       
   992 @return KErrNone if found, else KErrNotFound */
       
   993 	{
       
   994 	rBioMsgUID = KNullUid;
       
   995 	TInt pos;
       
   996 	TUid msgID;
       
   997 	TBool bioFound = EFalse;
       
   998 
       
   999 	const CArrayFix<TBioMsgId>* bioMsgIDs = BioEntryByTypeLC(EStart, bioMessageData.iType, pos);
       
  1000 	
       
  1001 	while (!bioFound && bioMsgIDs)
       
  1002 		{
       
  1003 		GetBioMsgID(pos, msgID);
       
  1004 		for (TInt i = 0; !bioFound && i < bioMsgIDs->Count(); i++)
       
  1005 			{
       
  1006 			if (bioMsgIDs->At(i).iType == bioMessageData.iType)
       
  1007 				{
       
  1008 				switch(bioMessageData.iType)
       
  1009 					{
       
  1010 					case EBioMsgIdIana:
       
  1011 					case EBioMsgIdNbs:
       
  1012 						if (bioMsgIDs->At(i).iText.CompareF(bioMessageData.iText)==0)
       
  1013 						{
       
  1014 							rBioMsgUID = msgID;
       
  1015 							bioFound = ETrue;
       
  1016 						}
       
  1017 						break;
       
  1018 					case EBioMsgIdWap:
       
  1019 					case EBioMsgIdWapSecure:
       
  1020 					case EBioMsgIdWsp:
       
  1021 					case EBioMsgIdWspSecure:
       
  1022 						if (bioMsgIDs->At(i).iPort == bioMessageData.iPort)
       
  1023 						{
       
  1024 							rBioMsgUID = msgID;
       
  1025 							bioFound = ETrue;
       
  1026 						}
       
  1027 						break;
       
  1028 					case EBioMsgIdUnknown:
       
  1029 					default:
       
  1030 						break;
       
  1031 					}
       
  1032 				}
       
  1033 			}
       
  1034 		CleanupStack::PopAndDestroy();	// bioMsgIDs
       
  1035 
       
  1036 		if (!bioFound)
       
  1037 			bioMsgIDs = BioEntryByTypeLC(ENext, bioMessageData.iType, pos);	
       
  1038 		} 
       
  1039 	
       
  1040 
       
  1041 	if (!bioFound)
       
  1042 		return KErrNotFound;
       
  1043 
       
  1044 	return KErrNone;
       
  1045 	}
       
  1046