/* PIP - Platform Independent Primitives Directory Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com 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, either version 3 of the License, or (at your option) any later version. 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, see . */ #include "pidir.h" #if !defined(WINDOWS) && !defined(ANDROID) #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; 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; } path_.replaceAll(PIString(separator) + PIString(separator), PIString(separator)); bool isAbs = isAbsolute(); PIStringList l = PIString(p).split(separator); l.removeAll("."); l.removeAll(""); 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_ << separator; path_ << path; return cleanPath(); } bool PIDir::mkDir(bool withParents) { PIDir d = cleanedPath(); PIString tp; int ret; bool isAbs = isAbsolute(); if (withParents) { PIStringList l = d.path_.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; ret = mkdir(tp.data(), 16877); if (ret == 0) continue; printf("[PIDir] mkDir(\"%s\") error: %s\n", d.path_.data(), strerror(errno)); return false; } break; }; } } else { ret = mkdir(d.path_.data(), 16877); if (ret == 0) return true; printf("[PIDir] mkDir(\"%s\") error: %s\n", d.path_.data(), strerror(errno)); } return false; } PIVector PIDir::entries() { PIDir d = cleanedPath(); PIString p = d.path_; dirent ** list; #ifndef QNX int cnt = scandir(const_cast(p.data()), &list, 0, alphasort); #else int cnt = scandir(const_cast(p.data()), 0, 0, alphasort); #endif struct stat fs; PIVector l; for (int i = 0; i < cnt; ++i) { stat((p + separator + PIString(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