Subversion Repositories spk

Rev

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