Re-organized sub-directory by category
[staging/basesystem.git] / service / native / framework_unified / client / NS_ConfigParser / src / ns_cfg_parser.cpp
1 /*
2  * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
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 /// \ingroup  tag_NS_ConfigParser
19 /// \brief    This file contains implementation of CCFGParser class.
20 ///
21 ////////////////////////////////////////////////////////////////////////////////////////////////////
22
23 ////////////////////////////////////////////////////////////////////////////////////////////////////
24 // Include Files
25 ////////////////////////////////////////////////////////////////////////////////////////////////////
26
27 #include <ns_cfg_internal.h>
28 #include <ns_cfg_parser.h>
29 #include <ns_config_parser_frameworkunifiedlog.h>
30
31 #include <fstream>
32 #include <string>
33
34 CCFGParser::CCFGParser()
35   : m_pmCFGData(NULL) {
36 }
37
38 // LCOV_EXCL_START 200:CCFGParser is not external API class, this constructed function isn't used by other function
39 CCFGParser::CCFGParser(const std::string &f_cfilepath)
40   : m_pmCFGData(NULL) {
41   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
42   CFGParseFile(f_cfilepath);
43 }
44 // LCOV_EXCL_STOP
45
46 CCFGParser::~CCFGParser() {
47   CFGData_Type::iterator l_itCfgStructure;
48
49   if (NULL != m_pmCFGData) {  // LCOV_EXCL_BR_LINE 5:m_pmCFGData cannot be NULL, because internal logic guarantee
50     // release the structure
51     for (l_itCfgStructure = m_pmCFGData->begin();
52          l_itCfgStructure != m_pmCFGData->end();
53          l_itCfgStructure++) {
54       CBlock *l_pBlock = (*l_itCfgStructure).second;
55       if (NULL != l_pBlock) {  // LCOV_EXCL_BR_LINE 5:l_pBlock cannot be NULL, because map insert data success.
56         // clear the vector
57         l_pBlock->m_vElementPair.clear();
58
59         delete l_pBlock;  // LCOV_EXCL_BR_LINE 11:except branch
60         l_pBlock = NULL;
61       }
62     }
63
64     delete m_pmCFGData;  // LCOV_EXCL_BR_LINE 11:except branch
65     m_pmCFGData = NULL;
66   }
67 }
68
69 EFrameworkunifiedStatus CCFGParser::CFGParseFile(const std::string &f_cfilepath) {
70   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
71
72   size_t l_uiPos = 0;
73   std::string l_cLine("");
74   std::string l_cTag("");  // LCOV_EXCL_BR_LINE 11:except branch
75   std::string l_cComment("");  // LCOV_EXCL_BR_LINE 11:except branch
76
77   m_pmCFGData = new(std::nothrow) CFGData_Type();  // LCOV_EXCL_BR_LINE 11:except branch
78
79   if (NULL != m_pmCFGData) {  // LCOV_EXCL_BR_LINE 5:new's error case
80     // open the file
81     std::ifstream l_objFile(f_cfilepath.c_str());  // LCOV_EXCL_BR_LINE 11:except branch
82
83     // check if file is opened
84     if (l_objFile.is_open()) {
85       CBlock *l_pBlock = NULL;
86
87       // read until end of file is not reached or any other stream error occurred
88       while (!l_objFile.eof()) {
89         // read the line from the file
90         getline(l_objFile, l_cLine);  // LCOV_EXCL_BR_LINE 11:except branch
91
92         // if line is a comment
93         if ('#' == l_cLine[0] || ';' == l_cLine[0]) {
94           if (!l_cComment.empty()) {
95             l_cComment.append("\n");  // LCOV_EXCL_BR_LINE 11:except branch
96           }
97           l_cComment.append(l_cLine);
98         } else if ('[' == l_cLine[0]) {  // if line is main tag
99           // creates new CBlock object,
100           // each block contains information of single like all its key-value pair and
101           // all the comments associated with it.
102           l_pBlock = new CBlock();  // LCOV_EXCL_BR_LINE 11:except branch
103           if (NULL != l_pBlock) {  // LCOV_EXCL_BR_LINE 5:new's error case
104             // set the tag comment
105             l_pBlock->m_cComment = l_cComment;
106             l_cComment.clear();
107
108             if (std::string::npos != (l_uiPos = l_cLine.find(']'))) {
109               // set the tag
110               l_cTag = l_cLine.substr(1, l_uiPos - 1);  // LCOV_EXCL_BR_LINE 11:except branch
111
112               // insert the block with its tag name in structure(map)
113               m_pmCFGData->insert(make_pair(l_cTag, l_pBlock));  // NOLINT (readability/nolint)
114             } else {
115               delete l_pBlock;  // LCOV_EXCL_BR_LINE 11:except branch
116               l_pBlock = NULL;
117
118               // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h"
119               FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "End Tag missing");
120               // LCOV_EXCL_BR_STOP
121               l_eStatus = eFrameworkunifiedStatusErrOther;
122               break;
123             }
124           } else {
125             // LCOV_EXCL_START 5:new's error case
126             AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
127             FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Error allocating memory for l_pBlock");
128             l_eStatus = eFrameworkunifiedStatusNullPointer;
129             break;
130             // LCOV_EXCL_STOP
131           }
132         } else if (std::string::npos != (l_uiPos = l_cLine.find('='))) {  // LCOV_EXCL_BR_LINE 11:except branch
133           if (NULL != l_pBlock) {  // LCOV_EXCL_BR_LINE 5:new's error case
134             // create new node object,
135             // each node object contains the information of singlr key-value pair and
136             /// it's comment(if any)
137             // LCOV_EXCL_BR_START 11:except branch
138             CNode l_objNode;
139             l_objNode.m_cComment.append(l_cComment);
140             l_objNode.m_cTag = l_cLine.substr(0, l_uiPos);
141             l_objNode.m_cValue = l_cLine.substr(l_uiPos + 1);
142
143             // insert the node object in block
144             l_pBlock->m_vElementPair.push_back(l_objNode);
145             // LCOV_EXCL_BR_STOP
146
147             l_cComment.clear();
148           } else {
149             // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h"
150             FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "l_pBlock is NULL");
151             // LCOV_EXCL_BR_STOP
152             l_eStatus = eFrameworkunifiedStatusNullPointer;
153             break;
154           }
155         }
156       }
157
158       // last comment
159       if (!l_cComment.empty()) {
160         m_cLastComment = l_cComment;
161       } else {
162         m_cLastComment.clear();
163       }
164
165       // close the file
166       l_objFile.close();  // LCOV_EXCL_BR_LINE 11:except branch
167     } else {
168       l_eStatus = eFrameworkunifiedStatusFail;
169       // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h"
170       FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Error Opening File");
171       // LCOV_EXCL_BR_STOP
172     }
173   } else {
174     // LCOV_EXCL_START 5:new's error case
175     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
176     FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "m_pmCFGData is NULL");
177     l_eStatus = eFrameworkunifiedStatusNullPointer;
178     // LCOV_EXCL_STOP
179   }
180
181   return l_eStatus;
182 }
183
184 std::string CCFGParser::CFGGetData(const std::string &f_ckey) {
185   CFGData_Type::iterator l_itCfgStructure;
186   std::string l_cHeadTag = "";
187   std::string l_cTag = "";  // LCOV_EXCL_BR_LINE 11:except branch
188   std::string l_cValue = "";  // LCOV_EXCL_BR_LINE 11:except branch
189
190   size_t l_uiPos = 0;
191
192   if (NULL != m_pmCFGData && !f_ckey.empty()) {  // LCOV_EXCL_BR_LINE 5:new's error case(in function CFGParseFile)
193     if (std::string::npos != (l_uiPos = f_ckey.find('.'))) {  // LCOV_EXCL_BR_LINE 11:except branch
194       l_cHeadTag = f_ckey.substr(0, l_uiPos);  // LCOV_EXCL_BR_LINE 11:except branch
195       l_cTag = f_ckey.substr(l_uiPos + 1);  // LCOV_EXCL_BR_LINE 11:except branch
196     }
197
198     // search for the key and its associated value in internal structure
199     for (l_itCfgStructure = m_pmCFGData->begin();
200          l_itCfgStructure != m_pmCFGData->end();
201          l_itCfgStructure++) {
202       CBlock *l_pBlock = (*l_itCfgStructure).second;
203
204       if (!l_cHeadTag.compare((*l_itCfgStructure).first) && NULL != l_pBlock) {
205         for (UI_32 l_uiCount = 0; l_uiCount < l_pBlock->m_vElementPair.size(); l_uiCount++) {
206           if (!l_cTag.compare(l_pBlock->m_vElementPair[l_uiCount].m_cTag)) {
207             // LCOV_EXCL_BR_START 200:After l_cValue assignment is empty,there is no other place to assignment the value
208             if (!l_cValue.empty()) {
209             // LCOV_EXCL_BR_STOP
210               // LCOV_EXCL_START 200:After l_cValue assignment is empty,there is no other place to assignment the value
211               AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
212               l_cValue.append("\n");
213               // LCOV_EXCL_STOP 200
214             }
215             l_cValue.append(l_pBlock->m_vElementPair[l_uiCount].m_cValue);
216           }
217         }
218       }
219     }
220   }
221
222   return l_cValue;
223 }
224
225 EFrameworkunifiedStatus CCFGParser::CFGGetData(const std::string &f_ckey, std::string &f_cvalue) {
226   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusFail;
227
228   CFGData_Type::iterator l_itCfgStructure;
229   std::string l_cHeadTag = "";
230   std::string l_cTag = "";  // LCOV_EXCL_BR_LINE 11:except branch
231   std::string l_cValue = "";  // LCOV_EXCL_BR_LINE 11:except branch
232
233   size_t l_uiPos = 0;
234
235   if (NULL != m_pmCFGData && !f_ckey.empty()) {  // LCOV_EXCL_BR_LINE 5:new's error case(in function CFGParseFile)
236     if (std::string::npos != (l_uiPos = f_ckey.find('.'))) {  // LCOV_EXCL_BR_LINE 11:except branch
237       l_cHeadTag = f_ckey.substr(0, l_uiPos);  // LCOV_EXCL_BR_LINE 11:except branch
238       l_cTag = f_ckey.substr(l_uiPos + 1);  // LCOV_EXCL_BR_LINE 11:except branch
239     }
240
241     // search for the key and its associated value in internal structure
242     for (l_itCfgStructure = m_pmCFGData->begin();
243          l_itCfgStructure != m_pmCFGData->end();
244          l_itCfgStructure++) {
245       CBlock *l_pBlock = (*l_itCfgStructure).second;
246
247       if (!l_cHeadTag.compare((*l_itCfgStructure).first) && NULL != l_pBlock) {
248         for (UI_32 l_uiCount = 0; l_uiCount < l_pBlock->m_vElementPair.size(); l_uiCount++) {
249           if (!l_cTag.compare(l_pBlock->m_vElementPair[l_uiCount].m_cTag)) {
250             if (!f_cvalue.empty()) {
251               f_cvalue.append("\n");
252             }
253             f_cvalue.append(l_pBlock->m_vElementPair[l_uiCount].m_cValue);
254
255             l_eStatus = eFrameworkunifiedStatusOK;
256           }
257         }
258       }
259     }
260   }
261
262   return l_eStatus;
263 }
264
265 EFrameworkunifiedStatus CCFGParser::CFGSetData(const std::string &f_cKey, std::string f_cvalue) {
266   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusFail;
267
268   CFGData_Type::iterator l_itCfgStructure;
269   std::string l_cHeadTag = "";
270   std::string l_cTag = "";  // LCOV_EXCL_BR_LINE 11:except branch
271   std::string l_cValue = "";  // LCOV_EXCL_BR_LINE 11:except branch
272   size_t l_uiPos = 0;
273
274   // LCOV_EXCL_BR_START 6:f_cKey is not NULL, because checked in CCFGWriter::SetValue
275   if (NULL != m_pmCFGData && !f_cKey.empty()) {
276   // LCOV_EXCL_BR_STOP
277     if (std::string::npos != (l_uiPos = f_cKey.find('.'))) {  // LCOV_EXCL_BR_LINE 11:except branch
278       l_cHeadTag = f_cKey.substr(0, l_uiPos);  // LCOV_EXCL_BR_LINE 11:except branch
279       l_cTag = f_cKey.substr(l_uiPos + 1);  // LCOV_EXCL_BR_LINE 11:except branch
280     }
281
282     // search for the key in internal structure and set the data for it
283     for (l_itCfgStructure = m_pmCFGData->begin();
284          l_itCfgStructure != m_pmCFGData->end();
285          l_itCfgStructure++) {
286       CBlock *l_pBlock = (*l_itCfgStructure).second;
287
288       if (!l_cHeadTag.compare((*l_itCfgStructure).first) && NULL != l_pBlock) {
289         for (UI_32 l_uiCount = 0; l_uiCount < l_pBlock->m_vElementPair.size(); l_uiCount++) {
290           if (!l_cTag.compare(l_pBlock->m_vElementPair[l_uiCount].m_cTag)) {
291             l_pBlock->m_vElementPair[l_uiCount].m_cValue.assign(f_cvalue);
292             l_eStatus = eFrameworkunifiedStatusOK;
293           }
294         }
295       }
296     }
297   } else {
298     // LCOV_EXCL_START 6:f_cKey is not NULL, because checked in CCFGWriter::SetValue
299     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
300     l_eStatus = eFrameworkunifiedStatusNullPointer;
301     FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "m_pmCFGData is NULL");
302     //  LCOV_EXCL_STOP
303   }
304
305   return l_eStatus;
306 }
307
308 EFrameworkunifiedStatus CCFGParser::CFGSaveData(const std::string &f_cfilepath) {
309   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
310
311   CFGData_Type::iterator l_itCfgStructure;
312
313   if (NULL != m_pmCFGData) {  // LCOV_EXCL_BR_LINE 5:m_pmCFGData cannot be NULL, because internal logic guarantee
314     std::ofstream l_objFile(f_cfilepath.c_str());
315
316     // check if file is open
317     if (l_objFile.is_open()) {
318       // write the updated CFG structure back to the file
319       for (l_itCfgStructure = m_pmCFGData->begin();
320            l_itCfgStructure != m_pmCFGData->end();
321            l_itCfgStructure++) {
322         CBlock *l_pBlock = (*l_itCfgStructure).second;
323         if (NULL != l_pBlock) {  // LCOV_EXCL_BR_LINE 11:except branch
324           // write the main tag comment in file
325           if (!l_pBlock->m_cComment.empty()) {
326             l_objFile << l_pBlock->m_cComment << std::endl;
327           }
328
329           // write main tag to file
330           l_objFile << "[" << (*l_itCfgStructure).first << "]" << std::endl;
331
332           for (UI_32 l_uiCount = 0; l_uiCount < l_pBlock->m_vElementPair.size(); l_uiCount++) {
333             // comment over the key-value pair
334             if (!l_pBlock->m_vElementPair[l_uiCount].m_cComment.empty()) {
335               l_objFile << l_pBlock->m_vElementPair[l_uiCount].m_cComment << std::endl;;
336             }
337
338             // key-value
339             l_objFile << l_pBlock->m_vElementPair[l_uiCount].m_cTag << "="
340                       << l_pBlock->m_vElementPair[l_uiCount].m_cValue << std::endl;
341           }
342         }
343       }
344
345       // last comment
346       if (!m_cLastComment.empty()) {
347         l_objFile << m_cLastComment << std::endl;
348       }
349
350       // close the file
351       l_objFile.close();  // LCOV_EXCL_BR_LINE 11:except branch
352     } else {
353       l_eStatus = eFrameworkunifiedStatusFail;
354       FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Cannot Open File");
355     }
356   } else {
357     // LCOV_EXCL_START 5:m_pmCFGData cannot be NULL, because internal logic guarantee
358     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
359     l_eStatus = eFrameworkunifiedStatusNullPointer;
360     FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "m_pmCFGData is NULL");
361     // LCOV_EXCL_STOP
362   }
363
364   return l_eStatus;
365 }