From: Markus R. <rol...@us...> - 2005-12-05 21:05:13
|
Update of /cvsroot/simspark/simspark/spark/zeitgeist/fileserver In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11684/fileserver Added Files: fileserver.cpp fileserver.h fileserver_c.cpp filesystem.h filesystem_c.cpp Log Message: --- NEW FILE: fileserver.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: fileserver.cpp,v 1.1 2005/12/05 21:05:01 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "fileserver.h" #include <salt/fileclasses.h> #include <zeitgeist/logserver/logserver.h> #include <zeitgeist/core.h> using namespace boost; using namespace salt; using namespace zeitgeist; using namespace std; FileServer::FileServer() : Node(), mNextHandle(1) { } FileServer::~FileServer() { } shared_ptr<salt::RFile> FileServer::Open(const string& inName) { for (TLeafList::iterator i = mChildren.begin(); i != mChildren.end(); ++i) { shared_ptr<FileSystem> fileSys = shared_static_cast<FileSystem>(*i); shared_ptr<salt::RFile> file(fileSys->Open(inName)); //first successful is returned if(file.get() != 0) { return file; } } // try to open it via the regular file system shared_ptr<salt::RFile> file(new StdFile()); if (! file->Open(inName.c_str())) { file.reset(); } return file; } FileServer::THandle FileServer::Register(const string& inName) { shared_ptr<salt::RFile> file = Open(inName); if (file.get() == 0) { return 0; } mFileMap[mNextHandle] = file; THandle h = mNextHandle; ++mNextHandle; return h; } shared_ptr<salt::RFile> FileServer::Get(THandle handle) const { TFileMap::const_iterator iter = mFileMap.find(handle); if (iter == mFileMap.end()) { GetLog()->Warning() << "(FileServer::Get) Warning: Unknown file handle " << handle << "\n"; return shared_ptr<salt::RFile>(); } return (*iter).second; } void FileServer::Close(THandle handle) { TFileMap::iterator iter = mFileMap.find(handle); if (iter == mFileMap.end()) { GetLog()->Warning() << "(FileServer::Close) Warning: Unknown file handle " << handle << "\n"; return; } mFileMap.erase(iter); if (mFileMap.empty()) { // restart handle counting on empty FileMap mNextHandle = 1; } } void FileServer::OnUnlink() { if (! mFileMap.empty()) { GetLog()->Warning() << "(FileServer) There are " << mFileMap.size() << " files left in the registry\n"; } } bool FileServer::Exist(const string& inName) { return (Open(inName).get() != 0); } // this routine registers a new file system instance with the server bool FileServer::Mount(const string& inFileSysName, const string& inPath) { shared_ptr<FileSystem> fileSys = shared_static_cast<FileSystem>(GetChild(inPath)); if (fileSys) { // we already have a file system which is bound to the same name if (fileSys->GetClass()->GetName().compare(inFileSysName) == 0) { // as the file system has the same type, we can return true return true; } else { // already have a file system of a different type, so return false GetLog()->Error() << "(FileServer) ERROR: a FileSystem is already mounted a " << inPath << "\n"; return false; } } // try to instantiate the file system fileSys = shared_static_cast<FileSystem>(GetCore()->New(inFileSysName)); if ( (fileSys.get() == 0) || (! fileSys->SetPath(inPath)) ) { return false; } // link it into our hierarchy AddChildReference(fileSys); GetLog()->Normal() << "(FileServer) successfully mounted a '" << inFileSysName << "' at '" << inPath << "'\n"; return true; } bool FileServer::Unmount(const string& inPath) { // try to remove a std file system first if (Unmount ("FileSystemSTD", inPath)) { return true; } shared_ptr<Leaf> leaf = GetChild(inPath); if(leaf) { leaf->Unlink(); return true; } return false; } bool FileServer::Unmount(const string& inFileSysName, const string& inPath) { shared_ptr<FileSystem> fileSystem = shared_static_cast<FileSystem>(GetChild(inPath)); if(fileSystem) { if (fileSystem->GetClass()->GetName().compare(inFileSysName) == 0) { fileSystem->Unlink(); return true; } } return false; } int FileServer::ForEachFile(const string& /*directory*/, const string& /*name*/, const string& /*extension*/, FileSystem::TCallback /*callback*/, void* /*param*/) { int count = 0; /*for (TDescriptionList::iterator iter = mFileSystems.begin (); iter != mFileSystems.end (); ++iter) { count += iter->fileSystem->ForEachFile(directory,name,extension,callback,param); }*/ return count; } --- NEW FILE: fileserver.h --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: fileserver.h,v 1.1 2005/12/05 21:05:01 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. FileServer - global interface for file system access HISTORY: 12.07.01 - MK - Initial version 14.07.01 - MK - ClassServer was added, so the FileServer doesn't manage the file system factories anymore (only concrete file system instances) 11.10.01 - MK - Made singleton functionality more secure 20.11.01 - AF - added the priority of the file systems : LIFO - added the information of the file system id and its path to every mounted file system - prevented the odditity to mount a file system more than once - added GetFirstFileSystem and GetNextFileSystem to iterate through the mounted file systems 26.01.02 - MR - added ForEachFile 27.06.02 - MK - converted this to the Zeitgeist framework 09.07.02 - MK - converted this to the Kerosin framework 10.10.02 - MK - back to Zeitgeist framework TODO: TOFIX: */ #ifndef ZEITGEIST_FILESERVER_H #define ZEITGEIST_FILESERVER_H #include <list> #include <zeitgeist/node.h> #include "filesystem.h" namespace zeitgeist { /** FileServer - the global interface for file system access What the FileServer does: - Manage different file systems - Load files from a FileSystem The file server is an extremely useful subsystem, since it allows to access various implemented file systems. The regular file system is a standard directory-based implementation. The ZIP file system can load files from within ZIP-files. Before actually being able to open files, the FileServer is initialized with several FileSystems, which are associated with different paths. For each path, you have to pass in a file system. Now, when trying to open a file, each registered file system is asked to open the file. Filesystems are searched in the inverse order in wich they were registered- think of a filesystem stack. The first succesful opened file wins. This allows for some nice effects. File systems are associated with id strings like 'STD' or 'ZIP'. */ class FileServer : public Node { // // functions // public: typedef int THandle; protected: typedef std::map<THandle, boost::shared_ptr<salt::RFile> > TFileMap; public: /** constructs the fileserver */ FileServer(); ~FileServer(); /** searchs each registered file system for a file with this name. Filesystems are searched in the inverse order in which they are registered to the fileserve, i.e. a filesystem stack. The first succesful opened file is returned. */ boost::shared_ptr<salt::RFile> Open(const std::string& inName); /** tries to open the requested file and registers it. On success it returns a non 0 handle assiociated with the file object. */ THandle Register(const std::string& inName); /** returns the file corresponding to the given handle. */ boost::shared_ptr<salt::RFile> Get(THandle handle) const; /** closes the file corresponding to the given handle */ void Close(THandle handle); /** returns true if the file 'inName' exists. */ bool Exist(const std::string& inName); /** registers a filesystem to the fileserver. A file system may be registered only once, on each further try nothing is done and false returned \param inFileSysName is the class name of the File system \param inPath is the mount point in the virtual file system provided by the fileserver */ bool Mount(const std::string& inFileSysName, const std::string& inPath); /** unmounts a file system at the mount point inPath. if no file system id is given, for a first try FileSystemSTD is assumed, then the type is ignored. Returns true on success. */ bool Unmount(const std::string& inPath); /** unmounts a file system at the mount point inPath. Returns true on success. */ bool Unmount(const std::string& inClass, const std::string& inPath); /** iterates through files. 'directory', 'name' and * 'extension' give directory, name and extension a file must * match. directory,name and extension may be NULL, in wich * case every directory,extension and/or name matches. For * each match the function callback is called with the name * of the matched file and the additional user parameter * 'param'. param is just passed through to the callback and * has no meaning to the filesystem. */ int ForEachFile(const std::string& directory, const std::string& name, const std::string& extension, FileSystem::TCallback callback, void* param); protected: /** This rountine is called, before the FileServer hierarchy object is removed from the parent. */ virtual void OnUnlink(); private: FileServer(const FileServer&); FileServer& operator=(const FileServer&); protected: /** registry of opened files using the handle base system */ TFileMap mFileMap; /** the next free handle */ THandle mNextHandle; }; DECLARE_CLASS(FileServer) } //namespace zeitgeist #endif //ZEITGEIST_FILESERVER_H --- NEW FILE: fileserver_c.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: fileserver_c.cpp,v 1.1 2005/12/05 21:05:01 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "fileserver.h" using namespace boost; using namespace zeitgeist; using namespace std; FUNCTION(FileServer,exist) { string inName; return ( (in.GetSize() == 1) && (in.GetValue(in.begin(),inName)) && (obj->Exist(inName.c_str())) ); } FUNCTION(FileServer,mount) { string inFsName; string inPath; return ( (in.GetSize() == 2) && (in.GetValue(in[0],inFsName)) && (in.GetValue(in[1],inPath)) && (obj->Mount(inFsName.c_str(),inPath.c_str())) ); } FUNCTION(FileServer,unmount) { bool ret = false; switch (in.GetSize()) { default: break; case 1: { string inPath; if (in.GetValue(in.begin(),inPath)) { ret = obj->Unmount(inPath.c_str()); } break; } case 2: { string inClass; string inPath; if ( (in.GetValue(in[0],inClass)) && (in.GetValue(in[1],inPath)) ) { ret = obj->Unmount(inClass.c_str(),inPath.c_str()); } break; } } return ret; } void CLASS(FileServer)::DefineClass() { DEFINE_BASECLASS(zeitgeist/Node); DEFINE_FUNCTION(exist); DEFINE_FUNCTION(mount); DEFINE_FUNCTION(unmount); } --- NEW FILE: filesystem_c.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: filesystem_c.cpp,v 1.1 2005/12/05 21:05:01 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "filesystem.h" using namespace boost; using namespace zeitgeist; using namespace std; FUNCTION(FileSystem,setPath) { string inPath; return( (in.GetSize() == 1) && (in.GetValue(in.begin(),inPath)) && (obj->SetPath(inPath.c_str()) != 0) ); } void CLASS(FileSystem)::DefineClass() { DEFINE_BASECLASS(zeitgeist/Leaf); DEFINE_FUNCTION(setPath); } --- NEW FILE: filesystem.h --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: filesystem.h,v 1.1 2005/12/05 21:05:01 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. FileSystem HISTORY: 27.06.2002 MK - initial version */ #ifndef ZEITGEIST_FILESYSTEM_H #define ZEITGEIST_FILESYSTEM_H #include <zeitgeist/class.h> #include <zeitgeist/leaf.h> #include <salt/fileclasses.h> namespace zeitgeist { /** this class defines the interface which derived filesystems must implement in order to be used with the fileserver. */ class FileSystem : public Leaf { // // types // public: /** this function defines an interface for a callback, used to iterate over files. It used in conjunction with ForEachFile(). */ typedef void (*TCallback) (char *filename, void *param); // // functions // public: /** constructs a filesystem */ FileSystem() : Leaf() {} virtual ~FileSystem() {} /** tries to open the file named inName. Returns an instance of a salt::RFile on success, NULL otherwise */ virtual boost::shared_ptr<salt::RFile> Open(const std::string& inName) = 0; /** sets the path all calls to Open are relative to. For a standard file system this call maps directly to a directory. For Filesystems providing access to an archive it is used to select the archive, i.e. it is the filename of an archive. Please refer to concrete Filesystems for an example implementation. */ virtual bool SetPath(const std::string& inPath) = 0; /** iterates over all files managed by this filesystem. * 'directory', 'name' and 'extension' give directory, name and * extension a file must match. directory,name and extension may * be NULL, in wich case every directory,extension and/or name * matches. For each match the function callback is called with * the name of the matched file and the additional user parameter * 'param'. param is just passed through to the callback and has * no meaning to the filesystem. */ virtual int ForEachFile(const std::string&, TCallback callback, void* param) = 0; private: FileSystem(const FileSystem& obj); FileSystem& operator=(const FileSystem& obj); }; DECLARE_ABSTRACTCLASS(FileSystem); } //namespace zeitgeist #endif //ZEITGEIST_FILESYSTEM_H |