--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingfw/biomsgfw/BDBSRC/BIODB.CPP Mon Jan 18 20:36:02 2010 +0200
@@ -0,0 +1,1046 @@
+// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// BIODB.CPP
+//
+
+#include "BIODB.H"
+#include "BDBPAN.H"
+#include "cbifentry.h"
+
+#include <s32file.h> // CFileStore
+#include <bautils.h>
+
+#include <basched.h>
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <bifchangeobserver.h>
+#endif
+
+//
+// Globals & Constants
+//
+// Old search paths are /system/bif
+// New (platsec) search paths are /resource/messaging/bif
+
+_LIT(KSecureBifPath, "\\resource\\messaging\\Bif\\");
+_LIT(KSecureBifSearchString, "?:\\resource\\messaging\\Bif\\");
+
+_LIT(KLanguageFileExt, ".r");
+_LIT(KDotRsc, ".rsc");
+
+// 30 seconds between attempts to scan drives if we get completed with an error,
+const TInt KBifRetryTimeOut=30000000;
+// Maximam attempts to scan drives if we get completed with an error,
+const TInt KMaxRetries = 1;
+
+// default size of array of entries in a bif directory
+const TInt KBifEntryArrayDefaultSize=5;
+const TInt KMinFileNameLength = 5;
+
+/*
+ * CBifChangeObserver
+ */
+
+/** Allocates and constructs a new BIF change observer.
+
+@param aObserver
+Callback interface to notify when a change occurs
+
+@param afileSystem
+Connected file system handle
+
+@return
+New BIF change observer
+*/
+EXPORT_C CBifChangeObserver* CBifChangeObserver::NewL(MBifChangeObserver& aObserver, RFs& aFs)
+ {
+ CBifChangeObserver* self=new(ELeave) CBifChangeObserver(aObserver, aFs);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+void CBifChangeObserver::ConstructL()
+ {
+ iBioDB = CBIODatabase::NewL(iFs);
+ User::LeaveIfError(iTimer.CreateLocal());
+ }
+
+CBifChangeObserver::CBifChangeObserver(MBifChangeObserver& aObserver, RFs& aFs)
+: CActive(EPriorityStandard), iChangeObserver(aObserver), iFs(aFs)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+/** Destructor. */
+CBifChangeObserver::~CBifChangeObserver()
+ {
+ Cancel();
+ iTimer.Close();
+ delete iBioDB;
+ iEntries.ResetAndDestroy();
+ }
+
+/** Starts the object watching for changes.
+
+To stop the object, simply delete it.
+*/
+EXPORT_C void CBifChangeObserver::Start()
+ {
+ // just complete myself so that RunL builds the list of entries and asks the file
+ // sever to notify us of changes.
+ TRequestStatus *status=&iStatus;
+ User::RequestComplete(status,KErrNone);
+ SetActive();
+ }
+
+void CBifChangeObserver::RunL()
+ {
+ TInt err=KErrNone;
+ if(iStatus.Int()==KErrNone)
+ {
+ // ignore the error
+ TRAP(err, DoRunL());
+ }
+#ifdef _DEBUG
+ else
+ {
+ // I don't expect to get here, it means that RFs::NotifyChangeL has completed
+ // this class with an error, which means we would loop rather quickly.
+ User::Invariant();
+ }
+#endif
+
+ if((iStatus.Int() != KErrNone || err != KErrNone) && iRetryCount < KMaxRetries)
+ {
+ iTimer.After(iStatus,KBifRetryTimeOut);
+ iRetryCount ++;
+ SetActive();
+ }
+ else
+ {
+ WaitForFileNotification();
+ iRetryCount = 0;
+ }
+ }
+
+void CBifChangeObserver::DoRunL()
+ {
+ TBool notify=EFalse;
+ // build a list of all the TEntrys in KBifPath on all drives/
+ RPointerArray<CBifEntry> entryList(KBifEntryArrayDefaultSize);
+ TCleanupItem cleanup(CleanupBifArray, &entryList);
+ CleanupStack::PushL(cleanup);
+
+ TFindFile fileFinder(iFs);
+ CDir *dir=NULL;
+ // Scan this folder from V1.5 onwards
+ TInt err = fileFinder.FindWildByDir(_L("*"),KSecureBifPath,dir);
+ while(err==KErrNone)
+ {
+ CleanupStack::PushL(dir);
+ TInt count=dir->Count();
+ while(count--)
+ {
+ CBifEntry* bifEntry = CBifEntry::NewLC((*dir)[count]);
+ entryList.AppendL(bifEntry);
+ CleanupStack::Pop(bifEntry);
+ }
+ CleanupStack::PopAndDestroy(dir);
+ err=fileFinder.Find();
+ }
+
+ if (err != KErrNotFound)
+ User::LeaveIfError(err);
+
+ // Check to see if iEntries matches entryList
+ if(iEntries.Count()!=0) // iEntries is empty the first time in so don't notify anyone.
+ {
+ // check to see if the two lists of entries are the same
+ if(iEntries.Count()!=entryList.Count())
+ notify=ETrue; // not the same if one is larger than the other
+ else
+ {
+ TInt count=entryList.Count();
+ while(count-- && notify==EFalse)
+ {
+ TInt index;
+ TInt found=FindEntry(*(entryList)[count],iEntries,index);
+ if(found==KErrNone)
+ {
+ delete (iEntries)[index];
+ iEntries.Remove(index);
+ }
+ else
+ notify=ETrue; // not the same if entryList contains something not in iEntries
+ }
+ if(iEntries.Count()!=0)
+ notify=ETrue; // not the same if iEntries contains something not in entryList;
+ }
+ }
+
+ // replace old iEntries with new entryList
+ CleanupStack::Pop(&entryList);
+ iEntries.ResetAndDestroy();
+ iEntries=entryList;
+
+ // notify observers if iEntries was != entryList;
+ if(notify!=EFalse)
+ NotifyObserverL();
+ }
+
+TInt CBifChangeObserver::FindEntry(const CBifEntry& aBifEntry, const RPointerArray<CBifEntry>& aEntries, TInt& aIndex) const
+ {
+ aIndex = aEntries.Count();
+
+ while (aIndex--)
+ {
+ if ( aBifEntry == *aEntries[aIndex] )
+ {
+ return KErrNone;
+ }
+ }
+
+ return KErrNotFound;
+ }
+
+void CBifChangeObserver::WaitForFileNotification()
+ {
+ // Observe this folder from V1.5 onwards
+ iFs.NotifyChange(ENotifyAll, iStatus, KSecureBifSearchString);
+ SetActive();
+ }
+
+void CBifChangeObserver::DoCancel()
+ {
+ iTimer.Cancel();
+
+ iFs.NotifyChangeCancel(iStatus); // Cancel only the specific
+ // request made by this observer
+ }
+
+TBool CBifChangeObserver::CompareReaders(const CBioInfoFileReader& aReader1, const CBioInfoFileReader& aReader2) const
+ {
+ TBool retVal = aReader1.BifEntry() == aReader2.BifEntry();
+
+ if (retVal)
+ {
+ //Compare the readers
+ retVal =
+ (aReader1.MessageParserName().Compare(aReader2.MessageParserName()) == 0)
+ && (aReader1.MessageAppCtrlName().Compare(aReader2.MessageAppCtrlName()) == 0)
+ && (aReader1.MessageAppUid() == aReader2.MessageAppUid())
+ && (aReader1.GeneralData1() == aReader2.GeneralData1())
+ && (aReader1.GeneralData2() == aReader2.GeneralData2())
+ && (aReader1.GeneralData3() == aReader2.GeneralData3())
+ && (aReader1.IconsFilename().Compare(aReader2.IconsFilename()) == 0)
+ && (aReader1.Description().Compare(aReader2.Description()) == 0);
+
+ //To Do: Should aReader1.IdsLC() and aReader2.IdsLC() be compared?
+ }
+
+ return retVal;
+ }
+
+void CBifChangeObserver::NotifyObserverL()
+ {
+ CArrayFixFlat<TUid>* addedBifs = new (ELeave) CArrayFixFlat<TUid>(1);
+ CleanupStack::PushL(addedBifs);
+
+ CArrayFixFlat<TUid>* changedBifs = new (ELeave) CArrayFixFlat<TUid>(1);
+ CleanupStack::PushL(changedBifs);
+
+ CArrayFixFlat<TUid>* deletedBifs = new (ELeave) CArrayFixFlat<TUid>(1);
+ CleanupStack::PushL(deletedBifs);
+
+ // Figure out what kind of change really happened here
+ CBIODatabase* newBioDB = CBIODatabase::NewL(iFs);
+ CleanupStack::PushL(newBioDB);
+
+
+ TInt err = KErrNone;
+
+ TUid uid;
+ TInt index = 0;
+ TKeyArrayFix key(0, ECmpTInt);
+ TInt count = newBioDB->BIOCount();
+
+ while (count--)
+ {
+ newBioDB->GetBioMsgID(count, uid);
+ TRAP(err, iBioDB->GetBioIndexWithMsgIDL(uid, index));
+
+ if (err)
+ {
+ //BIF in New BIO DB not found in Old BIO DB
+ addedBifs->InsertIsqL(uid, key);
+ }
+ else
+ {
+
+ //BIF in both BIO DBs, therefore check to see if the files have changed
+ if (!CompareReaders(iBioDB->BifReader(index), newBioDB->BifReader(count)))
+ {
+ changedBifs->InsertIsqL(uid, key);
+ }
+
+ //Remove this BIF from the Old BIO DB for efficiency in the next while loop.
+ iBioDB->RemoveBifL(index);
+ }
+ }
+
+ count = iBioDB->BIOCount();
+
+ while (count--)
+ {
+ //All remaining members of iBioDB are deleted BIFs
+ iBioDB->GetBioMsgID(count, uid);
+ deletedBifs->InsertIsqL(uid, key);
+ }
+
+ count = addedBifs->Count();
+
+ while (count--)
+ {
+ iChangeObserver.HandleBifChangeL(MBifChangeObserver::EBifAdded, addedBifs->At(count));
+ }
+
+ count = deletedBifs->Count();
+
+ while (count--)
+ {
+ iChangeObserver.HandleBifChangeL(MBifChangeObserver::EBifDeleted, deletedBifs->At(count));
+ }
+
+ count = changedBifs->Count();
+
+ while (count--)
+ {
+ iChangeObserver.HandleBifChangeL(MBifChangeObserver::EBifChanged, changedBifs->At(count));
+ }
+
+ // update the list we're holding onto
+ delete iBioDB;
+ iBioDB = newBioDB;
+
+ CleanupStack::Pop(); //newBioDB
+ CleanupStack::PopAndDestroy(3); //arrays
+ }
+
+void CBifChangeObserver::CleanupBifArray( TAny* aBifArray )
+ {
+ RPointerArray<CBifEntry>* bifArray = static_cast<RPointerArray<CBifEntry>*>(aBifArray);
+ bifArray->ResetAndDestroy();
+ }
+
+//
+// CBIODatabase
+//
+
+//
+// Construction
+// protected
+//
+CBIODatabase::CBIODatabase()
+ {
+ // We're a CBase derived class so we can assume that our data members are intialized to 0
+ }
+
+//
+EXPORT_C CBIODatabase* CBIODatabase::NewLC(RFs& afileSystem)
+/** Allocates and constructs a new BIO database object, leaving the object on the
+cleanup stack.
+
+It initialises the object from all the BIF files in the system\\bif directory.
+
+@param afileSystem Connected file system handle
+@return New BIO database object */
+ {
+ CBIODatabase* self=new(ELeave) CBIODatabase();
+ CleanupStack::PushL(self);
+ self->ConstructL(afileSystem);
+ return self;
+ }
+
+//
+EXPORT_C CBIODatabase* CBIODatabase::NewL(RFs& afileSystem)
+/** Allocates and constructs a new BIO database object.
+
+It initialises the object from all the BIF files in the system\\bif directory.
+
+@param afileSystem Connected file system handle
+@return New BIO database object */
+ {
+ CBIODatabase* self=CBIODatabase::NewLC(afileSystem);
+ CleanupStack::Pop(); // self
+ return self;
+ }
+
+//
+// Construction/destruction
+void CBIODatabase::ConstructL(RFs& afileSystem)
+ {
+ // put the real construction here
+ iBifReaders= new (ELeave) CArrayPtrFlat<CBioInfoFileReader>(10);
+ AddAllBifsL(afileSystem);
+ }
+
+//
+// Construction/destruction
+EXPORT_C CBIODatabase::~CBIODatabase()
+/** Destructor. */
+ {
+ if (iBifReaders)
+ iBifReaders->ResetAndDestroy();
+ delete iBifReaders;
+ }
+
+
+//
+EXPORT_C TInt CBIODatabase::BIOCount()
+/** Gets the number of BIF files.
+
+@return Number of BIF files */
+ {
+ return iBifReaders->Count();
+ }
+
+//
+EXPORT_C void CBIODatabase::AddAllBifsL(RFs& afileSystem)
+/** Initialises the object from all the BIF files in the system\\bif or resource\\messaging\\bif directory.
+
+@param afileSystem Connected file system handle */
+ {
+ // Walk through all the BIF Files, adding each one
+ // to the iBifReaders array
+ TDriveList drvList;
+
+ // User::LeaveIfError(afileSystem.Connect());
+ User::LeaveIfError(afileSystem.DriveList(drvList));
+
+ for (TInt n=0 ; n<KMaxDrives ; ++n)
+ {
+ if (drvList[n]!=0)
+ {
+ TDriveInfo driveinfo;
+ TInt ret=afileSystem.Drive(driveinfo,n);
+ if ((ret==KErrNone) && (driveinfo.iType!=EMediaNotPresent) && (driveinfo.iType!=EMediaRemote)
+ && (!(driveinfo.iMediaAtt & KMediaAttLocked)) )
+ {
+ TDriveUnit driveUnit(n);
+ TPath fullPath; // Length must hold x:\resource\messaging\bif\
+ fullPath.FillZ();
+ fullPath = driveUnit.Name();
+ fullPath += KSecureBifPath;
+
+ if (afileSystem.SetSessionPath(fullPath) == KErrNone)
+ {
+ CDir* entryList = NULL;
+
+ // Walk through all the BIF Files, adding each one
+
+ ret = afileSystem.GetDir( fullPath,
+ KEntryAttNormal|KEntryAttAllowUid,
+ ESortByDate,
+ entryList );
+ if (ret==KErrNone)
+ {
+ CleanupStack::PushL(entryList);
+ TInt cnt = entryList->Count();
+ for (TInt i = 0; i < cnt; ++i)
+ {
+ // get the file
+ TEntry entry = (*entryList)[i];
+
+ TFileName fileName(fullPath);
+ fileName.Append(entry.iName);
+
+ // Remove localization index from the filename and replace it with "rsc"
+ // example, abc.r05 -> abc.rsc
+ TInt extLength(0);
+ if ( IsLanguageFileL(entry.iName, extLength) && (fileName.Length() >= KMinFileNameLength) )
+ {
+ fileName.Replace(fileName.Length() - extLength, extLength, KDotRsc);
+ }
+ // Use the file most appropriate to the current language
+ BaflUtils::NearestLanguageFile(afileSystem,fileName);
+
+ // Load the bif file
+ CBioInfoFileReader* bifReader = NULL;
+ TRAPD(error, bifReader=CBioInfoFileReader::NewL(afileSystem,fileName));
+ if (!error)
+ {
+ AddBifL(bifReader);
+ }
+ else
+ {
+ // Ignore corrupt files
+ delete bifReader;
+
+ if (error != KErrCorrupt && error != KErrExtended && error != KErrNotFound)
+ {
+ User::LeaveIfError(error);
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy(entryList);
+ }
+ }
+ }
+ if (!(ret==KErrNone ||
+ ret==KErrPathNotFound ||
+ ret==KErrNotFound ||
+ ret==KErrNotReady ||
+ ret==KErrCorrupt ||
+ ret==KErrInUse ||
+ ret==KErrLocked ||
+ ret==KErrNotSupported))
+ {
+ User::LeaveIfError(ret);
+ }
+ }
+ }
+
+ }
+
+// Is the file a language file
+TBool CBIODatabase::IsLanguageFileL(const TDesC& aFileName, TInt& aExtLength) const
+ {
+ // Check the extension to see if it's a language file. we
+ // have to assume ".rXXX" is a resource file
+ TParse parse;
+ User::LeaveIfError(parse.Set(aFileName, NULL, NULL));
+ aExtLength=parse.Ext().Length();
+ return parse.Ext().Left(2).CompareF(KLanguageFileExt) == 0;
+ }
+
+//
+// This will add the Parser
+// Error returned
+EXPORT_C void CBIODatabase::AddBifL(CBioInfoFileReader* aBifReader)
+/** Adds a specified BIF.
+
+@param abifReader BIF file to add */
+ {
+ // This will manage the array - if a conflicting message
+ // id comes in, it will take the one with higher confidence
+ // or if a tie, the first one in
+ CleanupStack::PushL(aBifReader);
+
+ // Check if we have a reader with this message id
+ TInt index = 0;
+
+ TRAPD(leaveValue,GetBioIndexWithMsgIDL(aBifReader->MessageTypeUid(), index));
+
+ // We haven't read a BIF with the msgID in yet
+ if (leaveValue == KErrNotFound)
+ {
+ // just add it
+ iBifReaders->AppendL(aBifReader);
+ CleanupStack::Pop(); // aBifReader
+ }
+ else
+ {
+ CApaDataRecognizerType::TRecognitionConfidence newBifConf, oldBifConf;
+
+ // If we do have a match, take the one with higher confidence
+ const CArrayFix<TBioMsgId>* msgIDArray = BIOEntryLC(index);
+ oldBifConf = (*msgIDArray)[0].iConfidence;
+ CleanupStack::PopAndDestroy(); //msgIDArray
+
+ newBifConf = (*(aBifReader->IdsLC()))[0].iConfidence;
+ CleanupStack::PopAndDestroy(); //IdsLC
+
+ if ( newBifConf > oldBifConf )
+ {
+ CleanupStack::PushL(aBifReader);
+ RemoveBifL(aBifReader->MessageTypeUid());
+ iBifReaders->AppendL(aBifReader);
+ CleanupStack::Pop(); // aBifReader
+ }
+ else
+ CleanupStack::PopAndDestroy();// aBifReader
+
+ }
+
+ }
+
+//
+// Error returned
+EXPORT_C void CBIODatabase::RemoveBifL(TUid aMsgID)
+/** Removes a BIF specified by UID.
+
+@param aMsgID BIO type UID */
+ {
+ TInt index = 0;
+
+ TRAPD(leaveValue,GetBioIndexWithMsgIDL(aMsgID, index));
+
+ // We haven't read a BIF with the msgID in yet
+ if (leaveValue == KErrNone)
+ {
+ // just remove it
+ RemoveBifL(index);
+ }
+ else
+ {
+ //__ASSERT_DEBUG(Panic(EBioDBNotFound));
+ }
+ }
+
+EXPORT_C void CBIODatabase::RemoveBifL(TInt aIndex)
+/** Removes a BIF specified by index.
+
+@param aIndex Index of file in this object */
+ {
+ CBioInfoFileReader *bifReader = iBifReaders->At(aIndex);
+ iBifReaders->Delete(aIndex);
+ delete bifReader;
+ }
+
+
+//
+// Get the BioEntry at this index
+// Return Index if found, error if not
+EXPORT_C const CBioInfoFileReader& CBIODatabase::BifReader(TInt aIndex) const
+/** Gets a BIF reader for a BIF at a specified index.
+
+@param aIndex Index
+@return BIF file reader */
+ {
+ __ASSERT_DEBUG(aIndex >= 0 && aIndex <= iBifReaders->Count(),
+ Panic(EBioDBNotFound));
+ return *iBifReaders->At(aIndex);
+ }
+
+//
+// Get the BioEntry at this index
+// Return Index if found, error if not
+EXPORT_C const CArrayFix<TBioMsgId>* CBIODatabase::BIOEntryLC(TInt index)
+/** Gets the ID array of a BIF at a specified index.
+
+@param index Index
+@return ID array, or NULL if not found */
+ {
+ if (index >= 0 && index < iBifReaders->Count())
+ {
+ return iBifReaders->At(index)->IdsLC();
+ }
+ else
+ return NULL;
+ }
+
+//
+// Get the Index for the BioMessageID
+EXPORT_C void CBIODatabase::GetBioIndexWithMsgIDL(TUid aMsgID, TInt& rIndex)
+/** Gets the index of a BIF of a specified BIO message type.
+
+@param aMsgID BIO message type
+@param rIndex On return, index of found BIF
+@leave KErrNotFound Not found */
+ {
+ rIndex = iBifReaders->Count();
+
+ // See if we have one of these Messages
+ while (rIndex--)
+ {
+ if ((*iBifReaders)[rIndex]->MessageTypeUid() == aMsgID)
+ {
+ return;
+ }
+ }
+ User::Leave(KErrNotFound);
+ }
+
+
+//
+// Get the BioMessageID for the Index
+EXPORT_C void CBIODatabase::GetBioMsgID(TInt aIndex, TUid& rMsgID)
+/** Gets the BIO message type for a specified index.
+
+@param aIndex Index
+@param rMsgID On return, BIO message type */
+ {
+ __ASSERT_DEBUG(aIndex >= 0 && aIndex <= iBifReaders->Count(),
+ Panic(EBioDBNotFound));
+
+ rMsgID = (*iBifReaders)[aIndex]->MessageTypeUid();
+ }
+
+
+//
+// Get the BioParserName for the Index
+EXPORT_C const TPtrC CBIODatabase::GetBioParserName(TInt aIndex)
+/** Gets the BIO parser name for a specified index.
+
+@param aIndex Index
+@return BIO parser name */
+ {
+ __ASSERT_DEBUG( aIndex >= 0 && aIndex <= iBifReaders->Count(),
+ Panic(EBioDBNotFound));
+ return (*iBifReaders)[aIndex]->MessageParserName();
+ }
+
+/** Depreacated method.
+
+Need to use CBIODatabase::GetBioControlName instead.
+
+@see CBIODatabase::GetBioControlName
+
+@param aIndex Not used
+@param rControlID Not used
+
+@panic USER EInvariantFalse
+
+@deprecated */
+EXPORT_C void CBIODatabase::GetBioControlID(TInt /*aIndex*/, TUid& /*rControlID*/)
+ {
+ User::Invariant();
+ }
+
+/** Gets the BIO control name for a specified index.
+
+@param aIndex Index
+@return BIO control name */
+EXPORT_C const TPtrC CBIODatabase::GetBioControlName(TInt aIndex)
+ {
+ __ASSERT_DEBUG( aIndex >= 0 && aIndex <= iBifReaders->Count(),
+ Panic(EBioDBNotFound));
+ return (*iBifReaders)[aIndex]->MessageAppCtrlName();
+ }
+
+
+//
+// Get the first Port Number for this messaga type
+EXPORT_C void CBIODatabase::GetPortNumberL(TUid aMsgID, TBioMsgIdType aPortType, TInt& aPortNumber)
+/** Gets the port number for the BIF ID entry for a specified BIO message type
+and bearer type.
+
+@param aMsgID BIO message type
+@param aPortType Bearer type
+@param aPortNumber On return, the port number
+@leave KErrNotFound Not found */
+ {
+ TInt index = 0;
+ GetBioIndexWithMsgIDL(aMsgID, index);
+
+ // We haven't read a BIF with the msgID in yet
+ TBioMsgId tranportID;
+ GetTransportIDL(index, aPortType, tranportID);
+ aPortNumber = tranportID.iPort;
+ }
+
+
+//
+// Get the first ID String for this messaga type
+EXPORT_C void CBIODatabase::GetIdentifierTextL(TUid aMsgID, TBioMsgIdType aPortType, TBioMsgIdText& aText)
+/** Gets the identifier text for the BIF ID entry for a specified BIO message type
+and bearer type.
+
+@param aMsgID BIO message type
+@param aPortType Bearer type
+@param aText On return, the identifier text */
+ {
+ TInt index = 0;
+ GetBioIndexWithMsgIDL(aMsgID, index);
+
+ TBioMsgId tranportID;
+ GetTransportIDL(index, aPortType, tranportID);
+ aText.Copy(tranportID.iText);
+ }
+
+//
+// Get the GetTransportIDL
+void CBIODatabase::GetTransportIDL(TInt aIndex, TBioMsgIdType aPortType, TBioMsgId& aBioMsgID)
+ {
+ TBioMsgId tranportID;
+ TBool found = EFalse;
+
+ const CArrayFix<TBioMsgId>* msgIDArray = BIOEntryLC(aIndex);
+
+ for (TInt i = 0; i < msgIDArray->Count() && !found ; i++)
+ {
+ if ( (*msgIDArray)[i].iType == aPortType)
+ {
+ tranportID = (*msgIDArray)[i];
+
+ // Really should make a copy contructor & = operator
+ aBioMsgID.iType = (*msgIDArray)[i].iType;
+ aBioMsgID.iConfidence = (*msgIDArray)[i].iConfidence;
+ aBioMsgID.iText.Copy((*msgIDArray)[i].iText);
+ aBioMsgID.iPort = (*msgIDArray)[i].iPort;
+ aBioMsgID.iCharacterSet = (*msgIDArray)[i].iCharacterSet;
+ aBioMsgID.iGeneralIdData = (*msgIDArray)[i].iGeneralIdData;
+ found = ETrue;
+ }
+ }
+ CleanupStack::PopAndDestroy(); //msgIDArray
+
+ if (!found)
+ User::Leave(KErrNotFound);
+ }
+
+
+//
+// Get the BioParserName for the Message ID
+EXPORT_C const TPtrC CBIODatabase::GetBioParserNameL(TUid aMsgID)
+/** Gets the BIO parser name for a specified BIO message type.
+
+@param aMsgID BIO message type
+@return BIO parser name
+@leave KErrNotFound Not found */
+ {
+ TInt index = 0;
+ TRAPD(leaveValue, GetBioIndexWithMsgIDL(aMsgID, index));
+
+ // We haven't read a BIF with the msgID in yet
+ if (leaveValue != KErrNone)
+ {
+ __ASSERT_DEBUG(0, Panic(EBioDBNotFound));
+ User::Leave(leaveValue);
+ }
+
+ return GetBioParserName(index);
+ }
+
+
+/** Depreacated method.
+
+Need to use CBIODatabase::GetBioControlNameL instead.
+
+@see CBIODatabase::GetBioControlNameL
+
+@param aIndex Not used
+@param rControlID Not used
+
+@panic USER EInvariantFalse
+
+@deprecated */
+EXPORT_C void CBIODatabase::GetBioControlIDL(TUid /*aMsgID*/, TUid& /*rControlID*/)
+ {
+ User::Invariant();
+ }
+
+/** Gets the BIO control name for a specified BIO message type.
+
+@param aMsgID BIO message type
+@return BIO Control name
+
+@leave KErrNotFound BIO message type does not exist */
+EXPORT_C const TPtrC CBIODatabase::GetBioControlNameL(TUid aMsgID)
+ {
+ TInt index = 0;
+ TRAPD(leaveValue, GetBioIndexWithMsgIDL(aMsgID, index));
+
+ // We haven't read a BIF with the msgID in yet
+ if( leaveValue != KErrNone )
+ {
+ __ASSERT_DEBUG(0, Panic(EBioDBNotFound));
+ User::Leave(leaveValue);
+ }
+
+ return GetBioControlName(index);
+ }
+
+
+//
+// Get the String Extension for the BioMessageID
+EXPORT_C const TPtrC CBIODatabase::GetFileExtL(TUid aMsgID)
+/** Gets the BIO file extension for a specified BIO message type.
+
+@param aMsgID BIO message type
+@leave KErrNotFound Not found
+@return BIO file extension */
+{
+ TInt index = 0;
+ GetBioIndexWithMsgIDL(aMsgID, index);
+ return (*iBifReaders)[index]->FileExtension();
+}
+
+
+//
+EXPORT_C void CBIODatabase::GetDefaultSendBearerL(TUid aBioUID, TBioMsgId& rBioMsgIdentifier)
+/** Gets the default BIF ID entry for a specified BIO message type.
+
+@param aBioUID BIO message type
+@param rBioMsgIdentifier On return, the default BIF ID entry
+@leave KErrNotFound Not found */
+ {
+ TInt index = 0;
+ TBioMsgIdType portType = EBioMsgIdUnknown;
+ GetBioIndexWithMsgIDL(aBioUID, index);
+ GetDefaultSendBearerTypeL(aBioUID, portType);
+ GetTransportIDL(index, portType, rBioMsgIdentifier);
+ }
+
+//
+EXPORT_C void CBIODatabase::GetDefaultSendBearerTypeL(TUid aBioUID, TBioMsgIdType& rPortType)
+/** Gets the bearer type for the default BIF ID entry for a specified BIO message
+type.
+
+@param aBioUID BIO message type
+@param rPortType On return, the bearer type
+@leave KErrNotFound Not found */
+ {
+ TInt index = 0;
+ GetBioIndexWithMsgIDL(aBioUID, index);
+ const CArrayFix<TBioMsgId>* msgIDArray = BIOEntryLC(index);
+ rPortType = (*msgIDArray)[0].iType;
+ CleanupStack::PopAndDestroy();
+ }
+
+//
+EXPORT_C void CBIODatabase::GetDefaultSendBearerByTypeL(TUid aBioUID, TBioMsgIdType aPortType, TBioMsgId& rBioMsgIdentifier)
+/** Gets the default BIF ID entry for a specified BIO message type and bearer type.
+
+@param aBioUID BIO message type
+@param aPortType Bearer type
+@param rBioMsgIdentifier On return, the default BIF ID entry
+@leave KErrNotFound Not found */
+ {
+ TInt index = 0;
+ GetBioIndexWithMsgIDL(aBioUID, index);
+ GetTransportIDL(index, aPortType, rBioMsgIdentifier);
+ }
+
+//
+// Get the BIO Entry based on what type it is, pos indicates where to start looking after
+// if it can't be found, NULL returned
+EXPORT_C const CArrayFix<TBioMsgId>* CBIODatabase::BioEntryByTypeLC(
+ TSearchList aSearchType,
+ TBioMsgIdType portType,
+ TInt& rIndex)
+/** Gets the ID array of a BIF of a specified bearer source type.
+
+@param aSearchType Search type
+@param portType Bearer source type
+@param rIndex On return, index of found BIF
+@return ID array, or NULL if not found */
+ {
+
+ switch(aSearchType)
+ {
+ case EStart:
+ rIndex = 0;
+ break;
+ case ENext:
+ rIndex++;
+ break;
+ default:
+ __ASSERT_DEBUG(0 ,Panic(EBioDBNotFound));
+ break;
+ }
+
+
+
+ const CArrayFix<TBioMsgId>* msgIDArray = BIOEntryLC(rIndex);
+
+ while (msgIDArray)
+ {
+ for (TInt i = 0; i < msgIDArray->Count() ; i++)
+ {
+ if ( (*msgIDArray)[i].iType == portType)
+ return msgIDArray;
+ }
+ CleanupStack::PopAndDestroy(); //msgIDArray
+ msgIDArray = BIOEntryLC(++rIndex);
+ }
+ return NULL;
+
+ }
+
+
+
+//
+// This will compare strings for both NBS & IANA types handy when you have a start string
+// and want to know if there's a Bio Message to support this
+
+EXPORT_C TInt CBIODatabase::IsBioMessageL(TBioMsgIdType aPortType, const TDesC& aPattern, TUint16 aPort, TUid& rBioMsgUID)
+/** Tests if there is a BIO parser for the specificed BIF ID settings.
+
+@param aPortType Bearer type
+@param aPattern Text identifier to match
+@param aPort Port to match
+@param rBioMsgUID On return, the matching BIO message type
+@return KErrNone if found, else KErrNotFound */
+{
+ TBioMsgId bioMessageData;
+ bioMessageData.iType = aPortType;
+ bioMessageData.iText.Copy(aPattern.Left(KMaxBioIdText));
+ bioMessageData.iPort = aPort;
+
+ return ( IsBioMessageL(bioMessageData, rBioMsgUID) );
+}
+
+//
+EXPORT_C TInt CBIODatabase::IsBioMessageL(TBioMsgId bioMessageData, TUid& rBioMsgUID)
+/** Tests if there is a BIO parser for a specified BIF ID.
+
+@param bioMessageData BIF ID to match
+@param rBioMsgUID On return, the matching BIO message type
+@return KErrNone if found, else KErrNotFound */
+ {
+ rBioMsgUID = KNullUid;
+ TInt pos;
+ TUid msgID;
+ TBool bioFound = EFalse;
+
+ const CArrayFix<TBioMsgId>* bioMsgIDs = BioEntryByTypeLC(EStart, bioMessageData.iType, pos);
+
+ while (!bioFound && bioMsgIDs)
+ {
+ GetBioMsgID(pos, msgID);
+ for (TInt i = 0; !bioFound && i < bioMsgIDs->Count(); i++)
+ {
+ if (bioMsgIDs->At(i).iType == bioMessageData.iType)
+ {
+ switch(bioMessageData.iType)
+ {
+ case EBioMsgIdIana:
+ case EBioMsgIdNbs:
+ if (bioMsgIDs->At(i).iText.CompareF(bioMessageData.iText)==0)
+ {
+ rBioMsgUID = msgID;
+ bioFound = ETrue;
+ }
+ break;
+ case EBioMsgIdWap:
+ case EBioMsgIdWapSecure:
+ case EBioMsgIdWsp:
+ case EBioMsgIdWspSecure:
+ if (bioMsgIDs->At(i).iPort == bioMessageData.iPort)
+ {
+ rBioMsgUID = msgID;
+ bioFound = ETrue;
+ }
+ break;
+ case EBioMsgIdUnknown:
+ default:
+ break;
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy(); // bioMsgIDs
+
+ if (!bioFound)
+ bioMsgIDs = BioEntryByTypeLC(ENext, bioMessageData.iType, pos);
+ }
+
+
+ if (!bioFound)
+ return KErrNotFound;
+
+ return KErrNone;
+ }
+