COPASI API  4.16.103
CCopasiXMLInterface.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010 - 2015 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 // Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
7 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
8 // and The University of Manchester.
9 // All rights reserved.
10 
11 // Copyright (C) 2003 - 2007 by Pedro Mendes, Virginia Tech Intellectual
12 // Properties, Inc. and EML Research, gGmbH.
13 // All rights reserved.
14 
15 /**
16  * CCopasiXMLInterface class.
17  * The class CCopasiXMLInterface is the interface to various XML document
18  * containing COPASI relevant information.
19  *
20  * Created for COPASI by Stefan Hoops 2003
21  */
22 
23 #include <fstream>
24 #include <limits>
25 #include <cmath>
26 
27 #include "copasi.h"
28 #include "CCopasiXMLInterface.h"
29 #include "model/CModel.h"
34 #include "CCopasiXMLParser.h"
36 #include "utilities/CSlider.h"
37 #include "utilities/CDirEntry.h"
39 
40 SCopasiXMLGUI::SCopasiXMLGUI(const std::string & name,
41  const CCopasiContainer * pParent,
42  const std::string & type,
43  const unsigned C_INT32 & flag)
44  : CCopasiContainer(name, pParent, type, flag),
45  mpSliderList(new CCopasiVector<CSlider>("SliderList", this))
46 {}
47 
49 {
50 }
51 
52 /**
53  * Returns a pointer the the slider list.
54  */
56 {
57  return this->mpSliderList;
58 }
59 
60 /**
61  * Returns a const pointer to the slider list.
62  */
64 {
65  return this->mpSliderList;
66 }
67 
68 void encodeNONE(const char & chr, std::ostringstream & xml)
69 {
70  xml << chr;
71  return;
72 }
73 
74 void encodeSTD(const char & chr, std::ostringstream & xml)
75 {
76  switch (chr)
77  {
78  case '&':
79  xml << "&amp;";
80  break;
81 
82  case '\'':
83  xml << "&apos;";
84  break;
85 
86  case '<':
87  xml << "&lt;";
88  break;
89 
90  case '>':
91  xml << "&gt;";
92  break;
93 
94  case '\"':
95  xml << "&quot;";
96  break;
97 
98  default:
99  xml << chr;
100  break;
101  }
102 
103  return;
104 }
105 
106 void encodeATTRIBUTE(const char & chr, std::ostringstream & xml)
107 {
108  switch (chr)
109  {
110  case '&':
111  xml << "&amp;";
112  break;
113 
114  case '<':
115  xml << "&lt;";
116  break;
117 
118  case '\"':
119  xml << "&quot;";
120  break;
121 
122  case '\t': // Without this <tab> is converted to <space>
123  xml << "&#x09;";
124  break;
125 
126  case '\n': // Without this linebreak is converted to <space>
127  xml << "&#x0a;";
128  break;
129 
130  default:
131  xml << chr;
132  break;
133  }
134 
135  return;
136 }
137 
138 void encodeCHARACTER(const char & chr, std::ostringstream & xml)
139 {
140  switch (chr)
141  {
142  case '&':
143  xml << "&amp;";
144  break;
145 
146  case '<':
147  xml << "&lt;";
148  break;
149 
150  default:
151  xml << chr;
152  break;
153  }
154 
155  return;
156 }
157 
158 std::string CCopasiXMLInterface::encode(const std::string & str, const EncodingType & type)
159 {
160  /* All COPASI std::strings and char are already UTF-8 encoded.*/
161  std::string tmp = str;
162  std::ostringstream xml;
163 
164  void (*encode)(const char & chr, std::ostringstream & xml) = encodeNONE;
165 
166  std::string::const_iterator it = str.begin();
167  std::string::const_iterator end = str.end();
168 
169  switch (type)
170  {
171  case none:
172  encode = encodeNONE;
173  break;
174 
175  case standard:
176  encode = encodeSTD;
177  break;
178 
179  case attribute:
181  break;
182 
183  case character:
185  break;
186  }
187 
188  for (; it != end; ++it)
189  encode(*it, xml);
190 
191  return xml.str();
192 }
193 
195  mValue(value)
196 {
198  mValue = 0.0;
199 }
200 
201 CCopasiXMLInterface::DBL::DBL(const char * value):
202  mValue(std::numeric_limits<C_FLOAT64>::quiet_NaN())
203 {
204  if (!value || !*value) return;
205 
206  std::istringstream in;
207 
208  in.imbue(std::locale::classic());
209  in.str(value);
210 
211  in >> mValue;
212 
213  if (isnan(mValue))
214  {
215  if (!strcmp(value, "INF"))
216  mValue = std::numeric_limits<C_FLOAT64>::infinity();
217  else if (!strcmp(value, "-INF"))
218  mValue = - std::numeric_limits<C_FLOAT64>::infinity();
219  }
220 
221  return;
222 }
223 
225 
226 CCopasiXMLInterface::DBL::operator const C_FLOAT64 & () const
227 {return mValue;}
228 
229 std::ostream & operator << (std::ostream & os, const CCopasiXMLInterface::DBL & dbl)
230 {
231  os.precision(16);
232 
233  if (isnan(dbl.mValue))
234  os << "NaN";
235  else if (finite(dbl.mValue))
236  os << dbl.mValue;
237  else if (dbl.mValue > 0.0)
238  os << "INF";
239  else if (dbl.mValue < 0.0)
240  os << "-INF";
241 
242  return os;
243 }
244 
245 std::string CCopasiXMLInterface::utf8(const std::string & str)
246 {
247  std::ostringstream utf8;
248 
249  /* Based on RFC 2279.
250  Since every string within COPASI is treated as latin1 and input
251  is only obtained through QT and Expat which will provide latin1
252  encoded strings the below should suffice. */
253  size_t i, imax;
254 
255  for (i = 0, imax = str.length(); i < imax; i++)
256  {
257  const unsigned char Char = str[i];
258 
259  if (Char < 0x80)
260  utf8 << Char;
261  else
262  {
263  utf8 << (unsigned char)(0xc0 + ((Char >> 6) & 0x03));
264  utf8 << (unsigned char)(0x80 + (Char & 0x3f));
265  }
266  }
267 
268  return utf8.str();
269 }
270 
272  mpIstream(NULL),
273  mpOstream(NULL),
274  mIndent()
275 {}
276 
278 
279 bool CCopasiXMLInterface::load(const std::string & fileName,
280  const std::string & relativeTo)
281 {
282  mPWD = relativeTo;
283 
284  std::ifstream is(CLocaleString::fromUtf8(fileName).c_str());
285 
286  if (is.fail()) return false;
287 
288  return load(is, relativeTo);
289 }
290 
291 bool CCopasiXMLInterface::save(const std::string & fileName,
292  const std::string & relativeTo)
293 {
294  mPWD = relativeTo;
295 
296  std::ofstream os(CLocaleString::fromUtf8(fileName).c_str());
297 
298  if (os.fail()) return false;
299 
300  if (!save(os, relativeTo)) return false;
301 
302  return true;
303 }
304 
305 bool CCopasiXMLInterface::saveData(const std::string & data)
306 {
307  *mpOstream << mIndent << CCopasiXMLInterface::encode(data) << std::endl;
308 
309  return true;
310 }
311 
312 bool CCopasiXMLInterface::saveXhtml(const std::string & xhtml)
313 {
314  // if there is nothing to save bail
315  if (xhtml.empty())
316  return true;
317 
318  std::string::size_type start = xhtml.find_first_not_of("\x0a\x0d\t ");
319 
320  if (start != std::string::npos && xhtml[start] == '<')
321  {
322  std::string::size_type pos = xhtml.find('>');
323  std::string FirstElement = xhtml.substr(0, pos);
324 
325  if (FirstElement.find("xmlns=\"http://www.w3.org/1999/xhtml\"") == std::string::npos
326  && FirstElement.find("xmlns='http://www.w3.org/1999/xhtml'") == std::string::npos)
327  FirstElement += " xmlns=\"http://www.w3.org/1999/xhtml\"";
328 
329  *mpOstream << mIndent << FirstElement << xhtml.substr(pos) << std::endl;
330  }
331  else
332  {
333  saveData(xhtml);
334  }
335 
336  return true;
337 }
338 
339 bool CCopasiXMLInterface::saveElement(const std::string & name,
340  CXMLAttributeList & attributeList)
341 {
342  *mpOstream << mIndent << "<" << name;
343  *mpOstream << attributeList;
344  *mpOstream << "/>" << std::endl;
345 
346  return true;
347 }
348 
349 bool CCopasiXMLInterface::startSaveElement(const std::string & name)
350 {
351  *mpOstream << mIndent << "<" << name << ">" << std::endl;
352 
353  mIndent += " ";
354  return true;
355 }
356 
357 bool CCopasiXMLInterface::startSaveElement(const std::string & name,
358  CXMLAttributeList & attributeList)
359 {
360  *mpOstream << mIndent << "<" << name;
361  *mpOstream << attributeList;
362  *mpOstream << ">" << std::endl;
363 
364  mIndent += " ";
365  return true;
366 }
367 
368 bool CCopasiXMLInterface::endSaveElement(const std::string & name)
369 {
370  mIndent = mIndent.substr(0, mIndent.length() - 2);
371  *mpOstream << mIndent << "</" << name << ">" << std::endl;
372 
373  return true;
374 }
375 
377 {
378  bool success = true;
379 
380  CXMLAttributeList Attributes;
381  std::string File;
382 
383  Attributes.add("name", parameter.getObjectName());
384 
385  CCopasiParameter::Type Type = parameter.getType();
386  Attributes.add("type", CCopasiParameter::XMLType[Type]);
387 
388  switch (parameter.getType())
389  {
391  Attributes.add("value", * parameter.getValue().pDOUBLE);
392 
393  if (!saveElement("Parameter", Attributes)) success = false;
394 
395  break;
396 
398  Attributes.add("value", * parameter.getValue().pUDOUBLE);
399 
400  if (!saveElement("Parameter", Attributes)) success = false;
401 
402  break;
403 
405  Attributes.add("value", * parameter.getValue().pINT);
406 
407  if (!saveElement("Parameter", Attributes)) success = false;
408 
409  break;
410 
412  Attributes.add("value", * parameter.getValue().pUINT);
413 
414  if (!saveElement("Parameter", Attributes)) success = false;
415 
416  break;
417 
419  Attributes.add("value", * parameter.getValue().pBOOL);
420 
421  if (!saveElement("Parameter", Attributes)) success = false;
422 
423  break;
424 
426  Attributes.add("value", * parameter.getValue().pSTRING);
427 
428  if (!saveElement("Parameter", Attributes)) success = false;
429 
430  break;
431 
433  Attributes.add("value", * parameter.getValue().pKEY);
434 
435  if (!saveElement("Parameter", Attributes)) success = false;
436 
437  break;
438 
440  File = * parameter.getValue().pFILE;
441 
442  if (!CDirEntry::isRelativePath(File) &&
444  File = CDirEntry::fileName(File);
445 
446  Attributes.add("value", File);
447 
448  if (!saveElement("Parameter", Attributes)) success = false;
449 
450  break;
451 
453  Attributes.add("value", * parameter.getValue().pCN);
454 
455  if (!saveElement("Parameter", Attributes)) success = false;
456 
457  break;
458 
460 
461  if (!startSaveElement("ParameterText", Attributes)) success = false;
462 
463  if (!saveData(*parameter.getValue().pEXPRESSION)) success = false;
464 
465  if (!endSaveElement("ParameterText")) success = false;
466 
467  break;
468 
470  Attributes.skip(1);
471 
472  if (!startSaveElement("ParameterGroup", Attributes)) success = false;
473 
474  if (!saveParameterGroup(* parameter.getValue().pGROUP)) success = false;
475 
476  if (!endSaveElement("ParameterGroup")) success = false;
477 
478  break;
479 
481  default:
482  success = false;
483  break;
484  }
485 
486  return success;
487 }
488 
489 bool CCopasiXMLInterface::saveParameterGroup(const std::vector< CCopasiParameter * > & group)
490 {
491  bool success = true;
492 
493  std::vector< CCopasiParameter * >::const_iterator it = group.begin();
494  std::vector< CCopasiParameter * >::const_iterator end = group.end();
495 
496  for (; it != end; ++it)
497  if (!saveParameter(**it)) success = false;
498 
499  return success;
500 }
501 
503  mAttributeList(),
504  mSaveList()
505 {}
506 
508  mAttributeList(src.mAttributeList),
509  mSaveList(src.mSaveList)
510 {}
511 
513 
515 {
516  mAttributeList.clear();
517  mSaveList.clear();
518 
519  return true;
520 }
521 
522 size_t CXMLAttributeList::size() {return mAttributeList.size() / 2;}
523 
524 bool CXMLAttributeList::add(const std::string & name, const C_FLOAT64 & value)
525 {
526  return add(name,
527  (CCopasiXMLInterface::DBL) value,
529 }
530 
531 bool CXMLAttributeList::setName(const size_t & index,
532  const std::string & name)
533 {
534  mAttributeList[2 * index] = name;
535  return true;
536 }
537 
538 const std::string & CXMLAttributeList::getName(const size_t & index) const
539 {return mAttributeList[2 * index];}
540 
541 const std::string & CXMLAttributeList::getValue(const size_t & index) const
542 {return mAttributeList[2 * index + 1];}
543 
544 bool CXMLAttributeList::skip(const size_t & index)
545 {
546  mSaveList[index] = false;
547  return true;
548 }
549 
550 std::string CXMLAttributeList::getAttribute(const size_t & index) const
551 {
552  if (mSaveList[index])
553  return " " + mAttributeList[2 * index] + "=\"" + mAttributeList[2 * index + 1] + "\"";
554  else
555  return "";
556 }
557 
558 std::ostream &operator<<(std::ostream &os, const CXMLAttributeList & attr)
559 {
560  std::vector< std::string >::const_iterator itAttr = attr.mAttributeList.begin();
561  std::vector< bool >::const_iterator itSave = attr.mSaveList.begin();
562  std::vector< bool >::const_iterator endSave = attr.mSaveList.end();
563 
564  for (; itSave != endSave; ++itSave)
565  if (*itSave)
566  {
567  os << " " << *itAttr++;
568  os << "=\"" << *itAttr++ << "\"";
569  }
570  else
571  itAttr += 2;
572 
573  return os;
574 }
CCopasiVector< CSlider > * getSliderList()
void encodeATTRIBUTE(const char &chr, std::ostringstream &xml)
SCopasiXMLGUI(const std::string &name, const CCopasiContainer *pParent=NULL, const std::string &type="CN", const unsigned C_INT32 &flag=CCopasiObject::Container)
void encodeSTD(const char &chr, std::ostringstream &xml)
bool saveElement(const std::string &name, CXMLAttributeList &attributeList)
CCopasiVector< CSlider > * mpSliderList
const std::string & getObjectName() const
bool startSaveElement(const std::string &name)
static bool isRelativePath(const std::string &path)
Definition: CDirEntry.cpp:414
bool saveParameterGroup(const std::vector< CCopasiParameter * > &group)
bool saveData(const std::string &data)
std::vector< CCopasiParameter * > * pGROUP
const std::string & getValue(const size_t &index) const
bool saveXhtml(const std::string &xhtml)
static std::string fileName(const std::string &path)
Definition: CDirEntry.cpp:119
#define C_INT32
Definition: copasi.h:90
DBL(const C_FLOAT64 &value=0.0)
CRegisteredObjectName * pCN
const std::string & getName(const size_t &index) const
bool skip(const size_t &index)
const CCopasiParameter::Type & getType() const
bool setName(const size_t &index, const std::string &name)
virtual bool load(std::istream &is, const std::string &relativeTo)=0
std::string getAttribute(const size_t &index) const
const Value & getValue() const
unsigned C_INT32 * pUINT
void encodeNONE(const char &chr, std::ostringstream &xml)
void encodeCHARACTER(const char &chr, std::ostringstream &xml)
std::vector< std::string > mAttributeList
long int flag
Definition: f2c.h:52
#define C_FLOAT64
Definition: copasi.h:92
static std::string encode(const std::string &str, const EncodingType &type=standard)
bool endSaveElement(const std::string &name)
static const char * XMLType[]
() void(yyvaluep))
std::vector< bool > mSaveList
static CLocaleString fromUtf8(const std::string &utf8)
static std::string utf8(const std::string &str)
static bool makePathRelative(std::string &absolutePath, const std::string &relativeTo)
Definition: CDirEntry.cpp:434
virtual bool save(std::ostream &os, const std::string &relativeTo)=0
bool saveParameter(const CCopasiParameter &parameter)
#define min(a, b)
Definition: f2c.h:175
std::ostream & operator<<(std::ostream &os, const CCopasiXMLInterface::DBL &dbl)
bool add(const std::string &name, const CType &value)