ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
domain.inl
Go to the documentation of this file.
1/** ************************************************************************************************
2 * \file
3 * This header file is part of module \alib_alox of the \aliblong.
4 *
5 * \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
6 * Published under \ref mainpage_license "Boost Software License".
7 **************************************************************************************************/
8#ifndef HPP_ALOX_DETAIL_DOMAIN
9#define HPP_ALOX_DETAIL_DOMAIN 1
10
11#if !defined(HPP_ALIB_LOX_PROPPERINCLUDE)
12# error "ALib sources with ending '.inl' must not be included from outside."
13#endif
14
15#if !defined (HPP_ALOX_DETAIL_LOGGER)
17#endif
18
19#if !defined (HPP_ALIB_MONOMEM_LIST)
20# include "alib/monomem/list.hpp"
21#endif
22#if !defined (HPP_ALIB_MONOMEM_STDCONTAINERMA)
24#endif
25
26namespace alib::lox::detail {
27
28// forward declarations
29class ScopeInfo;
30
31/** ************************************************************************************************
32 * Used to store prefixes set. Those provided as
33 * \ref alib::boxing::Box "boxes" of character arrays are copied into an internal AString
34 * and will be deleted with the object. This ensures, that simple strings might get assembled
35 * on the stack and still be used as a prefix logable.
36 **************************************************************************************************/
37class PrefixLogable : public Box
38{
39 protected:
40 /** If set, it will be deleted. */
41 AString* copy = nullptr;
42
43 public:
44 /**
45 * Constructor taking the originally provided box. If this is an array of characters, the
46 * contents is copied into a heap allocated (new) AString and our vtable is replaced accordingly.
47 * @param src The prefix object provided by the user
48 */
49 PrefixLogable( const Box& src )
50 : Box( src )
51 {
52 // uses "placement new" to overwrite the box part of ourselves
53 if( src.IsNotNull() )
54 {
55 if ( IsArrayOf<nchar>() ) new (this) Box( copy= new AString( Unbox<NString>() ));
56 else if ( IsArrayOf<wchar>() ) new (this) Box( copy= new AString( Unbox<WString>() ));
57 else if ( IsArrayOf<xchar>() ) new (this) Box( copy= new AString( Unbox<XString>() ));
58 }
59 }
60
61 /** Destructor. Deletes field #copy if set. */
63 {
64 if(copy)
65 delete copy;
66 }
67
68 /**
69 * Move assignment operator.
70 * Default implementation of compiler is used.
71 * (Needs to be explicitly given due to custom destructor.)
72 * @param move The object to be moved.
73 * @return This object
74 */
76};
77
78/** ************************************************************************************************
79 * Objects of this class represent a <em>Log Domain</em> of \alox. This class is internally used by
80 * class \b Lox.
81 **************************************************************************************************/
82class Domain
83{
84 /** ********************************************************************************************
85 * Internal class that holds data stored per Logger
86 **********************************************************************************************/
87 public:
89 {
90 /** The logger. */
92
93 /** The verbosity of the \e Logger for this domain. */
94 Verbosity LoggerVerbosity = Verbosity::Off;
95
96 /** The priority value that was used to set the priority. */
97 Priorities Priority = Priorities::NONE;
98
99
100 /** the number of log calls on this domain for this logger. */
102
103 /**
104 * Constructor
105 * @param logger The logger to add
106 */
108 {
109 this->Logger= logger;
110 }
111 };
112
113 // #############################################################################################
114 // Public fields
115 // #############################################################################################
116 public:
117
118 /** The name of the domain. For root domains, this is \e nulled. */
120
121 /** The full path of the domain (set in the constructor once) . */
123
124 /** The parent domain. For root domains, this is \c nullptr. */
126
127 /** A list of sub domains, sorted by name. */
129
130 /** Data stored per logger. The index is corresponding to the list of loggers in 'our'
131 * Lox. */
132 std::vector<LoggerData,StdContMA<LoggerData>> Data;
133
134 /** <em>Prefix Logables</em> associated with this domain. */
136
137 /**
138 * A counter for the quantity of calls on this domain.
139 * Counting does not include:
140 * - logs when no \e Logger was set
141 * - conditional logs that were suppressed
142 * Otherwise, it includes all log calls, even when no \e Logger was enabled on this domain.
143 */
145
146 /** Flag which is set when verbosity configuration data was read. */
148
149 // #############################################################################################
150 // Public interface
151 // #############################################################################################
152 public:
153 /// @return Returns the domain path separation character.
154 static constexpr
156 {
157 return '/';
158 }
159
160 /** ****************************************************************************************
161 * Constructor used for the root domain.
162 * @param allocator The monotonic allocator used allocation of permanent objects.
163 * @param name The name of this root domains
164 ******************************************************************************************/
166 Domain( MonoAllocator* allocator, const NString& name );
167
168 /** ****************************************************************************************
169 * Constructor
170 * @param parent The parent domain. For root domains, this is \c nullptr.
171 * @param name The name of the domain.
172 ******************************************************************************************/
174 Domain( Domain* parent, const NString& name );
175
176 /** ****************************************************************************************
177 * Destroys the <em>Log Domain</em> object.
178 ******************************************************************************************/
180 ~Domain();
181
182 /** ****************************************************************************************
183 * Returns the root domain of this object.
184 * @return The root domain of this object
185 ******************************************************************************************/
187 {
188 Domain* rootDomain= this;
189 while ( rootDomain->Parent != nullptr )
190 rootDomain= rootDomain->Parent;
191 return rootDomain;
192 }
193
194 /** ****************************************************************************************
195 * Adds a new entry in field #Data and recursively demands the same from its sub-domains.
196 * Checks if a logger with the same name exists.
197 *
198 * @param logger The logger to add.
199 * @return The number of the \e Logger, -1 if a logger with the same name exists already.
200 ******************************************************************************************/
202 {
203 // let our root do this
204 if ( Parent != nullptr )
205 return Parent->AddLogger( logger );
206
207 // check for doubles
208 if ( GetLoggerNo( logger->GetName() ) >= 0 )
209 return -1;
210
211 // now this and all children
212 addLoggerRecursive( logger );
213 return static_cast<int>(Data.size()) - 1;
214 }
215
216 /** ****************************************************************************************
217 * Removes an new entry in field #Data and recursively demands the same from
218 * its sub-domains.
219 * @param loggerNo The number of the \e Logger to be removed.
220 ******************************************************************************************/
221 void RemoveLogger( int loggerNo )
222 {
223 // let our root do this
224 if ( Parent != nullptr )
225 {
226 Parent->RemoveLogger( loggerNo );
227 return;
228 }
229
230 // now this and all children
231 removeLoggerRecursive( loggerNo );
232 }
233
234 /** ****************************************************************************************
235 * Returns the number of loggers stored in this domain (the same for all domains within
236 * a tree).
237 * @return The number of loggers attached.
238 ******************************************************************************************/
240 {
241 return static_cast<int>( Data.size() );
242 }
243
244 /** ****************************************************************************************
245 * Searches and returns the \e Logger given by name.
246 * @param loggerName The logger to search.
247 * @return The \e Logger found corresponding to given name.
248 * If the \e Logger does not exist, nullptr is returned.
249 ******************************************************************************************/
250 detail::Logger* GetLogger( const NString& loggerName )
251 {
252 for ( size_t i= 0; i < Data.size() ; ++i )
253 if ( loggerName.Equals<true, lang::Case::Ignore>( Data[i].Logger->GetName()) )
254 return Data[i].Logger;
255 return nullptr;
256 }
257
258 /** ****************************************************************************************
259 * Returns logger of given number.
260 * @param no The number of the \e Logger to return.
261 * @return The \e Logger found with number \p{no}.
262 ******************************************************************************************/
264 {
265 ALIB_ASSERT_ERROR( no < static_cast<int>(Data.size()), "ALOX", "Internal error: Illegal Logger Number" )
266 return Data[static_cast<size_t>(no)].Logger;
267 }
268
269 /** ****************************************************************************************
270 * Returns the number of the \e Logger specified by name.
271 * @param loggerName The logger name to search.
272 * @return The number of the \e Logger found corresponding to given name.
273 * If the \e Logger does not exist, -1 is returned.
274 ******************************************************************************************/
275 int GetLoggerNo( const NString& loggerName )
276 {
277 for ( size_t i= 0; i < Data.size() ; ++i )
278 if ( loggerName.Equals<true, lang::Case::Ignore>( Data[i].Logger->GetName() ) )
279 return static_cast<int>( i );
280 return -1;
281 }
282
283 /** ****************************************************************************************
284 * Returns the number of the \e Logger.
285 * @param logger The logger to search.
286 * @return The number of the \e Logger. If the \e Logger does not exist, -1 is returned.
287 ******************************************************************************************/
289 {
290 for ( size_t i= 0; i < Data.size() ; ++i )
291 if ( logger == Data[i].Logger )
292 return static_cast<int>( i );
293 return -1;
294 }
295
296 /** ****************************************************************************************
297 * Sets the verbosity for a logger of this domain of all its sub domains to the specified
298 * value. If given priority is lower than those actually stored, nothing is set and
299 * recursion is stopped.
300 *
301 * @param loggerNo The number of the \e Logger to set the \e Verbosity for.
302 * @param verbosity The verbosity value to set.
303 * @param priority The priority of the setting.
304 * @return The new \e Verbosity.
305 ******************************************************************************************/
307 Verbosity SetVerbosity( int loggerNo, Verbosity verbosity, Priorities priority );
308
309 /** ****************************************************************************************
310 * Returns the <em>%Log %Domain's %Verbosity</em> for the given logger number.
311 * @param loggerNo The number of the \e Logger whose \e Verbosity is requested.
312 * @return The found/defined domain \e Verbosity.
313 ******************************************************************************************/
314 Verbosity GetVerbosity( int loggerNo )
315 {
316 return Data[static_cast<size_t>(loggerNo)].LoggerVerbosity;
317 }
318
319 /** ****************************************************************************************
320 * Returns the priority of the \e Verbosity setting for the given logger number.
321 * @param loggerNo The number of the \e Logger whose \e Verbosity is requested.
322 * @return The priority.
323 ******************************************************************************************/
324 Priorities GetPriority( int loggerNo )
325 {
326 return Data[static_cast<size_t>(loggerNo)].Priority;
327 }
328
329
330 /** ****************************************************************************************
331 * Returns the number of log calls for this domain and logger.
332 * @param loggerNo The number of the \e Logger whose \e Verbosity is requested.
333 * @return The number of calls executed by this logger on this domain.
334 ******************************************************************************************/
335 int GetCount( int loggerNo )
336 {
337 return Data[static_cast<size_t>(loggerNo)].LogCallsPerDomain;
338 }
339
340 /** ****************************************************************************************
341 * Determines if the domain is active in respect to the given Verbosity.
342 *
343 * @param loggerNo The number of the \e Logger whose \e Verbosity is to be evaluated against
344 * \p{statement}.
345 * @param statement The \e Verbosity to check.
346 * @return \c true if domain is active (log should be performed)
347 ******************************************************************************************/
348 bool IsActive( int loggerNo, Verbosity statement )
349 {
350 Verbosity domain= GetVerbosity( loggerNo );
351
352 // domain ^ / stmnt > | Off Error Warning Info Verbose
353 // ---------------------------------------------------------------------
354 // Off | - - - - -
355 // Errors | - Y - - -
356 // Warning | - Y Y - -
357 // Info | - Y Y Y -
358 // Verbose | - Y Y Y Y
359
360 if( statement != Verbosity::Off
361 && ( ( domain == Verbosity::Error && statement == Verbosity::Error )
362 || ( domain == Verbosity::Warning && ( statement == Verbosity::Warning || statement == Verbosity::Error ) )
363 || ( domain == Verbosity::Info && statement != Verbosity::Verbose )
364 || domain == Verbosity::Verbose )
365 )
366 {
367 ++Data[static_cast<size_t>(loggerNo)].LogCallsPerDomain;
368 return true;
369 }
370
371 return false;
372 }
373
374 /** ****************************************************************************************
375 * Searches a domain. If not found, the domain is (or path of domains are) created in
376 * the domain tree.
377 * If the path string starts with the character defined with #Separator, then
378 * the search (and creation) is done starting from the root domain of this domain and not
379 * from this domain.
380 *
381 * @param domainPath Path and domain to search.
382 * @param maxCreate The maximum number of sub domains that are created if not
383 * found at the end of the path.
384 * @param[out] wasCreated Output parameter that is set \c true if domain was not found
385 * and hence created. If \c nullptr, it is ignored.
386 * @return The domain found or created.
387 ******************************************************************************************/
389 Domain* Find( NSubstring domainPath, int maxCreate, bool* wasCreated );
390
391
392 /** ****************************************************************************************
393 * Creates a string representation of this object.
394 * @param target The target string.
395 ******************************************************************************************/
396 void ToString( NAString& target );
397
398 // #############################################################################################
399 // Internals
400 // #############################################################################################
401 protected:
402 /** ****************************************************************************************
403 * Internal, recursive helper of #Find.
404 *
405 * @param domainPath Path to search.
406 * @param maxCreate The maximum number of sub domains that are created if not
407 * found at the end of the path.
408 * @param[out] wasCreated Output parameter that is set \c true if domain was not found
409 * and hence created. If \c nullptr, it is ignored.
410 * @return The domain found or created.
411 ******************************************************************************************/
412 Domain* findRecursive( NSubstring& domainPath, int maxCreate, bool* wasCreated );
413
414 /** ****************************************************************************************
415 * Internal, recursive helper of #AddLogger.
416 * @param logger The logger to add.
417 ******************************************************************************************/
419 void addLoggerRecursive( detail::Logger* logger);
420
421 /** ****************************************************************************************
422 * Internal, recursive helper of #RemoveLogger.
423 * @param loggerNo The number of the \e Logger to be removed.
424 ******************************************************************************************/
426 void removeLoggerRecursive( int loggerNo );
427
428}; // Domain
429
430}// namespace [alib::lox::detail]
431
432#if !defined(ALIB_DOX)
434 target.Append(static_cast<const Box&>(src) ); )
435#endif
436
437#endif // HPP_ALOX_DETAIL_DOMAIN
ALIB_API bool IsNotNull() const
Definition boxing.cpp:194
constexpr Box() noexcept
Definition box.inl:234
bool IsArrayOf() const
Definition box.inl:724
std::vector< LoggerData, StdContMA< LoggerData > > Data
Definition domain.inl:132
Verbosity GetVerbosity(int loggerNo)
Definition domain.inl:314
ALIB_API void removeLoggerRecursive(int loggerNo)
Definition domain.cpp:241
int GetCount(int loggerNo)
Definition domain.inl:335
List< Domain > SubDomains
Definition domain.inl:128
ALIB_API Domain(MonoAllocator *allocator, const NString &name)
Definition domain.cpp:40
int GetLoggerNo(detail::Logger *logger)
Definition domain.inl:288
int AddLogger(detail::Logger *logger)
Definition domain.inl:201
ALIB_API Verbosity SetVerbosity(int loggerNo, Verbosity verbosity, Priorities priority)
Definition domain.cpp:220
void ToString(NAString &target)
Definition domain.cpp:248
detail::Logger * GetLogger(int no)
Definition domain.inl:263
bool IsActive(int loggerNo, Verbosity statement)
Definition domain.inl:348
Priorities GetPriority(int loggerNo)
Definition domain.inl:324
void RemoveLogger(int loggerNo)
Definition domain.inl:221
List< std::pair< PrefixLogable *, lang::Inclusion > > PrefixLogables
Definition domain.inl:135
ALIB_API void addLoggerRecursive(detail::Logger *logger)
Definition domain.cpp:234
Domain * findRecursive(NSubstring &domainPath, int maxCreate, bool *wasCreated)
Definition domain.cpp:127
int GetLoggerNo(const NString &loggerName)
Definition domain.inl:275
detail::Logger * GetLogger(const NString &loggerName)
Definition domain.inl:250
static constexpr nchar Separator()
Definition domain.inl:155
ALIB_API Domain * Find(NSubstring domainPath, int maxCreate, bool *wasCreated)
Definition domain.cpp:97
Logger(const NString &name, const NString &typeName)
Definition logger.hpp:141
const NString & GetName() const
Definition logger.hpp:184
PrefixLogable & operator=(PrefixLogable &&move)=default
PrefixLogable(const Box &src)
Definition domain.inl:49
bool Equals(const TString< TChar > &rhs) const
Definition string.hpp:573
#define ALIB_API
Definition alib.hpp:538
#define ALIB_STRINGS_APPENDABLE_TYPE_INLINE(TYPE, IMPL)
Definition astring.hpp:169
#define ALIB_ASSERT_ERROR(cond,...)
Definition alib.hpp:984
strings::TAString< character > AString
Type alias in namespace alib.
characters::nchar nchar
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:286
LoggerData(detail::Logger *logger)
Definition domain.inl:107