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