os/persistentdata/persistentstorage/centralrepository/pccenrep/src/pccenrepimpl.cpp
Update contrib.
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "pccenrepimpl.h"
21 const TInt KExtLength=4;
22 const TInt KMinReposFileLength=12;
24 //dummy fail transaction cleanup operation
25 void CPcRepImpl::FailTransactionCleanupOperation(TAny* /**aRepository*/)
30 CPcRepImpl* CPcRepImpl::NewL(TUid aRepositoryUid,const TDesC& aInFileName,const TDesC& aOutFileName,TBool aAutoLoading)
32 CPcRepImpl* self=new (ELeave)CPcRepImpl();
33 CleanupStack::PushL(self);
34 self->ConstructL(aRepositoryUid,aInFileName,aOutFileName,aAutoLoading);
39 void CPcRepImpl::ConstructL(TUid aRepositoryUid,const TDesC& aInFileName,const TDesC& aOutFileName,TBool aAutoLoading)
41 User::LeaveIfError(iFs.Connect());
42 iRepository=CHeapRepository::NewL(aRepositoryUid);
44 TFileName ognFile; // XXXXXXXX.ogn
47 IsOriginalL(aRepositoryUid, aOutFileName, aAutoLoading, ognFile, isOriginal);
48 iRepository->SettingsArray().SetIsDefault(isOriginal);
51 //verify file name must be in format of XXXXXXXX.<cre/txt> that is minimum length is 8+1+3=12
52 if (aInFileName.Length()<KMinReposFileLength || aOutFileName.Length()<KMinReposFileLength)
53 User::Leave(KErrArgument);
54 //verify it is in the format of <path>XXXXXXXX.<cre/txt>
55 TPtrC inFileName(aInFileName.Right(KMinReposFileLength));
56 TPtrC outFileName(aOutFileName.Right(KMinReposFileLength));
58 TLex parser(inFileName.Left(8));
59 TInt ret=parser.Val(inRepUid,EHex);
61 (ret==KErrNoMemory)?User::Leave(ret):User::Leave(KErrArgument);
62 parser.Assign(outFileName.Left(8));
64 ret=parser.Val(outRepUid,EHex);
66 (ret==KErrNoMemory)?User::Leave(ret):User::Leave(KErrArgument);
68 //now finally verify the extension of the output file
69 if (aOutFileName.Right(KExtLength).CompareF(KCreExt())!=0)
70 User::Leave(KErrArgument);
71 if (aInFileName.Right(KExtLength).CompareF(KTxtExt())==0)
73 iRepository->SetUid(TUid::Uid(inRepUid));
74 CIniFileIn* iniFile=NULL;
75 ret=CIniFileIn::NewLC(iFs,iniFile,aInFileName);
76 User::LeaveIfError(ret);
77 iRepository->ReloadContentL(*iniFile);
78 CleanupStack::PopAndDestroy();
80 else if (aInFileName.Right(KExtLength).CompareF(KCreExt())==0)
82 iRepository->SetUid(TUid::Uid(inRepUid));
83 iRepository->CreateRepositoryFromCreFileL(iFs,aInFileName);
86 User::Leave(KErrArgument);
87 iOutFileName=aOutFileName.AllocL();
91 //auto mode look for CRE first then TXT
93 crefile.AppendNumFixedWidth(aRepositoryUid.iUid,EHex,8);
94 crefile.Append(KCreExt());
96 TRAP(ret,iRepository->CreateRepositoryFromCreFileL(iFs,crefile));
99 if (ret!=KErrNotFound)
103 file.AppendNumFixedWidth(aRepositoryUid.iUid,EHex,8);
104 file.Append(KTxtExt());
105 CIniFileIn* iniFile=NULL;
106 ret=CIniFileIn::NewLC(iFs,iniFile,file);
107 User::LeaveIfError(ret);
108 iRepository->ReloadContentL(*iniFile);
109 CleanupStack::PopAndDestroy();
111 //output is always cre
112 iOutFileName=crefile.AllocL();
114 GetSingleMetaArrayL(iSingleMetaArray);
117 // An empty file is generated in the name of <Repository Uid>.ogn when
118 // the repository is loaded for the first time. see IsOriginalL().
120 User::LeaveIfError(file.Create(iFs, ognFile, EFileWrite));
126 CPcRepImpl::~CPcRepImpl()
128 /** persist to cre on destructor */
129 if (iRepository && iInitialised)
133 iSingleMetaArray.Close();
138 TInt CPcRepImpl::Flush()
140 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
141 return iRepository->CommitChanges(iFs,KPersistFormatSupportsIndMetaIndicator,*iOutFileName);
143 return iRepository->CommitChanges(iFs,KPersistFormatVersion,*iOutFileName);
147 void CPcRepImpl::MoveL(TUint32 aSourcePartialKey, TUint32 aTargetPartialKey,TUint32 aMask, TUint32& aErrorKey)
149 RSettingPointerArray sourceSettings;
150 CleanupClosePushL(sourceSettings);
151 TInt error=iRepository->SettingsArray().Find(aSourcePartialKey & aMask, aMask, sourceSettings);
153 //dont fail transaction if source settings is empty
156 aErrorKey = aSourcePartialKey;
159 else if (sourceSettings.Count() == 0)
161 aErrorKey = aSourcePartialKey;
162 User::Leave(KErrNotFound);
165 for (TInt i=0;i<sourceSettings.Count();i++)
167 TServerSetting* ts=sourceSettings[i];
168 TUint32 sourceKey = ts->Key();
169 TUint32 targetKey = sourceKey ^ ((aSourcePartialKey & aMask) ^ (aTargetPartialKey & aMask));
170 TServerSetting* targetSetting = GetSetting(targetKey);
171 if (targetSetting && !targetSetting->IsDeleted())
174 User::Leave(KErrAlreadyExists);
178 TRAPD(err,error = MOperationLogic::MoveL(aSourcePartialKey,aTargetPartialKey,aMask,aErrorKey, sourceSettings));
180 //the Move operation logic only mark it as deleted, now remove it from the settings list
181 RemoveAnyMarkDeleted();
183 User::LeaveIfError(err);
184 User::LeaveIfError(error);
186 CleanupStack::PopAndDestroy(&sourceSettings);
189 void CPcRepImpl::DeleteRangeL(TUint32 aPartialKey, TUint32 aMask,TUint32& aErrorKey)
191 RSettingPointerArray sourceSettings;
192 CleanupClosePushL(sourceSettings);
193 TInt error=FindSettings(aPartialKey & aMask, aMask, sourceSettings);
194 if (error==KErrNotFound)
196 aErrorKey=aPartialKey;
198 User::LeaveIfError(error);
199 DeleteSettingsRangeL(sourceSettings,aPartialKey,aErrorKey);
200 RemoveAnyMarkDeleted();
201 CleanupStack::PopAndDestroy(&sourceSettings);
204 void CPcRepImpl::GetSingleMetaArrayL(RSingleMetaArray& aMetaArray)
206 TInt numSettings = iRepository->SettingsArray().Count();
208 aMetaArray.ReserveL(numSettings);
209 for (TInt i = 0; i < numSettings; i++)
211 TUint32 key = iRepository->SettingsArray()[i].Key();
212 TUint32 meta = iRepository->SettingsArray()[i].Meta();
213 TSettingSingleMeta metaItem(key, meta);
214 aMetaArray.AppendL(metaItem);
218 // This function is used to identify wether the repository is loaded for the first
219 // time or not. The purpose of this function is to determine whether entries of a
220 // repository should be set clean during initializing process. At symbian side, this
221 // flag is only set when load from ROM, but at PC side, there is no ROM, so the clean
222 // flag is set when load for the first time to keep consistency with Symbian side Library.
223 void CPcRepImpl::IsOriginalL(TUid aUid, const TDesC& aOutFile, TBool aAutoLoading, TFileName& aOgnFileName, TBool& aIsOriginal)
227 TInt len = aOutFile.Length();
228 aOgnFileName = aOutFile.Left(len - KExtLength);
232 aOgnFileName.AppendNumFixedWidth(aUid.iUid,EHex,8);
234 aOgnFileName.Append(KOgnExt());
237 TInt err = file.Open(iFs,aOgnFileName,EFileRead|EFileShareReadersOnly);
241 if (err == KErrNotFound || err == KErrPathNotFound)
249 aIsOriginal = EFalse;