ALib C++ Library
Library Version: 2412 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
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 Configuration, 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 a 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 a software. This way, changes can easily be taken over into the INI-file in the right syntax that a 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 persistant with a next invocation of the software without again specifying this argument.
    • In 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 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.

    The term "writeback" is a resourced using token "INIWB" 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 field LinesWithReadErrors.
See also
Chapter 7.3 Built-in Class IniFileFeeder of the Programmer's Manual of ALib Camp ALib Configuration for how to use INI-files with ALib.

Reference Documentation

Exceptions
alib::config::Exceptions::ErrorOpeningFile
alib::config::Exceptions::ErrorWritingFile

Definition at line 124 of file inifile.hpp.

#include <inifile.hpp>

Collaboration diagram for 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.
 
lang::system::PathString FileName = nullptr
 The file name.
 
List< MonoAllocator, integerLinesWithReadErrors
 
List< MonoAllocator, SectionSections
 The list of sections.
 

Public Method Index:

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

A monotonic allocator used for allocating sections and entries.

Definition at line 129 of file inifile.hpp.

◆ entryTable

HashMap< MonoAllocator, EntryKey, std::pair<Section*, Entry*>, EntryKey::Hash, EntryKey::EqualTo > 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 224 of file inifile.hpp.

◆ FileComments

String FileComments = nullptr

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

Definition at line 242 of file inifile.hpp.

◆ FileName

lang::system::PathString FileName = nullptr

The file name.

Definition at line 239 of file inifile.hpp.

◆ LinesWithReadErrors

List<MonoAllocator, integer> 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 246 of file inifile.hpp.

◆ Sections

The list of sections.

Definition at line 236 of file inifile.hpp.

Constructor(s) / Destructor Details:

◆ IniFile() [1/2]

IniFile ( )

Default constructor.

Definition at line 39 of file inifile.cpp.

◆ IniFile() [2/2]

IniFile ( const lang::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 256 of file inifile.hpp.

Here is the call graph for this function:

◆ ~IniFile()

~IniFile ( )
inline

Destructor.

Definition at line 260 of file inifile.hpp.

Method Details:

◆ AddComments()

void 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 147 of file inifile.cpp.

Here is the call graph for this function:

◆ Count()

integer Count ( )
inline

Counts the number of entries over all sections.

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

Definition at line 280 of file inifile.hpp.

◆ CreateEntry()

IniFile::Entry * 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 105 of file inifile.cpp.

Here is the call graph for this function:

◆ CreateSection()

IniFile::Section * 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 56 of file inifile.cpp.

Here is the call graph for this function:

◆ DeleteEntry() [1/2]

Entry * 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 325 of file inifile.hpp.

Here is the call graph for this function:

◆ DeleteEntry() [2/2]

IniFile::Entry * 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 89 of file inifile.cpp.

◆ DeleteSection()

IniFile::Section * 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 63 of file inifile.cpp.

◆ Read()

integer Read ( const lang::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(config::Exceptions::ErrorOpeningFile ).

Definition at line 162 of file inifile.cpp.

Here is the call graph for this function:

◆ Reset()

void Reset ( )

Clears all data, resets the internal mono allocator.

Definition at line 46 of file inifile.cpp.

◆ SearchEntry()

std::pair< IniFile::Section *, IniFile::Entry * > 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 115 of file inifile.cpp.

Here is the call graph for this function:

◆ SearchOrCreateSection()

std::pair< IniFile::Section *, bool > 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 138 of file inifile.cpp.

Here is the call graph for this function:

◆ SearchSection()

IniFile::Section * 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 124 of file inifile.cpp.

Here is the call graph for this function:

◆ startsWithCommentSymbol()

bool 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 26 of file inifile.cpp.

Here is the call graph for this function:

◆ Write()

void Write ( const lang::system::PathString & path = lang::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(config::Exceptions::ErrorOpeningFile ).

Definition at line 339 of file inifile.cpp.

Here is the call graph for this function:

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