diff -r 8e5f6eea9c9f -r 5b3385a43d68 photosgallery/collectionframework/datasource/manager/src/glxstringcache.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/photosgallery/collectionframework/datasource/manager/src/glxstringcache.cpp Wed Sep 01 12:33:26 2010 +0100 @@ -0,0 +1,340 @@ +/* +* Copyright (c) 2008-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: This class caches resource strings +* +*/ + + + + +#include + +#include +#include +#include +#include + +#include "glxstringcache.h" + + +// ---------------------------------------------------------------------------- +// NewL +// ---------------------------------------------------------------------------- +// +CGlxStringCache::CGlxStringItem* CGlxStringCache::CGlxStringItem::NewL(TInt aId, HBufC* aString) + { + CGlxStringItem* self = new (ELeave) CGlxStringItem(aId); + CleanupStack::PushL(self); + self->ConstructL(aString); + CleanupStack::Pop(self); + return self; + } + +// ---------------------------------------------------------------------------- +// ConstructL +// ---------------------------------------------------------------------------- +// +void CGlxStringCache::CGlxStringItem::ConstructL(HBufC* aString) + { + if (NULL == aString) + { + User::Leave(KErrArgument); + } + + iString = (*aString).AllocL(); + } + +// ---------------------------------------------------------------------------- +// Constructor +// ---------------------------------------------------------------------------- +// +CGlxStringCache::CGlxStringItem::CGlxStringItem(TInt aId) +: iId(aId) + { + + } + +// ---------------------------------------------------------------------------- +// Destructor +// ---------------------------------------------------------------------------- +// +CGlxStringCache::CGlxStringItem::~CGlxStringItem() + { + delete iString; + } + +// ---------------------------------------------------------------------------- +// GetId +// ---------------------------------------------------------------------------- +// + +TInt CGlxStringCache::CGlxStringItem::GetId() const + { + return iId; + } + +// ---------------------------------------------------------------------------- +// GetString +// ---------------------------------------------------------------------------- +// + +HBufC* CGlxStringCache::CGlxStringItem::GetString() + { + return iString; + } + +// ---------------------------------------------------------------------------- +// NewL +// ---------------------------------------------------------------------------- +// + +EXPORT_C CGlxStringCache* CGlxStringCache::NewL() + { + CGlxStringCache* self = new(ELeave) CGlxStringCache; + return self; + } + +// ---------------------------------------------------------------------------- +// Constructor +// ---------------------------------------------------------------------------- +// +CGlxStringCache::CGlxStringCache() + { + TRACER("CGlxStringCache::CGlxStringCache()"); + iResourceFileName.Zero(); + } + +// ---------------------------------------------------------------------------- +// Destructor +// ---------------------------------------------------------------------------- +// +CGlxStringCache::~CGlxStringCache() + { + TRACER("CGlxStringCache::~CGlxStringCache()"); + iStringCache.ResetAndDestroy(); + } + +// ---------------------------------------------------------------------------- +// Count +// ---------------------------------------------------------------------------- +// +TInt CGlxStringCache::Count() + { + TRACER("TInt CGlxStringCache::Count()"); + return iStringCache.Count(); + } + +// ---------------------------------------------------------------------------- +// Find +// ---------------------------------------------------------------------------- +// +HBufC* CGlxStringCache::FindL(TInt aId) + { + TRACER("HBufC* CGlxStringCache::FindL(TInt aId)"); + // Create a TIdentityRelation to be used in the Find + TIdentityRelation match(&MatchById); + + // Create a dummy string item with the correct id to use in the find + CGlxStringItem* dummyItem = new (ELeave) CGlxStringItem(aId); + + // Call Find + TInt index = iStringCache.Find(dummyItem, match); + + // delete the dummy item + delete dummyItem; + + + if (KErrNotFound != index) + { + // The string was found so create a copy and pass to caller + CGlxStringItem* item = iStringCache[index]; + return item->GetString()->Des().AllocL(); + } + + // String was not found + return NULL; + } + +// ---------------------------------------------------------------------------- +// InsertL +// ---------------------------------------------------------------------------- +// +void CGlxStringCache::InsertL(TInt aId, HBufC* aString) + { + TRACER("void CGlxStringCache::InsertL(TInt aId, HBufC* aString)"); + // Create a TLinearOrder to be used in the InsertInOrder + TLinearOrder orderer(&OrderById); + + // Create the string item + CGlxStringItem* item = CGlxStringItem::NewL(aId, aString); + + // attempt to insert it + TInt err = iStringCache.InsertInOrder(item, orderer); + + switch (err) + { + case KErrNone: + // Do nothing as item has been inserted into cache + break; + + case KErrAlreadyExists: + // This is not an error, but we must tidy up + delete item; + break; + + default: + // We have an error + delete item; + User::Leave(err); + break; + } + } + +// ---------------------------------------------------------------------------- +// Compares two Id's by subtraction +// ---------------------------------------------------------------------------- +// +TInt CGlxStringCache::OrderById(const CGlxStringCache::CGlxStringItem& aItem1, const CGlxStringCache::CGlxStringItem& aItem2) + { + TRACER("TInt CGlxStringCache::OrderById()"); + return aItem1.GetId() - aItem2.GetId(); + } + +// ---------------------------------------------------------------------------- +// Compares two Id's logical equality +// ---------------------------------------------------------------------------- +// +TBool CGlxStringCache::MatchById(const CGlxStringCache::CGlxStringItem& aItem1, const CGlxStringCache::CGlxStringItem& aItem2) + { + TRACER("TBool CGlxStringCache::MatchById()"); + return aItem1.GetId() == aItem2.GetId(); + } + +// ---------------------------------------------------------------------------- +// Load the String +// ---------------------------------------------------------------------------- +// +EXPORT_C HBufC* CGlxStringCache::LoadLocalizedStringLC(const TDesC& aResourceFile, const TInt aResourceId) + { + TRACER("HBufC* CGlxCollectionPluginBase::LoadLocalizedStringLC()"); + HBufC* string = NULL; + + TFileName resourceFile; + resourceFile.Copy(aResourceFile); + + TRAPD(err, string = LoadLocalizedStringFromDriveL(resourceFile, aResourceId)); + + switch (err) + { + case KErrNone: + break; + + case KErrNotFound: + { + // Could not find resource file on drive z so try on drive c + _LIT(KCDrive,"c"); + resourceFile.Copy(KCDrive); + resourceFile.Append(aResourceFile.Mid(1)); + string = LoadLocalizedStringFromDriveL(resourceFile, aResourceId); + } + break; + + default: + { + GLX_DEBUG2("LEAVING LoadLocalizedStringLC with %d", err); + User::Leave(err); + } + break; + } + + CleanupStack::PushL(string); + + return string; + } + +// ---------------------------------------------------------------------------- +// Loads the String from a drive +// ---------------------------------------------------------------------------- +// +HBufC* CGlxStringCache::LoadLocalizedStringFromDriveL(const TDesC& aResourceFile, const TInt aResourceId) + { + TRACER("HBufC* CGlxCollectionPluginBase::LoadLocalizedStringFromDriveL()"); + + HBufC* string = NULL; + + if (NULL != (string = FindL(aResourceId))) + { + // String has been cached to return it + return string; + } + + + // The string has not been cached to read from resource file + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + + // find out if the resource name file has been cached + TBool resoureFileNameCached = (0 != iResourceFileName.Length()); + TFileName resFile; + + if (resoureFileNameCached) + { + // Use cached resource file name + resFile.Copy(iResourceFileName); + } + else + { + // Caluculate the path and language extension + TParse parse; + parse.Set( aResourceFile, &KDC_ECOM_RESOURCE_DIR, NULL ); + resFile.Copy(parse.FullName()); + + TLanguage language = ELangNone; + BaflUtils::NearestLanguageFile( fs, resFile, language); + // Do not cache the file name here as it could be the wrong drive + // causing a leave later + } + + RResourceFile resourceFile; + resourceFile.OpenL(fs, resFile); + CleanupClosePushL(resourceFile); + resourceFile.ConfirmSignatureL(0); // must use BA_RSS_SIGNATURE in resource file (not RSS_SIGNATURE). + + TResourceReader resReader; + + HBufC8* buf = resourceFile.AllocReadLC( aResourceId ); + resReader.SetBuffer( buf ); + string = resReader.ReadHBufCL(); + CleanupStack::PopAndDestroy( buf ); + + // We have succesfully read from the resource so + // check to see if we need to cache the file name + if (!resoureFileNameCached) + { + // Cache the resource file name + iResourceFileName.Copy(resFile); + } + + CleanupStack::PopAndDestroy( &resourceFile ); + CleanupStack::PopAndDestroy( &fs ); + + CleanupStack::PushL(string); + + InsertL(aResourceId, string); // InsertL won't create duplicates + + CleanupStack::Pop(string); + + return string; + }