ALib C++ Library
Library Version: 2402 R1
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 !defined(ALIB_DOX)
10# if !defined (HPP_ALIB_ALOX)
11# include "alib/alox/alox.hpp"
12# endif
13
14# define HPP_ALIB_LOX_PROPPERINCLUDE
15# if !defined (HPP_ALOX_DETAIL_DOMAIN)
17# endif
18# undef HPP_ALIB_LOX_PROPPERINCLUDE
19
20# if !defined (HPP_ALIB_ALOXMODULE)
22# endif
23
24# if !defined (HPP_ALIB_STRINGS_FORMAT)
26# endif
27#endif // !defined(ALIB_DOX)
28
29
30namespace alib { namespace lox { namespace detail {
31
32// #################################################################################################
33// static fields
34// #################################################################################################
35
36// #################################################################################################
37// Constructor/Destructor
38// #################################################################################################
39
40Domain::Domain( MonoAllocator* allocator, const NString& name )
41: SubDomains ( allocator )
42, Data (*allocator )
43, PrefixLogables( allocator )
44{
45 // store parameters
46 Parent= nullptr;
47 Name = allocator->EmplaceString( name );
48
49 Data .reserve( static_cast<size_t>( 2 ) );
50
51 // The full of the root domain equals the name
53 nchar* fullPath= allocator->AllocArray<nchar>( name.Length() + 1 );
54 name.CopyTo( fullPath );
55 fullPath[name.Length()]= '/';
56 FullPath= NString( fullPath, name.Length() + 1 );
58}
59
60
61Domain::Domain( Domain* parent, const NString& name )
62: SubDomains ( &parent->Data.get_allocator().allocator )
63, Data ( parent->Data.get_allocator().allocator )
64, PrefixLogables( &parent->Data.get_allocator().allocator )
65{
66 // store parameters
67 Parent= parent;
68 Name= Data.get_allocator().allocator.EmplaceString( name );
69
70 // if we have a parent, we inherit all logger's verbosities
71 if( parent != nullptr )
72 Data= parent->Data;
73
74 // assemble the full path once
75 const Domain* dom= this;
76 NString1K fullPath;
77 do
78 {
79 if ( dom != this || dom->Parent == nullptr )
80 fullPath.InsertAt( "/" , 0 );
81 fullPath.InsertAt( dom->Name, 0 );
82 dom= dom->Parent;
83 }
84 while( dom != nullptr );
85 FullPath= Data.get_allocator().allocator.EmplaceString( fullPath );
86}
87
89{
90 for ( auto& it : PrefixLogables )
91 delete it.first;
92}
93
94// #################################################################################################
95// Methods
96// #################################################################################################
97Domain* Domain::Find( NSubstring domainPath, int maxCreate, bool* wasCreated )
98{
99 // set optional output parameter as default to false
100 bool dummy;
101 if ( wasCreated == nullptr )
102 wasCreated= &dummy;
103 *wasCreated= false;
104
105 integer lenBeforeTrim= domainPath.Length();
106
107 // if string is empty (resp. contains only separator characters), return ourselves
108 while ( domainPath.ConsumeChar( Domain::Separator() ) )
109 ;
110 if( domainPath.IsEmpty() )
111 {
112 return this;
113 }
114
115 // Trailing domain separator found: call find on root domain
116 Domain* startDomain= this;
117 if ( lenBeforeTrim > domainPath.Length() )
118 {
119 while (startDomain->Parent != nullptr )
120 startDomain= startDomain->Parent;
121 }
122
123 // call find
124 return startDomain->findRecursive( domainPath, maxCreate, wasCreated );
125}
126
127Domain* Domain::findRecursive( NSubstring& domainPath, int maxCreate, bool* wasCreated )
128{
129 //--- get act sub-name and rest of path
130 domainPath.ConsumeChar( Domain::Separator() );
131 integer endSubName= domainPath.IndexOf( Domain::Separator() );
132
133 ALIB_ASSERT_ERROR( endSubName != 0, "ALOX","Internal Error" )
134
135 // find end of actual domain name and save rest
136 NSubstring restOfDomainPath= nullptr;
137 if ( endSubName > 0 )
138 domainPath.Split<false>( endSubName, restOfDomainPath, 1 );
139
140 // search sub-domain
141 Domain* subDomain= nullptr;
142
143 // "."
144 if( domainPath.Equals<false>( "." ) )
145 subDomain= this;
146
147 // ".."
148 else if( domainPath.Equals<false>( ".." ) )
149 subDomain= Parent != nullptr ? Parent : this;
150
151 // search in sub-domain
152 else
153 {
154 List<Domain>::Iterator subDomainIt;
155 bool fixedOnce= false;
156 for(;;)
157 {
158 subDomainIt= SubDomains.begin();
159 while ( subDomainIt != SubDomains.end() )
160 {
161 int comparison= (*subDomainIt).Name.CompareTo<false, lang::Case::Sensitive>( domainPath );
162
163 if( comparison >= 0 )
164 {
165 if ( comparison == 0 )
166 subDomain= &(*subDomainIt);
167 break;
168 }
169 ++subDomainIt;
170 }
171
172 // domain found?
173 if ( subDomain != nullptr )
174 break;
175
176 // try and fix name
177 if( !fixedOnce )
178 {
179 fixedOnce= true;
180
181 bool illegalCharacterFound= false;
182 for( int i= 0; i< domainPath.Length() ; ++i )
183 {
184 nchar c= domainPath[i];
185 if (!( isdigit( c )
186 || ( c >= 'A' && c <= 'Z' )
187 || c == '-'
188 || c == '_'
189 ))
190 {
191 illegalCharacterFound= true;
192 // oh dear: modifying const buffer...but this is definitely from an AString!
193 *const_cast<nchar*>( domainPath.Buffer() + i)= '#';
194 }
195 }
196
197 if ( illegalCharacterFound )
198 continue;
199 }
200
201 // create
202 if ( maxCreate == 0 )
203 return nullptr;
204
205 *wasCreated= true;
206 subDomainIt= SubDomains.Emplace( subDomainIt, this, domainPath );
207 --maxCreate;
208 if ( maxCreate == 0 )
209 return &(*subDomainIt);
210 break;
211 }
212 }
213
214 // recursion?
215 return restOfDomainPath.IsNotEmpty()
216 ? subDomain->findRecursive( restOfDomainPath, maxCreate, wasCreated )
217 : subDomain;
218}
219
220Verbosity Domain::SetVerbosity( int loggerNo, Verbosity verbosity, Priorities priority )
221{
222 LoggerData& ld= Data[static_cast<size_t>(loggerNo)];
223 if( priority >= ld.Priority )
224 {
225 ld.Priority= priority;
226 ld.LoggerVerbosity= verbosity;
227
228 for( Domain& subDomain : SubDomains )
229 subDomain.SetVerbosity( loggerNo, verbosity, priority );
230 }
231 return ld.LoggerVerbosity;
232}
233
235{
236 Data.emplace_back( LoggerData( logger ) );
237 for( Domain& subDomain : SubDomains )
238 subDomain.addLoggerRecursive( logger );
239}
240
242{
243 Data.erase( Data.begin() + loggerNo );
244 for( Domain& subDomain : SubDomains )
245 subDomain.removeLoggerRecursive( loggerNo );
246}
247
248void Domain::ToString( NAString& tAString )
249{
250 tAString << FullPath;
251 tAString._('[')._( NFormat( CntLogCalls,3 ) )._("] ");
252
253 // get verbosities
254 tAString._(" { ");
255 for( size_t i= 0; i < Data.size() ; ++i )
256 {
257 LoggerData& ld= Data[i];
258 tAString._(i!=0 ? ", " : "" )
259 ._('(')
260 ._('[')._( NFormat(ld.LogCallsPerDomain, 3) )._( "], " )
261 ._( std::make_pair( ld.LoggerVerbosity, ld.Priority) )
262 ._( ')' );
263 }
264 tAString._(" }");
265}
266
267
268}}}// namespace [alib::lox::detail]
std::vector< LoggerData, StdContMA< LoggerData > > Data
Definition domain.inl:132
ALIB_API void removeLoggerRecursive(int loggerNo)
Definition domain.cpp:241
List< Domain > SubDomains
Definition domain.inl:128
ALIB_API Domain(MonoAllocator *allocator, const NString &name)
Definition domain.cpp:40
ALIB_API Verbosity SetVerbosity(int loggerNo, Verbosity verbosity, Priorities priority)
Definition domain.cpp:220
void ToString(NAString &target)
Definition domain.cpp:248
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
static constexpr nchar Separator()
Definition domain.inl:155
ALIB_API Domain * Find(NSubstring domainPath, int maxCreate, bool *wasCreated)
Definition domain.cpp:97
strings::TString< TChar > EmplaceString(const strings::TString< TChar > &src)
ALIB_FORCE_INLINE T * AllocArray(TSize length)
TAString & _(const TString< TChar > &src, integer regionStart, integer regionLength=MAX_LEN)
Definition astring.hpp:1056
TAString & InsertAt(const TString< TChar > &src, integer pos)
Definition astring.hpp:1366
integer IndexOf(TChar needle, integer startIdx=0) const
Definition string.hpp:889
constexpr bool IsEmpty() const
Definition string.hpp:414
constexpr bool IsNotEmpty() const
Definition string.hpp:420
constexpr integer Length() const
Definition string.hpp:357
integer CopyTo(TChar *dest) const
Definition string.hpp:1974
bool Equals(const TString< TChar > &rhs) const
Definition string.hpp:573
constexpr const TChar * Buffer() const
Definition string.hpp:350
TSubstring & Split(integer position, TSubstring &target, integer separatorWidth=0, bool trim=false)
#define ALIB_ASSERT_ERROR(cond,...)
Definition alib.hpp:984
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
Definition alib.hpp:644
@ PrefixLogables
Prefix logables.
Definition alib.cpp:57
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:286