Merge "Remove fallback routines and memory leak." into tizen_2.1
[platform/framework/native/appfw.git] / src / io / FIo_RegistryImpl.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file        FIo_RegistryImpl.cpp
19  * @brief       This is the implementation file for _RegistryImpl class.
20  */
21
22 #include <unistd.h>
23 #include <new>
24 #include <unique_ptr.h>
25 #include <locale.h>
26 #include <string.h>
27 #include <errno.h>
28
29 #include <FBaseInteger.h>
30 #include <FBaseDouble.h>
31 #include <FBaseFloat.h>
32 #include <FBaseUuId.h>
33 #include <FBaseByteBuffer.h>
34 #include <FBaseColHashMap.h>
35 #include <FBaseColIEnumerator.h>
36 #include <FBaseUtilStringTokenizer.h>
37 #include <FBaseResult.h>
38 #include <FBaseSysLog.h>
39 #include <FIoFile.h>
40 #include <FIoRegistry.h>
41
42 #include <FBase_StringConverter.h>
43 #include <FIo_FileImpl.h>
44 #include <FIo_RegistryImpl.h>
45 #include <FIo_NormalRegistry.h>
46 #include <FIo_SecureRegistry.h>
47 #include <FIo_SecureIoUtil.h>
48
49 using namespace std;
50 using namespace Tizen::Base;
51 using namespace Tizen::Base::Utility;
52 using namespace Tizen::Base::Collection;
53
54 namespace Tizen { namespace Io
55 {
56
57 static const int _MAX_REG_OPENMODE_LENGTH = 2;
58
59 _RegistryImpl::_RegistryImpl(void)
60         : __pRegistryCore(null)
61         , __loc((locale_t)0)
62 {
63 }
64
65 _RegistryImpl::~_RegistryImpl(void)
66 {
67         delete __pRegistryCore;
68         if (__loc != (locale_t)0)
69         {
70                 freelocale(__loc);
71         }
72 }
73
74 bool
75 _RegistryImpl::ConvertRegistryOpenMode(long legacyMode, char* pOpenMode)
76 {
77         switch (legacyMode)
78         {
79         case REG_OPEN_READ_ONLY:
80                 strcpy(pOpenMode, "r\0");
81                 break;
82         case REG_OPEN_READ_WRITE:
83                 strcpy(pOpenMode, "r+\0");
84                 break; 
85         case (REG_OPEN_READ_WRITE | REG_OPEN_CREATE):
86                 strcpy(pOpenMode, "a+\0");
87                 break;
88         default:
89                 SysLog(NID_IO, "[E_INVALID_ARG] The specified openMode is invalid.");
90                 return false;
91         }
92         return true;
93 }
94
95 // This method will be removed in a future release.
96 result
97 _RegistryImpl::Construct(const String& regPath, long legacyMode, const ByteBuffer* pSecretKey)
98 {
99         SysAssertf(__pRegistryCore == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class\n");
100
101         unique_ptr<char[]> pOpenMode(new char[_MAX_REG_OPENMODE_LENGTH + 1]);
102         SysTryReturnResult(NID_IO, pOpenMode != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
103
104         bool isValid = _RegistryImpl::ConvertRegistryOpenMode(legacyMode, pOpenMode.get());
105         SysTryReturnResult(NID_IO, isValid == true, E_INVALID_ARG, "The specified openMode is invalid.");
106
107         return Construct(regPath, pOpenMode.get(), pSecretKey);
108 }
109
110 result
111 _RegistryImpl::Construct(const String& regPath, const char* pOpenMode, const ByteBuffer* pSecretKey)
112 {
113         SysAssertf(__pRegistryCore == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class\n");
114
115         result r = E_SUCCESS;
116         if (!pSecretKey)
117         {
118                 unique_ptr<_NormalRegistry> pNormalRegistry(new (std::nothrow) _NormalRegistry());
119                 SysTryReturnResult(NID_IO, pNormalRegistry != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
120
121                 r = pNormalRegistry->Construct(regPath, pOpenMode);
122                 if (IsFailed(r))
123                 {
124                         SysLogException(NID_IO, r, "[%s] Propagated.", GetErrorMessage(r));
125                         return r;
126                 }
127                 __pRegistryCore = pNormalRegistry.release();
128         }
129         else
130         {
131                 unique_ptr<_SecureRegistry> pSecureRegistry(new (std::nothrow) _SecureRegistry());
132                 SysTryReturnResult(NID_IO, pSecureRegistry != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
133
134                 r = pSecureRegistry->Construct(regPath, pOpenMode, pSecretKey);
135                 if (IsFailed(r))
136                 {
137                         SysLogException(NID_IO, r, "[%s] Propagated.", GetErrorMessage(r));
138                         return r;
139                 }
140                 __pRegistryCore = pSecureRegistry.release();
141         }
142
143         __loc = newlocale(LC_ALL_MASK, "C", (locale_t)0);
144         if (__loc == (locale_t)0)
145         {
146                 SysLogException(NID_IO, E_SYSTEM, "[E_SYSTEM] Failed to create locale object. errno: %d (%s)",
147                                 errno, strerror(errno));
148         }
149
150         return r;
151 }
152
153 result
154 _RegistryImpl::Remove(const String& regPath)
155 {
156         return _FileImpl::Remove(regPath);
157 }
158
159 result
160 _RegistryImpl::AddSection(const String& sectionName)
161 {
162         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
163         return __pRegistryCore->AddSection(sectionName);
164 }
165
166 result
167 _RegistryImpl::RemoveSection(const String& sectionName)
168 {
169         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
170         return __pRegistryCore->RemoveSection(sectionName);
171 }
172
173 result
174 _RegistryImpl::GetSectionListN(IList** pRetList)
175 {
176         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
177         return __pRegistryCore->GetSectionListN(pRetList);
178 }
179
180
181 result
182 _RegistryImpl::GetEntryList(const String& sectionName, Collection::HashMap& retMap)
183 {
184         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
185         return __pRegistryCore->GetEntryList(sectionName, retMap);
186 }
187
188
189 result
190 _RegistryImpl::GetEntryListN(const String& sectionName, HashMap** pRetList)
191 {
192         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
193         return __pRegistryCore->GetEntryListN(sectionName, pRetList);
194 }
195
196 IMap*
197 _RegistryImpl::GetAllEntriesN(const String& sectionName) const
198 {
199         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
200         return __pRegistryCore->GetAllEntriesN(sectionName);
201 }
202
203 IList*
204 _RegistryImpl::GetAllEntryNamesN(const String& sectionName) const
205 {
206         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
207         return __pRegistryCore->GetAllEntryNamesN(sectionName);
208 }
209
210 result
211 _RegistryImpl::GetValue(const String& sectionName, const String& entryName, float& entryValue)
212 {
213         String value;
214         uselocale(__loc);
215         result r = GetValue(sectionName, entryName, value);
216         if (!IsFailed(r))
217         {
218                 r = Float::Parse(value, entryValue);
219                 if (IsFailed(r))
220                 {
221                         r = E_PARSING_FAILED;
222                 }
223         }
224         uselocale(LC_GLOBAL_LOCALE);
225         return r;
226 }
227
228 result
229 _RegistryImpl::GetValue(const String& sectionName, const String& entryName, double& entryValue)
230 {
231         String value;
232         uselocale(__loc);
233         result r = GetValue(sectionName, entryName, value);
234         if (!IsFailed(r))
235         {
236                 r = Double::Parse(value, entryValue);
237                 if (IsFailed(r))
238                 {
239                         r = E_PARSING_FAILED;
240                 }
241         }
242         uselocale(LC_GLOBAL_LOCALE);
243         return r;
244 }
245
246 result
247 _RegistryImpl::GetValue(const String& sectionName, const String& entryName, String& entryValue)
248 {
249         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
250         return __pRegistryCore->GetValue(sectionName, entryName, entryValue);
251 }
252
253 result
254 _RegistryImpl::AddValue(const String& sectionName, const String& entryName, float entryValue)
255 {
256         uselocale(__loc);
257         result r = AddValue(sectionName, entryName, Float::ToString(entryValue));
258         uselocale(LC_GLOBAL_LOCALE);
259         return r;
260 }
261
262 result
263 _RegistryImpl::AddValue(const String& sectionName, const String& entryName, double entryValue)
264 {
265         uselocale(__loc);
266         result r = AddValue(sectionName, entryName, Double::ToString(entryValue));
267         uselocale(LC_GLOBAL_LOCALE);
268         return r;
269 }
270
271 result
272 _RegistryImpl::AddValue(const String& sectionName, const String& entryName, const String& entryValue)
273 {
274         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
275         return __pRegistryCore->AddValue(sectionName, entryName, entryValue);
276 }
277
278 result
279 _RegistryImpl::SetValue(const String& sectionName, const String& entryName, float entryValue)
280 {
281         uselocale(__loc);
282         result r = SetValue(sectionName, entryName, Float::ToString(entryValue));
283         uselocale(LC_GLOBAL_LOCALE);
284         return r;
285 }
286
287 result
288 _RegistryImpl::SetValue(const String& sectionName, const String& entryName, double entryValue)
289 {
290         uselocale(__loc);
291         result r = SetValue(sectionName, entryName, Double::ToString(entryValue));
292         uselocale(LC_GLOBAL_LOCALE);
293         return r;
294 }
295
296 result
297 _RegistryImpl::SetValue(const String& sectionName, const String& entryName, const String& entryValue)
298 {
299         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
300         return __pRegistryCore->SetValue(sectionName, entryName, entryValue);
301 }
302
303 result
304 _RegistryImpl::RemoveValue(const String& sectionName, const String& entryName)
305 {
306         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
307         return __pRegistryCore->RemoveValue(sectionName, entryName);
308 }
309
310 result
311 _RegistryImpl::Flush(void)
312 {
313         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
314         return __pRegistryCore->Flush();
315 }
316
317 result
318 _RegistryImpl::ConvertToSecureRegistry(const String& plainRegPath, const String& secureRegPath, const ByteBuffer* pKey)
319 {
320         return _SecureRegistry::ConvertToSecureRegistry(plainRegPath, secureRegPath, pKey);
321 }
322
323 int
324 _RegistryImpl::GetSectionIndex(const String& sectionName)
325 {
326         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
327         return __pRegistryCore->GetSectionIndex(sectionName);
328 }
329
330 void
331 _RegistryImpl::Removekey(const String& sectionName, const String& keyName)
332 {
333         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
334         __pRegistryCore->Removekey(sectionName, keyName);
335 }
336
337 int
338 _RegistryImpl::GetAllSectionCount(void)
339 {
340         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
341         return __pRegistryCore->GetAllSectionCount();
342 }
343
344
345 int
346 _RegistryImpl::GetAllEntryCount(int sectionIndex)
347 {
348         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
349         return __pRegistryCore->GetAllEntryCount(sectionIndex);
350 }
351
352 void
353 _RegistryImpl::RemoveEntry(int sectionIndex, int entryIndex)
354 {
355         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
356         __pRegistryCore->RemoveEntry(sectionIndex, entryIndex);
357 }
358
359 void
360 _RegistryImpl::ModifyEntryValue(int sectionIndex, int entryIndex, _RegValueType type, const void* pValue, int size)
361 {
362         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
363         __pRegistryCore->ModifyEntryValue(sectionIndex, entryIndex, type, pValue, size);
364 }
365
366 int
367 _RegistryImpl::GetEntryIndex(int sectionIndex, const String& entryName)
368 {
369         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
370         return __pRegistryCore->GetEntryIndex(sectionIndex, entryName);
371 }
372
373 String
374 _RegistryImpl::GetEntryName(int sectionIndex, int entryIndex)
375 {
376         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
377         return __pRegistryCore->GetEntryName(sectionIndex, entryIndex);
378 }
379
380 void
381 _RegistryImpl::GetEntryValue(int sectionIndex, int entryIndex, _RegValueType type, void* pValue, int* pSize)
382 {
383         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
384         if (type == REG_VALUE_TYPE_REAL)
385         {
386                 uselocale(__loc);
387                 __pRegistryCore->GetEntryValue(sectionIndex, entryIndex, type, pValue, pSize);
388                 uselocale(LC_GLOBAL_LOCALE);
389         }
390         else
391         {
392                 __pRegistryCore->GetEntryValue(sectionIndex, entryIndex, type, pValue, pSize);
393         }
394 }
395
396 String
397 _RegistryImpl::GetSectionName(int sectionIndex)
398 {
399         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
400         return __pRegistryCore->GetSectionName(sectionIndex);
401 }
402
403 void*
404 _RegistryImpl::GetSectionByIndex(int sectionIndex)
405 {
406         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
407         return __pRegistryCore->GetSectionByIndex(sectionIndex);
408 }
409
410 _RegistryImpl*
411 _RegistryImpl::GetInstance(Registry& registry)
412 {
413         return registry.__pRegistryImpl;
414 }
415
416 const _RegistryImpl*
417 _RegistryImpl::GetInstance(const Registry& registry)
418 {
419         return registry.__pRegistryImpl;
420 }
421
422 FileLock*
423 _RegistryImpl::LockN(FileLockType lockType)
424 {
425         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
426         return __pRegistryCore->LockN(lockType);
427 }
428
429 FileLock*
430 _RegistryImpl::TryToLockN(FileLockType lockType)
431 {
432         SysAssertf(__pRegistryCore != null, "Not yet constructed. Construct() should be called before use.\n");
433         return __pRegistryCore->TryToLockN(lockType);
434 }
435
436 }} // Tizen::Io
437