Subversion Repositories spk

Rev

Rev 1 | Rev 95 | 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
{
33
	SetDir(file->GetDir());
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
 
86
bool CDirIO::IsDir(CyString dir)
87
{
88
	dir = ParseDir(dir);
89
	if ( ACCESS( dir.c_str(), 0 ) == 0 )
90
	{
91
		struct stat status;
92
		stat( dir.c_str(), &status );
93
 
94
		if ( status.st_mode & S_IFDIR )
95
			return true;
96
	}
97
 
98
	return false;
99
}
100
 
101
bool CDirIO::IsFile(CyString dir)
102
{
103
	dir = ParseDir(dir);
104
	if ( ACCESS( dir.c_str(), 0 ) == 0 )
105
	{
106
		struct stat status;
107
		stat( dir.c_str(), &status );
108
 
109
		if ( status.st_mode & S_IFDIR )
110
			return false;
111
		else
112
			return true;
113
	}
114
 
115
	return false;
116
}
117
 
118
bool CDirIO::Create(CyString dir)
119
{
120
	if ( dir.Empty() )
121
		dir = m_sCurrentDir;
122
	dir = ParseDir(dir);
123
 
124
	// split up directorys
125
	int max = 0;
126
	CyString *dirs = dir.FindReplace ( "/", "\\" ).FindReplace ( "\\\\", "\\" ).SplitToken ( '\\', &max );
127
 
128
	// check if full dir, or relative
129
	int start = 1;
130
	CyString curDir;
131
 
132
	if ( dirs && max )
133
		curDir = dirs[0];
134
 
135
	if ( !curDir.IsIn(":") )
136
	{
137
		curDir = m_sCurrentDir;
138
		start = 0;
139
	}
140
 
141
	// process each dir
142
	for ( int i = start; i < max; i++ )
143
	{
144
		if ( !curDir.Empty() )
145
			curDir += "/";
146
		curDir += dirs[i];
147
 
148
		// check if the directory exists
149
		if ( !Exists(curDir) )
150
		{
151
#ifdef _WIN32
152
			if ( _mkdir(curDir.c_str()) )
153
#else
154
			if ( mkdir(curDir.c_str(), 0755) )
155
#endif
156
			{
157
				CLEANSPLIT(dirs, max);
158
				return false;
159
			}
160
		}
161
	}
162
 
163
	CLEANSPLIT(dirs, max);
164
 
165
	return true;
166
}
167
 
168
bool CDirIO::Move(CyString from, CyString to)
169
{
170
	from = ParseDir(from);
171
	to = ParseDir(to);
172
 
173
	if ( !Exists(to) )
174
	{
175
		if ( !Create(to) )
176
			return false;
177
	}
178
 
179
	if ( !rename(from.c_str(), to.c_str()) )
180
		return true;
181
 
182
	return false;
183
}
184
 
185
bool CDirIO::CheckEmptyDir(CyStringList *dirList)
186
{
187
	// no pointer, most likly empty
188
	if ( !dirList )
189
		return true;
190
	// not found any files, most likly empty
191
	if ( !dirList->Count() )
192
		return true;
193
	// check for any valid files
194
 
195
	for ( SStringList *str = dirList->Head(); str; str = str->next )
196
	{
197
		CyString d = str->str;
198
		if ( d == "." || d == ".." )
199
			continue;
200
 
201
		// found something
202
		return false;
203
	}
204
 
205
	return true;
206
}
207
 
208
bool CDirIO::RemoveDir(CyString dir, bool doFiles, bool recursive, CyStringList *errors)
209
{
210
	// check if the dir is empty
211
	CyStringList *dirList = DirList(dir);
212
	if ( CheckEmptyDir(dirList) )
213
	{
214
		CyString remDir = ParseDir(dir);
215
		#ifdef _WIN32
216
		if ( _rmdir(remDir.c_str()) == 0 )
217
		#else
218
		if ( rmdir(remDir.c_str()) == 0 )
219
		#endif
220
		{
221
			if ( errors )
222
				errors->PushBack(remDir);
223
		}
224
		return true;
225
	}
226
 
227
	// not empty
228
	if ( doFiles || recursive )
229
	{
230
		for ( SStringList *str = dirList->Head(); str; str = str->next )
231
		{
232
			CyString d = str->str;
233
			if ( d == "." || d == ".." )
234
				continue;
235
 
236
			// if its a file
237
			CyString fullFile = dir + "\\" + d;
238
			if ( doFiles && IsFile(fullFile) )
239
			{
240
				CyString remFile = ParseDir(fullFile);
241
				if ( remove(remFile.c_str()) == 0 )
242
				{
243
					if ( errors )
244
						errors->PushBack(remFile);
245
				}
246
			}
247
			else if ( recursive && IsDir(fullFile) )
248
				RemoveDir(fullFile, doFiles, recursive, errors);
249
		}
250
	}
251
 
252
	// now check if its empty
253
	delete dirList;
254
	dirList = DirList(dir);
255
	if ( CheckEmptyDir(dirList) )
256
	{
257
		CyString remDir = ParseDir(dir);
258
		#ifdef _WIN32
259
		if ( _rmdir(remDir.c_str()) == 0 )
260
		#else
261
		if ( rmdir(remDir.c_str()) == 0 )
262
		#endif
263
		{
264
			if ( errors )
265
				errors->PushBack(remDir);
266
		}
267
		return true;
268
	}
269
 
270
	return false;
271
}
272
 
273
CyStringList *CDirIO::DirList(CyString dir, CyString filepattern)
274
{
275
	dir = ParseDir(dir);
276
	if ( dir.Empty() )
277
		return 0;
278
 
279
	CyStringList *files = new CyStringList;
280
 
281
#ifdef _WIN32
282
	dir = dir.FindReplace("/", "\\");
283
	if ( filepattern.Empty() )
284
		dir += "\\*";
285
	else
286
	{
287
		dir += "\\";
288
		dir += filepattern;
289
	}
290
	dir = dir.FindReplace("\\\\", "\\");
291
 
292
	WIN32_FIND_DATA data;
293
	TCHAR buf[5000];
294
	wsprintf(buf, L"%hs", dir.c_str());
295
 
296
	HANDLE h = FindFirstFile(buf, &data);
297
	if ( h != INVALID_HANDLE_VALUE)
298
	{
299
		CyString checkFile(data.cFileName);
300
		if ( !checkFile.Compare(".") && !checkFile.Compare("..") )
301
			files->PushBack(checkFile);
302
		while ( FindNextFile(h, &data) )
303
		{
304
			CyString checkFile(data.cFileName);
305
			if ( checkFile != "." && checkFile != ".." )
306
				files->PushBack(checkFile);
307
		}
308
 
309
		FindClose(h);
310
	}
311
#else
312
 
313
#endif//_WIN32
314
 
315
	return files;
316
}
317
 
318
CyString CDirIO::File(CyString filename)
319
{
85 cycrow 320
	if ( m_sCurrentDir.empty() )
1 cycrow 321
		return filename;
322
 
85 cycrow 323
	return CyString(m_sCurrentDir) + "/" + filename;
1 cycrow 324
}
325
 
85 cycrow 326
Utils::String CDirIO::dir(const Utils::String &sDir) const
327
{
328
	return parseDir(sDir);
329
}
330
 
331
const Utils::String &CDirIO::dir() const
332
{
333
	return m_sCurrentDir;
334
}
335
 
1 cycrow 336
CyString CDirIO::Dir(CyString dir)
337
{
85 cycrow 338
	return parseDir(dir.ToString());
1 cycrow 339
}
340
 
341
bool CDirIO::cd(CyString dir)
342
{
85 cycrow 343
	Utils::String sDir = dir.ToString();
344
 
345
	if ( m_sCurrentDir.empty() )
346
		m_sCurrentDir = sDir;
1 cycrow 347
	else
85 cycrow 348
		m_sCurrentDir = m_sCurrentDir + "/" + sDir;
349
	m_sCurrentDir = m_sCurrentDir.asFilename();
1 cycrow 350
 
351
	return Exists();
352
}
353
 
354
bool CDirIO::CreateAndChange(CyString dir)
355
{
356
	if ( Create(dir) )
357
		return cd(dir);
358
	return false;
359
}
360
 
361
 
362
CyString CDirIO::TopDir()
363
{
85 cycrow 364
	if ( m_sCurrentDir.empty() )
1 cycrow 365
		return NullString;
366
 
85 cycrow 367
	return m_sCurrentDir.token("/", -1);
1 cycrow 368
}
369
 
370
CyString CDirIO::Back()
371
{
85 cycrow 372
	m_sCurrentDir = m_sCurrentDir.tokens("/", 1, -2);
373
 
1 cycrow 374
	return m_sCurrentDir;
375
}