ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
inifilefeeder.cpp
1// #################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2025 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6// #################################################################################################
7#include "alib_precompile.hpp"
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"
10#endif
11#if ALIB_C20_MODULES
12 module;
13#endif
14// ====================================== Global Fragment ======================================
16#include <fstream>
17// =========================================== Module ==========================================
18#if ALIB_C20_MODULES
21# if ALIB_EXCEPTIONS
22 import ALib.Exceptions;
23# endif
24 import ALib.System;
25 import ALib.Variables;
26# if ALIB_FORMAT
27 import ALib.Format;
29# endif
30#else
32# include "ALib.Exceptions.H"
33# include "ALib.System.H"
34# include "ALib.Variables.H"
35# include "ALib.Format.H"
38#endif
39// ====================================== Implementation =======================================
40
41namespace alib::variables {
42
43// #################################################################################################
44// helpers
45// #################################################################################################
46std::pair<IniFile::Section*, IniFile::Entry*> IniFileFeeder::SearchEntry ( const String& path )
47{
48 if(iniFile == nullptr)
49 {
50 ALIB_ERROR( "VARIABLES", "No INI-file loaded when trying to search data." )
51 return std::pair<IniFile::Section*, IniFile::Entry*>(nullptr, nullptr);
52 }
53
54 // separate section/entry name
55 auto sectionSeparator= path.LastIndexOf( configuration.Separator() );
56 String sectionName= (sectionSeparator != -1) ? path.Substring<NC>(0, sectionSeparator ) : EMPTY_STRING;
57 String entryName = (sectionSeparator != -1) ? path.Substring<NC>(sectionSeparator + 1, path.Length() - sectionSeparator - 1) : path;
58
59 // search for existing entry
60 return iniFile->SearchEntry(sectionName, entryName);
61}
62
63std::pair<IniFile::Section*, IniFile::Entry*> IniFileFeeder::SearchEntry ( const Variable& var )
64{
65 ALIB_ASSERT_ERROR( var.IsDeclared(), "VARIABLES", "Given Variable not declared." )
66 ALIB_ASSERT_ERROR( &var.GetConfiguration() == &configuration, "VARIABLES",
67 "Variable belongs to different configuration: ", var )
68 return SearchEntry( String256( var ) );
69}
70
71// #################################################################################################
72// Import interface
73// #################################################################################################
74int IniFileFeeder::ImportSection( const String& sectionName, const String& typeName )
75{
76 if(iniFile == nullptr)
77 {
78 ALIB_ERROR( "VARIABLES", "No INI-file loaded when trying to import data." )
79 return 0;
80 }
81
82 auto* section= iniFile->SearchSection( sectionName );
83 if(section == nullptr)
84 {
85 ALIB_WARNING( "VARIABLES", "Section named \"{}\" not found in INI-file.", sectionName )
86 return 0;
87 }
88
89 int cnt= 0;
90 String256 varName;
91
92 varName.Reset(sectionName);
93 if( varName.IsNotEmpty())
94 varName << configuration.Separator();
95
96 // loop over all entries
97 for ( auto& entry : section->Entries )
98 {
99 StringLengthResetter sectionNameResetter(varName);
100 varName << entry.Name;
101 Variable var(configuration, varName, typeName);
102 if( var.Define( priority) )
103 {
104 var.Import(entry.Value, priority, &configuration.Escaper );
105 ++cnt;
106 }
107 }
108
109 return cnt;
110}
111
113{
114 int cnt= 0;
115 String256 varName;
116
117 varName.Reset(section.Name);
118 if( varName.IsNotEmpty())
119 varName << configuration.Separator();
120
121 // loop over all entries
122 for ( auto& entry : section.Entries )
123 {
124 // Try if variable is declared and has lower or equal priority than us.
125 StringLengthResetter sectionNameResetter(varName);
126 varName << entry.Name;
128 Substring value= entry.Value;
129 if( var.Try(varName) )
130 {
131 var.Import(value, priority, &configuration.Escaper );
132 ++cnt;
133 continue;
134 }
135
136 // Variable not declared. Copy value to undeclared input variables
137 configuration.PresetImportString(varName, value, &configuration.Escaper, priority);
138 }
139
140 return cnt;
141}
142
143int IniFileFeeder::ImportSection( const String& sectionName )
144{
145 if(iniFile == nullptr)
146 {
147 ALIB_ERROR( "VARIABLES", "No INI-file loaded when trying to import data." )
148 return 0;
149 }
150
151 auto* section= iniFile->SearchSection( sectionName );
152 if(section == nullptr)
153 {
154 ALIB_WARNING( "VARIABLES", "Section name \"{}\" not found in INI-file.", sectionName )
155 return 0;
156 }
157
158 return importSection(*section);
159}
160
162{
163 if(iniFile == nullptr)
164 {
165 ALIB_ERROR( "VARIABLES", "No INI-file loaded when trying to import data." )
166 return 0;
167 }
168
169 int cnt= 0;
170 String256 varName;
171
172 // loop over all sections
173 for ( IniFile::Section& section : iniFile->Sections )
174 cnt+= importSection( section );
175
176 return cnt;
177}
178
179// #################################################################################################
180// Export interface
181// #################################################################################################
183{
184 if(iniFile == nullptr)
185 {
186 ALIB_ERROR( "VARIABLES", "No INI-file loaded when trying to export data." )
187 return false;
188 }
189 ALIB_ASSERT_ERROR(var.IsDeclared(), "VARIABLES", "Variable to export not declared: ", var)
190
191 String256 name(var);
192
193 // separate section/entry name
194 auto sectionSeparator= name.LastIndexOf( var.GetConfiguration().Separator() );
195 String sectionName= (sectionSeparator != -1) ? name.Substring<NC>(0, sectionSeparator ) : EMPTY_STRING;
196 String entryName = (sectionSeparator != -1) ? name.Substring<NC>(sectionSeparator + 1, name.Length() - sectionSeparator - 1) : name;
197
198 // search for existing entry
199 auto pair= iniFile->SearchEntry(sectionName, entryName);
200 auto* entry= pair.second;
201 if( entry )
202 {
203 // exists and no write back?
204 if( !entry->WriteBack && !pair.first->WriteBack )
205 return false;
206 }
207 else
208 {
209 // create entry
210 auto sectionIt= iniFile->SearchOrCreateSection( sectionName );
211 entry = iniFile->CreateEntry( sectionIt.first, entryName );
212 }
213
214 String2K buf;
215 var.Export( buf, &configuration.Escaper );
216 entry->NewValue.Allocate(iniFile->Allocator, buf );
217
218 // add comments
219 if(entry->Comments.IsNull())
220 {
221 auto* decl= var.GetDeclaration();
222 if( decl && decl->Comments().IsNotEmpty() )
223 iniFile->AddComments( entry->Comments, decl->Comments(), DefaultCommentPrefix );
224 }
225
226 return true;
227}
228
229int IniFileFeeder::ExportSubTree( Configuration::Cursor cursor, bool directChildrenOnly )
230{
231 if(iniFile == nullptr)
232 {
233 ALIB_ERROR( "VARIABLES", "No INI-file loaded when trying to export data." )
234 return 0;
235 }
236 int cnt= 0;
237 // check cursor itself first
238 if( !cursor.IsRoot() )
239 {
240 Variable var(cursor);
241 if( var.IsDeclared() )
242 if( Export( var ) )
243 cnt++;
244 }
245
247 rit.SetPathGeneration( lang::Switch::On );
248 rit.Initialize( cursor, directChildrenOnly ? 0 : (std::numeric_limits<unsigned int>::max)() );
249 while ( rit.IsValid() )
250 {
251 if( rit.Node().Name().Equals(A_CHAR("$PRESETS")) )
252 {
253 rit.NextSibling();
254 continue;
255 }
256
257 Variable var(rit.Node());
258 if( var.IsDeclared() && var.IsDefined() )
259 {
260 if( Export( var ) )
261 cnt++;
262 }
263 rit.Next();
264 }
265 return cnt;
266}
267
268#if ALIB_RESOURCES
270 const NString& resourceCategory,
271 const NString& resourceNamePrefix )
272{
273 if(iniFile == nullptr)
274 {
275 ALIB_ERROR( "VARIABLES", "No INI-file loaded when trying to import data." )
276 return 0;
277 }
278
279 // add section comments from resources to INI-file
280 int cnt= 0;
281 for( auto& section : iniFile->Sections )
282 if( section.Comments.IsNull() )
283 {
284 auto& comment= resourcePool.Get( resourceCategory,
285 NString128() << resourceNamePrefix << section.Name
286 ALIB_DBG(, false));
287 if( comment.IsNull() )
288 continue;
289
290 ++cnt;
291 Paragraphs text;
293 text.LineWidth= LineWidth;
294 text.Buffer._(NEW_LINE);
295 text.AddMarked( comment );
296 }
297 section.Comments.Allocate(iniFile->Allocator, text.Buffer);
298 }
299 return cnt;
300}
301#endif
302
304{
305 auto entry= SearchEntry( path );
306 ALIB_ASSERT_WARNING( entry.second , "VARIABLES",
307 "Variable \"{}\" to be marked as 'writeback' not found.", path )
308
309 if( entry.second && entry.second->RawValue.IsEmpty() )
310 {
311 entry.second->WriteBack= true;
312 return true;
313 }
314 return false;
315}
316
318{
319 ALIB_ASSERT_ERROR( var.IsDeclared(), "VARIABLES", "Given Variable not declared." )
320 ALIB_ASSERT_ERROR( &var.GetConfiguration() == &configuration, "VARIABLES",
321 "Variable belongs to different configuration: ", var)
322 return SetWriteBackFlag( String256(var) );
323}
324
325
326} // namespace [alib::variables]
constexpr CharacterType Separator() const noexcept
static ALIB_DLL threads::RecursiveLock DefaultLock
void AddMarked(boxing::TBoxes< TAllocatorArgs > &args)
integer LineWidth
Used as parameter lineWidth of static method invocations.
virtual const String & Get(const NString &category, const NString &name, bool dbgAssert)=0
TAString & _(const TAppendable &src)
constexpr integer Length() const
Definition string.inl:318
constexpr bool IsNotEmpty() const
Definition string.inl:371
integer LastIndexOf(TChar needle, integer startIndex=MAX_LEN) const
Definition string.inl:967
void Allocate(TAllocator &allocator, const TString< TChar > &copy)
Definition string.inl:1870
TString< TChar > Substring(integer regionStart, integer regionLength=MAX_LEN) const
Definition string.inl:386
ALIB_DLL std::pair< IniFile::Section *, IniFile::Entry * > SearchEntry(const Variable &variable)
ALIB_DLL int AddResourcedSectionComments(ResourcePool &resourcePool, const NString &resourceCategory, const NString &resourceNamePrefix)
ALIB_DLL int ExportSubTree(Configuration::Cursor cursor, bool directChildrenOnly=false)
IniFile * iniFile
The INI-file. Created with methods ImportStart and ExportStart.
ALIB_DLL bool SetWriteBackFlag(const String &path)
Configuration & configuration
The configuration to work with. Set with construction.
ALIB_DLL int ImportSection(const String &sectionName)
ALIB_DLL int importSection(IniFile::Section &section)
Priority priority
The priority to use to define variables. Set with construction.
ALIB_DLL bool Export(const Variable &var)
ALIB_DLL bool Define(Priority requestedPriority=Priority::Standard)
Definition variable.cpp:280
ALIB_DLL void Import(const String &src, Priority priority, const StringEscaper *escaper=nullptr)
Definition variable.cpp:357
AString & Export(AString &dest, const StringEscaper *escaper=nullptr) const
bool Try(const String &name)
const Declaration * GetDeclaration() const
Configuration & GetConfiguration() const
#define A_CHAR(STR)
#define ALIB_WARNING(domain,...)
Definition alib.inl:1046
#define ALIB_ASSERT_WARNING(cond, domain,...)
Definition alib.inl:1050
#define ALIB_ERROR(domain,...)
Definition alib.inl:1045
#define ALIB_LOCK_RECURSIVE_WITH(lock)
Definition alib.inl:1323
#define ALIB_DBG(...)
Definition alib.inl:836
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1049
@ On
Switch it on, switched on, etc.
strings::TStringLengthResetter< character,lang::HeapAllocator > StringLengthResetter
Type alias in namespace alib.
NLocalString< 128 > NString128
Type alias name for TLocalString<nchar,128>.
LocalString< 256 > String256
Type alias name for TLocalString<character,256>.
constexpr CString NEW_LINE
A zero-terminated string containing the new-line character sequence.
Definition cstring.inl:644
constexpr const String EMPTY_STRING
An empty string of the default character type.
Definition string.inl:2443
strings::TString< nchar > NString
Type alias in namespace alib.
Definition string.inl:2390
format::Paragraphs Paragraphs
Type alias in namespace alib.
resources::ResourcePool ResourcePool
Type alias in namespace alib.
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2381
LocalString< 2048 > String2K
Type alias name for TLocalString<character,2048>.
strings::TSubstring< character > Substring
Type alias in namespace alib.
A section of the INI-file.
Definition inifile.inl:145
List< MonoAllocator, Entry, Recycling::None > Entries
The list of variables of the section.
Definition inifile.inl:157
String Name
The name of the section.
Definition inifile.inl:155