Files
pip/pidir.cpp
2011-07-29 08:17:24 +04:00

203 lines
3.9 KiB
C++

#include "pidir.h"
#ifndef WINDOWS
#ifdef WINDOWS
const PIChar PIDir::separator = '\\';
#else
const PIChar PIDir::separator = '/';
#endif
PIDir::PIDir() {
path_ = PIDir::current().path_;
dir_ = 0;
open();
}
PIDir::PIDir(const PIString & dir) {
path_ = dir.stdString();
dir_ = 0;
open();
}
bool PIDir::operator ==(const PIDir & d) const {
return true;
}
bool PIDir::open() {
if (dir_ != 0)
if (!close())
return false;
dir_ = opendir(path_.data());
return (dir_ != 0);
}
bool PIDir::close() {
if (dir_ == 0) return true;
if (closedir(dir_) == 0) {
dir_ = 0;
return true;
}
return false;
}
PIString PIDir::absolutePath() {
//di;
return PIString();
}
PIDir & PIDir::cleanPath() {
PIString p(path_);
if (p.size() == 0) {
path_ = ".";
open();
return *this;
}
bool isAbs = isAbsolute();
for (uint i = p.size() - 1; i > 0; --i) {
if (p[i] == separator && p[i - 1] == separator) {
p.cutLeft(i);
isAbs = true;
break;
}
}
PIStringList l = PIString(p).split(separator);
l.removeStrings(".");
l.removeStrings("");
bool found = true;
while (found) {
found = false;
for (uint i = 0; i < l.size() - 1; ++i) {
if (l.size() < 2) break;
if (l[i] != ".." && l[i + 1] == "..") {
if (l.size() + i > 2) l.remove(i, 2);
else l.remove(i, 1);
--i;
found = true;
}
}
}
found = true;
while (found) {
found = false;
if (l.size() > 0) if (l[0] == "..")
{l.pop_front(); found = true;}
}
path_ = separator + l.join(separator);
if (!isAbs) path_.insert(0, ".");
if (path_.size() == 0) path_ = "./";
open();
return *this;
}
PIDir & PIDir::cd(const PIString & path) {
if (path_.size() == 0) return *this;
if (path_[path_.size() - 1] == separator) path_ << path;
else path_ << separator << path;
return cleanPath();
}
bool PIDir::mkDir(bool withParents) {
PIDir d = cleanedPath();
string p = d.path_;
PIString tp;
int ret;
bool isAbs = isAbsolute();
if (withParents) {
PIStringList l = PIString(p).split(separator);
for (int i = l.size_s() - 1; i >= 0; --i) {
if (i > 1) tp = PIStringList(l).remove(i, l.size_s() - i).join(separator);
else {
tp = separator;
if (!isAbs) tp.push_front('.');
}
//cout << tp << endl;
if (isExists(tp)) {
for (int j = i + 1; j <= l.size_s(); ++j) {
tp = PIStringList(l).remove(j, l.size_s() - j).join(separator);
//cout << tp << endl;
p = tp.stdString();
ret = mkdir(p.c_str(), 16877);
if (ret == 0) continue;
printf("[PIDir] mkDir(\"%s\") error: %s\n", p.c_str(), strerror(errno));
return false;
}
break;
};
}
} else {
ret = mkdir(p.c_str(), 16877);
if (ret == 0) return true;
printf("[PIDir] mkDir(\"%s\") error: %s\n", p.c_str(), strerror(errno));
}
return false;
}
PIVector<PIDir::DirEntry> PIDir::entries() {
PIDir d = cleanedPath();
PIString p = d.path_;
dirent ** list;
#ifndef QNX
int cnt = scandir(const_cast<char*>(p.data()), &list, 0, alphasort);
#else
int cnt = scandir(const_cast<char*>(p.data()), 0, 0, alphasort);
#endif
struct stat fs;
PIVector<DirEntry> l;
for (int i = 0; i < cnt; ++i) {
stat((p + separator + list[i]->d_name).data(), &fs);
l.push_back(DirEntry(list[i]->d_name, fs.st_mode, fs.st_size));
delete list[i];
}
delete list;
return l;
}
PIDir PIDir::current() {
char rc[1024];
if (getcwd(rc, 1024) == 0) return PIString();
return PIDir(rc);
}
PIDir PIDir::home() {
return PIDir(getenv("HOME"));
}
PIDir PIDir::temporary() {
char * rc;
rc = tmpnam(0);
PIString s(rc);
return PIDir(s.left(s.findLast(PIDir::separator)));
}
bool PIDir::mkDir(const PIString & path, bool withParents) {
PIDir d(path);
if (d.isExists()) return true;
return d.mkDir(withParents);
}
bool PIDir::rmDir(const PIString & path) {
string s = path.stdString();
int ret = rmdir(s.c_str());
if (ret == 0) return true;
printf("[PIDir] rmDir(\"%s\") error: %s\n", s.c_str(), strerror(errno));
return false;
}
#endif