ARTS  2.3.1285(git:92a29ea9-dirty)
xml_io.cc
Go to the documentation of this file.
1 /* Copyright (C) 2002-2012 Oliver Lemke <olemke@core-dump.info>
2 
3  This program is free software; you can redistribute it and/or modify it
4  under the terms of the GNU General Public License as published by the
5  Free Software Foundation; either version 2, or (at your option) any
6  later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16  USA. */
17 
19 // File description
21 
30 #include "xml_io.h"
31 #include "arts.h"
32 #include "bifstream.h"
33 #include "bofstream.h"
34 #include "file.h"
35 #include "parameters.h"
36 #include "xml_io_private.h"
37 #include "xml_io_types.h"
38 
39 #ifdef ENABLE_ZLIB
40 #include "gzstream.h"
41 #endif
42 
44 // ArtsXMLTag implementation
46 
48 
54 void ArtsXMLTag::check_name(const String& expected_name) {
55  if (name != expected_name)
56  xml_parse_error("Tag <" + expected_name + "> expected but <" + name +
57  "> found.");
58 }
59 
61 
66 void ArtsXMLTag::add_attribute(const String& aname, const String& value) {
67  XMLAttribute attr;
68 
69  attr.name = aname;
70  attr.value = value;
71  attribs.push_back(attr);
72 }
73 
75 
80 void ArtsXMLTag::add_attribute(const String& aname, const Index& value) {
81  ostringstream v;
82 
83  v << value;
84  add_attribute(aname, v.str());
85 }
86 
87 void ArtsXMLTag::add_attribute(const String& aname, const Numeric& value) {
88  ostringstream v;
89 
90  v << value;
91  add_attribute(aname, v.str());
92 }
93 
94 void ArtsXMLTag::add_attribute(const String& aname, const std::vector<QuantumNumberType>& value) {
95  ostringstream v;
96 
97  if(value.size() == 0)
98  v << "";
99  else {
100  for(size_t i=0; i<value.size()-1; i++)
101  v << quantumnumbertype2string(value[i]) << " ";
102  v << quantumnumbertype2string(value.back());
103  }
104 
105  add_attribute(aname, v.str());
106 }
107 
108 void ArtsXMLTag::add_attribute(const String& aname, const ArrayOfSpeciesTag& value, const bool self, const bool bath) {
109  ostringstream v;
110 
111  if(self)
112  v << LineShape::self_broadening;
113  for(Index i=Index(self); i<value.nelem()-Index(bath); i++)
114  v << ' ' << value[i].SpeciesNameMain();
115  if(bath) {
116  v << ' ' << LineShape::bath_broadening;
117  }
118 
119  add_attribute(aname, v.str());
120 }
121 
123 
131 void ArtsXMLTag::check_attribute(const String& aname, const String& value) {
132  String actual_value;
133 
134  get_attribute_value(aname, actual_value);
135 
136  if (actual_value == "*not found*") {
137  xml_parse_error("Required attribute " + aname + " does not exist");
138  } else if (actual_value != value) {
139  xml_parse_error("Attribute " + aname + " has value \"" + actual_value +
140  "\" but \"" + value + "\" was expected.");
141  }
142 }
143 
145 
153 void ArtsXMLTag::get_attribute_value(const String& aname, String& value) {
154  value = "";
155 
157  while (it != attribs.end()) {
158  if (it->name == aname) {
159  value = it->value;
160  it = attribs.end();
161  } else {
162  it++;
163  }
164  }
165 }
166 
168 
176 void ArtsXMLTag::get_attribute_value(const String& aname, Index& value) {
177  String attribute_value;
178  istringstream strstr("");
179 
180  get_attribute_value(aname, attribute_value);
181  strstr.str(attribute_value);
182  strstr >> value;
183  if (strstr.fail()) {
184  xml_parse_error("Error while parsing value of " + aname + " from <" + name +
185  ">");
186  }
187 }
188 
189 void ArtsXMLTag::get_attribute_value(const String& aname, Numeric& value) {
190  String attribute_value;
191  istringstream strstr("");
192 
193  get_attribute_value(aname, attribute_value);
194  strstr.str(attribute_value);
195  strstr >> value;
196  if (strstr.fail()) {
197  xml_parse_error("Error while parsing value of " + aname + " from <" + name +
198  ">");
199  }
200 }
201 
203  String attribute_value;
204 
205  get_attribute_value(aname, attribute_value);
206  value = SpeciesTag(attribute_value);
207 }
208 
209 void ArtsXMLTag::get_attribute_value(const String& aname, ArrayOfSpeciesTag& value, bool& self, bool& bath) {
210  value.resize(0);
211  self=false;
212  bath=false;
213 
214  String attribute_value;
215  istringstream strstr("");
216 
217  get_attribute_value(aname, attribute_value);
218  if (attribute_value.nelem() == 0) return;
219 
220  strstr.str(attribute_value);
221  String val;
222 
223  while(not strstr.eof()) {
224  strstr >> val;
225  if (strstr.fail()) {
226  xml_parse_error("Error while parsing value of " + aname + " from <" + name +
227  ">");
228  }
229 
230  if(val == LineShape::self_broadening) {
231  value.push_back(SpeciesTag());
232  self = true;
233  }
234  else if(val == LineShape::bath_broadening) {
235  value.push_back(SpeciesTag());
236  bath = true;
237  }
238  else
239  value.push_back(SpeciesTag(val));
240  }
241 }
242 
243 void ArtsXMLTag::get_attribute_value(const String& aname, std::vector<QuantumNumberType>& value) {
244  value.resize(0);
245 
246  String attribute_value;
247  istringstream strstr("");
248 
249  get_attribute_value(aname, attribute_value);
250  if (attribute_value.nelem() == 0) return;
251 
252  strstr.str(attribute_value);
253  String val;
254 
255  while(not strstr.eof()) {
256  strstr >> val;
257  if (strstr.fail()) {
258  xml_parse_error("Error while parsing value of " + aname + " from <" + name +
259  ">");
260  }
261  value.push_back(string2quantumnumbertype(val));
262  }
263 }
264 
266  String attribute_value;
267  istringstream strstr("");
268 
269  get_attribute_value(aname, attribute_value);
270 
271  strstr.str(attribute_value);
272  String key;
273  Rational r;
274 
275  strstr >> key;
276  while (strstr) {
277  strstr >> r;
278  value.Set(key, r);
279  strstr >> key;
280  }
281 }
282 
284 
289 void ArtsXMLTag::read_from_stream(istream& is) {
290  CREATE_OUT3;
291 
292  String token;
293  stringbuf tag;
294  istringstream sstr("");
295  XMLAttribute attr;
296  char ch = 0;
297 
298  attribs.clear();
299 
300  while (is.good() && isspace(is.peek())) {
301  is.get();
302  }
303 
304  is >> ch;
305 
306  if (ch != '<') {
307  is >> token;
308  token = ch + token;
309 
310  xml_parse_error("'<' expected but " + token + " found.");
311  }
312 
313  is.get(tag, '>');
314 
315  // Hit EOF while looking for '>'
316  if (is.bad() || is.eof()) {
317  xml_parse_error("Unexpected end of file while looking for '>'");
318  }
319 
320  if (is.get() != '>') {
321  xml_parse_error("Closing > not found in tag: " + tag.str());
322  }
323 
324  sstr.str(tag.str() + '>');
325  out3 << "Read: " << sstr.str() << '\n';
326 
327  sstr >> name;
328 
329  if (name[name.length() - 1] == '>') {
330  // Because closin > was found, the tag for sure has no
331  // attributes, set token to ">" to skip reading of attributes
332  name.erase(name.length() - 1, 1);
333  token = ">";
334  } else {
335  // Tag may have attributes, so read next token
336  sstr >> token;
337  }
338  out3 << "Name: " << name << '\n';
339 
340  //extract attributes
341  while (token != ">") {
342  String::size_type pos;
343 
344  pos = token.find("=", 0);
345  if (pos == String::npos) {
346  xml_parse_error("Syntax error in tag: " + tag.str());
347  }
348 
349  attr.name = token.substr(0, pos);
350  token.erase(0, pos + 1);
351 
352  if (token[0] != '\"') {
353  xml_parse_error("Missing \" in tag: " + tag.str());
354  }
355 
356  while ((pos = token.find("\"", 1)) == (String::size_type)String::npos &&
357  token != ">") {
358  String ntoken;
359  sstr >> ntoken;
360  if (!ntoken.length()) break;
361  token += " " + ntoken;
362  }
363 
364  if (pos == (String::size_type)String::npos) {
365  xml_parse_error("Missing \" in tag: " + sstr.str());
366  }
367 
368  if (pos == 1)
369  attr.value = "";
370  else
371  attr.value = token.substr(1, pos - 1);
372 
373  attribs.push_back(attr);
374 
375  out3 << "Attr: " << attr.name << '\n';
376  out3 << "Value: " << attr.value << '\n';
377 
378  if (token[token.length() - 1] == '>') {
379  token = ">";
380  } else {
381  sstr >> token;
382  }
383  }
384 
385  out3 << '\n';
386 
387  // Skip comments
388  if (name == "comment") {
389  is.get(tag, '<');
390 
391  // Hit EOF while looking for '<'
392  if (is.bad() || is.eof()) {
394  "Unexpected end of file while looking for "
395  "comment tag");
396  }
397 
398  read_from_stream(is);
399  check_name("/comment");
400  read_from_stream(is);
401  }
402 }
403 
405 
410 void ArtsXMLTag::write_to_stream(ostream& os) {
411  os << "<" << name;
412 
414 
415  while (it != attribs.end()) {
416  os << ' ' << it->name << "=\"" << it->value << '\"';
417  it++;
418  }
419 
420  os << ">";
421 }
422 
424 // Default file name
426 
428 
434 void filename_xml(String& filename, const String& varname) {
435  if ("" == filename) {
436  extern const String out_basename;
437  filename = out_basename + "." + varname + ".xml";
438  }
439 }
440 
442 
451  const Index& file_index,
452  const String& varname,
453  const Index& digits) {
454  if ("" == filename) {
455  extern const String out_basename;
456  ostringstream os;
457  os << out_basename << "." << varname << "." << std::setw((int)digits)
458  << std::setfill('0') << file_index << ".xml";
459  filename = os.str();
460  } else {
461  ostringstream os;
462  os << filename << "." << std::setw((int)digits) << std::setfill('0')
463  << file_index << ".xml";
464  filename = os.str();
465  }
466 }
467 
469 // Functions to open and read XML files
471 
473 
479 void xml_open_output_file(ofstream& file, const String& name) {
480  // Tell the stream that it should throw exceptions.
481  // Badbit means that the entire stream is corrupted, failbit means
482  // that the last operation has failed, but the stream is still
483  // valid. We don't want either to happen!
484  // FIXME: This does not yet work in egcs-2.91.66, try again later.
485  file.exceptions(ios::badbit | ios::failbit);
486 
487  // c_str explicitly converts to c String.
488  try {
489  file.open(name.c_str());
490  } catch (const std::exception&) {
491  ostringstream os;
492  os << "Cannot open output file: " << name << '\n'
493  << "Maybe you don't have write access "
494  << "to the directory or the file?";
495  throw runtime_error(os.str());
496  }
497 
498  // See if the file is ok.
499  // FIXME: This should not be necessary anymore in the future, when
500  // g++ stream exceptions work properly. (In that case we would not
501  // get here if there really was a problem, because of the exception
502  // thrown by open().)
503  if (!file) {
504  ostringstream os;
505  os << "Cannot open output file: " << name << '\n'
506  << "Maybe you don't have write access "
507  << "to the directory or the file?";
508  throw runtime_error(os.str());
509  }
510 }
511 
512 #ifdef ENABLE_ZLIB
513 
515 
521 void xml_open_output_file(ogzstream& file, const String& name) {
522  // Tell the stream that it should throw exceptions.
523  // Badbit means that the entire stream is corrupted, failbit means
524  // that the last operation has failed, but the stream is still
525  // valid. We don't want either to happen!
526  // FIXME: This does not yet work in egcs-2.91.66, try again later.
527  file.exceptions(ios::badbit | ios::failbit);
528 
529  // c_str explicitly converts to c String.
530  String nname = name;
531 
532  if (nname.nelem() < 3 || nname.substr(nname.length() - 3, 3) != ".gz") {
533  nname += ".gz";
534  }
535 
536  try {
537  file.open(nname.c_str());
538  } catch (const ios::failure&) {
539  ostringstream os;
540  os << "Cannot open output file: " << nname << '\n'
541  << "Maybe you don't have write access "
542  << "to the directory or the file?";
543  throw runtime_error(os.str());
544  }
545 
546  // See if the file is ok.
547  // FIXME: This should not be necessary anymore in the future, when
548  // g++ stream exceptions work properly. (In that case we would not
549  // get here if there really was a problem, because of the exception
550  // thrown by open().)
551  if (!file) {
552  ostringstream os;
553  os << "Cannot open output file: " << nname << '\n'
554  << "Maybe you don't have write access "
555  << "to the directory or the file?";
556  throw runtime_error(os.str());
557  }
558 }
559 
560 #endif /* ENABLE_ZLIB */
561 
563 
569 void xml_open_input_file(ifstream& ifs,
570  const String& name,
571  const Verbosity& verbosity) {
572  CREATE_OUT3;
573 
574  // Tell the stream that it should throw exceptions.
575  // Badbit means that the entire stream is corrupted.
576  // On the other hand, end of file will not lead to an exception, you
577  // have to check this manually!
578  ifs.exceptions(ios::badbit);
579 
580  // c_str explicitly converts to c String.
581  try {
582  ifs.open(name.c_str());
583  } catch (const ios::failure&) {
584  ostringstream os;
585  os << "Cannot open input file: " << name << '\n'
586  << "Maybe the file does not exist?";
587  throw runtime_error(os.str());
588  }
589 
590  // See if the file is ok.
591  // FIXME: This should not be necessary anymore in the future, when
592  // g++ stream exceptions work properly.
593  if (!ifs) {
594  ostringstream os;
595  os << "Cannot open input file: " << name << '\n'
596  << "Maybe the file does not exist?";
597  throw runtime_error(os.str());
598  }
599 
600  out3 << "- Reading input file " << name << "\n";
601 }
602 
603 #ifdef ENABLE_ZLIB
604 
606 
613  const String& name,
614  const Verbosity& verbosity) {
615  CREATE_OUT3;
616 
617  // Tell the stream that it should throw exceptions.
618  // Badbit means that the entire stream is corrupted.
619  // On the other hand, end of file will not lead to an exception, you
620  // have to check this manually!
621  ifs.exceptions(ios::badbit);
622 
623  // c_str explicitly converts to c String.
624  try {
625  ifs.open(name.c_str());
626  } catch (const ios::failure&) {
627  ostringstream os;
628  os << "Cannot open input file: " << name << '\n'
629  << "Maybe the file does not exist?";
630  throw runtime_error(os.str());
631  }
632 
633  // See if the file is ok.
634  // FIXME: This should not be necessary anymore in the future, when
635  // g++ stream exceptions work properly.
636  if (!ifs) {
637  ostringstream os;
638  os << "Cannot open input file: " << name << '\n'
639  << "Maybe the file does not exist?";
640  throw runtime_error(os.str());
641  }
642 
643  out3 << "- Reading input file " << name << "\n";
644 }
645 
646 #endif /* ENABLE_ZLIB */
647 
648 void xml_find_and_open_input_file(std::shared_ptr<istream>& ifs,
649  const String& filename,
650  const Verbosity& verbosity) {
651  CREATE_OUT2;
652 
653  String xml_file = filename;
654  find_xml_file(xml_file, verbosity);
655  out2 << " Reading " << xml_file << '\n';
656 
657  // Open input stream:
658  if (xml_file.substr(xml_file.length() - 3, 3) == ".gz")
659 #ifdef ENABLE_ZLIB
660  {
661  ifs = std::shared_ptr<istream>(new igzstream());
663  *(std::static_pointer_cast<igzstream>(ifs)), xml_file, verbosity);
664  }
665 #else
666  {
667  throw runtime_error(
668  "This arts version was compiled without zlib support.\n"
669  "Thus zipped xml files cannot be read.");
670  }
671 #endif /* ENABLE_ZLIB */
672  else {
673  ifs = shared_ptr<istream>(new ifstream());
675  *(std::static_pointer_cast<ifstream>(ifs)), xml_file, verbosity);
676  }
677 }
678 
680 // General XML functions (file header, start root tag, end root tag)
682 
684 
690 void xml_parse_error(const String& str_error) {
691  ostringstream os;
692  os << "XML parse error: " << str_error << '\n'
693  << "Check syntax of XML file\n";
694  throw runtime_error(os.str());
695 }
696 
698 
705 void xml_data_parse_error(ArtsXMLTag& tag, String str_error) {
706  ostringstream os;
707  os << "XML data parse error: Error reading ";
708  tag.write_to_stream(os);
709  os << str_error << "\n"
710  << "Check syntax of XML file. A possible cause is that the file "
711  << "contains NaN or Inf values.\n";
712  throw runtime_error(os.str());
713 }
714 
716 
726  FileType& ftype,
727  NumericType& ntype,
728  EndianType& etype,
729  const Verbosity& verbosity) {
730  char str[6];
731  stringbuf strbuf;
732  ArtsXMLTag tag(verbosity);
733  String strtype;
734 
735  while (!is.fail() && isspace(is.peek())) is.get();
736 
737  is.get(str, 6, ' ');
738 
739  if (string(str) != "<?xml") {
741  "Input file is not a valid xml file "
742  "(<?xml not found)");
743  }
744 
745  is.get(strbuf, '>');
746  is.get();
747 
748  if (is.fail()) {
749  xml_parse_error("Input file is not a valid xml file");
750  }
751 
752  tag.read_from_stream(is);
753  tag.check_name("arts");
754 
755  // Check file format
756  tag.get_attribute_value("format", strtype);
757  if (strtype == "binary") {
758  ftype = FILE_TYPE_BINARY;
759  } else {
760  ftype = FILE_TYPE_ASCII;
761  }
762 
763  // Check endian type
764  tag.get_attribute_value("endian_type", strtype);
765  if (strtype == "little") {
766  etype = ENDIAN_TYPE_LITTLE;
767  }
768  if (strtype == "big") {
769  etype = ENDIAN_TYPE_BIG;
770  }
771  if (strtype == "") {
772  /* out1 << " Warning: Endian type not specified in XML file, "
773  << "assuming little endian (PC)\n";*/
774  etype = ENDIAN_TYPE_LITTLE;
775  } else {
776  ostringstream os;
777  os << " Error: Unknown endian type \"" << strtype
778  << "\" specified in XML file.\n";
779  throw runtime_error(os.str());
780  }
781 
782  // Check numeric type
783  tag.get_attribute_value("numeric_type", strtype);
784  if (strtype == "float") {
785  ntype = NUMERIC_TYPE_FLOAT;
786  } else if (strtype == "double") {
787  ntype = NUMERIC_TYPE_DOUBLE;
788  } else if (strtype == "") {
789  /* out1 << " Warning: Numeric type not specified in XML file, "
790  << "assuming double\n";*/
791  ntype = NUMERIC_TYPE_DOUBLE;
792  } else {
793  ostringstream os;
794  os << " Error: Unknown numeric type \"" << strtype
795  << "\" specified in XML file.\n";
796  throw runtime_error(os.str());
797  }
798 }
799 
801 
806 void xml_read_footer_from_stream(istream& is, const Verbosity& verbosity) {
807  ArtsXMLTag tag(verbosity);
808 
809  tag.read_from_stream(is);
810  tag.check_name("/arts");
811 }
812 
814 
818 void xml_write_header_to_stream(ostream& os,
819  FileType ftype,
820  const Verbosity& verbosity) {
821  ArtsXMLTag tag(verbosity);
822 
823  os << "<?xml version=\"1.0\"?>" << '\n';
824 
825  tag.set_name("arts");
826  switch (ftype) {
827  case FILE_TYPE_ASCII:
829  tag.add_attribute("format", "ascii");
830  break;
831  case FILE_TYPE_BINARY:
832  tag.add_attribute("format", "binary");
833  break;
834  }
835 
836  tag.add_attribute("version", "1");
837 
838  tag.write_to_stream(os);
839 
840  os << '\n';
841 }
842 
844 
847 void xml_write_footer_to_stream(ostream& os, const Verbosity& verbosity) {
848  ArtsXMLTag tag(verbosity);
849 
850  tag.set_name("/arts");
851  tag.write_to_stream(os);
852 
853  os << endl;
854 }
855 
856 void xml_set_stream_precision(ostream& os) {
857  // Determine the precision, depending on whether Numeric is double
858  // or float:
859  int precision;
860 #ifdef USE_FLOAT
861  precision = FLT_DIG;
862 #else
863 #ifdef USE_DOUBLE
864  precision = DBL_DIG;
865 #else
866 #error Numeric must be double or float
867 #endif
868 #endif
869 
870  os << setprecision(precision);
871 }
872 
874 void parse_xml_tag_content_as_string(std::istream& is_xml, String& content) {
875  char dummy;
876 
877  content = "";
878  dummy = (char)is_xml.peek();
879  while (is_xml && dummy != '<') {
880  is_xml.get(dummy);
881  content += dummy;
882  dummy = (char)is_xml.peek();
883  }
884 
885  if (!is_xml) throw std::runtime_error("Unexpected end of file.");
886 }
887 
889 // Generic IO routines for XML files
891 
893 
900 template <typename T>
901 void xml_read_from_file(const String& filename,
902  T& type,
903  const Verbosity& verbosity) {
904  CREATE_OUT2;
905 
906  String xml_file = filename;
907  find_xml_file(xml_file, verbosity);
908  out2 << " Reading " + xml_file + '\n';
909 
910  // Open input stream:
911  istream* ifs;
912  if (xml_file.nelem() > 2 &&
913  xml_file.substr(xml_file.length() - 3, 3) == ".gz")
914 #ifdef ENABLE_ZLIB
915  {
916  ifs = new igzstream();
917  xml_open_input_file(*(igzstream*)ifs, xml_file, verbosity);
918  }
919 #else
920  {
921  throw runtime_error(
922  "This arts version was compiled without zlib support.\n"
923  "Thus zipped xml files cannot be read.");
924  }
925 #endif /* ENABLE_ZLIB */
926  else {
927  ifs = new ifstream();
928  xml_open_input_file(*(ifstream*)ifs, xml_file, verbosity);
929  }
930 
931  // No need to check for error, because xml_open_input_file throws a
932  // runtime_error with an appropriate error message.
933 
934  // Read the matrix from the stream. Here we catch the exception,
935  // because then we can issue a nicer error message that includes the
936  // filename.
937  try {
938  FileType ftype;
939  NumericType ntype;
940  EndianType etype;
941 
942  xml_read_header_from_stream(*ifs, ftype, ntype, etype, verbosity);
943  if (ftype == FILE_TYPE_ASCII) {
944  xml_read_from_stream(*ifs, type, NULL, verbosity);
945  } else {
946  String bfilename = xml_file + ".bin";
947  bifstream bifs(bfilename.c_str());
948  xml_read_from_stream(*ifs, type, &bifs, verbosity);
949  }
950  xml_read_footer_from_stream(*ifs, verbosity);
951  } catch (const std::runtime_error& e) {
952  delete ifs;
953  ostringstream os;
954  os << "Error reading file: " << xml_file << '\n' << e.what();
955  throw runtime_error(os.str());
956  }
957 
958  delete ifs;
959 }
960 
962 
971 template <typename T>
972 void xml_write_to_file(const String& filename,
973  const T& type,
974  const FileType ftype,
975  const Index no_clobber,
976  const Verbosity& verbosity) {
977  CREATE_OUT2;
978 
979  String efilename = add_basedir(filename);
980 
981  ostream* ofs;
982 
983  if (no_clobber) make_filename_unique(efilename, ".xml");
984 
985  out2 << " Writing " << efilename << '\n';
986  if (ftype == FILE_TYPE_ZIPPED_ASCII)
987 #ifdef ENABLE_ZLIB
988  {
989  ofs = new ogzstream();
990  xml_open_output_file(*(ogzstream*)ofs, efilename);
991  }
992 #else
993  {
994  throw runtime_error(
995  "This arts version was compiled without zlib support.\n"
996  "Thus zipped xml files cannot be written.");
997  }
998 #endif /* ENABLE_ZLIB */
999  else {
1000  ofs = new ofstream();
1001  xml_open_output_file(*(ofstream*)ofs, efilename);
1002  }
1003 
1004  try {
1005  xml_write_header_to_stream(*ofs, ftype, verbosity);
1006  if (ftype == FILE_TYPE_ASCII || ftype == FILE_TYPE_ZIPPED_ASCII) {
1007  xml_write_to_stream(*ofs, type, NULL, "", verbosity);
1008  } else {
1009  String bfilename = efilename + ".bin";
1010  bofstream bofs(bfilename.c_str());
1011  xml_write_to_stream(*ofs, type, &bofs, "", verbosity);
1012  }
1013 
1014  xml_write_footer_to_stream(*ofs, verbosity);
1015  } catch (const std::runtime_error& e) {
1016  delete ofs;
1017  ostringstream os;
1018  os << "Error writing file: " << efilename << '\n' << e.what();
1019  throw runtime_error(os.str());
1020  }
1021 
1022  delete ofs;
1023 }
1024 
1025 // We can't do the instantiation at the beginning of this file, because the
1026 // implementation of xml_write_to_file and xml_read_from_file have to be known.
1027 
1028 #include "xml_io_instantiation.h"
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
#define precision
Definition: logic.cc:43
void add_attribute(const String &aname, const String &value)
Adds a String attribute to tag.
Definition: xml_io.cc:66
void xml_write_header_to_stream(ostream &os, FileType ftype, const Verbosity &verbosity)
Writes XML header and root tag.
Definition: xml_io.cc:818
This file contains template instantiations to handle XML data files.
void xml_write_to_stream(ostream &os_xml, const ArrayOfAgenda &aa, bofstream *pbofs, const String &name, const Verbosity &)
Writes ArrayOfAgenda to XML output stream.
Index nelem() const
Number of elements.
Definition: array.h:195
void xml_read_footer_from_stream(istream &is, const Verbosity &verbosity)
Reads closing root tag.
Definition: xml_io.cc:806
void read_from_stream(istream &is)
Reads next XML tag.
Definition: xml_io.cc:289
void filename_xml_with_index(String &filename, const Index &file_index, const String &varname, const Index &digits)
Gives the default filename, with file index, for the XML formats.
Definition: xml_io.cc:450
void xml_find_and_open_input_file(std::shared_ptr< istream > &ifs, const String &filename, const Verbosity &verbosity)
Open plain or zipped xml file.
Definition: xml_io.cc:648
void xml_read_header_from_stream(istream &is, FileType &ftype, NumericType &ntype, EndianType &etype, const Verbosity &verbosity)
Reads XML header and root tag.
Definition: xml_io.cc:725
XML attribute class.
String out_basename
The basename for the report file and for all other output files.
Definition: messages.cc:42
void open(const char *name, int gz_open_mode=std::ios::in)
Definition: gzstream.h:100
QuantumNumberType string2quantumnumbertype(const String &s)
Definition: quantum.h:101
This file contains private function declarations and template instantiation to handle XML data files...
This file contains basic functions to handle XML data files.
This file contains basic functions to handle ASCII files.
void find_xml_file(String &filename, const Verbosity &verbosity)
Find an xml file.
Definition: file.cc:414
void xml_open_output_file(ofstream &file, const String &name)
Open file for XML output.
Definition: xml_io.cc:479
FileType
Definition: xml_io.h:37
void xml_parse_error(const String &str_error)
Throws XML parser runtime error.
Definition: xml_io.cc:690
String quantumnumbertype2string(QuantumNumberType s)
Definition: quantum.h:162
const Verbosity & verbosity
The ARTS XML tag class.
The global header file for ARTS.
void xml_open_input_file(ifstream &ifs, const String &name, const Verbosity &verbosity)
Open file for XML input.
Definition: xml_io.cc:569
void xml_set_stream_precision(ostream &os)
Definition: xml_io.cc:856
_CS_string_type str() const
Definition: sstream.h:491
void set_name(const String &new_name)
Binary output file stream class.
Definition: bifstream.h:42
Implements rational numbers to work with other ARTS types.
Definition: rational.h:54
This file contains the class declaration of bifstream.
This file contains the class declaration of bofstream.
A tag group can consist of the sum of several of these.
void parse_xml_tag_content_as_string(std::istream &is_xml, String &content)
Get the content of an xml tag as a string.
Definition: xml_io.cc:874
void xml_read_from_file(const String &filename, T &type, const Verbosity &verbosity)
Reads data from XML file.
Definition: xml_io.cc:901
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
void get_attribute_value(const String &aname, String &value)
Returns value of attribute as String.
Definition: xml_io.cc:153
Index nelem() const
Number of elements.
Definition: mystring.h:246
void xml_write_footer_to_stream(ostream &os, const Verbosity &verbosity)
Write closing root tag.
Definition: xml_io.cc:847
void Set(Index qn, Rational r)
Set quantum number at position.
Definition: quantum.h:310
Container class for Quantum Numbers.
Definition: quantum.h:222
void check_name(const String &expected_name)
Check tag name.
Definition: xml_io.cc:54
void xml_read_from_stream(istream &is_xml, ArrayOfAgenda &aa, bifstream *pbifs, const Verbosity &)
Reads ArrayOfAgenda from XML input stream.
void open(const char *name, int gz_open_mode=std::ios::out)
Definition: gzstream.h:111
basic_string< _CS_cT, _CS_traits, _CS_alloc > str() const
void check_attribute(const String &aname, const String &value)
Checks whether attribute has the expected value.
Definition: xml_io.cc:131
Array< XMLAttribute > attribs
EndianType
Definition: xml_io.h:44
void filename_xml(String &filename, const String &varname)
Gives the default filename for the XML formats.
Definition: xml_io.cc:434
Binary output file stream class.
Definition: bofstream.h:42
String add_basedir(const String &path)
Definition: file.cc:499
void make_filename_unique(String &filename, const String &extension)
Make filename unique.
Definition: file.cc:571
#define CREATE_OUT3
Definition: messages.h:207
static const Index npos
Define npos:
Definition: mystring.h:106
NumericType
Definition: xml_io.h:43
This file contains header information for the dealing with command line parameters.
#define CREATE_OUT2
Definition: messages.h:206
void xml_write_to_file(const String &filename, const T &type, const FileType ftype, const Index no_clobber, const Verbosity &verbosity)
Write data to XML file.
Definition: xml_io.cc:972
This file contains private function declarations and template instantiation to handle XML data files...
void xml_data_parse_error(ArtsXMLTag &tag, String str_error)
Throws XML parser runtime error.
Definition: xml_io.cc:705
void write_to_stream(ostream &os)
Write XML tag.
Definition: xml_io.cc:410