OpenStructure
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
star_parser.hh
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
2 // This file is part of the OpenStructure project <www.openstructure.org>
3 //
4 // Copyright (C) 2008-2020 by the OpenStructure authors
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License as published by the Free
8 // Software Foundation; either version 3.0 of the License, or (at your option)
9 // any later version.
10 // This library is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this library; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 //------------------------------------------------------------------------------
19 #ifndef OST_IO_STAR_PARSER_HH
20 #define OST_IO_STAR_PARSER_HH
21 
22 
23 /*
24  Author: Marco Biasini
25  */
26 #include <boost/iostreams/filtering_stream.hpp>
27 
28 #include <iostream>
29 #include <fstream>
30 #include <vector>
31 #include <map>
32 #include <ost/string_ref.hh>
33 #include <ost/io/module_config.hh>
34 
35 namespace ost { namespace io {
36 
37 
38 typedef enum {
41 } StarDiagType;
42 
43 
44 class DLLEXPORT_OST_IO StarDataItem {
45 public:
46  StarDataItem(const StringRef& category, const StringRef& name,
47  const StringRef& value):
48  category_(category), name_(name), value_(value)
49  { }
50  const StringRef& GetCategory() const { return category_; }
51  const StringRef& GetName() const { return name_; }
52  const StringRef& GetValue() const { return value_; }
53 private:
54  StringRef category_;
55  StringRef name_;
56  StringRef value_;
57 };
58 
59 class DLLEXPORT_OST_IO StarLoopDesc {
60 public:
62  category_("")
63  { }
64 
65  int GetIndex(const String& name) const
66  {
67  std::map<String, int>::const_iterator i=index_map_.find(name);
68  return i==index_map_.end() ? -1 : i->second;
69  }
70 
71  void SetCategory(const StringRef& category)
72  {
73  category_=category.str();
74  }
75 
76 
77 
78  void Add(const StringRef& name)
79  {
80  index_map_.insert(std::make_pair(name.str(), index_map_.size()));
81  }
82  size_t GetSize() const
83  {
84  return index_map_.size();
85  }
86  void Clear()
87  {
88  category_.clear();
89  index_map_.clear();
90  }
91 
92  const String& GetCategory() const { return category_; }
93 private:
94  String category_;
95  std::map<String, int> index_map_;
96 };
97 
114 class DLLEXPORT_OST_IO StarParser {
115 public:
122  explicit StarParser(std::istream& stream, bool items_as_row=false);
123  explicit StarParser(const String& filename, bool items_as_row=false);
124  virtual ~StarParser() { }
125 // callback interface
126 public:
131  virtual bool OnBeginLoop(const StarLoopDesc& header) { return true; }
135  virtual void OnEndLoop() { }
139  virtual void OnDataRow(const StarLoopDesc& header,
140  const std::vector<StringRef>& columns)
141  {
142  }
144  virtual void OnDataItem(const StarDataItem& item) { }
145 
149  virtual bool OnBeginData(const StringRef& data_name) { return true; }
150 
153  virtual void OnEndData() { }
154 
161  Real TryGetReal(const StringRef& data, const String& name) const;
162 
169  float TryGetFloat(const StringRef& data, const String& name) const;
170 
178  std::pair<bool, float> TryGetFloat(const StringRef& data,
179  const String& name,
180  bool may_fail) const;
181 
188  int TryGetInt(const StringRef& data, const String& name) const;
189 
197  std::pair<bool, int> TryGetInt(const StringRef& data,
198  const String& name,
199  bool may_fail) const;
200 
207  bool TryGetBool(const StringRef& data, const String& name) const;
208 
210  String FormatDiagnostic(StarDiagType type, const String& message,
211  int line=-1) const;
212 
213  void SetFilename(const String& filename)
214  {
215  filename_ = filename;
216  }
217 
219  int GetCurrentLinenum() const
220  {
221  return line_num_;
222  }
223 public:
224  void Parse();
225 
226 public:
227  static bool SplitLine(const StringRef& line,
228  std::vector<StringRef>& parts, bool clear=true);
229 private:
230  void ParseLoop();
233  void ParseLastDataItemRow();
236  void ParseDataItemOrRow(StarDataItem& item);
238  void ParseEndDataItemRow();
239 private:
241  bool NextLine(StringRef& str)
242  {
243  if (std::getline(stream_, current_line_)) {
244  str=StringRef(current_line_.data(), current_line_.length());
245  ++line_num_;
246  has_current_line_=true;
247  return true;
248  }
249  return false;
250  }
252  bool GetLine(StringRef& ref)
253  {
254  if (has_current_line_) {
255  ref=StringRef(current_line_.data(), current_line_.size());
256  return true;
257  }
258  return this->NextLine(ref);
259  }
260 
261  void ConsumeLine()
262  {
263  assert(has_current_line_);
264  has_current_line_=false;
265  }
266 
267  // the reason for having this function are problems when generating
268  // StringRefs that contain pointers to strings in a vector.
269  // When the vector grows, the memory of the strings might get
270  // reallocated and the StringRefs point into nothing.
271  // This function Prepares the stringrefs given a constant
272  // vector and calls OnDataRow to minimize the change in interface.
273  void CallOnDataRow(const StarLoopDesc& header,
274  const std::vector<String>& columns);
275 
276  void ParseDataItemIdent(const StringRef ident,
277  StringRef& cat, StringRef& name);
278  void ParseGlobal();
279  void ParseData();
280  void ParseDataItem();
281  void DiagnoseUnknown();
282  bool ParseMultilineValue(String& value, bool skip=false);
283  std::ifstream fstream_;
284  boost::iostreams::filtering_stream<boost::iostreams::input> stream_;
285  String filename_;
286  int line_num_;
287  bool has_current_line_;
288  String current_line_;
289  bool items_as_row_;
290  StarLoopDesc items_row_header_;
291  bool file_open_;
292  std::vector<String> items_row_values_;
293 };
294 
295 }}
296 
297 #endif
convenient datatype for referencing character data
Definition: string_ref.hh:39
const StringRef & GetCategory() const
Definition: star_parser.hh:50
const StringRef & GetValue() const
Definition: star_parser.hh:52
const StringRef & GetName() const
Definition: star_parser.hh:51
std::string String
Definition: base.hh:54
float Real
Definition: base.hh:44
int GetCurrentLinenum() const
retrieve the line, the parser is currently working on
Definition: star_parser.hh:219
virtual void OnDataRow(const StarLoopDesc &header, const std::vector< StringRef > &columns)
invoked when a data row in a loop is encountered.
Definition: star_parser.hh:139
virtual bool OnBeginLoop(const StarLoopDesc &header)
called when a loop is encountered
Definition: star_parser.hh:131
virtual void OnDataItem(const StarDataItem &item)
invoked when a data item is encountered
Definition: star_parser.hh:144
void SetCategory(const StringRef &category)
Definition: star_parser.hh:71
size_t GetSize() const
Definition: star_parser.hh:82
StarDataItem(const StringRef &category, const StringRef &name, const StringRef &value)
Definition: star_parser.hh:46
virtual bool OnBeginData(const StringRef &data_name)
invoked when a new data control structure is encountered
Definition: star_parser.hh:149
virtual void OnEndLoop()
invoked when leaving a loop
Definition: star_parser.hh:135
#define DLLEXPORT_OST_IO
void SetFilename(const String &filename)
Definition: star_parser.hh:213
std::string str() const
Definition: string_ref.hh:94
const String & GetCategory() const
Definition: star_parser.hh:92
int GetIndex(const String &name) const
Definition: star_parser.hh:65
void Add(const StringRef &name)
Definition: star_parser.hh:78
virtual void OnEndData()
called when leaving a datasection. Will only be invoked when OnBeginData() returned true...
Definition: star_parser.hh:153