ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
inifilefeeder.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_variables of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8ALIB_EXPORT namespace alib { namespace variables {
9//==================================================================================================
10/// Adapter type between class \alib{variables;IniFile} and class \alib{variables;Configuration}.
11/// INI-Files contents usually is fed in with bootstrapping an application and optionally be
12/// written out when an application ends (to populate empty INI-files or add new variables to
13/// existing ones). For this, an instance of this type is to be locally created each time. In other
14/// words, no instance of this type needs to be kept in memory during the life-span of an
15/// application.
16/// @see Chapter \ref alib_variables_external_ini of the Programmer's Manual of camp \alib_variables.
17/// @throws alib::variables::Exceptions::ErrorWritingFile \I{CLANGDUMMY}
18//==================================================================================================
20{
21 //==================================== Internals =============================================
22 protected:
23 /// The configuration to work with. Set with construction.
25
26 /// The priority to use to define variables. Set with construction.
28
29 /// The INI-file. Created with methods #ImportStart and #ExportStart.
30 IniFile* iniFile = nullptr;
31
32 /// Implements #ImportSection.
33 ///
34 /// @param section The section to import
35 /// @return The number of variables imported.
37 int importSection( IniFile::Section& section );
38
39
40 //================================== Public Fields ===========================================
41 public:
42 /// The desired maximum width of the INI-file. Defaults to <c>100</c>.
43 /// This value is used with utility method #AddResourcedSectionComments.
44 int LineWidth = 100;
45
46 /// The prefix that is used for comment lines of sections or variables that have been
47 /// added 'in code' (variables that have not been read from the file).
48 /// Comments that were read from the file preserve their prefix.
49 /// If comments including one of the valid prefixes are added to a variable or section
50 /// 'in code', such prefix is preserved.
52
53 //============================= Constructors/destructor ======================================
54 public:
55 /// Constructor.
56 /// @param pConfiguration Stored in field #configuration.
57 /// @param pPriority Stored in field #priority.
58 /// \alib{variables;Priority;ConfigFile}.
59 IniFileFeeder( Configuration& pConfiguration, Priority pPriority= Priority::ConfigFile )
60 : configuration(pConfiguration)
61 , priority (pPriority) {}
62
63 /// Virtual destructor. \ref alib_mod_assert "Raises an ALib warning" in debug-compilations,
64 /// if the internal INI-file was not disposed before deletion. Disposal is made with methods
65 /// #ImportEnd and ExportEnd.
67 {
68 #if ALIB_DEBUG && !ALIB_DEBUG_ASSERTION_PRINTABLES
69 ALIB_ASSERT_WARNING(iniFile == nullptr, "VARIABLES",
70 "Export or import sequence not completed before deleting the INI-file.\n"
71 "Filename of previous sequence: {}", iniFile->FileName )
72 delete iniFile;
73 #endif
74
75 }
76
77 //==================================== Interface =============================================
78 /// Imports all entries in the section named \p{sectionName} in the underlying INI-file into
79 /// the configuration.
80 /// @param sectionName The name of the section to import.
81 /// @return The number of variables imported.
83 int ImportSection( const String& sectionName );
84
85 /// Imports all entries in the section named \p{sectionName} in the underlying INI-file into
86 /// the configuration. This special version of the method accepts parameter \p{typeName}
87 /// and hence declares the variables in case they have not been declared, yet.
88 ///
89 /// \note
90 /// This method is useful to load a section of variables of the same type with a) avoiding to
91 /// set preset string and b) with the advantage that a using code may use
92 /// \alib{variables;Variable::Try} to find the variable already.<br>
93 /// This method may be used for example with camp \alib_expressions to declare nested
94 /// expressions to an \alib{expressions;StandardRepository}.
95 /// @param sectionName The name of the section to import.
96 /// @param typeName The type of the variable to declare.
97 /// @return The number of variables imported.
99 int ImportSection( const String& sectionName, const String& typeName );
100
101 /// Imports all entries found INI-file into the configuration. Variables which are already
102 /// declared and have a lower priority definition, will be set with the value found.
103 /// Otherwise, a \alib{variables;Configuration::PresetImportString;preset string} is set for the
104 /// variable.
105 /// @return The number of variables imported.
107 int ImportAll();
108
109 /// Creates the internal \p{iniFile} instance.
110 /// @param path The filepath to the INI-file.
111 /// @return A pointer to the (otherwise internal) \alib{variables;IniFile} object that was opened.
112 /// Use with caution. Could be used for example to detect the fact that the INI-file
113 /// was empty or not found.
115 {
116 if( iniFile != nullptr )
117 {
118 ALIB_ASSERT_WARNING(iniFile == nullptr, "VARIABLES",
119 "Export or import sequence not completed before starting a new one.\n"
120 "Previous filename: ", iniFile->FileName )
121 delete iniFile;
122 }
123 iniFile= new IniFile(path);
124 return iniFile;
125 }
126
127 /// Creates the internal \p{iniFile} instance.
128 /// @param path The filepath to the INI-file.
129 /// @return A pointer to the (otherwise internal) \alib{variables;IniFile} object that was opened.
130 /// Use with caution. Could be used for example to detect the fact that the INI-file
131 /// was empty or not found.
133 {
134 return ImportStart(path); // this is just the very same as ImportStart()
135 }
136
137 /// Closes and deletes the internal \p{iniFile} instance.
139 {
140 if(iniFile == nullptr)
141 {
142 ALIB_ERROR( "VARIABLES", "No INI-file loaded when trying to end import/export." )
143 return;
144 }
145 delete iniFile;
146 iniFile= nullptr;
147 }
148
149 /// Closes and deletes the internal \p{iniFile} instance without writing an opened INI-file.
150 void ExportEnd() { ImportEnd(); }
151
152 /// Writes the contents of the internal \p{iniFile} instance created with #ExportStart into
153 /// an (optionally) different file and then deletes the instance.
154 /// @param path The file path for writing.
155 void ExportEnd(const system::Path& path )
156 {
157 if(iniFile == nullptr)
158 {
159 ALIB_ERROR( "VARIABLES", "No INI-file loaded when trying to import data." )
160 return;
161 }
162 iniFile->Write(path);
163 delete iniFile;
164 iniFile= nullptr;
165 }
166
167
168 /// Writes the given variable to the internal INI-file.
169 /// If an INI-file was previously loaded, only those variables which are not existing in the
170 /// INI-file are written. This method can thus be used to "populate" an empty INI-file with
171 /// variables and their resourced or hard-coded default values and this way present all
172 /// configurable options to an end-user.
173 ///
174 /// Furthermore, a user can specify the word "writeback" (respectively what is resourced
175 /// with to token <c>"CFGIniWB"</c>) to force overwriting the INI-file contents with the current
176 /// value of the variable.
177 ///
178 /// @param var The variable to export.
179 /// @return \c true if the variable either did not exist yet in the INI-file or if it existed
180 /// and the write-back mechanism was in place. \c false otherwise.
182 bool Export( const Variable& var );
183
184 /// Creates a variable cursor with the given \p{cfg} and \p{path} and passes it to overloaded
185 /// method #Export(const Variable&).
186 /// @param path The path of the variable to export.
187 /// @return \c true if the variable either did not exist yet in the INI-file or if it existed
188 /// and the write-back mechanism was in place. \c false otherwise.
189 bool Export(const String& path)
190 {
191 auto cursor= configuration.Root();
192 auto remainder= cursor.GoTo(path);
193 if( remainder.IsNotEmpty() )
194 {
195 ALIB_WARNING("VARIABLES", "Configuration variable path \"{}\" to export not found.",
196 path)
197 return false;
198 }
199 return Export( Variable(cursor) );
200 }
201
202
203 /// Writes all variables below the given \alib{containers;StringTree::Cursor}
204 /// of the \alib{variables;Configuration} into the #iniFile, previously created with #ExportStart.
205 /// If an INI-file was previously loaded, only those variables which are not existing in the
206 /// INI-file are written.
207 /// This method can thus be used to "populate" an empty INI-file with default values and
208 /// this way present all configurable options to an end-user.
209 ///
210 /// Furthermore, a user can specify the word "writeback" (respectively what is resourced
211 /// with to token <c>"CFGIniWB"</c>) to force overwriting the INI-file contents with the current
212 /// value of the variable.
213 ///
214 /// @param cursor A cursor into the configuration's \alib{containers;StringTree}.
215 /// @param directChildrenOnly If \c true, only the direct children of this cursor are written
216 /// as variables. Defaults to \c false.
217 /// @return The number of variables exported. A negative value on error.
219 int ExportSubTree( Configuration::Cursor cursor, bool directChildrenOnly= false );
220
221 /// Invokes #ExportSubTree(Configuration::Cursor, bool) by creating a cursor from the given
222 /// \p{path}
223 /// @param path The path to the subtree (or single variable) to use.
224 /// @param directChildrenOnly If \c true, only the direct children of this \p{path} are written
225 /// as variables. Defaults to \c false.
226 /// @return The number of variables exported. A negative value on error.
227 int ExportSubTree( const String& path, bool directChildrenOnly= false )
228 {
229 auto cursor= configuration.Root();
230 auto remainder= cursor.GoTo(path);
231 if( remainder.IsNotEmpty() )
232 {
233 ALIB_WARNING("VARIABLES", "Configuration variable path \"{}\" to export not found.")
234 return -1;
235 }
236
237 return ExportSubTree( cursor, directChildrenOnly );
238 }
239
240 /// Searches the entry of the internal INI-file that represents the given \p{variable}
241 /// @param variable The variable to search in the INI-file.
242 /// @return The section and entry if found. If not found, the second member of the pair is
243 /// emtpy.
245 std::pair<IniFile::Section*, IniFile::Entry*> SearchEntry ( const Variable& variable );
246
247 /// Searches the entry of the internal INI-file that represents the given variable determined
248 /// by parameter \p{path}
249 /// @param path The path of the variable to search in the INI-file.
250 /// @return The section and entry if found. If not found, the second member of the pair is
251 /// emtpy.
253 std::pair<IniFile::Section*, IniFile::Entry*> SearchEntry ( const String& path );
254
255 /// This method may be used to set the \ref config_IniFile_writebackflag "writeback flag"
256 /// of an entry in the associated INI-file. The flag is only set if the entry was
257 /// programmaticaly created (usually with one of the <b>Export</b>-methods of this class) and
258 /// if it was not present in the INI-file before.
259 /// @see Chapter \ref alib_variables_external_session of the Programmer's Manual of module
260 /// \alib_variables_nl.
261 /// @param path The path of the variable to export.
262 /// @return \c true if the variable did exist and was newly added to the INI-file, \c false
263 /// otherwise.
265 bool SetWriteBackFlag( const String& path );
266
267 /// Invokes overloaded method #SetWriteBackFlag(const String& path).
268 /// @param var The variable to modifiy.
269 /// @return \c true if the variable did exist and was newly added to the INI-file, \c false
270 /// otherwise.
272 bool SetWriteBackFlag( const Variable& var );
273
274 #if ALIB_RESOURCES
275 //==============================================================================================
276 /// This is a utility function that reads section comments from
277 /// \ref alib_mod_resources "externalized string resources".
278 ///
279 /// All sections of the underlying INI-file are processed, but resourced comments
280 /// are only added in the case that a section's comment string is \c nulled. This is not the
281 /// case if a section was read from from an INI-file, as even if no comments are given,
282 /// the field is empty, but not \e nulled. In other words, only sections that have been
283 /// programmatically added during the run of software are changed<br>
284 /// This approach allows a user to remove the comments, without the software restoring them.
285 ///
286 /// The resource names are assembled from given \p{resourceNamePrefix} and the section name
287 /// The resource strings found are processed using method
288 /// \alib{format;Paragraphs.AddMarked}. This allows using text macros like <b>'\@HL'</b>
289 /// to format the text.
290 ///
291 /// \see
292 /// Field #LineWidth, which is respected when formatting comment lines.
293 ///
294 /// @param resourcePool The resource pool to use.
295 /// @param resourceCategory The category of the resourced comments.
296 /// @param resourceNamePrefix A prefix of the resource name.
297 /// @return The number of section comments written. This is useful to detect if the INI-file
298 /// needs to be written.
299 //==============================================================================================
301 const NString& resourceCategory,
302 const NString& resourceNamePrefix );
303 #endif
304
305 /// Allows access to the internal INI-file object created with either method #ImportStart or
306 /// #ExportStart. In debug-compilations, this method asserts that an INI-file was opened.
307 /// In release-compilations, a non-existing INI-file leads to undefined behavior.
308 /// @return The currently opened INI-File.
310 {
311 ALIB_ASSERT_ERROR( iniFile != nullptr, "VARIABLES",
312 "No INI-file loaded when trying to access it." )
313 return *iniFile;
314 }
315
316}; // class IniFileFeeder
317
318
319} // namespace alib[::config]
320
321/// Type alias in namespace \b alib.
323
324} // namespace [alib]
IniFile * ExportStart(const system::Path &path)
void ExportEnd()
Closes and deletes the internal iniFile instance without writing an opened INI-file.
ALIB_DLL std::pair< IniFile::Section *, IniFile::Entry * > SearchEntry(const Variable &variable)
ALIB_DLL int AddResourcedSectionComments(ResourcePool &resourcePool, const NString &resourceCategory, const NString &resourceNamePrefix)
ALIB_DLL int ExportSubTree(Configuration::Cursor cursor, bool directChildrenOnly=false)
IniFile * iniFile
The INI-file. Created with methods ImportStart and ExportStart.
void ExportEnd(const system::Path &path)
bool Export(const String &path)
ALIB_DLL bool SetWriteBackFlag(const String &path)
Configuration & configuration
The configuration to work with. Set with construction.
ALIB_DLL int ImportSection(const String &sectionName)
void ImportEnd()
Closes and deletes the internal iniFile instance.
ALIB_DLL int importSection(IniFile::Section &section)
IniFile * ImportStart(const system::Path &path)
Priority priority
The priority to use to define variables. Set with construction.
ALIB_DLL bool Export(const Variable &var)
int ExportSubTree(const String &path, bool directChildrenOnly=false)
IniFileFeeder(Configuration &pConfiguration, Priority pPriority=Priority::ConfigFile)
#define ALIB_DLL
Definition alib.inl:496
#define A_CHAR(STR)
#define ALIB_WARNING(domain,...)
Definition alib.inl:1046
#define ALIB_ASSERT_WARNING(cond, domain,...)
Definition alib.inl:1050
#define ALIB_ERROR(domain,...)
Definition alib.inl:1045
#define ALIB_EXPORT
Definition alib.inl:488
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1049
variables::IniFileFeeder IniFileFeeder
Type alias in namespace alib.
variables::Variable Variable
Type alias in namespace alib.
strings::TString< nchar > NString
Type alias in namespace alib.
Definition string.inl:2390
resources::ResourcePool ResourcePool
Type alias in namespace alib.
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2381
A section of the INI-file.
Definition inifile.inl:145