Loading...
Searching...
No Matches
MapReader.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31#ifndef MAPREADER_H_
32#define MAPREADER_H_
33
34#include <iostream>
35#include <fstream>
36
37#include <map>
38
39#include <drain/RegExp.h>
40
41// using namespace std;
42
43
44namespace drain
45{
46
47// consider changing back *m => &m ?
48
50
55template <class K, class V>
57{
58public:
59
61 std::string trimChars;
62
63 // If "limited", does not allow adding new entries but changes only.
64 bool limited;
65
66
67 MapReader() : limited(false), m(defaultMap) {};
68
69 MapReader(std::map<K,V> &target) : limited(false), m(&target) {
70
71 trimChars = " \t";
72 // WAS lazy hyphen in the leading characters
73 //std::string regExpString = "^[ \t]*([a-zA-Z][a-zA-Z0-9_]*)[ \t]*=(.*)$";
74
75 // Indices for the essential patterns in the following regexps
76 //KEY = 1;
77 //VALUE = 3;
78
79 // Mpeura 2009/07
80 //configLineParser.setExpression("^[ \t]*([a-zA-Z][a-zA-Z0-9_\\.]*)[ \t]*(=(.*))?$");
81 //commandLineParser.setExpression("^\\-\\-?([a-zA-Z][a-zA-Z0-9_\\.]*)(=(.*))?$"); // Must preserve position 1 and 3!
82 setKeySyntax("[a-zA-Z][a-zA-Z0-9_\\.]*");
83
84 //std::string regExpString = "^([a-z]*)$";
85 //setRegExp(regExpString);
86 //cout << lineParser.test("ksm=kks") << endl;
87 };
88
89 virtual ~MapReader(){};
90
91 void setMap(std::map<K,V> &target){
92 m = &target;
93 }
94
96 void setKeySyntax(const std::string & regExp){
97 configLineParser.setExpression(std::string("^[ \t]*(")+regExp+")[ \t]*(=(.*))?$");
98 commandLineParser.setExpression(std::string("^\\-\\-?(")+regExp+")(=(.*))?$"); // Must preserve position 1 and 3!
99 }
100
101 //std::string regexpString;
102 //drain::RegExp commandLineOptionParser;
103
104 void trim(std::string &s){
105 std::string::size_type pos1 = s.find_first_not_of(trimChars);
106 std::string::size_type pos2 = s.find_last_not_of(trimChars);
107 if (pos1 != std::string::npos)
108 s = s.substr(pos1,pos2-pos1 + 1);
109 else
110 s = "";
111 }
112
113
114 // PAH
115 /*
116 bool setRegExp(const std::string &regExpString){
117 return ( configLineParser.setExpression(regExpString) );
118 }
119 */
120
125 void read(const std::string &filename){ // replace with "readFile" or drain::InputFile()
126 std::ifstream ifstr;
127 ifstr.open(filename.c_str());
128 read(ifstr);
129 ifstr.close();
130 }
131
135 void read(std::istream &istr = std::cin){
136 std::string line;
137 while (getline(istr,line)){
138 //cout << "MapReader::read istr: " << line << '\n';
139 readConfigEntry(line);
140 }
141 }
142
146 void readConfigEntry(const std::string &line){ //const char *line){
147 readEntry(line,configLineParser);
148 }
149
153 void readCommandLineEntry(const std::string &s){ //const char *line){
154 readEntry(s,commandLineParser);
155 }
156
157 void readPendingCommandLineArgument(const std::string &s){
158 value = s;
159 trim(value);
160 (*m)[key] = value;
161 argumentRegistered = true;
162 }
163
164
168 void readEntry(const std::string &line, drain::RegExp &regExp){ //const char *line){
169
170 regExp.execute(line);
171
172 const std::vector<std::string> &result = regExp.result;
173
174 //std::string::size_type s = result.size();
175
176 /*
177 cout << "readEntry, size=" << s << '\n';
178 for (unsigned int i = 0; i < s; ++i) {
179 cout << i << ' ' << result[i] << '\n';
180 }
181 */
182 //cout << "VALUE=" << VALUE << result[VALUE] << '\n';
183 //cout << "KEY=" << KEY << result[KEY] << '\n';
184 //cout << "***** readEntry, size=" << s << '\n';
185
186
187 // If matches --xxxxxxx
188 if (!result.empty()){
189
190 key = result[1];
191 trim(key);
192
193 /*
194 if ((limited)&&(m->find(key) != m->end())){
195 throw "Closed map has not key " + key;
196 }
197 */
198
199 if (!result[2].empty()){// At least '=' found
200 value = result[3];
201 trim(value);
202 (*m)[key] = value;
203 argumentRegistered = true;
204 }
205 else {
206 value = "";
207 argumentRegistered = false; // user is hinted to use readPendingArgument now.
208 }
209 }
210 else { // loose argument
211 key="";
212 value = line;
213 trim(value);
214 argumentRegistered = true;
215 }
216
217
218
219 }
220
225 void read(int argc, char **argv){
226 for (int i = 1; i < argc; ++i) {
227 readCommandLineEntry(argv[i]);
228 }
229
230 }
231
232
233
234 inline const std::string &getKey(){return key;};
235 inline const std::string &getValue(){return value;};
236
237 //inline bool pendingArgument(){return !hasArgument;};
238 inline bool hasArgument(){return argumentRegistered;};
239
240protected:
241 std::map<K,V> *m;
242 std::map<K,V> defaultMap;
243
244 // For configuration file options
245 drain::RegExp configLineParser;
246
247 // For command line options
248 drain::RegExp commandLineParser;
249
250 std::string key;
251 std::string value;
252
253 // change to "pending argument" etc
254 bool argumentRegistered;
255 //int KEY;
256 //int VALUE;
257
258};
259
260} //namespace
261
262#endif /*MAPREADER_H_*/
263
264// Drain
General utility for reading text entries of type KEY=VALUE into a map.
Definition MapReader.h:57
void read(std::istream &istr=std::cin)
Definition MapReader.h:135
void readConfigEntry(const std::string &line)
Definition MapReader.h:146
void readEntry(const std::string &line, drain::RegExp &regExp)
Definition MapReader.h:168
void setKeySyntax(const std::string &regExp)
Defines the std::strings recognized (accepted) as keys. By default: [a-zA-Z][a-zA-Z0-9_\....
Definition MapReader.h:96
std::string trimChars
Leading and trailing characters to be pruned.
Definition MapReader.h:61
void read(const std::string &filename)
Definition MapReader.h:125
void readCommandLineEntry(const std::string &s)
Definition MapReader.h:153
void read(int argc, char **argv)
Definition MapReader.h:225
Definition RegExp.h:58
const std::vector< std::string > & result
Public interface for the result.
Definition RegExp.h:110
int execute(const std::string &str, T &result) const
Apply regexp matching in a string. Returns 0 on success, REG_NOMATCH on failure.
Definition RegExp.h:187
Definition DataSelector.cpp:1277