ATLAS Offline Software
Loading...
Searching...
No Matches
dbline.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5// INTRODUCTION
6//
7// DBline is a generic class which provides an easy interface to access
8// formatted data from an input stream. The purpose is to facilitate the
9// development of the reading routine (for an ASCII database) and, at the same
10// time, to increase its robustness against the various changes to which the
11// the database undergoes during the development phase. The flexibility needed
12// to deal with each kind of database, was achieved implementing a set of basic
13// functionalities which can be composed in a easy way to build a generic
14// reading routine.
15//
16// Considering a generic database whose data are input line by line, each line
17// can be decomposed into a set of small blocks having the following pattern:
18//
19// <Token> <set of data>
20//
21// where <Token> can be any character sequence (including the space character)
22// and <set of data> can be one ore more data of different nature that have to
23// be read. DBline implements an "extraction" mechanism which allows to select
24// a <Token> and to read the related data (only if the token is found) just in
25// one command line. Since the data input is performed line by line, such
26// "extraction" mechanism requires that the token and the data has to be found
27// in the same line of the database. This matches very well the case in which
28// the database is made of a set of control directives given in any order (i.e.
29// a DATACARD file).
30// In order to allow the reading of more complex structures of data which can
31// be spanned on more than one line, each "extraction" returns a boolean value
32// that can be checked in logical expression. Thus, it is possible to activate
33// a particular reading schema if a Token is found or to read with it until
34// another Token is found. Moreover is also possible to build logical
35// expression only with "extraction" procedures:
36//
37//
38// OPERATION MODE
39//
40// DBline receives an input line from a generic istream and held it into an
41// internal buffer to be processed during the extraction of data. The data
42// requests are send to DBline and are fulfilled only if the PATTERN (i.e. a
43// Token, or a set of Tokens) specified by the user is found into the internal
44// buffer. At each successful "extraction" the corresponding data (i.e. the
45// <Token> and the <related data>) are deleted from the internal buffer.
46//
47// The implemented operation mode, in which the user can read and process data
48// using this class, is made of three sequential step:
49//
50// 1 - Input request. On each input request only a data line is read (i.e.
51// data are read until the carriage return character) and is subsequently
52// stored into an internal buffer for further analysis. This operation
53// cause the deletion of data previously present into the internal
54// buffer. If the input stream is a file it will be automatically connected
55// to the DBline class to allow incremental input line controlled via class
56// operators. It is also possible to get input until a token is found; in
57// this case the token is only checked but not extracted (deleted) from the
58// internal buffer.
59//
60// 2 - Extraction of data. An extraction request is made of a Token request
61// plus a data request. When a Token is found it is extracted from the
62// internal buffer and the starting position from which the subsequent data
63// are extracted is updated to the actual Token position inside the line. If
64// something goes wrong (no Token found, or line become empty before all
65// the requested data are extracted), the extraction stops returning a
66// FALSE status, and all the data extracted from the last successful Token
67// request are restored into the internal buffer. It is possible to request
68// data without specifying a pattern before; in this case the data are
69// extracted in a sequential way from the position in which the last
70// requested Token was found (if no Token has been successfully found, the
71// starting position is the beginning of the line). Finally it is also
72// implemented a mechanism to request more complex pattern, i.e. pattern
73// like <TOKEN> <data> <SUBTOKEN1> <data> <SUBTOKEN2> <data> .....
74//
75// 3 - Check for error. Before a new input request the internal buffer is
76// checked and if there are still data inside an error message is output
77// showing the data that are going to be deleted. Such data directives
78// not understood by the reading routine.
79//
80//
81// SYNTAX
82//
83// ******** INSTANTIATION ********
84//----------------------------------------------------------------------------+
85// DBline data normal instantiantion, no file connected. |
86//----------------------------------------------------------------------------+
87// DBline data(file) where file is an ifstream object. Instantiate |
88// DBline object and connect a file to it. |
89// 04/08/2009 L. Bellagamba -> updated to works in |
90// the same way with ifstream and generic istream |
91//----------------------------------------------------------------------------+
92// ******** DATA INPUT FROM ISTREAM ********
93//----------------------------------------------------------------------------+
94// data << input where input is a generic istream. If input is a |
95// .. or .. file, it will be automatically connected with the |
96// input >> data DBline object. |
97//----------------------------------------------------------------------------+
98// data.connect(file) connect an ifstream to the DBline object. |
99//----------------------------------------------------------------------------+
100// data++ input of 1 more line. Works only with a connected |
101// .. or .. input file. Return FALSE if the END OF FILE is |
102// ++data reached |
103// 04/08/2009 L. Bellagamba -> updated to works also |
104// with a generic istream |
105//----------------------------------------------------------------------------+
106// data + n input of n lines. Works only with a connected |
107// input file.Return FALSE if the END OF FILE is |
108// reached |
109// 04/08/2009 L. Bellagamba -> updated to works also |
110// with a generic istream |
111//----------------------------------------------------------------------------+
112// ******** TOKEN REQUEST ********
113//----------------------------------------------------------------------------+
114// data.token("TOKEN") seek the position of the word "TOKEN" into the |
115// ... or ... database line stored internal buffer. If "TOKEN" |
116// data("TOKEN") is found it will return a TRUE value. |
117//----------------------------------------------------------------------------+
118// data.token("TOKEN #",t) multiple token seek. Substitute the character # |
119// ... or ... into the string "TOKEN #" with the ASCII type of |
120// data("TOKEN #",t) object t and then look for an occurrence of such |
121// token. |
122//----------------------------------------------------------------------------+
123// ******** DATA REQUEST ********
124//----------------------------------------------------------------------------+
125// data >> type use of extractor operator like in an I/O stream. |
126// Supported type are: (normal/unsigned) int/long int|
127// string. Other types can be added, but are not |
128// currently supported. |
129//----------------------------------------------------------------------------+
130// data.setf( .... ) use of the ios flags like in an I/O stream and |
131// setf( ) function works in the same way. |
132//----------------------------------------------------------------------------+
133// data.dbhex() set format flags to get data from an hexadec. base|
134//----------------------------------------------------------------------------+
135// data.dboct() set format flags to get data from an octal base |
136//----------------------------------------------------------------------------+
137// data.dbdec() set format flags to get data from a decimal base |
138//----------------------------------------------------------------------------+
139// data.reset_fmt() reset the format flags to default value |
140//----------------------------------------------------------------------------+
141// data >> data.dbhex same as data.dbhex() but usable in I/O sequence |
142//----------------------------------------------------------------------------+
143// data >> data.dboct() same as data.dboct() but usable in I/O sequence |
144//----------------------------------------------------------------------------+
145// data >> data.dbdec() same as data.dbdec() but usable in I/O sequence |
146//----------------------------------------------------------------------------+
147// ******** LOGICAL EXPRESSION ******** |
148//----------------------------------------------------------------------------+
149// operators ||, && combine the results from several extraction |
150// requests. Keep in mind that, in a logic expression|
151// it is possible that some terms are not evaluated |
152// (i.e. some of the extraction requests are not |
153// performed); this depends on the result of the |
154// previous terms in the logic sequence. |
155//----------------------------------------------------------------------------+
156// operators |, & combine the results from several extraction |
157// requests forcing all the terms present in the |
158// expression to be evaluated. |
159//----------------------------------------------------------------------------+
160//
161//
162// EXAMPLES
163//
164// to read a file until the end:
165//
166// --| ifstream file("name",0);
167// --| DBline data(file);
168// --| while (data++)
169// --| {
170// --| ..... process line ......
171// --| }
172//
173// to read the following line: < LABEL 1: 43 "this is a string" >
174//
175// --| int in; string str;
176// --| data("LABEL 1:") >> in >> str;
177//
178// in the following line:
179//
180// < FIRST 11 SECOND 12 "this is a string" THIRD 8 >
181//
182// each token can be read in an independent way with:
183//
184// --| int i1,i2,i3; string str;
185// --| data("FIRST") >> i1;
186// --| data("SECOND") >> i2 >> str;
187// --| data("THIRD") >> i3;
188//
189// or as a whole (i.e. researching the entire sequence in a given order):
190//
191// --| int i1,i2,i3; string str;
192// --| data("FIRST") >> i1 >> "SECOND" >> i2 >> str >> "THIRD" >> i3;
193//
194// to read until the occurrence of a TOKEN:
195//
196// --| do
197// --| {
198// --| ..... process line ......
199// --| data++;
200// --| } while (data("TOKEN"));
201//
202// increase line until the occurrence of a TOKEN:
203//
204// --| data.go_until("TOKEN");
205//
206// to read complex structure like:
207//
208// < START: "new sequence of data" { >
209// < Token 1 <data> >
210// < Token 2 <data> >
211// < } >
212//
213// --| if(data("START:") >> str >> "{")
214// --| {
215// --| data("Token 1") >> <data>;
216// --| data("Token 2") >> <data>;
217// --| data++;
218// --| } while (data("}"));
219//
220// to read hexadecimal values:
221//
222// < value ff >
223//
224// --| unsigned long int i1;
225// --| data("value").hex() >> i1;
226// --| data.reset_fmt();
227//
228// OR
229//
230// --| unsigned long int i1;
231// --| data("value") >> hex() >> i1 >> resetflags();
232
233#ifndef MUONCABLINGTOOLS_DBLINE_H
234#define MUONCABLINGTOOLS_DBLINE_H
235
236#include <ctype.h>
237#include <stdint.h>
238
239#include <algorithm>
240#include <fstream>
241#include <iomanip>
242#include <iostream>
243#include <sstream>
244#include <string>
245#include <string_view>
246#include <typeinfo>
247
249
250class DBfmt : public std::ios {
251public:
252 DBfmt();
253};
254
255class DBline : public std::ios {
256private:
258
259 std::ios::fmtflags m_default;
260 std::ifstream* m_file{nullptr};
261 std::istream* m_stream{nullptr};
262 std::string m_data, m_backup;
263 unsigned long int m_pos{0};
264 int m_line{0};
265 bool m_fail{false};
266 bool m_empty{false};
268 int m_base{10};
269
270 // Private member functions for setting internal status
271 void reset_data(void);
272 void reset_status(void);
273 void reset(void);
274
275 // Private member functions for setting extraction status
276 void GoodExtraction(void);
277 void BadExtraction(void);
278
279 // Private member functions for managing the internal buffer
280 void erase_comment(void);
281 void GetToken(size_t pos, std::string_view token);
282 void GetLine(std::istream& input);
283
284 // Private member functions for extracting data
285 template <class type> void GetValue(type& value);
286 void GetValue(std::string& value);
287 quote check_quote(std::string&) const;
288 void GetStr(std::string&);
289
290 // Check if internal buffer is empty
291 bool check_data(void);
292
293 // Private member to manage the I/O format
297
298public:
299 DBline();
300 DBline(std::ifstream& file);
301 DBline(std::istream& stream);
302
303 // Function to connect input file/stream
304 void connect(std::ifstream& file);
305 void connect(std::istream& stream);
306
307 // Function to get the token
308 DBline& token(std::string_view);
309 template <class type> DBline& token(std::string_view, type t);
310 template <class type> DBline& token(std::string_view, type t, int size);
311 void go_until(std::string_view token);
312
313 // Check if exits data into the internal buffer
314 bool empty(void) const;
315
316 // Public functions to set the I/O format
317 DBline& reset_fmt(void);
318 const DBfmt& dbhex() const;
319 const DBfmt& dboct() const;
320 const DBfmt& dbdec() const;
321
322 // Operators for extracting data
323 DBline& operator>>(std::string& str);
324
325 DBline& operator>>(int& i);
326 DBline& operator>>(uint8_t& i8);
327 DBline& operator>>(uint16_t& i16);
328 DBline& operator>>(uint32_t& i32);
329 DBline& operator>>(uint64_t& i64);
330
331 // Operator for allowing external manipulation of data
332 DBline& operator>>(const DBfmt& f);
333
334 // Operator for subtoken searching
335 DBline& operator>>(std::string_view token);
336
337 // Operators for incremental input
339 DBline& operator++(int i);
340 DBline& operator+(int i);
341
342 // Internal status operators
343 operator bool();
344 bool operator!();
345 operator DBstatus();
346
347 // Operators for extracting tokens
348 DBline& operator()(std::string_view);
349 DBline& operator()(std::string_view, int);
350 DBline& operator()(std::string_view, int, int);
351
352 // Member function for using input from streams
353 DBline& operator<<(std::istream& input);
354 DBline& operator<<(std::ifstream& file);
355
356 // Friend functions for using I/O whit streams
357 friend std::ifstream& operator>>(std::ifstream& file, DBline& db);
358 friend std::istream& operator>>(std::istream& stream, DBline& db);
359 friend std::ostream& operator<<(std::ostream& stream, DBline& db);
360};
361
362// inline methods
363
364inline bool DBline::check_data(void) {
365 m_empty = std::all_of(m_data.begin(), m_data.end(), isspace);
366 return m_empty;
367}
368
369inline const DBfmt& DBline::dbhex() const { return m_dbfmt_hex; }
370
371inline const DBfmt& DBline::dboct() const { return m_dbfmt_oct; }
372
373inline const DBfmt& DBline::dbdec() const { return m_dbfmt_dec; }
374
375inline bool DBline::empty() const { return m_empty; }
376
377#endif
DBfmt()
Definition dbline.cxx:423
DBline & operator>>(std::string &str)
Definition dbline.cxx:251
bool m_fail
Definition dbline.h:265
enum DBline::exist_quote quote
DBline & operator++()
Definition dbline.cxx:309
DBline & operator+(int i)
Definition dbline.cxx:323
void connect(std::ifstream &file)
Definition dbline.cxx:157
void BadExtraction(void)
Definition dbline.cxx:39
int m_base
Definition dbline.h:268
bool check_data(void)
Definition dbline.h:364
void reset_status(void)
Definition dbline.cxx:25
const DBfmt & dboct() const
Definition dbline.h:371
quote check_quote(std::string &) const
Definition dbline.cxx:139
void GoodExtraction(void)
Definition dbline.cxx:38
exist_quote
Definition dbline.h:257
@ end_quote
Definition dbline.h:257
@ no_quote
Definition dbline.h:257
@ begin_quote
Definition dbline.h:257
int m_line
Definition dbline.h:264
DBline & reset_fmt(void)
Definition dbline.cxx:241
std::string m_data
Definition dbline.h:262
unsigned long int m_pos
Definition dbline.h:263
DBfmt m_dbfmt_oct
Definition dbline.h:295
DBfmt m_dbfmt_hex
Definition dbline.h:294
DBstatus m_extraction
Definition dbline.h:267
DBfmt m_dbfmt_dec
Definition dbline.h:296
DBline & operator<<(std::istream &input)
Definition dbline.cxx:386
void GetToken(size_t pos, std::string_view token)
Definition dbline.cxx:56
std::istream * m_stream
Definition dbline.h:261
bool empty(void) const
Definition dbline.h:375
std::ios::fmtflags m_default
Definition dbline.h:259
const DBfmt & dbdec() const
Definition dbline.h:373
void GetStr(std::string &)
Definition dbline.cxx:120
bool m_empty
Definition dbline.h:266
void erase_comment(void)
Definition dbline.cxx:51
void GetValue(type &value)
Definition dbline.cxx:83
std::string m_backup
Definition dbline.h:262
void go_until(std::string_view token)
Definition dbline.cxx:229
const DBfmt & dbhex() const
Definition dbline.h:369
DBline & operator()(std::string_view)
Definition dbline.cxx:343
std::ifstream * m_file
Definition dbline.h:260
DBline()
Definition dbline.cxx:360
void reset(void)
Definition dbline.cxx:29
bool operator!()
Definition dbline.cxx:336
void reset_data(void)
Definition dbline.cxx:20
DBline & token(std::string_view)
Definition dbline.cxx:179
void GetLine(std::istream &input)
Definition dbline.cxx:62
result_extraction
Definition dbline.h:248
@ not_extracted
Definition dbline.h:248
@ extracted
Definition dbline.h:248
enum result_extraction DBstatus
TFile * file