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/StdFileSystem>
00026
00027 #include <unistd.h>
00028
00029 #include <base/Directory>
00030 #include <base/File>
00031
00032 using base::StdFileSystem;
00033 using base::VFileSystem;
00034 using base::VDirectory;
00035 using base::VFile;
00036 using base::Directory;
00037 using base::File;
00038 using base::ref;
00039
00040
00041 StdFileSystem::StdFileSystem()
00042 {
00043 try {
00044 char* cwdbuf = new char[512];
00045 if (getcwd(cwdbuf, 512) == 0) {
00046 cwdbuf = new char[8192];
00047 if (getcwd(cwdbuf, 8192) == 0) {
00048 delete[] cwdbuf;
00049 throw std::runtime_error(Exception("current directory path is too long"));
00050 }
00051 }
00052 currentDir = narrow_ref<Directory>(getDirectory(String(cwdbuf)));
00053 delete[] cwdbuf;
00054 }
00055 catch (std::exception&) {
00056 currentDir = narrow_ref<Directory>(root());
00057 }
00058 }
00059
00060 StdFileSystem::~StdFileSystem()
00061 {
00062 }
00063
00064
00065 ref<VDirectory> StdFileSystem::root()
00066 {
00067 ref<Directory> dir( NewObj Directory(String()+PathName::separator,ref<Directory>(0)) );
00068 return dir;
00069 }
00070
00071 ref<VDirectory> StdFileSystem::temp()
00072 {
00073 return getDirectory(String()+PathName::separator+"tmp");
00074 }
00075
00076 ref<VDirectory> StdFileSystem::current()
00077 {
00078 return currentDir;
00079 }
00080
00081 void StdFileSystem::setCurrent(const PathName& path) throw (path_not_found, io_error, std::invalid_argument)
00082 {
00083 PathName pn(path);
00084 if (pn.isRelative())
00085 pn = PathName(currentDir->pathName())+pn;
00086
00087 currentDir = narrow_ref<Directory>(getDirectory(pn));
00088
00089 if (chdir(currentDir->pathName().str().c_str()) == -1)
00090 throw io_error(Exception(String("error change current directory to '")+currentDir->pathName().str()+"': "+strerror(errno)));
00091
00092 }
00093
00094
00095
00096 ref<VDirectory> StdFileSystem::getDirectory(const PathName& path) throw (path_not_found, io_error, std::invalid_argument)
00097 {
00098 const PathName& pn(path);
00099 Int first = 0;
00100 ref<VDirectory> d = root();
00101 if (pn.isRelative())
00102 d = current();
00103
00104 if (pn.size() > 0) {
00105 if (pn[0] == PathName::currentDirectory) {
00106 d = current();
00107 first = 1;
00108 }
00109 if (pn[0] == PathName::parentDirectory) {
00110 d = current()->directory(PathName::parentDirectory);
00111 first = 1;
00112 }
00113 }
00114
00115 for(Int pc=first; pc<pn.size(); pc++) {
00116 try {
00117 d = d->directory(pn[pc]);
00118 } catch (path_not_found&) {
00119 throw path_not_found(Exception(String("'")+path.str()+"' is an invalid path: '"+pn[pc]+"' doesn't exist in '"+d->pathName().str()+"'"));
00120 }
00121 }
00122
00123 return d;
00124 }
00125
00126
00127
00128 ref<VFile> StdFileSystem::getFile(const PathName& path) throw (path_not_found, io_error, std::invalid_argument)
00129 {
00130 const PathName& pn(path);
00131 ref<VDirectory> dir;
00132 try {
00133 dir = getDirectory(pn.path());
00134 } catch (path_not_found& e) {
00135 throw path_not_found(Exception(String("'")+path.str()+"' file not found: "+e.what()));
00136 }
00137 return dir->file(pn.name());
00138 }
00139
00140
00141 bool StdFileSystem::exists(const PathName& path) throw (io_error)
00142 {
00143 const PathName& pn(path);
00144 Int first = 0;
00145 ref<VDirectory> d = root();
00146 if (pn.isRelative())
00147 d = current();
00148
00149 if (pn.size() > 0) {
00150 if (pn[0] == PathName::currentDirectory) {
00151 d = current();
00152 first = 1;
00153 }
00154 if (pn[0] == PathName::parentDirectory) {
00155 d = current()->directory(PathName::parentDirectory);
00156 first = 1;
00157 }
00158 }
00159
00160 if (pn.size() > 0) {
00161 for(Int pc=first; pc<pn.size()-1; pc++) {
00162 if (d->contains(pn[pc]))
00163 d = d->directory(pn[pc]);
00164 else
00165 return false;
00166 }
00167 }
00168 else
00169 return false;
00170
00171 if (!d->contains(pn[pn.size()-1]))
00172 return false;
00173
00174 return true;
00175 }
00176