1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
4 *
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
6 *
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
13 *
14 */
15
16 #include <cstdlib>
17
18 #include "XMLtools.hxx"
19 #include "SLint.hxx"
20 #include "SLintXMLException.hxx"
21 #include "UTF8.hxx"
22
23 extern "C"
24 {
25 #include "sci_malloc.h"
26 #include "charEncoding.h"
27 #include "localization.h"
28 }
29
30 #define SLINT_XML_ERROR_BUFFER_SIZE 1024
31
32 namespace slint
33 {
34
35 std::ostringstream XMLtools::errorBuffer;
36
getDouble(xmlNode * node,const char * attrName,double & out)37 bool XMLtools::getDouble(xmlNode * node, const char * attrName, double & out)
38 {
39 xmlAttr * attr = xmlHasProp(node, (const xmlChar *)attrName);
40 if (attr)
41 {
42 out = std::atof((const char *)attr->children->content);
43 return true;
44 }
45 return false;
46 }
47
getUIntVector(xmlNode * node,const char * attrName,std::vector<unsigned int> & out)48 bool XMLtools::getUIntVector(xmlNode * node, const char * attrName, std::vector<unsigned int> & out)
49 {
50 xmlAttr * attr = xmlHasProp(node, (const xmlChar *)attrName);
51 if (attr)
52 {
53 std::vector<std::string> toks = tokenize((const char *)attr->children->content, ',');
54 for (const auto & tok : toks)
55 {
56 const int i = std::stoi(tok);
57 if (i > 0)
58 {
59 out.emplace_back((unsigned int)i);
60 }
61 }
62 return !toks.empty();
63 }
64 return false;
65 }
66
getInt(xmlNode * node,const char * attrName,int & out)67 bool XMLtools::getInt(xmlNode * node, const char * attrName, int & out)
68 {
69 xmlAttr * attr = xmlHasProp(node, (const xmlChar *)attrName);
70 if (attr)
71 {
72 out = std::atoi((const char *)attr->children->content);
73 return true;
74 }
75 return false;
76 }
77
getString(xmlNode * node,const char * attrName,std::string & out)78 bool XMLtools::getString(xmlNode * node, const char * attrName, std::string & out)
79 {
80 xmlAttr * attr = xmlHasProp(node, (const xmlChar *)attrName);
81 if (attr)
82 {
83 out = std::string((const char *)attr->children->content);
84 return true;
85 }
86 return false;
87 }
88
getWString(xmlNode * node,const char * attrName,std::wstring & out)89 bool XMLtools::getWString(xmlNode * node, const char * attrName, std::wstring & out)
90 {
91 xmlAttr * attr = xmlHasProp(node, (const xmlChar *)attrName);
92 if (attr)
93 {
94 wchar_t * content = to_wide_string((const char *)attr->children->content);
95 out = std::wstring(content);
96 FREE(content);
97
98 return true;
99 }
100 return false;
101 }
102
getBool(xmlNode * node,const char * attrName,bool & out)103 bool XMLtools::getBool(xmlNode * node, const char * attrName, bool & out)
104 {
105 xmlAttr * attr = xmlHasProp(node, (const xmlChar *)attrName);
106 if (attr)
107 {
108 std::string val((const char *)attr->children->content);
109 if (val == "true" || val == "1" || val == "yes")
110 {
111 out = true;
112 return true;
113 }
114 else if (val == "false" || val == "0" || val == "no")
115 {
116 out = false;
117 return true;
118 }
119 }
120 return false;
121 }
122
readXML(const std::wstring & path)123 xmlDoc * XMLtools::readXML(const std::wstring & path)
124 {
125 const std::string fullpath = scilab::UTF8::toUTF8(SLint::getFullPath(path));
126 xmlParserCtxt * ctxt = xmlNewParserCtxt();
127 if (!ctxt)
128 {
129 throw SLintXMLException(fullpath, gettext("Cannot create a parser context"));
130 }
131
132 xmlSetGenericErrorFunc(ctxt, errorFunction);
133
134 int options = XML_PARSE_NSCLEAN | XML_PARSE_NOBLANKS;
135 xmlDoc * doc = xmlCtxtReadFile(ctxt, fullpath.c_str(), "UTF-8", options);
136 if (!doc || !ctxt->valid)
137 {
138 std::string error = errorBuffer.str();
139 errorBuffer.str("");
140 errorBuffer.clear();
141 throw SLintXMLException(fullpath, error);
142 }
143
144 xmlFreeParserCtxt(ctxt);
145
146 return doc;
147 }
148
errorFunction(void * ctx,const char * msg,...)149 void XMLtools::errorFunction(void * ctx, const char * msg, ...)
150 {
151 char str[SLINT_XML_ERROR_BUFFER_SIZE];
152 va_list args;
153
154 va_start(args, msg);
155 vsnprintf(str, SLINT_XML_ERROR_BUFFER_SIZE, msg, args);
156 va_end(args);
157
158 errorBuffer << str;
159 }
160
tokenize(const std::string & str,const char delim)161 std::vector<std::string> XMLtools::tokenize(const std::string & str, const char delim)
162 {
163 std::vector<std::string> tokens;
164 std::string token;
165 std::for_each(str.begin(), str.end(), [&](char c)
166 {
167 if (c != ' ' && c != '\t')
168 {
169 if (c != delim)
170 {
171 token += c;
172 }
173 else if (!token.empty())
174 {
175 tokens.emplace_back(token);
176 token.clear();
177 }
178 }
179 });
180
181 if (!token.empty())
182 {
183 tokens.emplace_back(token);
184 }
185 return tokens;
186 }
187
188 } // namespace slint
189