• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

dirent_msvc.h

Go to the documentation of this file.
00001 //
00002 // dirent.h - dirent API for Microsoft Visual Studio
00003 //
00004 // Copyright (C) 2006 Toni Ronkko
00005 //
00006 // Permission is hereby granted, free of charge, to any person obtaining
00007 // a copy of this software and associated documentation files (the
00008 // ``Software''), to deal in the Software without restriction, including
00009 // without limitation the rights to use, copy, modify, merge, publish,
00010 // distribute, sublicense, and/or sell copies of the Software, and to
00011 // permit persons to whom the Software is furnished to do so, subject to
00012 // the following conditions:
00013 //
00014 // The above copyright notice and this permission notice shall be included
00015 // in all copies or substantial portions of the Software.
00016 //
00017 // THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
00018 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00019 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00020 // IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
00021 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00022 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00023 // OTHER DEALINGS IN THE SOFTWARE.
00024 //
00025 //
00026 // Jan 18, 2008, Toni Ronkko
00027 // Using FindFirstFileA and WIN32_FIND_DATAA to avoid converting string
00028 // between multi-byte and unicode representations.  This makes the
00029 // code simpler and also allows the code to be compiled under MingW.  Thanks
00030 // to Azriel Fasten for the suggestion.
00031 //
00032 // Mar 4, 2007, Toni Ronkko
00033 // Bug fix: due to the strncpy_s() function this file only compiled in
00034 // Visual Studio 2005.  Using the new string functions only when the
00035 // compiler version allows.
00036 //
00037 // Nov  2, 2006, Toni Ronkko
00038 // Major update: removed support for Watcom C, MS-DOS and Turbo C to
00039 // simplify the file, updated the code to compile cleanly on Visual
00040 // Studio 2005 with both unicode and multi-byte character strings,
00041 // removed rewinddir() as it had a bug.
00042 //
00043 // Aug 20, 2006, Toni Ronkko
00044 // Removed all remarks about MSVC 1.0, which is antiqued now.  Simplified
00045 // comments by removing SGML tags.
00046 //
00047 // May 14 2002, Toni Ronkko
00048 // Embedded the function definitions directly to the header so that no
00049 // source modules need to be included in the Visual Studio project.  Removed
00050 // all the dependencies to other projects so that this very header can be
00051 // used independently.
00052 //
00053 // May 28 1998, Toni Ronkko
00054 // First version.
00055 //
00056 #ifndef DIRENT_H
00057 #define DIRENT_H
00058 
00059 #include <windows.h>
00060 #include <string.h>
00061 #include <assert.h>
00062 
00063 
00064 typedef struct dirent
00065 {
00066     // name of current directory entry (a multi-byte character string)
00067     char             d_name[MAX_PATH + 1];
00068 
00069     // file attributes
00070     WIN32_FIND_DATAA data;
00071 } dirent;
00072 
00073 
00074 typedef struct DIR
00075 {
00076     // current directory entry
00077     dirent current;
00078 
00079     // is there an un-processed entry in current?
00080     int    cached;
00081 
00082     // file search handle
00083     HANDLE search_handle;
00084 
00085     // search pattern (3 = zero terminator + pattern "\\*")
00086     char   patt[MAX_PATH + 3];
00087 } DIR;
00088 
00089 
00090 static DIR *opendir( const char *dirname );
00091 static struct dirent *readdir( DIR *dirp );
00092 static int closedir( DIR *dirp );
00093 
00094 
00095 // use the new safe string functions introduced in Visual Studio 2005
00096 #if defined ( _MSC_VER ) && _MSC_VER >= 1400
00097 # define STRNCPY( dest, src, size )    strncpy_s( ( dest ), ( size ), ( src ), _TRUNCATE )
00098 #else
00099 # define STRNCPY( dest, src, size )    strncpy( ( dest ), ( src ), ( size ) )
00100 #endif
00101 
00102 
00103 //
00104 // Open directory stream DIRNAME for read and return a pointer to the
00105 // internal working area that is used to retrieve individual directory
00106 // entries.
00107 //
00108 static DIR*
00109 opendir(
00110     const char *dirname )
00111 {
00112     DIR *dirp;
00113     assert( dirname != NULL );
00114     assert( strlen( dirname ) < MAX_PATH );
00115 
00116     // construct new DIR structure
00117     dirp = (DIR *) malloc( sizeof ( struct DIR ) );
00118     if ( dirp != NULL )
00119     {
00120         char *p;
00121 
00122         // take directory name...
00123         STRNCPY( dirp->patt, dirname, sizeof ( dirp->patt ) );
00124         dirp->patt[MAX_PATH] = '\0';
00125 
00126         // ... and append search pattern to it
00127         p = strchr( dirp->patt, '\0' );
00128         if ( dirp->patt < p && *( p - 1 ) != '\\' && *( p - 1 ) != ':' )
00129         {
00130             *p++ = '\\';
00131         }
00132         *p++ = '*';
00133         *p   = '\0';
00134 
00135         // open stream and retrieve first file
00136         dirp->search_handle = FindFirstFileA( dirp->patt, &dirp->current.data );
00137         if ( dirp->search_handle == INVALID_HANDLE_VALUE )
00138         {
00139             // invalid search pattern?
00140             free( dirp );
00141             return NULL;
00142         }
00143 
00144         // there is an un-processed directory entry in memory now
00145         dirp->cached = 1;
00146     }
00147     return dirp;
00148 }
00149 
00150 
00151 //
00152 // Read a directory entry, and return a pointer to a dirent structure
00153 // containing the name of the entry in d_name field.  Individual directory
00154 // entries returned by this very function include regular files,
00155 // sub-directories, pseudo-directories "." and "..", but also volume labels,
00156 // hidden files and system files may be returned.
00157 //
00158 static struct dirent *
00159 readdir(
00160     DIR *dirp )
00161 {
00162     assert( dirp != NULL );
00163 
00164     if ( dirp->search_handle == INVALID_HANDLE_VALUE )
00165     {
00166         // directory stream was opened/rewound incorrectly or it ended normally
00167         return NULL;
00168     }
00169 
00170     // get next directory entry
00171     if ( dirp->cached != 0 )
00172     {
00173         // a valid directory entry already in memory
00174         dirp->cached = 0;
00175     }
00176     else
00177     {
00178         // read next directory entry from disk
00179         if ( FindNextFileA( dirp->search_handle, &dirp->current.data ) == FALSE )
00180         {
00181             // the very last file has been processed or an error occured
00182             FindClose( dirp->search_handle );
00183             dirp->search_handle = INVALID_HANDLE_VALUE;
00184             return NULL;
00185         }
00186     }
00187 
00188     // copy as a multibyte character string
00189     STRNCPY( dirp->current.d_name, dirp->current.data.cFileName, sizeof ( dirp->current.d_name ) );
00190     dirp->current.d_name[MAX_PATH] = '\0';
00191 
00192     return &dirp->current;
00193 }
00194 
00195 
00196 //
00197 // Close directory stream opened by opendir() function.  Close of the
00198 // directory stream invalidates the DIR structure as well as any previously
00199 // read directory entry.
00200 //
00201 static int
00202 closedir(
00203     DIR *dirp )
00204 {
00205     assert( dirp != NULL );
00206 
00207     // release search handle
00208     if ( dirp->search_handle != INVALID_HANDLE_VALUE )
00209     {
00210         FindClose( dirp->search_handle );
00211         dirp->search_handle = INVALID_HANDLE_VALUE;
00212     }
00213 
00214     // release directory handle
00215     free( dirp );
00216     return 0;
00217 }
00218 
00219 
00220 #endif //DIRENT_H

Generated on Wed Oct 12 2011 20:42:21 for PLplot by  doxygen 1.7.1