Subversion Repositories spk

Rev

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