Subversion Repositories spk

Rev

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