1 mike 1.28 //%/////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001 The Open group, BMC Software, Tivoli Systems, IBM
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to
7 // deal in the Software without restriction, including without limitation the
8 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 // sell copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
13 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
14 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
16 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
18 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
19 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 //
21 //==============================================================================
22 mike 1.28 //
23 // Author: Mike Brasher (mbrasher@bmc.com)
24 //
25 // Modified By:
26 //
27 //%/////////////////////////////////////////////////////////////////////////////
28
29 #include <iostream>
30 #include <cstdio>
31 #include <Pegasus/Common/Config.h>
32 #include <Pegasus/Common/System.h>
33 #include "Destroyer.h"
34 #include "FileSystem.h"
35 #include "System.h"
36 #include "Dir.h"
37
38 PEGASUS_NAMESPACE_BEGIN
39
40 // Clone the path as a C String but discard trailing slash if any:
41
42 static char* _clonePath(const String& path)
43 mike 1.28 {
44 char* p = path.allocateCString();
45
46 if (!*p)
47 return p;
48
49 char* last = p + path.size() - 1;
50
51 if (*last == '/')
52 *last = '\0';
53
54 return p;
55 }
56
57 Boolean FileSystem::exists(const String& path)
58 {
59 ArrayDestroyer<char> p(_clonePath(path));
60 return System::exists(p.getPointer());
61 }
62
63 Boolean FileSystem::getCurrentDirectory(String& path)
64 mike 1.28 {
65 path.clear();
66 char tmp[4096];
67
68 if (!System::getCurrentDirectory(tmp, sizeof(tmp) - 1))
69 return false;
70
71 path.append(tmp);
72 return true;
73 }
74
75 Boolean FileSystem::existsNoCase(const String& path, String& realPath)
76 {
77 realPath.clear();
78 ArrayDestroyer<char> destroyer(_clonePath(path));
79 char* p = destroyer.getPointer();
80
81 const char* dirPath;
82 char* fileName;
83 char* slash = strrchr(p, '/');
84
85 mike 1.28 if (slash)
86 {
87 *slash = '\0';
88 fileName = slash + 1;
89 dirPath = p;
90
91 if (*fileName == '\0')
92 return false;
93 }
94 else
95 {
96 fileName = p;
97 dirPath = ".";
98 }
99
100
101 for (Dir dir(dirPath); dir.more(); dir.next())
102 {
103 if (CompareNoCase(fileName, dir.getName()) == 0)
104 {
105 if (strcmp(dirPath, ".") == 0)
106 mike 1.28 realPath = dir.getName();
107 else
108 {
109 realPath = dirPath;
110 realPath += '/';
111 realPath += dir.getName();
112 }
113 return true;
114 }
115 }
116
117 return false;
118 }
119
120 Boolean FileSystem::canRead(const String& path)
121 {
122 ArrayDestroyer<char> p(_clonePath(path));
123 return System::canRead(p.getPointer());
124 }
125
126 Boolean FileSystem::canWrite(const String& path)
127 mike 1.28 {
128 ArrayDestroyer<char> p(_clonePath(path));
129 return System::canWrite(p.getPointer());
130 }
131
132 Boolean FileSystem::getFileSize(const String& path, Uint32& size)
133 {
134 ArrayDestroyer<char> p(_clonePath(path));
135 return System::getFileSize(p.getPointer(), size);
136 }
137
138 Boolean FileSystem::removeFile(const String& path)
139 {
140 ArrayDestroyer<char> p(_clonePath(path));
141 return System::removeFile(p.getPointer());
142 }
143
144 void FileSystem::loadFileToMemory(
145 Array<Sint8>& array,
146 const String& fileName)
147 {
148 mike 1.28 Uint32 fileSize;
149
150 if (!getFileSize(fileName, fileSize))
151 throw CannotOpenFile(fileName);
152
153 char* tmp = fileName.allocateCString();
154 FILE* fp = fopen(tmp, "rb");
155 delete [] tmp;
156
157 if (fp == NULL)
158 throw CannotOpenFile(fileName);
159
160 array.reserve(fileSize);
161 char buffer[4096];
162 size_t n;
163
164 while ((n = fread(buffer, 1, sizeof(buffer), fp)) > 0)
165 array.append(buffer, n);
166
167 fclose(fp);
168 }
169 mike 1.28
170 Boolean FileSystem::compareFiles(
171 const String& path1,
172 const String& path2)
173 {
174 Uint32 fileSize1;
175
176 if (!getFileSize(path1, fileSize1))
177 throw CannotOpenFile(path1);
178
179 Uint32 fileSize2;
180
181 if (!getFileSize(path2, fileSize2))
182 throw CannotOpenFile(path2);
183
184 if (fileSize1 != fileSize2)
185 return false;
186
187 char* tmp1 = path1.allocateCString();
188 FILE* fp1 = fopen(tmp1, "rb");
189 delete [] tmp1;
190 mike 1.28
191 if (fp1 == NULL)
192 throw CannotOpenFile(path1);
193
194 char* tmp2 = path2.allocateCString();
195 FILE* fp2 = fopen(tmp2, "rb");
196 delete [] tmp2;
197
198 if (fp2 == NULL)
199 {
200 fclose(fp1);
201 throw CannotOpenFile(path2);
202 }
203
204 int c1;
205 int c2;
206
207 while ((c1 = fgetc(fp1)) != EOF && (c2 = fgetc(fp2)) != EOF)
208 {
209 if (c1 != c2)
210 {
211 mike 1.28 fclose(fp1);
212 fclose(fp2);
213 return false;
214 }
215 }
216
217 fclose(fp1);
218 fclose(fp2);
219 return true;
220 }
221
222 Boolean FileSystem::renameFile(
223 const String& oldPath,
224 const String& newPath)
225 {
226 ArrayDestroyer<char> p(oldPath.allocateCString());
227 ArrayDestroyer<char> q(newPath.allocateCString());
228 return System::renameFile(p.getPointer(), q.getPointer());
229 }
230
231 Boolean FileSystem::openNoCase(PEGASUS_STD(ifstream)& is, const String& path)
232 mike 1.28 {
233 String realPath;
234
235 if (!existsNoCase(path, realPath))
236 return false;
237
238 ArrayDestroyer<char> p(_clonePath(path));
239
240 is.open(p.getPointer() PEGASUS_IOS_BINARY);
241 return is != 0;
242 }
243
244 Boolean FileSystem::isDirectory(const String& path)
245 {
246 ArrayDestroyer<char> p(_clonePath(path));
247 return System::isDirectory(p.getPointer());
248 }
249
250 Boolean FileSystem::changeDirectory(const String& path)
251 {
252 ArrayDestroyer<char> p(_clonePath(path));
253 mike 1.28 return System::changeDirectory(p.getPointer());
254 }
255
256 Boolean FileSystem::makeDirectory(const String& path)
257 {
258 ArrayDestroyer<char> p(_clonePath(path));
259 return System::makeDirectory(p.getPointer());
260 }
261
262 Boolean FileSystem::removeDirectory(const String& path)
263 {
264 ArrayDestroyer<char> p(_clonePath(path));
265 return System::removeDirectory(p.getPointer());
266 }
267
268 Boolean FileSystem::removeDirectoryHier(const String& path)
269 {
270 Array<String> fileList;
271
272 // Get contents of current directory
273
274 mike 1.28 if (!FileSystem::getDirectoryContents(path,fileList))
275 return false;
276
277 // for files-in-directory, delete or recall removedir
278
279 for (Uint32 i = 0, n = fileList.size(); i < n; i++)
280 {
281 String newPath = path; // extend path to subdir
282 newPath.append("/");
283 newPath.append(fileList[i]);
284
285 if (FileSystem::isDirectory(newPath))
286 {
287 // Recall ourselves with extended path
288 if (!FileSystem::removeDirectoryHier(newPath))
289 return false;
290 }
291
292 else
293 {
294 if (!FileSystem::removeFile(newPath))
295 mike 1.28 return false;
296 }
297 }
298
299 return removeDirectory(path);
300 }
301
302 //
303 // Get the file list in the directory into the
304 // array of strings provided
305 // @return The function should return false under these circumstances:
306 //
307 //
308 // 1. The directory does not exist.
309 // 2. The file exists but is not a directory.
310 // 3. The directory is inaccessible.
311 //
312 //
313 Boolean FileSystem::getDirectoryContents(
314 const String& path,
315 Array<String>& paths)
316 mike 1.28 {
317 paths.clear();
318
319 try
320 {
321 for (Dir dir(path); dir.more(); dir.next())
322 {
323 String name = dir.getName();
324
325 if (String::equal(name, ".") || String::equal(name, ".."))
326 continue;
327
328 paths.append(name);
329 }
330 return true;
331 }
332
333 // Catch the Dir exception
334 catch(CannotOpenDirectory&)
335 {
336 return false;
337 mike 1.28 }
338 }
339
340 Boolean FileSystem::isDirectoryEmpty(const String& path)
341 {
342 for (Dir dir(path); dir.more(); dir.next())
343 {
344 const char* name = dir.getName();
345
346 if (strcmp(name, ".") != 0 && strcmp(name, "..") != 0)
347 return false;
348 }
349
350 return true;
351 }
352
353 void FileSystem::translateSlashes(String& path)
354 {
355 for (Char16* p = (Char16*)path.getData(); *p; p++)
356 {
357 if (*p == '\\')
358 mike 1.28 *p = '/';
359 }
360 }
361
362 PEGASUS_NAMESPACE_END
|