--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/zeroconf/cachemanager/src/cmdnscachemanager.cpp Thu Jun 24 19:09:47 2010 +0530
@@ -0,0 +1,413 @@
+/*
+* Copyright (c) 2010 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:
+*
+*/
+
+
+#include "cmdnscachemanager.h"
+#include "cserviceinfo.h"
+#include "ccacheentry.h"
+#include "dnsconstants.h"
+
+using namespace HashInfo;
+
+EXPORT_C CMDNSCacheManager* CMDNSCacheManager::NewL(TUint aMaxCacheEntries)
+ {
+ CMDNSCacheManager* self = CMDNSCacheManager::NewLC(aMaxCacheEntries);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+EXPORT_C CMDNSCacheManager* CMDNSCacheManager::NewLC(TUint aMaxCacheEntries)
+ {
+ CMDNSCacheManager* self = new (ELeave)CMDNSCacheManager();
+ CleanupStack::PushL(self);
+ self->ConstructL(aMaxCacheEntries);
+ return self;
+ }
+
+EXPORT_C CMDNSCacheManager* CMDNSCacheManager::NewL()
+ {
+ CMDNSCacheManager* self = new (ELeave)CMDNSCacheManager();
+ return self;
+ }
+
+void CMDNSCacheManager::ConstructL(TUint aMaxCacheEntries)
+ {
+ iHashMap=CMDNSCacheMap::NewL(aMaxCacheEntries);
+ }
+
+CMDNSCacheManager::CMDNSCacheManager()
+ {
+
+ }
+
+CMDNSCacheManager::~CMDNSCacheManager()
+ {
+ delete iHashMap;
+ iAuthoritativeEntries.ResetAndDestroy();
+ iAuthoritativeEntries.Close();
+ }
+
+/*Method to Insert / Update entries into Cache
+ * @param aEntry Record Entry to Insert
+ * @param aAuthoritative Flag to indicate whether the entry is Authoritative
+ * @param aSessionId To Store the Session Id for each entry
+ * @leave KErrNoMemory If Insert into Cache Failed because memory unavailability
+ * @leave KErrNotSupported if any record other than SRV, PTR, TXT ot A come
+ */
+EXPORT_C void CMDNSCacheManager::UpdateCacheL(CDnsResourceData& aEntry,TBool aAuthoritative,TUint32 aSessionId)
+ {
+ CDnsResourceData* resourceRecord = NULL;
+ CServiceInfo* foundEntry = NULL;
+ TBuf8<255> name;
+ _LIT8(KDot,".");
+ //Clone the entry to Insert in Cache
+ resourceRecord = aEntry.CloneL();
+
+ TUint16 recType(resourceRecord->Type());
+
+ if(recType == EDnsType_SRV || recType == EDnsType_TXT || recType == EDnsType_A || recType == EDnsType_PTR)
+ {
+ if(recType == EDnsType_PTR)
+ {
+ //Extract the Key- Service Instance Name
+ CRdTypePtr* ptrRecord = static_cast <CRdTypePtr*> (resourceRecord);
+ // before that insert the dot.
+ name.Copy(ptrRecord->DomainName());
+ if(name[name.Size()-1]!='.')
+ name.Append(KDot);
+ ptrRecord->SetDomainNameL(name);
+ foundEntry = iHashMap->Find(ptrRecord->DomainName());
+ }
+ else
+ {
+ //Extract the Key- Service Instance Name or Host Name
+ foundEntry = iHashMap->Find(resourceRecord->Name());
+ }
+
+ if(foundEntry)
+ {
+ //Update if the entry is already present in the Cache.
+ UpdateCacheEntry(foundEntry,resourceRecord);
+ }
+ else
+ {
+ //Entry not found in Cache,Insert it fresh
+ CServiceInfo* recordInfo = NULL;
+ recordInfo = CServiceInfo::NewL();
+ switch(recType)
+ {
+ case EDnsType_SRV:
+ CRdTypeSrv* srvRecord = static_cast <CRdTypeSrv*> (resourceRecord);
+ recordInfo->SetServiceRecord(srvRecord);
+ break;
+
+ case EDnsType_TXT:
+ CRdTypeTxt* txtRecord = static_cast <CRdTypeTxt*> (resourceRecord);
+ recordInfo->SetTxtRecord(txtRecord);
+ break;
+
+ case EDnsType_PTR:
+ CRdTypePtr* ptrRecord = static_cast <CRdTypePtr*> (resourceRecord);
+ recordInfo->SetPtrRecord(ptrRecord);
+ break;
+
+ case EDnsType_A:
+ CRdTypeA* addressRecord = static_cast <CRdTypeA*> (resourceRecord);
+ recordInfo->SetAddressRecord(addressRecord);
+ break;
+
+
+ default:
+ User::Leave(KErrNotSupported);
+ break;
+ }
+
+ recordInfo->SetAuthoritative(aAuthoritative);
+ recordInfo->SetSessionId(aSessionId);
+
+
+ // insert the entry
+ if(recType == EDnsType_PTR )
+ {
+ CRdTypePtr* ptrRecord = static_cast <CRdTypePtr*> (resourceRecord);
+ iHashMap->UpdateL(ptrRecord->DomainName(),recordInfo);
+ }
+ else
+ {
+ iHashMap->UpdateL(resourceRecord->Name(),recordInfo);
+ }
+
+ /*Maintain a list of all Services Published by us
+ (Authoritative records)*/
+ if(recordInfo->IsAuthoritative())
+ {
+ iAuthoritativeEntries.Append(recordInfo->CloneL());
+ }
+ }
+
+ }
+ else
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+ }
+
+
+
+
+/*Caters to finding varying types of records, for e.g:- find all the entries
+ that correspond to a particular service type or find the host name through the address record
+ @param aEntries List of entries that match the search constraint
+ @param aName could represent any search constraint Service Instance Type/ Name or the HostName
+ @param aType the desired record type
+ */
+EXPORT_C TInt CMDNSCacheManager::FindServiceL(RPointerArray <CCacheEntry> & aEntries,const TDesC8& aName,TDnsType aType)const
+ {
+ TInt error(KErrNotFound);
+ TPtrC8 keyToFind(aName);
+ TInt count;
+ switch(aType)
+ {
+ case EDnsType_A:
+ case EDnsType_SRV:
+ case EDnsType_TXT:
+ {
+ //Search for a specific CacheEntry
+ CServiceInfo* cacheEntry = iHashMap->Find(aName);
+ if(cacheEntry)
+ {
+ CCacheEntry* entry = CCacheEntry::NewL();
+ CacheEntryL(entry,cacheEntry);
+ aEntries.Append(entry);
+ error = KErrNone;
+ }
+ }
+ break;
+
+
+ case EDnsType_PTR:
+ //Match for all Cache Entries of the given Service Type
+ RPointerArray <const CServiceInfo> entries;
+ CleanupClosePushL(entries);
+ iHashMap->FindEntries(aName,entries);
+
+ for(count =0; count< entries.Count();count++)
+ {
+ if((*entries[count]).PtrRecord())
+ {
+ //The entries are considered only if they have PTR records
+ CCacheEntry* entry = CCacheEntry::NewL();
+ CacheEntryL(entry,entries[count]);
+ aEntries.Append(entry);
+ error = KErrNone;
+ }
+ }
+
+ CleanupStack::PopAndDestroy(&entries);
+ break;
+
+
+ case EDnsQType_Any:
+ {
+ //Search for a specific CacheEntry
+ CServiceInfo* cacheEntry = iHashMap->Find(aName);
+ if(cacheEntry)
+ {
+ CCacheEntry* entry = CCacheEntry::NewL();
+ CacheEntryL(entry,cacheEntry);
+ aEntries.Append(entry);
+ error = KErrNone;
+ }
+ else // may be its a PTR record
+ {
+ RPointerArray <const CServiceInfo> entries;
+ CleanupClosePushL(entries);
+ iHashMap->FindEntries(aName,entries);
+
+ for(count =0; count< entries.Count();count++)
+ {
+ if((*entries[count]).PtrRecord())
+ {
+ //The entries are considered only if they have PTR records
+ CCacheEntry* entry = CCacheEntry::NewL();
+ CacheEntryL(entry,entries[count]);
+ aEntries.Append(entry);
+ error = KErrNone;
+ }
+ }
+
+ CleanupStack::PopAndDestroy(&entries);
+ }
+ }
+
+ break;
+
+ default:
+ User::Leave(KErrNotSupported);
+ break;
+ }
+ return error;
+ }
+
+/*Deletes the specified entry from the Cache
+ @param aServiceInstanceName Instance Name , whose entry needs to be deleted
+ @leave KErrNotFound if specified entry is not found
+ */
+EXPORT_C TInt CMDNSCacheManager::DeleteEntryL(const TDesC8& aServiceInstanceName)
+ {
+ TInt err = iHashMap->DeleteL(aServiceInstanceName);
+
+ // check if it also on the authoritative list, if so delete it
+
+ for(TInt i=0; i<iAuthoritativeEntries.Count();i++)
+ {
+ if(iAuthoritativeEntries[i]->Key().Compare(aServiceInstanceName)==0)
+ {
+ // found the entry, now delete it;
+ CServiceInfo* info = iAuthoritativeEntries[i];
+ iAuthoritativeEntries.Remove(i);
+ delete info;
+ }
+ }
+ return err;
+ }
+
+
+EXPORT_C void CMDNSCacheManager::FlushCache()
+ {
+ iHashMap->DeleteAllEntries();
+ }
+
+EXPORT_C CCacheEntry* CMDNSCacheManager::NextStaleEntry(TBool aActiveCacheMgmtEnabled,TBool aIteratorReset)
+ {
+ CServiceInfo* nextEntry = iHashMap->NextStaleEntry(aActiveCacheMgmtEnabled,aIteratorReset);
+ CCacheEntry* nextCacheEntry = NULL;
+
+ if(nextEntry)
+ {
+
+ nextCacheEntry = CCacheEntry::NewL();
+ //Construct CCacheEntry object
+ CacheEntryL(nextCacheEntry,nextEntry);
+
+ //Mark whether the entry has to be deleted or to be queried for (i.e., has exceeded 80%)
+ nextCacheEntry->SetEntryExpired(nextEntry->StaleEntry());
+ }
+
+ return nextCacheEntry;
+ }
+
+void CMDNSCacheManager::UpdateCacheEntry(CServiceInfo* aEntry,CDnsResourceData* aRecordInfo)
+ {
+ TUint16 recType(aRecordInfo->Type());
+ switch(recType)
+ {
+ case EDnsType_SRV:
+ CRdTypeSrv* srvRecord = static_cast <CRdTypeSrv*> (aRecordInfo);
+ //Delete the previous Service Record and Insert the fresh one
+ delete aEntry->ServiceRecord();
+ aEntry->SetServiceRecord(srvRecord);
+ break;
+
+ case EDnsType_TXT:
+ CRdTypeTxt* txtRecord = static_cast <CRdTypeTxt*> (aRecordInfo);
+ //Delete the previous Text Record and Insert the fresh one
+ delete aEntry->TxtRecord();
+ aEntry->SetTxtRecord(txtRecord);
+ break;
+
+ case EDnsType_PTR:
+ CRdTypePtr* ptrRecord = static_cast <CRdTypePtr*> (aRecordInfo);
+ //Delete the previous Ptr Record and Insert the fresh one
+ delete aEntry->PtrRecord();
+ aEntry->SetPtrRecord(ptrRecord);
+ break;
+
+ case EDnsType_A:
+ CRdTypeA* addressRecord = static_cast <CRdTypeA*> (aRecordInfo);
+ //Delete the previous Address Record and Insert the fresh one
+ delete aEntry->AddressRecord();
+ aEntry->SetAddressRecord(addressRecord);
+ break;
+
+ default:
+ //Do nothing
+ break;
+ }
+ }
+
+EXPORT_C void CMDNSCacheManager::DumpCacheL()
+ {
+ iHashMap->DumpCacheL();
+ }
+
+EXPORT_C TUint32 CMDNSCacheManager::CacheEntryCount()
+ {
+ return iHashMap->NumberOfEntries();
+ }
+
+
+void CMDNSCacheManager::CacheEntryL(CCacheEntry* aTargetEntry,const CServiceInfo* aSourceEntry)const
+ {
+ //Check whether the specific records existed before making a copy
+ if(aSourceEntry->PtrRecord())
+ {
+ aTargetEntry->SetPtrRecord(static_cast <CRdTypePtr*>( aSourceEntry->PtrRecord()->CloneL()));
+ }
+
+ if(aSourceEntry->AddressRecord())
+ {
+ //This case occurs only for an idividual Address Record
+ aTargetEntry->SetAddressRecord(static_cast <CRdTypeA*>(aSourceEntry->AddressRecord()->CloneL()));
+ }
+
+ if(aSourceEntry->ServiceRecord())
+ {
+ aTargetEntry->SetServiceRecord(static_cast <CRdTypeSrv*>(aSourceEntry->ServiceRecord()->CloneL()));
+ //Set Address Record ; if it exists
+ CServiceInfo* entry = iHashMap->Find(aTargetEntry->ServiceRecord()->Target());
+ if(entry)
+ {
+ aTargetEntry->SetAddressRecord(static_cast <CRdTypeA*>(entry->AddressRecord()->CloneL()));
+ }
+ }
+
+ if(aSourceEntry->TxtRecord())
+ {
+ aTargetEntry->SetTxtRecord(static_cast <CRdTypeTxt*>(aSourceEntry->TxtRecord()->CloneL()));
+ }
+
+ aTargetEntry->SetAuthoritative(aSourceEntry->IsAuthoritative());
+ aTargetEntry->SetSessionId(aSourceEntry->SessionId());
+ }
+
+
+void CMDNSCacheManager::AuthoritativeEntriesL(RPointerArray <CCacheEntry>& aCacheEntries)
+ {
+ for(TInt index =0; index < iAuthoritativeEntries.Count();index++)
+ {
+ CCacheEntry* entry = CCacheEntry::NewL();
+ CacheEntryL(entry,iAuthoritativeEntries[index]);
+ aCacheEntries.Append(entry);
+ }
+ }
+
+TUint CMDNSCacheManager::NumberOfEntries()
+ {
+ return iHashMap->NumberOfEntries();
+ }