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