00001
00002
00003
00004
00005
00006
00007
00008 #include "ibrcommon/config.h"
00009 #include "ibrcommon/data/File.h"
00010 #include <sstream>
00011 #include <errno.h>
00012 #include <sys/stat.h>
00013 #include <stdio.h>
00014 #include <string.h>
00015 #include <stdlib.h>
00016
00017 namespace ibrcommon
00018 {
00019 File::File()
00020 : _path(), _type(DT_UNKNOWN)
00021 {
00022 }
00023
00024 File::File(const string path, const unsigned char t)
00025 : _path(path), _type(t)
00026 {
00027 removeSlash();
00028 }
00029
00030 File::File(const string path)
00031 : _path(path), _type(DT_UNKNOWN)
00032 {
00033 removeSlash();
00034 update();
00035 }
00036
00037 void File::removeSlash()
00038 {
00039 std::string::iterator iter = _path.end(); iter--;
00040
00041 if ((*iter) == '/')
00042 {
00043 _path.erase(iter);
00044 }
00045 }
00046
00047 bool File::exists() const
00048 {
00049 struct stat st;
00050 if( stat(_path.c_str(), &st ) == 0)
00051 return true;
00052
00053 return false;
00054 }
00055
00056 void File::update()
00057 {
00058 struct stat s;
00059 int type;
00060
00061 if ( stat(_path.c_str(), &s) == 0 )
00062 {
00063 type = s.st_mode & S_IFMT;
00064
00065 switch (type)
00066 {
00067 case S_IFREG:
00068 _type = DT_REG;
00069 break;
00070
00071 case S_IFLNK:
00072 _type = DT_LNK;
00073 break;
00074
00075 case S_IFDIR:
00076 _type = DT_DIR;
00077 break;
00078
00079 default:
00080 _type = DT_UNKNOWN;
00081 break;
00082 }
00083 }
00084 }
00085
00086 File::~File()
00087 {}
00088
00089 unsigned char File::getType() const
00090 {
00091 return _type;
00092 }
00093
00094 int File::getFiles(list<File> &files)
00095 {
00096 if (!isDirectory()) return -1;
00097
00098 DIR *dp;
00099 struct dirent *dirp;
00100 if((dp = opendir(_path.c_str())) == NULL) {
00101 return errno;
00102 }
00103
00104 while ((dirp = readdir(dp)) != NULL)
00105 {
00106 string name = string(dirp->d_name);
00107 stringstream ss; ss << getPath() << "/" << name;
00108 File file(ss.str(), dirp->d_type);
00109 files.push_back(file);
00110 }
00111 closedir(dp);
00112
00113 return 0;
00114 }
00115
00116 bool File::isSystem() const
00117 {
00118 if ((_path.substr(_path.length() - 2, 2) == "..") || (_path.substr(_path.length() - 1, 1) == ".")) return true;
00119 return false;
00120 }
00121
00122 bool File::isDirectory() const
00123 {
00124 if (_type == DT_DIR) return true;
00125 return false;
00126 }
00127
00128 string File::getPath() const
00129 {
00130 return _path;
00131 }
00132
00133 File File::get(string filename) const
00134 {
00135 stringstream ss; ss << getPath() << "/" << filename;
00136 File file(ss.str());
00137
00138 return file;
00139 }
00140
00141 int File::remove(bool recursive)
00142 {
00143 int ret;
00144
00145 if (isSystem()) return -1;
00146 if (_type == DT_UNKNOWN) return -1;
00147
00148 if (isDirectory())
00149 {
00150 if (recursive)
00151 {
00152
00153 list<File> files;
00154
00155
00156 if ((ret = getFiles(files)) < 0)
00157 return ret;
00158
00159 for (list<File>::iterator iter = files.begin(); iter != files.end(); iter++)
00160 {
00161 if (!(*iter).isSystem())
00162 {
00163 if ((ret = (*iter).remove(recursive)) < 0)
00164 return ret;
00165 }
00166 }
00167 }
00168
00169 ::rmdir(getPath().c_str());
00170 }
00171 else
00172 {
00173 ::remove(getPath().c_str());
00174 }
00175
00176 return 0;
00177 }
00178
00179 File File::getParent() const
00180 {
00181 size_t pos = _path.find_last_of('/');
00182 return File(_path.substr(0, pos));
00183 }
00184
00185 void File::createDirectory(File &path)
00186 {
00187 if (!path.exists())
00188 {
00189 File parent = path.getParent();
00190 File::createDirectory(parent);
00191
00192
00193 ::mkdir(path.getPath().c_str(), 0700);
00194
00195
00196 path.update();
00197 }
00198 }
00199
00200 size_t File::size() const
00201 {
00202 struct stat filestatus;
00203 stat( getPath().c_str(), &filestatus );
00204 return filestatus.st_size;
00205 }
00206
00207 TemporaryFile::TemporaryFile(const File &path, const std::string prefix)
00208 : File(tmpname(path, prefix))
00209 {
00210 }
00211
00212 TemporaryFile::~TemporaryFile()
00213 {
00214 }
00215
00216 std::string TemporaryFile::tmpname(const File &path, const std::string prefix)
00217 {
00218 char *name;
00219
00220 if ( (name = tempnam( path.getPath().c_str(), prefix.c_str() )) == NULL )
00221 throw ibrcommon::IOException("Could not create a temporary name.");
00222
00223 string filename(name);
00224 free(name);
00225
00226 return filename;
00227 }
00228 }