diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 2001-07-09 20:02:29 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 2001-07-09 20:02:29 +0000 |
commit | b161743f263428a37c8b56c5d2b31698a81000b4 (patch) | |
tree | f5daf4d0718ce49c9614f7ac85c78dc9e1a5e550 /ace | |
parent | 1ca4201b746610bd8e569f91942ad5bee7c44d82 (diff) | |
download | ATCD-b161743f263428a37c8b56c5d2b31698a81000b4.tar.gz |
ChangeLogTag:Mon Jul 9 06:52:09 2001 Douglas C. Schmidt <schmidt@tango.doc.wustl.edu>
Diffstat (limited to 'ace')
-rw-r--r-- | ace/Dirent.h | 4 | ||||
-rw-r--r-- | ace/Dirent_Selector.cpp | 36 | ||||
-rw-r--r-- | ace/Dirent_Selector.h | 64 | ||||
-rw-r--r-- | ace/Dirent_Selector.inl | 13 | ||||
-rw-r--r-- | ace/Makefile | 1 | ||||
-rw-r--r-- | ace/Makefile.bor | 1 | ||||
-rw-r--r-- | ace/OS_Dirent.cpp | 105 | ||||
-rw-r--r-- | ace/OS_Dirent.h | 33 | ||||
-rw-r--r-- | ace/OS_Dirent.inl | 22 | ||||
-rw-r--r-- | ace/OS_Memory.h | 4 | ||||
-rw-r--r-- | ace/Reactor.cpp | 1 | ||||
-rw-r--r-- | ace/Service_Object.cpp | 2 |
12 files changed, 259 insertions, 27 deletions
diff --git a/ace/Dirent.h b/ace/Dirent.h index 43ce109683d..0764011cd4d 100644 --- a/ace/Dirent.h +++ b/ace/Dirent.h @@ -6,7 +6,7 @@ * * $Id$ * - * Define a portable directory-entry manipulation interface. + * Define a portable C++ interface to <ACE_OS_Dirent> directory-entry manipulation. * * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> */ @@ -25,7 +25,7 @@ /** * @class ACE_Dirent * - * @brief Define a portable UNIX directory-entry iterator. + * @brief Define a portable C++ directory-entry iterator based on the POSIX API. */ class ACE_Export ACE_Dirent { diff --git a/ace/Dirent_Selector.cpp b/ace/Dirent_Selector.cpp new file mode 100644 index 00000000000..dce8d7f05ef --- /dev/null +++ b/ace/Dirent_Selector.cpp @@ -0,0 +1,36 @@ +// $Id$ + +#include "ace/OS.h" +#include "ace/Dirent_Selector.h" + +// Construction/Destruction + +ACE_Dirent_Selector::ACE_Dirent_Selector (void) + : n_ (0), + namelist_ (0) +{ +} + +ACE_Dirent_Selector::~ACE_Dirent_Selector (void) +{ +} + +int +ACE_Dirent_Selector::open (const ACE_TCHAR *dir, + int (*sel)(const dirent *d), + int (*cmp) (const dirent **d1, + const dirent **d2)) +{ + n_ = ACE_OS::scandir (dir, &this->namelist_, sel, cmp); + return n_; +} + +int +ACE_Dirent_Selector::close (void) +{ + for (--n_; n_>=0; --n_) + ACE_OS::free (this->namelist_[n_]); + + ACE_OS::free (this->namelist_); + return 0; +} diff --git a/ace/Dirent_Selector.h b/ace/Dirent_Selector.h new file mode 100644 index 00000000000..6f3ea0872fa --- /dev/null +++ b/ace/Dirent_Selector.h @@ -0,0 +1,64 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Dirent_Selector.h + * + * $Id$ + * + * Define a portable C++ interface to the <ACE_OS_Dirent::scandir> method. + * + * @author Rich Newman <RNewman@directv.com> + */ +//============================================================================= + +#ifndef ACE_DIRENT_SELECTOR_H +#define ACE_DIRENT_SELECTOR_H +#include "ace/pre.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class ACE_Dirent + * + * @brief Define a portable C++ directory-entry iterator based on the POSIX <scandir> API. + */ +class ACE_Export ACE_Dirent_Selector +{ +public: + /// Constructor + ACE_Dirent_Selector (void); + + /// Destructor. + virtual ~ACE_Dirent_Selector (void); + + /// Return the length of the list of matching directory entries. + int length (void) const; + + /// Return the entry at <index>. + dirent *operator[] (const int index) const; + + /// Free up resources. + int close (void); + + /// Open the director <dir> and populate the <namelist_> array with + /// directory entries that match the <selector> and <comparator>. + int open (const ACE_TCHAR *dir, + int (*selector)(const dirent *d) = 0, + int (*comparator)(const dirent **d1, const dirent **d2) = 0); + +protected: + /// Ptr to the namelist array. + dirent **namelist_; + + /// # of entries in the array. + int n_; +}; + +#include "ace/Dirent_Selector.inl" + +#include "ace/post.h" +#endif /* ACE_DIRENT_SELECTOR_H */ + diff --git a/ace/Dirent_Selector.inl b/ace/Dirent_Selector.inl new file mode 100644 index 00000000000..2bd4f42e024 --- /dev/null +++ b/ace/Dirent_Selector.inl @@ -0,0 +1,13 @@ +/* -*- C++ -*- */ + +ACE_INLINE int +ACE_Dirent_Selector::length (void) const +{ + return n_; +} + +ACE_INLINE dirent * +ACE_Dirent_Selector::operator[] (const int n) const +{ + return this->namelist_[n]; +} diff --git a/ace/Makefile b/ace/Makefile index 16d85d03aba..765f2fcf435 100644 --- a/ace/Makefile +++ b/ace/Makefile @@ -32,6 +32,7 @@ UTILS_FILES = \ Configuration \ Configuration_Import_Export \ Dirent \ + Dirent_Selector \ Dynamic \ Flag_Manip \ Functor \ diff --git a/ace/Makefile.bor b/ace/Makefile.bor index 34dd3e0c4f7..9275f3a9a25 100644 --- a/ace/Makefile.bor +++ b/ace/Makefile.bor @@ -49,6 +49,7 @@ OBJFILES = \ $(OBJDIR)\DEV_Connector.obj \ $(OBJDIR)\DEV_IO.obj \ $(OBJDIR)\Dirent.obj \ + $(OBJDIR)\Dirent_Selector.obj \ $(OBJDIR)\DLL.obj \ $(OBJDIR)\Dump.obj \ $(OBJDIR)\Dynamic.obj \ diff --git a/ace/OS_Dirent.cpp b/ace/OS_Dirent.cpp index 6f7bfcd3f69..90f3d760eb3 100644 --- a/ace/OS_Dirent.cpp +++ b/ace/OS_Dirent.cpp @@ -2,6 +2,8 @@ #include "ace/OS_Dirent.h" #include "ace/OS_String.h" +#include "ace/OS_Memory.h" +#include "ace/Log_Msg.h" ACE_RCSID(ace, OS_Dirent, "$Id$") @@ -76,7 +78,7 @@ ACE_OS_Dirent::closedir_emulation (ACE_DIR *d) #endif /* ACE_WIN32 */ } -struct dirent * +dirent * ACE_OS_Dirent::readdir_emulation (ACE_DIR *d) { #if defined (ACE_WIN32) @@ -116,8 +118,11 @@ ACE_OS_Dirent::readdir_emulation (ACE_DIR *d) if (d->current_handle_ != INVALID_HANDLE_VALUE) { - d->dirent_.d_name = d->fdata_.cFileName; - return &d->dirent_; + d->dirent_ = (dirent *) ACE_OS_Memory::malloc (sizeof (dirent) + + ACE_OS_String::strlen (d->fdata_.cFileName)); + ACE_OS_String::strcpy ((char *) d->dirent_->d_name, d->fdata_.cFileName); + d->dirent_->d_reclen = sizeof (dirent) + ACE_OS_String::strlen (d->dirent_->d_name); + return d->dirent_; } else return 0; @@ -126,3 +131,97 @@ ACE_OS_Dirent::readdir_emulation (ACE_DIR *d) ACE_NOTSUP_RETURN (0); #endif /* ACE_WIN32 */ } + +extern "C" +{ + typedef int (*ACE_SCANDIR_COMPARATOR) (const void *, const void *); +} + +int +ACE_OS_Dirent::scandir_emulation (const ACE_TCHAR *dirname, + dirent **namelist[], + int (*selector) (const dirent *entry), + int (*comparator) (const dirent **f1, + const dirent **f2)) +{ + ACE_DIR *dirp = ACE_OS_Dirent::opendir (dirname); + + if (dirp == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_LIB_TEXT ("scandir_emulation cannot open directory %s"), + dirname), + -1); + + // A sanity check here. "namelist" had better not be zero. + if (namelist == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_LIB_TEXT ("scandir_emulation namelist == 0!")), + -1); + + dirent **vector = 0; + dirent *dp; + int arena_size = 0; + + int nfiles = 0; + int fail = 0; + + // @@ This code shoulduse readdir_r() rather than readdir(). + for (dp = ACE_OS_Dirent::readdir (dirp); + dp != 0; + dp = ACE_OS_Dirent::readdir (dirp)) + { + if (selector && (*selector)(dp) == 0) + continue; + + // If we get here, we have a dirent that the user likes. + if (nfiles == arena_size) + { + dirent **newv; + if (arena_size == 0) + arena_size = 10; + else + arena_size *= 2; + + newv = (dirent **) ACE_OS_Memory::realloc (vector, + arena_size * sizeof (dirent *)); + if (newv == 0) + { + fail = 1; + break; + } + vector = newv; + } + + int dsize = sizeof (dirent) + ACE_OS_String::strlen (dp->d_name) + 1; + dirent *newdp = (dirent *) ACE_OS_Memory::malloc (dsize); + + if (newdp == 0) + { + fail = 1; + break; + } + + vector[nfiles++] = (dirent *) ACE_OS_String::memcpy (newdp, dp, dsize); + } + + if (fail) + { + ACE_OS_Dirent::closedir (dirp); + while (nfiles-- > 0) + ACE_OS_Memory::free (vector[nfiles]); + ACE_OS_Memory::free (vector); + return -1; + } + + ACE_OS_Dirent::closedir (dirp); + + *namelist = vector; + + if (comparator) + ACE_OS::qsort (*namelist, + nfiles, + sizeof (dirent *), + (ACE_SCANDIR_COMPARATOR) comparator); + + return nfiles; +} diff --git a/ace/OS_Dirent.h b/ace/OS_Dirent.h index 749eb52ac94..ed9f8946b26 100644 --- a/ace/OS_Dirent.h +++ b/ace/OS_Dirent.h @@ -12,7 +12,6 @@ */ //============================================================================= - #ifndef ACE_OS_DIRENT_H #define ACE_OS_DIRENT_H #include "ace/pre.h" @@ -44,24 +43,24 @@ struct dirent { unsigned short d_ino; unsigned short d_off; unsigned short d_reclen; - const ACE_TCHAR *d_name; + const ACE_TCHAR d_name[1]; }; struct ACE_DIR { + /// The name of the directory we are looking into ACE_TCHAR *directory_name_; - // The name of the directory we are looking into + /// Remember the handle between calls. HANDLE current_handle_; - // Remember the handle between calls. - dirent dirent_; - // The struct for the results + /// The struct for the results + dirent *dirent_; + /// The struct for intermediate results. ACE_TEXT_WIN32_FIND_DATA fdata_; - // The struct for intermediate results. + /// A flag to remember if we started reading already. int started_reading_; - // A flag to remember if we started reading already. }; #elif defined (ACE_PSOS) && !defined (ACE_PSOS_DIAB_PPC) // pHILE+ calls the DIR struct XDIR instead @@ -86,20 +85,30 @@ class ACE_OS_Export ACE_OS_Dirent public: static ACE_DIR *opendir (const ACE_TCHAR *filename); static void closedir (ACE_DIR *); - static struct dirent *readdir (ACE_DIR *); + static dirent *readdir (ACE_DIR *); static int readdir_r (ACE_DIR *dirp, - struct dirent *entry, - struct dirent **result); + dirent *entry, + dirent **result); static long telldir (ACE_DIR *); static void seekdir (ACE_DIR *, long loc); static void rewinddir (ACE_DIR *); + static int scandir (const ACE_TCHAR *dirname, + dirent **namelist[], + int (*selector) (const dirent *filename), + int (*comparator) (const dirent **f1, + const dirent **f2)); private: // Win32 emulation functions static ACE_DIR *opendir_emulation (const ACE_TCHAR *filename); + static int scandir_emulation (const ACE_TCHAR *dirname, + dirent **namelist[], + int (*selector)(const dirent *entry), + int (*comparator)(const dirent **f1, + const dirent**f2)); static void closedir_emulation (ACE_DIR *); - static struct dirent *readdir_emulation (ACE_DIR *); + static dirent *readdir_emulation (ACE_DIR *); }; # if defined (ACE_HAS_INLINED_OSCALLS) diff --git a/ace/OS_Dirent.inl b/ace/OS_Dirent.inl index a56b0ae58c6..75980e33a7e 100644 --- a/ace/OS_Dirent.inl +++ b/ace/OS_Dirent.inl @@ -1,4 +1,4 @@ -/* -*- C++ -*- */ +// -*- C++ -*- // $Id$ #if defined (ACE_HAS_PACE) @@ -123,9 +123,9 @@ ACE_OS_Dirent::readdir (ACE_DIR *d) ACE_INLINE int ACE_OS_Dirent::readdir_r (ACE_DIR *dirp, - struct dirent *entry, - struct dirent **result) -{ + struct dirent *entry, + struct dirent **result) +{ #if defined (ACE_HAS_PACE) && !defined (ACE_WIN32) return pace_readdir_r (dirp, entry, result); # elif !defined (ACE_HAS_REENTRANT_FUNCTIONS) @@ -207,3 +207,17 @@ ACE_OS_Dirent::rewinddir (ACE_DIR *d) ACE_UNUSED_ARG (d); #endif /* ACE_HAS_DIRENT */ } + +ACE_INLINE int +ACE_OS_Dirent::scandir (const ACE_TCHAR *dirname, + struct dirent **namelist[], + int (*selector)(const struct dirent *), + int (*comparator) (const struct dirent **f1, + const struct dirent **f2)) +{ +#if defined (ACE_HAS_SCANDIR) + return ::scandir (dirname, namelist, selector, comparator); +#else /* ! defined ( ACE_HAS_SCANDIR) */ + return ACE_OS_Dirent::scandir_emulation (dirname, namelist, selector, comparator); +#endif /* ACE_HAS_SCANDIR */ +} diff --git a/ace/OS_Memory.h b/ace/OS_Memory.h index 61d3195dd86..00f2f3e4666 100644 --- a/ace/OS_Memory.h +++ b/ace/OS_Memory.h @@ -12,7 +12,6 @@ */ //============================================================================= - #ifndef ACE_OS_MEMORY_H #define ACE_OS_MEMORY_H #include "ace/pre.h" @@ -100,8 +99,7 @@ typedef void *ACE_MALLOC_T; /** * @class ACE_OS_Memory * - * @brief This class is a wrapper for memory operations, like - * malloc, memcpy, etc. + * @brief This class is a wrapper for dynamic memory operations. * */ class ACE_OS_Export ACE_OS_Memory diff --git a/ace/Reactor.cpp b/ace/Reactor.cpp index ceeb3ff52b5..df535e187a5 100644 --- a/ace/Reactor.cpp +++ b/ace/Reactor.cpp @@ -20,7 +20,6 @@ ACE_RCSID(ace, Reactor, "$Id$") - ACE_ALLOC_HOOK_DEFINE(ACE_Reactor) ACE_Reactor::ACE_Reactor (ACE_Reactor_Impl *impl, diff --git a/ace/Service_Object.cpp b/ace/Service_Object.cpp index e768ebee113..c5dfa7ce240 100644 --- a/ace/Service_Object.cpp +++ b/ace/Service_Object.cpp @@ -1,7 +1,5 @@ // $Id$ -// Service_Object.cpp - #include "ace/Service_Types.h" #include "ace/Service_Object.h" |