8#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
9# error "Symbol 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.first == section ) {
111 for(
auto entryIt= section->
Entries.begin() ; entryIt != section->
Entries.end(); ++entryIt ) {
113 if( entryIt->Name.Equals(name)) {
114 auto* entry= &*entryIt;
126 std::make_pair(section, &newEntry) );
136 return std::pair<Section*, Entry*>(
nullptr,
nullptr);
150std::pair<IniFile::Section*, bool>
154 return std::make_pair( s,
false );
177 std::ifstream file( nPath );
179 if ( !file.is_open() ) {
183 if ( errNo ==
int(SystemErrors::enoent) )
193 throw std::runtime_error(
"ErrorOpeningFile");
202 String4K actComments;
ALIB_DBG( actComments.DbgDisableBufferReplacementWarning(); )
205 String8 equalSignOrWhitespace(
'=');
218 bool writebackFlag =
false;
219 int qtyEntriesRead = 0;
221 bool fileHeaderRead =
false;
222 while( !reader.
IsEOF() ) {
223 reader.
Read(actLine); ++lineNo;
229 if ( !fileHeaderRead && lineTrimmed.
IsEmpty() ) {
230 fileHeaderRead=
true;
237 actComments._(actLine).NewLine();
249 fileHeaderRead=
true;
257 if( actSection->Comments.IsEmpty())
259 actSection->WriteBack= writebackFlag;
260 writebackFlag=
false;
274 actName << lineTrimmed;
277 actName << lineTrimmed.
Substring( 0, idx );
280 actRawValue.
_(lineTrimmed);
288 reader.
Read(actLine);
289 if ( reader.
IsEOF() ) {
295 actRawValue << (actLine);
296 lineTrimmed= actLine;
301 auto* entry=
SearchEntry( actSection->Name, actName ).second;
302 if( entry ==
nullptr) {
307 "Variable \"{}\" was found twice in INI-file. First value will be discarded "
308 "on writing.",
String(actName) )
310 entry->Comments.Allocate(
Allocator, actComments );
311 entry->RawValue.Allocate(
Allocator, actRawValue );
312 entry->WriteBack= writebackFlag;
313 writebackFlag=
false;
321 while((parser= tknzr.
Next()).IsNotNull()) {
328 trimmedValue << parser;
330 entry->Value.Allocate(
Allocator, trimmedValue );
339 return qtyEntriesRead;
353 "Given Path is empty and no known filename from previous Read() operation available.")
356 std::ofstream outputFileStream( path.
Terminate(), std::ios::binary );
357 if ( !outputFileStream.is_open() ) {
364 throw std::runtime_error(
"ErrorWritingFile");
379 if( section.Name.IsNotEmpty()) {
381 if(section.Comments.CharAtStart() !=
'\n' && section.Comments.CharAtStart() !=
'\r')
383 writer.
Write( section.Comments );
384 if(section.WriteBack) {
385 writer.
Write( writeBackAttribute );
393 for (
auto& entry : section.Entries )
394 maxVarLength= (std::max)( maxVarLength, entry.Name.Length() );
396 for (
auto& entry : section.Entries ) {
398 if( entry.Comments.IsNotEmpty()) {
399 if (entry.Comments.CharAtStart() !=
'\n' && entry.Comments.CharAtStart() !=
'\r')
401 writer.
Write( entry.Comments );
404 if(entry.WriteBack) {
405 writer.
Write( writeBackAttribute );
408 writer.
Write( entry.Name );
411 if( entry.NewValue.IsNull()) {
412 writer.
Write( entry.RawValue );
413 if(!entry.NewValue.EndsWith(
NEW_LINE))
422 writer.
Fill(
' ', maxVarLength - ( cntLine == 0 ? entry.Name.Length() - 1
430 writer.
Write(
"\\" );
432 writer.
Write( actual );
438 if( actual.
Length() > maxValLength )
439 maxValLength= actual.
Length() + 2;
440 writer.
Fill(
' ', maxValLength - actual.
Length() );
442 writer.
Write(
"\\" );
449 outputFileStream.close();
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
TChar CharAt(integer idx) const
constexpr bool IsNotEmpty() const
integer IndexOfAny(const TString &needles, integer startIdx=0) const
void Allocate(TAllocator &allocator, const TString< TChar > ©)
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)
ALIB_DLL TSubstring< TChar > & Next(lang::Whitespaces trimming=lang::Whitespaces::Trim, TChar newDelim='\0')
ALIB_DLL void Reset()
Clears all data, resets the internal mono allocator.
ALIB_DLL Entry * DeleteEntry(Section *section, const String &name)
ALIB_DLL Section * CreateSection(const String &name)
ALIB_DLL void Write(const system::PathString &path=system::NULL_PATH)
ALIB_DLL Entry * CreateEntry(Section *section, const String &name)
ALIB_DLL void AddComments(String &dest, const String &comments, const String &prefix=A_CHAR("# "))
ListMA< integer > LinesWithReadErrors
system::PathString FileName
The file name.
bool startsWithCommentSymbol(String &subs)
HashMap< MonoAllocator, EntryKey, std::pair< Section *, Entry * >, EntryKey::Hash, EntryKey::EqualTo > entryTable
ALIB_DLL std::pair< Section *, bool > SearchOrCreateSection(const String §ionName)
ListMA< Section > Sections
The list of sections.
ALIB_DLL std::pair< Section *, Entry * > SearchEntry(const String §ion, const String &name)
ALIB_DLL integer Read(const system::CPathString &path)
ALIB_DLL IniFile()
Default constructor.
ALIB_DLL Section * DeleteSection(const String &name)
MonoAllocator Allocator
A monotonic allocator used for allocating sections and entries.
ALIB_DLL Section * SearchSection(const String §ionName)
String FileComments
The file header which will be written out as a comment lines with "# " prefixes.
#define ALIB_BOXING_VTABLE_DEFINE(TMapped, Identifier)
#define ALIB_CALLER_NULLED
#define ALIB_STRINGS_TO_NARROW( src, dest, bufSize)
#define ALIB_WARNING(domain,...)
#define ALIB_ASSERT_RESULT_GREATER_THAN(func, value)
#define ALIB_ASSERT_ERROR(cond, domain,...)
@ 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.
Exception CreateSystemException(const CallerInfo &ci, int errNo)
@ ErrorWritingFile
An error occurred writing the file .
@ ErrorOpeningFile
File not found when reading.
LocalString< 256 > String256
Type alias name for TLocalString<character,256>.
strings::util::TTokenizer< character > Tokenizer
Type alias in namespace alib.
LocalString< 4096 > String4K
Type alias name for TLocalString<character,4096>.
camp::Basecamp BASECAMP
The singleton instance of ALib Camp class Basecamp.
LocalString< 128 > String128
Type alias name for TLocalString<character,128>.
strings::compatibility::std::IStreamReader IStreamReader
Type alias in namespace alib.
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< 8 > String8
Type alias name for TLocalString<character,8>.
constexpr CString DEFAULT_WHITESPACES
A zero-terminated string of default whitespace characters.
exceptions::Exception Exception
Type alias in namespace alib.
strings::TString< character > String
Type alias in namespace alib.
NLocalString< 256 > NString256
Type alias name for TLocalString<nchar,256>.
strings::compatibility::std::OStreamWriter< TChar, TAllocator, TSynced, TTargetLF > OStreamWriter
Type alias in namespace alib.
LocalString< 2048 > String2K
Type alias name for TLocalString<character,2048>.
strings::TSubstring< character > Substring
Type alias in namespace alib.
Hash functor for nodes hashed in field entryTable. Ignores letter case.
String Name
The entry's name.
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.