root/ossiedev/branches/mcarrick/ossiedev/system/ossie/framework/FileSystem_impl.cpp @ 10799

Revision 10799, 12.8 KB (checked in by mcarrick, 22 months ago)

removing explicit support for previous versions of boost (1.35, 1.37); support for old versions will cause the code to be seriously fragmented

  • Property svn:eol-style set to native
Line 
1/****************************************************************************
2
3Copyright 2004, 2007, Virginia Polytechnic Institute and State University
4
5This file is part of the OSSIE Core Framework.
6
7OSSIE Core Framework is free software; you can redistribute it and/or modify
8it under the terms of the Lesser GNU General Public License as published by
9the Free Software Foundation; either version 2.1 of the License, or
10(at your option) any later version.
11
12OSSIE Core Framework is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15Lesser GNU General Public License for more details.
16
17You should have received a copy of the Lesser GNU General Public License
18along with OSSIE Core Framework; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
21****************************************************************************/
22
23/* SCA */
24
25#include <iostream>
26#include <string>
27
28#include <fnmatch.h>
29
30#include <boost/filesystem/operations.hpp>
31#include <boost/filesystem/path.hpp>
32#include <boost/filesystem/exception.hpp>
33#include <boost/cerrno.hpp>
34
35#ifndef BOOST_VERSION
36#include <boost/version.hpp>
37#endif
38
39namespace fs = boost::filesystem;
40
41#include "ossie/FileSystem_impl.h"
42#include "ossie/debug.h"
43
44FileSystem_impl::FileSystem_impl ()
45{
46    DEBUG(6, FileSystem, "In constructor.");
47
48        // this is legacy code that is not clear if it actually does anything.
49        // leaving in as a reference in case the code may be needed later.
50    //if (fs::path::default_name_check_writable())
51    //    fs::path::default_name_check(fs::portable_posix_name);
52
53    root = fs::initial_path();
54
55    init ();
56}
57
58
59FileSystem_impl::FileSystem_impl (const char *_root)
60{
61    DEBUG(6, FileSystem, "In constructor with " << _root);
62
63    root = _root;
64
65    init ();
66}
67
68
69void
70FileSystem_impl::init ()
71{
72    DEBUG(6, FileSystem, "In init()");
73}
74
75FileSystem_impl::~FileSystem_impl ()
76{
77    DEBUG(6, FileSystem, "In destructor.");
78}
79
80void FileSystem_impl::remove (const char *fileName) throw (CORBA::SystemException, CF::FileException, CF::InvalidFileName)
81{
82    DEBUG(6, FileSystem, "In remove with " << fileName);
83
84    if (!ossieSupport::isValidFileName(fileName)) {
85        DEBUG(7, FileSystem, "remove passed bad filename, throwing exception.");
86        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::remove] Invalid file name");
87    }
88
89    fs::path fname(root / fileName);
90
91    DEBUG(6, FileSystem, "About to remove file " << fname.string());
92    bool exists = fs::remove(fname);
93
94    if (!exists) {
95        DEBUG(6, FileSystem, "Attempt to remove non-existant file.");
96        throw (CF::FileException (CF::CFEEXIST, "[FileSystem_impl::remove] Error removing file from file system"));
97    }
98}
99
100void FileSystem_impl::copy (const char *sourceFileName, const char *destinationFileName) throw (CORBA::SystemException, CF::InvalidFileName, CF::FileException)
101{
102    DEBUG(6, FileSystem, "In copy from " << sourceFileName << " to " << destinationFileName);
103
104    if (sourceFileName[0] != '/' || destinationFileName[0] != '/' || !ossieSupport::isValidFileName(sourceFileName) || !ossieSupport::isValidFileName(destinationFileName)) {
105        DEBUG(7, FileSystem, "copy passed bad filename, throwing exception.");
106        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::copy] Invalid file name");
107    }
108
109    try {
110        fs::path sFile(root / sourceFileName);
111        fs::path dFile(root / destinationFileName);
112
113        if (fs::is_directory(sFile))
114            return;
115
116        fs::copy_file(sFile, dFile);
117    } catch (const fs::filesystem_error &ex) {
118        if (ex.code().value() == ENOENT)
119            throw CF::FileException(CF::CFENOENT, ex.what());
120    }
121}
122
123CORBA::Boolean FileSystem_impl::exists (const char *fileName)
124throw (CORBA::SystemException, CF::InvalidFileName)
125{
126    DEBUG(6, FileSystem, "In exists with " << fileName);
127
128    if (fileName[0] != '/' || !ossieSupport::isValidFileName(fileName)) {
129        DEBUG(7, FileSystem, "exists passed bad filename, throwing exception.");
130        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::exists] Invalid file name");
131    }
132
133    fs::path fname(root / fileName);
134
135    DEBUG(9, FileSystem, "Check for file " << fname.string());
136
137    return(fs::exists(fname));
138}
139
140void FileSystem_impl::recursiveList(const fs::path& dirPath, const char* pattern, CF::FileSystem::FileInformationSequence_var& fis)
141{
142    DEBUG(4, FileSystem, "Entering recursiveList")
143
144    try {
145        fs::path filePath(pattern);
146        std::string searchPattern(filePath.filename().c_str());
147        unsigned int idx = fis->length();
148        DEBUG(4, FileSystem, "In list with path " << dirPath.string() << ", and pattern " << searchPattern);
149        fs::directory_iterator end_itr; // past the end
150        for (fs::directory_iterator itr(dirPath); itr != end_itr; ++itr) {
151            if (fs::is_directory(*itr)) recursiveList(*itr, pattern, fis);
152            DEBUG(9, FileSystem, "In list checking file " << itr->path().filename().c_str());
153            if (fnmatch(searchPattern.c_str(), itr->path().filename().c_str(), 0) == 0) {
154                DEBUG(9, FileSystem, "Match in list with " << itr->path().filename().c_str());
155                fis->length(idx + 1);
156
157                if (fs::is_directory(*itr)) {
158                    std::string tmp(itr->path().filename().c_str());
159                    tmp += "/";
160                    fis[idx].name = CORBA::string_dup(tmp.c_str());
161                    fis[idx].kind = CF::FileSystem::DIRECTORY;
162                    fis[idx].size = 0;
163                } else {
164                    std::string full_path = dirPath.string();
165                    full_path += "/";
166                    full_path += itr->path().filename().c_str();
167                    fis[idx].name = CORBA::string_dup(full_path.c_str());
168                    fis[idx].kind = CF::FileSystem::PLAIN;
169                    fis[idx].size = fs::file_size(*itr);
170                }
171                /// \todo fix file creation time and last access time
172                CF::Properties prop;
173                prop.length(3);
174                prop[0].id = CORBA::string_dup(CF::FileSystem::CREATED_TIME_ID);
175                prop[0].value <<= fs::last_write_time(*itr);
176                prop[1].id = CORBA::string_dup(CF::FileSystem::MODIFIED_TIME_ID);
177                prop[1].value <<= fs::last_write_time(*itr);
178                prop[2].id = CORBA::string_dup(CF::FileSystem::LAST_ACCESS_TIME_ID);
179                prop[2].value <<= fs::last_write_time(*itr);
180                fis[idx].fileProperties = prop;
181                ++idx;
182            }
183        }
184        DEBUG(4, FileSystem, "About to return from list.");
185    } catch (const fs::filesystem_error &ex) {
186        DEBUG(9, FileSystem, "Caught exception in list, error_code " << ex.code().value());
187        if (ex.code().value() == EINVAL)
188            throw CF::InvalidFileName(CF::CFEINVAL, ex.what());
189        throw CF::FileException(CF::CFNOTSET, ex.what());
190    }
191    DEBUG(4, FileSystem, "Leaving recursiveList")
192}
193
194/// \todo: modify to search the pattern as a regular expression
195CF::FileSystem::FileInformationSequence* FileSystem_impl::list (const char *pattern) throw (CORBA::SystemException, CF::FileException, CF::InvalidFileName)
196{
197    DEBUG(6, FileSystem, "In list with " << pattern);
198
199    const fs::path rootDirPath(root);
200    CF::FileSystem::FileInformationSequence_var result = new CF::FileSystem::FileInformationSequence;
201    result->length(0);
202
203    recursiveList(rootDirPath, pattern, result);
204
205    return result._retn();
206}
207
208
209CF::File_ptr FileSystem_impl::create (const char *fileName) throw (CORBA::SystemException, CF::InvalidFileName, CF::FileException)
210{
211    DEBUG(6, FileSystem, "In create with " << fileName);
212
213    if (!ossieSupport::isValidFileName(fileName)) {
214        DEBUG(7, FileSystem, "create passed bad filename, throwing exception.");
215        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::create] Invalid file name");
216    }
217
218    if (exists(fileName)) {
219        DEBUG(6, FileSystem, "FileName exists in create, throwing exception.");
220        throw CF::FileException(CF::CFEEXIST, "File exists.");
221    }
222
223    File_impl *file = new File_impl (fileName, root, false, true);
224    CF::File_var fileServant = file->_this();
225
226    fileInfo newFile;
227    newFile.fileName = fileName;
228    newFile.servant = fileServant;
229    files.push_back(newFile);
230
231    return fileServant._retn();
232}
233
234CF::File_ptr FileSystem_impl::open (const char *fileName, CORBA::Boolean read_Only) throw (CORBA::SystemException, CF::InvalidFileName, CF::FileException)
235{
236    DEBUG(6, FileSystem, "In open with " << fileName);
237
238    if (!ossieSupport::isValidFileName(fileName)) {
239        DEBUG(7, FileSystem, "open passed bad filename, throwing exception.");
240        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::open] Invalid file name");
241    }
242
243
244    if (!exists(fileName)) {
245        DEBUG(6, FileSystem, "FileName does not exist in open, throwing exception.");
246        throw CF::FileException(CF::CFEEXIST, "[FileSystem::open] File does not exist.");
247    }
248
249//    fs::path filePath(root / fileName);
250
251    File_impl *file = new File_impl (fileName, root, read_Only, false);
252    CF::File_var fileServant = file->_this();
253
254    fileInfo newFile;
255    newFile.fileName = fileName;
256    newFile.servant = fileServant;
257    files.push_back(newFile);
258
259    return fileServant._retn();
260}
261
262
263void FileSystem_impl::mkdir (const char *directoryName) throw (CORBA::SystemException, CF::FileException, CF::InvalidFileName)
264{
265    DEBUG(6, FileSystem, "In mkdir with " << directoryName);
266
267    if (!ossieSupport::isValidFileName(directoryName)) {
268        DEBUG(7, FileSystem, "mkdir passed bad filename, throwing exception.");
269        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::mkdir] Invalid file name");
270    }
271
272    fs::path dirPath(root / directoryName);
273
274    if (fs::exists(dirPath))
275        throw CF::FileException (CF::CFEEXIST, "[FileSystem::mkdir] Directory exists.");
276
277    fs::path::iterator walkPath(dirPath.begin());
278    fs::path currentPath;
279    while (walkPath != dirPath.end()) {
280        DEBUG(9, FileSystem, "Walking path to create directories, current path " << currentPath.string());
281        currentPath /= *walkPath;
282        if (!fs::exists(currentPath)) {
283            DEBUG(9, FileSystem, "Creating directory " << currentPath.string());
284            try {
285                fs::create_directory(currentPath);
286            } catch (...) {
287                throw CF::FileException (CF::CFENFILE, "[FileSystem::mkdir] Failed to create directory");
288            }
289        }
290        ++walkPath;
291    }
292}
293
294void FileSystem_impl::removeDirectory(const fs::path &dirPath, bool doRemove)
295{
296
297    fs::directory_iterator end_itr; // past the end
298    for (fs::directory_iterator itr(dirPath); itr != end_itr; ++itr) {
299        if (fs::is_directory(*itr))
300            removeDirectory(*itr, doRemove);
301        else {
302            DEBUG(7, FileSystem, "Directory not empty in rmdir.");
303            throw CF::FileException();
304        }
305    }
306
307    if (doRemove)
308        fs::remove(dirPath);
309}
310
311void FileSystem_impl::rmdir (const char *directoryName) throw (CORBA::SystemException, CF::FileException, CF::InvalidFileName)
312{
313    DEBUG(6, FileSystem, "In rmdir with " << directoryName);
314
315    if (!ossieSupport::isValidFileName(directoryName)) {
316        DEBUG(7, FileSystem, "rmdir passed bad directory name, throwing exception.");
317        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::rmdir] Invalid directory name");
318    }
319
320    fs::path dirPath(root / directoryName);
321
322    if (!fs::exists(dirPath) || !fs::is_directory(dirPath)) {
323        DEBUG(7, FileSystem, "rmdir passed non_existant name or name is not a directory, throwing exception.");
324        throw CF::InvalidFileName (CF::CFEINVAL, "[FileSystem::rmdir] Invalid directory name");
325    }
326
327// See the JTAP test for rmdir to understand this
328    removeDirectory(dirPath, false); // Test for only empty directories
329    removeDirectory(dirPath, true);  // Only empty directories, remove them all
330}
331
332
333void FileSystem_impl::query (CF::Properties & fileSysProperties) throw (CORBA::SystemException, CF::FileSystem::UnknownFileSystemProperties)
334{
335    DEBUG(6, FileSystem, "In query");
336#if 0  ///\todo Implement query operations
337    bool check;
338
339    for (unsigned int i = 0; i < fileSysProperties.length (); i++) {
340        check = false;
341        if (strcmp (fileSysProperties[i].id, CF::FileSystem::SIZE) == 0) {
342            struct stat fileStat;
343            stat (root, &fileStat);
344//          fileSysProperties[i].value <<= fileStat.st_size;  /// \bug FIXME
345            check = true;
346        }
347        if (strcmp (fileSysProperties[i].id,
348                    CF::FileSystem::AVAILABLE_SIZE) == 0) {
349//to complete
350        }
351        if (!check)
352            throw CF::FileSystem::UnknownFileSystemProperties ();
353    }
354#endif
355}
356
357///\todo Implement File object reference clean up.
Note: See TracBrowser for help on using the browser.