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