8#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
9# error "Configuration MACRO ALIB_C20_MODULES has to be given to the compiler as either 0 or 1"
21 module ALib.Variables.IniFile;
24 import ALib.Strings.Tokenizer;
25 import ALib.Strings.StdIOStream;
27 import ALib.EnumRecords;
29 import ALib.Exceptions;
32 import ALib.Variables;
33 import ALib.Camp.Base;
61 || ( c ==
'/' && subs.
Length() > 1 && subs.
CharAt(1) ==
'/' );
94 if( secIt->Name.Equals(name)) {
95 auto* section= &*secIt;
98 if( entryIt->second.SectionPointer == section ) {
111 for(
auto entryIt= section->
Entries.begin() ; entryIt != section->
Entries.end(); ++entryIt ) {
113 if( entryIt->Name.Equals(name)) {
114 auto* entry= &*entryIt;
126 Handle{section, &newEntry} );
136 return Handle{
nullptr,
nullptr};
150std::pair<IniFile::Section*, bool>
154 return std::make_pair( s,
false );
179 file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
185 if ( !file.is_open() || errno ) {
198 String4K actComments;
ALIB_DBG( actComments.DbgDisableBufferReplacementWarning(); )
201 String8 equalSignOrWhitespace(
'=');
214 bool writebackFlag =
false;
215 int qtyEntriesRead = 0;
217 bool fileHeaderRead =
false;
218 while( !reader.
IsEOF() ) {
219 reader.
Read(actLine); ++lineNo;
225 if ( !fileHeaderRead && lineTrimmed.
IsEmpty() ) {
226 fileHeaderRead=
true;
227 if (actComments.IsNotEmpty())
234 actComments._(actLine).NewLine();
246 fileHeaderRead=
true;
254 if( actSection->Comments.IsEmpty())
256 actSection->WriteBack= writebackFlag;
257 writebackFlag=
false;
271 actName << lineTrimmed;
274 actName << lineTrimmed.
Substring( 0, idx );
277 actRawValue.
_(lineTrimmed);
285 reader.
Read(actLine);
286 if ( reader.
IsEOF() ) {
292 actRawValue << (actLine);
293 lineTrimmed= actLine;
299 if( entry ==
nullptr) {
307 "Variable \"{}\" was found twice in INI-file. First value will be discarded "
309 " Previous occurrence @ {}:{}\n"
310 " Current occurrence @ {}:{}"
311 ,
String(actName), path, entry->LineNo, path, lineNo )
314 entry->RawValue.Allocate(
Allocator, actRawValue );
315 entry->WriteBack= writebackFlag;
316 entry->LineNo= lineNo;
317 writebackFlag=
false;
325 while((parser= tknzr.
Next()).IsNotNull()) {
332 trimmedValue << parser;
334 entry->Value.Allocate(
Allocator, trimmedValue );
343 return qtyEntriesRead;
357 "Given Path is empty and no known filename from previous Read() operation available.")
362 file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
365 file.open( path.
Terminate(), std::ios::binary );
367 if ( !file.is_open() || errno ) {
386 if( section.Name.IsNotEmpty()) {
388 if(section.Comments.CharAtStart() !=
'\n' && section.Comments.CharAtStart() !=
'\r')
390 writer.
Write( section.Comments );
391 if(section.WriteBack) {
392 writer.
Write( writeBackAttribute );
400 for (
auto& entry : section.Entries )
401 maxVarLength= (std::max)( maxVarLength, entry.Name.Length() );
403 for (
auto& entry : section.Entries ) {
405 if( entry.Comments.IsNotEmpty()) {
406 if (entry.Comments.CharAtStart() !=
'\n' && entry.Comments.CharAtStart() !=
'\r')
408 writer.
Write( entry.Comments );
411 if(entry.WriteBack) {
412 writer.
Write( writeBackAttribute );
415 writer.
Write( entry.Name );
418 if( entry.NewValue.IsNull()) {
419 writer.
Write( entry.RawValue );
420 if(!entry.NewValue.EndsWith(
NEW_LINE))
429 writer.
Fill(
' ', maxVarLength - ( cntLine == 0 ? entry.Name.Length() - 1
437 writer.
Write(
"\\" );
439 writer.
Write( actual );
445 if( actual.
Length() > maxValLength )
446 maxValLength= actual.
Length() + 2;
447 writer.
Fill(
' ', maxValLength - actual.
Length() );
449 writer.
Write(
"\\" );
#define ALIB_CALLER_NULLED
#define ALIB_WARNING(domain,...)
#define ALIB_ASSERT_RESULT_GREATER_THAN(func, value)
#define ALIB_ASSERT_ERROR(cond, domain,...)
#define ALIB_BOXING_VTABLE_DEFINE(TMapped, Identifier)
Exception & Add(const lang::CallerInfo &ci, TEnum type, TArgs &&... args)
constexpr const TChar * Terminate() const
TAString & _(const TAppendable &src)
void DbgDisableBufferReplacementWarning()
TAString & TrimEnd(const TCString< TChar > &trimChars=CStringConstantsTraits< TChar >::DefaultWhitespaces())
constexpr integer Length() const
constexpr bool IsEmpty() const
TChar CharAtStart() const
constexpr bool IsNotNull() const
void Allocate(TAllocator &allocator, const TString< TChar > ©)
TChar CharAt(integer idx) const
constexpr bool IsNotEmpty() const
integer IndexOfAny(const TString &needles, integer startIdx=0) const
TString< TChar > Substring(integer regionStart, integer regionLength=MAX_LEN) const
bool Equals(const TString< TChar > &rhs) const
TSubstring & TrimStart(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
bool ConsumeCharFromEnd(TChar consumable)
integer ConsumeChars(integer regionLength, TSubstring *target=nullptr)
TSubstring & Trim(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
TString< TChar > ConsumeToken(TChar separator=',', lang::Inclusion includeSeparator=lang::Inclusion::Include)
TSubstring & TrimEnd(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
void Read(NAString &target)
void SetStream(::std::istream *is)
void Write(const NString &src, integer *printedWidth=nullptr)
void Fill(const TChar fillChar, integer count)
TSubstring< TChar > & Next(lang::Whitespaces trimming=lang::Whitespaces::Trim, TChar newDelim='\0')
void Reset()
Clears all data, resets the internal mono allocator.
Entry * DeleteEntry(Section *section, const String &name)
Section * CreateSection(const String &name)
void Write(const system::PathString &path=system::NULL_PATH)
Entry * CreateEntry(Section *section, const String &name)
void AddComments(String &dest, const String &comments, const String &prefix=A_CHAR("# "))
HashMap< MonoAllocator, EntryKey, Handle, EntryKey::Hash, EntryKey::EqualTo > entryTable
ListMA< integer > LinesWithReadErrors
system::PathString FileName
The file name.
bool startsWithCommentSymbol(String &subs)
Handle SearchEntry(const String §ion, const String &name)
int Read(const system::CPathString &path)
std::pair< Section *, bool > SearchOrCreateSection(const String §ionName)
ListMA< Section > Sections
The list of sections.
IniFile()
Default constructor.
Section * DeleteSection(const String &name)
MonoAllocator Allocator
A monotonic allocator used for allocating sections and entries.
Section * SearchSection(const String §ionName)
String FileComments
The file header which will be written out as comment lines with "# " prefixes.
Exception CreateExceptionFromSystemError(const CallerInfo &ci, std::error_code errorCode)
@ Include
Chooses inclusion.
strings::TCString< PathCharType > CPathString
The string-type used with this ALib Module.
strings::TString< PathCharType > PathString
The string-type used with this ALib Module.
@ ErrorWritingFile
An error occurred writing the file .
@ ErrorOpeningFile
File not found when reading.
strings::compatibility::std::IStreamReader IStreamReader
Type alias in namespace alib.
strings::util::TTokenizer< character > Tokenizer
Type alias in namespace alib.
LocalString< 8 > String8
Type alias name for #"TLocalString;TLocalString<character,8>".
constexpr CString NEW_LINE
A zero-terminated string containing the new-line character sequence.
constexpr const String EMPTY_STRING
An empty string of the default character type.
lang::integer integer
Type alias in namespace alib.
LocalString< 4096 > String4K
Type alias name for #"TLocalString;TLocalString<character,4096>".
strings::TString< character > String
Type alias in namespace alib.
strings::TSubstring< character > Substring
Type alias in namespace alib.
camp::Basecamp BASECAMP
The singleton instance of ALib Camp class #"Basecamp".
exceptions::Exception Exception
Type alias in namespace alib.
constexpr CString DEFAULT_WHITESPACES
A zero-terminated string of default whitespace characters.
LocalString< 128 > String128
Type alias name for #"TLocalString;TLocalString<character,128>".
NLocalString< 256 > NString256
Type alias name for #"TLocalString;TLocalString<nchar,256>".
LocalString< 256 > String256
Type alias name for #"TLocalString;TLocalString<character,256>".
LocalString< 2048 > String2K
Type alias name for #"TLocalString;TLocalString<character,2048>".
strings::compatibility::std::OStreamWriter< TChar, TAllocator, TSynced, TTargetLF > OStreamWriter
Type alias in namespace alib.
#define ALIB_STRINGS_TO_NARROW( src, dest, bufSize)
Hash functor for nodes hashed in field #"entryTable". Ignores letter case.
An entry in a #"IniFile::Section".
String Name
The entry's name.
String Comments
The entry's comments.
A pair of pointers to a section and an entry in the section.
Entry * EntryPointer
Pointer to the entry in the #"SectionPointer".
A section of the INI-file.
ListMA< Entry, Recycling::None > Entries
The list of variables of the section.
String Name
The name of the section.