Skip to content
Snippets Groups Projects

MuonCablingTools: cleanup/optimization of DBline class

Merged Frank Winklmeier requested to merge fwinkl/athena:muonmsg2 into master
6 files
+ 302
390
Compare changes
  • Side-by-side
  • Inline
Files
6
  • Cleanup and optimization of the `DBline` class that is used to parse RPC
    text configurations (usually read from COOL):
    
    - Add a unit test for the `DBline` class that will make future changes
      easier to validate.
    - Remove the obsolete I/O formatters (`hex`, `dec`, `oct`) that were
      using excessive amounts of `new`s. These functions were not used
      anymore and the code comments said those are obsolete and replaced by
      the equivalent `dbhex`, etc. version. Also delete the now obsolete
      `setdbfmtflag` to switch between the old/new formatters.
    - Update the documentation. It said floats are supported but that was
      never(?) the case.
    - Delete unsupported stream operators for floating point types. Also
      remove operators for pointer types (why would anybody use those?).
    - Use `std::string_view` where possible.
    - Use delegating constructor to avoid copy&paste.
    - Remove internal "store" that was not being used.
    - Use `std::getline` instead of `get` to read full line. This is a slight
      change of behavior as now the terminating newline will be part of the
      data. In practice this makes no difference as any whitespace is
      ignored via the `isspace` check already.
    - General code cleanup and improvements.
    
    hex/dec prefix optional
    
    Revert to stoll
@@ -7,10 +7,10 @@
// DBline is a generic class which provides an easy interface to access
// formatted data from an input stream. The purpose is to facilitate the
// development of the reading routine (for an ASCII database) and, at the same
// time, to increase its robustness against the varoius changes to which the
// time, to increase its robustness against the various changes to which the
// the database undergoes during the development phase. The flexibility needed
// to deal with each kind of database, was achieved implementing a set of basic
// functionalities which can be componed in a easy way to build a generic
// functionalities which can be composed in a easy way to build a generic
// reading routine.
//
// Considering a generic database whose data are input line by line, each line
@@ -21,15 +21,15 @@
// where <Token> can be any character sequence (including the space character)
// and <set of data> can be one ore more data of different nature that have to
// be read. DBline implements an "extraction" mechanism which allows to select
// a <Token> and to read the releted data (only if the token is found) just in
// one command line. Since the data input is perfomed line by line, such
// a <Token> and to read the related data (only if the token is found) just in
// one command line. Since the data input is performed line by line, such
// "extraction" mechanism requires that the token and the data has to be found
// in the same line of the database. This matches very well the case in which
// the database is made of a set of control directives given in any order (i.e.
// a DATACARD file).
// In order to allow the reading of more complex structures of data which can
// be spanned on more than one line, each "extraction" returns a boolean value
// that can be checked in logical expresssion. Thus, it is possible to activate
// that can be checked in logical expression. Thus, it is possible to activate
// a particular reading schema if a Token is found or to read with it until
// another Token is found. Moreover is also possible to build logical
// expression only with "extraction" procedures:
@@ -41,7 +41,7 @@
// internal buffer to be processed during the extraction of data. The data
// requests are send to DBline and are fulfilled only if the PATTERN (i.e. a
// Token, or a set of Tokens) specified by the user is found into the internal
// buffer. At each succesfull "extraction" the corresponding data (i.e. the
// buffer. At each successful "extraction" the corresponding data (i.e. the
// <Token> and the <related data>) are deleted from the internal buffer.
//
// The implemented operation mode, in which the user can read and process data
@@ -50,7 +50,7 @@
// 1 - Input request. On each input request only a data line is read (i.e.
// data are read until the carriage return character) and is subsequently
// stored into an internal buffer for further analysis. This operation
// cause the deletation of data previously present into the internal
// cause the deletion of data previously present into the internal
// buffer. If the input stream is a file it will be automatically connected
// to the DBline class to allow incremental input line controlled via class
// operators. It is also possible to get input until a token is found; in
@@ -58,18 +58,18 @@
// internal buffer.
//
// 2 - Extraction of data. An extraction request is made of a Token request
// plus a data request. When a Token is found it is extraced from the
// plus a data request. When a Token is found it is extracted from the
// internal buffer and the starting position from which the subsequent data
// are extraced is updated to the actual Token position inside the line. If
// are extracted is updated to the actual Token position inside the line. If
// something goes wrong (no Token found, or line become empty before all
// the requested data are extracted), the extraction stops returning a
// FALSE status, and all the data extracted from the last succesfull Token
// FALSE status, and all the data extracted from the last successful Token
// request are restored into the internal buffer. It is possible to request
// data without specifying a pattern before; in this case the data are
// extracted in a sequential way from the position in which the last
// requested Token was found (if no Token has been succesfully found, the
// requested Token was found (if no Token has been successfully found, the
// starting position is the beginning of the line). Finally it is also
// implemented a mechanism to request more complex pattern, i.e. pattren
// implemented a mechanism to request more complex pattern, i.e. pattern
// like <TOKEN> <data> <SUBTOKEN1> <data> <SUBTOKEN2> <data> .....
//
// 3 - Check for error. Before a new input request the internal buffer is
@@ -124,47 +124,25 @@
//----------------------------------------------------------------------------+
// data >> type use of extractor operator like in an I/O stream. |
// Supported type are: (normal/unsigned) int/long int|
// float, double, string. Other type can be added, |
// but are not currently supported. |
// string. Other types can be added, but are not |
// currently supported. |
//----------------------------------------------------------------------------+
// data.setf( .... ) use of the ios flags like in an I/O stream and |
// setf( ) function works in the same way. |
//----------------------------------------------------------------------------+
// data.hex() set format flags to get data from an hexadec. base|
// data.dbhex() set format flags to get data from an hexadec. base|
//----------------------------------------------------------------------------+
// data.oct() set format flags to get data from an octal base |
// data.dboct() set format flags to get data from an octal base |
//----------------------------------------------------------------------------+
// data.dec() set format flags to get data from a decimal base |
// data.dbdec() set format flags to get data from a decimal base |
//----------------------------------------------------------------------------+
// data.reset_fmt() reset the format flags to default value |
//----------------------------------------------------------------------------+
// data >> hex() same as data.hex() but can be used in I/O sequence|
// data >> data.dbhex same as data.dbhex() but usable in I/O sequence |
//----------------------------------------------------------------------------+
// data >> oct() same as data.oct() but can be used in I/O sequence|
// data >> data.dboct() same as data.dboct() but usable in I/O sequence |
//----------------------------------------------------------------------------+
// data >> dec() same as data.dec() but can be used in I/O sequence|
//----------------------------------------------------------------------------+
// data >> setflags ( ..) same as setf( .. ) but can be used in I/O sequence|
//----------------------------------------------------------------------------+
// data >> resetflags() same as data.reset_fmt() |
//----------------------------------------------------------------------------+
// |
// Lorenzo Bellagamba: 8 March 2011 |
// |
// data >> data.dbhex() to be used in I/O sequence as hex(), dec() and |
// data >> data.dboct() oct() but avoids creation and subsequent |
// data >> data.dbdec() destruction of objects for each I/O operation. |
// Such methods return a pointer to DBfmt* objects |
// created once for ever when the DBline object is |
// instantiated. To preserve the previous |
// functionality a further method |
// data.setdbfmtflag(int) has been introduced. Such method sets a bool |
// private variable (del_dbfmt) which controls the |
// deletion of the DBfmt object in the >> operator. |
// Such bool variable must be false to use these new |
// methods. By default the old functionality is |
// preserved and del_dbfmt=true: |
// setdbfmtflag(0/1) -> del_dbfmt=false/true |
// data >> data.dbdec() same as data.dbdec() but usable in I/O sequence |
//----------------------------------------------------------------------------+
// ******** LOGICAL EXPRESSION ******** |
//----------------------------------------------------------------------------+
@@ -173,7 +151,7 @@
// it is possible that some terms are not evaluated |
// (i.e. some of the extraction requests are not |
// performed); this depends on the result of the |
// previos terms in the logic sequence. |
// previous terms in the logic sequence. |
//----------------------------------------------------------------------------+
// operators |, & combine the results from several extraction |
// requests forcing all the terms present in the |
@@ -192,26 +170,26 @@
// --| ..... process line ......
// --| }
//
// to read the folowing line: < LABEL 1: 12.6 43 "this is a string" >
// to read the following line: < LABEL 1: 43 "this is a string" >
//
// --| float fl; int in; string str;
// --| data("LABEL 1:") >> fl >> in >> str;
// --| int in; string str;
// --| data("LABEL 1:") >> in >> str;
//
// in the following line:
//
// < FIRST 12.6 SECOND 12 "this is a string" THIRD 8 >
// < FIRST 11 SECOND 12 "this is a string" THIRD 8 >
//
// each token can be read in an indipendent way with:
// each token can be read in an independent way with:
//
// --| float fl; int i1,i2; string str;
// --| data("FIRST") >> fl;
// --| data("SECOND") >> i1 >> str;
// --| data("THIRD") >> i2;
// --| int i1,i2,i3; string str;
// --| data("FIRST") >> i1;
// --| data("SECOND") >> i2 >> str;
// --| data("THIRD") >> i3;
//
// or as a whole (i.e. researching the entire sequence in a given order):
//
// --| float fl; int i1,i2; string str;
// --| data("FIRST") >> fl >> "SECOND" >> i1 >> str >> "THIRD" >> i2;
// --| int i1,i2,i3; string str;
// --| data("FIRST") >> i1 >> "SECOND" >> i2 >> str >> "THIRD" >> i3;
//
// to read until the occurrence of a TOKEN:
//
@@ -239,7 +217,7 @@
// --| data++;
// --| } while (data("}"));
//
// to read hexadecimel values:
// to read hexadecimal values:
//
// < value ff >
//
@@ -258,34 +236,36 @@
#include <ctype.h>
#include <stdint.h>
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <string_view>
#include <typeinfo>
typedef enum result_extraction { not_extracted, extracted } DBstatus;
class DBfmt : virtual public std::ios {
class DBfmt : public std::ios {
public:
DBfmt();
};
class DBline : virtual public std::ios {
class DBline : public std::ios {
private:
typedef enum exist_quote { no_quote, begin_quote, end_quote, error } quote;
std::ios::fmtflags m_default;
std::ifstream* m_file;
std::istream* m_stream;
std::string m_data, m_backup, m_store;
unsigned long int m_pos;
int m_line;
bool m_fail;
bool m_empty;
DBstatus m_extraction;
int m_base;
std::ifstream* m_file{nullptr};
std::istream* m_stream{nullptr};
std::string m_data, m_backup;
unsigned long int m_pos{0};
int m_line{0};
bool m_fail{false};
bool m_empty{false};
DBstatus m_extraction{extracted};
int m_base{10};
// Private member functions for setting internal status
void reset_data(void);
@@ -298,90 +278,61 @@ private:
// Private member functions for managing the internal buffer
void erase_comment(void);
void GetToken(unsigned long int pos, const std::string& token);
void GetToken(size_t pos, std::string_view token);
void GetLine(std::istream& input);
// Private member functions for extracting data
template <class type> void GetValue(type& value);
void GetValue(std::string& value);
quote check_quote(std::string&);
quote check_quote(std::string&) const;
void GetStr(std::string&);
// Check if internal buffer is empty
bool check_data(void);
// Private member to manage the I/O format
DBfmt* m_dbfmt_hex;
DBfmt* m_dbfmt_oct;
DBfmt* m_dbfmt_dec;
bool m_del_dbfmt;
DBfmt m_dbfmt_hex;
DBfmt m_dbfmt_oct;
DBfmt m_dbfmt_dec;
public:
DBline();
DBline(std::ifstream& file);
DBline(std::istream& stream);
~DBline() {
delete m_dbfmt_hex;
delete m_dbfmt_oct;
delete m_dbfmt_dec;
}
// Function to connect input file/stream
void connect(std::ifstream& file);
void connect(std::istream& stream);
// Function to get the token
DBline& token(const std::string&);
template <class type> DBline& token(const std::string&, type t);
template <class type> DBline& token(const std::string&, type t, int size);
void go_until(const std::string& token);
DBline& token(std::string_view);
template <class type> DBline& token(std::string_view, type t);
template <class type> DBline& token(std::string_view, type t, int size);
void go_until(std::string_view token);
// Check if exits data into the internal buffer
bool empty(void);
// Dump the processed directives
const char* dump(void);
bool empty(void) const;
// Public functions to set the I/O format
DBline& hex(void);
DBline& dec(void);
DBline& oct(void);
DBline& reset_fmt(void);
DBfmt* dbhex();
DBfmt* dboct();
DBfmt* dbdec();
void setdbfmtflag(int);
const DBfmt& dbhex() const;
const DBfmt& dboct() const;
const DBfmt& dbdec() const;
// Operators for extracting data
// DBline& operator>> (unsigned long int &i);
DBline& operator>>(unsigned long int* i);
// DBline& operator>> (long int &i);
DBline& operator>>(long int* i);
// DBline& operator>> (unsigned int &i);
DBline& operator>>(unsigned int* i);
// DBline& operator>> (unsigned short &i);
DBline& operator>>(unsigned short* i);
DBline& operator>>(int& i);
DBline& operator>>(int* i);
DBline& operator>>(float& f);
DBline& operator>>(float* f);
DBline& operator>>(double& f);
DBline& operator>>(double* f);
DBline& operator>>(std::string& str);
DBline& operator>>(std::string* str);
DBline& operator>>(char& c);
// DBline& operator>> (unsigned char &c);
DBline& operator>>(int& i);
DBline& operator>>(uint8_t& i8);
DBline& operator>>(uint16_t& i16);
DBline& operator>>(uint32_t& i32);
DBline& operator>>(uint64_t& i64);
// Operator for allowing external manipulation of data
DBline& operator>>(DBfmt* f);
DBline& operator>>(const DBfmt& f);
// Operator for subtoken searching
DBline& operator>>(const std::string& token);
DBline& operator>>(std::string_view token);
// Operators for incremental input
DBline& operator++();
@@ -394,11 +345,11 @@ public:
operator DBstatus();
// Operators for extracting tokens
DBline& operator()(const std::string& str);
DBline& operator()(const std::string&, int);
DBline& operator()(const std::string&, int, int);
DBline& operator()(std::string_view);
DBline& operator()(std::string_view, int);
DBline& operator()(std::string_view, int, int);
// Member function for unsing input from streams
// Member function for using input from streams
DBline& operator<<(std::istream& input);
DBline& operator<<(std::ifstream& file);
@@ -408,11 +359,19 @@ public:
friend std::ostream& operator<<(std::ostream& stream, DBline& db);
};
DBfmt* hex(void);
DBfmt* oct(void);
DBfmt* dec(void);
DBfmt* resetflags(void);
DBfmt* setflags(std::ios::fmtflags);
DBfmt* setflags(std::ios::fmtflags, std::ios::fmtflags);
// inline methods
inline bool DBline::check_data(void) {
m_empty = std::all_of(m_data.begin(), m_data.end(), isspace);
return m_empty;
}
inline const DBfmt& DBline::dbhex() const { return m_dbfmt_hex; }
inline const DBfmt& DBline::dboct() const { return m_dbfmt_oct; }
inline const DBfmt& DBline::dbdec() const { return m_dbfmt_dec; }
inline bool DBline::empty() const { return m_empty; }
#endif
Loading