-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathfile_system.h
282 lines (223 loc) · 7.26 KB
/
file_system.h
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
/*
* Copyright (C) 2015, Simon Fuhrmann, Andre Schulz
* TU Darmstadt - Graphics, Capture and Massively Parallel Computing
* All rights reserved.
*
* This software may be modified and distributed under the terms
* of the BSD 3-Clause license. See the LICENSE.txt file for details.
*/
#ifndef UTIL_FS_HEADER
#define UTIL_FS_HEADER
#include <string>
#include <vector>
#include "util/defines.h"
UTIL_NAMESPACE_BEGIN
UTIL_FS_NAMESPACE_BEGIN
/*
* -------------------------- Path operations ------------------------
*/
/** Determines if the given path is a directory. */
bool exists (char const* pathname);
/** Determines if the given path is a directory. */
bool dir_exists (char const* pathname);
/** Determines if the given path is a file. */
bool file_exists (char const* pathname);
/** Determines the current user's path for application data. */
char const* get_app_data_dir (void);
/** Determines the home path for the current user. */
char const* get_home_dir (void);
/** Determines the current working directory of the process. */
char* get_cwd (char* buf, std::size_t size);
/**
* Changes the current working directory to 'pathname' and returns true
* on success. NOTE: An application should never change its working
* directory. Make sure this is really necessary.
*/
bool set_cwd (char const* pathname);
/*
* -------------------------- File operations ------------------------
*/
// TODO: define modes for mkdir() for all platforms?
/** Creates a new directory. */
bool mkdir (char const* pathname/*, mode_t mode*/);
/** Removes an empty directory */
bool rmdir (char const* pathname);
/** Unlinks (deletes) the given file. */
bool unlink (char const* pathname);
/** Renames the given file 'from' to new name 'to'. */
bool rename (char const* from, char const* to);
/** Copies a file from 'src' to 'dst', throws FileException on error. */
void copy_file (char const* src, char const* dst);
/*
* ----------------------------- File IO ----------------------------
*/
/** Reads the whole file into a string. Throws on error. */
void
read_file_to_string (std::string const& filename, std::string* data);
/** Writes the given data into a file. Throws on error. */
void
write_string_to_file (std::string const& data, std::string const& filename);
/** Writes the given data into a file. Throws on error. */
void
write_string_to_file (char const* data, std::size_t len,
std::string const& filename);
/*
* ------------------------- String processing -----------------------
*/
/** Determines the CWD and returns a convenient string. */
std::string get_cwd_string (void);
/** Returns the path of the binary currently executing. */
std::string get_binary_path (void);
/** Checks whether the given path is absolute. */
bool is_absolute (std::string const& path);
/** Canonicalize slashes in the given path. */
std::string sanitize_path (std::string const& path);
/**
* Concatenate and canonicalize two paths. The result is where you would
* end up after cd path1; cd path2.
*/
std::string join_path (std::string const& path1, std::string const& path2);
/** Returns the absolute representation of the given path. */
std::string abspath (std::string const& path);
/** Returns the directory name component of the given path. */
std::string dirname (std::string const& path);
/** Returns the file name component of the given path. */
std::string basename (std::string const& path);
/**
* Replaces extension of the given file with 'ext'. If the file name
* does not have an extension, the given extension is appended.
*/
std::string replace_extension (std::string const& fn, std::string const& ext);
/*
* ------------------------- File abstraction ------------------------
*/
struct File
{
std::string path;
std::string name;
bool is_dir;
File (void);
File (std::string const& path, std::string const& name, bool isdir = false);
std::string get_absolute_name (void) const;
bool operator< (File const& rhs) const;
};
/*
* ------------------------- Directory reading -----------------------
*/
/** Directory abstraction to scan directory contents. */
class Directory : public std::vector<File>
{
public:
Directory (void);
Directory (std::string const& path);
void scan (std::string const& path);
};
/*
* --------------------- File locking mechanism ----------------------
*/
/**
* A simple file-based file lock implementation.
* A file NAME.lock is created when a lock is acquired, and
* the file is removed when the lock is released. If the lock
* already exist, 'acquire' returns false. 'acquire_retry' retries for
* a few seconds and finally gives up returning false. Note that the ".lock"
* suffix is automatically used and must not be part of the given filenames.
*/
class FileLock
{
public:
enum Status
{
/** The lock has been created successfully. */
LOCK_CREATED,
/** The lock has NOT been created because a lock already exists. */
LOCK_EXISTS,
/** The lock has NOT been created because an existing lock persisted. */
LOCK_PERSISTENT,
/** The lock has NOT been created because of file system issues. */
LOCK_CREATE_ERROR
};
public:
FileLock (void);
/**
* Acquires a lock for the given filename. If the lock already exists,
* the operation is re-attempted using default values. If the lock
* cannot be created an exception is thrown.
*/
FileLock (std::string const& filename);
/** Removes the lock if it exists. */
~FileLock (void);
/**
* Tries to acquire a lock for the given filename and returns a status.
*/
Status acquire (std::string const& filename);
/**
* Tries to acquire a lock for the given filename.
* If a lock exists, the operation is re-attempted 'retry' times
* with 'sleep' milli seconds delay between the attempts.
*/
Status acquire_retry (std::string const& filename,
int retries = 50, int sleep = 100);
/**
* Returns true if a lock for the given filename exists.
*/
bool is_locked (std::string const& filename);
/**
* Waits until a lock for given filename is released. If filename is
* not locked, the method returns true immediately. If the lock is not
* released within the specified bounds, the method returns false.
*/
bool wait_lock (std::string const& filename,
int retries = 50, int sleep = 100);
/**
* Removes the lock if it exists.
* If removing the lock fails, the method returns false.
*/
bool release (void);
/**
* If locking failes, this returns the reason for failure.
*/
std::string const& get_reason (void) const;
private:
std::string lockfile;
std::string reason;
};
/*
* -------------------------- Implementation -------------------------
*/
inline
File::File (void)
: is_dir(false)
{
}
inline
File::File (std::string const& path, std::string const& name, bool isdir)
: path(path), name(name), is_dir(isdir)
{
}
inline
Directory::Directory (void)
{
}
inline
Directory::Directory (std::string const& path)
{
this->scan(path);
}
inline
FileLock::FileLock (void)
{
}
inline
FileLock::~FileLock (void)
{
this->release();
}
inline std::string const&
FileLock::get_reason (void) const
{
return this->reason;
}
UTIL_FS_NAMESPACE_END
UTIL_NAMESPACE_END
#endif /* UTIL_FS_HEADER */