Subversion Repositories spk

Rev

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