Subversion Repositories spk

Rev

Rev 197 | Rev 227 | 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
 
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
 
196 cycrow 88
	if (ACCESS(TOSTRING(dir).c_str(), 0) == 0)
121 cycrow 89
		return true;
90
 
91
	return false;
92
}
93
 
196 cycrow 94
bool CDirIO::exists(const Utils::WString &dir) const
121 cycrow 95
{
196 cycrow 96
	Utils::WString d = _parseDir(dir);
121 cycrow 97
 
98
	if (d.empty())
99
		return false;
100
 
196 cycrow 101
	if (ACCESS(TOSTRING(d).c_str(), 0) == 0)
121 cycrow 102
		return true;
103
 
104
	return false;
105
}
106
 
196 cycrow 107
Utils::WString CDirIO::_parseDir(const Utils::WString &dir) const
1 cycrow 108
{
196 cycrow 109
	Utils::WString sDir = dir.asFilename();
110
	if ( !m_sCurrentDir.empty() && !sDir.contains(L":") )
85 cycrow 111
	{
112
		if ( sDir.empty() )
113
			sDir = m_sCurrentDir;
114
		else
196 cycrow 115
			sDir = m_sCurrentDir + L"/" + sDir;
85 cycrow 116
	}
117
 
118
	return sDir.asFilename();
119
}
120
 
196 cycrow 121
bool CDirIO::isDir(const Utils::WString &sDir) const
121 cycrow 122
{
196 cycrow 123
	Utils::WString dir = _parseDir(sDir);
124
	if (ACCESS(TOSTRING(dir).c_str(), 0) != -1)
121 cycrow 125
	{
126
		struct stat status;
196 cycrow 127
		stat(TOSTRING(dir).c_str(), &status);
121 cycrow 128
 
129
		if (status.st_mode & S_IFDIR)
130
			return true;
131
	}
132
	else {
196 cycrow 133
		return !dir.token(L"/", -1).contains(L".");
121 cycrow 134
	}
135
 
136
	return false;
137
}
138
 
139
bool CDirIO::isDir() const
140
{
141
	return isDir(m_sCurrentDir);
142
}
143
 
144
bool CDirIO::isFile() const
145
{
146
	return isFile(m_sCurrentDir);
147
}
196 cycrow 148
bool CDirIO::isFile(const Utils::WString &sDir) const
121 cycrow 149
{
196 cycrow 150
	Utils::WString dir = _parseDir(sDir);
151
	if (ACCESS(TOSTRING(dir).c_str(), 0) != -1)
121 cycrow 152
	{
153
		struct stat status;
196 cycrow 154
		stat(TOSTRING(dir).c_str(), &status);
121 cycrow 155
 
156
		if (status.st_mode & S_IFDIR)
157
			return false;
158
		else
159
			return true;
160
	}
161
	else {
196 cycrow 162
		return dir.token(L"/", -1).contains(L".");
121 cycrow 163
	}
164
 
165
	return false;
166
}
1 cycrow 167
 
160 cycrow 168
 
129 cycrow 169
bool CDirIO::create() const
170
{
197 cycrow 171
	return create(Utils::WString::Null());
129 cycrow 172
}
196 cycrow 173
bool CDirIO::create(const Utils::WString &sDir) const
129 cycrow 174
{
196 cycrow 175
	Utils::WString dir = sDir;
121 cycrow 176
	if ( dir.empty() )
1 cycrow 177
		dir = m_sCurrentDir;
125 cycrow 178
	dir = _parseDir(dir);
1 cycrow 179
 
180
	// split up directorys
197 cycrow 181
	std::vector<Utils::WString> dirs;
196 cycrow 182
	if(dir.findReplace(L"/", L"\\").findReplace(L"\\\\", L"\\").tokenise(L"\\", dirs))
1 cycrow 183
	{
196 cycrow 184
		// check if full dir, or relative
185
		size_t start = 1;
186
		Utils::WString curDir = dirs.front();
1 cycrow 187
 
196 cycrow 188
		if (!curDir.contains(L":"))
189
		{
190
			curDir = m_sCurrentDir;
191
			start = 0;
192
		}
1 cycrow 193
 
196 cycrow 194
		// process each dir
195
		for (size_t i = start; i < dirs.size(); i++)
1 cycrow 196
		{
196 cycrow 197
			if (!curDir.empty())
198
				curDir += L"/";
199
			curDir += dirs.at(i);
200
 
201
			// check if the directory exists
202
			if (!exists(curDir))
203
			{
1 cycrow 204
#ifdef _WIN32
196 cycrow 205
				if (_mkdir(TOSTRING(curDir).c_str()))
1 cycrow 206
#else
196 cycrow 207
				if (mkdir(TOSTRING(curDir).c_str(), 0755))
1 cycrow 208
#endif
196 cycrow 209
					return false;
1 cycrow 210
			}
211
		}
212
	}
213
 
214
	return true;
215
}
216
 
196 cycrow 217
bool CDirIO::move(const Utils::WString &sTo)
1 cycrow 218
{
196 cycrow 219
	Utils::WString to = _parseDir(sTo);
1 cycrow 220
 
125 cycrow 221
	if (exists(to))
222
		return false;
223
 
197 cycrow 224
	if (!CFileIO::Rename(m_sCurrentDir, to))
1 cycrow 225
	{
125 cycrow 226
		m_sCurrentDir = to;
227
		return true;
228
	}
229
 
230
	return false;
231
}
232
 
233
 
196 cycrow 234
bool CDirIO::move(const Utils::WString &sFrom, const Utils::WString &sTo)
125 cycrow 235
{
196 cycrow 236
	Utils::WString from = _parseDir(sFrom);
237
	Utils::WString to = _parseDir(sTo);
125 cycrow 238
 
239
	if ( !exists(to) )
240
	{
160 cycrow 241
		if ( !create(to) )
1 cycrow 242
			return false;
243
	}
244
 
196 cycrow 245
	if ( !rename(TOSTRING(from).c_str(), TOSTRING(to).c_str()) )
1 cycrow 246
		return true;
247
 
248
	return false;
249
}
250
 
197 cycrow 251
bool CDirIO::checkEmptyDir(const Utils::WStringList &dirList) const
1 cycrow 252
{
253
	// not found any files, most likly empty
160 cycrow 254
	if (dirList.empty())
1 cycrow 255
		return true;
256
	// check for any valid files
257
 
160 cycrow 258
	for(auto itr = dirList.begin(); itr != dirList.end(); itr++)
1 cycrow 259
	{
197 cycrow 260
		Utils::WString d = (*itr)->str;
261
		if (d == L"." || d == L"..")
1 cycrow 262
			continue;
263
 
264
		// found something
265
		return false;
266
	}
267
 
268
	return true;
269
}
270
 
197 cycrow 271
bool CDirIO::removeDir(const Utils::WString& dir, bool doFiles, bool recursive, Utils::WStringList* errors)
1 cycrow 272
{
273
	// check if the dir is empty
196 cycrow 274
	Utils::WStringList list;
160 cycrow 275
	if (dirList(list, dir))
1 cycrow 276
	{
196 cycrow 277
		if (CDirIO::IsEmptyDir(list))
1 cycrow 278
		{
196 cycrow 279
			Utils::WString remDir = _parseDir(dir);
160 cycrow 280
#ifdef _WIN32
196 cycrow 281
			if (_rmdir(TOSTRING(remDir).c_str()) == 0)
160 cycrow 282
#else
196 cycrow 283
			if (rmdir(TOSTRING(remDir).c_str()) == 0)
160 cycrow 284
#endif
285
			{
286
				if (errors)
197 cycrow 287
					errors->pushBack(remDir);
160 cycrow 288
			}
289
			return true;
1 cycrow 290
		}
160 cycrow 291
 
292
		// not empty
293
		if (doFiles || recursive)
294
		{
295
			for (auto itr = list.begin(); itr != list.end(); itr++)
296
			{
196 cycrow 297
				Utils::WString d = (*itr)->str;
298
				if (d == L"." || d == L"..")
160 cycrow 299
					continue;
300
 
301
				// if its a file
196 cycrow 302
				Utils::WString fullFile = dir + "\\" + d;
160 cycrow 303
				if (doFiles && isFile(fullFile))
304
				{
196 cycrow 305
					Utils::WString remFile = _parseDir(fullFile);
197 cycrow 306
					if (!CFileIO::Remove(remFile))
160 cycrow 307
					{
308
						if (errors)
197 cycrow 309
							errors->pushBack(remFile);
160 cycrow 310
					}
311
				}
312
				else if (recursive && isDir(fullFile))
313
					removeDir(fullFile, doFiles, recursive, errors);
314
			}
315
		}
1 cycrow 316
	}
160 cycrow 317
	list.clear();
318
	// now check if its empty
319
	if(dirList(list, dir))
320
	{
196 cycrow 321
		if (CDirIO::IsEmptyDir(list))
160 cycrow 322
		{
196 cycrow 323
			Utils::WString remDir = _parseDir(dir);
160 cycrow 324
#ifdef _WIN32
196 cycrow 325
			if (_rmdir(TOSTRING(remDir).c_str()) == 0)
160 cycrow 326
#else
196 cycrow 327
			if (rmdir(TOSTRING(remDir).c_str()) == 0)
160 cycrow 328
#endif
329
			{
330
				if (errors)
197 cycrow 331
					errors->pushBack(remDir);
160 cycrow 332
			}
333
			return true;
334
		}
335
	}
336
	return false;
337
}
1 cycrow 338
 
196 cycrow 339
bool CDirIO::dirList(Utils::WStringList& files, const Utils::WString &sDir, const Utils::WString &filePattern) const
121 cycrow 340
{
196 cycrow 341
	Utils::WString dir = _parseDir(sDir);
342
	if (dir.empty())
343
		return false;
344
 
345
	dir = dir.findReplace(L"\\", L"/");
346
	if (filePattern.empty())
347
		dir += L"/*";
348
	else
349
	{
350
		dir += L"/";
351
		dir += filePattern;
352
	}
353
	dir = dir.findReplace(L"//", L"/");
354
 
355
#ifdef _WIN32
356
	dir = dir.findReplace(L"/", L"\\");
357
 
358
	WIN32_FIND_DATA data;
359
	HANDLE h = FindFirstFile(dir.c_str(), &data);
360
	if (h != INVALID_HANDLE_VALUE)
361
	{
362
		Utils::WString checkFile(data.cFileName);
363
		if (!checkFile.Compare(L".") && !checkFile.Compare(L".."))
364
			files.pushBack(checkFile);
365
 
366
		while (FindNextFile(h, &data))
367
		{
197 cycrow 368
			Utils::WString checkFile(data.cFileName);
196 cycrow 369
			if (checkFile != L"." && checkFile != L"..")
370
				files.pushBack(checkFile);
371
		}
372
 
373
		FindClose(h);
374
		return true;
375
	}
376
	return false;
377
#else
378
	DIR* dir;
379
	struct dirent* ent;
380
	if ((dir = opendir(dir.c_str())) != NULL) {
381
		while ((ent = readdir(dir)) != NULL) {
197 cycrow 382
			Utils::WString checkFile(ent->d_name);
383
			if (checkFile != L"." && checkFile != L"..")
196 cycrow 384
				files.pushBack(checkFile);
385
		}
386
		closedir(dir);
387
	}
388
	return true;
389
#endif//_WIN32
390
 
391
}
392
 
393
Utils::WString CDirIO::file(const Utils::WString &filename) const
394
{
121 cycrow 395
	if (m_sCurrentDir.empty())
396
		return filename;
397
 
196 cycrow 398
	return m_sCurrentDir + L"/" + filename;
121 cycrow 399
}
400
 
196 cycrow 401
Utils::WString CDirIO::dir(const Utils::WString &sDir) const
85 cycrow 402
{
125 cycrow 403
	return _parseDir(sDir);
85 cycrow 404
}
405
 
196 cycrow 406
const Utils::WString &CDirIO::dir() const
85 cycrow 407
{
408
	return m_sCurrentDir;
409
}
410
 
196 cycrow 411
bool CDirIO::cd(const Utils::WString &sDir)
1 cycrow 412
{
85 cycrow 413
	if ( m_sCurrentDir.empty() )
414
		m_sCurrentDir = sDir;
1 cycrow 415
	else
196 cycrow 416
		m_sCurrentDir = m_sCurrentDir + L"/" + sDir;
85 cycrow 417
	m_sCurrentDir = m_sCurrentDir.asFilename();
1 cycrow 418
 
121 cycrow 419
	return exists();
1 cycrow 420
}
421
 
196 cycrow 422
bool CDirIO::createAndChange(const Utils::WString &dir)
1 cycrow 423
{
160 cycrow 424
	if ( create(dir) )
425
		return cd(dir);
1 cycrow 426
	return false;
427
}
428
 
429
 
196 cycrow 430
Utils::WString CDirIO::topDir() const
1 cycrow 431
{
85 cycrow 432
	if ( m_sCurrentDir.empty() )
196 cycrow 433
		return Utils::WString(L"");
1 cycrow 434
 
196 cycrow 435
	return m_sCurrentDir.token(L"/", -1);
1 cycrow 436
}
437
 
196 cycrow 438
const Utils::WString &CDirIO::moveBack()
1 cycrow 439
{
196 cycrow 440
	m_sCurrentDir = m_sCurrentDir.tokens(L"/", 1, -2);
1 cycrow 441
	return m_sCurrentDir;
125 cycrow 442
}
196 cycrow 443
Utils::WString CDirIO::back() const
125 cycrow 444
{
196 cycrow 445
	return m_sCurrentDir.tokens(L"/", 1, -2);
125 cycrow 446
}