summaryrefslogtreecommitdiffstats
path: root/nsframework/framework_unified/client/NS_XMLConfigeParser/library/src/ns_xmlparser.cpp
blob: cb058658254dfb08762485e65a6d40df557375d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
/*
 * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \ingroup  tag_NS_XmlParser
/// \brief    This file contains implementation of CXmlParser class.
///
////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////
// Include Files
////////////////////////////////////////////////////////////////////////////////////////////////////
#include <native_service/ns_xmlparser_if.h>
#include <fstream>
#include <string>
#include "ns_xmlconfig_parser_frameworkunifiedlog.h"

////////////////////////////////////////////////////////////////////////////////////////////////
/// CXmlParser
/// Constructor
////////////////////////////////////////////////////////////////////////////////////////////////
CXmlParser::CXmlParser(): m_pXmlDoc(NULL), m_cFileName(""), m_pRootNode(NULL) {
  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");

  // for maintaining indentation
  xmlKeepBlanksDefault(0);  // LCOV_EXCL_BR_LINE 11: except branch

  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// ~CXmlParser
/// Destructor
////////////////////////////////////////////////////////////////////////////////////////////////
CXmlParser::~CXmlParser() {
  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");

  // clears the document structure
  ClearDocument();  // LCOV_EXCL_BR_LINE 11: except branch

  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// ParseXml
/// Parses the xml file and creates a document structure
////////////////////////////////////////////////////////////////////////////////////////////////
EFrameworkunifiedStatus CXmlParser::ParseXml(std::string f_cFileName) {
  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
  EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;

  // clears the document structure
  ClearDocument();  // LCOV_EXCL_BR_LINE 11: except branch

  m_cFileName = f_cFileName;

  if (IsReadable(m_cFileName)) {
    // create document object structure
    m_pXmlDoc = xmlParseFile(m_cFileName.c_str());

    if (NULL != m_pXmlDoc) {
      // sets the root node in class
      m_pRootNode.SetXmlNodePtr(xmlDocGetRootElement(m_pXmlDoc));
    } else {
      FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Document not parsed successfully :: %s", f_cFileName.c_str());  // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
      l_eStatus = eFrameworkunifiedStatusNullPointer;
    }
  } else {
    l_eStatus = eFrameworkunifiedStatusInvldParam;
    FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "File not exists :: %s", f_cFileName.c_str());  // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
  }

  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
  return l_eStatus;
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// CreateNewXmlDoc
/// Creates a new xml document with f_cRootNodeName as root node
////////////////////////////////////////////////////////////////////////////////////////////////
EFrameworkunifiedStatus CXmlParser::CreateNewXmlDoc(std::string f_cRootNodeName) {
  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
  EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;

  xmlNodePtr l_pRootNodePtr = NULL;

  // clears the document structure
  ClearDocument();

  if (0 < f_cRootNodeName.length()) {
    // creates new document structure
    m_pXmlDoc = xmlNewDoc((const xmlChar *)"1.0");
    if (NULL != m_pXmlDoc) {
      // create new node(root)
      l_pRootNodePtr = xmlNewNode(NULL,
                                  (const xmlChar *)f_cRootNodeName.c_str());
      if (NULL != l_pRootNodePtr) {
        // sets the root node in document structure
        xmlDocSetRootElement(m_pXmlDoc, l_pRootNodePtr);

        // sets the root node in class
        m_pRootNode.SetXmlNodePtr(l_pRootNodePtr);
      } else {
        l_eStatus = eFrameworkunifiedStatusNullPointer;
        FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Error creating new root node");  // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
      }
    } else {
      l_eStatus = eFrameworkunifiedStatusNullPointer;
      FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Unable to create new xml document structure");  // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
    }
  } else {
    l_eStatus = eFrameworkunifiedStatusInvldParam;
    FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "Invalid root node name :: %s", f_cRootNodeName.c_str());  // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
  }

  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
  return l_eStatus;
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// SaveXml
/// Saves the document structure in an xml file
////////////////////////////////////////////////////////////////////////////////////////////////
EFrameworkunifiedStatus CXmlParser::SaveXml(std::string f_cFileName) {
  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
  EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
  std::string l_cFileName = "";

  // if user explicitly provides file name
  if (0 < f_cFileName.length()) {
    l_cFileName.assign(f_cFileName);
  } else {  // takes the file name from the CXmlParser object
    l_cFileName.assign(m_cFileName);
  }

  if (NULL != m_pXmlDoc) {
    if (IsReadable(l_cFileName)) {
      // save the doc structure to the file
      if (-1 == xmlSaveFormatFileEnc(l_cFileName.c_str(), m_pXmlDoc, "UTF-8", 1)) {
        l_eStatus = eFrameworkunifiedStatusFail;
      }
    } else {
      l_eStatus = eFrameworkunifiedStatusInvldParam;
      FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "File not exists :: %s", f_cFileName.c_str());  // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
    }
  } else {
    l_eStatus = eFrameworkunifiedStatusNullPointer;
    FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "m_pXmlDoc is NULL");   // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
  }


  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
  return l_eStatus;
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// GetRootNode
/// Gets the root node object of xml
////////////////////////////////////////////////////////////////////////////////////////////////
CXmlNode CXmlParser::GetRootNode() {
  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");

  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
  return m_pRootNode;
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// AddNewNode
/// Adds the new node to the parent node
////////////////////////////////////////////////////////////////////////////////////////////////
CXmlNode CXmlParser::AddNewNode(CXmlNode m_pParentNode, std::string f_cNewNodeName, std::string f_cContent) {
  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
  CXmlNode l_pXmlNode;

  if (!m_pParentNode.IsNull()) {
    l_pXmlNode = m_pParentNode.AddChildNode(f_cNewNodeName, f_cContent);  // LCOV_EXCL_BR_LINE 11: except branch
  }

  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
  return l_pXmlNode;
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// RemoveNode
/// Removes the node from the xml
////////////////////////////////////////////////////////////////////////////////////////////////
EFrameworkunifiedStatus CXmlParser::RemoveNode(CXmlNode m_pNode) {
  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
  EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;

  if (!m_pNode.IsNull()) {
    xmlUnlinkNode(m_pNode.m_pXmlNodePtr);
    xmlFreeNode(m_pNode.m_pXmlNodePtr);
  } else {
    l_eStatus = eFrameworkunifiedStatusNullPointer;
  }

  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
  return l_eStatus;
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// FindNode
/// Finds the first matching node, by tag name or path
////////////////////////////////////////////////////////////////////////////////////////////////
CXmlNode CXmlParser::FindNode(std::string f_cNodePath, CXmlNode f_pCurrentNode) {
  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
  CXmlNode l_pXmlNode;

  xmlXPathObjectPtr l_pXpathObj = GetNodeSet(f_cNodePath, f_pCurrentNode);  // LCOV_EXCL_BR_LINE 11: except branch

  if (NULL != l_pXpathObj) {
    if (NULL != l_pXpathObj->nodesetval && 0 < l_pXpathObj->nodesetval->nodeNr) {
      l_pXmlNode.SetXmlNodePtr(l_pXpathObj->nodesetval->nodeTab[0]);  // LCOV_EXCL_BR_LINE 11: except branch
    } else {
      FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "NodeSetVal is NULL");  // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
    }

    xmlXPathFreeObject(l_pXpathObj);  // LCOV_EXCL_BR_LINE 11: except branch
  } else {
    FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "xmlXPathObjectPtr is NULL");  // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
  }

  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
  return l_pXmlNode;
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// FindAllNodes
/// Finds all the matching node, by tag name or path
////////////////////////////////////////////////////////////////////////////////////////////////
TNodeList CXmlParser::FindAllNodes(std::string f_cNodePath, CXmlNode f_pCurrentNode) {
  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
  TNodeList l_pNodeList;

  xmlXPathObjectPtr l_pXpathObj = GetNodeSet(f_cNodePath, f_pCurrentNode);  // LCOV_EXCL_BR_LINE 11: except branch

  if (NULL != l_pXpathObj) {
    if (NULL != l_pXpathObj->nodesetval && 0 < l_pXpathObj->nodesetval->nodeNr) {
      for (UI_8 l_uiSize = 0;
           l_uiSize < l_pXpathObj->nodesetval->nodeNr;
           l_uiSize++) {
        if (NULL != l_pXpathObj->nodesetval->nodeTab[l_uiSize]) {
          CXmlNode l_pNode(l_pXpathObj->nodesetval->nodeTab[l_uiSize]);  // LCOV_EXCL_BR_LINE 11: except branch
          l_pNodeList.push_back(l_pNode);
        } else {
          FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "node pointer is NULL");
        }
      }
    } else {
      FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "NodeSetVal is NULL");  // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
    }

    xmlXPathFreeObject(l_pXpathObj);  // LCOV_EXCL_BR_LINE 11: except branch
  } else {
    FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "xmlXPathObjectPtr is NULL");  // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
  }

  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
  return l_pNodeList;
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// GetNodeSet
/// Gets the node set resulting from search of nodepath using XPath
////////////////////////////////////////////////////////////////////////////////////////////////
xmlXPathObjectPtr CXmlParser::GetNodeSet(std::string f_cNodePath, CXmlNode f_pCurrentNode) {
  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
  xmlXPathObjectPtr l_pXpathObj = NULL;

  xmlXPathContextPtr l_pXpathCtx = NULL;
  CXmlNode l_pXmlNode;

  if (NULL != m_pXmlDoc) {
    if (!f_pCurrentNode.IsNull()) {
      l_pXmlNode = f_pCurrentNode;
    }

    // Create xpath evaluation context
    l_pXpathCtx = xmlXPathNewContext(m_pXmlDoc);  // LCOV_EXCL_BR_LINE 11: except branch

    if (NULL != l_pXpathCtx) {
      // set the current node in path context
      l_pXpathCtx->node = l_pXmlNode.m_pXmlNodePtr;

      // Evaluate xpath expression
      l_pXpathObj = xmlXPathEvalExpression((const xmlChar *)f_cNodePath.c_str(), l_pXpathCtx);  // LCOV_EXCL_BR_LINE 11: except branch

      if (NULL == l_pXpathObj) {
        FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Unable to evaluate nodepath :: \"%s\"", f_cNodePath.c_str());   // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
      }

      // Cleanup of XPath data
      xmlXPathFreeContext(l_pXpathCtx);  // LCOV_EXCL_BR_LINE 11: except branch
    } else {
      FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Unable to create new XPath context");   // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
    }
  } else {
    FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __FUNCTION__, "document object is NULL");   // LCOV_EXCL_BR_LINE 15:marco defined in "native_service/ns_logger_if.h"
  }

  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
  return l_pXpathObj;
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// ClearDocument
/// Clears the document structure and resets the root node
////////////////////////////////////////////////////////////////////////////////////////////////
VOID CXmlParser::ClearDocument() {
  if (NULL != m_pXmlDoc) {
    // free the document
    xmlFreeDoc(m_pXmlDoc);
    m_pXmlDoc = NULL;

    // free the global variables that may have been allocated by the parser
    xmlCleanupParser();
  }

  m_pRootNode = NULL;
  m_cFileName.clear();
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// IsReadable
/// Checks whether the file exists or not
////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CXmlParser::IsReadable(const std::string &filename) {
  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
  BOOL l_bReadable = FALSE;

  std::ifstream l_ifstream(filename.c_str());

  if (l_ifstream.good()) {
    l_bReadable = TRUE;
    l_ifstream.close();  // LCOV_EXCL_BR_LINE 11: except branch
  }

  FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
  return l_bReadable;
}