From cb4716f40360d10faa7e50baa09a5e4e75a96694 Mon Sep 17 00:00:00 2001 From: James Turner Date: Thu, 15 Jul 2010 09:40:46 +0100 Subject: [PATCH] Initial work on simgear::Dir, replacement for PLIB ulDir functions. --- projects/VC90/SimGear.vcproj | 8 ++ simgear/misc/Makefile.am | 6 +- simgear/misc/sg_dir.cxx | 153 +++++++++++++++++++++++++++++++++++ simgear/misc/sg_dir.hxx | 62 ++++++++++++++ 4 files changed, 227 insertions(+), 2 deletions(-) create mode 100644 simgear/misc/sg_dir.cxx create mode 100644 simgear/misc/sg_dir.hxx diff --git a/projects/VC90/SimGear.vcproj b/projects/VC90/SimGear.vcproj index 30b7b85d..24484e8c 100644 --- a/projects/VC90/SimGear.vcproj +++ b/projects/VC90/SimGear.vcproj @@ -627,6 +627,14 @@ RelativePath="..\..\simgear\misc\sg_path.hxx" > + + + + diff --git a/simgear/misc/Makefile.am b/simgear/misc/Makefile.am index dd4e6e41..0e0fc949 100644 --- a/simgear/misc/Makefile.am +++ b/simgear/misc/Makefile.am @@ -12,7 +12,8 @@ include_HEADERS = \ zfstream.hxx \ interpolator.hxx \ stdint.hxx \ - PathOptions.hxx + PathOptions.hxx \ + sg_dir.hxx libsgmisc_a_SOURCES = \ sg_path.cxx \ @@ -22,7 +23,8 @@ libsgmisc_a_SOURCES = \ texcoord.cxx \ zfstream.cxx \ interpolator.cxx \ - PathOptions.cxx + PathOptions.cxx \ + sg_dir.cxx #noinst_PROGRAMS = tabbed_value_test swap_test diff --git a/simgear/misc/sg_dir.cxx b/simgear/misc/sg_dir.cxx new file mode 100644 index 00000000..e8775093 --- /dev/null +++ b/simgear/misc/sg_dir.cxx @@ -0,0 +1,153 @@ +// Written by James Turner, started July 2010. +// +// Copyright (C) 2010 Curtis L. Olson - http://www.flightgear.org/~curt +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// $Id$ + + +#include + +#ifdef _WIN32 +# define WIN32_LEAN_AND_MEAN +# include +#else +# include +# include +#endif + +#include + +#include + +namespace simgear +{ + +Dir::Dir(const SGPath& path) : + _path(path) +{ +} + +Dir::Dir(const Dir& rel, const SGPath& relPath) : + _path(rel.file(relPath.str())) +{ +} + +PathList Dir::children(int types, const std::string& nameFilter) const +{ + PathList result; + if (types == 0) { + types = TYPE_FILE | TYPE_DIR | NO_DOT_OR_DOTDOT; + } + +#ifdef _WIN32 + std::string search(_path.str()); + if (nameFilter.empty()) { + search += "\\*"; // everything + } else { + search += "\\*" + nameFilter; + } + + WIN32_FIND_DATA fData; + HANDLE find = FindFirstFile(search.c_str(), &fData); + if (find == INVALID_HANDLE_VALUE) { + SG_LOG(SG_GENERAL, SG_WARN, "Dir::children: FindFirstFile failed:" << _path.str()); + return result; + } + + bool done = false; + for (bool done = false; !done; done = (FindNextFile(find, &fData) == 0)) { + if (fData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) { + if (!(types & INCLUDE_HIDDEN)) { + continue; + } + } + + if (fData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if (!(types & TYPE_DIR)) { + continue; + } + } else if ((fData.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) || + (fData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) + { + continue; // always ignore device files + } else if (!(types & TYPE_FILE)) { + continue; + } + + result.push_back(file(fData.cFileName)); + } + + FindClose(find); +#else + DIR* dp = opendir(_path.c_str()); + if (!dp) { + SG_LOG(SG_GENERAL, SG_WARN, "Dir::children: opendir failed:" << _path.str()); + return result; + } + + while (true) { + struct dirent* entry = readdir(dp); + if (!entry) { + break; // done iteration + } + + // skip hidden files (names beginning with '.') unless requested + if (!(types & INCLUDE_HIDDEN) && (entry->d_name[0] == '.')) { + continue; + } + + if (entry->d_type == DT_DIR) { + if (!(types & TYPE_DIR)) { + continue; + } + + if (types & NO_DOT_OR_DOTDOT) { + if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) { + continue; + } + } + } else if (entry->d_type == DT_REG) { + if (!(types & TYPE_FILE)) { + continue; + } + } else { + continue; // ignore char/block devices, fifos, etc + } + + if (!nameFilter.empty()) { + if (strstr(entry->d_name, nameFilter.c_str()) == NULL) { + continue; + } + } + + // passed all criteria, add to our result vector + result.push_back(file(entry->d_name)); + } + + closedir(dp); +#endif + return result; +} + +SGPath Dir::file(const std::string& name) const +{ + SGPath childPath = _path; + childPath.append(name); + return childPath; +} + +} // of namespace simgear diff --git a/simgear/misc/sg_dir.hxx b/simgear/misc/sg_dir.hxx new file mode 100644 index 00000000..5ff51c9c --- /dev/null +++ b/simgear/misc/sg_dir.hxx @@ -0,0 +1,62 @@ + +// Written by James Turner, started July 2010. +// +// Copyright (C) 2010 Curtis L. Olson - http://www.flightgear.org/~curt +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// $Id$ + + +#ifndef _SG_DIR_HXX +#define _SG_DIR_HXX + +#include + +#include +#include + +#include +#include + +namespace simgear +{ + typedef std::vector PathList; + + class Dir + { + public: + Dir(const SGPath& path); + Dir(const Dir& rel, const SGPath& relPath); + + enum FileTypes + { + TYPE_FILE = 1, + TYPE_DIR = 2, + NO_DOT_OR_DOTDOT = 1 << 12, + INCLUDE_HIDDEN = 1 << 13 + }; + + PathList children(int types = 0, const std::string& nameGlob = "") const; + + SGPath file(const std::string& name) const; + private: + mutable SGPath _path; + }; +} // of namespace simgear + +#endif // _SG_DIR_HXX + + -- 2.39.5