Merge branch 'main' of feistymeow.org:feisty_meow
[feisty_meow.git] / filesystem / directory.h
1 #ifndef DIRECTORY_CLASS
2 #define DIRECTORY_CLASS
3
4 /*****************************************************************************\
5 *                                                                             *
6 *  Name   : directory                                                         *
7 *  Author : Chris Koeritz                                                     *
8 *                                                                             *
9 *******************************************************************************
10 * Copyright (c) 2001-$now By Author.  This program is free software; you can  *
11 * redistribute it and/or modify it under the terms of the GNU General Public  *
12 * License as published by the Free Software Foundation; either version 2 of   *
13 * the License or (at your option) any later version.  This is online at:      *
14 *     http://www.fsf.org/copyleft/gpl.html                                    *
15 * Please send any updates to: fred@gruntose.com                               *
16 \*****************************************************************************/
17
18 #include <basis/astring.h>
19 #include <basis/contracts.h>
20 #include <structures/string_array.h>
21
22 namespace filesystem {
23
24 //! Implements a scanner that finds all filenames in the directory specified.
25
26 class directory : public virtual basis::root_object
27 {
28 public:
29   directory(const basis::astring &path, const char *pattern = "*");
30     //!< opens up the "path" specified and scans for files and subdirectories.
31     /*!< if the location was accessible, then the good() method returns true.
32     note that the "path" should just be a bare directory without any
33     wildcards attached.  the "pattern" can be specified if you wish to
34     strain out just a subset of the files in the directory.  it must meet
35     the same requirements that the operating system places on wildcard
36     patterns. */
37
38   directory(const directory &to_copy);
39
40   virtual ~directory();
41
42   directory &operator =(const directory &to_copy);
43
44   DEFINE_CLASS_NAME("directory");
45
46   bool good() const { return _scanned_okay; }
47     //!< true if the directory existed and its contents were readable.
48
49   const basis::astring &path() const;
50     //!< returns the directory that we manage.
51
52   const basis::astring &pattern() const;
53     //!< returns the pattern that the directory class scans for.
54
55   static basis::astring absolute_path(const basis::astring &relative_path);
56     //!< returns the absolute path to a file with "relative_path".
57     /*!< an empty string is returned on failure. */
58
59   bool reset(const basis::astring &path, const char *pattern = "*");
60     //!< gets rid of any current files and rescans the directory at "path".
61     /*!< a new "pattern" can be specified at this time also. */
62
63   bool move_up(const char *pattern = "*");
64     //!< resets the directory to be its own parent.
65
66   bool move_down(const basis::astring &subdir, const char *pattern = "*");
67     //!< changes down into a "subdir" of this directory.
68     /*!< the "subdir" should be just the file name component to change into.
69     absolute paths will not work.  for example, if a directory "/l/jed" has
70     a subdirectory named "clampett", then use: @code
71       my_dir->move_down("clampett") @endcode
72     */
73
74   bool rescan();
75     //!< reads our current directory's contents over again.
76
77   const structures::string_array &files() const;
78     //!< returns the list of files that we found in this directory.
79     /*!< these are all assumed to be located in our given path.  to find out
80     more information about the files themselves, construct a filename object
81     with the path() and the file of interest. */
82     
83   const structures::string_array &directories() const;
84     //!< these are the directory names from the folder.
85     /*!< they can also be examined using the filename object.  note that
86     this does not include the entry for the current directory (.) or the
87     parent (..). */
88
89   // static methods of general directory-related interest.
90
91   static basis::astring current();
92     //!< returns the current directory, as reported by the operating system.
93
94   static bool make_directory(const basis::astring &path);
95     //!< returns true if the directory "path" could be created.
96
97   static bool remove_directory(const basis::astring &path);
98     //!< returns true if the directory "path" could be removed.
99
100   static bool recursive_create(const basis::astring &directory_name);
101     //!< returns true if the "directory_name" can be created or already exists.
102     /*!< false returns indicate that the operating system wouldn't let us
103     make the directory, or that we didn't have sufficient permissions to
104     access an existing directory to view it or move into it. */
105
106 private:
107   bool _scanned_okay;  //!< did this directory work out?
108   basis::astring *_path;  //!< the directory we're looking at.
109   structures::string_array *_files;  //!< the list of files.
110   structures::string_array *_folders;  //!< the list of directories.
111   basis::astring *_pattern;  //!< the pattern used to find the files.
112 };
113
114 } //namespace.
115
116 #endif
117