Subversion Repositories spk

Rev

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