Subversion Repositories spk

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
148 cycrow 1
#include "pch.h"
2
#include "DirIO.h"
3
 
4
#include <sys/types.h>  // For stat().
5
#include <sys/stat.h>   // For stat().
6
#include <fcntl.h>
7
#include "File_IO.h"
8
 
9
#ifdef _WIN32
10
#include <windows.h>
11
#include <io.h>
12
#include <direct.h>
13
#define ACCESS _access
14
#else
15
#include <dirent.h>
16
#define ACCESS access
17
#endif
18
 
19
using namespace XLib;
20
 
21
/////////////////////////////////////////
22
// STATIC FUNCTIONS
23
bool DirIO::Exists(const XLib::String &dir)
24
{
25
	return DirIO(dir).exists();
26
}
27
 
28
 
29
////////////////////////////////////////
30
// Ctor/Dtor
31
 
32
DirIO::DirIO()
33
{
34
}
35
 
36
DirIO::~DirIO()
37
{
38
}
39
 
40
DirIO::DirIO(const XLib::String &dir)
41
{
42
	setDir(dir);
43
}
44
 
45
DirIO::DirIO(const FileIO &file)
46
{
47
	setDir(file.dir());
48
}
49
 
50
/////////////////////////////////////////////////////////
51
//
52
 
53
void DirIO::setDir(const XLib::String &dir)
54
{
55
	m_sCurrentDir = dir;
56
	m_sCurrentDir.toFilename();
57
}
58
 
59
 
60
bool DirIO::exists() const
61
{
62
	XLib::String dir = m_sCurrentDir;
63
 
64
	if (dir.empty())
65
		return false;
66
 
67
	if (ACCESS((const char *)dir, 0) == 0)
68
		return true;
69
 
70
	return false;
71
}
72
 
73
bool DirIO::exists(const XLib::String &dir) const
74
{
75
	XLib::String d = _parseDir(dir);
76
 
77
	if (d.empty())
78
		return false;
79
 
80
	if (ACCESS((const char *)d, 0) == 0)
81
		return true;
82
 
83
	return false;
84
}
85
 
86
XLib::String DirIO::_parseDir(const XLib::String &dir) const
87
{
88
	XLib::String sDir = dir.asFilename();
89
	if ( !m_sCurrentDir.empty() && !sDir.isin(":") )
90
	{
91
		if ( sDir.empty() )
92
			sDir = m_sCurrentDir;
93
		else
94
			sDir = m_sCurrentDir + "/" + sDir;
95
	}
96
 
97
	return sDir.asFilename();
98
}
99
 
100
bool DirIO::isDir(const XLib::String &sDir) const
101
{
102
	XLib::String dir = _parseDir(sDir);
103
	if (ACCESS(dir.c_str(), 0) != -1)
104
	{
105
		struct stat status;
106
		stat(dir.c_str(), &status);
107
 
108
		if (status.st_mode & S_IFDIR)
109
			return true;
110
	}
111
	else {
112
		return !dir.token("/", -1).isin(".");
113
	}
114
 
115
	return false;
116
}
117
 
118
bool DirIO::isDir() const
119
{
120
	return isDir(m_sCurrentDir);
121
}
122
 
123
bool DirIO::isFile() const
124
{
125
	return isFile(m_sCurrentDir);
126
}
127
bool DirIO::isFile(const XLib::String &sDir) const
128
{
129
	XLib::String dir = _parseDir(sDir);
130
	if (ACCESS(dir.c_str(), 0) != -1)
131
	{
132
		struct stat status;
133
		stat(dir.c_str(), &status);
134
 
135
		if (status.st_mode & S_IFDIR)
136
			return false;
137
		else
138
			return true;
139
	}
140
	else {
141
		return dir.token("/", -1).isin(".");
142
	}
143
 
144
	return false;
145
}
146
 
147
bool DirIO::create() const
148
{
149
	return create(XLib::String::Null());
150
}
151
bool DirIO::create(const XLib::String &sDir) const
152
{
153
	XLib::String dir = sDir;
154
	if ( dir.empty() )
155
		dir = m_sCurrentDir;
156
	dir = _parseDir(dir);
157
 
158
	// split up directorys
159
	StringList dirs = dir.findReplace( "/", "\\" ).findReplace( "\\\\", "\\" ).tokenise("\\");
160
 
161
	// check if full dir, or relative
162
	int start = 1;
163
	XLib::String curDir;
164
 
165
	if (!dirs.empty())
166
		curDir = dirs.front();
167
 
168
	if ( !curDir.isin(":") )
169
	{
170
		curDir = m_sCurrentDir;
171
		start = 0;
172
	}
173
 
174
	// process each dir
175
	for(auto itr = dirs.begin(); itr != dirs.end(); itr++)
176
	{
177
		if ( !curDir.empty() )
178
			curDir += "/";
179
		curDir += *itr;
180
 
181
		// check if the directory exists
182
		if ( !exists(curDir) )
183
		{
184
#ifdef _WIN32
185
			if ( _mkdir(curDir.c_str()) )
186
#else
187
			if ( mkdir(curDir.c_str(), 0755) )
188
#endif
189
			{
190
				return false;
191
			}
192
		}
193
	}
194
 
195
	return true;
196
}
197
 
198
bool DirIO::move(const XLib::String &sTo)
199
{
200
	XLib::String to = _parseDir(sTo);
201
 
202
	if (exists(to))
203
		return false;
204
 
205
	if (!rename(m_sCurrentDir.c_str(), to.c_str()))
206
	{
207
		m_sCurrentDir = to;
208
		return true;
209
	}
210
 
211
	return false;
212
}
213
 
214
 
215
bool DirIO::move(const XLib::String &sFrom, const XLib::String &sTo)
216
{
217
	if ( !exists(sTo) )
218
	{
219
		if ( !create(sTo) )
220
			return false;
221
	}
222
 
223
	if ( !rename(sFrom.c_str(), sTo.c_str()) )
224
		return true;
225
 
226
	return false;
227
}
228
 
229
bool DirIO::isEmptyDir(const StringList &dirList) const
230
{
231
	// not found any files, most likly empty
232
	if ( !dirList.size() )
233
		return true;
234
 
235
	// check for any valid files
236
	for (auto itr = dirList.begin(); itr != dirList.end(); itr++)
237
	{
238
		if (*itr == "." || *itr == "..")
239
			continue;
240
		return false;
241
	}
242
 
243
	return true;
244
}
245
 
246
bool DirIO::removeDir(const XLib::String &dir, bool doFiles, bool recursive, StringList *errors)
247
{
248
	StringList files;
249
	dirList(files, dir);
250
	if (isEmptyDir(files))
251
	{
252
		XLib::String remDir = _parseDir(dir);
253
#ifdef _WIN32
254
		if (_rmdir(remDir.c_str()) == 0)
255
#else
256
		if (rmdir(remDir.c_str()) == 0)
257
#endif
258
		{
259
			if (errors)
260
				errors->push_back(remDir);
261
		}
262
		return true;
263
	}
264
 
265
	// not empty
266
	if ( doFiles || recursive )
267
	{
268
		for (auto itr = files.begin(); itr != files.end(); itr++)
269
		{
270
			if (*itr == "." || *itr == "..")
271
				continue;
272
 
273
			XLib::String fullFile = (dir + "\\" + *itr);
274
			if (doFiles && isFile(fullFile))
275
			{
276
				XLib::String remFile = _parseDir(fullFile);
277
				if (remove(remFile.c_str()) == 0)
278
				{
279
					if (errors)
280
						errors->push_back(remFile);
281
				}
282
			}
283
			else if (recursive && isDir(fullFile))
284
				removeDir(fullFile, doFiles, recursive, errors);
285
		}
286
	}
287
 
288
	// now check if its empty
289
	files.clear();
290
	dirList(files, dir);
291
	if (isEmptyDir(files))
292
	{
293
		XLib::String remDir = _parseDir(dir);
294
		#ifdef _WIN32
295
		if ( _rmdir(remDir.c_str()) == 0 )
296
		#else
297
		if ( rmdir(remDir.c_str()) == 0 )
298
		#endif
299
		{
300
			if ( errors )
301
				errors->push_back(remDir);
302
		}
303
		return true;
304
	}
305
 
306
	return false;
307
}
308
 
309
StringList DirIO::dirList(XLib::String dir, XLib::String filePattern) const
310
{
311
	StringList files;
312
	dirList(files, dir, filePattern);
313
	return files;
314
}
315
bool DirIO::dirList(StringList &files, XLib::String dir, XLib::String filePattern) const
316
{
317
	dir = _parseDir(dir);
318
	if ( dir.empty() )
319
		return false;
320
 
321
	dir = dir.findReplace("\\", "/");
322
	if (filePattern.empty())
323
		dir += "/*";
324
	else
325
	{
326
		dir += "/";
327
		dir += filePattern;
328
	}
329
	dir = dir.findReplace("//", "/");
330
 
331
#ifdef _WIN32
332
	dir = dir.findReplace("/", "\\");
333
 
334
	WIN32_FIND_DATA data;
335
	TCHAR buf[5000];
336
	wsprintf(buf, L"%hs", dir.c_str());
337
 
338
	HANDLE h = FindFirstFile(buf, &data);
339
	if ( h != INVALID_HANDLE_VALUE)
340
	{
341
		std::wstring ws(data.cFileName);
342
		std::string s(ws.begin(), ws.end());
343
 
344
		XLib::String checkFile(s);
345
		if ( !checkFile.Compare(".") && !checkFile.Compare("..") )
346
			files.push_back(checkFile);
347
 
348
		while ( FindNextFile(h, &data) )
349
		{
350
			std::wstring ws(data.cFileName);
351
			std::string s(ws.begin(), ws.end());
352
 
353
			XLib::String checkFile(s);
354
			if ( checkFile != "." && checkFile != ".." )
355
				files.push_back(checkFile);
356
		}
357
 
358
		FindClose(h);
359
		return true;
360
	}
361
	return false;
362
#else
363
	DIR *dir;
364
	struct dirent *ent;
365
	if ((dir = opendir(dir.c_str())) != NULL) {
366
		while ((ent = readdir(dir)) != NULL) {
367
			XLib::String checkFile(ent->d_name);
368
			if (checkFile != "." && checkFile != "..")
369
				files.pushBack(checkFile);
370
		}
371
		closedir(dir);
372
	}
373
	return true;
374
#endif//_WIN32
375
 
376
}
377
 
378
XLib::String DirIO::file(const XLib::String &filename) const
379
{
380
	if (m_sCurrentDir.empty())
381
		return filename;
382
 
383
	return m_sCurrentDir + "/" + filename;
384
}
385
 
386
XLib::String DirIO::dir(const XLib::String &sDir) const
387
{
388
	return _parseDir(sDir);
389
}
390
 
391
const XLib::String &DirIO::dir() const
392
{
393
	return m_sCurrentDir;
394
}
395
 
396
bool DirIO::cd(const XLib::String &sDir)
397
{
398
	if ( m_sCurrentDir.empty() )
399
		m_sCurrentDir = sDir;
400
	else
401
		m_sCurrentDir = m_sCurrentDir + "/" + sDir;
402
	m_sCurrentDir = m_sCurrentDir.asFilename();
403
 
404
	return exists();
405
}
406
 
407
bool DirIO::createAndChange(const XLib::String &dir)
408
{
409
	if ( create(dir) )
410
		return cd(dir);
411
	return false;
412
}
413
 
414
 
415
XLib::String DirIO::topDir() const
416
{
417
	if ( m_sCurrentDir.empty() )
418
		return XLib::String("");
419
 
420
	return m_sCurrentDir.token("/", -1);
421
}
422
 
423
const XLib::String &DirIO::moveBack()
424
{
425
	m_sCurrentDir = m_sCurrentDir.tokens("/", 1, -2);
426
	return m_sCurrentDir;
427
}
428
XLib::String DirIO::back() const
429
{
430
	return m_sCurrentDir.tokens("/", 1, -2);
431
}