Subversion Repositories spk

Rev

Rev 121 | Rev 125 | 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;
124 cycrow 356
	dirList(files, dir, filePattern);
357
	return files;
358
}
359
bool CDirIO::dirList(Utils::CStringList &files, Utils::String dir, Utils::String filePattern) const
360
{
119 cycrow 361
	dir = parseDir(dir);
362
	if ( dir.empty() )
124 cycrow 363
		return false;
119 cycrow 364
 
121 cycrow 365
	dir = dir.findReplace("\\", "/");
366
	if (filePattern.empty())
367
		dir += "/*";
119 cycrow 368
	else
369
	{
121 cycrow 370
		dir += "/";
119 cycrow 371
		dir += filePattern;
372
	}
121 cycrow 373
	dir = dir.findReplace("//", "/");
119 cycrow 374
 
121 cycrow 375
#ifdef _WIN32
376
	dir = dir.findReplace("/", "\\");
377
 
119 cycrow 378
	WIN32_FIND_DATA data;
379
	TCHAR buf[5000];
380
	wsprintf(buf, L"%hs", dir.c_str());
381
 
382
	HANDLE h = FindFirstFile(buf, &data);
383
	if ( h != INVALID_HANDLE_VALUE)
384
	{
385
		std::wstring ws(data.cFileName);
386
		std::string s(ws.begin(), ws.end());
387
 
388
		Utils::String checkFile(s);
389
		if ( !checkFile.Compare(".") && !checkFile.Compare("..") )
121 cycrow 390
			files.pushBack(checkFile);
119 cycrow 391
 
392
		while ( FindNextFile(h, &data) )
393
		{
394
			std::wstring ws(data.cFileName);
395
			std::string s(ws.begin(), ws.end());
396
 
397
			Utils::String checkFile(s);
398
			if ( checkFile != "." && checkFile != ".." )
121 cycrow 399
				files.pushBack(checkFile);
119 cycrow 400
		}
401
 
402
		FindClose(h);
124 cycrow 403
		return true;
119 cycrow 404
	}
124 cycrow 405
	return false;
119 cycrow 406
#else
121 cycrow 407
	DIR *dir;
408
	struct dirent *ent;
409
	if ((dir = opendir(dir.c_str())) != NULL) {
410
		while ((ent = readdir(dir)) != NULL) {
411
			Utils::String checkFile(ent->d_name);
412
			if (checkFile != "." && checkFile != "..")
413
				files.pushBack(checkFile);
414
		}
415
		closedir(dir);
416
	}
124 cycrow 417
	return true;
119 cycrow 418
#endif//_WIN32
419
 
420
}
421
 
1 cycrow 422
CyStringList *CDirIO::DirList(CyString dir, CyString filepattern)
423
{
424
	dir = ParseDir(dir);
425
	if ( dir.Empty() )
426
		return 0;
427
 
428
	CyStringList *files = new CyStringList;
429
 
430
#ifdef _WIN32
431
	dir = dir.FindReplace("/", "\\");
432
	if ( filepattern.Empty() )
433
		dir += "\\*";
434
	else
435
	{
436
		dir += "\\";
437
		dir += filepattern;
438
	}
439
	dir = dir.FindReplace("\\\\", "\\");
440
 
441
	WIN32_FIND_DATA data;
442
	TCHAR buf[5000];
443
	wsprintf(buf, L"%hs", dir.c_str());
444
 
445
	HANDLE h = FindFirstFile(buf, &data);
446
	if ( h != INVALID_HANDLE_VALUE)
447
	{
448
		CyString checkFile(data.cFileName);
449
		if ( !checkFile.Compare(".") && !checkFile.Compare("..") )
450
			files->PushBack(checkFile);
451
		while ( FindNextFile(h, &data) )
452
		{
453
			CyString checkFile(data.cFileName);
454
			if ( checkFile != "." && checkFile != ".." )
455
				files->PushBack(checkFile);
456
		}
457
 
458
		FindClose(h);
459
	}
460
#else
461
 
462
#endif//_WIN32
463
 
464
	return files;
465
}
466
 
467
CyString CDirIO::File(CyString filename)
468
{
121 cycrow 469
	if (m_sCurrentDir.empty())
1 cycrow 470
		return filename;
471
 
85 cycrow 472
	return CyString(m_sCurrentDir) + "/" + filename;
1 cycrow 473
}
474
 
121 cycrow 475
Utils::String CDirIO::file(const Utils::String &filename) const
476
{
477
	if (m_sCurrentDir.empty())
478
		return filename;
479
 
480
	return m_sCurrentDir + "/" + filename;
481
}
482
 
85 cycrow 483
Utils::String CDirIO::dir(const Utils::String &sDir) const
484
{
485
	return parseDir(sDir);
486
}
487
 
488
const Utils::String &CDirIO::dir() const
489
{
490
	return m_sCurrentDir;
491
}
492
 
1 cycrow 493
CyString CDirIO::Dir(CyString dir)
494
{
85 cycrow 495
	return parseDir(dir.ToString());
1 cycrow 496
}
497
 
498
bool CDirIO::cd(CyString dir)
499
{
85 cycrow 500
	Utils::String sDir = dir.ToString();
501
 
502
	if ( m_sCurrentDir.empty() )
503
		m_sCurrentDir = sDir;
1 cycrow 504
	else
85 cycrow 505
		m_sCurrentDir = m_sCurrentDir + "/" + sDir;
506
	m_sCurrentDir = m_sCurrentDir.asFilename();
1 cycrow 507
 
121 cycrow 508
	return exists();
1 cycrow 509
}
510
 
511
bool CDirIO::CreateAndChange(CyString dir)
512
{
513
	if ( Create(dir) )
514
		return cd(dir);
515
	return false;
516
}
517
 
518
 
121 cycrow 519
Utils::String CDirIO::topDir() const
1 cycrow 520
{
85 cycrow 521
	if ( m_sCurrentDir.empty() )
121 cycrow 522
		return Utils::String("");
1 cycrow 523
 
85 cycrow 524
	return m_sCurrentDir.token("/", -1);
1 cycrow 525
}
526
 
527
CyString CDirIO::Back()
528
{
85 cycrow 529
	m_sCurrentDir = m_sCurrentDir.tokens("/", 1, -2);
530
 
1 cycrow 531
	return m_sCurrentDir;
532
}