FOX/ObjCryst++  1.10.X (development)
RefinableObj/IO.cpp
1 /* ObjCryst++ Object-Oriented Crystallographic Library
2  (c) 2000-2002 Vincent Favre-Nicolin vincefn@users.sourceforge.net
3  2000-2001 University of Geneva (Switzerland)
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 /*
20 * source file for generic XMLInput/XMLOutput in
21 *
22 */
23 
24 
25 #include <sstream>
26 #include "ObjCryst/RefinableObj/RefinableObj.h"
27 #include "ObjCryst/RefinableObj/IO.h"
28 
29 namespace ObjCryst
30 {
32 //
33 // XMLCrystTag
34 //
36 XMLCrystTag::XMLCrystTag():
37 mIsEndTag(false),mIsEmptyTag(false)
38 {}
39 
40 XMLCrystTag::XMLCrystTag(istream &is)
41 {
42  is >> *this;
43 }
44 
45 XMLCrystTag::XMLCrystTag(const string &tagName,
46  const bool isEndTag,
47  const bool isEmptyTag):
48 mName(tagName),mIsEndTag(isEndTag),mIsEmptyTag(isEmptyTag)
49 {}
50 
51 XMLCrystTag::~XMLCrystTag(){}
52 
53 const string& XMLCrystTag::GetName()const{return mName;}
54 const string& XMLCrystTag::GetClassName()const{static string str="XMLCrystTag";return str;}
55 
56 unsigned int XMLCrystTag::GetNbAttribute()const{return mvAttribute.size();}
57 
58 void XMLCrystTag::AddAttribute(const string &attName,const string &attValue)
59 {
60  VFN_DEBUG_ENTRY("XMLCrystTag::AddAttribute():"<<this->GetName(),4)
61  mvAttribute.push_back(make_pair(attName,attValue));
62  VFN_DEBUG_EXIT("XMLCrystTag::AddAttribute():"<<this->GetName(),4)
63 }
64 void XMLCrystTag::GetAttribute(const int attNum,string &attName,string &attValue)
65 {
66  attName=mvAttribute[attNum].first;
67  attValue=mvAttribute[attNum].second;
68 }
69 
70 const string& XMLCrystTag::GetAttributeName(const int attNum)const
71 {return mvAttribute[attNum].first;}
72 
73 const string& XMLCrystTag::GetAttributeValue(const int attNum)const
74 {return mvAttribute[attNum].second;}
75 
76 void XMLCrystTag::SetIsEndTag(const bool isEndTag){mIsEndTag=isEndTag;}
77 bool XMLCrystTag::IsEndTag()const{return mIsEndTag;}
78 void XMLCrystTag::SetIsEmptyTag(const bool isEmptyTag){mIsEmptyTag=isEmptyTag;}
79 bool XMLCrystTag::IsEmptyTag()const{return mIsEmptyTag;}
80 void XMLCrystTag::Print()const{cout<<*this;}
81 #ifdef __WX__CRYST__
82 WXCrystObj* XMLCrystTag::WXCreate(wxWindow *parent)
83 {
84  //:TODO:
85  //mpWXXMLCrystTag=new WXXMLCrystTag (parent,this);
86  return mpWXXMLCrystTag;
87 }
88 WXCrystObj* XMLCrystTag::WXGet()
89 {
90  return mpWXXMLCrystTag;
91 }
92 void XMLCrystTag::WXDelete()
93 {
94  if(0!=mpWXXMLCrystTag) delete mpWXXMLCrystTag;
95  mpWXXMLCrystTag=0;
96 }
97 void XMLCrystTag::WXNotifyDelete()
98 {
99  mpWXXMLCrystTag=0;
100 }
101 #endif
102 
103 ostream& operator<< (ostream& os, const XMLCrystTag&tag)
104 {
105  if(true==tag.mIsEndTag)
106  {
107  os <<"</"<<tag.mName<<">";
108  return os;
109  }
110  os <<"<"<<tag.mName;
111  for(unsigned int i=0;i<tag.GetNbAttribute();i++)
112  {
113  os<<" "<<tag.mvAttribute[i].first<<"=\""<<tag.mvAttribute[i].second<<"\"";
114  }
115  if(true==tag.mIsEmptyTag) os <<"/>";
116  else os <<">";
117  return os;
118 }
119 istream& operator>> (istream& is, XMLCrystTag &tag)
120 {
121  ios::fmtflags f=is.flags();
122  is.unsetf(ios::skipws);//skip whitespaces
123  tag.mIsEmptyTag=false;
124  tag.mIsEndTag=false;
125  char tmp;
126  is>>tmp;
127  while ((tmp!='<') && !(is.eof()) && !(is.fail()) )is>>tmp;
128  if(is.eof()) return is;
129  if(is.fail()) {cout<<"throw:"<<__FILE__<<":"<<__LINE__<<":"<<tag<<endl;throw ObjCrystException("XMLCrystTag::>> failed input");}
130  while ((tmp==' ')||(tmp=='<'))is>>tmp;
131 
132  if('/'==tmp)
133  {
134  tag.mIsEndTag=true;
135  while ((tmp==' ')||(tmp=='/'))is>>tmp;
136  }
137 
138  string str="";
139  do
140  {
141  str+=tmp;
142  is>>tmp;
143  VFN_DEBUG_MESSAGE(str,1);
144  if(is.fail()) {cout<<"throw:"<<__FILE__<<":"<<__LINE__<<":"<<tag<<endl;throw ObjCrystException("XMLCrystTag::>> failed input");}
145  } while ((tmp!=' ')&&(tmp!='>')&&(tmp!='/'));
146  tag.mName=str;
147 
148  string str2;
149  while(true)
150  {
151  while(tmp==' ')is>>tmp;
152  if(tmp=='>')
153  {
154  is.setf(f);
155  return is;
156  }
157  if(tmp=='/')
158  {
159  is>>tmp;
160  //if(tmp!='>') ; :TODO:
161  tag.mIsEmptyTag=true;
162  is.setf(f);
163  return is;
164  }
165  str="";
166  do {str+=tmp;is>>tmp;VFN_DEBUG_MESSAGE(str,1)} while ((tmp!=' ')&&(tmp!='='));
167  while(tmp!='"')is>>tmp;
168  str2="";
169  is>>tmp;
170  if(tmp!='"') do {str2+=tmp;is>>tmp;VFN_DEBUG_MESSAGE(str2,1)} while (tmp!='"');
171  is>>tmp;
172 
173  tag.AddAttribute(str,str2);
174  }
175 
176  is.setf(f);
177  return is;
178 }
180 //
181 // I/O RefinablePar
182 //
184 void RefinablePar::XMLOutput(ostream &os,const string &name,int indent)const
185 {
186  VFN_DEBUG_ENTRY("RefinablePar::XMLOutput():"<<this->GetName(),5)
187  XMLCrystTag tag("Par");
188  {
189  stringstream ss;
190  ss <<!(this->IsFixed());
191  tag.AddAttribute("Refined",ss.str());
192  }
193  {
194  stringstream ss;
195  ss <<this->IsLimited();
196  tag.AddAttribute("Limited",ss.str());
197  }
198  {
199  stringstream ss;
200  ss <<this->GetHumanMin();
201  tag.AddAttribute("Min",ss.str());
202  }
203  {
204  stringstream ss;
205  ss <<this->GetHumanMax();
206  tag.AddAttribute("Max",ss.str());
207  }
208  #if 0
209  {//Useless. Periodicity cannot be changed for a given parameter
210  stringstream ss;
211  ss <<this->IsPeriodic();
212  tag.AddAttribute("Periodic",ss.str());
213  }
214  #endif
215  //the name of the parameter is saved last to enhance readability of saved files
216  tag.AddAttribute("Name",name);
217 
218  for(int i=0;i<indent;i++) os << " " ;
219  os <<tag;
220  tag.SetIsEndTag(true);
221  os <<this->GetHumanValue()<<tag;
222  VFN_DEBUG_EXIT("RefinablePar::XMLOutput():"<<this->GetName(),5)
223 }
224 void RefinablePar::XMLOutput(ostream &os,int indent)const
225 {
226  this->XMLOutput(os,mName,indent);
227 }
228 
229 void RefinablePar::XMLInput(istream &is,const XMLCrystTag &tag)
230 {
231  VFN_DEBUG_ENTRY("RefinablePar::XMLInput():"<<this->GetName(),5)
232  for(unsigned int i=0;i<tag.GetNbAttribute();i++)
233  {
234  if("Name"==tag.GetAttributeName(i)) continue;//names must be set by the object
235  if("Refined"==tag.GetAttributeName(i))
236  {
237  bool b;
238  stringstream ss(tag.GetAttributeValue(i));
239  ss.imbue(std::locale::classic());
240  ss >>b;
241  this->SetIsFixed(!b);
242  continue;
243  }
244  if("Limited"==tag.GetAttributeName(i))
245  {
246  bool b;
247  stringstream ss(tag.GetAttributeValue(i));
248  ss.imbue(std::locale::classic());
249  ss >>b;
250  this->SetIsLimited(b);
251  continue;
252  }
253  if("Min"==tag.GetAttributeName(i))
254  {
255  REAL f;
256  stringstream ss(tag.GetAttributeValue(i));
257  ss.imbue(std::locale::classic());
258  ss >>f;
259  this->SetHumanMin(f);
260  continue;
261  }
262  if("Max"==tag.GetAttributeName(i))
263  {
264  REAL f;
265  stringstream ss(tag.GetAttributeValue(i));
266  ss.imbue(std::locale::classic());
267  ss >>f;
268  this->SetHumanMax(f);
269  continue;
270  }
271  if("Periodic"==tag.GetAttributeName(i))
272  {
273  bool b;
274  stringstream ss(tag.GetAttributeValue(i));
275  ss.imbue(std::locale::classic());
276  ss >>b;
277  this->SetIsPeriodic(b);
278  continue;
279  }
280  }
281  VFN_DEBUG_MESSAGE(tag, 10)
282  REAL f=InputFloat(is,'<');
283  if(ISNAN_OR_INF(f)) f=1.0;
284  this->SetHumanValue(f);
285  XMLCrystTag junk(is);//read end tag
286  VFN_DEBUG_MESSAGE(tag, 10)
287  VFN_DEBUG_EXIT("RefinablePar::XMLInput():"<<this->GetName(),5)
288 }
289 
291 //
292 // I/O RefObjOpt
293 //
295 void RefObjOpt::XMLOutput(ostream &os,int indent)const
296 {
297  VFN_DEBUG_ENTRY("RefObjOpt::XMLOutput():"<<this->GetName(),5)
298  XMLCrystTag tag("Option",false,true);
299  tag.AddAttribute("Name",this->GetName());
300  {
301  stringstream ss;
302  ss <<this->GetChoice();
303  tag.AddAttribute("Choice",ss.str());
304  }
305  tag.AddAttribute("ChoiceName",this->GetChoiceName(this->GetChoice()));
306 
307  for(int i=0;i<indent;i++) os << " " ;
308  os <<tag;
309 
310  VFN_DEBUG_EXIT("RefObjOpt::XMLOutput():"<<this->GetName(),5)
311 }
312 
313 void RefObjOpt::XMLInput(istream &is,const XMLCrystTag &tag)
314 {
315  VFN_DEBUG_ENTRY("RefObjOpt::XMLInput():"<<this->GetName(),5)
316  for(unsigned int i=0;i<tag.GetNbAttribute();i++)
317  {
318  if("Name"==tag.GetAttributeName(i)) continue;//names must be set by the object
319  if("ChoiceName"==tag.GetAttributeName(i)) continue;//just for info
320  if("Choice"==tag.GetAttributeName(i))
321  {
322  int b;
323  stringstream ss(tag.GetAttributeValue(i));
324  ss >>b;
325  this->SetChoice(b);
326  continue;
327  }
328  }
329  VFN_DEBUG_EXIT("RefObjOpt::XMLInput():"<<this->GetName(),5)
330 }
332 //
333 // I/O RefinableObj // Does nothing ! Should be purely virtual...
334 //
336 void RefinableObj::XMLOutput(ostream &os,int indent)const
337 {
338  VFN_DEBUG_MESSAGE("RefinableObj::XMLOutput():"<<this->GetName(),5)
339 }
340 
341 void RefinableObj::XMLInput(istream &is,const XMLCrystTag &tag)
342 {
343  VFN_DEBUG_MESSAGE("RefinableObj::XMLInput():"<<this->GetName(),5)
344 }
345 #if 0
346 void RefinableObj::XMLInputOld(istream &is,const IOCrystTag &tag)
347 {
348  VFN_DEBUG_MESSAGE("RefinableObj::XMLInput():"<<this->GetName(),5)
349 }
350 #endif
351 //
353 // OLD Functions & objects
354 //
356 #if 0
357 void IOCrystExtractNameSpace(istream &is,string &str)
358 {
359  ios::fmtflags f=is.flags();
360  is.unsetf(ios::skipws);//skip whitespaces
361  char tmp;
362  do {is>>tmp;} while (tmp==' ');
363  str="";
364  do {str+=tmp;is>>tmp;VFN_DEBUG_MESSAGE(str,1)} while ((tmp!=' ')&&(tmp!='>'));
365  if(tmp=='>') is.putback(tmp);
366  is.setf(f);
367 }
368 
369 void IOCrystExtractNameLine(istream &is,string &str)
370 {
371  ios::fmtflags f=is.flags();
372  is.setf(ios::skipws);//skip leading whitespaces
373  getline(is,str);
374  is.setf(f);
375 }
376 
377 void IOCrystExtractNameQuoted(istream &is,string &str)
378 {
379  char tmp;
380  do {is>>tmp;} while ((tmp!='\'')&&(tmp!='\"'));
381  str="";
382  is>>tmp;
383  if((tmp=='\'')||(tmp=='\"')) return;
384  ios::fmtflags f=is.flags();
385  is.unsetf(ios::skipws);//do not skip whitespaces
386  do {str+=tmp;is>>tmp;VFN_DEBUG_MESSAGE(str,1)} while ((tmp!='\'')&&(tmp!='\"'));
387  is.setf(f);
388 }
389 
390 void IOCrystXMLOutputNameQuoted(ostream &os,const string &str)
391 {
392  os << '\"' << str << '\"';
393 }
394 
396 //
397 // IOCrystTag
398 //
400 
401 IOCrystTag::IOCrystTag(const string& type,const string& name, const unsigned long version):
402 mTagType(type),mTagName(name),mTagVersion(version),mIsClosingTag(false)
403 {}
404 IOCrystTag::IOCrystTag(istream &is)
405 {
406  VFN_DEBUG_MESSAGE("IOCrystTag::IOCrystTag(istream &is)",2)
407  char tmp;
408  do
409  {
410  is>>tmp;
411  if(true==is.eof())
412  {
413  mTagVersion=0;//closing tag
414  mTagName="";
415  mTagType="";
416  mIsClosingTag=true;
417  return;
418  }
419  } while (tmp!='<');
420  IOCrystExtractNameSpace(is,mTagType);
421  VFN_DEBUG_MESSAGE("IOCrystTag::IOCrystTag(istream &is):TagType:"<<mTagType,1)
422  if(*(mTagType.c_str())=='\\')
423  {
424  mTagVersion=0;//closing tag
425  mTagName="";
426  mIsClosingTag=true;
427  }
428  else
429  {
430  IOCrystExtractNameQuoted(is,mTagName);
431  is >> mTagVersion;
432  mIsClosingTag=false;
433  }
434  do {is>>tmp;} while (tmp!='>');
435  VFN_DEBUG_MESSAGE("IOCrystTag::IOCrystTag(istream &is):End",2)
436 }
437 IOCrystTag::~IOCrystTag(){}
438 
439 bool IOCrystTag::operator==(const IOCrystTag& rhs)const
440 {
441  if( (rhs.GetType()==this->GetType()) && (rhs.GetName()==this->GetName())) return true;
442  return false;
443 }
444 void IOCrystTag::XMLInput(istream &is)
445 {
446  VFN_DEBUG_MESSAGE("IOCrystTag::XMLInput(istream &is)",2)
447  char tmp;
448  do {is>>tmp;} while ((tmp!='<') && (!is.eof()) );
449  if(is.eof()) return;
450  IOCrystExtractNameSpace(is,mTagType);
451  VFN_DEBUG_MESSAGE("IOCrystTag::XMLInput(istream &is):TagType:"<<mTagType,1)
452  if(*(mTagType.c_str())=='\\')
453  {
454  mTagVersion=0;//closing tag
455  mTagName="";
456  mIsClosingTag=true;
457  }
458  else
459  {
460  IOCrystExtractNameQuoted(is,mTagName);
461  is >> mTagVersion;
462  mIsClosingTag=false;
463  }
464  do {is>>tmp;} while (tmp!='>');
465  VFN_DEBUG_MESSAGE("IOCrystTag::XMLInput(istream &is):End",2)
466 }
467 const string &IOCrystTag::GetType() const{return mTagType;}
468 const string &IOCrystTag::GetName() const{return mTagName;}
469 unsigned long IOCrystTag::GetVersion()const{return mTagVersion;}
470 bool IOCrystTag::IsClosingTag()const{return mIsClosingTag;}
471 void IOCrystTag::Print() const
472 {
473  if(mIsClosingTag==true) cout <<"<"<<mTagType<<">"<<endl;
474  else
475  cout <<"<"<<mTagType<<" \""<<mTagName<<"\" "<<mTagVersion<<">"<<endl;
476 }
477 const string &IOCrystTag::GetClassName() const{return mTagType;}
478 #ifdef __WX__CRYST__
479 WXCrystObj* IOCrystTag::WXCreate(wxWindow *parent)
480 {
481  //mpWXIOCrystTag=new WXIOCrystTag (parent,this);
482  return mpWXIOCrystTag;
483 }
484 WXCrystObj* IOCrystTag::WXGet()
485 {
486  return mpWXIOCrystTag;
487 }
488 void IOCrystTag::WXDelete()
489 {
490  if(0!=mpWXIOCrystTag) delete mpWXIOCrystTag;
491  mpWXIOCrystTag=0;
492 }
493 void IOCrystTag::WXNotifyDelete()
494 {
495  mpWXIOCrystTag=0;
496 }
497 #endif
498 #endif
499 
500 } //namespace
bool ISNAN_OR_INF(REAL r)
Test if the value is a NaN.
Definition: ObjCryst/IO.cpp:97
friend istream & operator>>(istream &, XMLCrystTag &)
Input an XMLCrystTag from a stream.
void XMLInput(istream &is, const XMLCrystTag &tag)
XMLInput From stream.
void XMLInput(istream &is, const XMLCrystTag &tag)
XMLInput From stream.
float InputFloat(istream &is, const char endchar)
Safely read a floating-point value from a stream.
Definition: ObjCryst/IO.cpp:68
void XMLOutput(ostream &os, int indent=0) const
XMLOutput to stream in well-formed XML.
virtual void XMLOutput(ostream &os, int indent=0) const
Output to stream in well-formed XML.
friend ostream & operator<<(ostream &, const XMLCrystTag &)
Output an XMLCrystTag to a stream.
Exception class for ObjCryst++ library.
Definition: General.h:119
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
Definition: Atom.cpp:47
class to input or output a well-formatted xml beginning or ending tag.
void XMLOutput(ostream &os, const string &name, int indent=0) const
XMLOutput to stream in well-formed XML.
virtual void XMLInput(istream &is, const XMLCrystTag &tag)
Input From stream.