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