/** * @file Common/inifile_p.h * @brief Internal implementation of the class for reading and writing parameter values in INI files. * @author Enar Vaikene * * Copyright (c) 2011-2019 Enar Vaikene * * This file is part of the eVaf C++ cross-platform application development framework. * * This file can be used under the terms of the GNU General Public License * version 3.0 as published by the Free Software Foundation and appearing in * the file LICENSE included in the packaging of this file. Please review the * the following information to ensure the GNU General Public License version * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. * * Alternatively, this file may be used in accordance with the Commercial License * Agreement provided with the Software. */ #ifndef __COMMON_INIFILE_P_H #define __COMMON_INIFILE_P_H #include #include #include #include #include #include #include namespace eVaf { namespace Common { namespace Internal { /** * INI file value in the internal cache */ class IniFileValue : public QSharedData { public: IniFileValue(qint64 pos) : QSharedData() , filePos(pos) , thisOsOnly(false) {} /** * File position * * Offset of the parameter in the INI file. By seeking the file to this offset value, * the next character read or written will be the beginning of the key name. */ qint64 filePos; /** * Key name of the parameter */ QByteArray name; /** * Value from the INI file */ QByteArray paramValue; /** * Value converted to the final type (defaults to QVariant::Invalid */ QVariant value; /** * Flag indicating that this value is valid on this OS only */ bool thisOsOnly; }; /** * INI file section in the internal cache */ class IniFileSection : public QSharedData { public: IniFileSection(qint64 pos) : QSharedData() , filePos(pos) {} /** * File position * * Offset of the section in the INI file. By seeking the file to this offset value, * the next character read or written will be the first character of the section. */ qint64 filePos; /** * Name of the section */ QByteArray name; /** * List of all the known parameter values in this section * * The key to the hash table is the name of the key for the parameters value. */ QHash > values; }; /** * Internal implementation of the IniFile class. */ class IniFileImpl { public: IniFileImpl(QString const & fileName, QIODevice::OpenMode mode); ~IniFileImpl(); QVariant getValue(QByteArray const & paramName, QVariant const & defaultValue); bool setValue(QByteArray const & paramName, QVariant const & value); inline bool isValid() const { return mValid; } inline QString const & fileName() const { return mFileName; } inline QString const & errorString() const { return mErrorString; } private: // Members /// Flag indicating that the INI file object is valid and can be used to access the INI file bool mValid; /// Name of the INI file QString mFileName; /// INI file opening mode QIODevice::OpenMode mMode; /// Last human-readable error message if an operation with the INI file failed QString mErrorString; /** * Internal cache of sections and parameter values. * * The key to the hash table is the name of the section. */ QHash > mCache; /// When was the INI file modified. QDateTime mLastModified; private: /// Methods /** * Updates items in the internal cache after changes to the INI file * @param pos File offset from where the cache should be updated * @param diff Difference between old and new file offsets * * When a parameter value is modified or a new value inserted, the length of the INI file changes. * Sections and parameters that come after the modified parameter value are shifted and their file * positions changed. This method updates items in the internal cache after changes to the INI file. */ void updateCache(qint64 pos, qint64 diff); /** * Looks for a section in the INI file * @param file The file object * @param sectionName Name of the section * @return The section object or an invalid object if not found * * This method reads the INI file and looks for the section with the given name. If found, returns the section * object and seeks the file to the first character after the section name. * * If the section is not found, returns an invalid section object and seeks the file to the end of the file. * * The file object is expected to be opened if the mValid flag is true. If the mValid flag is false, looks * only in the cache. */ QExplicitlySharedDataPointer getSection(QFile & file, QByteArray const & sectionName); /** * Looks for a parameter in the INI file * @param file The file object * @param section The section object * @param paramName Name of the parameter * @return The value object or an invalid object if not found * * This method reads the INI file and looks for the parameter with the given name. If found, returns the value * object and seeks the file to the beginning of the line containing the parameter. * * If not found, returns an invalid value object and seeks the file to the end of the section. * * The file object is expected to be opened if the mValid flag is true. If the mValid flag is false, looks * only in the cache. */ QExplicitlySharedDataPointer getParameter(QFile & file, IniFileSection & section, QByteArray const & paramName); }; } // namespace eVaf::Common::Internal } // namespace eVaf::Common } // namespace eVaf #endif // inifile_p.h