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