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