00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <base/CacheDirectory>
00026
00027 #include <base/File>
00028
00029 extern "C" {
00030 #include <sys/types.h>
00031 #include <sys/stat.h>
00032 #include <dirent.h>
00033 #include <errno.h>
00034 }
00035
00036 using base::CacheDirectory;
00037 using base::VEntry;
00038 using base::VDirectory;
00039 using base::VFile;
00040 using base::PathName;
00041
00042
00043 CacheDirectory::CacheDirectory(ref<VDirectory> actualDir, const String& prefix)
00044 : VDirectory(String()+PathName::separator),
00045 actualDir(actualDir), prefix(prefix), loaded(false)
00046 {
00047
00048 }
00049
00050
00051 CacheDirectory::CacheDirectory(const CacheDirectory& d)
00052 : VDirectory(d),
00053 actualDir(d.actualDir), prefix(d.prefix), loaded(false)
00054 {
00055 }
00056
00057 CacheDirectory::~CacheDirectory()
00058 {
00059 }
00060
00061
00062 void CacheDirectory::load() const
00063 {
00064 if (!loaded) {
00065
00066
00067
00068 entries.clear();
00069 VDirectory::const_iterator f = actualDir->begin();
00070 VDirectory::const_iterator end = actualDir->end();
00071 while (f != end) {
00072 ref<VEntry> ent = *f;
00073
00074 if (!ent->isDirectory()) {
00075 ref<VFile> file( narrow_ref<VFile>(ent) );
00076 String name(file->name().str());
00077
00078
00079 if (name.find(prefix,0)==0) {
00080 String suffix(name.substr(prefix.length(),name.length()-prefix.length()));
00081 ref<CacheFile> cfile( NewObj CacheFile(suffix,file) );
00082 entries.push_back(cfile);
00083 }
00084
00085 }
00086 ++f;
00087 }
00088 }
00089 loaded = true;
00090 }
00091
00092
00093 ref<VEntry> CacheDirectory::find(const String& name) const
00094 {
00095 load();
00096 bool found=false;
00097 CacheFileEntries::iterator it = entries.begin();
00098 while ((it != entries.end()) && !found) {
00099 if ( (*it)->name() == name )
00100 return (*it);
00101 ++it;
00102 }
00103 return ref<VEntry>(0);
00104 }
00105
00106
00107 void CacheDirectory::operator=(const CacheDirectory& d)
00108 {
00109 VDirectory::operator=(d);
00110 actualDir = d.actualDir;
00111 prefix = d.prefix;
00112 loaded=false;
00113 }
00114
00115
00116
00117 bool CacheDirectory::contains(ref<const VEntry> entry) const
00118 {
00119 if (entry->path() != String()+PathName::separator) return false;
00120 return ( find(entry->name().str()) != 0);
00121 }
00122
00123 bool CacheDirectory::contains(const PathName& name) const
00124 {
00125 if (name.str() == PathName::currentDirectory) return true;
00126 if (name.str() == PathName::parentDirectory) return false;
00127 return ( find(name.str()) != 0 );
00128 }
00129
00130
00131
00132 base::ref<VFile> CacheDirectory::file(const PathName& name) const throw(path_not_found)
00133 {
00134 ref<VEntry> e = find(name.str());
00135 if (e==0) throw path_not_found(Exception(String("file '")+name.str()+"' doesn't exists in this directory: "+pathname.str()));
00136 return narrow_ref<VFile>(e);
00137 }
00138
00139 base::ref<VDirectory> CacheDirectory::directory(const PathName& name) const throw(path_not_found)
00140 {
00141 throw path_not_found(Exception("A CacheDirectory can only contain files"));
00142 }
00143
00144 ref<VFile> CacheDirectory::createFile(const PathName& name) const throw(io_error)
00145 {
00146 const PathName& pn(name);
00147 if (!pn.isRelative() || pn.path() != PathName::currentDirectory)
00148 throw io_error(Exception(String("'")+name.str()+"' must be a simple file name, not a path"));
00149
00150 String fullname = prefix+name.str();
00151 loaded=false;
00152 return actualDir->createFile(fullname);
00153 }
00154
00155 void CacheDirectory::deleteFile(const PathName& name) const throw(path_not_found, io_error)
00156 {
00157 ref<VEntry> e = find(name.str());
00158 if (e==0) throw path_not_found(Exception(String("file '")+name.str()+"' doesn't exists in this directory"));
00159 ref<CacheFile> file = narrow_ref<CacheFile>(e);
00160 actualDir->deleteFile(file->actualFile->name());
00161 loaded=false;
00162 }
00163
00164 ref<VDirectory> CacheDirectory::createDirectory(const PathName& name) const throw(io_error)
00165 {
00166 throw io_error(Exception(String("error creating directory '")+name.str()+"': CacheDirectory can only contain files."));
00167 }
00168
00169 void CacheDirectory::deleteDirectory(const PathName& name) const throw(path_not_found, io_error)
00170 {
00171 throw path_not_found(Exception(name.str()+" doesn't exist in directory '"+pathName().str()+"' (CacheDirectory can only contain files)"));
00172 }
00173
00174
00175
00176 base::ref<VEntry> CacheDirectory::entry(Int i) const
00177 {
00178 if (!loaded) load();
00179 return entries[i];
00180 }
00181
00182 Int CacheDirectory::size() const
00183 {
00184 if (!loaded) load();
00185 return entries.size();
00186 }
00187
00188
00189