ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
ftree.cpp
1
2using namespace alib::system;
3namespace alib::filetree {
4
5//==================================================================================================
6//=== FTreeNodeHandler
7//==================================================================================================
8namespace detail {
9
12 const PathString& symLinkDest,
13 const PathString& symLinkRealPath ) {
15 || node->Type() == FileStatus::Types::SYMBOLIC_LINK
16 || node->Type() == FileStatus::Types::SYMBOLIC_LINK_DIR,
17 "FILETREE", "Given node is not a directory or symbolic link." )
18
20 == symLinkDest.IsEmpty(),
21 "FILETREE", "Error in symbolic link parameter" )
22
23
24 auto& v = *node;
25 bool isAllocated= v.GetExtendedInfo(); // this might happen with forced rescans
26
27 auto pool= node.Tree<FTree>().Pool();
29 switch (v.Type()) {
31 {
32 if( isAllocated )
33 *static_cast<FTValue::EIDirectory*>(v.GetExtendedInfo())= FTValue::EIDirectory();
34 else
35 v.SetExtendedInfo( pool.New<FTValue::EIDirectory>() );
36 }
37 return;
38
40 {
41 if( isAllocated )
42 *static_cast<FTValue::EISymLinkFile*>(v.GetExtendedInfo())= FTValue::EISymLinkFile();
43 else
44 v.SetExtendedInfo( pool.New<FTValue::EISymLinkFile>() );
45 v.SetLinkTarget( node.Tree<FTree>(), symLinkDest, symLinkRealPath);
46 }
47 return;
48
50 {
51 if( isAllocated )
52 *static_cast<FTValue::EISymLinkDir*>(v.GetExtendedInfo())= FTValue::EISymLinkDir();
53 else
54 v.SetExtendedInfo( pool.New<FTValue::EISymLinkDir>() );
55 v.SetLinkTarget( node.Tree<FTree>(), symLinkDest, symLinkRealPath);
56 }
57 return;
58
59 default:
60 return;
61 }
63}
64# include "ALib.Lang.CIMethods.H"
65
66} // namespace alib::filetree[::detail]
67
68//==================================================================================================
69//=== FTree
70//==================================================================================================
72: StringTree( allocator, DIRECTORY_SEPARATOR )
73, Pool ( allocator )
75, listeners ( allocator ) {
77 numberFormat.FractionalPartWidth= 1;
78
79 DbgSetDCSName("FTree");
80
81 ALIB_DBG( if( alib::FILETREE.IsBootstrapped())
82 {
83 Log_SetDomain( "ALIB/FILETREE", Scope::Path)
84 Log_SetDomain( "FTREE" , Scope::Filename)
85 } )
86}
87
89 #if ALIB_DEBUG
90 for( auto& node : nodeTable )
91 if( node.data.custom ) {
92 Path path;
93 createCursor(node).AssemblePath(path);
94 ALIB_ERROR( "FILETREE",
95 "CustomData not deleted before destruction of class FTree.\n"
96 " First node found: {}.\n"
97 " Attached data type: {}" , path, node.data.dbgCustomType )
98 }
99 #endif
100
101 // we have to delete all nodes before the invocation of the base destructor, because
102 // this would use our pool allocator on existing nodes (which is then destructed already).
103 Clear();
104
105 // delete root value
106 auto* extendedInfo= Root()->GetExtendedInfo();
107 if( extendedInfo )
108 Pool().Delete( static_cast<FTValue::EIDirectory*>(extendedInfo) );
109
111}
112
114 lang::ContainerOp insertOrRemove,
116 const FTFile* file,
117 const StringTree::Cursor* subTree,
118 const PathString& fileName,
119 const PathString& pathPrefix,
120 const PathString& pathSubstring ) {
121 // checks
122 ALIB_ASSERT_ERROR( file ==nullptr || &file->AsCursor().Tree() == this,"FILETREE","Given file does not belong to this FTree." )
123 ALIB_ASSERT_ERROR( subTree ==nullptr || subTree->IsValid() ,"FILETREE","Invalid cursor given." )
124 ALIB_ASSERT_ERROR( subTree ==nullptr || &subTree ->Tree() == this,"FILETREE","Given cursor does not belong to this FTree." )
125
126 //------------------------------------------ registration ----------------------------------------
127 if( insertOrRemove == lang::ContainerOp::Insert) {
128 listeners.emplace_back( ListenerRecord{ listener,
129 event,
130 (file ? file->AsCursor().Export() : ConstCursorHandle()),
131 (subTree ? subTree-> Export() : ConstCursorHandle()),
134 PathStringPA(Pool) } );
135 listeners.back().fileName << fileName;
136 listeners.back().pathPrefix << pathPrefix;
137 listeners.back().pathSubstring<< pathSubstring;
138
139 return;
140 }
141
142 //----------------------------------------------- de ---------------------------------------------
143 for (auto it= listeners.begin() ; it != listeners.end() ; ++it )
144 if( it->listener == listener
145 && it->event == event
146 && it->file == ( file ? file->AsCursor().Export() : ConstCursorHandle() )
147 && it->subTree == ( subTree ? subTree ->Export() : ConstCursorHandle() )
148 && it->fileName .Equals( fileName )
149 && it->pathPrefix .Equals( pathPrefix )
150 && it->pathSubstring.Equals( pathSubstring ) )
151 {
152 (void) listeners.erase( it );
153 return;
154 }
155
156 ALIB_WARNING("FILETREE", "Listener with matching set of parameters not found with deregistration.")
157
158} // FTree::registerListener
159
160
162 // checks
163 ALIB_ASSERT_ERROR( listener!=nullptr, "FILETREE", "Given listener is nullptr." )
164
165 //----------------------------------------------- de ---------------------------------------------
166 int cnt= 0;
167 for (auto it= listeners.begin() ; it != listeners.end() ; )
168 if( it->listener == listener ) {
169 Log_Verbose("Removing listener")
170 it= listeners.erase( it );
171 ++cnt;
172 }
173 else
174 ++it;
175
176 Log_If(cnt==0, Verbosity::Warning, "No listener found to be removed." )
177
178 return cnt;
179} // FTree::registerListener
180
182 FTFile& file,
183 const PathString& filePathGiven ) {
184 Path filePathBuffer;
185 const PathString* filePath= &filePathGiven;
186 for (auto it= listeners.begin() ; it != listeners.end() ; ++it )
187 if( event == it->event ) {
188 // if needed generate file path
189 if( filePath->IsEmpty()
190 && ( it->fileName .IsNotEmpty()
191 || it->pathPrefix .IsNotEmpty()
192 || it->pathSubstring.IsNotEmpty() ) )
193 {
194 (file.AsCursor().IsRoot() ? file.AsCursor()
195 : file.AsCursor().Parent() ).AssemblePath(filePathBuffer);
196 filePath= &filePathBuffer;
197 }
198
199 if( ( it->file .IsValid() && ( it->file == file.AsCursor().Export() ) )
200 || ( it->subTree .IsValid() && ( file.AsCursor().Distance( ImportCursor(it->subTree) ) >= 0 ) )
201 || ( it->fileName .IsNotEmpty() && it->fileName.Equals(file.AsCursor().Name()) )
202 || ( it->pathPrefix .IsNotEmpty() && filePath->StartsWith(it->pathPrefix) )
203 || ( it->pathSubstring.IsNotEmpty() && filePath->IndexOf(it->pathSubstring) >= 0 )
204 )
205 {
206 Log_Verbose("Notifying listener. Event=", event == FTreeListener::Event::CreateNode
207 ? "CreateNode" : "DeleteNode" )
208 it->listener->Notify( file, event );
209 } }
210} // FTree::notifyListeners
211
212
213# include "ALib.Lang.CIFunctions.H"
214void FTree::FixSums( Cursor directory) {
216 "FILETREE", "Given node is not a directory." )
217
218 FTValue::DirectorySums& sums= directory->Sums();
220 directory.GoToFirstChild();
221 while( directory.IsValid()) {
222 FTValue& v= *directory;
223 sums.TypeCounters[size_t(v.Type())]++;
224 if( v.IsDirectory() )
225 sums+= v.Sums();
226
227 directory.GoToNextSibling();
228} }
229
230//==================================================================================================
231//=== Debug Dump
232//==================================================================================================
233
234#if ALIB_DEBUG && !DOXYGEN
235
237 A_CHAR("{:ta h{2,r} on{10,r} gn{10,r} s(IEC){10,r} dm qqq FxFa (rd{3r}' D' rf{3r}' F' re{2r}' EA' rb{2r}'BL) 'nx l b }\n");
238
239AString& DbgDump( AString& target,
240 FTree& tree,
241 EnumBitSet<FileStatus::Types> includedTypes,
242 FTree::Cursor startNode ,
243 unsigned depth ) {
244 if( startNode.IsInvalid() )
245 startNode= tree.Root().AsCursor();
246
249 fmt.Reset();
250DOX_MARKER( [DOX_FILETREE_ITERATION])
251// create and configure iteratator
254stit.SetMaxDepth( depth );
255stit.Initialize ( startNode, startNode.IsRoot() ? lang::Inclusion::Exclude
257// loop over all nodes and dump
258while( stit.IsValid()) {
259 if( includedTypes.Test(stit.Node()->Type()))
260 fmt.Format( target, DBG_DUMP_FORMAT, FTFile(stit.Node()) );
261 stit.Next();
262}
263DOX_MARKER( [DOX_FILETREE_ITERATION])
264 return target;
265}
266
267#endif // ALIB_DEBUG && !DOXYGEN (dump methods)
268# include "ALib.Lang.CIMethods.H"
269
270} // namespace alib::filetree
#define ALIB_ALLOW_SPARSE_ENUM_SWITCH
#define A_CHAR(STR)
#define ALIB_WARNING(domain,...)
#define ALIB_ERROR(domain,...)
#define ALIB_LOCK_RECURSIVE_WITH(lock)
#define ALIB_POP_ALLOWANCE
#define ALIB_DBG(...)
#define ALIB_ASSERT_ERROR(cond, domain,...)
#define Log_If(...)
#define Log_Verbose(...)
#define Log_SetDomain(...)
void SetMaxDepth(unsigned int newMaxDepth=(std::numeric_limits< unsigned >::max)())
void Initialize(CursorType startNode, lang::Inclusion includeStartNode)
void SetPathGeneration(lang::Switch pathGeneration)
StringTree(AllocatorType &allocator, CharacterType pathSeparator)
Cursor & AsCursor()
Definition ftree.hpp:678
constexpr ExtendedEntryInfo * GetExtendedInfo() const
Definition ftvalue.hpp:165
constexpr DirectorySums & Sums() const
Definition ftvalue.hpp:177
OwnerAndGroupResolver ogResolver
Definition ftree.hpp:176
void registerListener(FTreeListener *listener, lang::ContainerOp insertOrRemove, FTreeListener::Event event, const FTFile *file, const StringTree::Cursor *subTree, const PathString &fileName, const PathString &pathPrefix, const PathString &pathSubstring)
Definition ftree.cpp:113
FTree(MonoAllocator &allocator)
Definition ftree.cpp:71
NumberFormat numberFormat
Definition ftree.hpp:172
~FTree()
Destructor.
Definition ftree.cpp:88
void notifyListeners(FTreeListener::Event event, FTFile &file, const PathString &filePath)
Definition ftree.cpp:181
int MonitorStop(FTreeListener *listener)
Definition ftree.cpp:161
PoolAllocator Pool
Definition ftree.hpp:159
static void FixSums(Cursor directory)
Definition ftree.cpp:214
ListMA< ListenerRecord > listeners
The list of registered listeners.
Definition ftree.hpp:192
static threads::RecursiveLock DEFAULT_LOCK
Formatter & Format(AString &target, TArgs &&... args)
static SPFormatter DEFAULT
virtual BoxesMA & Reset()
constexpr bool Test(TInterface bit) noexcept
Definition bitset.hpp:315
constexpr bool IsEmpty() const
Definition string.hpp:349
integer IndexOf(TChar needle, integer startIdx=0) const
Definition string.hpp:799
bool StartsWith(const TString &needle) const
Definition string.hpp:735
constexpr Types Type() const noexcept
constexpr bool IsDirectory() const noexcept
This namespace implements internals of namespace #"alib::filetree;2".
Definition ftree.cpp:8
AString & DbgDump(AString &target, FTree &tree, EnumBitSet< FileStatus::Types > includedTypes=EnumBitSet< FileStatus::Types >(true), FTree::Cursor startNode=FTree::Cursor(), unsigned depth=(std::numeric_limits< unsigned int >::max)())
String DBG_DUMP_FORMAT
ContainerOp
Denotes standard container operations.
@ Insert
Denotes insertions.
@ Off
Switch it off, switched off, etc.
@ Exclude
Chooses exclusion.
@ Include
Chooses inclusion.
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
format::Formatter Formatter
Type alias in namespace #"%alib".
filetree::FilesCamp FILETREE
The singleton instance of ALib Camp class #"FilesCamp".
strings::TString< character > String
Type alias in namespace #"%alib".
Definition string.hpp:2165
system::Path Path
Type alias in namespace #"%alib".
Definition path.hpp:417
strings::TAString< PathCharType, PoolAllocator > PathStringPA
A pool-allocated string representing a path.
Definition path.hpp:47
strings::TString< PathCharType > PathString
The string-type used with this ALib Module.
Definition path.hpp:34
lang::TBitSet< TEnum, enumops::IterableTraits< TEnum >::End, enumops::IterableTraits< TEnum >::Begin > EnumBitSet
filetree::FTFile FTFile
Type alias in namespace #"%alib".
Definition ftree.hpp:1045
constexpr PathCharType DIRECTORY_SEPARATOR
The standard path separator character. Defaults to '\' on Windows OS, '/' else.
Definition path.hpp:63
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace #"%alib".
containers::StringTreeIterator< TTree > StringTreeIterator
Type alias in namespace #"%alib".
HashTable< TAllocator, typename NodeKey::ValueDescriptor, typename NodeKey::Hash, typename NodeKey::EqualTo, lang::Caching::Enabled, TRecycling > nodeTable
Recursively accumulated values for directories.
Definition ftvalue.hpp:25
std::array< uint32_t, size_t(Types::MARKER_TYPES_END)> TypeCounters
Per-type counters.
Definition ftvalue.hpp:27
Event
The type of change that imposes the notification of a listener.
Definition ftree.hpp:94
Record used to manage registered listeners.
Definition ftree.hpp:179
static void AllocateExtendedInfo(StringTree< MonoAllocator, FTValue, FTreeNodeHandler >::Cursor &node, const PathString &symLinkDest, const PathString &symLinkRealPath)
Definition ftree.cpp:11