OpenStructure
Loading...
Searching...
No Matches
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>
34
35namespace ost { namespace io {
36
37
42
43
45public:
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_; }
53private:
54 StringRef category_;
55 StringRef name_;
56 StringRef value_;
57};
58
60public:
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_; }
93private:
94 String category_;
95 std::map<String, int> index_map_;
96};
97
115public:
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
126public:
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
172 const String& name,
173 Real alt,
174 bool (*is_default)(StringRef)) const;
175
182 float TryGetFloat(const StringRef& data, const String& name) const;
183
191 std::pair<bool, float> TryGetFloat(const StringRef& data,
192 const String& name,
193 bool may_fail) const;
194
201 int TryGetInt(const StringRef& data, const String& name) const;
202
210 std::pair<bool, int> TryGetInt(const StringRef& data,
211 const String& name,
212 bool may_fail) const;
213
220 bool TryGetBool(const StringRef& data, const String& name) const;
221
224 int line=-1) const;
225
226 void SetFilename(const String& filename)
227 {
228 filename_ = filename;
229 }
230
233 {
234 return line_num_;
235 }
236public:
237 void Parse();
238
239public:
240 static bool SplitLine(const StringRef& line,
241 std::vector<StringRef>& parts, bool clear=true);
242 static inline bool IsUndefined(StringRef value)
243{
244 return value.size()==1 && (value[0]=='?' || value[0]=='.');
245}
246
247private:
248 void ParseLoop();
251 void ParseLastDataItemRow();
254 void ParseDataItemOrRow(StarDataItem& item);
256 void ParseEndDataItemRow();
257private:
259 bool NextLine(StringRef& str)
260 {
261 if (std::getline(stream_, current_line_)) {
262 str=StringRef(current_line_.data(), current_line_.length());
263 ++line_num_;
264 has_current_line_=true;
265 return true;
266 }
267 return false;
268 }
270 bool GetLine(StringRef& ref)
271 {
272 if (has_current_line_) {
273 ref=StringRef(current_line_.data(), current_line_.size());
274 return true;
275 }
276 return this->NextLine(ref);
277 }
278
279 void ConsumeLine()
280 {
281 assert(has_current_line_);
282 has_current_line_=false;
283 }
284
285 // the reason for having this function are problems when generating
286 // StringRefs that contain pointers to strings in a vector.
287 // When the vector grows, the memory of the strings might get
288 // reallocated and the StringRefs point into nothing.
289 // This function Prepares the stringrefs given a constant
290 // vector and calls OnDataRow to minimize the change in interface.
291 void CallOnDataRow(const StarLoopDesc& header,
292 const std::vector<String>& columns);
293
294 void ParseDataItemIdent(const StringRef ident,
295 StringRef& cat, StringRef& name);
296 void ParseGlobal();
297 void ParseData();
298 void ParseDataItem();
299 void DiagnoseUnknown();
300 bool ParseMultilineValue(String& value, bool skip=false);
301 std::ifstream fstream_;
302 boost::iostreams::filtering_stream<boost::iostreams::input> stream_;
303 String filename_;
304 int line_num_;
305 bool has_current_line_;
306 String current_line_;
307 bool items_as_row_;
308 StarLoopDesc items_row_header_;
309 bool file_open_;
310 std::vector<String> items_row_values_;
311};
312
313}}
314
315#endif
convenient datatype for referencing character data
Definition string_ref.hh:39
size_t size() const
Definition string_ref.hh:54
std::string str() const
Definition string_ref.hh:94
const StringRef & GetCategory() const
const StringRef & GetName() const
const StringRef & GetValue() const
StarDataItem(const StringRef &category, const StringRef &name, const StringRef &value)
size_t GetSize() const
void Add(const StringRef &name)
void SetCategory(const StringRef &category)
int GetIndex(const String &name) const
const String & GetCategory() const
parser for the STAR file format
virtual bool OnBeginData(const StringRef &data_name)
invoked when a new data control structure is encountered
int GetCurrentLinenum() const
retrieve the line, the parser is currently working on
float TryGetFloat(const StringRef &data, const String &name) const
try to convert a value to float, on failure raise an exception.
static bool SplitLine(const StringRef &line, std::vector< StringRef > &parts, bool clear=true)
void SetFilename(const String &filename)
static bool IsUndefined(StringRef value)
virtual void OnEndData()
called when leaving a datasection. Will only be invoked when OnBeginData() returned true.
String FormatDiagnostic(StarDiagType type, const String &message, int line=-1) const
format diagnostic and returns it as a string.
virtual void OnEndLoop()
invoked when leaving a loop
virtual void OnDataItem(const StarDataItem &item)
invoked when a data item is encountered
virtual void OnDataRow(const StarLoopDesc &header, const std::vector< StringRef > &columns)
invoked when a data row in a loop is encountered.
Real TryGetReal(const StringRef &data, const String &name) const
try to convert a value to Real, on failure raise an exception.
int TryGetInt(const StringRef &data, const String &name) const
try to convert a value to integer, on failure raise an exception.
std::pair< bool, int > TryGetInt(const StringRef &data, const String &name, bool may_fail) const
try to convert a value to integer, exception can be turned off.
bool TryGetBool(const StringRef &data, const String &name) const
try to convert a value to bool, on failure raise an exception.
StarParser(std::istream &stream, bool items_as_row=false)
create a StarParser
StarParser(const String &filename, bool items_as_row=false)
std::pair< bool, float > TryGetFloat(const StringRef &data, const String &name, bool may_fail) const
try to convert a value to float, on failure raise an exception.
virtual bool OnBeginLoop(const StarLoopDesc &header)
called when a loop is encountered
Real GetRealOrDefault(const StringRef &data, const String &name, Real alt, bool(*is_default)(StringRef)) const
try to convert a value to Real, on failure return default value.
#define DLLEXPORT_OST_IO
float Real
Definition base.hh:44
std::string String
Definition base.hh:54
@ STAR_DIAG_ERROR
@ STAR_DIAG_WARNING
Definition base.dox:1