Subversion Repositories spk

Rev

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