Subversion Repositories spk

Rev

Rev 183 | Rev 196 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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