|
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". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "pccenrepimpl.h" |
|
17 |
|
18 _LIT(KCreExt,".cre"); |
|
19 _LIT(KTxtExt,".txt"); |
|
20 _LIT(KOgnExt,".ogn"); |
|
21 const TInt KExtLength=4; |
|
22 const TInt KMinReposFileLength=12; |
|
23 |
|
24 //dummy fail transaction cleanup operation |
|
25 void CPcRepImpl::FailTransactionCleanupOperation(TAny* /**aRepository*/) |
|
26 { |
|
27 //do nothing |
|
28 } |
|
29 |
|
30 CPcRepImpl* CPcRepImpl::NewL(TUid aRepositoryUid,const TDesC& aInFileName,const TDesC& aOutFileName,TBool aAutoLoading) |
|
31 { |
|
32 CPcRepImpl* self=new (ELeave)CPcRepImpl(); |
|
33 CleanupStack::PushL(self); |
|
34 self->ConstructL(aRepositoryUid,aInFileName,aOutFileName,aAutoLoading); |
|
35 CleanupStack::Pop(); |
|
36 return self; |
|
37 } |
|
38 |
|
39 void CPcRepImpl::ConstructL(TUid aRepositoryUid,const TDesC& aInFileName,const TDesC& aOutFileName,TBool aAutoLoading) |
|
40 { |
|
41 User::LeaveIfError(iFs.Connect()); |
|
42 iRepository=CHeapRepository::NewL(aRepositoryUid); |
|
43 |
|
44 TFileName ognFile; // XXXXXXXX.ogn |
|
45 TBool isOriginal; |
|
46 |
|
47 IsOriginalL(aRepositoryUid, aOutFileName, aAutoLoading, ognFile, isOriginal); |
|
48 iRepository->SettingsArray().SetIsDefault(isOriginal); |
|
49 if (!aAutoLoading) |
|
50 { |
|
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)); |
|
57 TUint inRepUid; |
|
58 TLex parser(inFileName.Left(8)); |
|
59 TInt ret=parser.Val(inRepUid,EHex); |
|
60 if (ret!=KErrNone) |
|
61 (ret==KErrNoMemory)?User::Leave(ret):User::Leave(KErrArgument); |
|
62 parser.Assign(outFileName.Left(8)); |
|
63 TUint outRepUid; |
|
64 ret=parser.Val(outRepUid,EHex); |
|
65 if (ret!=KErrNone) |
|
66 (ret==KErrNoMemory)?User::Leave(ret):User::Leave(KErrArgument); |
|
67 |
|
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) |
|
72 { |
|
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(); |
|
79 } |
|
80 else if (aInFileName.Right(KExtLength).CompareF(KCreExt())==0) |
|
81 { |
|
82 iRepository->SetUid(TUid::Uid(inRepUid)); |
|
83 iRepository->CreateRepositoryFromCreFileL(iFs,aInFileName); |
|
84 } |
|
85 else |
|
86 User::Leave(KErrArgument); |
|
87 iOutFileName=aOutFileName.AllocL(); |
|
88 } |
|
89 else |
|
90 { |
|
91 //auto mode look for CRE first then TXT |
|
92 TFileName crefile; |
|
93 crefile.AppendNumFixedWidth(aRepositoryUid.iUid,EHex,8); |
|
94 crefile.Append(KCreExt()); |
|
95 TInt ret=KErrNone; |
|
96 TRAP(ret,iRepository->CreateRepositoryFromCreFileL(iFs,crefile)); |
|
97 if (ret!=KErrNone) |
|
98 { |
|
99 if (ret!=KErrNotFound) |
|
100 User::Leave(ret); |
|
101 //look for TXT now |
|
102 TFileName file; |
|
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(); |
|
110 } |
|
111 //output is always cre |
|
112 iOutFileName=crefile.AllocL(); |
|
113 } |
|
114 GetSingleMetaArrayL(iSingleMetaArray); |
|
115 if (isOriginal) |
|
116 { |
|
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(). |
|
119 RFile file; |
|
120 User::LeaveIfError(file.Create(iFs, ognFile, EFileWrite)); |
|
121 file.Close(); |
|
122 } |
|
123 iInitialised=ETrue; |
|
124 } |
|
125 |
|
126 CPcRepImpl::~CPcRepImpl() |
|
127 { |
|
128 /** persist to cre on destructor */ |
|
129 if (iRepository && iInitialised) |
|
130 Flush(); |
|
131 |
|
132 iFs.Close(); |
|
133 iSingleMetaArray.Close(); |
|
134 delete iRepository; |
|
135 delete iOutFileName; |
|
136 } |
|
137 |
|
138 TInt CPcRepImpl::Flush() |
|
139 { |
|
140 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS |
|
141 return iRepository->CommitChanges(iFs,KPersistFormatSupportsIndMetaIndicator,*iOutFileName); |
|
142 #else |
|
143 return iRepository->CommitChanges(iFs,KPersistFormatVersion,*iOutFileName); |
|
144 #endif |
|
145 } |
|
146 |
|
147 void CPcRepImpl::MoveL(TUint32 aSourcePartialKey, TUint32 aTargetPartialKey,TUint32 aMask, TUint32& aErrorKey) |
|
148 { |
|
149 RSettingPointerArray sourceSettings; |
|
150 CleanupClosePushL(sourceSettings); |
|
151 TInt error=iRepository->SettingsArray().Find(aSourcePartialKey & aMask, aMask, sourceSettings); |
|
152 |
|
153 //dont fail transaction if source settings is empty |
|
154 if (error!=KErrNone) |
|
155 { |
|
156 aErrorKey = aSourcePartialKey; |
|
157 User::Leave(error); |
|
158 } |
|
159 else if (sourceSettings.Count() == 0) |
|
160 { |
|
161 aErrorKey = aSourcePartialKey; |
|
162 User::Leave(KErrNotFound); |
|
163 } |
|
164 |
|
165 for (TInt i=0;i<sourceSettings.Count();i++) |
|
166 { |
|
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()) |
|
172 { |
|
173 aErrorKey=targetKey; |
|
174 User::Leave(KErrAlreadyExists); |
|
175 } |
|
176 } |
|
177 |
|
178 TRAPD(err,error = MOperationLogic::MoveL(aSourcePartialKey,aTargetPartialKey,aMask,aErrorKey, sourceSettings)); |
|
179 |
|
180 //the Move operation logic only mark it as deleted, now remove it from the settings list |
|
181 RemoveAnyMarkDeleted(); |
|
182 |
|
183 User::LeaveIfError(err); |
|
184 User::LeaveIfError(error); |
|
185 |
|
186 CleanupStack::PopAndDestroy(&sourceSettings); |
|
187 } |
|
188 |
|
189 void CPcRepImpl::DeleteRangeL(TUint32 aPartialKey, TUint32 aMask,TUint32& aErrorKey) |
|
190 { |
|
191 RSettingPointerArray sourceSettings; |
|
192 CleanupClosePushL(sourceSettings); |
|
193 TInt error=FindSettings(aPartialKey & aMask, aMask, sourceSettings); |
|
194 if (error==KErrNotFound) |
|
195 { |
|
196 aErrorKey=aPartialKey; |
|
197 } |
|
198 User::LeaveIfError(error); |
|
199 DeleteSettingsRangeL(sourceSettings,aPartialKey,aErrorKey); |
|
200 RemoveAnyMarkDeleted(); |
|
201 CleanupStack::PopAndDestroy(&sourceSettings); |
|
202 } |
|
203 |
|
204 void CPcRepImpl::GetSingleMetaArrayL(RSingleMetaArray& aMetaArray) |
|
205 { |
|
206 TInt numSettings = iRepository->SettingsArray().Count(); |
|
207 aMetaArray.Reset(); |
|
208 aMetaArray.ReserveL(numSettings); |
|
209 for (TInt i = 0; i < numSettings; i++) |
|
210 { |
|
211 TUint32 key = iRepository->SettingsArray()[i].Key(); |
|
212 TUint32 meta = iRepository->SettingsArray()[i].Meta(); |
|
213 TSettingSingleMeta metaItem(key, meta); |
|
214 aMetaArray.AppendL(metaItem); |
|
215 } |
|
216 } |
|
217 |
|
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) |
|
224 { |
|
225 if (!aAutoLoading) |
|
226 { |
|
227 TInt len = aOutFile.Length(); |
|
228 aOgnFileName = aOutFile.Left(len - KExtLength); |
|
229 } |
|
230 else |
|
231 { |
|
232 aOgnFileName.AppendNumFixedWidth(aUid.iUid,EHex,8); |
|
233 } |
|
234 aOgnFileName.Append(KOgnExt()); |
|
235 |
|
236 RFile file; |
|
237 TInt err = file.Open(iFs,aOgnFileName,EFileRead|EFileShareReadersOnly); |
|
238 file.Close(); |
|
239 if (err != KErrNone) |
|
240 { |
|
241 if (err == KErrNotFound || err == KErrPathNotFound) |
|
242 { |
|
243 aIsOriginal = ETrue; |
|
244 return; |
|
245 } |
|
246 else |
|
247 User::Leave(err); |
|
248 } |
|
249 aIsOriginal = EFalse; |
|
250 } |