]> vaikene.ee Git - evaf/blob - src/libs/Common/inifile_p.h
07ac793cdc8347ccc72c446c6cc0f54c767aecc9
[evaf] / src / libs / Common / inifile_p.h
1 /**
2 * @file Common/inifile_p.h
3 * @brief Internal implementation of the class for reading and writing parameter values in INI files.
4 * @author Enar Vaikene
5 *
6 * Copyright (c) 2011-2019 Enar Vaikene
7 *
8 * This file is part of the eVaf C++ cross-platform application development framework.
9 *
10 * This file can be used under the terms of the GNU General Public License
11 * version 3.0 as published by the Free Software Foundation and appearing in
12 * the file LICENSE included in the packaging of this file. Please review the
13 * the following information to ensure the GNU General Public License version
14 * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
15 *
16 * Alternatively, this file may be used in accordance with the Commercial License
17 * Agreement provided with the Software.
18 */
19
20 #ifndef __COMMON_INIFILE_P_H
21 #define __COMMON_INIFILE_P_H
22
23 #include <QSharedData>
24 #include <QExplicitlySharedDataPointer>
25 #include <QHash>
26 #include <QString>
27 #include <QVariant>
28 #include <QDateTime>
29 #include <QFile>
30
31
32 namespace eVaf {
33 namespace Common {
34 namespace Internal {
35
36 /**
37 * INI file value in the internal cache
38 */
39 class IniFileValue : public QSharedData
40 {
41 public:
42
43 IniFileValue(quint64 pos)
44 : QSharedData()
45 , filePos(pos)
46 , thisOsOnly(false)
47 {}
48
49 /**
50 * File position
51 *
52 * Offset of the parameter in the INI file. By seeking the file to this offset value,
53 * the next character read or written will be the beginning of the key name.
54 */
55 quint64 filePos;
56
57 /**
58 * Key name of the parameter
59 */
60 QByteArray name;
61
62 /**
63 * Value from the INI file
64 */
65 QByteArray paramValue;
66
67 /**
68 * Value converted to the final type (defaults to QVariant::Invalid
69 */
70 QVariant value;
71
72 /**
73 * Flag indicating that this value is valid on this OS only
74 */
75 bool thisOsOnly;
76 };
77
78 /**
79 * INI file section in the internal cache
80 */
81 class IniFileSection : public QSharedData
82 {
83 public:
84
85 IniFileSection(quint64 pos)
86 : QSharedData()
87 , filePos(pos)
88 {}
89
90 /**
91 * File position
92 *
93 * Offset of the section in the INI file. By seeking the file to this offset value,
94 * the next character read or written will be the first character of the section.
95 */
96 quint64 filePos;
97
98 /**
99 * Name of the section
100 */
101 QByteArray name;
102
103 /**
104 * List of all the known parameter values in this section
105 *
106 * The key to the hash table is the name of the key for the parameters value.
107 */
108 QHash<QByteArray, QExplicitlySharedDataPointer<IniFileValue> > values;
109
110 };
111
112 /**
113 * Internal implementation of the IniFile class.
114 */
115 class IniFileImpl
116 {
117 public:
118
119 IniFileImpl(QString const & fileName, QIODevice::OpenMode mode);
120
121 ~IniFileImpl();
122
123 QVariant getValue(QByteArray const & paramName, QVariant const & defaultValue);
124
125 bool setValue(QByteArray const & paramName, QVariant const & value);
126
127 inline bool isValid() const { return mValid; }
128
129 inline QString const & fileName() const { return mFileName; }
130
131 inline QString const & errorString() const { return mErrorString; }
132
133
134 private: // Members
135
136 /// Flag indicating that the INI file object is valid and can be used to access the INI file
137 bool mValid;
138
139 /// Name of the INI file
140 QString mFileName;
141
142 /// INI file opening mode
143 QIODevice::OpenMode mMode;
144
145 /// Last human-readable error message if an operation with the INI file failed
146 QString mErrorString;
147
148 /**
149 * Internal cache of sections and parameter values.
150 *
151 * The key to the hash table is the name of the section.
152 */
153 QHash<QByteArray, QExplicitlySharedDataPointer<IniFileSection> > mCache;
154
155 /// When was the INI file modified.
156 QDateTime mLastModified;
157
158
159 private: /// Methods
160
161 /**
162 * Updates items in the internal cache after changes to the INI file
163 * @param pos File offset from where the cache should be updated
164 * @param diff Difference between old and new file offsets
165 *
166 * When a parameter value is modified or a new value inserted, the length of the INI file changes.
167 * Sections and parameters that come after the modified parameter value are shifted and their file
168 * positions changed. This method updates items in the internal cache after changes to the INI file.
169 */
170 void updateCache(quint64 pos, qint64 diff);
171
172 /**
173 * Looks for a section in the INI file
174 * @param file The file object
175 * @param sectionName Name of the section
176 * @return The section object or an invalid object if not found
177 *
178 * This method reads the INI file and looks for the section with the given name. If found, returns the section
179 * object and seeks the file to the first character after the section name.
180 *
181 * If the section is not found, returns an invalid section object and seeks the file to the end of the file.
182 *
183 * The file object is expected to be opened if the mValid flag is true. If the mValid flag is false, looks
184 * only in the cache.
185 */
186 QExplicitlySharedDataPointer<IniFileSection> getSection(QFile & file, QByteArray const & sectionName);
187
188 /**
189 * Looks for a parameter in the INI file
190 * @param file The file object
191 * @param section The section object
192 * @param paramName Name of the parameter
193 * @return The value object or an invalid object if not found
194 *
195 * This method reads the INI file and looks for the parameter with the given name. If found, returns the value
196 * object and seeks the file to the beginning of the line containing the parameter.
197 *
198 * If not found, returns an invalid value object and seeks the file to the end of the section.
199 *
200 * The file object is expected to be opened if the mValid flag is true. If the mValid flag is false, looks
201 * only in the cache.
202 */
203 QExplicitlySharedDataPointer<IniFileValue> getParameter(QFile & file, IniFileSection & section, QByteArray const & paramName);
204
205 };
206
207
208 } // namespace eVaf::Common::Internal
209 } // namespace eVaf::Common
210 } // namespace eVaf
211
212 #endif // inifile_p.h