Merge "Fix the defect of calculating time" into tizen_2.2
[platform/framework/native/appfw.git] / src / io / FIo_RegistryCore.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_RegistryCore.cpp
19  * @brief       This is the implementation file for _RegistryCore class.
20  */
21
22 #include <unistd.h>
23 #include <new>
24 #include <unique_ptr.h>
25
26 #include <FBaseInteger.h>
27 #include <FBaseDouble.h>
28 #include <FBaseFloat.h>
29 #include <FBaseUuId.h>
30 #include <FBaseByteBuffer.h>
31 #include <FBaseColIEnumerator.h>
32 #include <FBaseUtilStringTokenizer.h>
33 #include <FBaseResult.h>
34 #include <FBaseSysLog.h>
35 #include <FBaseColAllElementsDeleter.h>
36 #include <FIoFile.h>
37 #include <FIoRegistry.h>
38
39 #include <FBase_StringConverter.h>
40 #include <FApp_AppInfo.h>
41 #include "FIo_FileImpl.h"
42 #include "FIo_NormalRegistry.h"
43 #include "FIo_SecureRegistry.h"
44 #include "FIo_RegistryCore.h"
45 #include "FIo_SecureIoUtil.h"
46
47 using namespace std;
48 using namespace Tizen::Base;
49 using namespace Tizen::Base::Utility;
50 using namespace Tizen::Base::Collection;
51
52 namespace Tizen { namespace Io
53 {
54
55 static const size_t _MAX_REG_OPENMODE_LENGTH = 2;
56
57 #define _REGISTRY_SECTION_MARKER_CHAR   L'#'
58 #define _REGISTRY_SECTION_VALUE_ASSIGNMENT_MARKER_CHAR L'='
59
60 class _RegistrySection
61         : public Object
62 {
63 public:
64         ~_RegistrySection(void);
65 private:
66         String __sectionName;
67         LinkedList __entryList;
68         friend class _RegistryCore;
69 };
70
71 _RegistrySection::~_RegistrySection(void)
72 {
73         __entryList.RemoveAll(true);
74 }
75
76 class _RegistryEntry
77         : public Object
78 {
79 public:
80         String entryName;
81         String entryValue;
82 };
83
84 _RegistryCore::_RegistryCore(void)
85         : _constructed(false)
86         , _read(false)
87         , _write(false)
88         , _truncate(false)
89         , _append(false)
90         , _update(false)
91         , _pBuffer(null)
92         , _length(0)
93         , __pFileImpl(null)
94 {
95 }
96
97 _RegistryCore::~_RegistryCore(void)
98 {
99         delete __pFileImpl;
100 }
101
102 bool
103 _RegistryCore::VerifyRegistryOpenMode(const char* pOpenMode)
104 {
105         if (pOpenMode == null)
106         {
107                 SysLog(NID_IO, "[E_INVALID_ARG] The specified openMode is null.");
108                 return false;
109         }
110
111         if (strlen(pOpenMode) > _MAX_REG_OPENMODE_LENGTH)
112         {
113                 SysLog(NID_IO, "[E_INVALID_ARG] The specified openMode (%s) is invalid.", pOpenMode);
114                 return false;
115         }
116
117         switch (pOpenMode[0])
118         {
119         case 'r':
120                 _read = true;
121                 break;
122         case 'w':
123                 _write = true;
124                 _truncate = true;
125                 break;
126         case 'a':
127                 _write = true;
128                 _append = true;
129                 break;
130         default:
131                 SysLog(NID_IO, "[E_INVALID_ARG] The specified openMode (%s) is invalid.", pOpenMode);
132                 return false;
133         }
134
135         switch (pOpenMode[1])
136         {
137         case '\0':
138                 break;
139         case '+':
140                 if (pOpenMode[2] == '\0')
141                 {
142                         _read = true;
143                         _write = true;
144                         break;
145                 }
146                 else
147                 {
148                         SysLog(NID_IO, "[E_INVALID_ARG] The specified openMode (%s) is invalid.", pOpenMode);
149                         return false;
150                 }
151         default:
152                 SysLog(NID_IO, "[E_INVALID_ARG] The specified openMode (%s) is invalid.", pOpenMode);
153                 return false;
154         }
155
156         return true;
157 }
158
159 result
160 _RegistryCore::Parse(void)
161 {
162         result r = E_SUCCESS;
163         wchar_t ch = '\0';
164         bool sectionFound = false;
165         String sectionName;
166         int length = 0;
167         unique_ptr<char[]> pEntryName(null);
168         unique_ptr<char[]> pEntryValue(null);
169         int firstTokenPos = 0;
170         String line;
171
172         if (_pBuffer == null)
173         {
174                 SysLog(NID_IO, "The buffer is empty.");
175                 return E_SUCCESS;
176         }
177
178         String inputStr = String((char*)_pBuffer);
179         StringTokenizer lineTok(inputStr, L"\n");
180
181         r = lineTok.GetNextToken(line);
182
183         while (r == E_SUCCESS)
184         {
185                 // skip empty lines
186                 if (line.GetLength() == 0)
187                 {
188                         r = lineTok.GetNextToken(line);
189                         continue;
190                 }
191
192                 // find registry section marker
193                 line.GetCharAt(0, ch);
194                 if (ch == _REGISTRY_SECTION_MARKER_CHAR)
195                 {
196                         sectionFound = true;
197
198                         // skip '#' and "\n' at the end
199                         r = line.SubString(1, line.GetLength() - 1, sectionName);
200                         SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Propagated.", GetErrorMessage(r));
201
202                         // if End of the document follows section name without newline character.
203                         sectionName.GetCharAt(sectionName.GetLength() - 1, ch);
204                         if (ch == L'\n')
205                         {
206                                 sectionName.SetLength(sectionName.GetLength() - 1); //Remove '\n'
207                         }
208
209                         // for compatibility check if line contains  '\r' at the end
210                         sectionName.GetCharAt(sectionName.GetLength() - 1, ch);
211                         if (ch == L'\r')
212                         {
213                                 sectionName.SetLength(sectionName.GetLength() - 1); //Remove '\r'
214                         }
215
216                         //TODO: check if remaining data in sectionName is valid or not
217                         //after removing '#', '\n', and '\r', sectionName should contain at least 1 valid character
218                         SysTryCatch(NID_IO,
219                                            sectionName.GetLength() > 0, r = E_PARSING_FAILED, E_PARSING_FAILED,
220                                            "[E_PARSING_FAILED] Section length cannot be <2.");
221
222                         unique_ptr<char[]> pSectionName(_StringConverter::CopyToCharArrayN(sectionName));
223                         SysTryCatch(NID_IO, pSectionName != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
224                                            "[E_OUT_OF_MEMORY] The memory is insufficient.");
225
226                         if (!_RegistryCore::CheckSectionName(pSectionName.get()))
227                         {
228                                 SysTryCatch(NID_IO, false, r = E_PARSING_FAILED, E_PARSING_FAILED,
229                                                    "[E_PARSING_FAILED] Section name could not be parsed.");
230                         }
231
232                         r = _RegistryCore::AddSection(_sectionList, sectionName);
233                         SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Propagated.", GetErrorMessage(r));
234                 }
235                 else    // not a section.. but may belongs to a section (entry)
236                 {
237                         // ignores blank lines
238                         line.GetCharAt(0, ch);
239                         if ((ch == L'\n') || (ch == L'\r'))
240                         {
241                                 r = lineTok.GetNextToken(line);
242                                 continue;
243                         }
244
245                         //TODO
246                         // Need to check for tabs, spaces in the beginning of each line
247
248                         // if no section found till now.. ignore
249                         if (sectionFound == false)
250                         {
251                                 r = lineTok.GetNextToken(line);
252                                 continue;
253                         }
254
255                         // if End of the document follows entry value without newline character.
256                         line.GetCharAt(line.GetLength() - 1, ch);
257                         if (ch == L'\n')
258                         {
259                                 line.SetLength(line.GetLength() - 1); //Remove '\n'
260                         }
261
262                         line.GetCharAt(line.GetLength() - 1, ch);
263                         if (ch == L'\r')
264                         {
265                                 line.SetLength(line.GetLength() - 1); //Remove '\r'
266                         }
267
268                         String entryName("");
269                         String entryVal("");
270
271                         // we will have sectionitem=value (or) sectionitem= (or) sectionitem
272                         // as our string. Break this into entry and value
273                         StringTokenizer strTok(line, L"=");
274
275                         // extract entry name
276                         if (strTok.HasMoreTokens())
277                         {
278                                 line.IndexOf(L'=', 0, firstTokenPos); // position of first occurance of '=' in a line
279                                 if (firstTokenPos == 0)
280                                 {
281                                         // entryName should not be empty. i.e., "=value"  or just '=' is invalid case
282                                         SysTryCatch(NID_IO, false, r = E_PARSING_FAILED, E_PARSING_FAILED,
283                                                            "[E_PARSING_FAILED] Entry name cannot be empty.");
284                                 }
285                                 else
286                                 {
287                                         strTok.GetNextToken(entryName);
288                                 }
289                         }
290                         else // missing '=' in  entry line or entry line does not seem to contain "xxx=xxx" format
291                         {
292                                 SysTryCatch(NID_IO, false, r = E_PARSING_FAILED, E_PARSING_FAILED, "[E_PARSING_FAILED] invalid entry Line found.");
293                         }
294
295                         // check if entry name contains invalid chars
296                         pEntryName.reset(_StringConverter::CopyToCharArrayN(entryName));
297                         SysTryCatch(NID_IO, pEntryName, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
298                                            "[E_OUT_OF_MEMORY] The memory is insufficient.");
299
300                         if (!_RegistryCore::CheckEntryName(pEntryName.get()))
301                         {
302                                 SysTryCatch(NID_IO, false, r = E_PARSING_FAILED, E_PARSING_FAILED,
303                                                    "[E_PARSING_FAILED] Entry name could not be parsed.");
304                         }
305
306                         line.SubString(firstTokenPos + 1, entryVal); // extract entry value
307
308                         // check if entry value contains invalid chars
309                         pEntryValue.reset(_StringConverter::CopyToCharArrayN(entryVal));
310                         SysTryCatch(NID_IO, pEntryValue, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
311                                            "[E_OUT_OF_MEMORY] The memory is insufficient.");
312
313                         length = strlen(pEntryValue.get());
314                         if (length > 0)
315                         {
316                                 if (!_RegistryCore::CheckEntryValue(pEntryValue.get()))
317                                 {
318                                         SysTryCatch(NID_IO, false, r = E_PARSING_FAILED, E_PARSING_FAILED,
319                                                            "[E_PARSING_FAILED] Entry value could not be parsed.");
320                                 }
321                         }
322
323                         // add the entry and value
324                         r = _RegistryCore::AddValue(_sectionList, sectionName, entryName, entryVal);
325                         SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Propagated.", GetErrorMessage(r));
326                 }
327                 r = lineTok.GetNextToken(line);
328         } // while()
329
330         if (r == E_OUT_OF_RANGE)
331         {
332                 r = E_SUCCESS;
333         }
334
335         // fall through
336 CATCH:
337
338         if (r == E_PARSING_FAILED && Tizen::App::_AppInfo::IsOspCompat() == false)
339         {
340                 r = E_INVALID_FORMAT;
341         }
342
343         SysLog(NID_IO, "[%s] exception occurred.", GetErrorMessage(r));
344         return r;
345 }
346
347 result
348 _RegistryCore::Load(const String& regPath, const char* pOpenMode)
349 {
350         result r = E_SUCCESS;
351         delete[] _pBuffer; //clear existing buffer
352         _pBuffer = null;
353         _length = 0;
354
355         // open registry file
356         unique_ptr<_FileImpl> pFileImpl(new (std::nothrow) _FileImpl());
357         SysTryReturnResult(NID_IO, pFileImpl != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
358
359         r = pFileImpl->Construct(regPath, pOpenMode, null);
360         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Constructing the file has failed.", GetErrorMessage(r));
361
362         // reset the section list to be sure that its empty
363         _sectionList.RemoveAll(true);
364
365         if (_truncate == false)
366         {
367                 // load the registry file
368                 r = pFileImpl->ReadN((char**)&_pBuffer, _length);
369                 if (_length > 0)
370                 {
371                         _length--;
372                 }
373         }
374
375         __pFileImpl = pFileImpl.release();
376
377         return r;
378 }
379
380 result
381 _RegistryCore::AddSection(const String& sectionName)
382 {
383         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
384
385         result r = E_SUCCESS;
386         bool sectionFound = false;
387
388         // Get section information
389         unique_ptr<IEnumerator> pEnum(_sectionList.GetEnumeratorN());
390         if (pEnum == null)
391         {
392                 return GetLastResult();
393         }
394
395         while (pEnum->MoveNext() == E_SUCCESS)
396         {
397                 _RegistrySection* pRegSection = dynamic_cast <_RegistrySection*>(pEnum->GetCurrent());
398                 SysTryReturn(NID_IO, pRegSection != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
399                                    GetErrorMessage(GetLastResult()));
400
401                 if (pRegSection->__sectionName == sectionName)
402                 {
403                         sectionFound = true;
404                         break;
405                 }
406         }
407
408         if (sectionFound == true)
409         {
410                 return E_SECTION_ALREADY_EXIST;
411         }
412
413         // create a key with section name
414         unique_ptr<_RegistrySection> pRegSection(new (std::nothrow) _RegistrySection());
415         SysTryReturnResult(NID_IO, pRegSection != null, E_OUT_OF_MEMORY,
416                            "The memory is insufficient.");
417
418         pRegSection->__sectionName = sectionName;
419
420         // add new section and section-entry map
421         r = _sectionList.Add(*(pRegSection.release()));
422         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
423
424         _update = true;
425         return E_SUCCESS;
426 }
427
428 result
429 _RegistryCore::RemoveSection(const String& sectionName)
430 {
431         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
432
433         result r = E_SUCCESS;
434         _RegistrySection* pRegSection = null;
435         bool sectionFound = false;
436
437         if (_sectionList.GetCount() == 0)
438         {
439                 return E_SECTION_NOT_FOUND;
440         }
441
442         // Get section information
443         unique_ptr<IEnumerator> pEnum(_sectionList.GetEnumeratorN());
444         if (pEnum == null)
445         {
446                 return GetLastResult();
447         }
448
449         while (pEnum->MoveNext() == E_SUCCESS)
450         {
451                 pRegSection = dynamic_cast< _RegistrySection* >(pEnum->GetCurrent());
452                 SysTryReturn(NID_IO, pRegSection != null, GetLastResult(), GetLastResult(), "[%s] Propagating.",
453                                    GetErrorMessage(GetLastResult()));
454
455                 if (pRegSection->__sectionName == sectionName)
456                 {
457                         sectionFound = true;
458                         break;
459                 }
460         }
461
462         if (sectionFound == false)
463         {
464                 return E_SECTION_NOT_FOUND;
465         }
466
467         r = _sectionList.Remove(*pRegSection, true);
468         SysTryReturnResult(NID_IO, !IsFailed(r), E_IO, "system error");
469
470         _update = true;
471         return E_SUCCESS;
472 }
473
474 result
475 _RegistryCore::GetSectionListN(IList** pRetList)
476 {
477         result r = E_SUCCESS;
478         unique_ptr<IEnumerator> pEnum(null);
479         _RegistrySection* pSection = null;
480
481         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
482         SysTryReturnResult(NID_IO, pRetList != null, E_INVALID_ARG, "pList cannot be null.");
483
484         // construct an array list to be returned
485         unique_ptr<ArrayList, AllElementsDeleter> pSectionList(new (std::nothrow) ArrayList());
486         SysTryReturnResult(NID_IO, pSectionList != null, E_OUT_OF_MEMORY,
487                            "The memory is insufficient.");
488
489         r = pSectionList->Construct();
490         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
491
492         // if no sectons, return empty list
493         if (_sectionList.GetCount() == 0)
494         {
495                 *pRetList = pSectionList.release();
496                 return E_SUCCESS;
497         }
498
499         // copy from class section list to the new list and return
500         pEnum.reset(_sectionList.GetEnumeratorN());
501         SysTryReturn(NID_IO, pEnum != null, GetLastResult(), GetLastResult(), "[%s] Section list is empty.", GetErrorMessage(GetLastResult()));
502
503         while (pEnum->MoveNext() == E_SUCCESS)
504         {
505                 pSection = dynamic_cast <_RegistrySection*>(pEnum->GetCurrent());
506                 SysTryReturn(NID_IO, pSection != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
507                                    GetErrorMessage(GetLastResult()));
508
509                 unique_ptr<String> pSectionName(new (std::nothrow) String(pSection->__sectionName));
510                 SysTryReturnResult(NID_IO, pSectionName != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
511
512                 r = pSectionList->Add(*(pSectionName.release()));
513                 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
514         }
515
516         *pRetList = pSectionList.release();
517
518         return E_SUCCESS;
519 }
520
521 result
522 _RegistryCore::GetEntryList(const String& sectionName, Collection::HashMap& retMap)
523 {
524         result r = E_SUCCESS;
525         unique_ptr<IEnumerator> pEnum(null);
526         unique_ptr<String> pKeyEntryStr(null);
527         unique_ptr<String> pKeyValStr(null);
528         bool sectionFound = false;
529         _RegistrySection* pRegSection = null;
530         _RegistryEntry* pRegEntry = null;
531
532         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
533
534         if (_sectionList.GetCount() == 0)
535         {
536                 return E_SECTION_NOT_FOUND;
537         }
538
539         // Get section information
540         pEnum.reset(_sectionList.GetEnumeratorN());
541         SysTryReturnResult(NID_IO, pEnum != null, E_SYSTEM, "Section list is empty.");
542
543         while (pEnum->MoveNext() == E_SUCCESS)
544         {
545                 pRegSection = dynamic_cast <_RegistrySection*>(pEnum->GetCurrent());
546                 SysTryReturn(NID_IO, pRegSection != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
547                                    GetErrorMessage(GetLastResult()));
548
549                 if (pRegSection->__sectionName == sectionName)
550                 {
551                         sectionFound = true;
552                         break;
553                 }
554         }
555
556         if (sectionFound == false)
557         {
558                 return E_SECTION_NOT_FOUND;
559         }
560
561         // copy from item list to the new list and return
562         pEnum.reset((pRegSection->__entryList).GetEnumeratorN());
563         SysTryReturn(NID_IO, pEnum != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
564                                            GetErrorMessage(GetLastResult()));
565
566         while (pEnum->MoveNext() == E_SUCCESS)
567         {
568                 pRegEntry = dynamic_cast <_RegistryEntry*>(pEnum->GetCurrent());
569                 SysTryReturn(NID_IO, pRegEntry != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
570                                    GetErrorMessage(GetLastResult()));
571
572                 pKeyEntryStr.reset(new (std::nothrow) String((pRegEntry->entryName)));
573                 SysTryCatch(NID_IO, pKeyEntryStr != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
574                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
575                 pKeyValStr.reset(new (std::nothrow) String((pRegEntry->entryValue)));
576                 SysTryCatch(NID_IO, pKeyValStr != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
577                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
578
579                 r = retMap.Add(*(pKeyEntryStr.release()), *(pKeyValStr.release()));
580                 SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Propagated.", GetErrorMessage(r));
581         }
582
583         return E_SUCCESS;
584
585 CATCH:
586         retMap.RemoveAll(true);
587
588         return r;
589 }
590
591 result
592 _RegistryCore::GetEntryListN(const String& sectionName, HashMap** pRetList)
593 {
594         result r = E_SUCCESS;
595
596         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
597         SysTryReturnResult(NID_IO, pRetList != null, E_INVALID_ARG, "pRetList cannot be null.");
598
599         // construct an array list to be returned
600         unique_ptr<HashMap, AllElementsDeleter> pEntryList(new (std::nothrow) HashMap());
601         SysTryReturnResult(NID_IO, pEntryList != null, E_OUT_OF_MEMORY,
602                         "The memory is insufficient.");
603         r = pEntryList->Construct();
604         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
605         r = GetEntryList(sectionName, *(pEntryList.get()));
606         *pRetList = pEntryList.release();
607
608         return r;
609 }
610
611 IMap*
612 _RegistryCore::GetAllEntriesN(const String& sectionName)
613 {
614         result r = E_SUCCESS;
615         HashMap* pMap = null;
616
617         r = GetEntryListN(sectionName, &pMap);
618         SysTryCatch(NID_IO, !IsFailed(r), , r, "[%s] Propagated.", GetErrorMessage(r));
619
620         SetLastResult(E_SUCCESS);
621         return pMap;
622
623 CATCH:
624         SetLastResult(r);
625         return null;
626 }
627
628 IList*
629 _RegistryCore::GetAllEntryNamesN(const String& sectionName)
630 {
631         result r = E_SUCCESS;
632
633         unique_ptr<ArrayList, AllElementsDeleter> pEntryList(new (std::nothrow) ArrayList());
634         SysTryReturn(NID_IO, pEntryList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
635
636         r = pEntryList->Construct();
637         SysTryReturn(NID_IO, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
638
639         unique_ptr<IMap, AllElementsDeleter> pMap(this->GetAllEntriesN(sectionName));
640         SysTryReturn(NID_IO, pMap != null, null, GetLastResult(), "[%s] Getting all entries was failed.",
641                         GetErrorMessage(GetLastResult()));
642
643         unique_ptr<IMapEnumerator> pMapEnum(pMap->GetMapEnumeratorN());
644         SysTryReturn(NID_IO, pMapEnum, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
645         while (pMapEnum->MoveNext() == E_SUCCESS)
646         {
647                 String* pKey = dynamic_cast< String* >(pMapEnum->GetKey());
648                 SysTryReturn(NID_IO, pKey != null, null, E_IO, "[E_OUT_OF_MEMORY] The system error occurred.");
649
650                 String* pEntryName = new (std::nothrow) String(*pKey);
651                 SysTryReturn(NID_IO, pEntryName != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
652
653                 r = pEntryList->Add(*pEntryName);
654                 SysTryReturn(NID_IO, !IsFailed(r), null, r, "[%s] Propagated.", GetErrorMessage(r));
655         }
656
657         SetLastResult(E_SUCCESS);
658         return pEntryList.release();
659 }
660
661 result
662 _RegistryCore::GetValue(const String& sectionName, const String& entryName, String& valStr)
663 {
664         bool sectionFound = false;
665         bool entryFound = false;
666         _RegistrySection* pRegSection = null;
667         _RegistryEntry* pRegEntry = null;
668
669         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
670
671         if (_sectionList.GetCount() == 0)
672         {
673                 return E_SECTION_NOT_FOUND;
674         }
675
676         // Get section information
677         unique_ptr<IEnumerator> pEnum(_sectionList.GetEnumeratorN());
678         if (pEnum == null)
679         {
680                 return GetLastResult();
681         }
682
683         while (pEnum->MoveNext() == E_SUCCESS)
684         {
685                 pRegSection = dynamic_cast <_RegistrySection*>(pEnum->GetCurrent());
686                 SysTryReturn(NID_IO, pRegSection != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
687                                    GetErrorMessage(GetLastResult()));
688
689                 if (pRegSection->__sectionName == sectionName)
690                 {
691                         sectionFound = true;
692                         break;
693                 }
694         }
695
696         if (sectionFound == false)
697         {
698                 return E_SECTION_NOT_FOUND;
699         }
700
701         pEnum.reset(pRegSection->__entryList.GetEnumeratorN());
702         if (pEnum == null)
703         {
704                 return GetLastResult();
705         }
706
707         while (pEnum->MoveNext() == E_SUCCESS)
708         {
709                 pRegEntry = dynamic_cast <_RegistryEntry*>(pEnum->GetCurrent());
710                 SysTryReturn(NID_IO, pRegEntry != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
711                                    GetErrorMessage(GetLastResult()));
712
713                 if (pRegEntry->entryName == entryName)
714                 {
715                         valStr = pRegEntry->entryValue;
716                         entryFound = true;
717                         break;
718                 }
719         }
720
721         SysTryLog(NID_IO, entryFound, "Entry not found");
722
723         return((entryFound == true) ? E_SUCCESS : E_KEY_NOT_FOUND);
724 }
725
726 result
727 _RegistryCore::AddValue(const String& sectionName, const String& entryName, const String& valStr)
728 {
729         result r = E_SUCCESS;
730         bool sectionFound = false;
731         bool entryFound = false;
732         _RegistrySection* pRegSection = null;
733         int length = 0;
734
735         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
736
737         // Get section information
738         unique_ptr<IEnumerator> pEnum(_sectionList.GetEnumeratorN());
739         if (pEnum == null)
740         {
741                 return GetLastResult();
742         }
743
744         while (pEnum->MoveNext() == E_SUCCESS)
745         {
746                 pRegSection = dynamic_cast <_RegistrySection*>(pEnum->GetCurrent());
747                 SysTryReturn(NID_IO, pRegSection != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
748                                    GetErrorMessage(GetLastResult()));
749
750                 if (pRegSection->__sectionName == sectionName)
751                 {
752                         sectionFound = true;
753                         break;
754                 }
755         }
756
757         if (sectionFound == false)
758         {
759                 return E_SECTION_NOT_FOUND;
760         }
761
762         pEnum.reset(pRegSection->__entryList.GetEnumeratorN());
763         if (pEnum == null)
764         {
765                 return GetLastResult();
766         }
767
768         while (pEnum->MoveNext() == E_SUCCESS)
769         {
770                 _RegistryEntry* pRegEntry = dynamic_cast <_RegistryEntry*>(pEnum->GetCurrent());
771                 SysTryReturn(NID_IO, pRegEntry != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
772                                    GetErrorMessage(GetLastResult()));
773
774                 if (pRegEntry->entryName == entryName)
775                 {
776                         entryFound = true;
777                         break;
778                 }
779         }
780
781         if (entryFound == true)
782         {
783                 return E_KEY_ALREADY_EXIST;
784         }
785
786         unique_ptr<_RegistryEntry> pRegEntry(new (std::nothrow) _RegistryEntry());
787         SysTryReturnResult(NID_IO, pRegEntry != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
788
789         unique_ptr<char[]> pEntryName(_StringConverter::CopyToCharArrayN(entryName));
790         SysTryReturnResult(NID_IO, pEntryName != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
791
792         length = strlen(pEntryName.get());
793         if (!_RegistryCore::CheckEntryName(pEntryName.get()))
794         {
795                 SysTryReturnResult(NID_IO, false, E_PARSING_FAILED, "Entry name could not be parsed.");
796         }
797
798         unique_ptr<char[]> pEntryValue(_StringConverter::CopyToCharArrayN(valStr));
799         SysTryReturnResult(NID_IO, pEntryValue != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
800
801         length = strlen(pEntryValue.get());
802         if (length > 0 && !_RegistryCore::CheckEntryValue(pEntryValue.get()))
803         {
804                 SysTryReturnResult(NID_IO, false, E_PARSING_FAILED, "Entry value could not be parsed.");
805         }
806
807         pRegEntry->entryName = entryName;
808         pRegEntry->entryValue = valStr;
809
810         r = pRegSection->__entryList.Add(*(pRegEntry.release()));
811         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
812
813         _update = true;
814         return E_SUCCESS;
815 }
816
817 result
818 _RegistryCore::SetValue(const String& sectionName, const String& entryName, const String& valStr)
819 {
820         result r = E_SUCCESS;
821         bool sectionFound = false;
822         bool entryFound = false;
823         _RegistryEntry* pRegEntry = null;
824         _RegistrySection* pRegSection = null;
825         int length = 0;
826         int entryIndex = 0;
827
828         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
829
830         if (_sectionList.GetCount() == 0)
831         {
832                 return E_SECTION_NOT_FOUND;
833         }
834
835         // Get section information
836         unique_ptr<IEnumerator> pEnum(_sectionList.GetEnumeratorN());
837         if (pEnum == null)
838         {
839                 return GetLastResult();
840         }
841
842         while (pEnum->MoveNext() == E_SUCCESS)
843         {
844                 pRegSection = dynamic_cast< _RegistrySection* >(pEnum->GetCurrent());
845                 SysTryReturn(NID_IO, pRegSection != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
846                                    GetErrorMessage(GetLastResult()));
847
848                 if (pRegSection->__sectionName == sectionName)
849                 {
850                         sectionFound = true;
851                         break;
852                 }
853         }
854
855         if (sectionFound == false)
856         {
857                 return E_SECTION_NOT_FOUND;
858         }
859
860         pEnum.reset(pRegSection->__entryList.GetEnumeratorN());
861         if (pEnum == null)
862         {
863                 return GetLastResult();
864         }
865
866         while (pEnum->MoveNext() == E_SUCCESS)
867         {
868                 pRegEntry = dynamic_cast< _RegistryEntry* >(pEnum->GetCurrent());
869                 SysTryReturn(NID_IO, pRegEntry != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
870                                    GetErrorMessage(GetLastResult()));
871
872                 if (pRegEntry->entryName == entryName)
873                 {
874                         entryFound = true;
875                         break;
876                 }
877                 entryIndex++;
878         }
879
880         if (entryFound == false)
881         {
882                 return E_KEY_NOT_FOUND;
883         }
884
885         if (valStr.GetLength() > 0)
886         {
887                 unique_ptr<char[]> pEntryValue(_StringConverter::CopyToCharArrayN(valStr));
888                 SysTryReturnResult(NID_IO, pEntryValue != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
889
890                 length = strlen(pEntryValue.get());
891                 if (!_RegistryCore::CheckEntryValue(pEntryValue.get()))
892                 {
893                         return E_PARSING_FAILED;
894                 }
895         }
896
897         pRegEntry->entryValue = valStr;
898         r = pRegSection->__entryList.SetAt(*pRegEntry, entryIndex);
899         SysTryReturnResult(NID_IO, !IsFailed(r), E_IO, "system error");
900
901         _update = true;
902         return E_SUCCESS;
903 }
904
905 result
906 _RegistryCore::RemoveValue(const String& sectionName, const String& entryName)
907 {
908         result r = E_SUCCESS;
909         bool sectionFound = false;
910         bool entryFound = false;
911         _RegistryEntry* pRegEntry = null;
912         _RegistrySection* pRegSection = null;
913
914         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
915
916         if (_sectionList.GetCount() <= 0)
917         {
918                 return E_SECTION_NOT_FOUND;
919         }
920
921         // Get section information
922         unique_ptr<IEnumerator> pEnum(_sectionList.GetEnumeratorN());
923         if (pEnum == null)
924         {
925                 return E_SECTION_NOT_FOUND;
926         }
927
928         while (pEnum->MoveNext() == E_SUCCESS)
929         {
930                 pRegSection = dynamic_cast <_RegistrySection*>(pEnum->GetCurrent());
931                 SysTryReturn(NID_IO, pRegSection != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
932                                    GetErrorMessage(GetLastResult()));
933
934                 if (pRegSection->__sectionName == sectionName)
935                 {
936                         sectionFound = true;
937                         break;
938                 }
939         }
940
941         if (sectionFound == false)
942         {
943                 return E_SECTION_NOT_FOUND;
944         }
945
946         pEnum.reset(pRegSection->__entryList.GetEnumeratorN());
947         if (pEnum == null)
948         {
949                 return E_SECTION_NOT_FOUND;
950         }
951
952         while (pEnum->MoveNext() == E_SUCCESS)
953         {
954                 pRegEntry = dynamic_cast <_RegistryEntry*>(pEnum->GetCurrent());
955                 SysTryReturn(NID_IO, pRegEntry != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
956                                    GetErrorMessage(GetLastResult()));
957
958                 if (pRegEntry->entryName == entryName)
959                 {
960                         entryFound = true;
961                         break;
962                 }
963         }
964
965         if (entryFound == false)
966         {
967                 return E_KEY_NOT_FOUND;
968         }
969
970         r = pRegSection->__entryList.Remove(*pRegEntry, true);
971         SysTryReturnResult(NID_IO, !IsFailed(r), E_IO, "system error");
972
973         _update = true;
974         return E_SUCCESS;
975 }
976
977 result
978 _RegistryCore::Flush(void)
979 {
980         return E_SUCCESS;
981 }
982
983 result
984 _RegistryCore::Write(void)
985 {
986         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
987
988         if (_pBuffer == null)
989         {
990                 SysLog(NID_IO, "The buffer is empty.");
991                 return E_SUCCESS;
992         }
993
994         result r = E_SUCCESS;
995
996         String openMode(L"w+");
997         unique_ptr<_FileImpl> pFileImpl(new (std::nothrow) _FileImpl);
998         SysTryReturnResult(NID_IO, pFileImpl != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
999
1000         //TODO: Secure mode is to be handled
1001         r = pFileImpl->Construct(_regPath, "w+", null);
1002         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
1003
1004         r = pFileImpl->Write(_pBuffer, _length);
1005         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
1006
1007         r = pFileImpl->Flush();
1008         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
1009
1010         return r;
1011 }
1012
1013 result
1014 _RegistryCore::PrepareToWrite(void)
1015 {
1016         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
1017
1018         result r = E_SUCCESS;
1019         _RegistryEntry* pRegEntry = null;
1020         _RegistrySection* pRegSection = null;
1021         String inputBuffer;
1022
1023         delete[] _pBuffer; //clear existing buffer
1024         _pBuffer = null;
1025         _length = 0;
1026
1027         if (_write == false)
1028         {
1029                 SysLog(NID_IO, "[E_ILLEGAL_ACCESS] Registry cannot be flushed as it was opened in read only mode.");
1030                 return E_ILLEGAL_ACCESS;
1031         }
1032
1033         // if no sections, do nothing
1034         if (_sectionList.GetCount() == 0)
1035         {
1036                 unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(_regPath));
1037                 truncate(pFilePath.get(), 0);
1038
1039                 return E_SUCCESS;
1040         }
1041
1042         // write the registry map to a file
1043         // Get section information
1044         unique_ptr<IEnumerator> pSectionEnum(_sectionList.GetEnumeratorN());
1045         SysTryReturn(NID_IO, pSectionEnum != null, GetLastResult(), GetLastResult(), "[%s] Section list is empty.",
1046                            GetErrorMessage(GetLastResult()));
1047
1048         while (pSectionEnum->MoveNext() == E_SUCCESS)
1049         {
1050                 // get section name
1051                 pRegSection = dynamic_cast <_RegistrySection*>(pSectionEnum->GetCurrent());
1052                 SysTryReturn(NID_IO, pRegSection != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
1053                                    GetErrorMessage(GetLastResult()));
1054
1055                 // write section name to file
1056                 r = inputBuffer.Append(String(L"#" + pRegSection->__sectionName + String(L'\n')));
1057                 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
1058
1059                 // read the entries for this section
1060                 unique_ptr<IEnumerator> pEntryEnum(pRegSection->__entryList.GetEnumeratorN());
1061                 SysTryReturn(NID_IO, pSectionEnum != null, GetLastResult(), GetLastResult(), "[%s] Entry list is empty.",
1062                                    GetErrorMessage(GetLastResult()));
1063
1064                 while (pEntryEnum->MoveNext() == E_SUCCESS)
1065                 {
1066                         pRegEntry = dynamic_cast <_RegistryEntry*>(pEntryEnum->GetCurrent());
1067                         SysTryReturn(NID_IO, pRegEntry != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
1068                                            GetErrorMessage(GetLastResult()));
1069
1070                         // write entry name to file
1071                         r = inputBuffer.Append(pRegEntry->entryName + String(L"=" + pRegEntry->entryValue + String(L'\n')));
1072                         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
1073                 }
1074
1075         }
1076
1077         _pBuffer = (byte*)_StringConverter::CopyToCharArrayN(inputBuffer);
1078         SysTryReturn(NID_IO, _pBuffer != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
1079                                                    GetErrorMessage(GetLastResult()));
1080
1081         _length = strlen((char*)_pBuffer);
1082
1083         return r;
1084 }
1085
1086 int
1087 _RegistryCore::GetSectionIndex(const String& sectionName)
1088 {
1089         bool sectionFound = false;
1090         _RegistrySection* pRegSection = null;
1091         int index = 0;
1092
1093         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
1094         SysTryReturn(NID_IO, sectionName.GetLength() > 0, -1, E_INVALID_ARG,
1095                            "[E_INVALID_ARG] sectionName.GetLength() <= 0");
1096
1097         SysTryReturn(NID_IO, _sectionList.GetCount() > 0, -1, E_SECTION_NOT_FOUND, "[E_SECTION_NOT_FOUND] Section not found.");
1098
1099         // Get section information
1100         unique_ptr<IEnumerator> pEnum(_sectionList.GetEnumeratorN());
1101         SysTryReturn(NID_IO, pEnum != null, GetLastResult(), GetLastResult(), "[%s] Section list is empty.",
1102                            GetErrorMessage(GetLastResult()));
1103
1104         while (pEnum->MoveNext() == E_SUCCESS)
1105         {
1106                 pRegSection = dynamic_cast <_RegistrySection*>(pEnum->GetCurrent());
1107                 SysTryReturn(NID_IO, pRegSection != null, -1, GetLastResult(), "[%s] Propagated.",
1108                                    GetErrorMessage(GetLastResult()));
1109
1110                 if (pRegSection->__sectionName == sectionName)
1111                 {
1112                         sectionFound = true;
1113                         break;
1114                 }
1115                 index++;
1116         }
1117
1118         if (sectionFound == false)
1119         {
1120                 return E_SECTION_NOT_FOUND;
1121         }
1122
1123         SetLastResult(E_SUCCESS);
1124         return index;
1125 }
1126
1127 void
1128 _RegistryCore::Removekey(const String& sectionName, const String& keyName)
1129 {
1130         result r = E_SUCCESS;
1131         int sectionIndex = -1;
1132         int entryIndex = -1;
1133
1134         sectionIndex = GetSectionIndex(sectionName);
1135         r = GetLastResult();
1136         SysTryReturnVoidResult(NID_IO, !IsFailed(r), r, "[%s] Propagated.", GetErrorMessage(r));
1137
1138         entryIndex = GetEntryIndex(sectionIndex, keyName);
1139         r = GetLastResult();
1140         SysTryReturnVoidResult(NID_IO, !IsFailed(r), r, "[%s] Propagated.", GetErrorMessage(r));
1141
1142         RemoveEntry(sectionIndex, entryIndex);
1143         r = GetLastResult();
1144         SysTryReturnVoidResult(NID_IO, !IsFailed(r), r, "[%s] Propagated.", GetErrorMessage(r));
1145
1146         SetLastResult(E_SUCCESS);
1147         return;
1148 }
1149
1150 int
1151 _RegistryCore::GetAllSectionCount(void)
1152 {
1153         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
1154
1155         SetLastResult(E_SUCCESS);
1156         return _sectionList.GetCount();
1157 }
1158
1159 int
1160 _RegistryCore::GetAllEntryCount(int sectionIndex)
1161 {
1162         _RegistrySection* pRegSection = null;
1163         int listSize = 0;
1164
1165         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
1166         SysTryReturn(NID_IO, sectionIndex >= 0, 0, E_INVALID_ARG, "[E_INVALID_ARG] sectionIndex < 0.");
1167         listSize = _sectionList.GetCount();
1168         SysTryReturn(NID_IO, listSize > 0, 0, E_SECTION_NOT_FOUND, "[E_INVALID_ARG] section listSize <= 0.");
1169         SysTryReturn(NID_IO, sectionIndex >= listSize, 0, E_SECTION_NOT_FOUND,
1170                            "[E_INVALID_ARG] sectionIndex > listSize.");
1171
1172         pRegSection = (_RegistrySection*) GetSectionByIndex(sectionIndex);
1173         SysTryReturn(NID_IO, pRegSection != null, 0, E_SECTION_NOT_FOUND,
1174                            "[E_SECTION_NOT_FOUND] section was not found.");
1175
1176         SetLastResult(E_SUCCESS);
1177         return pRegSection->__entryList.GetCount();
1178 }
1179
1180 void
1181 _RegistryCore::RemoveEntry(int sectionIndex, int entryIndex)
1182 {
1183         result r = E_SUCCESS;
1184         int listSize = 0;
1185         int entryListSize = 0;
1186         _RegistrySection* pRegSection = null;
1187
1188         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
1189         SysTryReturnVoidResult(NID_IO, sectionIndex >= 0, E_INVALID_ARG, "[E_INVALID_ARG] sectionIndex < 0.");
1190         SysTryReturnVoidResult(NID_IO, entryIndex >= 0, E_INVALID_ARG, "[E_INVALID_ARG] entryIndex < 0.");
1191
1192         listSize = _sectionList.GetCount();
1193         SysTryReturnVoidResult(NID_IO, listSize > 0, E_SECTION_NOT_FOUND,
1194                            "[E_SECTION_NOT_FOUND] section listSize <= 0.");
1195         SysTryReturnVoidResult(NID_IO, sectionIndex < listSize, E_SECTION_NOT_FOUND,
1196                            "[E_SECTION_NOT_FOUND] sectionIndex >= listSize.");
1197
1198         pRegSection = (_RegistrySection*) GetSectionByIndex(sectionIndex);
1199         SysTryReturnVoidResult(NID_IO, pRegSection != null, E_SECTION_NOT_FOUND,
1200                            "[E_SECTION_NOT_FOUND] Section at index (%d) not found.", sectionIndex);
1201
1202         r = GetLastResult();
1203         SysTryReturnVoidResult(NID_IO, !IsFailed(r), r,"[%s] Propagated.", GetErrorMessage(r));
1204
1205         entryListSize = pRegSection->__entryList.GetCount();
1206         SysTryReturnVoidResult(NID_IO, (entryListSize > 0 || entryIndex < entryListSize), E_KEY_NOT_FOUND,
1207                            "[E_KEY_NOT_FOUND] entryListSize is 0 or entryIndex >= entryListSize.");
1208
1209         r = pRegSection->__entryList.RemoveAt(entryIndex, true);
1210         SysTryReturnVoidResult(NID_IO, !IsFailed(r), r, "[%s] Propagated.", GetErrorMessage(r));
1211
1212         SetLastResult(E_SUCCESS);
1213 }
1214
1215 void
1216 _RegistryCore::ModifyEntryValue(int sectionIndex, int entryIndex, _RegValueType type, const void* pValue, int size)
1217 {
1218         SetLastResult(E_UNSUPPORTED_OPERATION);
1219 }
1220
1221 int
1222 _RegistryCore::GetEntryIndex(int sectionIndex, const String& entryName)
1223 {
1224         _RegistrySection* pRegSection = null;
1225         _RegistryEntry* pRegEntry = null;
1226         int listSize = 0;
1227         bool entryFound = false;
1228         int entryIndex = -1;
1229
1230         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
1231         SysTryReturn(NID_IO, sectionIndex >= 0, -1, E_INVALID_ARG, "[E_INVALID_ARG]sectionIndex < 0.");
1232         SysTryReturn(NID_IO, entryName.GetLength() > 0, -1, E_INVALID_ARG, "[E_INVALID_ARG]entryName length < 0.");
1233
1234         listSize = _sectionList.GetCount();
1235         SysTryReturn(NID_IO, listSize > 0, -1, E_SECTION_NOT_FOUND,
1236                            "[E_SECTION_NOT_FOUND]Registry section list is empty.");
1237         SysTryReturn(NID_IO, sectionIndex < listSize, -1, E_SECTION_NOT_FOUND,
1238                            "[E_SECTION_NOT_FOUND]sectionIndex >= listSize.");
1239
1240         pRegSection = (_RegistrySection*) GetSectionByIndex(sectionIndex);
1241         SysTryReturn(NID_IO, pRegSection != null, -1, E_SECTION_NOT_FOUND,
1242                            "[E_SECTION_NOT_FOUND] Section at index (%d) not found.", sectionIndex);
1243
1244         // read the entries for this section
1245         unique_ptr<IEnumerator> pEntryEnum(pRegSection->__entryList.GetEnumeratorN());
1246         SysTryReturn(NID_IO, pEntryEnum != null, -1, GetLastResult(), "[%s] Entry list is empty.",
1247                            GetErrorMessage(GetLastResult()));
1248
1249         entryIndex = 0;
1250         while (pEntryEnum->MoveNext() == E_SUCCESS)
1251         {
1252                 pRegEntry = dynamic_cast <_RegistryEntry*>(pEntryEnum->GetCurrent());
1253                 SysTryReturn(NID_IO, pRegEntry != null, -1, GetLastResult(), "[%s] Propagated.",
1254                                    GetErrorMessage(GetLastResult()));
1255
1256                 if (entryName == pRegEntry->entryName)
1257                 {
1258                         entryFound = true;
1259                         break;
1260                 }
1261                 entryIndex++;
1262         }
1263
1264         SysTryReturn(NID_IO, entryFound != false, -1, E_KEY_NOT_FOUND, "[E_KEY_NOT_FOUND] entry was not found.");
1265
1266         SetLastResult(E_SUCCESS);
1267         return entryIndex;
1268 }
1269
1270 String
1271 _RegistryCore::GetEntryName(int sectionIndex, int entryIndex)
1272 {
1273         _RegistrySection* pRegSection = null;
1274         _RegistryEntry* pRegEntry = null;
1275         int listSize = 0;
1276         int tmpIndex = -1;
1277         String empty;
1278
1279         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
1280         SysTryReturn(NID_IO, sectionIndex >= 0, empty, E_INVALID_ARG, "[E_INVALID_ARG]sectionIndex < 0.");
1281         SysTryReturn(NID_IO, entryIndex >= 0, empty, E_INVALID_ARG, "[E_INVALID_ARG]entryIndex < 0.");
1282
1283         listSize = _sectionList.GetCount();
1284         SysTryReturn(NID_IO, listSize > 0, empty, E_SECTION_NOT_FOUND,
1285                            "[E_SECTION_NOT_FOUND]Registry section list is empty.");
1286         SysTryReturn(NID_IO, sectionIndex < listSize, empty, E_SECTION_NOT_FOUND,
1287                            "[E_SECTION_NOT_FOUND]sectionIndex >= listSize.");
1288
1289         pRegSection = (_RegistrySection*) GetSectionByIndex(sectionIndex);
1290         SysTryReturn(NID_IO, pRegSection != null, empty, E_SECTION_NOT_FOUND,
1291                            "[E_SECTION_NOT_FOUND] Section at index (%d) not found.", sectionIndex);
1292
1293         // read the entries for this section
1294         unique_ptr<IEnumerator> pEntryEnum(pRegSection->__entryList.GetEnumeratorN());
1295         SysTryReturn(NID_IO, pEntryEnum != null, empty, GetLastResult(), "[%s] Entry list is empty.",
1296                         GetErrorMessage(GetLastResult()));
1297
1298         tmpIndex = entryIndex;
1299         while (pEntryEnum->MoveNext() == E_SUCCESS)
1300         {
1301                 if (tmpIndex == 0)
1302                 {
1303                         pRegEntry = dynamic_cast <_RegistryEntry*>(pEntryEnum->GetCurrent());
1304                         SysTryReturn(NID_IO, pRegEntry != null, empty, GetLastResult(), "[%s] Propagated.",
1305                                            GetErrorMessage(GetLastResult()));
1306
1307                         break;
1308                 }
1309                 tmpIndex--;
1310         }
1311
1312         SysTryReturn(NID_IO, pRegEntry != null, empty, E_KEY_NOT_FOUND, "[E_KEY_NOT_FOUND] entry was not found.");
1313
1314         SetLastResult(E_SUCCESS);
1315         return pRegEntry->entryName;
1316 }
1317
1318 void
1319 _RegistryCore::GetEntryValue(int sectionIndex, int entryIndex, _RegValueType type, void* pValue, int* pSize)
1320 {
1321         _RegistrySection* pRegSection = null;
1322         _RegistryEntry* pRegEntry = null;
1323         result r = E_SUCCESS;
1324         int listSize = 0;
1325         int tmpEntryIndex = -1;
1326         int entryListSize = 0;
1327         String strValueEncoded;
1328
1329         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
1330         SysTryReturnVoidResult(NID_IO, sectionIndex >= 0, E_INVALID_ARG, "[E_INVALID_ARG]sectionIndex < 0.");
1331         SysTryReturnVoidResult(NID_IO, type >= 0 && type <= REG_VALUE_TYPE_MAX, E_INVALID_ARG,
1332                            "[E_INVALID_ARG] invalid registry type.");
1333         SysTryReturnVoidResult(NID_IO, pValue != null, E_INVALID_ARG, "[E_INVALID_ARG]pValue is null.");
1334         SysTryReturnVoidResult(NID_IO, pSize != null, E_INVALID_ARG, "[E_INVALID_ARG]pSize is null.");
1335         SysTryReturnVoidResult(NID_IO, *pSize > 0, E_INVALID_ARG, "[E_INVALID_ARG] *pSize < 0.");
1336
1337         listSize = _sectionList.GetCount();
1338         SysTryReturnVoidResult(NID_IO, listSize > 0, E_SECTION_NOT_FOUND,
1339                            "[E_SECTION_NOT_FOUND]Registry section list is empty.");
1340         SysTryReturnVoidResult(NID_IO, sectionIndex < listSize, E_SECTION_NOT_FOUND,
1341                            "[E_SECTION_NOT_FOUND]sectionIndex >= listSize.");
1342
1343         pRegSection = (_RegistrySection*) GetSectionByIndex(sectionIndex);
1344         SysTryReturnVoidResult(NID_IO, pRegSection != null, E_SECTION_NOT_FOUND,
1345                            "[E_SECTION_NOT_FOUND] section at index (%d) is not available.", sectionIndex);
1346
1347         entryListSize = pRegSection->__entryList.GetCount();
1348         SysTryReturnVoidResult(NID_IO, entryListSize > 0, E_KEY_NOT_FOUND, "[E_KEY_NOT_FOUND]Entry list is empty.");
1349         SysTryReturnVoidResult(NID_IO, entryIndex < entryListSize, E_KEY_NOT_FOUND, "[E_KEY_NOT_FOUND]Entry not found.");
1350
1351         // read the entries for this section
1352         unique_ptr< IEnumerator > pEntryEnum(pRegSection->__entryList.GetEnumeratorN());
1353         SysTryReturnVoidResult(NID_IO, pEntryEnum != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND]Entry list is empty.");
1354
1355         tmpEntryIndex = entryIndex;
1356         while (pEntryEnum->MoveNext() == E_SUCCESS)
1357         {
1358                 if (entryIndex == 0)
1359                 {
1360                         pRegEntry = dynamic_cast <_RegistryEntry*>(pEntryEnum->GetCurrent());
1361                         SysTryReturnVoidResult(NID_IO, pRegEntry != null, GetLastResult(), "[%s] Propagated.",
1362                                            GetErrorMessage(GetLastResult()));
1363
1364                         break;
1365                 }
1366                 entryIndex--;
1367
1368         }
1369
1370         SysTryReturnVoidResult(NID_IO, pRegEntry != null, E_KEY_NOT_FOUND,
1371                            "[E_KEY_NOT_FOUND] Entry was not found.");
1372
1373         strValueEncoded = pRegEntry->entryValue;
1374
1375         DecodeData(strValueEncoded, type, pValue, pSize);
1376         r = GetLastResult();
1377         SysTryReturnVoidResult(NID_IO, !IsFailed(r), E_PARSING_FAILED, "[%s] Propagated.", GetErrorMessage(r));
1378
1379         SetLastResult(E_SUCCESS);
1380         return;
1381 }
1382
1383 String
1384 _RegistryCore::GetSectionName(int sectionIndex)
1385 {
1386         _RegistrySection* pRegSection = null;
1387         result r = E_SUCCESS;
1388         int listSize = 0;
1389         String sectionName("");
1390
1391         SysAssertf(_constructed == true, "Not yet constructed. Construct() should be called before use.\n");
1392         SysTryReturn(NID_IO, sectionIndex >= 0, sectionName, E_INVALID_ARG, "[E_INVALID_ARG]sectionIndex < 0.");
1393
1394         listSize = _sectionList.GetCount();
1395         SysTryReturn(NID_IO, listSize > 0, sectionName, E_SECTION_NOT_FOUND,
1396                            "[E_SECTION_NOT_FOUND]Registry section list is empty.");
1397         SysTryReturn(NID_IO, sectionIndex < listSize, sectionName, E_SECTION_NOT_FOUND,
1398                            "[E_SECTION_NOT_FOUND]sectionIndex >= listSize.");
1399
1400         pRegSection = (_RegistrySection*) GetSectionByIndex(sectionIndex);
1401         SysTryReturn(NID_IO, pRegSection != null, sectionName, E_SECTION_NOT_FOUND,
1402                            "[E_SECTION_NOT_FOUND] sectionIndex is not available.");
1403
1404         r = GetLastResult();
1405         SysTryReturn(NID_IO, !IsFailed(r), sectionName, r, "[%s] Propagated.", GetErrorMessage(r));
1406
1407         SetLastResult(E_SUCCESS);
1408         return pRegSection->__sectionName;
1409 }
1410
1411 void*
1412 _RegistryCore::GetSectionByIndex(int sectionIndex)
1413 {
1414         _RegistrySection* pRegSection = null;
1415         int index = sectionIndex;
1416
1417         // Get section information
1418         unique_ptr<IEnumerator> pEnum(_sectionList.GetEnumeratorN());
1419         SysTryReturn(NID_IO, pEnum != null, null, GetLastResult(),
1420                            "[%s] section list is empty.", GetErrorMessage(GetLastResult()));
1421
1422         while (pEnum->MoveNext() == E_SUCCESS)
1423         {
1424                 if (index == 0)
1425                 {
1426                         pRegSection = dynamic_cast< _RegistrySection* >(pEnum->GetCurrent());
1427                         SysTryReturn(NID_IO, pRegSection != null, null, GetLastResult(), "[%s] Propagated.",
1428                                            GetErrorMessage(GetLastResult()));
1429                         break;
1430                 }
1431                 index--;
1432
1433         }
1434
1435         SysTryReturn(NID_IO, pRegSection != null, null, E_SECTION_NOT_FOUND,
1436                            "[E_SECTION_NOT_FOUND] Section was not found.");
1437
1438         SetLastResult(E_SUCCESS);
1439
1440         return pRegSection;
1441 }
1442
1443 void
1444 _RegistryCore::DecodeData(const String& strValueEncoded, _RegValueType type, void* pValue, int* pSize)
1445 {
1446         SysAssert(strValueEncoded.GetLength() > 0);
1447         SysAssert(pValue);
1448         SysAssert(pSize);
1449         SysAssert(pSize && *pSize > 0);
1450
1451         SysTryReturnVoidResult(NID_IO, pValue != null, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument.");
1452         SysTryReturnVoidResult(NID_IO, pSize != null, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument.");
1453
1454         switch (type)
1455         {
1456         case REG_VALUE_TYPE_INT: // (-2147483647 - 1) ~ 2147483647
1457         {
1458                 int retIntVal = 0;
1459                 result r = E_SUCCESS;
1460
1461                 if (*pSize != sizeof(int))
1462                 {
1463                         SetLastResult(E_INVALID_ARG);
1464                         return;
1465                 }
1466
1467                 r = Integer::Parse(strValueEncoded, retIntVal);
1468                 SysTryReturnVoidResult(NID_IO, !IsFailed(r), E_PARSING_FAILED, "[%s] Propagated.", GetErrorMessage(r));
1469
1470                 *(int*) pValue = retIntVal;
1471                 break;
1472         }
1473
1474         case REG_VALUE_TYPE_REAL:  // Holds signed IEEE 64-bit (8-byte) double-precision floating-point numbers
1475                                         // ranging in value from -1.79769313486231570E+308 through -4.94065645841246544E-324
1476                                         // for negative values and from 4.94065645841246544E-324 through 1.79769313486231570E+308
1477                                         // for positive values.
1478         {
1479                 double retDoubleVal = 0;
1480                 result r = E_SUCCESS;
1481
1482                 if (*pSize != sizeof(double))
1483                 {
1484                         SetLastResult(E_INVALID_ARG);
1485                         return;
1486                 }
1487
1488                 r = Double::Parse(strValueEncoded, retDoubleVal);
1489                 SysTryReturnVoidResult(NID_IO, !IsFailed(r), E_PARSING_FAILED, "[%s] Propagated.", GetErrorMessage(r));
1490
1491                 *(double*) pValue = retDoubleVal;
1492                 break;
1493         }
1494
1495         case REG_VALUE_TYPE_STRING:
1496         {
1497 //              if(*pSize != sizeof(String))
1498 //              {
1499 //                      SetLastResult(E_INVALID_ARG);
1500 //                      return;
1501 //              }
1502                 *(String*) pValue = strValueEncoded;
1503                 break;
1504         }
1505
1506         case REG_VALUE_TYPE_BINARY:
1507         {
1508                 SetLastResult(E_PARSING_FAILED);
1509                 return;
1510         }
1511
1512         case REG_VALUE_TYPE_UUID:
1513         {
1514                 UuId retUuIdVal;
1515                 result r = E_SUCCESS;
1516
1517                 r = UuId::Parse(strValueEncoded, retUuIdVal);
1518                 SysTryReturnVoidResult(NID_IO, !IsFailed(r), E_PARSING_FAILED, "[%s] Propagated.", GetErrorMessage(r));
1519
1520                 *(UuId*) pValue = retUuIdVal;
1521                 break;
1522         }
1523
1524         case REG_VALUE_TYPE_UUIDSET:
1525         {
1526                 SetLastResult(E_PARSING_FAILED);
1527                 return;
1528         }
1529
1530         default:
1531                 SysAssert(0); // should not happen!
1532                 return;
1533         }
1534
1535         SetLastResult(E_SUCCESS);
1536         return;
1537 }
1538
1539 result
1540 _RegistryCore::AddSection(LinkedList& sectionList, const String& sectionName)
1541 {
1542         result r = E_SUCCESS;
1543         bool sectionFound = false;
1544
1545         // Get section information
1546         unique_ptr<IEnumerator> pEnum(sectionList.GetEnumeratorN());
1547         if (pEnum == null)
1548         {
1549                 return GetLastResult();
1550         }
1551
1552         while (pEnum->MoveNext() == E_SUCCESS)
1553         {
1554                 _RegistrySection* pRegSection = dynamic_cast <_RegistrySection*>(pEnum->GetCurrent());
1555                 SysTryReturn(NID_IO, pRegSection != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
1556                                    GetErrorMessage(GetLastResult()));
1557
1558                 if (pRegSection->__sectionName == sectionName)
1559                 {
1560                         sectionFound = true;
1561                         break;
1562                 }
1563         }
1564
1565         if (sectionFound == true)
1566         {
1567                 return E_SECTION_ALREADY_EXIST;
1568         }
1569
1570         // create a key with section name
1571         unique_ptr<_RegistrySection> pRegSection(new (std::nothrow) _RegistrySection());
1572
1573         SysTryReturnResult(NID_IO, pRegSection != null, E_OUT_OF_MEMORY,
1574                            "The memory is insufficient.");
1575
1576         pRegSection->__sectionName = sectionName;
1577
1578         // add new section and section-entry map
1579         r = sectionList.Add(*(pRegSection.release()));
1580         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
1581
1582         return E_SUCCESS;
1583 }
1584
1585 result
1586 _RegistryCore::AddValue(LinkedList& sectionList, const String& sectionName, const String& entryName, const String& valStr)
1587 {
1588         result r = E_SUCCESS;
1589         bool sectionFound = false;
1590         bool entryFound = false;
1591         _RegistrySection* pRegSection = null;
1592
1593         // Get section information
1594         unique_ptr<IEnumerator> pEnum(sectionList.GetEnumeratorN());
1595         if (pEnum == null)
1596         {
1597                 return GetLastResult();
1598         }
1599
1600         while (pEnum->MoveNext() == E_SUCCESS)
1601         {
1602                 pRegSection = dynamic_cast <_RegistrySection*>(pEnum->GetCurrent());
1603                 SysTryReturn(NID_IO, pRegSection != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
1604                                    GetErrorMessage(GetLastResult()));
1605
1606                 if (pRegSection->__sectionName == sectionName)
1607                 {
1608                         sectionFound = true;
1609                         break;
1610                 }
1611         }
1612
1613         if (sectionFound == false)
1614         {
1615                 return E_SECTION_NOT_FOUND;
1616         }
1617
1618         pEnum.reset(pRegSection->__entryList.GetEnumeratorN());
1619         if (pEnum == null)
1620         {
1621                 return GetLastResult();
1622         }
1623
1624         while (pEnum->MoveNext() == E_SUCCESS)
1625         {
1626                 _RegistryEntry* pRegEntry = dynamic_cast <_RegistryEntry*>(pEnum->GetCurrent());
1627                 SysTryReturn(NID_IO, pRegEntry != null, GetLastResult(), GetLastResult(), "[%s] Propagated.",
1628                                    GetErrorMessage(GetLastResult()));
1629
1630                 if (pRegEntry->entryName == entryName)
1631                 {
1632                         entryFound = true;
1633                         break;
1634                 }
1635         }
1636
1637         if (entryFound == true)
1638         {
1639                 return E_KEY_ALREADY_EXIST;
1640         }
1641
1642         unique_ptr<_RegistryEntry> pRegEntry(new (std::nothrow) _RegistryEntry());
1643         SysTryReturnResult(NID_IO, pRegEntry != null, E_OUT_OF_MEMORY,
1644                         "The memory is insufficient.");
1645
1646         pRegEntry->entryName = entryName;
1647         pRegEntry->entryValue = valStr;
1648
1649         r = pRegSection->__entryList.Add(*(pRegEntry.release()));
1650         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
1651
1652         return E_SUCCESS;
1653 }
1654
1655 bool
1656 _RegistryCore::CheckSectionName(char* pSectionName)
1657 {
1658         char* pTemp = null;
1659         int length = 0;
1660         char* pFrom = null;
1661         char* pTo = null;
1662
1663         if (pSectionName == null)
1664         {
1665                 return false;
1666         }
1667
1668         pFrom = pSectionName;
1669         length = strlen(pSectionName);
1670         pTo = pSectionName + (length - 1);
1671
1672         if (!pFrom || !pTo || pFrom > pTo)
1673         {
1674                 return false;
1675         }
1676
1677         for (pTemp = pFrom; pTemp <= pTo; pTemp++)
1678         {
1679                 if (*pTemp == '\0' || *pTemp == '\n' || *pTemp == '#' || *pTemp == '=')
1680                 {
1681                         return false;
1682                 }
1683         }
1684
1685         return true;
1686 }
1687
1688 bool
1689 _RegistryCore::CheckEntryName(char* pEntryName)
1690 {
1691         char* pTemp = null;
1692         int length = 0;
1693         char* pFrom = null;
1694         char* pTo = null;
1695
1696         if (pEntryName == null)
1697         {
1698                 return false;
1699         }
1700
1701         pFrom = pEntryName;
1702         length = strlen(pEntryName);
1703         pTo = pEntryName + (length - 1);
1704
1705         if (!pFrom || !pTo || pFrom > pTo)
1706         {
1707                 return false;
1708         }
1709
1710         for (pTemp = pFrom; pTemp <= pTo; pTemp++)
1711         {
1712                 if (*pTemp == '\0' || *pTemp == '\n' || *pTemp == '#' || *pTemp == '=')
1713                 {
1714                         return false;
1715                 }
1716         }
1717
1718         return true;
1719 }
1720
1721 bool
1722 _RegistryCore::CheckEntryValue(char* pEntryVal)
1723 {
1724         char* pTemp = null;
1725         int length = 0;
1726         char* pFrom = null;
1727         char* pTo = null;
1728
1729         if (pEntryVal == null)
1730         {
1731                 return false;
1732         }
1733
1734         pFrom = pEntryVal;
1735         length = strlen(pEntryVal);
1736         pTo = pEntryVal + (length - 1);
1737
1738         if (!pFrom || !pTo || pFrom > pTo)
1739         {
1740                 return false;
1741         }
1742
1743         for (pTemp = pFrom; pTemp <= pTo; pTemp++)
1744         {
1745                 if (*pTemp == '\0' || *pTemp == '\n')
1746                 {
1747                         return false;
1748                 }
1749         }
1750
1751         return true;
1752 }
1753
1754 result
1755 _RegistryCore::ConvertToSecureRegistry(const String& plainRegPath, const String& secureRegPath, const ByteBuffer* pKey)
1756 {
1757         result  r = E_SUCCESS;
1758
1759         if (File::IsFileExist(secureRegPath))
1760         {
1761                 r = GetLastResult();
1762                 if (r == E_SUCCESS)
1763                 {
1764                         r = E_FILE_ALREADY_EXIST;
1765                         SysLog(NID_IO, "[E_FILE_ALREADY_EXIST] The secure registry already exists.");
1766                 }
1767                 else
1768                 {
1769                         SysLog(NID_IO, "[%s]Propagated.", GetErrorMessage(r));
1770                 }
1771                 return r;
1772         }
1773
1774         unique_ptr<_NormalRegistry> pNormalReg(new (std::nothrow) _NormalRegistry());
1775         SysTryReturnResult(NID_IO, pNormalReg != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
1776
1777         r = pNormalReg->Load(plainRegPath, "r");
1778         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
1779
1780         unique_ptr<_SecureRegistry> pSecureReg(new (std::nothrow) _SecureRegistry());
1781         SysTryReturnResult(NID_IO, pSecureReg != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
1782
1783         r = pSecureReg->Construct(secureRegPath, "w+", pKey);
1784         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
1785
1786         if (pNormalReg->_pBuffer != null && pNormalReg->_length > 0)
1787         {
1788                 pSecureReg->_pBuffer = pNormalReg->_pBuffer;
1789                 pSecureReg->_length = pNormalReg->_length;
1790
1791                 pNormalReg->_pBuffer = null;
1792                 pNormalReg->_length = 0;
1793
1794                 r = pSecureReg->Parse();
1795                 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
1796         }
1797
1798         r = pSecureReg->Flush();
1799         SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
1800
1801         return E_SUCCESS;
1802 }
1803
1804 FileLock*
1805 _RegistryCore::LockN(FileLockType lockType)
1806 {
1807         SysAssertf(_constructed == true && __pFileImpl != null, "Not yet constructed. Construct() should be called before use.\n");
1808         return __pFileImpl->LockN(lockType);
1809 }
1810
1811 FileLock*
1812 _RegistryCore::TryToLockN(FileLockType lockType)
1813 {
1814         SysAssertf(_constructed == true && __pFileImpl != null, "Not yet constructed. Construct() should be called before use.\n");
1815         return __pFileImpl->TryToLockN(lockType);
1816 }
1817
1818 }} // Tizen::Io
1819