diff -r 000000000000 -r 8e480a14352b messagingfw/biomsgfw/BDBSRC/BIODB.CPP --- /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 // CFileStore +#include + +#include +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#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 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& 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* addedBifs = new (ELeave) CArrayFixFlat(1); + CleanupStack::PushL(addedBifs); + + CArrayFixFlat* changedBifs = new (ELeave) CArrayFixFlat(1); + CleanupStack::PushL(changedBifs); + + CArrayFixFlat* deletedBifs = new (ELeave) CArrayFixFlat(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* bifArray = static_cast*>(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(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 ; nCount(); + 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* 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* 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* 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* 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* 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* 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* 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; + } +