root/ossiedev/trunk/system/ossie/framework/FileSystem_impl.cpp @ 9980

Revision 9980, 13.1 KB (checked in by shereef, 3 years ago)

fixes for boost <= v1.35, >= v1.37 ... i hope

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