ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
domain.cpp
1// #################################################################################################
2// alib::lox::detail - ALox Logging 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// #################################################################################################
8// alib::lox - ALox Logging Library
9//
10// Copyright 2013-2025 A-Worx GmbH, Germany
11// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
12// #################################################################################################
13#include "alib_precompile.hpp"
14#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
15# error "Symbol ALIB_C20_MODULES has to be given to the compiler as either 0 or 1"
16#endif
17#if ALIB_C20_MODULES
18 module;
19#endif
20// ====================================== Global Fragment ======================================
22
23// =========================================== Module ==========================================
24#if ALIB_C20_MODULES
25 module ALib.ALox.Impl;
26 import ALib.Lang;
27 import ALib.Strings;
28 import ALib.Boxing;
29 import ALib.EnumRecords;
31 import ALib.Variables;
32 import ALib.Camp;
33 import ALib.Camp.Base;
34#else
35# include "ALib.ALox.H"
36# include "ALib.Lang.H"
37# include "ALib.Strings.H"
38# include "ALib.Boxing.H"
40# include "ALib.Variables.H"
41# include "ALib.Camp.H"
42# include "ALib.Camp.Base.H"
43# include "ALib.ALox.Impl.H"
44#endif
45// ====================================== Implementation =======================================
46namespace alib { namespace lox { namespace detail {
47
48// #################################################################################################
49// static fields
50// #################################################################################################
51
52// #################################################################################################
53// Constructor/Destructor
54// #################################################################################################
55
56Domain::Domain( MonoAllocator& allocator, PoolAllocator& pool, const NString& name )
57: Name (allocator, name)
58, Parent (nullptr)
59, SubDomains (allocator)
60, Data (allocator)
61, PrefixLogables(pool)
62{
63 Data .reserve( size_t( 2 ) );
64
65 // The full of the root domain equals the name
66 nchar* fullPath= allocator().AllocArray<nchar>( name.Length() + 1 );
67 name.CopyTo( fullPath );
68 fullPath[name.Length()]= '/';
69 FullPath= NString( fullPath, name.Length() + 1 );
70}
71
72
73Domain::Domain( Domain* parent, const NString& name )
74: Name( parent->Data.get_allocator().GetAllocator(), name )
75, Parent ( parent )
76, SubDomains ( parent->Data.get_allocator().GetAllocator() )
77, Data ( parent->Data.get_allocator().GetAllocator() )
78, PrefixLogables( parent->PrefixLogables.GetAllocator() )
79{
80 // if we have a parent, we inherit all logger's verbosities
81 if( parent != nullptr )
82 Data= parent->Data;
83
84 // assemble the full path once
85 const Domain* dom= this;
86 NString1K fullPath;
87 do
88 {
89 if ( dom != this || dom->Parent == nullptr )
90 fullPath.InsertAt( "/" , 0 );
91 fullPath.InsertAt( dom->Name, 0 );
92 dom= dom->Parent;
93 }
94 while( dom != nullptr );
95 FullPath.Allocate( Data.get_allocator().GetAllocator(), fullPath );
96}
97
98// #################################################################################################
99// Methods
100// #################################################################################################
101Domain* Domain::Find( NSubstring domainPath, int maxCreate, bool* wasCreated )
102{
103 // set optional output parameter as default to false
104 bool dummy;
105 if ( wasCreated == nullptr )
106 wasCreated= &dummy;
107 *wasCreated= false;
108
109 integer lenBeforeTrim= domainPath.Length();
110
111 // if string is empty (resp. contains only separator characters), return ourselves
112 while ( domainPath.ConsumeChar( Domain::Separator() ) )
113 ;
114 if( domainPath.IsEmpty() )
115 {
116 return this;
117 }
118
119 // Trailing domain separator found: call find on root domain
120 Domain* startDomain= this;
121 if ( lenBeforeTrim > domainPath.Length() )
122 {
123 while (startDomain->Parent != nullptr )
124 startDomain= startDomain->Parent;
125 }
126
127 // call find
128 return startDomain->findRecursive( domainPath, maxCreate, wasCreated );
129}
130
131Domain* Domain::findRecursive( NSubstring& domainPath, int maxCreate, bool* wasCreated )
132{
133 //--- get act sub-name and rest of path
134 domainPath.ConsumeChar( Domain::Separator() );
135 integer endSubName= domainPath.IndexOf( Domain::Separator() );
136
137 ALIB_ASSERT_ERROR( endSubName != 0, "ALOX", "Internal error. This must never happen." )
138
139 // find end of actual domain name and save rest
140 NSubstring restOfDomainPath= nullptr;
141 if ( endSubName > 0 )
142 domainPath.Split<NC>( endSubName, restOfDomainPath, 1 );
143
144 // search subdomain
145 Domain* subDomain= nullptr;
146
147 // "."
148 if( domainPath.Equals<NC>( "." ) )
149 subDomain= this;
150
151 // ".."
152 else if( domainPath.Equals<NC>( ".." ) )
153 subDomain= Parent != nullptr ? Parent : this;
154
155 // search in subdomain
156 else
157 {
158 decltype(SubDomains)::iterator subDomainIt;
159 bool fixedOnce= false;
160 for(;;)
161 {
162 subDomainIt= SubDomains.begin();
163 while ( subDomainIt != SubDomains.end() )
164 {
165 int comparison= (*subDomainIt).Name.CompareTo<NC, lang::Case::Sensitive>( domainPath );
166
167 if( comparison >= 0 )
168 {
169 if ( comparison == 0 )
170 subDomain= &(*subDomainIt);
171 break;
172 }
173 ++subDomainIt;
174 }
175
176 // domain found?
177 if ( subDomain != nullptr )
178 break;
179
180 // try and fix name
181 if( !fixedOnce )
182 {
183 fixedOnce= true;
184
185 bool illegalCharacterFound= false;
186 for( int i= 0; i< domainPath.Length() ; ++i )
187 {
188 nchar c= domainPath[i];
189 if (!( isdigit( c )
190 || ( c >= 'A' && c <= 'Z' )
191 || c == '-'
192 || c == '_'
193 ))
194 {
195 illegalCharacterFound= true;
196 // oh dear: modifying const buffer...but this is definitely from an AString!
197 *const_cast<nchar*>( domainPath.Buffer() + i)= '#';
198 }
199 }
200
201 if ( illegalCharacterFound )
202 continue;
203 }
204
205 // create
206 if ( maxCreate == 0 )
207 return nullptr;
208
209 *wasCreated= true;
210 subDomainIt= SubDomains.emplace( subDomainIt, this, domainPath );
211 --maxCreate;
212 if ( maxCreate == 0 )
213 return &(*subDomainIt);
214 break;
215 }
216 }
217
218 // recursion?
219 return restOfDomainPath.IsNotEmpty()
220 ? subDomain->findRecursive( restOfDomainPath, maxCreate, wasCreated )
221 : subDomain;
222}
223
224Verbosity Domain::SetVerbosity( int loggerNo, Verbosity verbosity, Priority priority )
225{
226 LoggerData& ld= Data[size_t(loggerNo)];
227 if( priority >= ld.Priority )
228 {
229 ld.Priority= priority;
230 ld.LoggerVerbosity= verbosity;
231
232 for( Domain& subDomain : SubDomains )
233 subDomain.SetVerbosity( loggerNo, verbosity, priority );
234 }
235 return ld.LoggerVerbosity;
236}
237
239{
240 Data.emplace_back( LoggerData( logger ) );
241 for( Domain& subDomain : SubDomains )
242 subDomain.addLoggerRecursive( logger );
243}
244
246{
247 Data.erase( Data.begin() + loggerNo );
248 for( Domain& subDomain : SubDomains )
249 subDomain.removeLoggerRecursive( loggerNo );
250}
251
252void Domain::ToString( NAString& tAString )
253{
254 tAString << FullPath;
255 tAString._('[')._( NDec( CntLogCalls,3 ) )._("] ");
256
257 // get verbosities
258 tAString._(" { ");
259 for( size_t i= 0; i < Data.size() ; ++i )
260 {
261 LoggerData& ld= Data[i];
262 tAString._(i!=0 ? ", " : "" )
263 ._('(')
264 ._('[')._( NDec(ld.LogCallsPerDomain, 3) )._( "], " )
266 ._( ')' );
267 }
268 tAString._(" }");
269}
270
271
272}}}// namespace [alib::lox::detail]
273
List< PoolAllocator, std::pair< PrefixLogable *, lang::Inclusion >, Recycling::None > PrefixLogables
Prefix Logables associated with this domain.
Definition domain.inl:104
StdVectorMono< LoggerData > Data
Definition domain.inl:98
ALIB_DLL Domain * Find(NSubstring domainPath, int maxCreate, bool *wasCreated)
Definition domain.cpp:101
void ToString(NAString &target)
Definition domain.cpp:252
ALIB_DLL Domain(MonoAllocator &allocator, PoolAllocator &pool, const NString &name)
Definition domain.cpp:56
ALIB_DLL void addLoggerRecursive(detail::Logger *logger)
Definition domain.cpp:238
NString Name
The name of the domain. For root domains, this is nulled.
Definition domain.inl:84
Domain * Parent
The parent domain. For root domains, this is nullptr.
Definition domain.inl:90
List< MonoAllocator, Domain, Recycling::None > SubDomains
A list of subdomains, sorted by name.
Definition domain.inl:94
ALIB_DLL Verbosity SetVerbosity(int loggerNo, Verbosity verbosity, Priority priority)
Definition domain.cpp:224
NString FullPath
The full path of the domain (set in the constructor once) .
Definition domain.inl:87
ALIB_DLL void removeLoggerRecursive(int loggerNo)
Definition domain.cpp:245
static constexpr nchar Separator()
Definition domain.inl:122
Domain * findRecursive(NSubstring &domainPath, int maxCreate, bool *wasCreated)
Definition domain.cpp:131
TAString & _(const TAppendable &src)
integer CopyTo(TChar *dest) const
Definition string.inl:1850
constexpr integer Length() const
Definition string.inl:318
constexpr bool IsEmpty() const
Definition string.inl:367
integer IndexOf(TChar needle, integer startIdx=0) const
Definition string.inl:844
constexpr bool IsNotEmpty() const
Definition string.inl:371
constexpr const TChar * Buffer() const
Definition string.inl:313
bool Equals(const TString< TChar > &rhs) const
Definition string.inl:541
TSubstring & Split(integer position, TSubstring &target, integer separatorWidth=0, bool trim=false)
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1049
constexpr Pair< T1, T2 > MakePair(const T1 &t1, const T2 &t2)
strings::TDec< nchar > NDec
Type alias in namespace alib.
Definition format.inl:548
strings::TSubstring< nchar > NSubstring
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
monomem::TPoolAllocator< MonoAllocator > PoolAllocator
strings::TString< nchar > NString
Type alias in namespace alib.
Definition string.inl:2390
NLocalString< 1024 > NString1K
Type alias name for TLocalString<nchar,1024>.
strings::TAString< nchar, lang::HeapAllocator > NAString
Type alias in namespace alib.
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
alib::variables::Priority Priority
Type alias in namespace alib.
characters::nchar nchar
Type alias in namespace alib.
Internal class that holds data stored per Logger.
Definition domain.inl:57
Verbosity LoggerVerbosity
The verbosity of the Logger for this domain.
Definition domain.inl:62
int LogCallsPerDomain
the number of log calls on this domain for this logger.
Definition domain.inl:68
variables::Priority Priority
The priority value that was used to set the verbosity.
Definition domain.inl:65