sl@0: // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "pccenrepimpl.h" sl@0: sl@0: _LIT(KCreExt,".cre"); sl@0: _LIT(KTxtExt,".txt"); sl@0: _LIT(KOgnExt,".ogn"); sl@0: const TInt KExtLength=4; sl@0: const TInt KMinReposFileLength=12; sl@0: sl@0: //dummy fail transaction cleanup operation sl@0: void CPcRepImpl::FailTransactionCleanupOperation(TAny* /**aRepository*/) sl@0: { sl@0: //do nothing sl@0: } sl@0: sl@0: CPcRepImpl* CPcRepImpl::NewL(TUid aRepositoryUid,const TDesC& aInFileName,const TDesC& aOutFileName,TBool aAutoLoading) sl@0: { sl@0: CPcRepImpl* self=new (ELeave)CPcRepImpl(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aRepositoryUid,aInFileName,aOutFileName,aAutoLoading); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: void CPcRepImpl::ConstructL(TUid aRepositoryUid,const TDesC& aInFileName,const TDesC& aOutFileName,TBool aAutoLoading) sl@0: { sl@0: User::LeaveIfError(iFs.Connect()); sl@0: iRepository=CHeapRepository::NewL(aRepositoryUid); sl@0: sl@0: TFileName ognFile; // XXXXXXXX.ogn sl@0: TBool isOriginal; sl@0: sl@0: IsOriginalL(aRepositoryUid, aOutFileName, aAutoLoading, ognFile, isOriginal); sl@0: iRepository->SettingsArray().SetIsDefault(isOriginal); sl@0: if (!aAutoLoading) sl@0: { sl@0: //verify file name must be in format of XXXXXXXX. that is minimum length is 8+1+3=12 sl@0: if (aInFileName.Length()XXXXXXXX. sl@0: TPtrC inFileName(aInFileName.Right(KMinReposFileLength)); sl@0: TPtrC outFileName(aOutFileName.Right(KMinReposFileLength)); sl@0: TUint inRepUid; sl@0: TLex parser(inFileName.Left(8)); sl@0: TInt ret=parser.Val(inRepUid,EHex); sl@0: if (ret!=KErrNone) sl@0: (ret==KErrNoMemory)?User::Leave(ret):User::Leave(KErrArgument); sl@0: parser.Assign(outFileName.Left(8)); sl@0: TUint outRepUid; sl@0: ret=parser.Val(outRepUid,EHex); sl@0: if (ret!=KErrNone) sl@0: (ret==KErrNoMemory)?User::Leave(ret):User::Leave(KErrArgument); sl@0: sl@0: //now finally verify the extension of the output file sl@0: if (aOutFileName.Right(KExtLength).CompareF(KCreExt())!=0) sl@0: User::Leave(KErrArgument); sl@0: if (aInFileName.Right(KExtLength).CompareF(KTxtExt())==0) sl@0: { sl@0: iRepository->SetUid(TUid::Uid(inRepUid)); sl@0: CIniFileIn* iniFile=NULL; sl@0: ret=CIniFileIn::NewLC(iFs,iniFile,aInFileName); sl@0: User::LeaveIfError(ret); sl@0: iRepository->ReloadContentL(*iniFile); sl@0: CleanupStack::PopAndDestroy(); sl@0: } sl@0: else if (aInFileName.Right(KExtLength).CompareF(KCreExt())==0) sl@0: { sl@0: iRepository->SetUid(TUid::Uid(inRepUid)); sl@0: iRepository->CreateRepositoryFromCreFileL(iFs,aInFileName); sl@0: } sl@0: else sl@0: User::Leave(KErrArgument); sl@0: iOutFileName=aOutFileName.AllocL(); sl@0: } sl@0: else sl@0: { sl@0: //auto mode look for CRE first then TXT sl@0: TFileName crefile; sl@0: crefile.AppendNumFixedWidth(aRepositoryUid.iUid,EHex,8); sl@0: crefile.Append(KCreExt()); sl@0: TInt ret=KErrNone; sl@0: TRAP(ret,iRepository->CreateRepositoryFromCreFileL(iFs,crefile)); sl@0: if (ret!=KErrNone) sl@0: { sl@0: if (ret!=KErrNotFound) sl@0: User::Leave(ret); sl@0: //look for TXT now sl@0: TFileName file; sl@0: file.AppendNumFixedWidth(aRepositoryUid.iUid,EHex,8); sl@0: file.Append(KTxtExt()); sl@0: CIniFileIn* iniFile=NULL; sl@0: ret=CIniFileIn::NewLC(iFs,iniFile,file); sl@0: User::LeaveIfError(ret); sl@0: iRepository->ReloadContentL(*iniFile); sl@0: CleanupStack::PopAndDestroy(); sl@0: } sl@0: //output is always cre sl@0: iOutFileName=crefile.AllocL(); sl@0: } sl@0: GetSingleMetaArrayL(iSingleMetaArray); sl@0: if (isOriginal) sl@0: { sl@0: // An empty file is generated in the name of .ogn when sl@0: // the repository is loaded for the first time. see IsOriginalL(). sl@0: RFile file; sl@0: User::LeaveIfError(file.Create(iFs, ognFile, EFileWrite)); sl@0: file.Close(); sl@0: } sl@0: iInitialised=ETrue; sl@0: } sl@0: sl@0: CPcRepImpl::~CPcRepImpl() sl@0: { sl@0: /** persist to cre on destructor */ sl@0: if (iRepository && iInitialised) sl@0: Flush(); sl@0: sl@0: iFs.Close(); sl@0: iSingleMetaArray.Close(); sl@0: delete iRepository; sl@0: delete iOutFileName; sl@0: } sl@0: sl@0: TInt CPcRepImpl::Flush() sl@0: { sl@0: #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS sl@0: return iRepository->CommitChanges(iFs,KPersistFormatSupportsIndMetaIndicator,*iOutFileName); sl@0: #else sl@0: return iRepository->CommitChanges(iFs,KPersistFormatVersion,*iOutFileName); sl@0: #endif sl@0: } sl@0: sl@0: void CPcRepImpl::MoveL(TUint32 aSourcePartialKey, TUint32 aTargetPartialKey,TUint32 aMask, TUint32& aErrorKey) sl@0: { sl@0: RSettingPointerArray sourceSettings; sl@0: CleanupClosePushL(sourceSettings); sl@0: TInt error=iRepository->SettingsArray().Find(aSourcePartialKey & aMask, aMask, sourceSettings); sl@0: sl@0: //dont fail transaction if source settings is empty sl@0: if (error!=KErrNone) sl@0: { sl@0: aErrorKey = aSourcePartialKey; sl@0: User::Leave(error); sl@0: } sl@0: else if (sourceSettings.Count() == 0) sl@0: { sl@0: aErrorKey = aSourcePartialKey; sl@0: User::Leave(KErrNotFound); sl@0: } sl@0: sl@0: for (TInt i=0;iKey(); sl@0: TUint32 targetKey = sourceKey ^ ((aSourcePartialKey & aMask) ^ (aTargetPartialKey & aMask)); sl@0: TServerSetting* targetSetting = GetSetting(targetKey); sl@0: if (targetSetting && !targetSetting->IsDeleted()) sl@0: { sl@0: aErrorKey=targetKey; sl@0: User::Leave(KErrAlreadyExists); sl@0: } sl@0: } sl@0: sl@0: TRAPD(err,error = MOperationLogic::MoveL(aSourcePartialKey,aTargetPartialKey,aMask,aErrorKey, sourceSettings)); sl@0: sl@0: //the Move operation logic only mark it as deleted, now remove it from the settings list sl@0: RemoveAnyMarkDeleted(); sl@0: sl@0: User::LeaveIfError(err); sl@0: User::LeaveIfError(error); sl@0: sl@0: CleanupStack::PopAndDestroy(&sourceSettings); sl@0: } sl@0: sl@0: void CPcRepImpl::DeleteRangeL(TUint32 aPartialKey, TUint32 aMask,TUint32& aErrorKey) sl@0: { sl@0: RSettingPointerArray sourceSettings; sl@0: CleanupClosePushL(sourceSettings); sl@0: TInt error=FindSettings(aPartialKey & aMask, aMask, sourceSettings); sl@0: if (error==KErrNotFound) sl@0: { sl@0: aErrorKey=aPartialKey; sl@0: } sl@0: User::LeaveIfError(error); sl@0: DeleteSettingsRangeL(sourceSettings,aPartialKey,aErrorKey); sl@0: RemoveAnyMarkDeleted(); sl@0: CleanupStack::PopAndDestroy(&sourceSettings); sl@0: } sl@0: sl@0: void CPcRepImpl::GetSingleMetaArrayL(RSingleMetaArray& aMetaArray) sl@0: { sl@0: TInt numSettings = iRepository->SettingsArray().Count(); sl@0: aMetaArray.Reset(); sl@0: aMetaArray.ReserveL(numSettings); sl@0: for (TInt i = 0; i < numSettings; i++) sl@0: { sl@0: TUint32 key = iRepository->SettingsArray()[i].Key(); sl@0: TUint32 meta = iRepository->SettingsArray()[i].Meta(); sl@0: TSettingSingleMeta metaItem(key, meta); sl@0: aMetaArray.AppendL(metaItem); sl@0: } sl@0: } sl@0: sl@0: // This function is used to identify wether the repository is loaded for the first sl@0: // time or not. The purpose of this function is to determine whether entries of a sl@0: // repository should be set clean during initializing process. At symbian side, this sl@0: // flag is only set when load from ROM, but at PC side, there is no ROM, so the clean sl@0: // flag is set when load for the first time to keep consistency with Symbian side Library. sl@0: void CPcRepImpl::IsOriginalL(TUid aUid, const TDesC& aOutFile, TBool aAutoLoading, TFileName& aOgnFileName, TBool& aIsOriginal) sl@0: { sl@0: if (!aAutoLoading) sl@0: { sl@0: TInt len = aOutFile.Length(); sl@0: aOgnFileName = aOutFile.Left(len - KExtLength); sl@0: } sl@0: else sl@0: { sl@0: aOgnFileName.AppendNumFixedWidth(aUid.iUid,EHex,8); sl@0: } sl@0: aOgnFileName.Append(KOgnExt()); sl@0: sl@0: RFile file; sl@0: TInt err = file.Open(iFs,aOgnFileName,EFileRead|EFileShareReadersOnly); sl@0: file.Close(); sl@0: if (err != KErrNone) sl@0: { sl@0: if (err == KErrNotFound || err == KErrPathNotFound) sl@0: { sl@0: aIsOriginal = ETrue; sl@0: return; sl@0: } sl@0: else sl@0: User::Leave(err); sl@0: } sl@0: aIsOriginal = EFalse; sl@0: }