OpenStructure
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-2011 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 <iostream>
27 #include <vector>
28 #include <map>
29 #include <ost/string_ref.hh>
30 #include <ost/io/module_config.hh>
31 
32 namespace ost { namespace io {
33 
35 public:
36  StarDataItem(const StringRef& category, const StringRef& name,
37  const StringRef& value):
38  category_(category), name_(name), value_(value)
39  { }
40  const StringRef& GetCategory() const { return category_; }
41  const StringRef& GetName() const { return name_; }
42  const StringRef& GetValue() const { return value_; }
43 private:
44  StringRef category_;
45  StringRef name_;
46  StringRef value_;
47 };
48 
50 public:
52  category_("")
53  { }
54 
55  int GetIndex(const String& name) const
56  {
57  std::map<String, int>::const_iterator i=index_map_.find(name);
58  return i==index_map_.end() ? -1 : i->second;
59  }
60 
61  void SetCategory(const StringRef& category)
62  {
63  category_=category.str();
64  }
65 
66  void Add(const StringRef& name)
67  {
68  index_map_.insert(std::make_pair(name.str(), index_map_.size()));
69  }
70  size_t GetSize() const
71  {
72  return index_map_.size();
73  }
74  const String& GetCategory() const { return category_; }
75 private:
76  String category_;
77  std::map<String, int> index_map_;
78 };
79 
97 public:
98  StarParser(std::istream& istream);
99 
100  virtual ~StarParser() { }
101 // callback interface
102 public:
107  virtual bool OnBeginLoop(const StarLoopDesc& header) { return true; }
111  virtual void OnEndLoop() { }
115  virtual void OnDataRow(const StarLoopDesc& header,
116  const std::vector<StringRef>& columns)
117  {
118  }
120  virtual void OnDataItem(const StarDataItem& item) { }
121 
125  virtual bool OnBeginData(const StringRef& data_name) { return true; }
126 
129  virtual void OnEndData() { }
130 public:
131  void Parse();
132 
133 public:
134  static bool SplitLine(const StringRef& line,
135  std::vector<StringRef>& parts, bool clear=true);
136 private:
137  void ParseLoop();
138 private:
140  bool NextLine(StringRef& str)
141  {
142  if (std::getline(stream_, current_line_)) {
143  str=StringRef(current_line_.data(), current_line_.length());
144  ++line_num_;
145  has_current_line_=true;
146  return true;
147  }
148  return false;
149  }
151  bool GetLine(StringRef& ref)
152  {
153  if (has_current_line_) {
154  ref=StringRef(current_line_.data(), current_line_.size());
155  return true;
156  }
157  return this->NextLine(ref);
158  }
159 
160  void ConsumeLine()
161  {
162  assert(has_current_line_);
163  has_current_line_=false;
164  }
165  void ParseGlobal();
166  void ParseData();
167  void ParseDataItem();
168  void DiagnoseUnknown();
169  bool ParseMultilineValue(String& value, bool skip=false);
170  std::istream& stream_;
171  int line_num_;
172  bool has_current_line_;
173  String current_line_;
174 };
175 
176 }}
177 
178 #endif