📄 dir.cpp
字号:
// Copyright (C) 1999-2005 Open Source Telecom Corporation.//// 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 2 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, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.// // As a special exception, you may use this file as part of a free software// library without restriction. Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License. This exception does not however // invalidate any other reasons why the executable file might be covered by// the GNU General Public License. //// This exception applies only to the code released under the name GNU// Common C++. If you copy code from other releases into a copy of GNU// Common C++, as the General Public License permits, the exception does// not apply to the code that you add in this way. To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for GNU Common C++, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.//#include <cc++/config.h>#include <cc++/export.h>#include <cc++/exception.h>#include <cc++/file.h>#include "private.h"#ifdef WIN32#include <sys/stat.h>#include <malloc.h>#endif#ifdef CCXX_NAMESPACESnamespace ost {using namespace std;#endifDir::Dir(const char *fname) :#ifdef WIN32hDir(INVALID_HANDLE_VALUE), name(NULL)#elsedir(NULL)#endif{#ifdef HAVE_READDIR_R save = reinterpret_cast<struct dirent*>(save_space);#endif if(fname) open(fname);}bool Dir::create(const char *path, Attr attr){ long xmask = 0; bool rtn = true;#ifdef WIN32 // fixme: make it form a security attributes structure if(!CreateDirectory(path, NULL)) rtn = false;#else switch(attr) { case attrPublic: xmask |= S_IXOTH; case attrGroup: xmask |= S_IXGRP; case attrPrivate: xmask |= S_IXUSR; break; default: return false; } if(mkdir(path, (long)attr | xmask)) rtn = false;#endif return rtn;}bool Dir::remove(const char *path){ bool rtn = true;#ifdef WIN32 if(!RemoveDirectory(path)) rtn = false;#else if(rmdir(path)) rtn = false;#endif return rtn;}bool Dir::setPrefix(const char *prefix){ bool rtn = true;#ifdef WIN32 if(!SetCurrentDirectory(prefix)) rtn = false;#else if(chdir(prefix)) rtn = false;#endif return rtn;}bool Dir::getPrefix(char *prefix, size_t size){ bool rtn = true;#ifdef WIN32 if(!GetCurrentDirectory((DWORD)size, prefix)) rtn = false;#else if(getcwd(prefix, size) == NULL) rtn = false;#endif return rtn;}void Dir::open(const char *fname){#ifdef WIN32 size_t len = strlen(fname) + 4; char *path;#endif close();#ifdef WIN32 DWORD attr = GetFileAttributes(fname); if( (attr == (DWORD)~0l) || !(attr & FILE_ATTRIBUTE_DIRECTORY) ) {#ifdef CCXX_EXCEPTIONS if(Thread::getException() == Thread::throwObject) throw(this);#ifdef COMMON_STD_EXCEPTION else if(Thread::getException() == Thread::throwException) throw(DirException(String(fname) + ": failed"));#endif#endif } path = (char *)alloca(len + 1); if(path) snprintf(path, len + 1, "%s", fname);#ifdef CCXX_EXCEPTIONS if (!path && Thread::getException() == Thread::throwObject) throw(this);#ifdef COMMON_STD_EXCEPTION else if(!path && Thread::getException() == Thread::throwException) throw(DirException(String(fname) + ": failed"));#endif#endif addString(path, len, "\\*"); hDir = FindFirstFile(path, &fdata); if(hDir != INVALID_HANDLE_VALUE) name = fdata.cFileName; memcpy(&data, &fdata, sizeof(fdata));#else // WIN32 entry = NULL; dir = opendir(fname);#ifdef CCXX_EXCEPTIONS if(!dir && Thread::getException() == Thread::throwObject) throw(this);#ifdef COMMON_STD_EXCEPTION else if(!dir && Thread::getException() == Thread::throwException) throw(DirException(String(fname) + ": failed"));#endif#endif#endif // WIN32} Dir::~Dir(){ close();}void Dir::close(void){#ifdef WIN32 if(hDir != INVALID_HANDLE_VALUE) FindClose(hDir); hDir = INVALID_HANDLE_VALUE;#else if(dir) closedir(dir); dir = NULL; entry = NULL;#endif}bool Dir::rewind(void){ bool rtn = true;#ifdef WIN32 memcpy(&data, &fdata, sizeof(data)); name = fdata.cFileName;#else if(!dir) rtn = false; else rewinddir(dir);#endif return rtn;}bool Dir::isValid(void){#ifdef WIN32 if(hDir == INVALID_HANDLE_VALUE)#else if(!dir)#endif return false; return true;}const char *Dir::operator*(){#ifdef WIN32 return name;#else if(!dir) return NULL; if(!entry) return getName(); return entry->d_name;#endif}const char *Dir::getName(void){#ifdef WIN32 char *retname = name; if(hDir == INVALID_HANDLE_VALUE) return NULL; if(retname) { name = NULL; if(FindNextFile(hDir, &data)) name = data.cFileName; } return retname;#else if(!dir) return NULL;#ifdef HAVE_READDIR_R readdir_r(dir, save, &entry);#else entry = readdir(dir);#endif if(!entry) return NULL; return entry->d_name;#endif // WIN32}DirTree::DirTree(const char *prefix, unsigned depth){ max = ++depth; dir = new Dir[depth]; current = 0; open(prefix);}DirTree::DirTree(unsigned depth){ max = ++depth; dir = new Dir[depth]; current = 0;}void DirTree::open(const char *prefix){ char *cp; close(); if(!isDir(prefix)) return; snprintf(path, sizeof(path), "%s/", prefix); prefixpos = (unsigned)strlen(path) - 1; while(NULL != (cp = strchr(path, '\\'))) *cp = '/'; while(prefixpos && path[prefixpos - 1] == '/') path[prefixpos--] = 0; dir[current++].open(prefix); }DirTree::~DirTree(){ close(); if(dir) delete[] dir; dir = NULL;}unsigned DirTree::perform(const char *prefix){ unsigned count = 0; open(prefix); while(NULL != (getPath())) ++count; close(); return count;}void DirTree::close(void){ while(current--) dir[current].close(); current = 0;}bool DirTree::filter(const char *path, struct stat *ino){ path = strrchr(path, '/'); if(path) ++path; else return false; if(!strcmp(path, ".")) return false; if(!strcmp(path, "..")) return false; if(!ino) return false; return true;}char *DirTree::getPath(void){ char *cp; const char *name; struct stat ino; bool flag; while(current) { cp = strrchr(path, '/'); name = dir[current - 1].getName(); if(!name) { *cp = 0; dir[--current].close(); continue; } snprintf(cp + 1, sizeof(path) - strlen(path) - 2, "%s", name); if(::stat(path, &ino)) { ino.st_mode = 0; flag = filter(path, NULL); } else flag = filter(path, &ino); if(!flag) continue; if((ino.st_mode & S_IFMT) == S_IFDIR) { if(!canAccess(path)) break; if(current < max) dir[current++].open(path); snprintf(path + strlen(path), sizeof(path) - strlen(path), "/"); } break; } if(!current) return NULL; return path; }#ifdef CCXX_NAMESPACES}#endif/** EMACS ** * Local variables: * mode: c++ * c-basic-offset: 8 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -