Subversion Repositories spk

Rev

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