10#if !defined (HPP_ALIB_CONFIG_INI_FILE)
15#if !defined(HPP_ALIB_CONFIG_CONFIG)
18#if !defined(HPP_ALIB_CONFIG_CONFIGURATION)
22#if !defined (HPP_ALIB_CAMP_DIRECTORY)
25#if !defined (HPP_ALIB_CAMP_PROCESSINFO)
28#if !defined (HPP_ALIB_STRINGS_UTIL_TOKENIZER)
31#if !defined (HPP_ALIB_STRINGS_UTIL_SPACES)
34#if !defined (HPP_ALIB_LANG_FORMAT_PARAGRAPHS)
37#if !defined (HPP_ALIB_COMPATIBILITY_STD_STRINGS_IOSTREAM)
41#if !defined (_GLIBCXX_FSTREAM) && !defined(_FSTREAM_)
44#if defined(_MSC_VER) && !defined(_ALGORITHM_)
50namespace alib {
namespace config {
91 while ( (startIdx= raw.
IndexOf(
'\n', startIdx )) >= 0 )
95 if ( raw.
CharAt( --startIdx) ==
'\r' )
101 raw.
Delete( startIdx, delLen );
103 startIdx= raw.
TrimAt( startIdx );
104 if( startIdx >= raw.
Length() )
108 if( startIdx >0 && raw[startIdx-1] ==
'"' && raw[startIdx] ==
'"' )
121 && ( c !=
'/' || raw.
CharAt( startIdx + 1 ) !=
'/' ) )
125 if (idx < 0 ) idx= raw.
Length();
126 raw.
Delete( startIdx, idx - startIdx + 1 );
127 if( startIdx >= raw.
Length() )
129 startIdx= raw.
TrimAt( startIdx );
137 auto varSize= variable.
Size();
163, LinesWithReadErrors( allocator )
176 && (fileName.
Length() < 2 || fileName.
CharAt(1) !=
':' )
216bool startsWithCommentSymbol(
Substring& subs );
217bool startsWithCommentSymbol(
Substring& subs )
221 || ( i == 2 && subs.
Length() > 1 && subs[1] ==
'/' );
232 std::ifstream file( nFileName );
235 if ( !file.is_open() )
240 if ( errNo == UnderlyingIntegral(SystemErrors::enoent) )
257 bool fileHeaderRead=
false;
262 String16 separatorCharacters(
'=' );
265 while( !reader.
IsEOF() )
267 reader.
Read( lineAS );
272 bool isCommentLine= startsWithCommentSymbol( line );
283 if ( !fileHeaderRead )
285 fileHeaderRead=
true;
301 fileHeaderRead=
true;
323 name.
Reset().
_( line, 0, idx );
333 reader.
Read( lineAS );
334 if ( reader.
IsEOF() )
349 if( entry ==
nullptr)
351 entry->Value .Reset();
352 entry->AdditionalValues.Reset();
353 entry->Comments .Reset( comments );
354 entry->RawValue .Reset( value );
366 if (
Substring(comments).Trim().IsEmpty() )
375 if ( !startsWithCommentSymbol( tknzr.
Actual ) )
386 int getAssignmentPos(
const AString& value,
const String& alignmentSeparator )
392 if ( idxQuote > idx )
393 return static_cast<int>(idx);
404 std::ofstream outputFileStream ( nFileName );
405 if ( !outputFileStream.is_open() )
420 outputFileStream << std::endl;
429 outputFileStream << std::endl;
433 if ( section.Name().IsNotEmpty() )
438 for (
auto& entry : section.Entries() )
439 maxVarLength= (std::max)( maxVarLength, entry.Name().Length() );
441 bool previousVarHasComments=
true;
442 for (
auto& entry : section.Entries() )
447 if( entry.Comments.IsNotEmpty() )
450 if( !previousVarHasComments)
451 outputFileStream << std::endl;
457 writer.
Write( entry.Name() );
461 if ( entry.RawValue.IsNotEmpty() )
462 writer.
Write( entry.RawValue );
467 outputFileStream <<
'=';
468 Spaces::Write( outputFileStream, maxVarLength - entry.Name().Length() + 1 );
472 auto qtyValues= entry.AdditionalValues.Size() + 1;
473 auto entryIt = entry.AdditionalValues.begin();
476 if ( !HasBits( entry.FmtHints, FormatHints::MultiLine ) )
478 bool delimSpaces= (! HasBits( entry.FmtHints, FormatHints::NoDelimSpaces ) );
480 for (
integer idx= 0; idx < qtyValues; ++idx )
492 "No delimiter given for multi-value variable {!Q}.",
496 outputFileStream <<
' ';
501 outputFileStream <<
' ';
506 externalizedValue.
Reset();
508 writer.
Write( externalizedValue );
519 int maxAttributeAssignPos = 0;
520 bool allAttrHavePrecedingBlanks=
true;
521 if (entry.FormatAttrAlignment.IsNotEmpty() )
523 auto entryIt2 = entry.AdditionalValues.begin();
524 for (
integer idx= 0; idx < qtyValues; ++idx )
537 int attributeAssignPos= getAssignmentPos( *value, entry.FormatAttrAlignment );
538 if ( attributeAssignPos > 0 )
540 if ( maxAttributeAssignPos < attributeAssignPos )
541 maxAttributeAssignPos= attributeAssignPos;
542 allAttrHavePrecedingBlanks&= value->
CharAt( attributeAssignPos - 1 ) ==
' ';
545 if ( !allAttrHavePrecedingBlanks )
546 maxAttributeAssignPos += 1;
550 for (
integer idx= 0; idx < qtyValues; ++idx )
562 "No delimiter given for multi-value variable {!Q}.",
567 if ( backSlashPos < lastLineLen + 1 )
568 backSlashPos= lastLineLen + 4;
570 Spaces::Write( outputFileStream, backSlashPos - lastLineLen );
572 outputFileStream <<
'\\' << std::endl;
579 externalizedValue.
Reset();
584 if( idx != 0 && (firstChar ==
'#' || firstChar ==
';' ) )
588 if (entry.FormatAttrAlignment.IsNotEmpty() )
590 int attributeAssignPos= getAssignmentPos( externalizedValue, entry.FormatAttrAlignment );
591 if ( attributeAssignPos > 0 && attributeAssignPos < maxAttributeAssignPos )
593 maxAttributeAssignPos-attributeAssignPos,
595 0 : entry.FormatAttrAlignment.Length() )
598 writer.
Write( externalizedValue );
600 lastLineLen= maxVarLength + 2 + externalizedValue.
Length();
604 outputFileStream << std::endl;
607 if( (previousVarHasComments= entry.Comments.IsNotEmpty() ) ==
true )
608 outputFileStream << std::endl;
613 outputFileStream.close();
618 const NString& resourceCategory,
619 const NString& resourceNamePrefix )
628 for(
auto& section : iniFile->
sections )
629 if( section.Comments.IsNull() )
631 auto& comment= resourcePool.
Get( resourceCategory,
632 NString128() << resourceNamePrefix << section.Name()
634 if( comment.IsNull() )
641 section.Comments << text.
Buffer;
XTernalizer * StringConverter
TValueList::Iterator SetValueCount(integer requestedSize)
TValueList AdditionalValues
const String & Name() const
virtual ALIB_API void ToVariable(Entry &entry, Variable &variable) const
ALIB_API Entry * createEntry(Section *section, const String &name)
ALIB_API std::pair< Section *, bool > SearchOrCreateSection(const String §ionName)
virtual Section * createSection(const String §ionName)
virtual ALIB_API void Clear()
virtual ALIB_API void FromVariable(Entry &entry, Variable &variable) const
Entry * searchEntry(const String §ion, const String &name)
bool FormatSpaceAfterDelim
virtual ALIB_API void ToVariable(Entry &entry, Variable &variable) const override
ALIB_API void WriteFile()
static String DefaultFileExtension
String DefaultCommentPrefix
bool FormatSpaceBeforeDelim
virtual ALIB_API void FromVariable(Entry &entry, Variable &variable) const override
static ALIB_API void AddResourcedSectionComments(Configuration &config, ResourcePool &resourcePool, const NString &resourceCategory, const NString &resourceNamePrefix)
ALIB_API IniFile(const String &filePathAndName=nullptr)
ALIB_API void writeComments(strings::compatibility::std::StringWriter &os, const AString &comments)
virtual String Name() const override
virtual ALIB_API void Clear() override
bool FormatIncludeDelimInAttrAlignment
List< integer > LinesWithReadErrors
void ReplaceComments(const String &newValue)
ALIB_API const String & Fullname()
const String & GetString(int idx=0)
virtual ALIB_API void ExternalizeValue(const String &src, AString &dest, character delim)
virtual ALIB_API void LoadFromString(Variable &variable, const String &src)
Exception & Add(const NCString &file, int line, const NCString &func, TEnum type, TArgs &&... args)
TPlugin * GetPlugin(integer number)
virtual const String & Get(const NString &category, const NString &name, bool dbgAssert)=0
static ALIB_API const ProcessInfo & Current()
T & EmplaceBack(TArgs &&... args)
ALIB_API integer TrimAt(integer idx, const TCString< TChar > &trimChars=TT_StringConstants< TChar >::DefaultWhitespaces())
TAString & Delete(integer regionStart, integer regionLength=MAX_LEN)
TAString & DeleteEnd(integer regionLength)
TAString & TrimStart(const TCString< TChar > &trimChars=TT_StringConstants< TChar >::DefaultWhitespaces())
TAString & InsertChars(TChar c, integer qty)
TAString & TrimEnd(const TCString< TChar > &trimChars=TT_StringConstants< TChar >::DefaultWhitespaces())
TAString & _(const TString< TChar > &src, integer regionStart, integer regionLength=MAX_LEN)
TAString & DeleteStart(integer regionLength)
void DbgDisableBufferReplacementWarning()
TAString & InsertAt(const TString< TChar > &src, integer pos)
integer IndexOf(TChar needle, integer startIdx=0) const
constexpr bool IsEmpty() const
TChar CharAt(integer idx) const
constexpr bool IsNotEmpty() const
constexpr integer Length() const
TChar CharAtStart() const
integer IndexOfAny(const TString &needles, integer startIdx=0) const
integer IndexOfOrLength(TChar needle) const
bool EndsWith(const TString &needle) const
bool StartsWith(const TString &needle) const
TSubstring & Trim(const TCString< TChar > &whiteSpaces=TT_StringConstants< TChar >::DefaultWhitespaces())
integer ConsumeChars(integer regionLength, TSubstring *target=nullptr)
bool ConsumeCharFromEnd(TChar consumable)
void Read(NAString &target)
void SetStream(::std::istream *is)
::std::ostream * GetStream()
void SetStream(::std::ostream *os)
void Write(const NString &src)
static ALIB_API void Write(std::basic_ostream< char > &os, integer qty)
TLocalString< TChar, 8 > TrimChars
ALIB_API TSubstring< TChar > & Next(lang::Whitespaces trimming=lang::Whitespaces::Trim, TChar newDelim='\0')
TSubstring< TChar > Actual
#define ALIB_WARNING(...)
#define ALIB_CALLER_NULLED
#define ALIB_STRINGS_TO_NARROW( src, dest, bufSize)
#define ALIB_ASSERT_ERROR(cond,...)
#define ALIB_ASSERT(cond)
Exception CreateSystemException(const NCString &file, int line, const NCString &func, int errNo)
@ Include
Chooses inclusion.
@ Keep
Keep whitespaces in string.
constexpr CString DefaultWhitespaces()
NLocalString< 16 > NString16
Type alias name for TLocalString<nchar,16> .
NLocalString< 128 > NString128
Type alias name for TLocalString<nchar,128> .
constexpr CString NewLine()
constexpr nchar DirectorySeparator
strings::TSubstring< character > Substring
Type alias in namespace alib.
constexpr CString EmptyString()
constexpr String NullString()
NLocalString< 256 > NString256
Type alias name for TLocalString<nchar,256> .
LocalString< 8 > String8
Type alias name for TLocalString<character,8> .
characters::character character
Type alias in namespace alib.
strings::TString< character > String
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.