ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
alib::variables::IniFile Class Reference

Description:

This class implements a rather simple foundation for reading and writing INI-Files.

Note
This class is not considered to be used directly to interface into the ALib configuration system implemented with camp ALib Variables, which introduces this class. Instead, class IniFileFeeder provides all mechanics to easily use INI-files. For this reason, there is no type alias defined for this class in namespace alib.

The design goal was to preserve any user formatting of the INI-file as much as possible. Thus, if the INI-file is written without any modification since it was read from a file, the resulting file should quite exactly in respect comments, values and even whitespaces. Exceptions are:

  • Whitespaces at the end of lines, are trimmed.
  • Sections that occur more than one time in the original file, are merged into one (the first) occurrence.
  • Some empty lines are removed.

When read, a linked list of INI-file sections is created and within each section a list of variables is created. The linked lists allow to write sections and their variables in the same order they have been read. In addition to the lists, a hashtable is created which allows finding variables quickly. To find a section, the section list is iterated.

After a file has been read (or also on a blank instance of this class), sections and variables can be manipulated (insert, delete, modify). It is also possible to read one or more files in a sequence and write a merged INI-file back.

This class does not perform any interpretation of the variable values. Neither escape sequences are converted, nor array values parsed or anything. Instead, the "raw" value of each variable, including the equal sign '=' after the variable name is stored. It is up to other types to parse and interpret variable values and to convert a programm's variable values to strings which can be stored in INI-files (ASCII or UTF8 files).

Attention
This class is also not designed to be used as a variable store with continued modifications during a run of software. The class performs monotonic allocation but does not implement recycling of any objects (sections, variables, comments, values, etc.). Instead, the allocated memory is continued to grow with any operation.
This is a design decision and the class is meant to be used rather along the following approach:
  • Load an INI-file at the start of an application, transfer the values to a different place and then delete the instance of this class.
  • Before terminating an application, load the file again, perform appropriate changes, write the file back and delete the instance of this class.
Such approach is implemented with type IniFileFeeder. Hence, the direct use of this class is not recommended, instead use the techniques described in chapter 7.3 Built-in Class IniFileFeeder of the Programmer's Manual of this ALib Camp.

Some remarks on the functionality and supported format:

  • Comments
    • Lines that start (apart from whitespace) with either a double slash "//", a sharp sign '#' or a semicolon ';' are comment lines.
    • Comment lines at the beginning of the file are associated with the file and are written back. Such comment block is stopped with the first single blank line.
    • Comment lines and empty lines before sections and variables are associated with the respective objects.
    • Comments cannot reside in the same line together with section names or variables.
  • Sections
    • Sections names are enclosed by brackets '[' and ']'.
    • Section names can be repeated. In this case the corresponding section is continued. As mentioned above, when the file is written, the sections are merged.
  • Variables
    • Variable names and their values are separated by an equal sign '='.
    • Variables definition are being continued (values are concatenated) if the line ends with a backslash '\'.
    • Comment lines in-between continued lines are recognized as such. To continue a variable after a 'continued' comment line, the comment line needs to end with a backslash '\'.

  • Writeback Attribution
    This is a non-standard feature of this class. Anywhere in the file, a line with the term writeback may appear. This flags the next section or variable to be written back by software. This way, changes can easily be taken over into the INI-file in the right syntax that software expects. In the case of using class Configuration and associated type IniFileFeeder (the intended case!), the following use-cases can be achieved:

    • Command line argument might be used overwrite INI-file values. Using this flag, such overwrites become persistent with the next invocation of the program without again specifying this argument.
    • In the case of interactive software, changes may come from a user manipulating configuration dialogs. If the user had specified "writeback", this configuration change would automatically end up in the INI-file, even if the software does not provide its own mechanics for this.
    • Session-related variables can be stored and updated in the INI-file, hence without creating a distinct temporary session file. This is useful for rather volatile variables and such that are implementing convenience features, rather than basic functionality.

    In the case that module ALib Camp is included in the ALib Build, the term "writeback" is a token resourced in class Basecamp with key "CFGIniWB" and thus can be localized (translated to a different language) as appropriate.

  • Erroneous Lines
    Lines with errors are ignored and not written back. Line numbers with erroneous lines are collected in the field LinesWithReadErrors.
See also
Chapter 7.3 Built-in Class IniFileFeeder of the Programmer's Manual of ALib Camp ALib Variables for how to use INI-files with ALib.

Reference Documentation

Exceptions
alib::variables::Exceptions::ErrorOpeningFile
alib::variables::Exceptions::ErrorWritingFile

Definition at line 117 of file inifile.inl.

Collaboration diagram for alib::variables::IniFile:
[legend]

Inner Type Index:

struct  Entry
 An entry in a Section. More...
 
struct  EntryKey
 Hash functor for nodes hashed in field entryTable. Ignores letter case. More...
 
struct  Section
 A section of the INI-file. More...
 

Public Field Index:

MonoAllocator Allocator
 A monotonic allocator used for allocating sections and entries.
 
String FileComments = nullptr
 The file header which will be written out as a comment lines with "# " prefixes.
 
system::PathString FileName = nullptr
 The file name.
 
List< MonoAllocator, integerLinesWithReadErrors
 
List< MonoAllocator, SectionSections
 The list of sections.
 

Public Method Index:

ALIB_DLL IniFile ()
 Default constructor.
 
 IniFile (const system::Path &path)
 
 ~IniFile ()
 Destructor.
 
ALIB_DLL void AddComments (String &dest, const String &comments, const String &prefix=A_CHAR("# "))
 
integer Count ()
 
ALIB_DLL EntryCreateEntry (Section *section, const String &name)
 
ALIB_DLL SectionCreateSection (const String &name)
 
EntryDeleteEntry (const String &sectionName, const String &name)
 
ALIB_DLL EntryDeleteEntry (Section *section, const String &name)
 
ALIB_DLL SectionDeleteSection (const String &name)
 
ALIB_DLL integer Read (const system::CPathString &path)
 
ALIB_DLL void Reset ()
 Clears all data, resets the internal mono allocator.
 
ALIB_DLL std::pair< Section *, Entry * > SearchEntry (const String &section, const String &name)
 
ALIB_DLL std::pair< Section *, bool > SearchOrCreateSection (const String &sectionName)
 
ALIB_DLL SectionSearchSection (const String &sectionName)
 
ALIB_DLL void Write (const system::PathString &path=system::NULL_PATH)
 

Protected Field Index:

HashMap< MonoAllocator, EntryKey, std::pair< Section *, Entry * >, EntryKey::Hash, EntryKey::EqualToentryTable
 

Protected Method Index:

bool startsWithCommentSymbol (String &subs)
 

Field Details:

◆ Allocator

MonoAllocator alib::variables::IniFile::Allocator

A monotonic allocator used for allocating sections and entries.

Definition at line 122 of file inifile.inl.

◆ entryTable

HashMap< MonoAllocator, EntryKey, std::pair<Section*, Entry*>, EntryKey::Hash, EntryKey::EqualTo > alib::variables::IniFile::entryTable
protected

The entry hash set. This is used to find entries by section name and entry name. The set contains all entries of all sections.

Definition at line 217 of file inifile.inl.

◆ FileComments

String alib::variables::IniFile::FileComments = nullptr

The file header which will be written out as a comment lines with "# " prefixes.

Definition at line 235 of file inifile.inl.

◆ FileName

system::PathString alib::variables::IniFile::FileName = nullptr

The file name.

Definition at line 232 of file inifile.inl.

◆ LinesWithReadErrors

List<MonoAllocator, integer> alib::variables::IniFile::LinesWithReadErrors

Filled with faulty line numbers when reading the file. (E.g., when a line is no section, no comment and not the attribute "writeback", but still has no equal sign ('=').

Definition at line 239 of file inifile.inl.

◆ Sections

List<MonoAllocator, Section> alib::variables::IniFile::Sections

The list of sections.

Definition at line 229 of file inifile.inl.

Constructor(s) / Destructor Details:

◆ IniFile() [1/2]

alib::variables::IniFile::IniFile ( )

Default constructor.

Definition at line 70 of file inifile.cpp.

◆ IniFile() [2/2]

alib::variables::IniFile::IniFile ( const system::Path & path)
inline

Constructs an instance of this class and reads the file specified with path.

Parameters
pathThe filepath to the INI-file.

Definition at line 249 of file inifile.inl.

Here is the call graph for this function:

◆ ~IniFile()

alib::variables::IniFile::~IniFile ( )
inline

Destructor.

Definition at line 253 of file inifile.inl.

Method Details:

◆ AddComments()

void alib::variables::IniFile::AddComments ( String & dest,
const String & comments,
const String & prefix = A_CHAR("# ") )

Parses the comments for newline tokens and adds given comment prefix to each line (in case no known comment prefix is present, yet). Then storage is allocated and output reference dest is set accordingly.

Parameters
destThe destination string to set.
commentsThe comments to add.
prefixThe prefix to use if no other prefixes were found. Defaults to "# ".

Definition at line 178 of file inifile.cpp.

Here is the call graph for this function:

◆ Count()

integer alib::variables::IniFile::Count ( )
inline

Counts the number of entries over all sections.

Returns
The number of "variables" in this INI-file.

Definition at line 273 of file inifile.inl.

◆ CreateEntry()

IniFile::Entry * alib::variables::IniFile::CreateEntry ( Section * section,
const String & name )

Creates a new entry. Must be invoked only if the entry does not exist, yet. The given entry name is copied to the internal allocator.

Parameters
sectionThe section.
nameThe name of the entry to be created.
Returns
The entry found or created.

Definition at line 136 of file inifile.cpp.

Here is the call graph for this function:

◆ CreateSection()

IniFile::Section * alib::variables::IniFile::CreateSection ( const String & name)

Appends a new section to the end of the list of sections. Must be invoked only if a section with the same name does not exist, yet.

See also
Method SearchOrCreateSection.
Parameters
nameThe name of the section.
Returns
The created section.

Definition at line 87 of file inifile.cpp.

◆ DeleteEntry() [1/2]

Entry * alib::variables::IniFile::DeleteEntry ( const String & sectionName,
const String & name )
inline

Deletes an entry. This overloaded searches the section by its name first.

Parameters
sectionNameThe section.
nameThe name of the entry to be deleted.
Returns
The entry deleted. If not found, nullptr is returned. The entry will still be a valid and accessible object within the monotonic allocator.

Definition at line 318 of file inifile.inl.

Here is the call graph for this function:

◆ DeleteEntry() [2/2]

IniFile::Entry * alib::variables::IniFile::DeleteEntry ( Section * section,
const String & name )

Deletes an entry.

Parameters
sectionThe section of the entry.
nameThe name of the entry to be deleted.
Returns
The entry deleted. If not found, nullptr is returned. The entry will still be a valid and accessible object within the mono allocator.

Definition at line 120 of file inifile.cpp.

◆ DeleteSection()

IniFile::Section * alib::variables::IniFile::DeleteSection ( const String & name)

Deletes a section.

Parameters
nameThe name of the section to be deleted.
Returns
The deleted section. If not found, nullptr is returned. The section will still be a valid and accessible object within the mono allocator.

Definition at line 94 of file inifile.cpp.

◆ Read()

integer alib::variables::IniFile::Read ( const system::CPathString & path)

Reads an INI-File and adds its contents to the existing data. In case only the new entries should be contained, use method Reset to delete existing data before invoking this function.

It might happen that lines are ignored or otherwise marked as faulty. All numbers of such lines get collected in field LinesWithReadErrors.

Any other i/o errors throws, with the exception of "file not found", which simply returns -1.

Parameters
pathThe file to read and write.
Returns
-1 if the file does not exist. Otherwise the number of entries read.
Exceptions
Exception(variables::Exceptions::ErrorOpeningFile ). In the case the module ALib Camp is not included in the ALib Build, then a std::runtime_error("ErrorOpeningFile") may be thrown.

Definition at line 193 of file inifile.cpp.

Here is the call graph for this function:

◆ Reset()

void alib::variables::IniFile::Reset ( )

Clears all data, resets the internal mono allocator.

Definition at line 77 of file inifile.cpp.

◆ SearchEntry()

std::pair< IniFile::Section *, IniFile::Entry * > alib::variables::IniFile::SearchEntry ( const String & section,
const String & name )

Searches an entry with the given name. The search is performed case-insensitive.

Parameters
sectionThe name of the section
nameThe name of the entry to be searched.
Returns
The section and entry if found, a nulled pair if not found.

Definition at line 146 of file inifile.cpp.

Here is the call graph for this function:

◆ SearchOrCreateSection()

std::pair< IniFile::Section *, bool > alib::variables::IniFile::SearchOrCreateSection ( const String & sectionName)

Searches the section with the given name.

Parameters
sectionNameThe name of the section to be retrieved.
Returns
Returns the section if it was found, nullptr otherwise.

Definition at line 169 of file inifile.cpp.

Here is the call graph for this function:

◆ SearchSection()

IniFile::Section * alib::variables::IniFile::SearchSection ( const String & sectionName)

Searches the section with the given name.

Parameters
sectionNameThe name of the section to be retrieved.
Returns
Returns the section if it was found, nullptr otherwise.

Definition at line 155 of file inifile.cpp.

Here is the call graph for this function:

◆ startsWithCommentSymbol()

bool alib::variables::IniFile::startsWithCommentSymbol ( String & subs)
protected

Tests if the given string starts with '#', ';' or '//'.

Parameters
subsThe string to test.
Returns
true if this is a comment line, false otherwise.

Definition at line 57 of file inifile.cpp.

Here is the call graph for this function:

◆ Write()

void alib::variables::IniFile::Write ( const system::PathString & path = system::NULL_PATH)

Writes the data into the file.

Parameters
pathThe file to to write. If this is nulled, the default, then the same file name as with the last Read is used.
Exceptions
Exception(variables::Exceptions::ErrorOpeningFile ). In the case the module ALib Camp is not included in the ALib Build, then a std::runtime_error("ErrorWritingFile") may be thrown.

Definition at line 378 of file inifile.cpp.

Here is the call graph for this function:

The documentation for this class was generated from the following files: