2 * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ////////////////////////////////////////////////////////////////////////////////////////////////////
18 /// \ingroup tag_NS_ConfigParser
19 /// \brief This file contains implementation of CXMLWriter class.
21 ////////////////////////////////////////////////////////////////////////////////////////////////////
23 ////////////////////////////////////////////////////////////////////////////////////////////////////
25 ////////////////////////////////////////////////////////////////////////////////////////////////////
26 #include <native_service/ns_xml_writer.h>
28 #include "ns_xmlconfig_parser_frameworkunifiedlog.h"
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
39 return l_p_xml_writer;
42 CXMLWriter *GetCXMLWriterObjectNoParam() {
43 return (new(std::nothrow) CXMLWriter()); // LCOV_EXCL_BR_LINE 11: except branch
50 CXMLWriter::CXMLWriter(): m_pXmlDoc(NULL), m_cFilePath("") {
51 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
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());
57 // create document object structure
58 m_pXmlDoc = xmlParseFile(m_cFilePath.c_str()); // LCOV_EXCL_BR_LINE 11: except branch
61 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Pointer to document structure is NULL");
65 CXMLWriter::~CXMLWriter() {
66 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "Destructor");
68 if (NULL != m_pXmlDoc) {
69 xmlFreeDoc(m_pXmlDoc); // LCOV_EXCL_BR_LINE 11: except branch
74 EFrameworkunifiedStatus CXMLWriter::ParseFile(const std::string &f_cFilePath) {
75 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
76 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
78 l_eStatus = SetPath(f_cFilePath);
80 if (NULL != m_pXmlDoc) {
81 xmlFreeDoc(m_pXmlDoc);
85 // create document object structure
86 m_pXmlDoc = xmlParseFile(f_cFilePath.c_str());
88 if (NULL == m_pXmlDoc) {
89 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Pointer to document structure is NULL");
90 l_eStatus = eFrameworkunifiedStatusNullPointer;
93 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
97 EFrameworkunifiedStatus CXMLWriter::SetPath(const std::string &f_cPath) {
98 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
100 if (!f_cPath.empty()) {
102 m_cFilePath.assign(f_cPath);
104 l_eStatus = eFrameworkunifiedStatusInvldParam;
110 VOID CXMLWriter::SetDataPtr(PVOID f_pData) {
112 if (NULL != f_pData) {
113 // set the doc pointer
114 m_pXmlDoc = static_cast<xmlDocPtr>(f_pData);
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"
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;
124 if (NULL != m_pXmlDoc && (!f_cKey.empty())) {
125 std::string l_cUserKey = "";
126 l_cUserKey.assign(f_cKey);
128 // get the root node element
129 xmlNodePtr l_pCurrNode = xmlDocGetRootElement(m_pXmlDoc);
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
135 if (std::string::npos != l_uiLength) {
136 l_cUserKey = l_cUserKey.substr(l_uiLength + 1); // LCOV_EXCL_BR_LINE 11: except branch
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);
144 l_eStatus = eFrameworkunifiedStatusFail;
148 l_eStatus = eFrameworkunifiedStatusInvldParam;
151 l_eStatus = eFrameworkunifiedStatusNullPointer;
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;
161 EFrameworkunifiedStatus CXMLWriter::XMLSetValue(xmlNodePtr f_pCurrNode,
162 const std::string &f_cUserKey,
163 std::string &f_cValue,
165 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
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"
170 std::string l_cKey = "";
172 // result of previous attribute of same node
173 BOOL l_bResult = TRUE;
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;
179 // position of "@" in user key if exists
180 size_t l_uiAttrLen = 0;
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
186 // contains the single attribute key, value
187 std::string l_cAttrOpt = ""; // LCOV_EXCL_BR_LINE 11: except branch
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
194 size_t l_uiSplitProp = 0;
195 size_t l_uiAttrSplit = 0;
196 BOOL l_bCurrentResult = FALSE;
198 l_cKey.assign(f_cUserKey);
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
206 l_cNodeName.assign(l_cKey);
209 // get children of current node
210 f_pCurrNode = f_pCurrNode->children;
212 while (NULL != f_pCurrNode) {
213 // check whether current node is an element node.
214 if (XML_ELEMENT_NODE == f_pCurrNode->type) {
216 l_bOperation = FALSE;
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
225 // remove the attribute string from key string
226 l_cKey = l_cKey.substr(0, l_uiAttrLen); // LCOV_EXCL_BR_LINE 11: except branch
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);
233 while (0 < l_cAttr.length()) {
234 // initialize variables
236 l_cAttrValue.clear();
239 l_bCurrentResult = FALSE;
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);
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);
249 } else if (std::string::npos != (l_uiSplitProp = l_cAttr.find('&'))) {
250 l_cAttrOpt = l_cAttr.substr(0, l_uiSplitProp);
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);
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
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;
271 xmlFree(l_pAttrValue);
274 // combine the result of all attributes
276 l_bResult = l_bResult && l_bCurrentResult;
278 l_bResult = l_bResult || l_bCurrentResult;
281 if ('|' == l_cAttr[l_uiSplitProp]) {
284 l_bOperation = FALSE;
287 if ((!l_bResult) && (!l_bOperation)) {
288 // break from current while loop
292 l_cAttr = l_cAttr.substr(l_uiSplitProp + 1); // LCOV_EXCL_BR_LINE 11: except branch
295 // if attributes not matched move to next node
297 // search for the same node name in next child nodes
298 l_cKey.assign(l_cNodeName);
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)) {
305 xmlNodeSetContent(f_pCurrNode, (const xmlChar *)f_cValue.c_str());
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);
319 f_pCurrNode = f_pCurrNode->next;
322 l_eStatus = eFrameworkunifiedStatusNullPointer;
328 EFrameworkunifiedStatus CXMLWriter::SaveData() {
329 FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
330 EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
332 // save the doc structure to the file
333 if (-1 == xmlSaveFileEnc(m_cFilePath.c_str(), m_pXmlDoc, "UTF-8")) {
334 l_eStatus = eFrameworkunifiedStatusFail;