ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
ftree.hpp
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_filetree of the \aliblong.
4///
5/// Copyright 2013-2026 A-Worx GmbH, Germany.
6/// Published under #"mainpage_license".
7//==================================================================================================
8ALIB_EXPORT namespace alib { namespace filetree {
9
10class FTree;
11class FTFile;
12template<typename TLock>
13struct TSharedFTree;
14
15/// This namespace implements internals of namespace #"alib::filetree;2".
16namespace detail {
17
18struct FTreeNodeHandler;
19
20/// A shortcut to the base class of the base class of class #"FTree".
22 FTValue,
24 Recycling::Private>;
25
26/// Specialized #"alib_ns_containers_stringtree_referencedoc;TNodeHandler" for class
27/// #"FTree" which recycles extended information objects of type
28/// #"FTValue::EIDirectory;*", #"FTValue::EISymLinkFile;*", and
29/// #"FTValue::EISymLinkDir;*" with node deletion.
30///
31/// In respect to the node name allocation, this type behaves like
32/// default handler #"StringTreeNamesDynamic".
33/// In debug compilations, statistics
34/// variables #"DBG_STATS_STRINGTREE_NAMES" and
35/// #"DBG_STATS_STRINGTREE_NAME_OVERFLOWS" are increased, just like the original
36/// does.
38 /// The character type that the #"%StringTree" uses for child name and path strings.
39 /// This is taken from the C++ standard library.
41
42 /// The string-type of a node's name. This is a simple static string, allocated with the
43 /// pool allocator.
45
46 /// Copies the node's name to the local string.
47 ///
48 /// @param node The node that was just created. Allows access to the key and
49 /// custom value data. While the parent and sibling nodes are likewise accessible,
50 /// it is strictly forbidden to modify those.
51 /// @param tree The instance of struct #"detail::StringTreeBase;*" that invokes
52 /// this method. Any member may be accessed, including
53 /// #"StringTreeBase;nodeTable" which contains the
54 /// #"MonoAllocator" that the tree uses for the allocation of nodes.
55 static
56 inline
57 void InitializeNode( TTree::Node& node, TTree& tree );
58
59 /// This implementation frees any dynamically allocated memory of the node's name and in
60 /// addition recycles any extended information object attached to the #"FTValue"
61 /// object.
62 /// @param node The node that is to be removed. Allows access to the key and
63 /// custom value data. While the parent and sibling nodes are likewise accessible,
64 /// it is strictly forbidden to modify those.
65 /// @param tree The instance of struct #"detail::StringTreeBase;*" that invokes
66 /// this method. Any member may be accessed, including
67 /// #"StringTreeBase;nodeTable" which contains the
68 /// #"MonoAllocator" that the tree uses for the allocation of nodes.
69 static
70 inline
71 void FreeNode( TTree::Node& node, TTree& tree );
72
73 /// Implements #"FTree::AllocateExtendedInfo;*".
74 /// @param node The node add extended information to.
75 /// @param symLinkDest In case of symbolic link types, the symbolic link target.
76 /// @param symLinkRealPath In case of symbolic link types, the symbolic link target as real path.
78 static
80 const PathString& symLinkDest,
81 const PathString& symLinkRealPath );
82}; // struct FTreeNodeHandler
83
84} // namespace alib::filetree[::detail]
85
86
87//==================================================================================================
88/// Abstract virtual interface type to implement types observing changes in instances of class
89/// #"FTree".
90/// @see Chapter #"alib_filetree_monitoring" of the Programmer's Manual of camp \alib_filetree_nl.
91//==================================================================================================
93 /// The type of change that imposes the notification of a listener.
94 enum class Event {
95 CreateNode, ///< A file or directory entry was created.
96 DeleteNode, ///< A file or directory entry was deleted.
97 };
98
99 /// Virtual destructor.
100 virtual ~FTreeListener() {}
101
102 /// The virtual notification method.
103 /// @param file The file or directory that was modified.
104 /// @param event The type of modification.
105 virtual void Notify( FTFile& file, Event event ) =0;
106
107}; // struct FTreeListener
108
109
110//==================================================================================================
111/// This class builds on \alib type #"StringTree".
112/// The contained elements (tree nodes) are of type#"FTValue" and represent entries in
113/// filesystems.
114/// Usually the tree is filled using the function #"ScanFiles(FTree&)".
115///
116/// ### StringTree Interface ###
117/// Public base class #"StringTree" provides all interfaces necessary to create and
118/// delete entries, iterate and recursively walk the file tree. Please consult its documentation
119/// for further information.
120///
121/// \note As #"ScanFiles(FTree&);documented with function ScanFiles", entities of this
122/// module \alib_filetree_nl exclusively store entries along their <em>"Real Path"</em>, hence
123/// always resolving symbolic links. A user of this library may deviate from this
124/// "data contract".
125///
126/// ### Class FTFile ###
127/// The base classes' method #"StringTree::Root;*" is overloaded by this class
128/// and returns an instance of class #"filetree::FTFile" instead of an instance of class
129/// alib{containers;StringTree::Cursor}.
130/// This class can be turned into a cursor using #"FTFile::AsCursor" and then used to
131/// navigate through the tree. Then, the cursor can be cast back (or assigned) to a #"%FTFile"
132/// instance.
133///
134/// ### Monotonic Behavior ###
135/// The class fulfills #"alib_contmono_intro_strictweak;weak monotonic allocation requirements",
136/// which is achieved by recycling not only the nodes (what base type #"%StringTree" does by default)
137/// but also any extended node information. This is implemented with the <b>StringTree</b>
138/// handler-type #"detail::FTreeNodeHandler;*" on the one hand, and on the other hand,
139/// with the implementation of the method #".AllocateExtendedInfo", which has to be exclusively used
140/// to attach information structs on #"%FTValue" elements.<br>
141/// Furthermore, class #"%FTFile" (the nodes of the tree) provides method
142/// #"FTFile::AttachCustomData", which likewise uses the internal pool-allocator.
143///
144/// In summary, this allows an indefinite sequence of file-scan and result filtering (deletions)
145/// with using more memory than the highest resulting fill state in such sequence requires.
146//==================================================================================================
147class FTree : public StringTree<MonoAllocator, FTValue, detail::FTreeNodeHandler> {
148 friend struct FTreeNodeHandler;
149
150 public:
151 /// An object pool used for recycling all sorts of allocated objects as well as the
152 /// hashtable entries.
153 /// It is #"alib_contmono_chaining;chained" to the allocator provided with construction.
154 ///
155 /// The pool may be used in accordance with the general rules imposed by camp \alib_monomem.
156 /// If so, in multithreaded environments, this object has to be locked (in addition
157 /// to all other custom locks when interfacing this type), when using this pool from custom
158 /// code.
160
161 protected:
162 /// Type alias of this classes' base class.
164
165 #if !DOXYGEN
166 friend struct detail::FTreeNodeHandler; ///< Friendship declaration.
167 friend class filetree::FTFile; ///< Friendship declaration.
168 #endif
169
170 /// Formatting information used with #"FTFile::Format;format methods" of associated
171 /// #"%FTFile" instances.
173
174 /// A caching owner and group resolver. Used with #"FTFile::Format;format methods"
175 /// of associated #"%FTFile" instances.
177
178 /// Record used to manage registered listeners.
180 FTreeListener* listener; ///< The listener to register or dispose.
181 FTreeListener::Event event; ///< The event to listen to.
182 ConstCursorHandle file; ///< If given, the files to listen to.
183 ConstCursorHandle subTree; ///< If given, the path of files to listen to.
184 PathStringPA fileName; ///< If given, the file's name to listen to.
185 PathStringPA pathPrefix; ///< If given, the start string of the file path
186 ///< to monitor.
187 PathStringPA pathSubstring; ///< If given, the substring to match in the path
188 ///< (including the file name) of files to monitor.
189 };
190
191 /// The list of registered listeners.
193
194 /// Implements the various overloaded listener registration methods.
195 /// @param listener The listener to register or dispose.
196 /// @param insertOrRemove Denotes registration or disposal of a listener.
197 /// @param event The event to listen to.
198 /// @param file If given, the exported value of the file to listen to.
199 /// @param subTree If given, the exported value of the subtree of files to listen to.
200 /// @param fileName If given, the file's name to listen to.
201 /// @param pathPrefix If given, the start string of the file path to monitor.
202 /// @param pathSubstring If given, the substring to match in the path (including the file name)
203 /// of the files to monitor.
205 lang::ContainerOp insertOrRemove,
207 const FTFile* file,
208 const StringTree::Cursor* subTree,
209 const PathString& fileName,
210 const PathString& pathPrefix,
211 const PathString& pathSubstring );
212
213 /// Notifies registered listeners on events.
214 /// @param event The event that occurred.
215 /// @param file The file.
216 /// @param filePath The full path of the file. Might be nulled if not available, yet.
218 FTFile& file,
219 const PathString& filePath );
220
221 public:
222 /// Constructor.
223 /// @param allocator The allocator to use.
225 FTree( MonoAllocator& allocator );
226
227 /// Destructor.
229 ~FTree();
230
231 /// Sort of 'overloads' method #"StringTree::Root;*", which otherwise is accessible
232 /// via <b>operator-></b> inherited by parent class #"TSharedMonoVal".
233 /// In contrast to the inherited method, this version returns an instance of type #"%FTFile".
234 /// @return A file-cursor pointing to the root node of this file tree.
235 inline
236 FTFile Root();
237
238 /// Allocates (or recycles) an appropriate information object fitting to the type of this entry.
239 /// This method must only be applied to entries of types
240 /// - #"Types::DIRECTORY",
241 /// - #"Types::SYMBOLIC_LINK" or
242 /// - #"Types::SYMBOLIC_LINK_DIR".
243 /// In debug compilations, this is asserted. It is likewise asserted that the sybolic link
244 /// information strings are empty in case the type is #"Types::DIRECTORY".
245 ///
246 /// @param node The node add extended information to.
247 /// @param symLinkDest In case of symbolic link types, the symbolic link target.
248 /// @param symLinkRealPath In case of symbolic link types, the symbolic link target as real
249 /// path.
250 void AllocateExtendedInfo( Cursor& node, const PathString& symLinkDest,
251 const PathString& symLinkRealPath )
252 { detail::FTreeNodeHandler::AllocateExtendedInfo( node, symLinkDest, symLinkRealPath); }
253
254 /// Deletes all custom data objects attached to any #"%FTFile" in this tree.<br>
255 /// Note that this method is only applicable if all custom data objects set in any node
256 /// of this tree share the same type \p{TCustom}.
257 /// With debug-compilations this is asserted.
258 ///
259 /// @see Method #"FTFile::AttachCustomData;*".
260 /// @tparam TCustom The object type to optionally store in tree nodes.
261 template<typename TCustom>
263 for( auto& node : nodeTable ) {
264 if( node.data.custom ) {
265 ALIB_ASSERT_ERROR( &typeid(TCustom) == node.data.dbgCustomType, "FILETREE",
266 "CustomData to delete does not match attached type.\n"
267 "Deletion has to be performed individually by this software.\n"
268 "This method must only be used if all tree nodes have the same custom data "
269 "attached\n"
270 " Attached type: <{}>\n"
271 " Given type: <{}>" , &typeid(TCustom), node.data.dbgCustomType )
272
273 static_cast<TCustom*>( node.data.custom ) -> ~TCustom();
274 Pool.free( node.data.custom, sizeof(TCustom) );
275 node.data.custom= nullptr;
276 ALIB_DBG( node.data.dbgCustomType= nullptr; )
277 } } }
278
279 /// Recalculates the sums of the given node. This is \b not done recursively. The fix is needed
280 /// when scanning an existent directory with potentially more greedy scan parameters.
281 /// @param directory The directory to re-calculate the sums for.
283 static
284 void FixSums(Cursor directory);
285
286 /// Retrieves formatting flags which are used with method #"FTFile::Format;*".
287 /// @return Number formatting information for #"%FTFile" objects associated with this file tree.
289
290 /// Retrieves formatting flags which are used with method #"FTFile::Format;*".
291 /// @return Number formatting information for #"%FTFile" objects associated with this file tree.
292 const NumberFormat& GetNumberFormat() const { return numberFormat; }
293
294 /// Retrieves formatting flags which are used with method #"FTFile::Format;*".
295 /// @return Number formatting information for #"%FTFile" objects associated with this file tree.
297
298 //===================================== Listener Registration ====================================
299
300
301 /// Notifies registered listeners on events.
302 /// @param event The event that occurred.
303 /// @param file The file.
304 /// @param filePath The full path of the file. Might be nulled if not available to the caller.
305 /// In this case it is internally created.<br>
306 /// Defaults to #"NULL_STRING".
307 inline
308 void Notify( FTreeListener::Event event,
309 FTFile file ,
310 const PathString& filePath= NULL_PATH );
311
312 /// @return \c true if listeners are registered with this file tree, \c false otherwise
313 bool HasListeners() { return listeners.size() > 0; }
314
315 /// Inserts or removes a listener to a specific file.
316 /// @param insertOrRemove Denotes whether the listener should be inserted or removed.
317 /// (Only enum elements #"%ContainerOp::Insert" or #"%ContainerOp::Remove"
318 /// must be passed.)
319 /// @param listener The listener to register.
320 /// @param event The event to listen to.
321 /// @param file The file to listen to.
322 /// @see Chapter #"alib_filetree_monitoring" of the Programmer's Manual of camp \alib_filetree_nl.
324 FTreeListener* listener,
326 const FTFile& file ) {
327 ALIB_ASSERT_WARNING( event != FTreeListener::Event::CreateNode, "VARIABLES",
328 "Event::Creation will never be invoked with this listener-registration-type." )
329 registerListener( listener, insertOrRemove, event, &file, nullptr,
331 }
332
333 /// Inserts or removes a listener for all files that share the given \p{fileName}.
334 /// @param insertOrRemove Denotes whether the listener should be inserted or removed.
335 /// (Only enum elements #"%ContainerOp::Insert" or #"%ContainerOp::Remove"
336 /// must be passed.)
337 /// @param listener The listener to register.
338 /// @param event The event to listen to.
339 /// @param fileName The name of one or more files to listen to.
340 /// @see Chapter #"alib_filetree_monitoring" of the Programmer's Manual of camp \alib_filetree_nl.
342 FTreeListener* listener,
344 const PathString& fileName ) {
345 ALIB_ASSERT_ERROR( fileName.IsNotEmpty(), "VARIABLES", "Empty file name given." )
346 registerListener( listener, insertOrRemove, event, nullptr, nullptr, fileName,
348 }
349
350
351 /// Inserts or removes a listener for all files below the subtree specified by the
352 /// given \p{cursor}.
353 /// @param insertOrRemove Denotes whether the listener should be inserted or removed.
354 /// (Only enum elements #"%ContainerOp::Insert" or #"%ContainerOp::Remove"
355 /// must be passed.)
356 /// @param listener The listener to register.
357 /// @param event The event to listen to.
358 /// @param cursor The parent node in the tree of files to monitor.
359 /// @see Chapter #"alib_filetree_monitoring" of the Programmer's Manual of camp \alib_filetree_nl.
360 void MonitorPath( lang::ContainerOp insertOrRemove,
361 FTreeListener* listener,
363 const FTree::Cursor& cursor ) {
364 registerListener( listener, insertOrRemove, event, nullptr, &cursor,
366 }
367
368 /// Inserts or removes a listener for all files below the subtree specified by the
369 /// given \p{startPath}.
370 /// \attention Note that the parameter \p{pathPrefix} has to be a portion of a
371 /// #"Path::;real path".
372 /// @param insertOrRemove Denotes whether the listener should be inserted or removed.
373 /// (Only enum elements #"%ContainerOp::Insert" or #"%ContainerOp::Remove"
374 /// must be passed.)
375 /// @param listener The listener to register.
376 /// @param event The event to listen to.
377 /// @param pathPrefix The path prefix of the subtree of files to monitor. Note that a
378 /// missing leading separator character will be added.
379 /// @see Chapter #"alib_filetree_monitoring" of the Programmer's Manual of camp \alib_filetree_nl.
381 FTreeListener* listener,
383 const PathString& pathPrefix ) {
384 ALIB_ASSERT_ERROR( pathPrefix.IsNotEmpty(), "VARIABLES", "Empty path prefix given." )
385 registerListener( listener, insertOrRemove, event, nullptr, nullptr,
386 NULL_PATH, pathPrefix, NULL_PATH );
387 }
388
389 /// Inserts or removes a listener for all files whose path (excluding the file name) contains
390 /// the given \p{pathSubstring}.
391 /// \attention Note that the parameter \p{pathSubstring} has to be a portion of a
392 /// #"Path::;real path".
393 /// @param insertOrRemove Denotes whether the listener should be inserted or removed.
394 /// (Only enum elements #"%ContainerOp::Insert" or #"%ContainerOp::Remove"
395 /// must be passed.)
396 /// @param listener The listener to register.
397 /// @param event The event to listen to.
398 /// @param pathSubstring The substring to match in the path (including the file name)
399 /// of the files to monitor.
400 /// @see Chapter #"alib_filetree_monitoring" of the Programmer's Manual of camp \alib_filetree_nl.
402 FTreeListener* listener,
404 const PathString& pathSubstring ) {
405 ALIB_ASSERT_ERROR( pathSubstring.IsNotEmpty(), "VARIABLES", "Empty path substring given." )
406 registerListener( listener, insertOrRemove, event, nullptr, nullptr,
407 NULL_PATH, NULL_PATH, pathSubstring );
408 }
409
410 /// Removes all registrations of the given listener.
411 /// @param listener The listener to remove.
412 /// @return The number of registrations that have been removed.
413 /// @see Chapter #"alib_filetree_monitoring" of the Programmer's Manual of camp \alib_filetree_nl.
415 int MonitorStop( FTreeListener* listener );
416}; // FTree
417
418
419/// Utility type which implements #"TSharedMonoVal" with class #"FTree".
420/// The result of combining both is an automatic pointer to a #"%FTree" that is "self-contained"
421/// in the first buffer of a #"MonoAllocator" together with the allocator itself.
422/// The tree is deleted and all associated memory is freed when the last copy of the pointer
423/// goes out of scope.
424///
425/// Along with the #"%FTree", this shared object includes a #"SharedLock".
426/// See chapter #"alib_contmono_smv_locking" of the Programmer's Manual of module \alib_monomem
427/// for further information on how to protect the contents of this type against
428/// thread-racing-conditions.
429///
430/// @tparam TLock The lock type passed to the template parameter of parent type
431/// #"TSharedMonoVal" with the same name.<br>
432/// With the inclusion of module \alib_threads in the \alibbuild, the type-alias
433/// #"alib::SharedFTree;2" chooses type #"SharedLock".<br>
434/// Otherwise, in case \alib is compiled without threading support, the alias chooses
435/// <c>void</c>.<br>
436/// If it is assured that no racing-conditions occur with shared instances in
437/// multithreaded software, the using code may pass <c>void</c> here as well.
438template<typename TLock>
439struct TSharedFTree : monomem::TSharedMonoVal<FTree, HeapAllocator, TLock> {
440 /// Exposed shortcut to the base type.
442
443 /// Constructs an empty instance, hence a cleared automatic pointer.
444 TSharedFTree() =default;
445
446 /// Constructs an empty instance from \c std::nullptr.
447 /// This constructor is necessary to allow assignment of \c nullptr to values of this type,
448 /// which clears the automatic pointer.
449 TSharedFTree(std::nullptr_t) noexcept {}
450
451 /// Constructor.
452 /// Calls the constructor of parent #"%TSharedMonoVal" and then invokes
453 /// #"TSharedMonoVal::ConstructT;*" passing the mono allocator that the
454 /// parent creates this instance in.<br>
455 /// Furthermore calls DbgCriticalSections to enable assertions to locked usage.
456 /// @param initialBufferSizeInKB The initial size of memory buffers.
457 /// Passed to the allocator given with parent class
458 /// #"TSharedMonoVal".
459 /// @param bufferGrowthInPercent Optional growth factor in percent, applied to the buffer size
460 /// with each next buffer allocation.
461 /// Passed to the allocator given with parent class
462 /// #"TSharedMonoVal".
463 /// Should be set to \c 200, to double the size with each
464 /// allocation.
465 /// Defaults to \c 200.
466 TSharedFTree( size_t initialBufferSizeInKB,
467 unsigned bufferGrowthInPercent = 200 )
468 : Base(initialBufferSizeInKB, bufferGrowthInPercent) {
471 ALIB_DBG(Base::GetAllocator().DbgName= "SharedFTree";)
472 }
473
474 /// Defaulted copy-assignment operator.
475 /// @return A reference to <c>this</c>.
477
478 /// Destructor.
479 /// Calls #".DbgCriticalSections" to stop checking the integrated \p{TLock}.
481
482 #if DOXYGEN
483 /// Enables or disables critical section checks between the contained \p{T} and the likewise
484 /// contained \p{TLock}.<br>
485 /// In case \p{TLock} equals <c>void</c> or if symbol #"ALIB_DEBUG_CRITICAL_SECTIONS" is not
486 /// set, this method is empty (and its use is optimized out).
487 /// @param onOff The switch.
489 #else
490 template<typename TRequires= typename Base::LockType>
491 requires( !std::same_as<TRequires, void> )
493 #if ALIB_DEBUG_CRITICAL_SECTIONS
494 if ( !Base::IsNulled() ) {
495 if( onOff == lang::Switch::On ) {
496 Base::Self().NodeTable().dcs .DCSLock= &Base::GetLock();
499 }
500 else {
501 Base::Self().NodeTable().dcs .DCSLock= nullptr;
502 Base::GetAllocator().DbgCriticalSectionsPH.Get()->DCSLock= nullptr;
503 Base::Self().Pool .DCSLock= nullptr;
504 } }
505 #else
506 (void) onOff;
507 #endif
508 }
509
510 template<typename TRequires= typename Base::LockType>
511 requires std::same_as<TRequires, void>
513 #endif
514
515 /// Clears all scanned or otherwise inserted data and re-initializes this object to its
516 /// constructor defaults and resets the #"%MonoAllocator" of the parent class.<br>
517 ///
518 /// All shared instances remain valid (while, of course, their content is likewise reset).
519 void Reset() {
520 // just invoke parent's reset method passing the mono allocator to the constructor.
524 }
525
526}; // struct TSharedFTree
527
528//==================================================================================================
529//================================ Implementation of the node mainer ===============================
530//==================================================================================================
531#if !DOXYGEN
533
534void detail::FTreeNodeHandler::InitializeNode( TTree::Node& node, TTree& tree )
535{ node.name.storage.Allocate( static_cast<FTree&>(tree).Pool, node.name.key ); }
536
537void detail::FTreeNodeHandler::FreeNode( TTree::Node& node, TTree& tree ) {
538 // delete node name
539 auto& pool= static_cast<FTree&>(tree).Pool;
540
541 if ( node.name.storage.Length() )
542 pool.free( const_cast<TTree::CharacterType*>(node.name.storage.Buffer()),
543 size_t(node.name.storage.Length()) * sizeof(TTree::CharacterType) );
544
545 // recycle extended info structs
546 FTValue& value= node.data;
547 auto extendedInfo= value.GetExtendedInfo();
548 if( extendedInfo == nullptr )
549 return;
550
551 if( value.IsSymbolicLink() ) {
552 // delete old values
553 FTValue::EISymLinkFile& ei= *static_cast<FTValue::EISymLinkFile*>(extendedInfo);
554
555 if( ei.RealTarget.Length() && ei.RealTarget.Buffer() != ei.Target.Buffer() )
556 pool().Free( ei.RealTarget.Buffer(), ei.RealTarget.Length() + 1 );
557
558 if( ei.Target.Buffer() )
559 pool().Free( ei.Target.Buffer(), ei.Target.Length() + 1 );
560
561 if( value.Type() == FileStatus::Types::SYMBOLIC_LINK )
562 pool().Delete( static_cast<FTValue::EISymLinkFile*>(extendedInfo) );
563 else
564 pool().Delete( static_cast<FTValue::EISymLinkDir*>(extendedInfo) );
565
566 // clear to be able to check double use in debug mode
567 ALIB_DBG( value.SetExtendedInfo(nullptr) );
568 return;
569 }
570
572 "FILETREE", "Given node is not a directory or symbolic link but still has extendedInfo set." )
573
574 pool().Delete( static_cast<FTValue::EIDirectory*>(extendedInfo) );
575
576 // clear to be able to check double use in debug mode
577 ALIB_DBG( value.SetExtendedInfo(nullptr) );
578}
579#include "ALib.Lang.CIMethods.H"
580#endif
581
582
583//==================================================================================================
584/// This class represents nodes in #"FTree" instances.
585/// While class #"%FTree" is just a rather small wrapper around its base class
586/// #"StringTree", this class #"%FTFile" is a wrapper around class
587/// #"StringTree::Cursor;*".
588/// With that, instances of this class are very lightweight and contain only two pointers: One
589/// pointing to the #"%FTree" that an instance originates from, the second pointing to the
590/// node in the tree. The node in the tree then contains a pointer to type #"FTValue" which is
591/// an extension of the class #"FileStatus".
592///
593/// It is important to understand that with this architecture, this class has three interfaces.
594/// 1. The direct interface as exposed with this class.
595/// 2. The interface reached with <c>operator-></c> which indirects to the embedded #"%FTValue"
596/// data.
597/// 3. The interface of class #"^StringTree::Cursor", which is accessible with method #".AsCursor"
598///
599/// To get a thorough understanding of why this split exists and what purpose which of the
600/// three interfaces serve, a basic understanding of container type class
601/// #"StringTree" is very helpful.
602/// A similar design principle is implemented with class #"Variable" of module
603/// \alib_variables. A technical explanation to why base class <b>FTree::Cursor</b> is protected
604/// there in the same fashion is #"Variable::AsCursor;given here".
605///
606/// @see
607/// - For a quick tutorial about using \alib files, consult the tutorial-style
608/// #"alib_mod_filetree;Programmer's Manual" of camp \alib_filetree_nl.
609/// - For this class, a #"alibtools_debug_helpers_gdb;pretty printer" for the
610/// GNU debugger is provided.
611/// - Instances of this type are #"alib_strings_assembly_ttostring;appendable" to
612/// class #"%AString". If done, the full path and file name is written to the target string.
613//==================================================================================================
614class FTFile : protected FTree::Cursor {
615 public:
616 /// The base cursor type of the internal #"%StringTree". This type is used to perform
617 /// cursor operations on #"%FTree" instances.
619
620 /// The constant version of type #".Cursor".
622
623
624 /// Returns a \c reference to the file tree that this file resides in.
625 /// @return The associated file tree instance.
626 FTree& GetFTree() const { return static_cast<FTree&>(Tree()); }
627
628 /// Defaulted default constructor.
629 FTFile() =default;
630
631 /// Constructor taking a file tree. After construction, this file will point to the root
632 /// node <c>"/"</c> of the tree.
633 /// @param pTree The tree to associate this file instance with.
634 FTFile( FTree& pTree )
635 : Cursor( pTree.Root() ) {}
636
637 /// Constructs an instance of this type from its base type.
638 /// This constructor is for advanced use when direct operations with class #"%StringTree" and
639 /// its cursor and iterator types are performed.
640 /// @param cursor The #"%StringTree" cursor representing a file.
641 FTFile( const Cursor& cursor )
642 : Cursor(cursor) {}
643
644 /// Comparison operator.
645 /// @param other The object to compare ourselves to.
646 /// @return \c true if this and the given cursor are equal, \c false
647 /// otherwise.
648 bool operator==(const FTFile &other) const { return node == other.node && tree == other.tree; }
649
650 /// Comparison operator.
651 /// @param other The object to compare ourselves to.
652 /// @return \c false if this and the given file are equal, \c true
653 /// otherwise.
654 bool operator!=(const FTFile &other) const { return !((*this) == other); }
655
656 /// Sets this \b Cursor to point to the same file (node in the #"FTree") as the given
657 /// \p{other}.
658 /// @param other The node to let this file instance point to.
659 /// @return A reference to \c this.
660 FTFile& operator=( const Cursor& other ) { Cursor::operator=( other ); return *this; }
661
662 /// Provides \c const access to members of contained #"FTValue" record. Note that
663 /// access to a mutable version of the type is available with method #".GetMutableFInfo".
664 /// @return A non-writable pointer to the embedded #"%FTValue" data.
665 const FTValue* operator->() const { return Cursor::operator->(); }
666
667 /// Provides \c access to members of contained #"FTValue" record. Note that
668 /// \c const access is available with method #".operator->".<br>
669 /// Changes to the values should be done with caution. Usually the values are only set when
670 /// scanning files or using certain interface methods of this class.
671 /// @return A \b writable pointer to the embedded #"%FTValue" data.
672 FTValue& GetMutableFInfo() { return Value(); }
673
674 /// This is an explicit <c>cast operator</c> to the protected base class.
675 /// \note For details on the code design which makes this method necessary, consult the
676 /// documentation of the same concept found with method #"Variable::AsCursor;*".
677 /// @return This instance cast 'down' to its protected base class.
678 Cursor& AsCursor() { return static_cast<Cursor&>(*this); }
679
680 /// \c const version of the <c>cast operator</c> to the protected base class.
681 /// @return This instance cast 'down' to its protected base class.
682 const Cursor& AsCursor() const { return static_cast<const Cursor&>(*this); }
683
684 /// Sets the symbolic parent in case it is not already set, or \p{overwrite} is given.
685 /// \attention The tree node represented by the given cursor handle has to stay valid as long
686 /// as symbolic path assembly is used with this node.
687 /// @see Manual chapter #"alib_filetree_tut_scan_realpath".
688 /// @param handle The exported cursor to the symbolic link that targets this file.
689 /// @param overwrite Advises setting the new value even if a different symbolic parent is
690 /// already set. Defaults to \c false.
691 void SetSymbolicParent(FTree::CursorHandle handle, bool overwrite= false) {
692 FTValue& value= Value();
693 if(handle.value && (!value.symParent || overwrite))
694 value.symParent= handle.value;
695 }
696
697 /// Sets the symbolic parent in case it is not already set, or \p{overwrite} is given.
698 /// \attention The tree node \p{symbolicParent} has to stay valid as long as symbolic path
699 /// assembly is used with this node.
700 /// @param symbolicParent A symbolic link that targets this file.
701 /// @param overwrite Advises setting the new value even if a different symbolic parent is
702 /// already set. Defaults to \c false.
703 /// @see Manual chapter #"alib_filetree_tut_scan_realpath".
704 void SetSymbolicParent(FTFile& symbolicParent, bool overwrite= false)
705 { SetSymbolicParent(symbolicParent.Export(), overwrite); }
706
707 /// Clears the symbolic parent.
708 /// @see Manual chapter #"alib_filetree_tut_scan_realpath".
709 /// already set. Defaults to \c false.
710 void ClearSymbolicParent() { Value().symParent= 0; }
711
712 /// Tests if this file has a symbolic parent.
713 /// @see Manual chapter #"alib_filetree_tut_scan_realpath".
714 /// @return \c true if a symbolic parent is set, \c false otherwise.
715 bool HasSymbolicParent() { return Value().symParent != 0; }
716
717 /// Returns the symbolic parent detected when scanning the file.
718 /// @see Manual chapter #"alib_filetree_tut_scan_realpath".
719 /// @return If present, the symbolic parent that resolved this file.
720 /// Otherwise the "real" parent in the #"FTree".
722 uinteger handleValue= Value().symParent;
723 return handleValue ? FTFile(GetFTree().ImportCursor(FTree::CursorHandle(handleValue)))
724 : FTFile(AsCursor().Parent());
725 }
726
727 /// \c const version of #".GetSymbolicParent".
728 /// @return If present, the symbolic parent that resolved this file.
729 /// Otherwise the "real" parent in the #"FTree".
730 const FTFile GetSymbolicParent() const {
731 uinteger handleValue= Value().symParent;
732 return handleValue ? FTFile(GetFTree().ImportCursor(FTree::CursorHandle(handleValue)))
733 : FTFile(AsCursor().Parent());
734 }
735
736
737
738 // Publishes the protected method TCursor::Name.
739 using Cursor::Name;
740
741 // Publishes the protected method TCursor::IsValid.
742 using Cursor::IsValid;
743
744 // Publishes the protected method TCursor::IsInvalid.
745 using Cursor::IsInvalid;
746
747 /// Re-implements #"TCursor::Parent" to return the parent-file.
748 /// @return A #"%C;FTFile" pointing to the parent folder of the file or folder represented by this.
749 FTFile Parent() const { return TCursor::Parent(); }
750
751 /// Returns the substring from the beginning of #"TCursor::Name" up to (and not including) the
752 /// last period <c>'.'</c> character which is not located at the start of the name.
753 /// With that, edge cases are treated as follows:
754 /// - A filename like "filename.ext.txt" -> "filename.ext"
755 /// - A filename like ".profile" results to identity ".profile".
756 /// @return The filename excluding the #".Extension".
757 PathString Stem() const {
758 PathString result= Name();
759 auto dotPos= result.LastIndexOf('.');
760 return dotPos < 2 ? result
761 : result.Substring( 0, dotPos );
762 }
763
764 /// Returns the file extension, which is the substring behind the last period <c>'.'</c>
765 /// character which is not located at the start of the name.
766 /// (A filename like ".profile" is not treated to have an extension).
767 /// @return The extension found in the filename. An empty string if none is found.
769 auto dotPos= Name().LastIndexOf('.');
770 return dotPos < 2 ? EMPTY_PATH
771 : Name().Substring( dotPos + 1 );
772 }
773
774 /// Appends the file's #"alib_filetree_tut_scan_realpath;real path" to the given \p{target} string.
775 /// The result excludes a trailing separation character.
776 /// If this file represents the root folder of the file tree, nothing is written to \p{target}.
777 /// @see Sibling method #".AssembleSymbolicPath".
778 /// @param target The string buffer to append the path to.
779 /// @param includeFilename Denotes whether the filename should be included or if the path
780 /// to the parent directory is requested.
781 /// @return The given #"%AString" to allow concatenated operations.
784 lang::Inclusion includeFilename ) const {
785 if(includeFilename==lang::Inclusion::Exclude) {
786 if( !AsCursor().IsRoot() )
787 AsCursor().Parent().AssemblePath(target, lang::CurrentData::Keep);
788 }
789 else
790 AsCursor().AssemblePath(target, lang::CurrentData::Keep);
791 return target;
792 }
793
794 /// Returns the #"alib_filetree_tut_scan_realpath;symbolic path" to this file.
795 /// The result excludes a trailing separation character.
796 /// If this file represents the root folder of the file tree, nothing is written to \p{target}.
797 /// @see Sibling method #".AssembleRealPath".
798 /// @param target The string buffer to append the path to.
799 /// @param includeFilename Denotes whether the filename should be included or if the path
800 /// to the parent directory is requested.
801 /// @return The given #"%AString" to allow concatenated operations.
804 AssembleSymbolicPath( strings::TAString<PathCharType>& target,
805 lang::Inclusion includeFilename ) const;
806
807 /// Retrieves the file's owner's name.
808 /// @return The name of the owner of the file.
809 const NString GetOwnerName() const { return GetFTree().GetOGResolver().GetOwnerName(Value()); }
810
811 /// Retrieves the file's group name.
812 /// @return The name of the group of the file.
813 const NString GetGroupName() const { return GetFTree().GetOGResolver().GetGroupName(Value()); }
814
815 /// Tests if custom data is attached to this file.
816 /// @see Methods #".AttachCustomData", #".GetCustomData", #".DeleteCustomData", and
817 /// #"FTree::DeleteAllCustomData;*".
818 /// @return <c>true</c> if custom data is attached to this file, <c>false</c> otherwise.
819 bool HasCustomData() const { return Value().custom != nullptr; }
820
821 /// Retrieves a custom data object.
822 /// With debug-compilations it is asserted that #".HasCustomData" returns <c>true</c>
823 /// and that \p{TCustom} is the same as set.
824 /// @tparam TCustom The type of custom data requested. In case no data was previously attached,
825 /// yet, the constructor of this type is called on the new allocated memory.
826 /// @see Methods #".AttachCustomData", #".HasCustomData", #".DeleteCustomData", and
827 /// #"FTree::DeleteAllCustomData;*".
828 /// @return The custom data record.
829 template<typename TCustom>
830 TCustom& GetCustomData() {
831 ALIB_ASSERT_ERROR( Value().custom != nullptr, "FILETREE", "No custom data set." )
832 ALIB_ASSERT_ERROR( &typeid(TCustom) == Value().dbgCustomType, "FILETREE",
833 "Requested custom object type mismatch.\n"
834 " Attached type: <{}>\n"
835 " Given type: <{}>" , &typeid(TCustom), Value().dbgCustomType )
836
837 return *static_cast<TCustom*>( Value().custom );
838 }
839
840 /// Allocates a custom object attached to this file using the
841 /// #"TPoolAllocator;PoolAllocator" of the #"%FTree".
842 ///
843 /// @see Methods #".GetCustomData", #".HasCustomData", #".DeleteCustomData", and
844 /// #"FTree::DeleteAllCustomData;*".
845 /// @tparam TCustom The type of custom data associated to the #"%FTree" that this file belongs
846 /// to.
847 /// @tparam TArgs Types of the variadic arguments \p{args} that construct \p{TCustom}.
848 /// @param args Variadic arguments forwarded to the constructor of \p{TCustom}.
849 /// @return The custom data record.
850 template<typename TCustom, typename... TArgs>
851 TCustom& AttachCustomData(TArgs&&... args) {
852 ALIB_ASSERT_ERROR( Value().custom == nullptr, "FILETREE", "Custom data already set." )
853
854 auto* custom= GetFTree().Pool().template New<TCustom>( std::forward<TArgs>(args)... );
855 Value().custom= custom;
856 ALIB_DBG(Value().dbgCustomType= &typeid(TCustom); )
857 return *custom;
858 }
859
860 /// Destructs and deletes the custom data attached to this file.
861 /// With debug-compilations it is asserted that #".HasCustomData" returns <c>true</c>
862 /// and that \p{TCustom} is the same as set.
863 /// @see Methods #".AttachCustomData", #".GetCustomData", #HasCustomData, and
864 /// #"FTree::DeleteAllCustomData;*".
865 /// @tparam TCustom The object type to optionally store in tree nodes.
866 template<typename TCustom>
869 GetFTree().Pool.free( Value().custom, sizeof(TCustom) );
870 Value().custom= nullptr;
871 }
872
873 /// Writes the permission flags to the given \p{target} string in the
874 /// same format as GNU/Linux command <em>'ls -l'</em> does.
875 /// @param target The target string to write into.
876 /// @return The given target to allow concatenated calls.
877 AString& FormatAccessRights(AString& target) const;
878
879 /// Writes formatted information on this file to the given string buffer \p{target}.
880 /// Within the pattern string \p{format}, different symbols are interpreted as tokens.
881 /// Spaces between tokens are written as given.
882 /// Strings within the format text that should not be interpreted as tokens may be given
883 /// in single quotes.
884 /// Two consecutive single quotes will be replaced to one single quote.<br>
885 ///
886 /// Tokens are defined in lower case letters.
887 /// If given with upper case letters, the generated string is converted to upper case letters.
888 ///
889 /// This method supports the following tokens:
890 ///
891 /// <center>Token</center> | <center>Description</center>
892 /// - - - - - - - - - - - - | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
893 /// a |Invokes #FormatAccessRights.
894 /// b |In case this node has a #"alib_filetree_tut_scan_realpath;symbolic parent", prints " <- /absolute/real/path/to/symbolicparent".
895 /// dm{DATEFORMAT}|The #"FileStatus::MDate;modification date" of this file. This token is optionally followed by a "DATEFORMAT" string given in curly braces. For specification information, see #"CalendarDateTime::Format;*".
896 /// db{DATEFORMAT}|Same as 'dm', but uses the #"FileStatus::BDate;creation date" of this file.
897 /// dc{DATEFORMAT}|Same as 'dm', but uses the #"FileStatus::CDate;change date" of this file.
898 /// da{DATEFORMAT}|Same as 'dm', but uses the #"FileStatus::ADate;date of last access" to this file.
899 /// fx |Prints <c>'m'</c> if #"FileStatus::IsCrossingFS" returns \c true, <c>'-'</c> otherwise.
900 /// fa |Prints <c>'a'</c> if #"FileStatus::IsArtificialFS" returns \c true, <c>'-'</c> otherwise.
901 /// gi[{width[,alignment]}] |The ID of the user group of the file.
902 /// gn[{width[,alignment]}] |The name of the user group of the file.
903 /// h |The #"QtyHardLinks;number of hard links" pointing to this file.
904 /// l |In case of Symbolic links, prints " -> linktarget". If the linktarget is a relative path, then the absolute path is appended in round brackets.
905 /// na |The name of the file.
906 /// ns |The #"Stem;stem" of the file.
907 /// ne |The #"Extension;extension" of the file.
908 /// np |The #"alib_filetree_tut_scan_realpath;symbolic path" to the file, excluding the file name and a trailing separation character.
909 /// nf |The #"alib_filetree_tut_scan_realpath;symbolic path" to the file, including the file name and excluding a trailing separation character.
910 /// nr |The #"alib_filetree_tut_scan_realpath;real path" to the file, excluding the file name and a trailing separation character.
911 /// nx |The #"alib_filetree_tut_scan_realpath;real path" to the file, including the file name and excluding a trailing separation character.
912 /// oi[{width[,alignment]}] |The ID of the owner of the file.
913 /// on[{width[,alignment]}] |The name of the owner of the file.
914 /// q |The scan state printed as resourced with enum #"ScanStates".
915 /// rd |Recursively counted subfolders.
916 /// rf |Recursively counted files.
917 /// re |Recursively counted access errors.
918 /// rb |Recursively counted broken links.
919 /// qqq |The scan #"ScanStates", encoded in three characters. The conversion is resourced with enum #"FileStatus::ScanStates3Letters".
920 /// s[{unit}] |The size of the file. See the explanation below.
921 /// t |The #"FileStatus::Types;type", encoded in a single character. The conversion is resourced with enum #"FileStatus::TypeNames1Letter".
922 /// tt |The #"FileStatus::Types;type", encoded in two characters. The conversion is resourced with enum #"FileStatus::TypeNames2Letters".
923 /// ttt |The #"FileStatus::Types;type", encoded in three characters. The conversion is resourced with enum #"FileStatus::TypeNames3Letters".
924 /// tttt |The #"FileStatus::Types;type", as a full word. The conversion is resourced with enum #"FileStatus::Types".
925 ///
926 /// \par Fields and Alignment
927 /// Any of the tokens above may be followed by <b>{width[,Alignment]}</b>. In words:
928 /// a pair of curly braces that contains an integral value specifying a field width
929 /// and, optionally and separated by a comma, an #"lang::Alignment;alignment" specifier.
930 /// (The optional alignment specifier is #"enumrecords::Parse;parsed using enum records".)
931 /// If so, a corresponding field, using spaces as padding character, is printed.
932 ///
933 /// \par Printing sizes:
934 /// Token <c>"s[(unit)]"</c> is used to print file sizes.
935 /// The optional unit string in curly braces may have one the following values:
936 /// - <c>IEC</c>: Chooses #"ByteSizeIEC;IEC standard" with automatic
937 /// detection of an appropriate magnitude. The unit of the magnitude found (<c>"B"</c>,
938 /// <c>"KiB"</c>, <c>"MiB"</c>, <c>"GiB"</c>,...) is added to the output.
939 /// This is the default if the optional unit-partis omitted.
940 /// - <c>SI</c>: Chooses #"ByteSizeSI;SI standard" with automatic
941 /// detection of an appropriate magnitude. The unit of the magnitude found (<c>"B"</c>,
942 /// <c>"kB"</c>, <c>"MB"</c>, <c>"GB"</c>,...) is added to the output.
943 /// - One of the more than 20 possible entity names of either IEC or SI standard.
944 /// In this case, the unit is \b not included after the number, because this way it can be
945 /// optionally added to the format string by using a pair of single quotes <c>'</c>.
946 /// \par
947 /// With the two automatic modes <c>IEC</c> and <c>SI</c>, the namespace function
948 /// #"FormatByteSize" is used.<br>
949 ///
950 /// \par
951 /// For formatting the file size numbers, this method retrieves formatting hints with
952 /// #"FTree::GetNumberFormat;*". With that, the details of the format can
953 /// be specified "per FTree". Manipulations of this object before invoking this method,
954 /// allows specifying output widths, group characters, decimal separation character, and so
955 /// forth.
956 ///
957 ///
958 /// \par Printing owner and group:
959 /// For printing owner and group names, those have to be queried from the OS.
960 /// To increase performance, the resolver utility instance received with
961 /// #"FTree::GetOGResolver;*" is used. The use of this instance has to be protected
962 /// against racing conditions in multithreaded applications. This means if two threads
963 /// invoke this method on #"%FTFile" object that belong to the same #"%FTree", a locking
964 /// mechanism has to be used, to avoid undefined behavior. (For example, by using the class
965 /// #"threads::Lock".)
966 ///
967 /// \par Sample
968 /// As a sample, the following format string mimics the output of GNU/Linux console command
969 /// <em>ls -l</em>:
970 ///
971 /// "ta h on gn s dm nal"
972 ///
973 /// @see This method is invoked by #"FFormat_File", which is an implementation of
974 /// box-function #"FFormat". With hat, objects of this type can be used
975 /// as arguments for #"FormatterPythonStyle".
976 /// The format specifier passed to this method has to be placed behind the colon
977 /// in the placeholder field, as in <c>"{:FORMATSPEC}"</c>.
978 /// If no format string is given in the placeholder, the string
979 /// <b>"ta h on gn s dm nal"</b> is used, which is resourced in the camp
980 /// #"FILETREE;2" under key <b>"FFMT"</b>.
981 ///
982 ///
983 /// @param format The format pattern string.
984 /// @param target A reference to an AString that gets the result of the format processing
985 /// appended.
986 /// @param targetData If \c CurrentData::Keep (the default) the string is appended to \p{target}.
987 /// if \c CurrentData::Clear, \p{target} is cleared.
988 /// @param numberFormat The number format specification to use. Defaults to \c nullptr which
989 /// chooses #"TNumberFormat::Computational;*".
990 /// @returns \p{target} (for convenience).
992 AString& Format( Substring format,
993 AString& target,
995 NumberFormat* numberFormat = nullptr ) const;
996
997}; // class FTFile
998
999//==================================================================================================
1000//============================= Implementation of inlines of class FTree ===========================
1001//==================================================================================================
1003
1004void FTree::Notify( FTreeListener::Event event, FTFile file, const PathString& filePath )
1005{ if (HasListeners()) notifyListeners(event, file, filePath); }
1006
1007
1008//==================================================================================================
1009//==================================== Box-function FFormat_File ===================================
1010//==================================================================================================
1011/// This implementation of boxing function #"%FFormat" for objects of type #"%FTFile", simply
1012/// invokes the method #"FTFile::Format;*" and thus, using the format specification is given
1013/// with that method.
1014///
1015/// Note that the #"TNumberFormat;NumberFormat" instance used for formatting file sizes
1016/// and similar, does not use the instance given with parameter \p{nf}. Instead, the instance
1017/// retrieved with #"FTree::GetNumberFormat;*" is used. This feature enables to
1018/// determine the number format separately for file data output, independent of the settings the
1019/// formater uses.
1020///
1021/// If the parameter \p{formatSpec} is empty, the string <b>"ta h on gn s dm nal"</b> is used,
1022/// which is resourced in camp #"FILETREE" under the key <b>"FFMT"</b>.
1023///
1024/// @param box The box containing the file object.
1025/// @param formatSpec The format string.
1026/// @param nf The number format specification to use.
1027/// @param target The target string to write to.
1028void FFormat_File( const Box& box, const String& formatSpec, NumberFormat& nf, AString& target );
1029
1030} // namespace alib[::filetree]
1031
1032/// Type alias in namespace #"%alib".
1034
1035#if !ALIB_SINGLE_THREADED || DOXYGEN
1036DOX_MARKER([DOX_MANUAL_ALIASES_FTREE])
1037/// Type alias in namespace #"%alib".
1038using SharedFTree= filetree::TSharedFTree<SharedLock>;
1039DOX_MARKER([DOX_MANUAL_ALIASES_FTREE])
1040#else
1042#endif
1043
1044/// Type alias in namespace #"%alib".
1046
1047} // namespace [alib]
1048
1049
1050//##################################################################################################
1051// struct AppendableTraits<Cursor>
1052//##################################################################################################
1053
1054// Faking all template specializations of namespace strings for doxygen into namespace
1055// strings::APPENDABLES to keep the documentation of namespace string clean!
1056namespace alib::strings {
1057#if DOXYGEN
1058namespace APPENDABLES {
1059#endif
1060
1061/// Specialization of functor #"AppendableTraits" for type #"filetree::FTFile".
1062template<typename TChar>
1064 /// Writes the file's complete path (including the filename) to the given AString.
1065 /// @param target The #"%WAString" that #"%Append(const TAppendable&)" was invoked on.
1066 /// @param file The file.
1068 requires (sizeof(TChar) == sizeof(PathCharType)) {
1069 file.AssembleSymbolicPath( target, lang::Inclusion::Include );
1070 }
1071
1072 #if !DOXYGEN
1073 void operator()( TAString<TChar, lang::HeapAllocator>& target, const filetree::FTFile& file )
1074 requires (sizeof(TChar) != sizeof(PathCharType)) {
1075 Path path;
1076 file.AssembleSymbolicPath( path, lang::Inclusion::Include );
1077 target << path;
1078 }
1079 #endif
1080
1081};
1082
1083#if DOXYGEN
1084} // namespace alib::strings[APPENDABLES]
1085#endif
1086} // namespace [alib::strings]
1087
1088ALIB_BOXING_VTABLE_DECLARE( alib::filetree::FTFile , vt_files_cursor )
1089
1090//-------------------------------------------- Debug Dump ------------------------------------------
1091#if ALIB_DEBUG
1092ALIB_EXPORT namespace alib::filetree {
1093
1094 /// The format string used with namespace function #"filetree::DbgDump".<br>
1095 /// Defaults to <c>"{: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) 'nf l}\n"</c><br>
1096 /// This global variable is only available with debug-compilations.
1097 extern String DBG_DUMP_FORMAT;
1098
1099/// Dumps the given branch of this object's tree.<br>
1100/// This function is only available with debug-compilations.
1101/// @param target The target string buffer.
1102/// @param tree The tree to dump.
1103/// @param includedTypes Optional filter for types. Defaults to 'all'.
1104/// @param startNode The start node. If this is not #"TCursor::IsValid;valid",
1105/// the root node is chosen. Defaults to an invalid cursor.
1106/// @param depth The maximum depth of recursion. Defaults to unlimited depth.
1107/// @return The given \p{target} to allow concatenated operations.
1110 FTree& tree ,
1112 FTree::Cursor startNode = FTree::Cursor(),
1113 unsigned depth = (std::numeric_limits<unsigned int>::max)() );
1114
1115} // namespace [alib::filetree]
1116#endif
1117
1118#if DOXYGEN
1119namespace alib::filetree {
1120#endif
1121/// This is the namespace <c>::std</c>.
1122/// Only for this documentation it is placed inside <c>alib::filetree</c>.
1123namespace std {
1124
1125/// Specialization of <c>std::hash</c> for the type #"^FTree::CursorHandle".
1126template <>
1127struct hash<alib::filetree::FTree::CursorHandle> {
1128 /// Functor operator returning the hash-value.
1129 /// @param cursorHandle The handle to get the hash for.
1130 /// @return Simply this handle's field "CursorHandle::value".
1131 size_t operator()(const alib::filetree::FTree::CursorHandle& cursorHandle) const noexcept {
1132 return cursorHandle.value;
1133 }
1134};
1135
1136/// Specialization of <c>std::hash</c> for the type #"^FTree::ConstCursorHandle".
1137template <>
1138struct hash<alib::filetree::FTree::ConstCursorHandle> {
1139 /// Functor operator returning the hash-value.
1140 /// @param cursorHandle The handle to get the hash for.
1141 /// @return Simply this handle's field "CursorHandle::value".
1142 size_t operator()(const alib::filetree::FTree::ConstCursorHandle& cursorHandle) const noexcept {
1143 return cursorHandle.value;
1144 }
1145};
1146
1147} // namespace std
1148#if DOXYGEN
1149} namespace [alib::filetree]
1150#endif
#define ALIB_DLL
#define ALIB_ASSERT_WARNING(cond, domain,...)
#define ALIB_EXPORT
#define ALIB_DBG(...)
#define ALIB_ASSERT_ERROR(cond, domain,...)
#define ALIB_BOXING_VTABLE_DECLARE(TMapped, Identifier)
StringTree(AllocatorType &allocator, CharacterType pathSeparator)
const FTValue * operator->() const
Definition ftree.hpp:665
strings::TAString< PathCharType > & AssembleRealPath(strings::TAString< PathCharType > &target, lang::Inclusion includeFilename) const
Definition ftree.hpp:783
const FTFile GetSymbolicParent() const
Definition ftree.hpp:730
const Cursor & AsCursor() const
Definition ftree.hpp:682
FTFile()=default
Defaulted default constructor.
TCustom & AttachCustomData(TArgs &&... args)
Definition ftree.hpp:851
bool operator!=(const FTFile &other) const
Definition ftree.hpp:654
TCustom & GetCustomData()
Definition ftree.hpp:830
FTree::Cursor Cursor
Definition ftree.hpp:618
bool operator==(const FTFile &other) const
Definition ftree.hpp:648
const NString GetOwnerName() const
Definition ftree.hpp:809
bool HasCustomData() const
Definition ftree.hpp:819
PathString Stem() const
Definition ftree.hpp:757
FTFile(const Cursor &cursor)
Definition ftree.hpp:641
FTFile & operator=(const Cursor &other)
Definition ftree.hpp:660
void SetSymbolicParent(FTree::CursorHandle handle, bool overwrite=false)
Definition ftree.hpp:691
FTFile(FTree &pTree)
Definition ftree.hpp:634
FTFile GetSymbolicParent()
Definition ftree.hpp:721
FTFile Parent() const
Definition ftree.hpp:749
Cursor & AsCursor()
Definition ftree.hpp:678
FTValue & GetMutableFInfo()
Definition ftree.hpp:672
const NString GetGroupName() const
Definition ftree.hpp:813
void SetSymbolicParent(FTFile &symbolicParent, bool overwrite=false)
Definition ftree.hpp:704
PathString Extension() const
Definition ftree.hpp:768
FTree & GetFTree() const
Definition ftree.hpp:626
FTree::ConstCursor ConstCursor
The constant version of type #".Cursor".
Definition ftree.hpp:621
constexpr ExtendedEntryInfo * GetExtendedInfo() const
Definition ftvalue.hpp:165
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
void MonitorPathSubstring(lang::ContainerOp insertOrRemove, FTreeListener *listener, FTreeListener::Event event, const PathString &pathSubstring)
Definition ftree.hpp:401
FTree(MonoAllocator &allocator)
Definition ftree.cpp:71
NumberFormat numberFormat
Definition ftree.hpp:172
StringTree< MonoAllocator, FTValue, detail::FTreeNodeHandler > base
Type alias of this classes' base class.
Definition ftree.hpp:163
NumberFormat & GetNumberFormat()
Definition ftree.hpp:288
~FTree()
Destructor.
Definition ftree.cpp:88
void MonitorDistinctFile(lang::ContainerOp insertOrRemove, FTreeListener *listener, FTreeListener::Event event, const FTFile &file)
Definition ftree.hpp:323
void notifyListeners(FTreeListener::Event event, FTFile &file, const PathString &filePath)
Definition ftree.cpp:181
int MonitorStop(FTreeListener *listener)
Definition ftree.cpp:161
void MonitorFilesByName(lang::ContainerOp insertOrRemove, FTreeListener *listener, FTreeListener::Event event, const PathString &fileName)
Definition ftree.hpp:341
PoolAllocator Pool
Definition ftree.hpp:159
const OwnerAndGroupResolver & GetOGResolver() const
Definition ftree.hpp:296
void MonitorPathPrefix(lang::ContainerOp insertOrRemove, FTreeListener *listener, FTreeListener::Event event, const PathString &pathPrefix)
Definition ftree.hpp:380
void MonitorPath(lang::ContainerOp insertOrRemove, FTreeListener *listener, FTreeListener::Event event, const FTree::Cursor &cursor)
Definition ftree.hpp:360
void AllocateExtendedInfo(Cursor &node, const PathString &symLinkDest, const PathString &symLinkRealPath)
Definition ftree.hpp:250
void DeleteAllCustomData()
Definition ftree.hpp:262
static void FixSums(Cursor directory)
Definition ftree.cpp:214
void Notify(FTreeListener::Event event, FTFile file, const PathString &filePath=NULL_PATH)
Definition ftree.hpp:1004
ListMA< ListenerRecord > listeners
The list of registered listeners.
Definition ftree.hpp:192
const NumberFormat & GetNumberFormat() const
Definition ftree.hpp:292
lang::Placeholder< lang::DbgCriticalSections > DbgCriticalSectionsPH
bool IsNulled() const noexcept
AllocatorType & GetAllocator() noexcept
constexpr bool IsNotEmpty() const
Definition string.hpp:353
integer LastIndexOf(TChar needle, integer startIndex=MAX_LEN) const
Definition string.hpp:909
TString< TChar > Substring(integer regionStart, integer regionLength=MAX_LEN) const
Definition string.hpp:368
This namespace implements internals of namespace #"alib::filetree;2".
Definition ftree.cpp:8
containers::detail::StringTreeBase< MonoAllocator, FTValue, FTreeNodeHandler, Recycling::Private > TTree
A shortcut to the base class of the base class of class #"FTree".
Definition ftree.hpp:21
void FFormat_File(const Box &box, const String &formatSpec, NumberFormat &nf, AString &target)
Definition ftfile.cpp:417
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.
Switch
Denotes if sth. is switched on or off.
@ On
Switch it on, switched on, etc.
@ Off
Switch it off, switched off, etc.
@ Keep
Chooses not no clear existing data.
void Destruct(T &object)
Definition tmp.hpp:82
Inclusion
Denotes how members of a set something should be taken into account.
@ Exclude
Chooses exclusion.
@ Include
Chooses inclusion.
Definition alox.cpp:14
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
filetree::FTValue FTValue
Type alias in namespace #"%alib".
Definition ftvalue.hpp:312
strings::TNumberFormat< character > NumberFormat
Type alias in namespace #"%alib".
strings::TString< nchar > NString
Type alias in namespace #"%alib".
Definition string.hpp:2174
threads::SharedLock SharedLock
Type alias in namespace #"%alib".
filetree::TSharedFTree< SharedLock > SharedFTree
Type alias in namespace #"%alib".
Definition ftree.hpp:1038
filetree::FTree FTree
Type alias in namespace #"%alib".
Definition ftree.hpp:1033
containers::List< T, MonoAllocator, TRecycling > ListMA
Type alias in namespace #"%alib".
Definition list.hpp:689
monomem::TPoolAllocator< MonoAllocator > PoolAllocator
boxing::Box Box
Type alias in namespace #"%alib".
Definition box.hpp:1128
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
constexpr PathString NULL_PATH
A nulled path string.
Definition path.hpp:52
strings::TSubstring< character > Substring
Type alias in namespace #"%alib".
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
std::filesystem::path::value_type PathCharType
Definition path.hpp:12
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace #"%alib".
lang::uinteger uinteger
Type alias in namespace #"%alib".
Definition integers.hpp:152
constexpr PathString EMPTY_PATH
An empty path string.
Definition path.hpp:55
HashTable< TAllocator, typename NodeKey::ValueDescriptor, typename NodeKey::Hash, typename NodeKey::EqualTo, lang::Caching::Enabled, TRecycling > nodeTable
virtual ~FTreeListener()
Virtual destructor.
Definition ftree.hpp:100
virtual void Notify(FTFile &file, Event event)=0
Event
The type of change that imposes the notification of a listener.
Definition ftree.hpp:94
@ DeleteNode
A file or directory entry was deleted.
Definition ftree.hpp:96
@ CreateNode
A file or directory entry was created.
Definition ftree.hpp:95
Record used to manage registered listeners.
Definition ftree.hpp:179
FTreeListener * listener
The listener to register or dispose.
Definition ftree.hpp:180
PathStringPA fileName
If given, the file's name to listen to.
Definition ftree.hpp:184
ConstCursorHandle subTree
If given, the path of files to listen to.
Definition ftree.hpp:183
FTreeListener::Event event
The event to listen to.
Definition ftree.hpp:181
ConstCursorHandle file
If given, the files to listen to.
Definition ftree.hpp:182
TSharedFTree()=default
Constructs an empty instance, hence a cleared automatic pointer.
TSharedFTree(size_t initialBufferSizeInKB, unsigned bufferGrowthInPercent=200)
Definition ftree.hpp:466
TSharedFTree & operator=(const TSharedFTree &)=default
void DbgCriticalSections(lang::Switch onOff)
monomem::TSharedMonoVal< FTree, HeapAllocator, TLock > Base
Exposed shortcut to the base type.
Definition ftree.hpp:441
TSharedFTree(std::nullptr_t) noexcept
Definition ftree.hpp:449
static void AllocateExtendedInfo(StringTree< MonoAllocator, FTValue, FTreeNodeHandler >::Cursor &node, const PathString &symLinkDest, const PathString &symLinkRealPath)
Definition ftree.cpp:11
static void FreeNode(TTree::Node &node, TTree &tree)
static void InitializeNode(TTree::Node &node, TTree &tree)
size_t operator()(const alib::filetree::FTree::ConstCursorHandle &cursorHandle) const noexcept
Definition ftree.hpp:1142
size_t operator()(const alib::filetree::FTree::CursorHandle &cursorHandle) const noexcept
Definition ftree.hpp:1131
void operator()(TAString< TChar, lang::HeapAllocator > &target, const filetree::FTFile &file)
Definition ftree.hpp:1067