ParserItem.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2013 Statoil ASA.
3 
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18  */
19 #ifndef PARSER_ITEM_H
20 #define PARSER_ITEM_H
21 
22 #include <string>
23 #include <sstream>
24 #include <iostream>
25 #include <deque>
26 
27 #include <memory>
28 #include <boost/lexical_cast.hpp>
29 
30 #include <opm/json/JsonObject.hpp>
31 
36 
37 namespace Opm {
38 
39  class ParserItem {
40  public:
41  ParserItem(const std::string& itemName);
42  ParserItem(const std::string& itemName, ParserItemSizeEnum sizeType);
43  explicit ParserItem(const Json::JsonObject& jsonConfig);
44 
45  virtual void push_backDimension(const std::string& dimension);
46  virtual const std::string& getDimension(size_t index) const;
47  virtual DeckItemPtr scan(RawRecordPtr rawRecord) const = 0;
48  virtual bool hasDimension() const;
49  virtual size_t numDimensions() const;
50  const std::string className() const;
51  const std::string& name() const;
53  std::string getDescription() const;
54  bool scalar() const;
55  void setDescription(std::string helpText);
56 
57  virtual std::string createCode() const = 0;
58  virtual void inlineClass(std::ostream& /* os */ , const std::string& indent) const = 0;
59  virtual std::string inlineClassInit(const std::string& parentClass) const = 0;
60 
61  virtual ~ParserItem() {
62  }
63 
64  virtual bool equal(const ParserItem& other) const = 0;
65 
66  protected:
67  template <class T>
68  bool parserRawItemEqual(const ParserItem &other) const {
69  const T * lhs = dynamic_cast<const T*>(this);
70  const T * rhs = dynamic_cast<const T*>(&other);
71  if (!lhs || !rhs)
72  return false;
73 
74  if (lhs->name() != rhs->name())
75  return false;
76 
77  if (lhs->getDescription() != rhs->getDescription())
78  return false;
79 
80  if (lhs->sizeType() != rhs->sizeType())
81  return false;
82 
83  if (lhs->m_defaultSet != rhs->m_defaultSet)
84  return false;
85 
86  // we only care that the default value is equal if it was
87  // specified...
88  if (lhs->m_defaultSet && lhs->getDefault() != rhs->getDefault())
89  return false;
90 
91  return true;
92  }
93 
95 
96  private:
97  std::string m_name;
98  ParserItemSizeEnum m_sizeType;
99  std::string m_description;
100  };
101 
102  typedef std::shared_ptr<const ParserItem> ParserItemConstPtr;
103  typedef std::shared_ptr<ParserItem> ParserItemPtr;
104 
105 
106 
107  template<typename ParserItemType, typename ValueType>
108  void ParserItemInlineClassDeclaration(const ParserItemType * self , std::ostream& os, const std::string& indent , const std::string& typeString) {
109  os << indent << "class " << self->className( ) << " {" << std::endl;
110  os << indent << "public:" << std::endl;
111  {
112  std::string local_indent = indent + " ";
113  os << local_indent << "static const std::string itemName;" << std::endl;
114  if (self->hasDefault())
115  os << local_indent << "static const " << typeString << " defaultValue;" << std::endl;
116  }
117  os << indent << "};" << std::endl;
118  }
119 
120 
121  template<typename ParserItemType, typename ValueType>
122  std::string ParserItemInlineClassInit(const ParserItemType * self ,
123  const std::string& parentClass ,
124  const std::string& typeString ,
125  const std::string * defaultValue = NULL) {
126 
127  std::stringstream ss;
128  ss << "const std::string " << parentClass << "::" << self->className() << "::itemName = \"" << self->name() << "\";" << std::endl;
129 
130  if (self->hasDefault()) {
131  if (defaultValue)
132  ss << "const " << typeString << " " << parentClass << "::" << self->className() << "::defaultValue = " << *defaultValue << ";" << std::endl;
133  else
134  ss << "const " << typeString << " " << parentClass << "::" << self->className() << "::defaultValue = " << self->getDefault() << ";" << std::endl;
135  }
136 
137  return ss.str();
138  }
139 
140 
141 
142 
143 
147  template<typename ParserItemType , typename DeckItemType , typename ValueType>
148  DeckItemPtr ParserItemScan(const ParserItemType * self , RawRecordPtr rawRecord) {
149  std::shared_ptr<DeckItemType> deckItem = std::make_shared<DeckItemType>( self->name() , self->scalar() );
150 
151  if (self->sizeType() == ALL) {
152  while (rawRecord->size() > 0) {
153  std::string token = rawRecord->pop_front();
154 
155  std::string countString;
156  std::string valueString;
157  if (isStarToken(token, countString, valueString)) {
158  StarToken st(token, countString, valueString);
159  ValueType value;
160 
161  if (st.hasValue()) {
162  value = readValueToken<ValueType>(st.valueString());
163  deckItem->push_backMultiple( value , st.count());
164  } else {
165  value = self->getDefault();
166  for (size_t i=0; i < st.count(); i++)
167  deckItem->push_backDefault( value );
168  }
169  } else {
170  ValueType value = readValueToken<ValueType>(token);
171  deckItem->push_back(value);
172  }
173  }
174  } else {
175  if (rawRecord->size() == 0) {
176  // if the record was ended prematurely,
177  if (self->hasDefault()) {
178  // use the default value for the item, if there is one...
179  deckItem->push_backDefault( self->getDefault() );
180  } else {
181  // ... otherwise indicate that the deck item should throw once the
182  // item's data is accessed.
183  deckItem->push_backDummyDefault();
184  }
185  } else {
186  // The '*' should be interpreted as a repetition indicator, but it must
187  // be preceeded by an integer...
188  std::string token = rawRecord->pop_front();
189  std::string countString;
190  std::string valueString;
191  if (isStarToken(token, countString, valueString)) {
192  StarToken st(token, countString, valueString);
193 
194  if (!st.hasValue()) {
195  if (self->hasDefault())
196  deckItem->push_backDefault( self->getDefault() );
197  else
198  deckItem->push_backDummyDefault();
199  } else
200  deckItem->push_back(readValueToken<ValueType>(st.valueString()));
201 
202  // replace the first occurence of "N*FOO" by a sequence of N-1 times
203  // "1*FOO". this is slightly hacky, but it makes it work if the
204  // number of defaults pass item boundaries...
205  std::string singleRepetition;
206  if (st.hasValue())
207  singleRepetition = st.valueString();
208  else
209  singleRepetition = "1*";
210 
211  for (size_t i=0; i < st.count() - 1; i++)
212  rawRecord->push_front(singleRepetition);
213  } else {
214  ValueType value = readValueToken<ValueType>(token);
215  deckItem->push_back(value);
216  }
217  }
218  }
219  return deckItem;
220  }
221 
222 
223 
224 }
225 
226 #endif
227 
virtual void inlineClass(std::ostream &, const std::string &indent) const =0
const std::string & valueString() const
Definition: StarToken.hpp:119
std::shared_ptr< DeckItem > DeckItemPtr
Definition: DeckItem.hpp:126
virtual const std::string & getDimension(size_t index) const
Definition: Deck.hpp:29
Definition: StarToken.hpp:83
virtual std::string createCode() const =0
void setDescription(std::string helpText)
std::shared_ptr< ParserItem > ParserItemPtr
Definition: ParserItem.hpp:103
virtual bool equal(const ParserItem &other) const =0
bool parserRawItemEqual(const ParserItem &other) const
Definition: ParserItem.hpp:68
virtual size_t numDimensions() const
virtual std::string inlineClassInit(const std::string &parentClass) const =0
std::shared_ptr< const ParserItem > ParserItemConstPtr
Definition: ParserItem.hpp:102
size_t count() const
Definition: StarToken.hpp:99
const std::string & name() const
void ParserItemInlineClassDeclaration(const ParserItemType *self, std::ostream &os, const std::string &indent, const std::string &typeString)
Definition: ParserItem.hpp:108
Definition: JsonObject.hpp:31
ParserItemSizeEnum
Definition: ParserEnums.hpp:37
std::string ParserItemInlineClassInit(const ParserItemType *self, const std::string &parentClass, const std::string &typeString, const std::string *defaultValue=NULL)
Definition: ParserItem.hpp:122
bool isStarToken(const std::string &token, std::string &countString, std::string &valueString)
Definition: ParserItem.hpp:39
bool hasValue() const
Definition: StarToken.hpp:103
Definition: ParserEnums.hpp:38
std::string getDescription() const
ParserItemSizeEnum sizeType() const
bool scalar() const
virtual DeckItemPtr scan(RawRecordPtr rawRecord) const =0
bool m_defaultSet
Definition: ParserItem.hpp:94
virtual bool hasDimension() const
virtual ~ParserItem()
Definition: ParserItem.hpp:61
std::shared_ptr< RawRecord > RawRecordPtr
Definition: RawRecord.hpp:64
const std::string className() const
virtual void push_backDimension(const std::string &dimension)
DeckItemPtr ParserItemScan(const ParserItemType *self, RawRecordPtr rawRecord)
Definition: ParserItem.hpp:148
ParserItem(const std::string &itemName)