common_library: gettid is multiple declaration in cl_error
[staging/basesystem.git] / video_in_hal / nsframework / framework_unified / client / NS_XMLConfigeParser / library / src / ns_xml_writer.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 CXMLWriter class.
20 ///
21 ////////////////////////////////////////////////////////////////////////////////////////////////////
22
23 ////////////////////////////////////////////////////////////////////////////////////////////////////
24 // Include Files
25 ////////////////////////////////////////////////////////////////////////////////////////////////////
26 #include <native_service/ns_xml_writer.h>
27 #include <string>
28 #include "ns_xmlconfig_parser_frameworkunifiedlog.h"
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 CXMLWriter *GetCXMLWriterObject(CHAR *f_cfilepath) {
35   CXMLWriter *l_p_xml_writer = NULL;
36   if (NULL != f_cfilepath) {
37     l_p_xml_writer = new(std::nothrow) CXMLWriter(f_cfilepath);  // LCOV_EXCL_BR_LINE 11: except branch
38   }
39   return l_p_xml_writer;
40 }
41
42 CXMLWriter *GetCXMLWriterObjectNoParam() {
43   return (new(std::nothrow) CXMLWriter());  // LCOV_EXCL_BR_LINE 11: except branch
44 }
45
46 #ifdef __cplusplus
47 }
48 #endif
49
50 CXMLWriter::CXMLWriter(): m_pXmlDoc(NULL), m_cFilePath("") {
51   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
52 }
53
54 CXMLWriter::CXMLWriter(const std::string &f_cFilePath): m_pXmlDoc(NULL), m_cFilePath(f_cFilePath) {
55   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "File Path %s", f_cFilePath.c_str());
56
57   // create document object structure
58   m_pXmlDoc = xmlParseFile(m_cFilePath.c_str());  // LCOV_EXCL_BR_LINE 11: except branch
59
60   if (!m_pXmlDoc) {
61     FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Pointer to document structure is NULL");
62   }
63 }
64
65 CXMLWriter::~CXMLWriter() {
66   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "Destructor");
67
68   if (NULL != m_pXmlDoc) {
69     xmlFreeDoc(m_pXmlDoc);  // LCOV_EXCL_BR_LINE 11: except branch
70     m_pXmlDoc = NULL;
71   }
72 }
73
74 EFrameworkunifiedStatus CXMLWriter::ParseFile(const std::string &f_cFilePath) {
75   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
76   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
77
78   l_eStatus = SetPath(f_cFilePath);
79
80   if (NULL != m_pXmlDoc) {
81     xmlFreeDoc(m_pXmlDoc);
82     m_pXmlDoc = NULL;
83   }
84
85   // create document object structure
86   m_pXmlDoc = xmlParseFile(f_cFilePath.c_str());
87
88   if (NULL == m_pXmlDoc) {
89     FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Pointer to document structure is NULL");
90     l_eStatus = eFrameworkunifiedStatusNullPointer;
91   }
92
93   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
94   return l_eStatus;
95 }
96
97 EFrameworkunifiedStatus CXMLWriter::SetPath(const std::string &f_cPath) {
98   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
99
100   if (!f_cPath.empty()) {
101     // set the file path
102     m_cFilePath.assign(f_cPath);
103   } else {
104     l_eStatus = eFrameworkunifiedStatusInvldParam;
105   }
106
107   return l_eStatus;
108 }
109
110 VOID CXMLWriter::SetDataPtr(PVOID f_pData) {
111   m_pXmlDoc = NULL;
112   if (NULL != f_pData) {
113     // set the doc pointer
114     m_pXmlDoc = static_cast<xmlDocPtr>(f_pData);
115   } else {
116     FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Data Pointer not set in xml writer");  // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
117   }
118 }
119
120 EFrameworkunifiedStatus CXMLWriter::SetValue(const std::string &f_cKey, std::string f_cValue) {
121   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "Key %s", f_cKey.c_str());
122   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
123
124   if (NULL != m_pXmlDoc && (!f_cKey.empty())) {
125     std::string l_cUserKey = "";
126     l_cUserKey.assign(f_cKey);
127
128     // get the root node element
129     xmlNodePtr l_pCurrNode = xmlDocGetRootElement(m_pXmlDoc);
130
131     if (NULL != l_pCurrNode) {
132       // remove the root node name from key
133       size_t l_uiLength = l_cUserKey.find('.');  // LCOV_EXCL_BR_LINE 11: except branch
134
135       if (std::string::npos != l_uiLength) {
136         l_cUserKey = l_cUserKey.substr(l_uiLength + 1);  // LCOV_EXCL_BR_LINE 11: except branch
137
138         // if root node name matches with the name in received key
139         if (!(f_cKey.substr(0, l_uiLength)).compare((PCSTR)l_pCurrNode->name)) {
140           BOOL l_bKeyFound = FALSE;
141           l_eStatus = XMLSetValue(l_pCurrNode, l_cUserKey, f_cValue, l_bKeyFound);
142
143           if (!l_bKeyFound) {
144             l_eStatus = eFrameworkunifiedStatusFail;
145           }
146         }
147       } else {
148         l_eStatus = eFrameworkunifiedStatusInvldParam;
149       }
150     } else {
151       l_eStatus = eFrameworkunifiedStatusNullPointer;
152     }
153   } else {
154     FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Document structure pointer m_pXmlDoc is NULL");  // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
155     l_eStatus = eFrameworkunifiedStatusInvldParam;
156   }
157
158   return l_eStatus;
159 }
160
161 EFrameworkunifiedStatus CXMLWriter::XMLSetValue(xmlNodePtr f_pCurrNode,
162                                    const std::string &f_cUserKey,
163                                    std::string &f_cValue,
164                                    BOOL &f_bKeyFound) {
165   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
166
167   if (!f_cUserKey.empty() && NULL != f_pCurrNode) {
168     FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Key :: %s", f_cUserKey.c_str());  // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
169
170     std::string l_cKey = "";
171
172     // result of previous attribute of same node
173     BOOL l_bResult = TRUE;
174
175     // this parameter specifies whether to AND or OR the current result with previous result
176     // TRUE means AND while FALSE means OR
177     BOOL l_bOperation = FALSE;
178
179     // position of "@" in user key if exists
180     size_t l_uiAttrLen = 0;
181
182     // get the single attribute from list of attributes of node
183     std::string l_cAttr = "";  // LCOV_EXCL_BR_LINE 11: except branch
184     std::string l_cNodeName = "";  // LCOV_EXCL_BR_LINE 11: except branch
185
186     // contains the single attribute key, value
187     std::string l_cAttrOpt = "";  // LCOV_EXCL_BR_LINE 11: except branch
188
189     // l_cAttrId of the attribute
190     std::string l_cAttrId = "";  // LCOV_EXCL_BR_LINE 11: except branch
191     // value of the attribute
192     std::string l_cAttrValue = "";  // LCOV_EXCL_BR_LINE 11: except branch
193
194     size_t l_uiSplitProp = 0;
195     size_t l_uiAttrSplit = 0;
196     BOOL l_bCurrentResult = FALSE;
197
198     l_cKey.assign(f_cUserKey);
199
200     // position of first "." in user key
201     size_t l_uiLength = l_cKey.find('.');  // LCOV_EXCL_BR_LINE 11: except branch
202     if (std::string::npos != l_uiLength) {
203       // get the current node name string with node attributes
204       l_cKey = l_cKey.substr(0, l_uiLength);  // LCOV_EXCL_BR_LINE 11: except branch
205
206       l_cNodeName.assign(l_cKey);
207     }
208
209     // get children of current node
210     f_pCurrNode = f_pCurrNode->children;
211
212     while (NULL != f_pCurrNode) {
213       // check whether current node is an element node.
214       if (XML_ELEMENT_NODE == f_pCurrNode->type) {
215         l_bResult = TRUE;
216         l_bOperation = FALSE;
217         l_uiAttrLen = 0;
218         l_cAttr.clear();
219
220         // check whether key contains attribute for current node
221         if (std::string::npos != (l_uiAttrLen = l_cKey.find('@'))) {
222           // get the attribute string from node key
223           l_cAttr.assign(l_cKey, (l_uiAttrLen + 1), std::string::npos);  // LCOV_EXCL_BR_LINE 11: except branch
224
225           // remove the attribute string from key string
226           l_cKey = l_cKey.substr(0, l_uiAttrLen);  // LCOV_EXCL_BR_LINE 11: except branch
227         }
228
229         // check whether node name string matches with the current node name
230         if (!l_cKey.compare((PCSTR)f_pCurrNode->name)) {
231           l_cAttrOpt.assign(l_cAttr);
232
233           while (0 < l_cAttr.length()) {
234             // initialize variables
235             l_cAttrId.clear();
236             l_cAttrValue.clear();
237             l_uiSplitProp = 0;
238             l_uiAttrSplit = 0;
239             l_bCurrentResult = FALSE;
240
241             // check whether node have multiple attributes
242             if (std::string::npos != (l_uiSplitProp = l_cAttr.find('|'))) {
243               l_cAttrOpt = l_cAttr.substr(0, l_uiSplitProp);
244
245               if (std::string::npos != (l_uiAttrSplit = l_cAttrOpt.find('='))) {
246                 l_cAttrId = l_cAttrOpt.substr(0, l_uiAttrSplit);
247                 l_cAttrValue = l_cAttrOpt.substr(l_uiAttrSplit + 1);
248               }
249             } else if (std::string::npos != (l_uiSplitProp = l_cAttr.find('&'))) {
250               l_cAttrOpt = l_cAttr.substr(0, l_uiSplitProp);
251
252               if (std::string::npos != (l_uiAttrSplit = l_cAttrOpt.find('='))) {
253                 l_cAttrId = l_cAttrOpt.substr(0, l_uiAttrSplit);
254                 l_cAttrValue = l_cAttrOpt.substr(l_uiAttrSplit + 1);
255               }
256             } else {
257               l_uiSplitProp = l_cAttr.length() - 1;
258               if (std::string::npos != (l_uiAttrSplit = l_cAttr.find('='))) {
259                 l_cAttrId = l_cAttr.substr(0, l_uiAttrSplit);  // LCOV_EXCL_BR_LINE 11: except branch
260                 l_cAttrValue = l_cAttr.substr(l_uiAttrSplit + 1);  // LCOV_EXCL_BR_LINE 11: except branch
261               }
262             }
263
264             // compare the value of attributes
265             xmlChar *l_pAttrValue = xmlGetProp(f_pCurrNode, (const xmlChar *)l_cAttrId.c_str());  // LCOV_EXCL_BR_LINE 11: except branch
266             if (NULL != l_pAttrValue) {
267               if (!l_cAttrValue.compare((PCSTR)l_pAttrValue)) {
268                 l_bCurrentResult = TRUE;
269               }
270             }
271             xmlFree(l_pAttrValue);
272             l_pAttrValue = NULL;
273
274             // combine the result of all attributes
275             if (!l_bOperation) {
276               l_bResult = l_bResult && l_bCurrentResult;
277             } else {
278               l_bResult = l_bResult || l_bCurrentResult;
279             }
280
281             if ('|' == l_cAttr[l_uiSplitProp]) {
282               l_bOperation = TRUE;
283             } else {
284               l_bOperation = FALSE;
285             }
286
287             if ((!l_bResult) && (!l_bOperation)) {
288               // break from current while loop
289               break;
290             }
291
292             l_cAttr = l_cAttr.substr(l_uiSplitProp + 1);  // LCOV_EXCL_BR_LINE 11: except branch
293           }
294
295           // if attributes not matched move to next node
296           if (!l_bResult) {
297             // search for the same node name in next child nodes
298             l_cKey.assign(l_cNodeName);
299           } else {
300             // read text of current node
301             if ((NULL != f_pCurrNode->children) &&
302                 (XML_TEXT_NODE == f_pCurrNode->children->type) &&
303                 (NULL == f_pCurrNode->children->next)) {
304               // set the value
305               xmlNodeSetContent(f_pCurrNode, (const xmlChar *)f_cValue.c_str());
306
307               f_bKeyFound = TRUE;
308             }
309           }
310         }
311
312         if (l_bResult) {
313           // parse children and next nodes of current node
314           l_cKey = f_cUserKey.substr(l_uiLength + 1);  // LCOV_EXCL_BR_LINE 11: except branch
315           l_eStatus = XMLSetValue(f_pCurrNode, l_cKey, f_cValue, f_bKeyFound);
316         }
317       }
318
319       f_pCurrNode = f_pCurrNode->next;
320     }
321   } else {
322     l_eStatus = eFrameworkunifiedStatusNullPointer;
323   }
324
325   return l_eStatus;
326 }
327
328 EFrameworkunifiedStatus CXMLWriter::SaveData() {
329   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
330   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
331
332   // save the doc structure to the file
333   if (-1 == xmlSaveFileEnc(m_cFilePath.c_str(), m_pXmlDoc, "UTF-8")) {
334     l_eStatus = eFrameworkunifiedStatusFail;
335   }
336
337   return l_eStatus;
338 }