Subversion Repositories spk

Rev

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