ManaPlus
xmlutils.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2014-2019 The ManaPlus Developers
4  * Copyright (C) 2019-2021 Andrei Karas
5  *
6  * This file is part of The ManaPlus Client.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "utils/xmlutils.h"
23 
24 #include "logger.h"
25 
26 #include "utils/xml.h"
27 
28 #include "debug.h"
29 
30 void readXmlIntVector(const std::string &fileName,
31  const std::string &rootName,
32  const std::string &sectionName,
33  const std::string &itemName,
34  const std::string &attributeName,
35  STD_VECTOR<int> &arr,
36  const SkipError skipError)
37 {
38  XML::Document doc(fileName, UseVirtFs_true, skipError);
39  XmlNodeConstPtrConst rootNode = doc.rootNode();
40 
41  if (rootNode == nullptr || !xmlNameEqual(rootNode, rootName.c_str()))
42  {
43  logger->log("Error while loading %s!", fileName.c_str());
44  return;
45  }
46 
47  for_each_xml_child_node(sectionNode, rootNode)
48  {
49  if (!xmlNameEqual(sectionNode, sectionName.c_str()))
50  continue;
51  for_each_xml_child_node(childNode, sectionNode)
52  {
53  if (xmlNameEqual(childNode, itemName.c_str()))
54  {
55  const int val = XML::getProperty(childNode,
56  attributeName.c_str(), -1);
57  if (val == -1)
58  continue;
59  arr.push_back(val);
60  }
61  else if (xmlNameEqual(childNode, "include"))
62  {
63  const std::string name = XML::getProperty(
64  childNode, "name", "");
65  if (!name.empty())
66  {
67  readXmlIntVector(name,
68  rootName,
69  sectionName,
70  itemName,
71  attributeName,
72  arr,
73  skipError);
74  }
75  }
76  }
77  }
78 }
79 
80 void readXmlStringMap(const std::string &fileName,
81  const std::string &rootName,
82  const std::string &sectionName,
83  const std::string &itemName,
84  const std::string &attributeKeyName,
85  const std::string &attributeValueName,
86  std::map<std::string, std::string> &arr,
87  const SkipError skipError)
88 {
89  XML::Document doc(fileName, UseVirtFs_true, skipError);
90  XmlNodeConstPtrConst rootNode = doc.rootNode();
91 
92  if (rootNode == nullptr || !xmlNameEqual(rootNode, rootName.c_str()))
93  {
94  logger->log("Error while loading %s!", fileName.c_str());
95  return;
96  }
97 
98  for_each_xml_child_node(sectionNode, rootNode)
99  {
100  if (!xmlNameEqual(sectionNode, sectionName.c_str()))
101  continue;
102  for_each_xml_child_node(childNode, sectionNode)
103  {
104  if (xmlNameEqual(childNode, itemName.c_str()))
105  {
106  const std::string key = XML::getProperty(childNode,
107  attributeKeyName.c_str(), "");
108  if (key.empty())
109  continue;
110  const std::string val = XML::getProperty(childNode,
111  attributeValueName.c_str(), "");
112  arr[key] = val;
113  }
114  else if (xmlNameEqual(childNode, "include"))
115  {
116  const std::string name = XML::getProperty(
117  childNode, "name", "");
118  if (!name.empty())
119  {
120  readXmlStringMap(name,
121  rootName,
122  sectionName,
123  itemName,
124  attributeKeyName,
125  attributeValueName,
126  arr,
127  skipError);
128  }
129  }
130  }
131  }
132 }
133 
134 void readXmlIntMap(const std::string &fileName,
135  const std::string &rootName,
136  const std::string &sectionName,
137  const std::string &itemName,
138  const std::string &attributeKeyName,
139  const std::string &attributeValueName,
140  std::map<int32_t, int32_t> &arr,
141  const SkipError skipError)
142 {
143  XML::Document doc(fileName, UseVirtFs_true, skipError);
144  XmlNodeConstPtrConst rootNode = doc.rootNode();
145 
146  if (rootNode == nullptr || !xmlNameEqual(rootNode, rootName.c_str()))
147  {
148  logger->log("Error while loading %s!", fileName.c_str());
149  return;
150  }
151 
152  for_each_xml_child_node(sectionNode, rootNode)
153  {
154  if (!xmlNameEqual(sectionNode, sectionName.c_str()))
155  continue;
156  for_each_xml_child_node(childNode, sectionNode)
157  {
158  if (xmlNameEqual(childNode, itemName.c_str()))
159  {
160  const std::string key = XML::getProperty(childNode,
161  attributeKeyName.c_str(), "");
162  if (key.empty())
163  continue;
164  const int32_t val = XML::getProperty(childNode,
165  attributeValueName.c_str(), 0);
166  arr[atoi(key.c_str())] = val;
167  }
168  else if (xmlNameEqual(childNode, "include"))
169  {
170  const std::string name = XML::getProperty(
171  childNode, "name", "");
172  if (!name.empty())
173  {
174  readXmlIntMap(name,
175  rootName,
176  sectionName,
177  itemName,
178  attributeKeyName,
179  attributeValueName,
180  arr,
181  skipError);
182  }
183  }
184  }
185  }
186 }
void log(const char *const log_text,...)
Definition: logger.cpp:269
xmlNodePtr rootNode()
Definition: libxml.cpp:169
#define for_each_xml_child_node(var, parent)
Definition: libxml.h:161
Logger * logger
Definition: logger.cpp:89
int getProperty(const xmlNodePtr node, const char *const name, int def)
Definition: libxml.cpp:174
bool SkipError
Definition: skiperror.h:30
std::string fileName
Definition: testmain.cpp:39
const bool UseVirtFs_true
Definition: usevirtfs.h:30
void readXmlStringMap(const std::string &fileName, const std::string &rootName, const std::string &sectionName, const std::string &itemName, const std::string &attributeKeyName, const std::string &attributeValueName, std::map< std::string, std::string > &arr, const SkipError skipError)
Definition: xmlutils.cpp:80
void readXmlIntMap(const std::string &fileName, const std::string &rootName, const std::string &sectionName, const std::string &itemName, const std::string &attributeKeyName, const std::string &attributeValueName, std::map< int32_t, int32_t > &arr, const SkipError skipError)
Definition: xmlutils.cpp:134
void readXmlIntVector(const std::string &fileName, const std::string &rootName, const std::string &sectionName, const std::string &itemName, const std::string &attributeName, std::vector< int > &arr, const SkipError skipError)
Definition: xmlutils.cpp:30