File: fs.h

package info (click to toggle)
libwibble 0.1.9
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 500 kB
  • ctags: 1,183
  • sloc: cpp: 5,760; sh: 113; makefile: 71
file content (120 lines) | stat: -rw-r--r-- 2,620 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#ifndef WIBBLE_SYS_DIRECTORY_H
#define WIBBLE_SYS_DIRECTORY_H

#include <string>
#include <dirent.h>		// opendir, closedir
#include <memory>		// auto_ptr

struct stat;

namespace wibble {
namespace sys {
namespace fs {

/**
 * stat() the given file and return the struct stat with the results.
 * If the file does not exist, return NULL.
 * Raises exceptions in case of errors.
 */
std::auto_ptr<struct stat> stat(const std::string& pathname);

/// access() a filename
bool access(const std::string &s, int m);

/// Create the given directory, if it does not already exists.
/// It will complain if the given pathname already exists but is not a
/// directory.
void mkdirIfMissing(const std::string& dir, mode_t mode);

/// Create all the component of the given directory, including the directory
/// itself.
void mkpath(const std::string& dir);

/// Ensure that the path to the given file exists, creating it if it does not.
/// The file itself will not get created.
void mkFilePath(const std::string& file);

/// Nicely wrap access to directories
class Directory
{
	std::string m_path;

public:
	class const_iterator
	{
		DIR* dir;
		struct dirent* d;

	public:
		// Create an end iterator
		const_iterator() : dir(0), d(0) {}
		// Create a begin iterator
		const_iterator(DIR* dir) : dir(dir), d(0) { ++(*this); }
		// Cleanup properly
		~const_iterator() { if (dir) closedir(dir); }

		// auto_ptr style copy semantics
		const_iterator(const const_iterator& i)
		{
			dir = i.dir;
			d = i.d;
			const_iterator* wi = const_cast<const_iterator*>(&i);
			wi->dir = 0;
			wi->d = 0;
		}
		const_iterator& operator=(const const_iterator& i)
		{
			// Catch a = a
			if (&i == this) return *this;
			if (dir) closedir(dir);
			dir = i.dir;
			d = i.d;
			const_iterator* wi = const_cast<const_iterator*>(&i);
			wi->dir = 0;
			wi->d = 0;
		}

		const_iterator& operator++()
		{
			if ((d = readdir(dir)) == 0)
			{
				closedir(dir);
				dir = 0;
			}
			return *this;
		}

		std::string operator*() { return d->d_name; }
		struct dirent* operator->() { return d; }

		bool operator==(const const_iterator& iter) const
		{
			return dir == iter.dir && d == iter.d;
		}
		bool operator!=(const const_iterator& iter) const
		{
			return dir != iter.dir || d != iter.d;
		}
	};

	Directory(const std::string& path) : m_path(path) {}

	/// Pathname of the directory
	const std::string& path() const { return m_path; }

	/// Check that the directory exists and is a directory
	bool valid();

	/// Begin iterator
	const_iterator begin();

	/// End iterator
	const_iterator end() const;
};

}
}
}

// vim:set ts=4 sw=4:
#endif