1 /**
2 * @file fctxml.cpp
3 *
4 */
5
6 // This file is part of Cantera. See License.txt in the top-level directory or
7 // at https://cantera.org/license.txt for license and copyright information.
8
9 #include "clib/clib_utils.h"
10 #include "cantera/base/ctml.h"
11 #include "cantera/base/global.h"
12
13 #include <cstring>
14 #include <fstream>
15
16 using namespace std;
17 using Cantera::XML_Node;
18 using Cantera::CanteraError;
19 using Cantera::handleAllExceptions;
20
21 #include "clib/Cabinet.h"
22
23 typedef Cabinet<XML_Node, false> XmlCabinet;
24 template<> XmlCabinet* XmlCabinet::s_storage = 0;
25
26 typedef integer status_t;
27
28 namespace {
29
_xml(const integer * i)30 XML_Node* _xml(const integer* i)
31 {
32 return &XmlCabinet::item(*i);
33 }
34
35 } // unnamed namespace
36
37 std::string f2string(const char* s, ftnlen n);
38
39 extern "C" {
40
fxml_new_(const char * name,ftnlen namelen)41 integer fxml_new_(const char* name, ftnlen namelen)
42 {
43 try {
44 XML_Node* x;
45 if (!name) {
46 x = new XML_Node;
47 } else {
48 x = new XML_Node(f2string(name, namelen), 0);
49 }
50 return XmlCabinet::add(x);
51 } catch (...) {
52 return handleAllExceptions(-1, ERR);
53 }
54 }
55
fxml_get_xml_file_(const char * file,ftnlen filelen)56 status_t fxml_get_xml_file_(const char* file, ftnlen filelen)
57 {
58 try {
59 XML_Node* x = Cantera::get_XML_File(f2string(file, filelen));
60 return XmlCabinet::add(x);
61 } catch (...) {
62 return handleAllExceptions(-1, ERR);
63 }
64 }
65
fxml_clear_()66 status_t fxml_clear_()
67 {
68 try {
69 XmlCabinet::clear();
70 Cantera::close_XML_File("all");
71 return 0;
72 } catch (...) {
73 return handleAllExceptions(-1, ERR);
74 }
75 }
76
fxml_del_(const integer * i)77 status_t fxml_del_(const integer* i)
78 {
79 try {
80 XmlCabinet::del(*i);
81 return 0;
82 } catch (...) {
83 return handleAllExceptions(-1, ERR);
84 }
85 }
86
fxml_removechild_(const integer * i,const integer * j)87 status_t fxml_removechild_(const integer* i, const integer* j)
88 {
89 try {
90 _xml(i)->removeChild(_xml(j));
91 return 0;
92 } catch (...) {
93 return handleAllExceptions(-1, ERR);
94 }
95 }
96
fxml_copy_(const integer * i)97 status_t fxml_copy_(const integer* i)
98 {
99 try {
100 return XmlCabinet::newCopy(*i);
101 } catch (...) {
102 return handleAllExceptions(-1, ERR);
103 }
104 }
105
fxml_attrib_(const integer * i,const char * key,char * value,ftnlen keylen,ftnlen valuelen)106 status_t fxml_attrib_(const integer* i, const char* key, char* value,
107 ftnlen keylen, ftnlen valuelen)
108 {
109 try {
110 std::string ky = f2string(key, keylen);
111 XML_Node& node = *_xml(i);
112 if (node.hasAttrib(ky)) {
113 std::string v = node[ky];
114 strncpy(value, v.c_str(), valuelen);
115 } else {
116 throw CanteraError("fxml_attrib","node "
117 " has no attribute '"+ky+"'");
118 }
119 } catch (...) {
120 return handleAllExceptions(-1, ERR);
121 }
122 return 0;
123 }
124
fxml_addattrib_(const integer * i,const char * key,const char * value,ftnlen keylen,ftnlen valuelen)125 status_t fxml_addattrib_(const integer* i, const char* key,
126 const char* value, ftnlen keylen, ftnlen valuelen)
127 {
128 try {
129 std::string ky = f2string(key, keylen);
130 std::string val = f2string(value, valuelen);
131 XML_Node& node = *_xml(i);
132 node.addAttribute(ky, val);
133 } catch (...) {
134 return handleAllExceptions(-1, ERR);
135 }
136 return 0;
137 }
138
fxml_addcomment_(const integer * i,const char * comment,ftnlen commentlen)139 status_t fxml_addcomment_(const integer* i, const char* comment,
140 ftnlen commentlen)
141 {
142 try {
143 std::string c = f2string(comment, commentlen);
144 XML_Node& node = *_xml(i);
145 node.addComment(c);
146 } catch (...) {
147 return handleAllExceptions(-1, ERR);
148 }
149 return 0;
150 }
151
fxml_tag_(const integer * i,char * tag,ftnlen taglen)152 status_t fxml_tag_(const integer* i, char* tag, ftnlen taglen)
153 {
154 try {
155 XML_Node& node = *_xml(i);
156 const std::string v = node.name();
157 strncpy(tag, v.c_str(), taglen);
158 } catch (...) {
159 return handleAllExceptions(-1, ERR);
160 }
161 return 0;
162 }
163
fxml_value_(const integer * i,char * value,ftnlen valuelen)164 status_t fxml_value_(const integer* i, char* value, ftnlen valuelen)
165 {
166 try {
167 XML_Node& node = *_xml(i);
168 const std::string v = node.value();
169 strncpy(value, v.c_str(), valuelen);
170 } catch (...) {
171 return handleAllExceptions(-1, ERR);
172 }
173 return 0;
174 }
175
fxml_child_(const integer * i,const char * loc,ftnlen loclen)176 status_t fxml_child_(const integer* i, const char* loc, ftnlen loclen)
177 {
178 try {
179 XML_Node& node = *_xml(i);
180 XML_Node& c = node.child(f2string(loc, loclen));
181 return XmlCabinet::add(&c);
182 } catch (...) {
183 return handleAllExceptions(-1, ERR);
184 }
185 }
186
fxml_child_bynumber_(const integer * i,const integer * m)187 status_t fxml_child_bynumber_(const integer* i, const integer* m)
188 {
189 try {
190 XML_Node& node = *_xml(i);
191 XML_Node& c = node.child(*m);
192 return XmlCabinet::add(&c);
193 } catch (...) {
194 return handleAllExceptions(-1, ERR);
195 }
196 return 0;
197 }
198
fxml_findid_(const integer * i,const char * id,ftnlen idlen)199 status_t fxml_findid_(const integer* i, const char* id, ftnlen idlen)
200 {
201 try {
202 XML_Node& node = *_xml(i);
203 XML_Node* c = node.findID(f2string(id, idlen));
204 if (c) {
205 return XmlCabinet::add(c);
206 } else {
207 throw CanteraError("fxml_findid", "id not found: '{}'",
208 f2string(id, idlen));
209 }
210 } catch (...) {
211 return handleAllExceptions(-1, ERR);
212 }
213 return 0;
214 }
215
fxml_findbyname_(const integer * i,const char * nm,ftnlen nmlen)216 status_t fxml_findbyname_(const integer* i, const char* nm, ftnlen nmlen)
217 {
218 try {
219 XML_Node& node = *_xml(i);
220 XML_Node* c = node.findByName(f2string(nm, nmlen));
221 if (c) {
222 return XmlCabinet::add(c);
223 } else {
224 throw CanteraError("fxml_findByName", "name '{}' not found",
225 f2string(nm, nmlen));
226 }
227 } catch (...) {
228 return handleAllExceptions(-1, ERR);
229 }
230 return 0;
231 }
232
fxml_nchildren_(const integer * i)233 integer fxml_nchildren_(const integer* i)
234 {
235 try {
236 XML_Node& node = *_xml(i);
237 return node.nChildren();
238 } catch (...) {
239 return handleAllExceptions(-1, ERR);
240 }
241 return 0;
242 }
243
fxml_addchild_(const integer * i,const char * name,const char * value,ftnlen namelen,ftnlen valuelen)244 status_t fxml_addchild_(const integer* i, const char* name,
245 const char* value, ftnlen namelen, ftnlen valuelen)
246 {
247 try {
248 XML_Node& node = *_xml(i);
249 XML_Node& c = node.addChild(f2string(name, namelen),
250 f2string(value,valuelen));
251 return XmlCabinet::add(&c);
252 } catch (...) {
253 return handleAllExceptions(-1, ERR);
254 }
255 return 0;
256 }
257
fxml_addchildnode_(const integer * i,const integer * j)258 status_t fxml_addchildnode_(const integer* i, const integer* j)
259 {
260 try {
261 XML_Node& node = *_xml(i);
262 XML_Node& chld = *_xml(j);
263 XML_Node& c = node.addChild(chld);
264 return XmlCabinet::add(&c);
265 } catch (...) {
266 return handleAllExceptions(-1, ERR);
267 }
268 return 0;
269 }
270
fxml_write_(const integer * i,const char * file,ftnlen filelen)271 status_t fxml_write_(const integer* i, const char* file, ftnlen filelen)
272 {
273 try {
274 std::string ff(file, filelen);
275 ofstream f(ff.c_str());
276 if (f) {
277 XML_Node& node = *_xml(i);
278 node.write(f);
279 } else {
280 throw CanteraError("fxml_write",
281 "file "+f2string(file, filelen)+" not found.");
282 }
283 return 0;
284 } catch (...) {
285 return handleAllExceptions(-1, ERR);
286 }
287 return 0;
288 }
289
ctml_getfloatarray_(const integer * i,const integer * n,doublereal * data,const integer * iconvert)290 status_t ctml_getfloatarray_(const integer* i, const integer* n,
291 doublereal* data, const integer* iconvert)
292 {
293 try {
294 XML_Node& node = *_xml(i);
295 Cantera::vector_fp v;
296 bool conv = false;
297 if (*iconvert > 0) {
298 conv = true;
299 }
300 getFloatArray(node, v, conv);
301 int nv = v.size();
302
303 // array not big enough
304 if (*n < nv) {
305 throw CanteraError("ctml_getfloatarray",
306 "array must be dimensioned at least {}", nv);
307 }
308
309 for (int i = 0; i < nv; i++) {
310 data[i] = v[i];
311 }
312 } catch (...) {
313 return handleAllExceptions(-1, ERR);
314 }
315 return 0;
316 }
317
318 }
319