// // File: Inifile.hh // // Author: Th. Wiegert // // Purpose: Header file for Inifile.cc (derived from inifile.hxx, Rev. 2.1) // // $Id: Inifile.hh 13042 2012-04-23 09:04:07Z mathes $ // /** @file Inifile.hh * Declaration of the class Inifile. * @author Th. Wiegert, FzK */ #ifndef _FdUtil_Inifile_hh_ #define _FdUtil_Inifile_hh_ #include #include #include #include #include #include #ifndef NO_VERSION # include #endif // NO_VERSION namespace FdUtil { /** This module contains functions that support data handling with initialisation text files that are build up like MS-Windows ini-files. By Thomas Wiegert, 27.11.95 - 10.06.98. Example: Let us assume the following entry in a file named "address.ini": @verbatim [Thomas] . . weight= 80 city= 76137 Karlsruhe . [Helmut] . weight= 280 city= 67137 Oggersheim . @endverbatim If we want to get the post code and the town in the group [Thomas] we have to call the following instructions: @li specify file: @verbatim OpenIniFile ("address.ini"); @endverbatim @li specify group (groups are indicated by brackets []): @verbatim SpecifyGroup ("Thomas"); @endverbatim @li getting first entry for "city" as an integer value The argument "city" only has to be passed to get the first entry. @verbatim code = GetFirstValue("city"); // -> 76137 @endverbatim @li getting next entry as a string @verbatim strcpy (city, GetNextString()); // -> "Karlsruhe" @endverbatim @li closing file: @verbatim CloseIniFile(); @endverbatim @note An occuring '\' means skipping to next line and appending it. @todo @li don't use strtok() functions, not thread safe etc. @li probably use the C++ string class */ class Inifile { protected: /** 'tokenizer' following ROOT::TIterator interface. * * This is the standard for of the ini-file: * [Group] * name[whitespace]=[whitespace]value1 [[value2] ...] * * [whitespace] can be a or a character. */ class StringTokenizer { public: StringTokenizer(const char* = ""); virtual ~StringTokenizer() { } /** @return found token or string::npos if no more tokens found. */ virtual std::string operator()(); virtual std::string Next() { return (*this)();} virtual void Reset(); /** Will also execute Reset() */ virtual void Set(std::string&); private: //StringTokenizer& StringTokenizer(const StringTokenizer&); //StringTokenizer& operator=(const StringTokenizer&); std::string fString; }; public: enum { /** Return value if successful. */ kSUCCESS = 0, /** Return value in case of failure. */ kFAIL = -1, }; /** Constructor for the class Inifile. * * Initialize all internal variables and try to open the ini-file * at all possible locations. * * Locations where to search for the file:
* 1. current working directory
* 2. in the directory returned by FdNaming::GetConfigDirectory()
* 3. in the users home directory
* 4. in /opt/auger/etc
* 5. in $FD_ROOT/etc
* 6. in $FDDAS_CONFIG_DIR
* 7. in $FDDAS_BASE_DIR
* 8. in $INIFILE_PATH
*/ Inifile(const char*); /** Constructor for the class Inifile. The file is searched for in: @li the current working directory @li the first passed directory @li the second passed directory */ Inifile(const char*,std::FILE *logfile, const char *secondDir=NULL, const char *thirdDir=NULL); /** Copy constructor of the class Inifile. */ Inifile(const Inifile&); /** Destructor of the class Inifile. */ virtual ~Inifile(); /** Return the current print level (= level of verbosity) for all * instances of this class. */ static unsigned int GetPrintLevel() { return fgPrintLevel; } /** Return the status of the last operation of the ini-file reader. */ int GetStatus() const { return fStatus; } /** Get the name of the current ini-file. */ virtual const char* GetFilename() const { return fFilename.c_str(); } /** Get the first float value for the requested entry. * * If the requested entry is not existing, 0.0 is returned. * If passed, the error variable will contain either Inifile::kSUCCESS or Inifile::kFAIL, * depending on the status of the last action. */ virtual double GetFirstFloat(const char* _entry, int* error = NULL); /** Get the first float value for the requested entry. * * If the requested entry is not existing, the value passed as default * value, is returned. If passed, the error variable will contain either * Inifile::kSUCCESS or Inifile::kFAIL, depending on the status of the last action. */ virtual double GetFirstFloat(const char* _entry, double def_value, int* error = NULL); /** Get the first string value for the requested entry. If the requested * entry is not existing, NULL is returned. */ virtual const char* GetFirstString(const char*); /** Get the first string value for the requested entry. * * If the requested entry is not existing, the value passed as default * value, is returned. * If passed, the error variable will contain either Inifile::kSUCCESS * or Inifile::kFAIL, depending on the status of the last action. */ virtual const char* GetFirstString(const char* _entry, const char* def_str, int* error = NULL); /** Get the first integer value for the requested entry. If the requested entry is not existing, 0 is returned. If passed, the error variable will contain either Inifile::kSUCCESS or Inifile::kFAIL, depending on the status of the last action. */ virtual int GetFirstValue(const char* _entry, int* error = NULL); /** Get the first integer value for the requested entry. * * If the requested entry is not existing, the value passed as default * value, is returned. * If passed, the error variable will contain either Inifile::kSUCCESS or Inifile::kFAIL, * depending on the status of the last action. */ virtual int GetFirstValue(const char* _entry, int def_value, int* error = NULL); /** Get the next float value for the previously requested entry. */ virtual double GetNextFloat(int* error = NULL); /** Get the next float value for the previously requested entry. * * If passed, the error variable will contain either Inifile::kSUCCESS or Inifile::kFAIL, * depending on the status of the last action. */ virtual double GetNextFloat(double def_value,int* error = NULL); /** Get the next string value for the previously requested entry. */ virtual const char * GetNextString(int* error = NULL); /** Get the next string value for the previously requested entry. * * If passed, the error variable will contain either Inifile::kSUCCESS or Inifile::kFAIL, * depending on the status of the last action. */ virtual const char * GetNextString(const char* def_str,int* error = NULL); /** Get the next string value for the previously requested entry. */ virtual int GetNextValue(int* error = NULL); /** Get the next integer value for the previously requested entry. * * If passed, the error variable will contain either Inifile::kSUCCESS or Inifile::kFAIL, * depending on the status of the last action. */ virtual int GetNextValue(int def_value,int* error = NULL); /** Locate the inifile with the specified name in a number of standard * directories. * * If 'filename' has already path specifiers, only this path is * checked for the file. */ static std::string Locate(const char* filename); /** Move the file read pointer to the beginning of the file. */ void Reset(); /** Set the level of verbose debugging. */ static void SetPrintLevel(unsigned int level) { fgPrintLevel = level; } /** Specify the group ['group'] from where to read next. */ virtual int SpecifyGroup(const char *str); protected: /** Close the current file. */ virtual void Close(); /** Internal method: convert a digit to a value. */ char Digit2Value(char digit); /** Internal method: convert digits to a value. */ char Digits2Value(char** src, char* end, int base); /** Internal method: read one character. */ char GetNextCharacter(char** src, char* end); /** Internal method: read a line from the file and strip comments. */ std::size_t GetLine(); /** Open the specified file. * * If successful, the fInifile file handle is set. * * @return kSuccess on success, kFAIL else. */ virtual int Open(const char *filename); /** Open the file 'fFilename'. */ virtual int Open(); /** Set the 'fStatus' attribute. */ void SetStatus(int status) { fStatus = status; } /** Search if the specified inifile is in a certain directory. * * If this is the case, directory and name are concatenated and returned. */ static std::string TestFile(const std::string directory, const std::string filename); private: // these ones are not allowed Inifile(); Inifile& operator=(const Inifile&); static unsigned int fgPrintLevel; std::ifstream fInifile; std::string fLinebuf; std::string fFilename; std::string fGroup; std::size_t fLineptr; char *fPtr; std::streampos fGrPos; // result of tellg(), input to seekg() int fStatus; }; } // namespace FdUtil #endif // _FdUtil_Inifile_hh_